aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmma Miler <emma.pi@protonmail.com>2022-12-22 20:05:45 +0100
committerGitHub <noreply@github.com>2022-12-22 20:05:45 +0100
commitff889f16820430461dec797bb34eeab195b5e930 (patch)
treec145c0285d779975ff521319824c0f7210e3933a
parent64100065b55f79e76542ba689545c60e6fb0dcef (diff)
downloadNorthstarLauncher-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.vcxproj1
-rw-r--r--NorthstarDLL/NorthstarDLL.vcxproj.filters3
-rw-r--r--NorthstarDLL/core/convar/cvar.h1
-rw-r--r--NorthstarDLL/core/macros.h19
-rw-r--r--NorthstarDLL/logging/logging.h1
-rw-r--r--NorthstarDLL/pch.h23
-rw-r--r--NorthstarDLL/squirrel/squirrel.cpp42
-rw-r--r--NorthstarDLL/squirrel/squirrel.h28
-rw-r--r--NorthstarDLL/squirrel/squirrelclasstypes.h2
-rw-r--r--NorthstarDLL/squirrel/squirreldatatypes.h4
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;