diff options
author | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2021-07-21 00:51:32 +0100 |
---|---|---|
committer | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2021-07-21 00:51:32 +0100 |
commit | 93fe64e04ed766727634e5b5f6906f6461a70711 (patch) | |
tree | 467f58533ddf4c139f896166894bde8213fd34c8 /NorthstarDedicatedTest/squirrel.cpp | |
parent | 958d03d2817e312c8eb70234f1c65e4bcbded716 (diff) | |
download | NorthstarLauncher-93fe64e04ed766727634e5b5f6906f6461a70711.tar.gz NorthstarLauncher-93fe64e04ed766727634e5b5f6906f6461a70711.zip |
add eval commands and script compile error hook
Diffstat (limited to 'NorthstarDedicatedTest/squirrel.cpp')
-rw-r--r-- | NorthstarDedicatedTest/squirrel.cpp | 130 |
1 files changed, 106 insertions, 24 deletions
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp index 90d16e89..27b997ab 100644 --- a/NorthstarDedicatedTest/squirrel.cpp +++ b/NorthstarDedicatedTest/squirrel.cpp @@ -3,6 +3,7 @@ #include "hooks.h" #include "hookutils.h" #include "sigscanning.h" +#include "concommand.h" #include <iostream> // hook forward declarations @@ -12,10 +13,31 @@ SQPrintType UISQPrint; SQPrintType ServerSQPrint; template<Context context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...); -typedef void* (*CreateNewVMType)(void* a1, Context contextArg); +typedef void*(*CreateNewVMType)(void* a1, Context contextArg); CreateNewVMType ClientCreateNewVM; // only need a client one since ui doesn't have its own func for this CreateNewVMType ServerCreateNewVM; -void* CreateNewVMHook(void* a1, Context contextArg); +template<Context context> void* CreateNewVMHook(void* a1, Context contextArg); + +typedef void(*DestroyVMType)(void* a1, void* sqvm); +DestroyVMType ClientDestroyVM; // only need a client one since ui doesn't have its own func for this +DestroyVMType ServerDestroyVM; +template<Context context> void DestroyVMHook(void* a1, void* sqvm); + +typedef void (*SQCompileErrorType)(void* sqvm, const char* error, const char* file, int line, int column); +SQCompileErrorType ClientSQCompileError; // only need a client one since ui doesn't have its own func for this +SQCompileErrorType ServerSQCompileError; +template<Context context> void SQCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column); + +sq_compilebufferType ClientSq_compilebuffer; +sq_compilebufferType ServerSq_compilebuffer; + +sq_pushroottableType ClientSq_pushroottable; +sq_pushroottableType ServerSq_pushroottable; + +sq_callType ClientSq_call; +sq_callType ServerSq_call; + +template<Context context> void ExecuteCodeCommand(const CCommand& args); // inits SquirrelManager<CLIENT>* g_ClientSquirrelManager; @@ -29,13 +51,21 @@ void InitialiseClientSquirrel(HMODULE baseAddress) // client inits g_ClientSquirrelManager = new SquirrelManager<CLIENT>(); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x12B00, &SQPrintHook<CLIENT>, reinterpret_cast<LPVOID*>(&ClientSQPrint)); // client print function + RegisterConCommand("script_client", ExecuteCodeCommand<CLIENT>, "Executes script code in the client vm", FCVAR_CLIENTDLL); // ui inits g_UISquirrelManager = new SquirrelManager<UI>(); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x12BA0, &SQPrintHook<UI>, reinterpret_cast<LPVOID*>(&UISQPrint)); // ui print function + RegisterConCommand("script_ui", ExecuteCodeCommand<UI>, "Executes script code in the client vm", FCVAR_CLIENTDLL); + + // inits for both client and ui, since they share some functions + ClientSq_compilebuffer = (sq_compilebufferType)((char*)baseAddress + 0x3110); + ClientSq_pushroottable = (sq_pushroottableType)((char*)baseAddress + 0x5860); + ClientSq_call = (sq_callType)((char*)baseAddress + 0x8650); - // hooks for both client and ui, since they share some functions - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26130, &CreateNewVMHook, reinterpret_cast<LPVOID*>(&ClientCreateNewVM)); // client createnewvm function + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26130, &CreateNewVMHook<CLIENT>, reinterpret_cast<LPVOID*>(&ClientCreateNewVM)); // client createnewvm function + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26E70, &DestroyVMHook<CLIENT>, reinterpret_cast<LPVOID*>(&ClientDestroyVM)); // client destroyvm function + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x79A50, &SQCompileErrorHook<CLIENT>, reinterpret_cast<LPVOID*>(&ClientSQCompileError)); // client compileerror function } void InitialiseServerSquirrel(HMODULE baseAddress) @@ -43,8 +73,17 @@ void InitialiseServerSquirrel(HMODULE baseAddress) g_ServerSquirrelManager = new SquirrelManager<SERVER>(); HookEnabler hook; + + ServerSq_compilebuffer = (sq_compilebufferType)((char*)baseAddress + 0x3110); + ServerSq_pushroottable = (sq_pushroottableType)((char*)baseAddress + 0x5840); + ServerSq_call = (sq_callType)((char*)baseAddress + 0x8620); + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1FE90, &SQPrintHook<SERVER>, reinterpret_cast<LPVOID*>(&ServerSQPrint)); // server print function - ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x260E0, &CreateNewVMHook, reinterpret_cast<LPVOID*>(&ServerCreateNewVM)); // server createnewvm function + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x260E0, &CreateNewVMHook<SERVER>, reinterpret_cast<LPVOID*>(&ServerCreateNewVM)); // server createnewvm function + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x26E20, &DestroyVMHook<SERVER>, reinterpret_cast<LPVOID*>(&ServerDestroyVM)); // server destroyvm function + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x799E0, &SQCompileErrorHook<SERVER>, reinterpret_cast<LPVOID*>(&ServerSQCompileError)); // server compileerror function + + RegisterConCommand("script", ExecuteCodeCommand<SERVER>, "Executes script code in the server vm", FCVAR_GAMEDLL); } // hooks @@ -59,7 +98,7 @@ template<Context context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...) if (charsWritten > 0) { if (buf[charsWritten - 1] == '\n') - buf[charsWritten - 1] == '\0'; + buf[charsWritten - 1] = '\0'; spdlog::info("[{} SCRIPT] {}", GetContextName(context), buf); } @@ -68,35 +107,78 @@ template<Context context> SQInteger SQPrintHook(void* sqvm, char* fmt, ...) return 0; } -void* CreateNewVMHook(void* a1, Context context) -{ - spdlog::info("CreateNewVM {}", GetContextName(context)); - +template<Context context> void* CreateNewVMHook(void* a1, Context realContext) +{ + void* sqvm; + if (context == CLIENT) { - void* sqvm = ClientCreateNewVM(a1, context); - g_ClientSquirrelManager->sqvm = sqvm; + sqvm = ClientCreateNewVM(a1, realContext); - return sqvm; + if (realContext == UI) + g_UISquirrelManager->sqvm = sqvm; + else + g_ClientSquirrelManager->sqvm = sqvm; } - else if (context == UI) + else if (context == SERVER) { - void* sqvm = ClientCreateNewVM(a1, context); - g_UISquirrelManager->sqvm = sqvm; + sqvm = ServerCreateNewVM(a1, context); + g_ServerSquirrelManager->sqvm = sqvm; + } + + spdlog::info("CreateNewVM {} {}", GetContextName(context), sqvm); + return sqvm; +} + +template<Context context> void DestroyVMHook(void* a1, void* sqvm) +{ + Context realContext = context; // ui and client use the same function so we use this for prints - return sqvm; + if (context == CLIENT) + { + if (g_ClientSquirrelManager->sqvm == sqvm) + g_ClientSquirrelManager->sqvm = nullptr; + else if (g_UISquirrelManager->sqvm == sqvm) + { + g_UISquirrelManager->sqvm = nullptr; + realContext == UI; + } + + ClientDestroyVM(a1, sqvm); } else if (context == SERVER) { - void* sqvm = ServerCreateNewVM(a1, context); - g_ServerSquirrelManager->sqvm = sqvm; - - return sqvm; + g_ServerSquirrelManager->sqvm = nullptr; + ServerDestroyVM(a1, sqvm); } + + spdlog::info("DestroyVM {} {}", GetContextName(realContext), sqvm); } -// manager -template<Context context> SquirrelManager<context>::SquirrelManager() : sqvm(nullptr) +template<Context context> void SQCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column) { - + // note: i think vanilla might actually show the script line that errored, might be nice to implement that if it's a thing + // look into client.dll+79540 for way better errors too + + Context realContext = context; + if (context == CLIENT && sqvm == g_UISquirrelManager->sqvm) + realContext = UI; + + spdlog::error("{} SCRIPT COMPILE ERROR {}", GetContextName(realContext), error); + spdlog::error("{} line [{}] column [{}]", file, line, column); + + // dont call the original since it kills game + // in the future it'd be nice to do an actual error with UICodeCallback_ErrorDialog here, but only if we're compiling level scripts + // compilestring and stuff shouldn't tho + // though, that also has potential to be REALLY bad if we're compiling ui scripts lol +} + +template<Context context> void ExecuteCodeCommand(const CCommand& args) +{ + if (context == CLIENT) + g_ClientSquirrelManager->ExecuteCode(args.ArgS()); + else if (context == UI) + g_UISquirrelManager->ExecuteCode(args.ArgS()); + else if (context == SERVER) + g_ServerSquirrelManager->ExecuteCode(args.ArgS()); }
\ No newline at end of file |