From f5ab6fb5e8be7b73e6003d4145081d5e0c0ce287 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Wed, 27 Dec 2023 00:32:01 +0000 Subject: Folder restructuring from primedev (#624) Copies of over the primedev folder structure for easier cherry-picking of further changes Co-authored-by: F1F7Y --- NorthstarDLL/squirrel/squirrel.cpp | 943 ------------------------------------- 1 file changed, 943 deletions(-) delete mode 100644 NorthstarDLL/squirrel/squirrel.cpp (limited to 'NorthstarDLL/squirrel/squirrel.cpp') diff --git a/NorthstarDLL/squirrel/squirrel.cpp b/NorthstarDLL/squirrel/squirrel.cpp deleted file mode 100644 index ac9a2ce9..00000000 --- a/NorthstarDLL/squirrel/squirrel.cpp +++ /dev/null @@ -1,943 +0,0 @@ -#include "squirrel.h" -#include "mods/modsavefiles.h" -#include "logging/logging.h" -#include "core/convar/concommand.h" -#include "mods/modmanager.h" -#include "dedicated/dedicated.h" -#include "engine/r2engine.h" -#include "core/tier0.h" -#include "plugins/plugin_abi.h" -#include "plugins/plugins.h" -#include "ns_version.h" -#include "core/vanilla.h" - -#include - -AUTOHOOK_INIT() - -std::shared_ptr getSquirrelLoggerByContext(ScriptContext context) -{ - switch (context) - { - case ScriptContext::UI: - return NS::log::SCRIPT_UI; - case ScriptContext::CLIENT: - return NS::log::SCRIPT_CL; - case ScriptContext::SERVER: - return NS::log::SCRIPT_SV; - default: - throw std::runtime_error("getSquirrelLoggerByContext called with invalid context"); - return nullptr; - } -} - -namespace NS::log -{ - template std::shared_ptr squirrel_logger() - { - // Switch statements can't be constexpr afaik - // clang-format off - if constexpr (context == ScriptContext::UI) { return SCRIPT_UI; } - if constexpr (context == ScriptContext::CLIENT) { return SCRIPT_CL; } - if constexpr (context == ScriptContext::SERVER) { return SCRIPT_SV; } - // clang-format on - } -}; // namespace NS::log - -const char* GetContextName(ScriptContext context) -{ - switch (context) - { - case ScriptContext::CLIENT: - return "CLIENT"; - case ScriptContext::SERVER: - return "SERVER"; - case ScriptContext::UI: - return "UI"; - default: - return "UNKNOWN"; - } -} - -const char* GetContextName_Short(ScriptContext context) -{ - switch (context) - { - case ScriptContext::CLIENT: - return "CL"; - case ScriptContext::SERVER: - return "SV"; - case ScriptContext::UI: - return "UI"; - default: - return "??"; - } -} - -eSQReturnType SQReturnTypeFromString(const char* pReturnType) -{ - static const std::map sqReturnTypeNameToString = { - {"bool", eSQReturnType::Boolean}, - {"float", eSQReturnType::Float}, - {"vector", eSQReturnType::Vector}, - {"int", eSQReturnType::Integer}, - {"entity", eSQReturnType::Entity}, - {"string", eSQReturnType::String}, - {"array", eSQReturnType::Arrays}, - {"asset", eSQReturnType::Asset}, - {"table", eSQReturnType::Table}}; - - if (sqReturnTypeNameToString.find(pReturnType) != sqReturnTypeNameToString.end()) - return sqReturnTypeNameToString.at(pReturnType); - else - return eSQReturnType::Default; // previous default value -} - -ScriptContext ScriptContextFromString(std::string string) -{ - if (string == "UI") - return ScriptContext::UI; - if (string == "CLIENT") - return ScriptContext::CLIENT; - if (string == "SERVER") - return ScriptContext::SERVER; - else - return ScriptContext::INVALID; -} - -const char* SQTypeNameFromID(int type) -{ - switch (type) - { - case OT_ASSET: - return "asset"; - case OT_INTEGER: - return "int"; - case OT_BOOL: - return "bool"; - case SQOBJECT_NUMERIC: - return "float or int"; - case OT_NULL: - return "null"; - case OT_VECTOR: - return "vector"; - case 0: - return "var"; - case OT_USERDATA: - return "userdata"; - case OT_FLOAT: - return "float"; - case OT_STRING: - return "string"; - case OT_ARRAY: - return "array"; - case 0x8000200: - return "function"; - case 0x8100000: - return "structdef"; - case OT_THREAD: - return "thread"; - case OT_FUNCPROTO: - return "function"; - case OT_CLAAS: - return "class"; - case OT_WEAKREF: - return "weakref"; - case 0x8080000: - return "unimplemented function"; - case 0x8200000: - return "struct instance"; - case OT_TABLE: - return "table"; - case 0xA008000: - return "instance"; - case OT_ENTITY: - return "entity"; - } - return ""; -} - -template void SquirrelManager::GenerateSquirrelFunctionsStruct(SquirrelFunctions* s) -{ - s->RegisterSquirrelFunc = RegisterSquirrelFunc; - s->__sq_defconst = __sq_defconst; - - s->__sq_compilebuffer = __sq_compilebuffer; - s->__sq_call = __sq_call; - s->__sq_raiseerror = __sq_raiseerror; - s->__sq_compilefile = __sq_compilefile; - - s->__sq_newarray = __sq_newarray; - s->__sq_arrayappend = __sq_arrayappend; - - s->__sq_newtable = __sq_newtable; - s->__sq_newslot = __sq_newslot; - - s->__sq_pushroottable = __sq_pushroottable; - s->__sq_pushstring = __sq_pushstring; - s->__sq_pushinteger = __sq_pushinteger; - s->__sq_pushfloat = __sq_pushfloat; - s->__sq_pushbool = __sq_pushbool; - s->__sq_pushasset = __sq_pushasset; - s->__sq_pushvector = __sq_pushvector; - s->__sq_pushobject = __sq_pushobject; - - s->__sq_getstring = __sq_getstring; - s->__sq_getinteger = __sq_getinteger; - s->__sq_getfloat = __sq_getfloat; - s->__sq_getbool = __sq_getbool; - s->__sq_get = __sq_get; - s->__sq_getasset = __sq_getasset; - s->__sq_getuserdata = __sq_getuserdata; - s->__sq_getvector = __sq_getvector; - s->__sq_getthisentity = __sq_getthisentity; - s->__sq_getobject = __sq_getobject; - - s->__sq_stackinfos = __sq_stackinfos; - - s->__sq_createuserdata = __sq_createuserdata; - s->__sq_setuserdatatypeid = __sq_setuserdatatypeid; - s->__sq_getfunction = __sq_getfunction; - - s->__sq_schedule_call_external = AsyncCall_External; - - s->__sq_getentityfrominstance = __sq_getentityfrominstance; - s->__sq_GetEntityConstant_CBaseEntity = __sq_GetEntityConstant_CBaseEntity; - - s->__sq_pushnewstructinstance = __sq_pushnewstructinstance; - s->__sq_sealstructslot = __sq_sealstructslot; -} - -// Allows for generating squirrelmessages from plugins. -void AsyncCall_External(ScriptContext context, const char* func_name, SquirrelMessage_External_Pop function, void* userdata) -{ - SquirrelMessage message {}; - message.functionName = func_name; - message.isExternal = true; - message.externalFunc = function; - message.userdata = userdata; - switch (context) - { - case ScriptContext::CLIENT: - g_pSquirrel->messageBuffer->push(message); - break; - case ScriptContext::SERVER: - g_pSquirrel->messageBuffer->push(message); - break; - case ScriptContext::UI: - g_pSquirrel->messageBuffer->push(message); - break; - } -} - -// needed to define implementations for squirrelmanager outside of squirrel.h without compiler errors -template class SquirrelManager; -template class SquirrelManager; -template class SquirrelManager; - -template void SquirrelManager::VMCreated(CSquirrelVM* newSqvm) -{ - m_pSQVM = newSqvm; - - for (SQFuncRegistration* funcReg : m_funcRegistrations) - { - spdlog::info("Registering {} function {}", GetContextName(context), funcReg->squirrelFuncName); - RegisterSquirrelFunc(m_pSQVM, funcReg, 1); - } - - for (auto& pair : g_pModManager->m_DependencyConstants) - { - bool bWasFound = false; - - for (Mod& dependency : g_pModManager->m_LoadedMods) - { - if (!dependency.m_bEnabled) - continue; - - if (dependency.Name == pair.second) - { - bWasFound = true; - break; - } - } - - defconst(m_pSQVM, pair.first.c_str(), bWasFound); - } - - auto loadedPlugins = &g_pPluginManager->m_vLoadedPlugins; - for (const auto& pluginName : g_pModManager->m_PluginDependencyConstants) - { - auto f = [&](Plugin plugin) -> bool { return plugin.dependencyName == pluginName; }; - defconst(m_pSQVM, pluginName.c_str(), std::find_if(loadedPlugins->begin(), loadedPlugins->end(), f) != loadedPlugins->end()); - } - - defconst(m_pSQVM, "MAX_FOLDER_SIZE", GetMaxSaveFolderSize() / 1024); - - // define squirrel constants for northstar(.dll) version - constexpr int version[4] {NORTHSTAR_VERSION}; - defconst(m_pSQVM, "NS_VERSION_MAJOR", version[0]); - defconst(m_pSQVM, "NS_VERSION_MINOR", version[1]); - defconst(m_pSQVM, "NS_VERSION_PATCH", version[2]); - defconst(m_pSQVM, "NS_VERSION_DEV", version[3]); - - // define squirrel constant for if we are in vanilla-compatibility mode - defconst(m_pSQVM, "VANILLA", g_pVanillaCompatibility->GetVanillaCompatibility()); - - g_pSquirrel->messageBuffer = new SquirrelMessageBuffer(); - g_pPluginManager->InformSQVMCreated(context, newSqvm); -} - -template void SquirrelManager::VMDestroyed() -{ - // Call all registered mod Destroy callbacks. - if (g_pModManager) - { - NS::log::squirrel_logger()->info("Calling Destroy callbacks for all loaded mods."); - - for (const Mod& loadedMod : g_pModManager->m_LoadedMods) - { - for (const ModScript& script : loadedMod.Scripts) - { - for (const ModScriptCallback& callback : script.Callbacks) - { - if (callback.Context != context || callback.DestroyCallback.length() == 0) - { - continue; - } - - Call(callback.DestroyCallback.c_str()); - NS::log::squirrel_logger()->info("Executed Destroy callback {}.", callback.DestroyCallback); - } - } - } - } - - g_pPluginManager->InformSQVMDestroyed(context); - - // Discard the previous vm and delete the message buffer. - m_pSQVM = nullptr; - - delete g_pSquirrel->messageBuffer; - g_pSquirrel->messageBuffer = nullptr; -} - -template void SquirrelManager::ExecuteCode(const char* pCode) -{ - if (!m_pSQVM || !m_pSQVM->sqvm) - { - spdlog::error("Cannot execute code, {} squirrel vm is not initialised", GetContextName(context)); - return; - } - - spdlog::info("Executing {} script code {} ", GetContextName(context), pCode); - - std::string strCode(pCode); - CompileBufferState bufferState = CompileBufferState(strCode); - - SQRESULT compileResult = compilebuffer(&bufferState, "console"); - spdlog::info("sq_compilebuffer returned {}", PrintSQRESULT.at(compileResult)); - - if (compileResult != SQRESULT_ERROR) - { - pushroottable(m_pSQVM->sqvm); - SQRESULT callResult = _call(m_pSQVM->sqvm, 0); - spdlog::info("sq_call returned {}", PrintSQRESULT.at(callResult)); - } -} - -template void SquirrelManager::AddFuncRegistration( - std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func) -{ - SQFuncRegistration* reg = new SQFuncRegistration; - - reg->squirrelFuncName = new char[name.size() + 1]; - strcpy((char*)reg->squirrelFuncName, name.c_str()); - reg->cppFuncName = reg->squirrelFuncName; - - reg->helpText = new char[helpText.size() + 1]; - strcpy((char*)reg->helpText, helpText.c_str()); - - reg->returnTypeString = new char[returnType.size() + 1]; - strcpy((char*)reg->returnTypeString, returnType.c_str()); - reg->returnType = SQReturnTypeFromString(returnType.c_str()); - - reg->argTypes = new char[argTypes.size() + 1]; - strcpy((char*)reg->argTypes, argTypes.c_str()); - - reg->funcPtr = func; - - m_funcRegistrations.push_back(reg); -} - -template SQRESULT SquirrelManager::setupfunc(const SQChar* funcname) -{ - pushroottable(m_pSQVM->sqvm); - pushstring(m_pSQVM->sqvm, funcname, -1); - - SQRESULT result = get(m_pSQVM->sqvm, -2); - if (result != SQRESULT_ERROR) - pushroottable(m_pSQVM->sqvm); - - return result; -} - -template void SquirrelManager::AddFuncOverride(std::string name, SQFunction func) -{ - m_funcOverrides[name] = func; -} - -// hooks -bool IsUIVM(ScriptContext context, HSquirrelVM* pSqvm) -{ - return ScriptContext(pSqvm->sharedState->cSquirrelVM->vmContext) == ScriptContext::UI; -} - -template void* (*sq_compiler_create)(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError); -template void* __fastcall sq_compiler_createHook(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError) -{ - // store whether errors generated from this compile should be fatal - if (IsUIVM(context, sqvm)) - g_pSquirrel->m_bFatalCompilationErrors = bShouldThrowError; - else - g_pSquirrel->m_bFatalCompilationErrors = bShouldThrowError; - - return sq_compiler_create(sqvm, a2, a3, bShouldThrowError); -} - -template SQInteger (*SQPrint)(HSquirrelVM* sqvm, const char* fmt); -template SQInteger SQPrintHook(HSquirrelVM* sqvm, const char* fmt, ...) -{ - va_list va; - va_start(va, fmt); - - SQChar buf[1024]; - int charsWritten = vsnprintf_s(buf, _TRUNCATE, fmt, va); - - if (charsWritten > 0) - { - if (buf[charsWritten - 1] == '\n') - buf[charsWritten - 1] = '\0'; - g_pSquirrel->logger->info("{}", buf); - } - - va_end(va); - return 0; -} - -template CSquirrelVM* (*CreateNewVM)(void* a1, ScriptContext realContext); -template CSquirrelVM* __fastcall CreateNewVMHook(void* a1, ScriptContext realContext) -{ - CSquirrelVM* sqvm = CreateNewVM(a1, realContext); - if (realContext == ScriptContext::UI) - g_pSquirrel->VMCreated(sqvm); - else - g_pSquirrel->VMCreated(sqvm); - - spdlog::info("CreateNewVM {} {}", GetContextName(realContext), (void*)sqvm); - return sqvm; -} - -template bool (*CSquirrelVM_init)(CSquirrelVM* vm, ScriptContext realContext, float time); -template bool __fastcall CSquirrelVM_initHook(CSquirrelVM* vm, ScriptContext realContext, float time) -{ - bool ret = CSquirrelVM_init(vm, realContext, time); - for (Mod mod : g_pModManager->m_LoadedMods) - { - if (mod.m_bEnabled && mod.initScript.size() != 0) - { - std::string name = mod.initScript.substr(mod.initScript.find_last_of('/') + 1); - std::string path = std::string("scripts/vscripts/") + mod.initScript; - if (g_pSquirrel->compilefile(vm, path.c_str(), name.c_str(), 0)) - g_pSquirrel->compilefile(vm, path.c_str(), name.c_str(), 1); - } - } - return ret; -} - -template void (*DestroyVM)(void* a1, CSquirrelVM* sqvm); -template void __fastcall DestroyVMHook(void* a1, CSquirrelVM* sqvm) -{ - ScriptContext realContext = context; // ui and client use the same function so we use this for prints - if (IsUIVM(context, sqvm->sqvm)) - { - realContext = ScriptContext::UI; - g_pSquirrel->VMDestroyed(); - DestroyVM(a1, sqvm); // If we pass UI here it crashes - } - else - { - g_pSquirrel->VMDestroyed(); - DestroyVM(a1, sqvm); - } - - spdlog::info("DestroyVM {} {}", GetContextName(realContext), (void*)sqvm); -} - -template void (*SQCompileError)(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column); -template -void __fastcall ScriptCompileErrorHook(HSquirrelVM* sqvm, const char* error, const char* file, int line, int column) -{ - bool bIsFatalError = g_pSquirrel->m_bFatalCompilationErrors; - ScriptContext realContext = context; // ui and client use the same function so we use this for prints - if (IsUIVM(context, sqvm)) - { - realContext = ScriptContext::UI; - bIsFatalError = g_pSquirrel->m_bFatalCompilationErrors; - } - - auto logger = getSquirrelLoggerByContext(realContext); - - logger->error("COMPILE ERROR {}", error); - logger->error("{} line [{}] column [{}]", file, line, column); - - // use disconnect to display an error message for the compile error, but only if the compilation error was fatal - // todo, we could get this from sqvm itself probably, rather than hooking sq_compiler_create - if (bIsFatalError) - { - // kill dedicated server if we hit this - if (IsDedicatedServer()) - { - logger->error("Exiting dedicated server, compile error is fatal"); - // flush the logger before we exit so debug things get saved to log file - logger->flush(); - exit(EXIT_FAILURE); - } - else - { - Cbuf_AddText( - Cbuf_GetCurrentPlayer(), - fmt::format("disconnect \"Encountered {} script compilation error, see console for details.\"", GetContextName(realContext)) - .c_str(), - cmd_source_t::kCommandSrcCode); - - // likely temp: show console so user can see any errors, as error message wont display if ui is dead - // maybe we could disable all mods other than the coremods and try a reload before doing this? - // could also maybe do some vgui bullshit to show something visually rather than console - if (realContext == ScriptContext::UI) - Cbuf_AddText(Cbuf_GetCurrentPlayer(), "showconsole", cmd_source_t::kCommandSrcCode); - } - } - - // dont call the original function since it kills game lol -} - -template int64_t (*RegisterSquirrelFunction)(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown); -template -int64_t __fastcall RegisterSquirrelFunctionHook(CSquirrelVM* sqvm, SQFuncRegistration* funcReg, char unknown) -{ - if (IsUIVM(context, sqvm->sqvm)) - { - if (g_pSquirrel->m_funcOverrides.count(funcReg->squirrelFuncName)) - { - g_pSquirrel->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr; - funcReg->funcPtr = g_pSquirrel->m_funcOverrides[funcReg->squirrelFuncName]; - spdlog::info("Replacing {} in UI", std::string(funcReg->squirrelFuncName)); - } - - return g_pSquirrel->RegisterSquirrelFunc(sqvm, funcReg, unknown); - } - - if (g_pSquirrel->m_funcOverrides.find(funcReg->squirrelFuncName) != g_pSquirrel->m_funcOverrides.end()) - { - g_pSquirrel->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr; - funcReg->funcPtr = g_pSquirrel->m_funcOverrides[funcReg->squirrelFuncName]; - spdlog::info("Replacing {} in Client", std::string(funcReg->squirrelFuncName)); - } - - return g_pSquirrel->RegisterSquirrelFunc(sqvm, funcReg, unknown); -} - -template bool (*CallScriptInitCallback)(void* sqvm, const char* callback); -template bool __fastcall CallScriptInitCallbackHook(void* sqvm, const char* callback) -{ - ScriptContext realContext = context; - bool bShouldCallCustomCallbacks = true; - - if (context == ScriptContext::CLIENT) - { - if (!strcmp(callback, "UICodeCallback_UIInit")) - realContext = ScriptContext::UI; - else if (strcmp(callback, "ClientCodeCallback_MapSpawn")) - bShouldCallCustomCallbacks = false; - } - else if (context == ScriptContext::SERVER) - bShouldCallCustomCallbacks = !strcmp(callback, "CodeCallback_MapSpawn"); - - if (bShouldCallCustomCallbacks) - { - for (Mod mod : g_pModManager->m_LoadedMods) - { - if (!mod.m_bEnabled) - continue; - - for (ModScript script : mod.Scripts) - { - for (ModScriptCallback modCallback : script.Callbacks) - { - if (modCallback.Context == realContext && modCallback.BeforeCallback.length()) - { - spdlog::info("Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.BeforeCallback); - CallScriptInitCallback(sqvm, modCallback.BeforeCallback.c_str()); - } - } - } - } - } - - spdlog::info("{} CodeCallback {} called", GetContextName(realContext), callback); - if (!bShouldCallCustomCallbacks) - spdlog::info("Not executing custom callbacks for CodeCallback {}", callback); - bool ret = CallScriptInitCallback(sqvm, callback); - - // run after callbacks - if (bShouldCallCustomCallbacks) - { - for (Mod mod : g_pModManager->m_LoadedMods) - { - if (!mod.m_bEnabled) - continue; - - for (ModScript script : mod.Scripts) - { - for (ModScriptCallback modCallback : script.Callbacks) - { - if (modCallback.Context == realContext && modCallback.AfterCallback.length()) - { - spdlog::info("Running custom {} script callback \"{}\"", GetContextName(realContext), modCallback.AfterCallback); - CallScriptInitCallback(sqvm, modCallback.AfterCallback.c_str()); - } - } - } - } - } - - return ret; -} - -template void ConCommand_script(const CCommand& args) -{ - g_pSquirrel->ExecuteCode(args.ArgS()); -} - -// literal class type that wraps a constant expression string -template struct TemplateStringLiteral -{ - constexpr TemplateStringLiteral(const char (&str)[N]) - { - std::copy_n(str, N, value); - } - - char value[N]; -}; - -template SQRESULT SQ_StubbedFunc(HSquirrelVM* sqvm) -{ - spdlog::info("Blocking call to stubbed function {} in {}", funcName.value, GetContextName(context)); - return SQRESULT_NULL; -} - -template void StubUnsafeSQFuncs() -{ - if (!CommandLine()->CheckParm("-allowunsafesqfuncs")) - { - g_pSquirrel->AddFuncOverride("DevTextBufferWrite", SQ_StubbedFunc); - g_pSquirrel->AddFuncOverride("DevTextBufferClear", SQ_StubbedFunc); - g_pSquirrel->AddFuncOverride("DevTextBufferDumpToFile", SQ_StubbedFunc); - g_pSquirrel->AddFuncOverride("Dev_CommandLineAddParam", SQ_StubbedFunc); - g_pSquirrel->AddFuncOverride("DevP4Checkout", SQ_StubbedFunc); - g_pSquirrel->AddFuncOverride("DevP4Add", SQ_StubbedFunc); - } -} - -template void SquirrelManager::ProcessMessageBuffer() -{ - while (std::optional maybeMessage = messageBuffer->pop()) - { - 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 - { - NS::log::squirrel_logger()->error( - "ProcessMessageBuffer was unable to find function with name '{}'. Is it global?", message.functionName); - continue; - } - - pushobject(m_pSQVM->sqvm, &functionobj); // Push the function object - pushroottable(m_pSQVM->sqvm); - - int argsAmount = message.args.size(); - - if (message.isExternal && message.externalFunc != NULL) - { - argsAmount = message.externalFunc(m_pSQVM->sqvm, message.userdata); - } - else - { - for (auto& v : message.args) - { - // Execute lambda to push arg to stack - v(); - } - } - - _call(m_pSQVM->sqvm, argsAmount); - } -} - -ADD_SQFUNC( - "string", - NSGetCurrentModName, - "", - "Returns the mod name of the script running this function", - ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) -{ - int depth = g_pSquirrel->getinteger(sqvm, 1); - if (auto mod = g_pSquirrel->getcallingmod(sqvm, depth); mod == nullptr) - { - g_pSquirrel->raiseerror(sqvm, "NSGetModName was called from a non-mod script. This shouldn't be possible"); - return SQRESULT_ERROR; - } - else - { - g_pSquirrel->pushstring(sqvm, mod->Name.c_str()); - } - return SQRESULT_NOTNULL; -} - -ADD_SQFUNC( - "string", - NSGetCallingModName, - "int depth = 0", - "Returns the mod name of the script running this function", - ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) -{ - int depth = g_pSquirrel->getinteger(sqvm, 1); - if (auto mod = g_pSquirrel->getcallingmod(sqvm, depth); mod == nullptr) - { - g_pSquirrel->pushstring(sqvm, "Unknown"); - } - else - { - g_pSquirrel->pushstring(sqvm, mod->Name.c_str()); - } - return SQRESULT_NOTNULL; -} - -ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) -{ - AUTOHOOK_DISPATCH_MODULE(client.dll) - - g_pSquirrel->__sq_defconst = module.Offset(0x12120).RCast(); - g_pSquirrel->__sq_defconst = g_pSquirrel->__sq_defconst; - - g_pSquirrel->__sq_compilebuffer = module.Offset(0x3110).RCast(); - g_pSquirrel->__sq_pushroottable = module.Offset(0x5860).RCast(); - g_pSquirrel->__sq_compilefile = module.Offset(0xF950).RCast(); - g_pSquirrel->__sq_compilebuffer = g_pSquirrel->__sq_compilebuffer; - g_pSquirrel->__sq_pushroottable = g_pSquirrel->__sq_pushroottable; - g_pSquirrel->__sq_compilefile = g_pSquirrel->__sq_compilefile; - - g_pSquirrel->__sq_call = module.Offset(0x8650).RCast(); - g_pSquirrel->__sq_call = g_pSquirrel->__sq_call; - - g_pSquirrel->__sq_newarray = module.Offset(0x39F0).RCast(); - g_pSquirrel->__sq_arrayappend = module.Offset(0x3C70).RCast(); - g_pSquirrel->__sq_newarray = g_pSquirrel->__sq_newarray; - g_pSquirrel->__sq_arrayappend = g_pSquirrel->__sq_arrayappend; - - g_pSquirrel->__sq_newtable = module.Offset(0x3960).RCast(); - g_pSquirrel->__sq_newslot = module.Offset(0x70B0).RCast(); - g_pSquirrel->__sq_newtable = g_pSquirrel->__sq_newtable; - g_pSquirrel->__sq_newslot = g_pSquirrel->__sq_newslot; - - g_pSquirrel->__sq_pushstring = module.Offset(0x3440).RCast(); - g_pSquirrel->__sq_pushinteger = module.Offset(0x36A0).RCast(); - g_pSquirrel->__sq_pushfloat = module.Offset(0x3800).RCast(); - g_pSquirrel->__sq_pushbool = module.Offset(0x3710).RCast(); - g_pSquirrel->__sq_pushasset = module.Offset(0x3560).RCast(); - g_pSquirrel->__sq_pushvector = module.Offset(0x3780).RCast(); - g_pSquirrel->__sq_pushobject = module.Offset(0x83D0).RCast(); - g_pSquirrel->__sq_raiseerror = module.Offset(0x8470).RCast(); - g_pSquirrel->__sq_pushstring = g_pSquirrel->__sq_pushstring; - g_pSquirrel->__sq_pushinteger = g_pSquirrel->__sq_pushinteger; - g_pSquirrel->__sq_pushfloat = g_pSquirrel->__sq_pushfloat; - g_pSquirrel->__sq_pushbool = g_pSquirrel->__sq_pushbool; - g_pSquirrel->__sq_pushvector = g_pSquirrel->__sq_pushvector; - g_pSquirrel->__sq_pushasset = g_pSquirrel->__sq_pushasset; - g_pSquirrel->__sq_pushobject = g_pSquirrel->__sq_pushobject; - g_pSquirrel->__sq_raiseerror = g_pSquirrel->__sq_raiseerror; - - g_pSquirrel->__sq_getstring = module.Offset(0x60C0).RCast(); - g_pSquirrel->__sq_getinteger = module.Offset(0x60E0).RCast(); - g_pSquirrel->__sq_getfloat = module.Offset(0x6100).RCast(); - g_pSquirrel->__sq_getbool = module.Offset(0x6130).RCast(); - g_pSquirrel->__sq_get = module.Offset(0x7C30).RCast(); - g_pSquirrel->__sq_getasset = module.Offset(0x6010).RCast(); - g_pSquirrel->__sq_getuserdata = module.Offset(0x63D0).RCast(); - g_pSquirrel->__sq_getvector = module.Offset(0x6140).RCast(); - g_pSquirrel->__sq_getthisentity = module.Offset(0x12F80).RCast(); - g_pSquirrel->__sq_getobject = module.Offset(0x6160).RCast(); - g_pSquirrel->__sq_getstring = g_pSquirrel->__sq_getstring; - g_pSquirrel->__sq_getinteger = g_pSquirrel->__sq_getinteger; - g_pSquirrel->__sq_getfloat = g_pSquirrel->__sq_getfloat; - g_pSquirrel->__sq_getbool = g_pSquirrel->__sq_getbool; - g_pSquirrel->__sq_get = g_pSquirrel->__sq_get; - g_pSquirrel->__sq_getasset = g_pSquirrel->__sq_getasset; - g_pSquirrel->__sq_getuserdata = g_pSquirrel->__sq_getuserdata; - g_pSquirrel->__sq_getvector = g_pSquirrel->__sq_getvector; - g_pSquirrel->__sq_getthisentity = g_pSquirrel->__sq_getthisentity; - g_pSquirrel->__sq_getobject = g_pSquirrel->__sq_getobject; - - g_pSquirrel->__sq_createuserdata = module.Offset(0x38D0).RCast(); - g_pSquirrel->__sq_setuserdatatypeid = module.Offset(0x6490).RCast(); - g_pSquirrel->__sq_createuserdata = g_pSquirrel->__sq_createuserdata; - g_pSquirrel->__sq_setuserdatatypeid = g_pSquirrel->__sq_setuserdatatypeid; - - g_pSquirrel->__sq_GetEntityConstant_CBaseEntity = module.Offset(0x3E49B0).RCast(); - g_pSquirrel->__sq_getentityfrominstance = module.Offset(0x114F0).RCast(); - g_pSquirrel->__sq_GetEntityConstant_CBaseEntity = - g_pSquirrel->__sq_GetEntityConstant_CBaseEntity; - g_pSquirrel->__sq_getentityfrominstance = g_pSquirrel->__sq_getentityfrominstance; - - // Message buffer stuff - g_pSquirrel->messageBuffer = g_pSquirrel->messageBuffer; - g_pSquirrel->__sq_getfunction = module.Offset(0x572FB0).RCast(); - g_pSquirrel->__sq_getfunction = g_pSquirrel->__sq_getfunction; - g_pSquirrel->__sq_stackinfos = module.Offset(0x35970).RCast(); - g_pSquirrel->__sq_stackinfos = g_pSquirrel->__sq_stackinfos; - - // Structs - g_pSquirrel->__sq_pushnewstructinstance = module.Offset(0x5400).RCast(); - g_pSquirrel->__sq_sealstructslot = module.Offset(0x5530).RCast(); - g_pSquirrel->__sq_pushnewstructinstance = g_pSquirrel->__sq_pushnewstructinstance; - g_pSquirrel->__sq_sealstructslot = g_pSquirrel->__sq_sealstructslot; - - MAKEHOOK( - module.Offset(0x108E0), - &RegisterSquirrelFunctionHook, - &g_pSquirrel->RegisterSquirrelFunc); - g_pSquirrel->RegisterSquirrelFunc = g_pSquirrel->RegisterSquirrelFunc; - - g_pSquirrel->logger = NS::log::SCRIPT_CL; - g_pSquirrel->logger = NS::log::SCRIPT_UI; - - // uiscript_reset concommand: don't loop forever if compilation fails - module.Offset(0x3C6E4C).NOP(6); - - MAKEHOOK(module.Offset(0x8AD0), &sq_compiler_createHook, &sq_compiler_create); - - MAKEHOOK(module.Offset(0x12B00), &SQPrintHook, &SQPrint); - MAKEHOOK(module.Offset(0x12BA0), &SQPrintHook, &SQPrint); - - MAKEHOOK(module.Offset(0x26130), &CreateNewVMHook, &CreateNewVM); - MAKEHOOK(module.Offset(0x26E70), &DestroyVMHook, &DestroyVM); - MAKEHOOK(module.Offset(0x79A50), &ScriptCompileErrorHook, &SQCompileError); - - MAKEHOOK(module.Offset(0x10190), &CallScriptInitCallbackHook, &CallScriptInitCallback); - - MAKEHOOK(module.Offset(0xE3B0), &CSquirrelVM_initHook, &CSquirrelVM_init); - - RegisterConCommand("script_client", ConCommand_script, "Executes script code on the client vm", FCVAR_CLIENTDLL); - RegisterConCommand("script_ui", ConCommand_script, "Executes script code on the ui vm", FCVAR_CLIENTDLL); - - StubUnsafeSQFuncs(); - StubUnsafeSQFuncs(); - - g_pSquirrel->__sq_getfunction = module.Offset(0x6CB0).RCast(); - g_pSquirrel->__sq_getfunction = g_pSquirrel->__sq_getfunction; - - SquirrelFunctions s = {}; - g_pSquirrel->GenerateSquirrelFunctionsStruct(&s); - g_pPluginManager->InformSQVMLoad(ScriptContext::CLIENT, &s); -} - -ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) -{ - AUTOHOOK_DISPATCH_MODULE(server.dll) - - g_pSquirrel->__sq_defconst = module.Offset(0x1F550).RCast(); - - g_pSquirrel->__sq_compilebuffer = module.Offset(0x3110).RCast(); - g_pSquirrel->__sq_pushroottable = module.Offset(0x5840).RCast(); - g_pSquirrel->__sq_call = module.Offset(0x8620).RCast(); - g_pSquirrel->__sq_compilefile = module.Offset(0x1CD80).RCast(); - - g_pSquirrel->__sq_newarray = module.Offset(0x39F0).RCast(); - g_pSquirrel->__sq_arrayappend = module.Offset(0x3C70).RCast(); - - g_pSquirrel->__sq_newtable = module.Offset(0x3960).RCast(); - g_pSquirrel->__sq_newslot = module.Offset(0x7080).RCast(); - - g_pSquirrel->__sq_pushstring = module.Offset(0x3440).RCast(); - g_pSquirrel->__sq_pushinteger = module.Offset(0x36A0).RCast(); - g_pSquirrel->__sq_pushfloat = module.Offset(0x3800).RCast(); - g_pSquirrel->__sq_pushbool = module.Offset(0x3710).RCast(); - g_pSquirrel->__sq_pushasset = module.Offset(0x3560).RCast(); - g_pSquirrel->__sq_pushvector = module.Offset(0x3780).RCast(); - g_pSquirrel->__sq_pushobject = module.Offset(0x83A0).RCast(); - - g_pSquirrel->__sq_raiseerror = module.Offset(0x8440).RCast(); - - g_pSquirrel->__sq_getstring = module.Offset(0x60A0).RCast(); - g_pSquirrel->__sq_getinteger = module.Offset(0x60C0).RCast(); - g_pSquirrel->__sq_getfloat = module.Offset(0x60E0).RCast(); - g_pSquirrel->__sq_getbool = module.Offset(0x6110).RCast(); - g_pSquirrel->__sq_getasset = module.Offset(0x5FF0).RCast(); - g_pSquirrel->__sq_getuserdata = module.Offset(0x63B0).RCast(); - g_pSquirrel->__sq_getvector = module.Offset(0x6120).RCast(); - g_pSquirrel->__sq_get = module.Offset(0x7C00).RCast(); - - g_pSquirrel->__sq_getthisentity = module.Offset(0x203B0).RCast(); - g_pSquirrel->__sq_getobject = module.Offset(0x6140).RCast(); - - g_pSquirrel->__sq_createuserdata = module.Offset(0x38D0).RCast(); - g_pSquirrel->__sq_setuserdatatypeid = module.Offset(0x6470).RCast(); - - g_pSquirrel->__sq_GetEntityConstant_CBaseEntity = module.Offset(0x418AF0).RCast(); - g_pSquirrel->__sq_getentityfrominstance = module.Offset(0x1E920).RCast(); - - g_pSquirrel->logger = NS::log::SCRIPT_SV; - // Message buffer stuff - g_pSquirrel->__sq_getfunction = module.Offset(0x6C85).RCast(); - g_pSquirrel->__sq_stackinfos = module.Offset(0x35920).RCast(); - - // Structs - g_pSquirrel->__sq_pushnewstructinstance = module.Offset(0x53e0).RCast(); - g_pSquirrel->__sq_sealstructslot = module.Offset(0x5510).RCast(); - - MAKEHOOK( - module.Offset(0x1DD10), - &RegisterSquirrelFunctionHook, - &g_pSquirrel->RegisterSquirrelFunc); - - MAKEHOOK(module.Offset(0x8AA0), &sq_compiler_createHook, &sq_compiler_create); - - MAKEHOOK(module.Offset(0x1FE90), &SQPrintHook, &SQPrint); - MAKEHOOK(module.Offset(0x260E0), &CreateNewVMHook, &CreateNewVM); - MAKEHOOK(module.Offset(0x26E20), &DestroyVMHook, &DestroyVM); - MAKEHOOK(module.Offset(0x799E0), &ScriptCompileErrorHook, &SQCompileError); - MAKEHOOK(module.Offset(0x1D5C0), &CallScriptInitCallbackHook, &CallScriptInitCallback); - MAKEHOOK(module.Offset(0x1B7E0), &CSquirrelVM_initHook, &CSquirrelVM_init); - // FCVAR_CHEAT and FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS allows clients to execute this, but since it's unsafe we only allow it when cheats - // are enabled for script_client and script_ui, we don't use cheats, so clients can execute them on themselves all they want - RegisterConCommand( - "script", - ConCommand_script, - "Executes script code on the server vm", - FCVAR_GAMEDLL | FCVAR_GAMEDLL_FOR_REMOTE_CLIENTS | FCVAR_CHEAT); - - StubUnsafeSQFuncs(); - - SquirrelFunctions s = {}; - g_pSquirrel->GenerateSquirrelFunctionsStruct(&s); - g_pPluginManager->InformSQVMLoad(ScriptContext::SERVER, &s); -} - -void InitialiseSquirrelManagers() -{ - g_pSquirrel = new SquirrelManager; - g_pSquirrel = new SquirrelManager; - g_pSquirrel = new SquirrelManager; -} -- cgit v1.2.3