From ff889f16820430461dec797bb34eeab195b5e930 Mon Sep 17 00:00:00 2001 From: Emma Miler Date: Thu, 22 Dec 2022 20:05:45 +0100 Subject: Add NSGetModName (#366) * Stackinfos * Formatting * Add option for depth * Revert "Merge branch 'main' into stackinfos" This reverts commit e9e8948d2ae9ab72095eb2162de40383b7211276, reversing changes made to d1cf18f7165a9d4fbe7f8ae2f1dfacbba36e4852. * Move macros header * Add macro header to filters * Fix merge conflict mistake * Fix stuff * I hate git * create `NSGetCurrentModName` * Fix merge issues --- NorthstarDLL/NorthstarDLL.vcxproj | 1 + NorthstarDLL/NorthstarDLL.vcxproj.filters | 3 +++ NorthstarDLL/core/convar/cvar.h | 1 - NorthstarDLL/core/macros.h | 19 ++++++++++++++ NorthstarDLL/logging/logging.h | 1 + NorthstarDLL/pch.h | 23 +++------------- NorthstarDLL/squirrel/squirrel.cpp | 42 ++++++++++++++++++++++++++++++ NorthstarDLL/squirrel/squirrel.h | 28 +++++++++++++++++--- NorthstarDLL/squirrel/squirrelclasstypes.h | 2 ++ NorthstarDLL/squirrel/squirreldatatypes.h | 4 +-- 10 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 NorthstarDLL/core/macros.h diff --git a/NorthstarDLL/NorthstarDLL.vcxproj b/NorthstarDLL/NorthstarDLL.vcxproj index e9f8eb57..4615a0f5 100644 --- a/NorthstarDLL/NorthstarDLL.vcxproj +++ b/NorthstarDLL/NorthstarDLL.vcxproj @@ -400,6 +400,7 @@ + diff --git a/NorthstarDLL/NorthstarDLL.vcxproj.filters b/NorthstarDLL/NorthstarDLL.vcxproj.filters index cb86a077..09648489 100644 --- a/NorthstarDLL/NorthstarDLL.vcxproj.filters +++ b/NorthstarDLL/NorthstarDLL.vcxproj.filters @@ -1170,6 +1170,9 @@ Header Files\core + + Header Files\core + diff --git a/NorthstarDLL/core/convar/cvar.h b/NorthstarDLL/core/convar/cvar.h index e65e5145..3a3e1815 100644 --- a/NorthstarDLL/core/convar/cvar.h +++ b/NorthstarDLL/core/convar/cvar.h @@ -1,6 +1,5 @@ #pragma once #include "convar.h" -#include "pch.h" //----------------------------------------------------------------------------- // Forward declarations diff --git a/NorthstarDLL/core/macros.h b/NorthstarDLL/core/macros.h new file mode 100644 index 00000000..ae944cca --- /dev/null +++ b/NorthstarDLL/core/macros.h @@ -0,0 +1,19 @@ +#pragma once +template ReturnType CallVFunc(int index, void* thisPtr, Args... args) +{ + return (*reinterpret_cast(thisPtr))[index](thisPtr, args...); +} + +template constexpr T CallVFunc_Alt(void* classBase, Args... args) noexcept +{ + return ((*(T(__thiscall***)(void*, Args...))(classBase))[index])(classBase, args...); +} + +#define STR_HASH(s) (std::hash()(s)) + +// Example usage: M_VMETHOD(int, GetEntityIndex, 8, (CBaseEntity* ent), (this, ent)) +#define M_VMETHOD(returnType, name, index, args, argsRaw) \ + FORCEINLINE returnType name args noexcept \ + { \ + return CallVFunc_Alt argsRaw; \ + } diff --git a/NorthstarDLL/logging/logging.h b/NorthstarDLL/logging/logging.h index af20c3e8..b710915e 100644 --- a/NorthstarDLL/logging/logging.h +++ b/NorthstarDLL/logging/logging.h @@ -2,6 +2,7 @@ #include "pch.h" #include "spdlog/sinks/base_sink.h" #include "spdlog/logger.h" +#include "squirrel/squirrel.h" #include "core/math/color.h" void CreateLogFiles(); diff --git a/NorthstarDLL/pch.h b/NorthstarDLL/pch.h index a6a3f06d..55ebba8b 100644 --- a/NorthstarDLL/pch.h +++ b/NorthstarDLL/pch.h @@ -24,6 +24,8 @@ namespace fs = std::filesystem; #define assert_msg(exp, msg) assert((exp, msg)) //clang-format on +#include "core/macros.h" + #include "core/structs.h" #include "core/math/color.h" #include "spdlog/spdlog.h" @@ -31,25 +33,6 @@ namespace fs = std::filesystem; #include "MinHook.h" #include "libcurl/include/curl/curl.h" #include "core/hooks.h" -#include "memory.h" - -template ReturnType CallVFunc(int index, void* thisPtr, Args... args) -{ - return (*reinterpret_cast(thisPtr))[index](thisPtr, args...); -} - -template constexpr T CallVFunc_Alt(void* classBase, Args... args) noexcept -{ - return ((*(T(__thiscall***)(void*, Args...))(classBase))[index])(classBase, args...); -} - -#define STR_HASH(s) (std::hash()(s)) - -// Example usage: M_VMETHOD(int, GetEntityIndex, 8, (CBaseEntity* ent), (this, ent)) -#define M_VMETHOD(returnType, name, index, args, argsRaw) \ - FORCEINLINE returnType name args noexcept \ - { \ - return CallVFunc_Alt argsRaw; \ - } +#include "core/memory.h" #endif diff --git a/NorthstarDLL/squirrel/squirrel.cpp b/NorthstarDLL/squirrel/squirrel.cpp index 8761fb13..d594ede9 100644 --- a/NorthstarDLL/squirrel/squirrel.cpp +++ b/NorthstarDLL/squirrel/squirrel.cpp @@ -561,6 +561,45 @@ template void SquirrelManager::ProcessMessageBu _call(m_pSQVM->sqvm, message.args.size()); } +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) @@ -637,6 +676,8 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module)) g_pSquirrel->messageBuffer = g_pSquirrel->messageBuffer; g_pSquirrel->__sq_getfunction = module.Offset(0x572FB0).As(); g_pSquirrel->__sq_getfunction = g_pSquirrel->__sq_getfunction; + g_pSquirrel->__sq_stackinfos = module.Offset(0x35970).As(); + g_pSquirrel->__sq_stackinfos = g_pSquirrel->__sq_stackinfos; MAKEHOOK( module.Offset(0x108E0), @@ -718,6 +759,7 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) g_pSquirrel->logger = NS::log::SCRIPT_SV; // Message buffer stuff g_pSquirrel->__sq_getfunction = module.Offset(0x6C85).As(); + g_pSquirrel->__sq_stackinfos = module.Offset(0x35920).As(); MAKEHOOK( module.Offset(0x1DD10), diff --git a/NorthstarDLL/squirrel/squirrel.h b/NorthstarDLL/squirrel/squirrel.h index 51fa93b3..82825b3c 100644 --- a/NorthstarDLL/squirrel/squirrel.h +++ b/NorthstarDLL/squirrel/squirrel.h @@ -1,9 +1,9 @@ #pragma once -#include "logging/logging.h" #include "squirrelclasstypes.h" #include "squirrelautobind.h" #include "core/math/vector.h" +#include "mods/modmanager.h" // stolen from ttf2sdk: sqvm types typedef float SQFloat; @@ -39,8 +39,6 @@ const char* SQTypeNameFromID(const int iTypeId); ScriptContext ScriptContextFromString(std::string string); -std::shared_ptr getSquirrelLoggerByContext(ScriptContext context); - namespace NS::log { template std::shared_ptr squirrel_logger(); @@ -98,6 +96,8 @@ class SquirrelManagerBase sq_getthisentityType __sq_getthisentity; sq_getobjectType __sq_getobject; + sq_stackinfosType __sq_stackinfos; + sq_createuserdataType __sq_createuserdata; sq_setuserdatatypeidType __sq_setuserdatatypeid; sq_getfunctionType __sq_getfunction; @@ -230,6 +230,28 @@ class SquirrelManagerBase return __sq_getasset(sqvm, stackpos, result); } + inline long long sq_stackinfos(HSquirrelVM* sqvm, int level, SQStackInfos& out) + { + return __sq_stackinfos(sqvm, level, &out, sqvm->_callstacksize); + } + + inline Mod* getcallingmod(HSquirrelVM* sqvm, int depth = 0) + { + SQStackInfos stackInfo {}; + if (1 + depth >= sqvm->_callstacksize) + { + return nullptr; + } + sq_stackinfos(sqvm, 1 + depth, stackInfo); + std::string sourceName = stackInfo._sourceName; + std::replace(sourceName.begin(), sourceName.end(), '/', '\\'); + std::string filename = "scripts\\vscripts\\" + sourceName; + if (auto res = g_pModManager->m_ModFiles.find(filename); res != g_pModManager->m_ModFiles.end()) + { + return res->second.m_pOwningMod; + } + return nullptr; + } template inline SQRESULT getuserdata(HSquirrelVM* sqvm, const SQInteger stackpos, T* data, uint64_t* typeId) { return __sq_getuserdata(sqvm, stackpos, (void**)data, typeId); // this sometimes crashes idk diff --git a/NorthstarDLL/squirrel/squirrelclasstypes.h b/NorthstarDLL/squirrel/squirrelclasstypes.h index 0672724c..efc80f15 100644 --- a/NorthstarDLL/squirrel/squirrelclasstypes.h +++ b/NorthstarDLL/squirrel/squirrelclasstypes.h @@ -224,6 +224,8 @@ typedef SQFloat* (*sq_getvectorType)(HSquirrelVM* sqvm, SQInteger iStackpos); typedef SQBool (*sq_getthisentityType)(HSquirrelVM*, void** ppEntity); typedef void (*sq_getobjectType)(HSquirrelVM*, SQInteger iStackPos, SQObject* pOutObj); +typedef long long (*sq_stackinfosType)(HSquirrelVM* sqvm, int iLevel, SQStackInfos* pOutObj, int iCallStackSize); + // sq stack userpointer funcs typedef void* (*sq_createuserdataType)(HSquirrelVM* sqvm, SQInteger iSize); typedef SQRESULT (*sq_setuserdatatypeidType)(HSquirrelVM* sqvm, SQInteger iStackpos, uint64_t iTypeId); diff --git a/NorthstarDLL/squirrel/squirreldatatypes.h b/NorthstarDLL/squirrel/squirreldatatypes.h index e9f88d08..b5025f6b 100644 --- a/NorthstarDLL/squirrel/squirreldatatypes.h +++ b/NorthstarDLL/squirrel/squirreldatatypes.h @@ -251,7 +251,7 @@ struct alignas(8) HSquirrelVM void* pointer_28; CallInfo* ci; CallInfo* _callstack; - int _callsstacksize; + int _callstacksize; int _stackbase; SQObject* _stackOfCurrentFunction; SQSharedState* sharedState; @@ -275,7 +275,7 @@ struct alignas(8) HSquirrelVM int _nnativecalls; int _suspended; int _suspended_root; - int _callstacksize; + int _unk; int _suspended_target; int trapAmount; int _suspend_varargs; -- cgit v1.2.3