diff options
author | Emma Miler <emma.pi@protonmail.com> | 2022-11-21 00:38:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-20 23:38:42 +0000 |
commit | 9e469ac28b610ecb8bce3e6c279660fae78861cf (patch) | |
tree | 57274f3be03cb160e42af7ed939274a2a028dbf0 /NorthstarDLL/squirrel.cpp | |
parent | 70b71ba3d3ad7121c6aabe55271542f55abe4008 (diff) | |
download | NorthstarLauncher-9e469ac28b610ecb8bce3e6c279660fae78861cf.tar.gz NorthstarLauncher-9e469ac28b610ecb8bce3e6c279660fae78861cf.zip |
Squirrel bridge v3 (#310)
* Initial
* Move squirrelmanager to virtual base class
* Implement changes from code review
* Formatting
* Update squirrel.cpp
* Formatting shit
* Fix filters
* Fix up
Use new squirrel autobind syntax
Move from `std::vector` to `std::queue` for message buffer
Add `NSTestMessageBuffer`
* Update squirrel.cpp
* Update squirrel.h
* Remove inline virtual final because this is stupid
I probably had a bit of a brain fart when this was written
* Moved to running ProcessMessages in-engine
* Remove TestMessageBuffer
* Formatting
* Rename pushSQObject -> pushobject
* Rename some stuff
* Update squirrel.h
* Formattting
* Remove unneeded global access
* Oops
Diffstat (limited to 'NorthstarDLL/squirrel.cpp')
-rw-r--r-- | NorthstarDLL/squirrel.cpp | 83 |
1 files changed, 80 insertions, 3 deletions
diff --git a/NorthstarDLL/squirrel.cpp b/NorthstarDLL/squirrel.cpp index c90b2d7f..673e2098 100644 --- a/NorthstarDLL/squirrel.cpp +++ b/NorthstarDLL/squirrel.cpp @@ -6,6 +6,8 @@ #include "r2engine.h" #include "tier0.h" +#include <any> + AUTOHOOK_INIT() std::shared_ptr<ColoredLogger> getSquirrelLoggerByContext(ScriptContext context) @@ -138,6 +140,25 @@ const char* SQTypeNameFromID(int type) return ""; } +// Allows for generating squirrelmessages from plugins. +// Not used in this version, but will be used later +void AsyncCall_External(ScriptContext context, const char* func_name, SquirrelMessage_External_Pop function) +{ + SquirrelMessage message {}; + message.functionName = func_name; + message.isExternal = true; + message.externalFunc = function; + switch (context) + { + case ScriptContext::CLIENT: + g_pSquirrel<ScriptContext::CLIENT>->messageBuffer->push(message); + case ScriptContext::SERVER: + g_pSquirrel<ScriptContext::SERVER>->messageBuffer->push(message); + case ScriptContext::UI: + g_pSquirrel<ScriptContext::UI>->messageBuffer->push(message); + } +} + // needed to define implementations for squirrelmanager outside of squirrel.h without compiler errors template class SquirrelManager<ScriptContext::SERVER>; template class SquirrelManager<ScriptContext::CLIENT>; @@ -156,6 +177,7 @@ template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquir for (auto& pair : g_pModManager->m_DependencyConstants) { bool bWasFound = false; + for (Mod& dependency : g_pModManager->m_LoadedMods) { if (!dependency.m_bEnabled) @@ -170,6 +192,7 @@ template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquir defconst(m_pSQVM, pair.first.c_str(), bWasFound); } + g_pSquirrel<context>->messageBuffer = new SquirrelMessageBuffer(); } template <ScriptContext context> void SquirrelManager<context>::VMDestroyed() @@ -196,7 +219,7 @@ template <ScriptContext context> void SquirrelManager<context>::ExecuteCode(cons if (compileResult != SQRESULT_ERROR) { pushroottable(m_pSQVM->sqvm); - SQRESULT callResult = call(m_pSQVM->sqvm, 0); + SQRESULT callResult = _call(m_pSQVM->sqvm, 0); spdlog::info("sq_call returned {}", PrintSQRESULT.at(callResult)); } } @@ -304,7 +327,10 @@ template <ScriptContext context> void __fastcall DestroyVMHook(void* a1, HSquirr g_pSquirrel<ScriptContext::UI>->VMDestroyed(); } else + { + g_pSquirrel<context>->m_pSQVM = nullptr; // Fixes a race-like bug DestroyVM<context>(a1, sqvm); + } spdlog::info("DestroyVM {} {}", GetContextName(realContext), (void*)sqvm); } @@ -482,6 +508,44 @@ template <ScriptContext context> void StubUnsafeSQFuncs() } } +template <ScriptContext context> void SquirrelManager<context>::ProcessMessageBuffer() +{ + auto maybeMessage = messageBuffer->pop(); + if (!maybeMessage) + { + return; + } + + SquirrelMessage message = maybeMessage.value(); + + SQObject functionobj {}; + int result = sq_getfunction(m_pSQVM->sqvm, message.functionName.c_str(), &functionobj, 0); + if (result != 0) // This func returns 0 on success for some reason + { + spdlog::error( + "ProcessMessageBuffer was unable to find function with name '{}' on {}. Is it global?", + message.functionName, + GetContextName(context)); + return; + } + pushobject(m_pSQVM->sqvm, &functionobj); // Push the function object + pushroottable(m_pSQVM->sqvm); + if (message.isExternal) + { + message.externalFunc(m_pSQVM->sqvm); + } + else + { + for (auto& v : message.args) + { + // Execute lambda to push arg to stack + v(); + } + } + + _call(m_pSQVM->sqvm, message.args.size()); +} + ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) { AUTOHOOK_DISPATCH_MODULE(client.dll) @@ -516,6 +580,7 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::CLIENT>->__sq_pushbool = module.Offset(0x3710).As<sq_pushboolType>(); g_pSquirrel<ScriptContext::CLIENT>->__sq_pushasset = module.Offset(0x3560).As<sq_pushassetType>(); g_pSquirrel<ScriptContext::CLIENT>->__sq_pushvector = module.Offset(0x3780).As<sq_pushvectorType>(); + g_pSquirrel<ScriptContext::CLIENT>->__sq_pushobject = module.Offset(0x83D0).As<sq_pushobjectType>(); g_pSquirrel<ScriptContext::CLIENT>->__sq_raiseerror = module.Offset(0x8470).As<sq_raiseerrorType>(); g_pSquirrel<ScriptContext::UI>->__sq_pushstring = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushstring; g_pSquirrel<ScriptContext::UI>->__sq_pushinteger = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushinteger; @@ -523,6 +588,7 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::UI>->__sq_pushbool = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushbool; g_pSquirrel<ScriptContext::UI>->__sq_pushvector = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushvector; g_pSquirrel<ScriptContext::UI>->__sq_pushasset = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushasset; + g_pSquirrel<ScriptContext::UI>->__sq_pushobject = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushobject; g_pSquirrel<ScriptContext::UI>->__sq_raiseerror = g_pSquirrel<ScriptContext::CLIENT>->__sq_raiseerror; g_pSquirrel<ScriptContext::CLIENT>->__sq_getstring = module.Offset(0x60C0).As<sq_getstringType>(); @@ -533,8 +599,6 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::CLIENT>->__sq_getasset = module.Offset(0x6010).As<sq_getassetType>(); g_pSquirrel<ScriptContext::CLIENT>->__sq_getuserdata = module.Offset(0x63D0).As<sq_getuserdataType>(); g_pSquirrel<ScriptContext::CLIENT>->__sq_getvector = module.Offset(0x6140).As<sq_getvectorType>(); - g_pSquirrel<ScriptContext::CLIENT>->__sq_getthisentity = module.Offset(0x12F80).As<sq_getthisentityType>(); - g_pSquirrel<ScriptContext::CLIENT>->__sq_getobject = module.Offset(0x6160).As<sq_getobjectType>(); g_pSquirrel<ScriptContext::UI>->__sq_getstring = g_pSquirrel<ScriptContext::CLIENT>->__sq_getstring; g_pSquirrel<ScriptContext::UI>->__sq_getinteger = g_pSquirrel<ScriptContext::CLIENT>->__sq_getinteger; g_pSquirrel<ScriptContext::UI>->__sq_getfloat = g_pSquirrel<ScriptContext::CLIENT>->__sq_getfloat; @@ -557,6 +621,11 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::CLIENT>->__sq_GetEntityConstant_CBaseEntity; g_pSquirrel<ScriptContext::UI>->__sq_getentityfrominstance = g_pSquirrel<ScriptContext::CLIENT>->__sq_getentityfrominstance; + // Message buffer stuff + g_pSquirrel<ScriptContext::UI>->messageBuffer = g_pSquirrel<ScriptContext::CLIENT>->messageBuffer; + g_pSquirrel<ScriptContext::CLIENT>->__sq_getfunction = module.Offset(0x572FB0).As<sq_getfunctionType>(); + g_pSquirrel<ScriptContext::UI>->__sq_getfunction = g_pSquirrel<ScriptContext::CLIENT>->__sq_getfunction; + MAKEHOOK( module.Offset(0x108E0), &RegisterSquirrelFunctionHook<ScriptContext::CLIENT>, @@ -585,6 +654,9 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) StubUnsafeSQFuncs<ScriptContext::CLIENT>(); StubUnsafeSQFuncs<ScriptContext::UI>(); + + g_pSquirrel<ScriptContext::CLIENT>->__sq_getfunction = module.Offset(0x6CB0).As<sq_getfunctionType>(); + g_pSquirrel<ScriptContext::UI>->__sq_getfunction = g_pSquirrel<ScriptContext::CLIENT>->__sq_getfunction; } ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) @@ -611,6 +683,8 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::SERVER>->__sq_pushbool = module.Offset(0x3710).As<sq_pushboolType>(); g_pSquirrel<ScriptContext::SERVER>->__sq_pushasset = module.Offset(0x3560).As<sq_pushassetType>(); g_pSquirrel<ScriptContext::SERVER>->__sq_pushvector = module.Offset(0x3780).As<sq_pushvectorType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_pushobject = module.Offset(0x83A0).As<sq_pushobjectType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_raiseerror = module.Offset(0x8440).As<sq_raiseerrorType>(); g_pSquirrel<ScriptContext::SERVER>->__sq_getstring = module.Offset(0x60A0).As<sq_getstringType>(); @@ -621,6 +695,7 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::SERVER>->__sq_getuserdata = module.Offset(0x63B0).As<sq_getuserdataType>(); g_pSquirrel<ScriptContext::SERVER>->__sq_getvector = module.Offset(0x6120).As<sq_getvectorType>(); g_pSquirrel<ScriptContext::SERVER>->__sq_get = module.Offset(0x7C00).As<sq_getType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_getthisentity = module.Offset(0x203B0).As<sq_getthisentityType>(); g_pSquirrel<ScriptContext::SERVER>->__sq_getobject = module.Offset(0x6140).As<sq_getobjectType>(); @@ -631,6 +706,8 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::SERVER>->__sq_getentityfrominstance = module.Offset(0x1E920).As<sq_getentityfrominstanceType>(); g_pSquirrel<ScriptContext::SERVER>->logger = NS::log::SCRIPT_SV; + // Message buffer stuff + g_pSquirrel<ScriptContext::SERVER>->__sq_getfunction = module.Offset(0x6C85).As<sq_getfunctionType>(); MAKEHOOK( module.Offset(0x1DD10), |