- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 505
- Реакции
- 13
В общем, застрял на одном моменте в Phasmophobia. Пытаюсь заставить работать RPC вызовы через Photon, но ловлю странный баг: игра ловит микро-статтер на секунду и просто закрывается без ошибок. Что интересно — это происходит только когда я ставлю RpcTarget::All. Если ставить Others, краша нет, но и профита ноль, ничего не происходит.
Подозрение падает на метод CreateBoxedValue. При этом обычные RPC со строковыми параметрами через IL2CPP::String::New залетают на ура, а вот с боксингом примитивов (в данном случае bool) какая-то беда.
Юзаю классический IL2CPP_Resolver для поиска экспортов и вызова методов. Конвенция вызова определена как __fastcall.
Сам метод упаковки значения выглядит так:
Есть мысли, почему Unity схлопывается именно на All? По идее, при All клиент пытается выполнить этот же RPC локально, и где-то здесь происходит фатал. Возможно, проблема в передаче bool через il2cpp_value_box или в структуре массива параметров.
Если кто-то плотно реверсил Photon в инди-хоррорах на Unity, накидайте вариантов, где я мог ошибиться в передаче аргументов.
Подозрение падает на метод CreateBoxedValue. При этом обычные RPC со строковыми параметрами через IL2CPP::String::New залетают на ура, а вот с боксингом примитивов (в данном случае bool) какая-то беда.
Юзаю классический IL2CPP_Resolver для поиска экспортов и вызова методов. Конвенция вызова определена как __fastcall.
Код:
auto lp = SDK::GetLocalPlayer();
if (!lp) return;
if (auto punView = lp->fields.view; punView && punView->fields.viewIdField != 0) {
dprnt("Photon view id: {}", punView->fields.viewIdField);
static auto sysObjClass = IL2CPP::Class::Find("System.Object");
auto paramsArray = SDK::Array::Il2cppArrayNew(sysObjClass, 1);
bool diedOrDisconnected = false;
static auto sysBoolClass = IL2CPP::Class::Find("System.Boolean");
paramsArray->At(0) = SDK::CreateBoxedValue(sysBoolClass, &diedOrDisconnected);
// Вызываем ForceDropPropsNetworked(bool diedOrDisconnected, PhotonMessageInfo info)
reinterpret_cast<Unity::CComponent*>(punView)->CallMethodSafe<void*>("RPC", IL2CPP::String::New("ForceDropPropsNetworked"), SDK::RpcTarget::All, paramsArray);
}
else {
dprnt("Photon view was null");
}
Сам метод упаковки значения выглядит так:
Код:
Unity::il2cppObject* SDK::CreateBoxedValue(Unity::il2cppClass* klass, const void* value) {
static auto resolvedValueBox = IL2CPP::UnityAPI::ResolveExport("il2cpp_value_box");
if (!resolvedValueBox) return nullptr;
using Il2cppValueBox_T = Unity::il2cppObject*(UNITY_CALLING_CONVENTION)(Unity::il2cppClass*, const void*);
auto il2cpp_value_box = reinterpret_cast<Il2cppValueBox_T>(resolvedValueBox);
return il2cpp_value_box(klass, value);
}
Есть мысли, почему Unity схлопывается именно на All? По идее, при All клиент пытается выполнить этот же RPC локально, и где-то здесь происходит фатал. Возможно, проблема в передаче bool через il2cpp_value_box или в структуре массива параметров.
Если кто-то плотно реверсил Photon в инди-хоррорах на Unity, накидайте вариантов, где я мог ошибиться в передаче аргументов.