aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/squirrel.cpp
diff options
context:
space:
mode:
authorEmma Miler <emma.pi@protonmail.com>2022-11-21 00:38:42 +0100
committerGitHub <noreply@github.com>2022-11-20 23:38:42 +0000
commit9e469ac28b610ecb8bce3e6c279660fae78861cf (patch)
tree57274f3be03cb160e42af7ed939274a2a028dbf0 /NorthstarDLL/squirrel.cpp
parent70b71ba3d3ad7121c6aabe55271542f55abe4008 (diff)
downloadNorthstarLauncher-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.cpp83
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),