From 7b7f974e42985b274472ad26aef494746b695c32 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Fri, 23 Jul 2021 17:31:05 +0300 Subject: [PATCH] Allow current client data buffer to be retrieved anywhere during the callback. --- module/Core.cpp | 10 ++++++++++ module/Core.hpp | 11 +++++++++++ module/Core/Events.inc | 15 ++++++++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/module/Core.cpp b/module/Core.cpp index 1dadc2bd..7b125deb 100644 --- a/module/Core.cpp +++ b/module/Core.cpp @@ -181,6 +181,7 @@ Core::Core() noexcept , m_LockUnloadSignal(false) , m_EmptyInit(false) , m_Verbosity(1) + , m_ClientData() , m_NullBlip() , m_NullCheckpoint() , m_NullKeyBind() @@ -560,6 +561,8 @@ void Core::Terminate(bool shutdown) NullObject().Release(); NullLightObj().Release(); NullFunction().Release(); + // Release client data buffer, if any + m_ClientData.Release(); // Release null entity instances m_NullBlip.Release(); m_NullCheckpoint.Release(); @@ -2846,6 +2849,12 @@ static bool SqDelVehicle(int32_t id, int32_t header, LightObj & payload) return Core::Get().DelVehicle(id, header, payload); } +// ------------------------------------------------------------------------------------------------ +static LightObj & SqGetClientDataBuffer() +{ + return Core::Get().GetClientDataBuffer(); +} + // ================================================================================================ void Register_Core(HSQUIRRELVM vm) { @@ -2894,6 +2903,7 @@ void Register_Core(HSQUIRRELVM vm) .Func(_SC("DestroyObject"), &SqDelObject) .Func(_SC("DestroyPickup"), &SqDelPickup) .Func(_SC("DestroyVehicle"), &SqDelVehicle) + .Func(_SC("ClientDataBuffer"), &SqGetClientDataBuffer) .Func(_SC("OnPreLoad"), &SqGetPreLoadEvent) .Func(_SC("OnPostLoad"), &SqGetPostLoadEvent) .Func(_SC("OnUnload"), &SqGetUnloadEvent) diff --git a/module/Core.hpp b/module/Core.hpp index 4d41f5ab..8af99743 100644 --- a/module/Core.hpp +++ b/module/Core.hpp @@ -104,6 +104,9 @@ private: // -------------------------------------------------------------------------------------------- int32_t m_Verbosity; // Restrict the amount of outputted information. + // -------------------------------------------------------------------------------------------- + LightObj m_ClientData; // Currently processed client data buffer. + // -------------------------------------------------------------------------------------------- LightObj m_NullBlip; // Null Blips instance. LightObj m_NullCheckpoint; // Null Checkpoints instance. @@ -383,6 +386,14 @@ public: return (!m_IncomingNameBuffer) ? _SC("") : m_IncomingNameBuffer; } + /* -------------------------------------------------------------------------------------------- + * Retrieve the current client data buffer, if any. + */ + SQMOD_NODISCARD LightObj & GetClientDataBuffer() + { + return m_ClientData; + } + /* -------------------------------------------------------------------------------------------- * Retrieves a line of code from a certain source. */ diff --git a/module/Core/Events.inc b/module/Core/Events.inc index a3677cd8..3dcf3635 100644 --- a/module/Core/Events.inc +++ b/module/Core/Events.inc @@ -2213,18 +2213,25 @@ void Core::EmitClientScriptData(int32_t player_id, const uint8_t * data, size_t { SQMOD_CO_EV_TRACEBACK("[TRACE<] Core::ClientScriptData(%d, [byte stream], %" PRINT_SZ_FMT ")", player_id, size) PlayerInst & _player = m_Players.at(static_cast< size_t >(player_id)); +#ifndef VCMP_ENABLE_OFFICIAL // Don't even bother if there's no one listening if (!(_player.mOnClientScriptData.first->IsEmpty()) || !(mOnClientScriptData.first->IsEmpty())) { +#endif // Allocate a buffer with the received size Buffer b(static_cast< Buffer::SzType >(size)); // Replicate the data to the allocated buffer b.Write(0, reinterpret_cast< Buffer::ConstPtr >(data), static_cast< Buffer::SzType >(size)); // Prepare an object for the obtained buffer - LightObj o(SqTypeIdentity< SqBuffer >{}, m_VM, std::move(b)); + m_ClientData = LightObj(SqTypeIdentity< SqBuffer >{}, m_VM, std::move(b)); +#ifdef VCMP_ENABLE_OFFICIAL + // Don't even bother if there's no one listening + if (!(_player.mOnClientScriptData.first->IsEmpty()) || !(mOnClientScriptData.first->IsEmpty())) + { +#endif // Forward the event call - (*_player.mOnClientScriptData.first)(o, size); - (*mOnClientScriptData.first)(_player.mObj, o, size); + (*_player.mOnClientScriptData.first)(m_ClientData, size); + (*mOnClientScriptData.first)(_player.mObj, m_ClientData, size); } SQMOD_CO_EV_TRACEBACK("[TRACE>] Core::ClientScriptData") #ifdef VCMP_ENABLE_OFFICIAL @@ -2234,6 +2241,8 @@ void Core::EmitClientScriptData(int32_t player_id, const uint8_t * data, size_t ExecuteLegacyEvent(m_VM, _SC("onClientScriptData"), _player.mLgObj); } #endif + // Discard the buffer instance, if any + m_ClientData.Release(); } #undef NULL_SQOBJ_ // don't need this anymore