This commit is contained in:
uniboi 2024-04-05 14:00:20 -04:00 committed by GitHub
commit 21bc087b0e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 113 additions and 2 deletions

View File

@ -10,6 +10,8 @@
#include "plugins/pluginmanager.h"
#include "ns_version.h"
#include "core/vanilla.h"
#include "squirrelclasstypes.h"
#include "squirreldatatypes.h"
#include <any>
@ -162,16 +164,78 @@ template class SquirrelManager<ScriptContext::SERVER>;
template class SquirrelManager<ScriptContext::CLIENT>;
template class SquirrelManager<ScriptContext::UI>;
// create a string -> integer slot in table at index -1
template <ScriptContext context> SQRESULT SquirrelManager<context>::CreateSlot(const char* key, SQInteger val)
{
pushstring(m_pSQVM->sqvm, key, -1);
pushinteger(m_pSQVM->sqvm, val);
return newslot(m_pSQVM->sqvm, -3, false);
}
// expects const table to be at stack index -1
template <ScriptContext context> void SquirrelManager<context>::CreateDependencyConstantsForMod(Mod& mod, const char* dependencyName)
{
std::string version = mod.Version;
auto nDots = std::count(version.begin(), version.end(), '.');
// push mod name as key
pushstring(m_pSQVM->sqvm, dependencyName, -1);
newtable(m_pSQVM->sqvm);
// valid semver must at least include 2 dots to seperate versions
if (nDots >= 2)
{
std::string major = version.substr(0, version.find('.'));
std::string minor = version.substr(major.length() + 1, version.length() - version.find('.', major.length() + 1));
size_t preRelease = version.find('-');
size_t build = version.find('+');
size_t patchEnd = version.length();
if (build != std::string::npos)
{
patchEnd = build;
}
// pre-releases are always in front of build meta data
if (preRelease != std::string::npos)
{
patchEnd = preRelease;
}
std::string patch = version.substr(major.length() + minor.length() + 2, patchEnd);
if (std::all_of(major.begin(), major.end(), ::isdigit))
{
CreateSlot("major", stoi(major));
}
if (std::all_of(minor.begin(), minor.end(), ::isdigit))
{
CreateSlot("minor", stoi(minor));
}
if (std::all_of(patch.begin(), patch.end(), ::isdigit))
{
CreateSlot("patch", stoi(patch));
}
}
newslot(m_pSQVM->sqvm, -3, false);
}
template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquirrelVM* newSqvm)
{
m_pSQVM = newSqvm;
for (SQFuncRegistration* funcReg : m_funcRegistrations)
{
spdlog::info("Registering {} function {}", GetContextName(context), funcReg->squirrelFuncName);
RegisterSquirrelFunc(m_pSQVM, funcReg, 1);
}
pushconsttable(m_pSQVM->sqvm);
for (auto& pair : g_pModManager->m_DependencyConstants)
{
bool bWasFound = false;
@ -184,13 +248,21 @@ template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquir
if (dependency.Name == pair.second)
{
bWasFound = true;
CreateDependencyConstantsForMod(dependency, pair.first.c_str());
break;
}
}
defconst(m_pSQVM, pair.first.c_str(), bWasFound);
// if the dependency is not loaded, place a falsy value in the map
// null would've been cooler but pushing null in the table erased the slot for some reason
if (!bWasFound)
{
defconst(m_pSQVM, pair.first.c_str(), 0);
}
}
poptop(m_pSQVM->sqvm);
std::vector<Plugin> loadedPlugins = g_pPluginManager->GetLoadedPlugins();
for (const auto& pluginName : g_pModManager->m_PluginDependencyConstants)
{
@ -210,6 +282,8 @@ template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquir
// define squirrel constant for if we are in vanilla-compatibility mode
defconst(m_pSQVM, "VANILLA", g_pVanillaCompatibility->GetVanillaCompatibility());
// poptop(m_pSQVM->sqvm);
g_pSquirrel<context>->messageBuffer = new SquirrelMessageBuffer();
g_pPluginManager->InformSqvmCreated(newSqvm);
}
@ -729,6 +803,13 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module))
g_pSquirrel<ScriptContext::UI>->__sq_pushnewstructinstance = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushnewstructinstance;
g_pSquirrel<ScriptContext::UI>->__sq_sealstructslot = g_pSquirrel<ScriptContext::CLIENT>->__sq_sealstructslot;
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushconsttable = module.Offset(0x5940).RCast<sq_pushconsttableType>();
g_pSquirrel<ScriptContext::UI>->__sq_pushconsttable = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushconsttable;
g_pSquirrel<ScriptContext::CLIENT>->__sq_poptop = module.Offset(0x7030).RCast<sq_poptopType>();
g_pSquirrel<ScriptContext::UI>->__sq_poptop = g_pSquirrel<ScriptContext::CLIENT>->__sq_poptop;
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushnull = module.Offset(0x33d0).RCast<sq_pushnullType>();
g_pSquirrel<ScriptContext::UI>->__sq_pushnull = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushnull;
MAKEHOOK(
module.Offset(0x108E0),
&RegisterSquirrelFunctionHook<ScriptContext::CLIENT>,
@ -815,6 +896,10 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module))
g_pSquirrel<ScriptContext::SERVER>->__sq_pushnewstructinstance = module.Offset(0x53e0).RCast<sq_pushnewstructinstanceType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_sealstructslot = module.Offset(0x5510).RCast<sq_sealstructslotType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushconsttable = module.Offset(0x5920).RCast<sq_pushconsttableType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_poptop = module.Offset(0x7000).RCast<sq_poptopType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushnull = module.Offset(0x33d0).RCast<sq_pushnullType>();
MAKEHOOK(
module.Offset(0x1DD10),
&RegisterSquirrelFunctionHook<ScriptContext::SERVER>,

View File

@ -4,6 +4,7 @@
#include "squirrelautobind.h"
#include "core/math/vector.h"
#include "mods/modmanager.h"
#include "squirreldatatypes.h"
/*
definitions from hell
@ -120,6 +121,10 @@ public:
sq_pushnewstructinstanceType __sq_pushnewstructinstance;
sq_sealstructslotType __sq_sealstructslot;
sq_pushconsttableType __sq_pushconsttable;
sq_poptopType __sq_poptop;
sq_pushnullType __sq_pushnull;
#pragma endregion
#pragma region SQVM func wrappers
@ -254,6 +259,21 @@ public:
return __sq_stackinfos(sqvm, level, &out, sqvm->_callstacksize);
}
inline void pushconsttable(HSquirrelVM* sqvm)
{
return __sq_pushconsttable(sqvm);
}
inline void poptop(HSquirrelVM* sqvm)
{
return __sq_poptop(sqvm);
}
inline void pushnull(HSquirrelVM* sqvm)
{
return __sq_pushnull(sqvm);
}
inline Mod* getcallingmod(HSquirrelVM* sqvm, int depth = 0)
{
SQStackInfos stackInfo {};
@ -407,6 +427,8 @@ public:
m_pSQVM = nullptr;
}
SQRESULT CreateSlot(const char* key, SQInteger val);
void CreateDependencyConstantsForMod(Mod& mod, const char* dependencyName);
void VMCreated(CSquirrelVM* newSqvm);
void VMDestroyed();
void ExecuteCode(const char* code);

View File

@ -235,4 +235,8 @@ typedef int (*sq_getfunctionType)(HSquirrelVM* sqvm, const char* name, SQObject*
typedef SQRESULT (*sq_pushnewstructinstanceType)(HSquirrelVM* sqvm, int fieldCount);
typedef SQRESULT (*sq_sealstructslotType)(HSquirrelVM* sqvm, int slotIndex);
typedef void (*sq_poptopType)(HSquirrelVM* sqvm);
typedef void (*sq_pushconsttableType)(HSquirrelVM* sqvm);
typedef void (*sq_pushnullType)(HSquirrelVM* sqvm);
#pragma endregion