diff options
author | Emma Miler <emma.pi@protonmail.com> | 2022-12-22 20:05:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-22 20:05:45 +0100 |
commit | ff889f16820430461dec797bb34eeab195b5e930 (patch) | |
tree | c145c0285d779975ff521319824c0f7210e3933a | |
parent | 64100065b55f79e76542ba689545c60e6fb0dcef (diff) | |
download | NorthstarLauncher-ff889f16820430461dec797bb34eeab195b5e930.tar.gz NorthstarLauncher-ff889f16820430461dec797bb34eeab195b5e930.zip |
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
-rw-r--r-- | NorthstarDLL/NorthstarDLL.vcxproj | 1 | ||||
-rw-r--r-- | NorthstarDLL/NorthstarDLL.vcxproj.filters | 3 | ||||
-rw-r--r-- | NorthstarDLL/core/convar/cvar.h | 1 | ||||
-rw-r--r-- | NorthstarDLL/core/macros.h | 19 | ||||
-rw-r--r-- | NorthstarDLL/logging/logging.h | 1 | ||||
-rw-r--r-- | NorthstarDLL/pch.h | 23 | ||||
-rw-r--r-- | NorthstarDLL/squirrel/squirrel.cpp | 42 | ||||
-rw-r--r-- | NorthstarDLL/squirrel/squirrel.h | 28 | ||||
-rw-r--r-- | NorthstarDLL/squirrel/squirrelclasstypes.h | 2 | ||||
-rw-r--r-- | NorthstarDLL/squirrel/squirreldatatypes.h | 4 |
10 files changed, 98 insertions, 26 deletions
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 @@ <ClInclude Include="core\filesystem\filesystem.h" />
<ClInclude Include="core\filesystem\rpakfilesystem.h" />
<ClInclude Include="core\hooks.h" />
+ <ClInclude Include="core\macros.h" />
<ClInclude Include="core\math\bitbuf.h" />
<ClInclude Include="core\math\bits.h" />
<ClInclude Include="core\math\color.h" />
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 @@ <ClInclude Include="core\sourceinterface.h">
<Filter>Header Files\core</Filter>
</ClInclude>
+ <ClInclude Include="core\macros.h">
+ <Filter>Header Files\core</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\include\spdlog\fmt\bundled\LICENSE.rst">
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 <typename ReturnType, typename... Args> ReturnType CallVFunc(int index, void* thisPtr, Args... args) +{ + return (*reinterpret_cast<ReturnType(__fastcall***)(void*, Args...)>(thisPtr))[index](thisPtr, args...); +} + +template <typename T, size_t index, typename... Args> constexpr T CallVFunc_Alt(void* classBase, Args... args) noexcept +{ + return ((*(T(__thiscall***)(void*, Args...))(classBase))[index])(classBase, args...); +} + +#define STR_HASH(s) (std::hash<std::string>()(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<returnType, index> 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 <typename ReturnType, typename... Args> ReturnType CallVFunc(int index, void* thisPtr, Args... args) -{ - return (*reinterpret_cast<ReturnType(__fastcall***)(void*, Args...)>(thisPtr))[index](thisPtr, args...); -} - -template <typename T, size_t index, typename... Args> constexpr T CallVFunc_Alt(void* classBase, Args... args) noexcept -{ - return ((*(T(__thiscall***)(void*, Args...))(classBase))[index])(classBase, args...); -} - -#define STR_HASH(s) (std::hash<std::string>()(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<returnType, index> 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 <ScriptContext context> void SquirrelManager<context>::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<context>->getinteger(sqvm, 1); + if (auto mod = g_pSquirrel<context>->getcallingmod(sqvm, depth); mod == nullptr) + { + g_pSquirrel<context>->raiseerror(sqvm, "NSGetModName was called from a non-mod script. This shouldn't be possible"); + return SQRESULT_ERROR; + } + else + { + g_pSquirrel<context>->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<context>->getinteger(sqvm, 1); + if (auto mod = g_pSquirrel<context>->getcallingmod(sqvm, depth); mod == nullptr) + { + g_pSquirrel<context>->pushstring(sqvm, "Unknown"); + } + else + { + g_pSquirrel<context>->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<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; + g_pSquirrel<ScriptContext::CLIENT>->__sq_stackinfos = module.Offset(0x35970).As<sq_stackinfosType>(); + g_pSquirrel<ScriptContext::UI>->__sq_stackinfos = g_pSquirrel<ScriptContext::CLIENT>->__sq_stackinfos; MAKEHOOK( module.Offset(0x108E0), @@ -718,6 +759,7 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module)) g_pSquirrel<ScriptContext::SERVER>->logger = NS::log::SCRIPT_SV; // Message buffer stuff g_pSquirrel<ScriptContext::SERVER>->__sq_getfunction = module.Offset(0x6C85).As<sq_getfunctionType>(); + g_pSquirrel<ScriptContext::SERVER>->__sq_stackinfos = module.Offset(0x35920).As<sq_stackinfosType>(); 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<ColoredLogger> getSquirrelLoggerByContext(ScriptContext context); - namespace NS::log { template <ScriptContext context> std::shared_ptr<spdlog::logger> 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 <typename T> 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; |