diff --git a/c-api/core.cpp b/c-api/core.cpp index 5c50759..0aa6e10 100644 --- a/c-api/core.cpp +++ b/c-api/core.cpp @@ -1000,6 +1000,16 @@ void Core_SetMigrationDistance(alt::ICore* core, uint32_t limit) { core->SetMigrationDistance(limit); } + +void Core_TriggerClientRPCAnswer(alt::ICore* core, alt::IPlayer* target, uint16_t answerID, alt::MValueConst* args[], + int size, const char* error) +{ + alt::MValueArgs mValues = alt::MValueArgs(size); + for (int i = 0; i < size; i++) { + ToMValueArg(mValues, core, args[i], i); + } + core->TriggerClientRPCAnswer(target, answerID, mValues, error); +} #endif #ifdef ALT_CLIENT_API @@ -1998,6 +2008,15 @@ void Core_GetAllWeaponData(alt::ICore* core, uint32_t weaponHashes[], uint64_t s weaponHashes[i] = weaponData[i]->GetNameHash(); } } + +uint16_t Core_TriggerServerRPCEvent(alt::ICore* core, const char* ev, alt::MValueConst* args[], int size) +{ + alt::MValueArgs mValues = alt::MValueArgs(size); + for (int i = 0; i < size; i++) { + ToMValueArg(mValues, core, args[i], i); + } + return core->TriggerServerRPCEvent(ev, mValues); +} #endif CAPI_END() diff --git a/c-api/core.h b/c-api/core.h index 48e4513..7cebfd9 100644 --- a/c-api/core.h +++ b/c-api/core.h @@ -396,4 +396,7 @@ EXPORT_SERVER uint32_t Core_GetColShapeTickRate(alt::ICore* core); EXPORT_SERVER void Core_SetColShapeTickRate(alt::ICore* core, uint32_t limit); EXPORT_SERVER uint32_t Core_GetMigrationDistance(alt::ICore* core); -EXPORT_SERVER void Core_SetMigrationDistance(alt::ICore* core, uint32_t limit); \ No newline at end of file +EXPORT_SERVER void Core_SetMigrationDistance(alt::ICore* core, uint32_t limit); + +EXPORT_SERVER void Core_TriggerClientRPCAnswer(alt::ICore* server, alt::IPlayer* target, uint16_t answerID, alt::MValueConst* args[], int size, const char* error); +EXPORT_CLIENT uint16_t Core_TriggerServerRPCEvent(alt::ICore* server, const char* ev, alt::MValueConst* args[], int size); diff --git a/c-api/event.cpp b/c-api/event.cpp index 116cfba..42f8161 100644 --- a/c-api/event.cpp +++ b/c-api/event.cpp @@ -1,5 +1,6 @@ #include "event.h" +#include "mvalue.h" #include "utils/macros.h" CAPI_START() @@ -7,7 +8,29 @@ CAPI_START() #ifdef ALT_SERVER_API void Event_WeaponDamageEvent_SetDamageValue(alt::CEvent* event, uint32_t damageValue) { - ((alt::CWeaponDamageEvent*) event)->SetDamageValue(damageValue); + dynamic_cast(event)->SetDamageValue(damageValue); +} + +uint8_t Event_ClientScriptRPCEvent_WillAnswer(alt::CEvent* event) +{ + auto rpcEvent = dynamic_cast(event); + return rpcEvent->WillAnswer(); +} + +uint8_t Event_ClientScriptRPCEvent_Answer(alt::CEvent* event, alt::ICore* core, alt::MValueConst* args[], int size) +{ + alt::MValueArgs mValues = alt::MValueArgs(size); + for (int i = 0; i < size; i++) { + ToMValueArg(mValues, core, args[i], i); + } + auto rpcEvent = dynamic_cast(event); + return rpcEvent->Answer(mValues); +} + +uint8_t Event_ClientScriptRPCEvent_AnswerWithError(alt::CEvent* event, const char* error) +{ + auto rpcEvent = dynamic_cast(event); + return rpcEvent->AnswerWithError(error); } #endif @@ -90,6 +113,8 @@ SetDelegate(PlayerBulletHit); SetDelegate(VoiceConnection); SetDelegate(AudioEvent); +SetDelegate(ServerScriptRPCAnswer) + #endif CAPI_END() \ No newline at end of file diff --git a/c-api/event.h b/c-api/event.h index 9b7a527..75324d6 100644 --- a/c-api/event.h +++ b/c-api/event.h @@ -21,6 +21,9 @@ EXPORT_SHARED void Event_Cancel(alt::CCancellableEvent* event); EXPORT_SERVER void Event_WeaponDamageEvent_SetDamageValue(alt::CEvent* event, uint32_t damageValue); +EXPORT_SERVER uint8_t Event_ClientScriptRPCEvent_WillAnswer(alt::CEvent* event); +EXPORT_SERVER uint8_t Event_ClientScriptRPCEvent_Answer(alt::CEvent* event, alt::MValueConst* args[], int size); +EXPORT_SERVER uint8_t Event_ClientScriptRPCEvent_AnswerWithError(alt::CEvent* event, const char* error); EXPORT_SHARED uint8_t Event_WasCancelled(alt::CCancellableEvent* event); #ifdef ALT_CLIENT_API @@ -92,4 +95,5 @@ EXPORT_CLIENT void Event_SetPlayerStartLeaveVehicleDelegate(CSharpResourceImpl* EXPORT_CLIENT void Event_SetPlayerBulletHitDelegate(CSharpResourceImpl* resource, /** ClientEvents.PlayerBulletHitModuleDelegate */ PlayerBulletHitDelegate_t delegate); EXPORT_CLIENT void Event_SetVoiceConnectionDelegate(CSharpResourceImpl* resource, /** ClientEvents.VoiceConnectionModuleDelegate */ VoiceConnectionDelegate_t delegate); +EXPORT_CLIENT void Event_SetServerScriptRPCAnswerDelegate(CSharpResourceImpl* resource, /** ClientEvents.ServerScriptRPCAnswerModuleDelegate */ ServerScriptRPCAnswerDelegate_t delegate); #endif diff --git a/c-api/func_table.cpp b/c-api/func_table.cpp index 2bafd5d..6587372 100644 --- a/c-api/func_table.cpp +++ b/c-api/func_table.cpp @@ -1,6 +1,6 @@ #include "func_table.h" -inline uint64_t capiHash = 3088291357268716232UL; +inline uint64_t capiHash = 11229478147648242923UL; inline uint64_t capiHashes[] = { 0, #ifdef ALT_CLIENT_API @@ -245,6 +245,7 @@ inline uint64_t capiHashes[] = { 1817218062913323235UL, 4092140335578989631UL, 718150788563346996UL, + 5920144219377072122UL, 3268039739443301173UL, 17753040748478874447UL, 5389506501733691988UL, @@ -286,6 +287,7 @@ inline uint64_t capiHashes[] = { 8121512912272945641UL, 1513529985252499227UL, 5521055548998327457UL, + 13554094634858443749UL, 8576321635222028243UL, 12745100726667735891UL, 11607888672861240667UL, @@ -1374,6 +1376,7 @@ inline uint64_t capiHashes[] = { 4821179867491879744UL, 9578627964183564598UL, 14557546483922608997UL, + 9224620724544415249UL, 4092140335578989631UL, 17237210604041123822UL, 11965009764904998252UL, @@ -1390,6 +1393,9 @@ inline uint64_t capiHashes[] = { 6004628797499736605UL, 12798418058428333585UL, 8026011842118229214UL, + 9846613369628943706UL, + 2674464925851684396UL, + 5065438074644693875UL, 18440396865533386791UL, 2348810001298180138UL, 13016512038826983106UL, @@ -1969,6 +1975,7 @@ inline void* capiPointers[] = { (void*) Core_ToggleVoiceInput, (void*) Core_TriggerServerEvent, (void*) Core_TriggerServerEventUnreliable, + (void*) Core_TriggerServerRPCEvent, (void*) Core_TriggerWebViewEvent, (void*) Core_UnloadYtyp, (void*) Core_WorldToScreen, @@ -2010,6 +2017,7 @@ inline void* capiPointers[] = { (void*) Event_SetRemoveBaseObjectDelegate, (void*) Event_SetRmlEventDelegate, (void*) Event_SetServerEventDelegate, + (void*) Event_SetServerScriptRPCAnswerDelegate, (void*) Event_SetStreamSyncedMetaChangeDelegate, (void*) Event_SetSyncedMetaChangeDelegate, (void*) Event_SetTaskChangeDelegate, @@ -3098,6 +3106,7 @@ inline void* capiPointers[] = { (void*) Core_TriggerClientEventUnreliable, (void*) Core_TriggerClientEventUnreliableForAll, (void*) Core_TriggerClientEventUnreliableForSome, + (void*) Core_TriggerClientRPCAnswer, (void*) Core_TriggerServerEvent, (void*) Core_UnregisterMetric, (void*) Entity_AttachToEntity, @@ -3114,6 +3123,9 @@ inline void* capiPointers[] = { (void*) Entity_SetStreamed, (void*) Entity_SetStreamSyncedMetaData, (void*) Entity_SetVisible, + (void*) Event_ClientScriptRPCEvent_Answer, + (void*) Event_ClientScriptRPCEvent_AnswerWithError, + (void*) Event_ClientScriptRPCEvent_WillAnswer, (void*) Event_WeaponDamageEvent_SetDamageValue, (void*) Metric_Begin, (void*) Metric_End, diff --git a/client/src/runtime/CSharpResourceImpl.cpp b/client/src/runtime/CSharpResourceImpl.cpp index 9659340..d49babd 100644 --- a/client/src/runtime/CSharpResourceImpl.cpp +++ b/client/src/runtime/CSharpResourceImpl.cpp @@ -586,6 +586,24 @@ void CSharpResourceImpl::OnEvent(const alt::CEvent* ev) size); break; } + case alt::CEvent::Type::SERVER_SCRIPT_RPC_ANSWER_EVENT: + { + auto serverScriptRPCAnswerEvent = dynamic_cast(ev); + + auto answers = serverScriptRPCAnswerEvent->GetAnswer(); + auto size = answers.size(); + auto constAnswers = new alt::MValueConst*[size]; + + for (uint64_t i = 0; i < size; i++) + { + constAnswers[i] = &answers[i]; + } + OnServerScriptRPCAnswerDelegate(serverScriptRPCAnswerEvent->GetAnswerID(), + constAnswers, + size, + serverScriptRPCAnswerEvent->GetAnswerError().c_str()); + break; + } default: { std::cout << "Unhandled client event #" << static_cast(ev->GetType()) << " got called" << std::endl; @@ -1012,4 +1030,6 @@ void CSharpResourceImpl::ResetDelegates() { OnPlayerBulletHitDelegate = [](auto var, auto var2, auto var3, auto var4) {}; OnVoiceConnectionDelegate = [](auto var) {}; + + OnServerScriptRPCAnswerDelegate = [](auto var, auto var2, auto var3, auto var4) {}; } \ No newline at end of file diff --git a/client/src/runtime/CSharpResourceImpl.h b/client/src/runtime/CSharpResourceImpl.h index b8ac171..0469cfc 100644 --- a/client/src/runtime/CSharpResourceImpl.h +++ b/client/src/runtime/CSharpResourceImpl.h @@ -102,6 +102,8 @@ class CSharpResourceImpl : public alt::IResource::Impl VoiceConnectionDelegate_t OnVoiceConnectionDelegate = nullptr; + ServerScriptRPCAnswerDelegate_t OnServerScriptRPCAnswerDelegate = nullptr; + bool MakeClient(alt::IResource::CreationInfo* info, std::vector files) { diff --git a/client/src/runtime/eventDelegates.h b/client/src/runtime/eventDelegates.h index 7799cb0..08638bb 100644 --- a/client/src/runtime/eventDelegates.h +++ b/client/src/runtime/eventDelegates.h @@ -77,3 +77,4 @@ typedef void (* PlayerStartLeaveVehicleDelegate_t)(void* target, void* player, u typedef void (* PlayerBulletHitDelegate_t)(uint32_t weapon, void* victim, alt::IBaseObject::Type victimType, position_t pos); typedef void (* VoiceConnectionDelegate_t)(uint8_t state); +typedef void (* ServerScriptRPCAnswerDelegate_t)(uint16_t answerId, alt::MValueConst** answer, uint64_t size, const char* answerError); diff --git a/server/include/CSharpResourceImpl.h b/server/include/CSharpResourceImpl.h index 36cb84b..00f13cb 100644 --- a/server/include/CSharpResourceImpl.h +++ b/server/include/CSharpResourceImpl.h @@ -209,6 +209,8 @@ typedef void (* PedHealDelegate_t)(alt::IPed* target, uint16_t oldHealth, uint16 typedef void (* PlayerStartTalkingDelegate_t)(alt::IPlayer* player); typedef void (* PlayerStopTalkingDelegate_t)(alt::IPlayer* player); +typedef void (* ClientScriptRPCDelegate_t)(const alt::CEvent* event, alt::IPlayer* target, const char* name, alt::MValueConst** args, uint64_t size, uint16_t answerID); + class CSharpResourceImpl : public alt::IResource::Impl { void OnEvent(const alt::CEvent* ev) override; @@ -351,6 +353,8 @@ class CSharpResourceImpl : public alt::IResource::Impl { PlayerStartTalkingDelegate_t OnPlayerStartTalkingDelegate = nullptr; PlayerStopTalkingDelegate_t OnPlayerStopTalkingDelegate = nullptr; + ClientScriptRPCDelegate_t OnClientScriptRPCDelegate = nullptr; + std::vector invokers; std::mutex invokersLock = {}; CoreClr* coreClr; @@ -571,3 +575,5 @@ EXPORT void CSharpResourceImpl_SetPedHealDelegate(CSharpResourceImpl* resource, EXPORT void CSharpResourceImpl_SetPlayerStartTalkingDelegate(CSharpResourceImpl* resource, PlayerStartTalkingDelegate_t delegate); EXPORT void CSharpResourceImpl_SetPlayerStopTalkingDelegate(CSharpResourceImpl* resource, PlayerStopTalkingDelegate_t delegate); + +EXPORT void CSharpResourceImpl_SetClientScriptRPCDelegate(CSharpResourceImpl* resource, ClientScriptRPCDelegate_t delegate); diff --git a/server/src/CSharpResourceImpl.cpp b/server/src/CSharpResourceImpl.cpp index fcb6d98..1395d38 100644 --- a/server/src/CSharpResourceImpl.cpp +++ b/server/src/CSharpResourceImpl.cpp @@ -76,6 +76,8 @@ void CSharpResourceImpl::ResetDelegates() OnPedDamageDelegate = [](auto var, auto var2, auto var3, auto var4, auto var5, auto var6) {}; OnPedDeathDelegate = [](auto var, auto var2, auto var3, auto var4) {}; OnPedHealDelegate = [](auto var, auto var2, auto var3, auto var4, auto var5) {}; + + OnClientScriptRPCDelegate = [](auto var, auto var2, auto var3, auto var4, auto var5, auto var6) {}; } bool CSharpResourceImpl::Start() @@ -836,6 +838,32 @@ case alt::CEvent::Type::SYNCED_META_CHANGE: OnPlayerStopTalkingDelegate(player); break; } + case alt::CEvent::Type::CLIENT_SCRIPT_RPC_EVENT: + { + auto clientScriptRPCEvent = dynamic_cast(ev); + + auto target = clientScriptRPCEvent->GetTarget(); + if (target == nullptr) return; + + auto name = clientScriptRPCEvent->GetName(); + auto args = clientScriptRPCEvent->GetArgs(); + auto size = args.size(); + auto constArgs = new alt::MValueConst*[size]; + + for (uint64_t i = 0; i < size; i++) + { + constArgs[i] = &args[i]; + } + + OnClientScriptRPCDelegate(clientScriptRPCEvent, + target, + name.c_str(), + constArgs, + size, + clientScriptRPCEvent->GetAnswerID() + ); + break; + } default: { std::cout << "Unhandled server event #" << static_cast(ev->GetType()) << " got called" << std::endl; @@ -1377,6 +1405,11 @@ void CSharpResourceImpl_SetPlayerStopTalkingDelegate(CSharpResourceImpl* resourc resource->OnPlayerStopTalkingDelegate = delegate; } +void CSharpResourceImpl_SetClientScriptRPCDelegate(CSharpResourceImpl* resource, ClientScriptRPCDelegate_t delegate) +{ + resource->OnClientScriptRPCDelegate = delegate; +} + bool CSharpResourceImpl::MakeClient(alt::IResource::CreationInfo* info, std::vector files) { const std::string clientMain = resource->GetClientMain();