Reduce templating of squirrel managers (#863)

* Untemplate g_pSquirrel so intellisense and stuff actually works with it
* Remove unnecessary bitwise operations
* Don't use ScriptContext_COUNT and treat INVALID as a valid flag
This commit is contained in:
Jack 2025-12-21 19:41:44 +00:00 committed by GitHub
parent 116c74f36e
commit 44755cd2da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 668 additions and 670 deletions

View file

@ -77,7 +77,7 @@ bool InitialiseNorthstar()
g_pPluginManager = new PluginManager();
g_pPluginManager->LoadPlugins();
InitialiseSquirrelManagers();
g_pSquirrel.InitialiseSquirrelManagers();
// Fix some users' failure to connect to respawn datacenters
SetEnvironmentVariableA("OPENSSL_ia32cap", "~0x200000200000000");

View file

@ -158,14 +158,14 @@ static void __fastcall h_CHostState__FrameUpdate(CHostState* self, double flCurr
}
// Run Squirrel message buffer
if (g_pSquirrel<ScriptContext::UI>->m_pSQVM != nullptr && g_pSquirrel<ScriptContext::UI>->m_pSQVM->sqvm != nullptr)
g_pSquirrel<ScriptContext::UI>->ProcessMessageBuffer();
if (g_pSquirrel[ScriptContext::UI]->m_pSQVM != nullptr && g_pSquirrel[ScriptContext::UI]->m_pSQVM->sqvm != nullptr)
g_pSquirrel[ScriptContext::UI]->ProcessMessageBuffer();
if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM != nullptr && g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM->sqvm != nullptr)
g_pSquirrel<ScriptContext::CLIENT>->ProcessMessageBuffer();
if (g_pSquirrel[ScriptContext::CLIENT]->m_pSQVM != nullptr && g_pSquirrel[ScriptContext::CLIENT]->m_pSQVM->sqvm != nullptr)
g_pSquirrel[ScriptContext::CLIENT]->ProcessMessageBuffer();
if (g_pSquirrel<ScriptContext::SERVER>->m_pSQVM != nullptr && g_pSquirrel<ScriptContext::SERVER>->m_pSQVM->sqvm != nullptr)
g_pSquirrel<ScriptContext::SERVER>->ProcessMessageBuffer();
if (g_pSquirrel[ScriptContext::SERVER]->m_pSQVM != nullptr && g_pSquirrel[ScriptContext::SERVER]->m_pSQVM->sqvm != nullptr)
g_pSquirrel[ScriptContext::SERVER]->ProcessMessageBuffer();
g_pPluginManager->RunFrame();
}

View file

@ -721,17 +721,17 @@ ADD_SQFUNC(
{
if (!g_pModDownloader)
{
g_pSquirrel<context>->pushbool(sqvm, false);
g_pSquirrel[context]->pushbool(sqvm, false);
return SQRESULT_NOTNULL;
}
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
const SQChar* modName = g_pSquirrel<context>->getstring(sqvm, 1);
const SQChar* modVersion = g_pSquirrel<context>->getstring(sqvm, 2);
const SQChar* modName = g_pSquirrel[context]->getstring(sqvm, 1);
const SQChar* modVersion = g_pSquirrel[context]->getstring(sqvm, 2);
bool result = g_pModDownloader->IsModAuthorized(modName, modVersion);
g_pSquirrel<context>->pushbool(sqvm, result);
g_pSquirrel[context]->pushbool(sqvm, result);
return SQRESULT_NOTNULL;
}
@ -741,8 +741,8 @@ ADD_SQFUNC("void", NSDownloadMod, "string name, string version", "", ScriptConte
if (!g_pModDownloader)
return SQRESULT_NULL;
const SQChar* modName = g_pSquirrel<context>->getstring(sqvm, 1);
const SQChar* modVersion = g_pSquirrel<context>->getstring(sqvm, 2);
const SQChar* modName = g_pSquirrel[context]->getstring(sqvm, 1);
const SQChar* modVersion = g_pSquirrel[context]->getstring(sqvm, 2);
g_pModDownloader->DownloadMod(modName, modVersion);
return SQRESULT_NULL;
@ -750,7 +750,7 @@ ADD_SQFUNC("void", NSDownloadMod, "string name, string version", "", ScriptConte
ADD_SQFUNC("ModInstallState", NSGetModInstallState, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
g_pSquirrel<context>->pushnewstructinstance(sqvm, 4);
g_pSquirrel[context]->pushnewstructinstance(sqvm, 4);
ModDownloader::MOD_STATE modState = {};
if (g_pModDownloader)
@ -759,20 +759,20 @@ ADD_SQFUNC("ModInstallState", NSGetModInstallState, "", "", ScriptContext::SERVE
modState.state = ModDownloader::NOT_FOUND;
// state
g_pSquirrel<context>->pushinteger(sqvm, modState.state);
g_pSquirrel<context>->sealstructslot(sqvm, 0);
g_pSquirrel[context]->pushinteger(sqvm, modState.state);
g_pSquirrel[context]->sealstructslot(sqvm, 0);
// progress
g_pSquirrel<context>->pushinteger(sqvm, modState.progress);
g_pSquirrel<context>->sealstructslot(sqvm, 1);
g_pSquirrel[context]->pushinteger(sqvm, modState.progress);
g_pSquirrel[context]->sealstructslot(sqvm, 1);
// total
g_pSquirrel<context>->pushinteger(sqvm, modState.total);
g_pSquirrel<context>->sealstructslot(sqvm, 2);
g_pSquirrel[context]->pushinteger(sqvm, modState.total);
g_pSquirrel[context]->sealstructslot(sqvm, 2);
// ratio
g_pSquirrel<context>->pushfloat(sqvm, modState.ratio);
g_pSquirrel<context>->sealstructslot(sqvm, 3);
g_pSquirrel[context]->pushfloat(sqvm, modState.ratio);
g_pSquirrel[context]->sealstructslot(sqvm, 3);
return SQRESULT_NOTNULL;
}

View file

@ -37,11 +37,11 @@ ModManager::ModManager()
template <ScriptContext context> void ModConCommandCallback_Internal(std::string name, const CCommand& command)
{
if (g_pSquirrel<context>->m_pSQVM && g_pSquirrel<context>->m_pSQVM)
if (g_pSquirrel[context]->m_pSQVM && g_pSquirrel[context]->m_pSQVM)
{
if (command.ArgC() == 1)
{
g_pSquirrel<context>->AsyncCall(name);
g_pSquirrel[context]->AsyncCall(name);
}
else
{
@ -49,7 +49,7 @@ template <ScriptContext context> void ModConCommandCallback_Internal(std::string
args.reserve(command.ArgC());
for (int i = 1; i < command.ArgC(); i++)
args.push_back(command.Arg(i));
g_pSquirrel<context>->AsyncCall(name, args);
g_pSquirrel[context]->AsyncCall(name, args);
}
}
else

View file

@ -154,7 +154,7 @@ template <ScriptContext context> int SaveFileManager::LoadFileAsync(fs::path fil
{
spdlog::error("A file was supposed to be loaded but we can't access it?!");
g_pSquirrel<context>->AsyncCall("NSHandleLoadResult", handle, false, "");
g_pSquirrel[context]->AsyncCall("NSHandleLoadResult", handle, false, "");
mutex.get().unlock();
return;
}
@ -162,7 +162,7 @@ template <ScriptContext context> int SaveFileManager::LoadFileAsync(fs::path fil
std::stringstream stringStream;
stringStream << fileStr.rdbuf();
g_pSquirrel<context>->AsyncCall("NSHandleLoadResult", handle, true, stringStream.str());
g_pSquirrel[context]->AsyncCall("NSHandleLoadResult", handle, true, stringStream.str());
fileStr.close();
mutex.get().unlock();
@ -174,7 +174,7 @@ template <ScriptContext context> int SaveFileManager::LoadFileAsync(fs::path fil
catch (std::exception ex)
{
spdlog::error("LOAD FAILED!");
g_pSquirrel<context>->AsyncCall("NSHandleLoadResult", handle, false, "");
g_pSquirrel[context]->AsyncCall("NSHandleLoadResult", handle, false, "");
mutex.get().unlock();
spdlog::error(ex.what());
}
@ -252,18 +252,18 @@ bool IsPathSafe(const std::string param, fs::path dir)
// void NSSaveFile( string file, string data )
ADD_SQFUNC("void", NSSaveFile, "string file, string data", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
if (mod == nullptr)
{
g_pSquirrel<context>->raiseerror(sqvm, "Has to be called from a mod function!");
g_pSquirrel[context]->raiseerror(sqvm, "Has to be called from a mod function!");
return SQRESULT_ERROR;
}
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string fileName = g_pSquirrel<context>->getstring(sqvm, 1);
std::string fileName = g_pSquirrel[context]->getstring(sqvm, 1);
if (!IsPathSafe(fileName, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -274,10 +274,10 @@ ADD_SQFUNC("void", NSSaveFile, "string file, string data", "", ScriptContext::SE
return SQRESULT_ERROR;
}
std::string content = g_pSquirrel<context>->getstring(sqvm, 2);
std::string content = g_pSquirrel[context]->getstring(sqvm, 2);
if (ContainsInvalidChars(content))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm, fmt::format("File contents may not contain NUL/\\0 characters! Make sure your strings are valid!", mod->Name).c_str());
return SQRESULT_ERROR;
}
@ -288,7 +288,7 @@ ADD_SQFUNC("void", NSSaveFile, "string file, string data", "", ScriptContext::SE
// this ain't a cloud service.
if (GetSizeOfFolderContentsMinusFile(dir, fileName) + content.length() > MAX_FOLDER_SIZE)
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"The mod {} has reached the maximum folder size.\n\nAsk the mod developer to optimize their data usage,"
@ -306,18 +306,18 @@ ADD_SQFUNC("void", NSSaveFile, "string file, string data", "", ScriptContext::SE
// void NSSaveJSONFile(string file, table data)
ADD_SQFUNC("void", NSSaveJSONFile, "string file, table data", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
if (mod == nullptr)
{
g_pSquirrel<context>->raiseerror(sqvm, "Has to be called from a mod function!");
g_pSquirrel[context]->raiseerror(sqvm, "Has to be called from a mod function!");
return SQRESULT_ERROR;
}
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string fileName = g_pSquirrel<context>->getstring(sqvm, 1);
std::string fileName = g_pSquirrel[context]->getstring(sqvm, 1);
if (!IsPathSafe(fileName, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -333,7 +333,7 @@ ADD_SQFUNC("void", NSSaveJSONFile, "string file, table data", "", ScriptContext:
std::string content = EncodeJSON<context>(sqvm);
if (ContainsInvalidChars(content))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm, fmt::format("File contents may not contain NUL/\\0 characters! Make sure your strings are valid!", mod->Name).c_str());
return SQRESULT_ERROR;
}
@ -344,7 +344,7 @@ ADD_SQFUNC("void", NSSaveJSONFile, "string file, table data", "", ScriptContext:
// this ain't a cloud service.
if (GetSizeOfFolderContentsMinusFile(dir, fileName) + content.length() > MAX_FOLDER_SIZE)
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"The mod {} has reached the maximum folder size.\n\nAsk the mod developer to optimize their data usage,"
@ -362,18 +362,18 @@ ADD_SQFUNC("void", NSSaveJSONFile, "string file, table data", "", ScriptContext:
// int NS_InternalLoadFile(string file)
ADD_SQFUNC("int", NS_InternalLoadFile, "string file", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm, 1); // the function that called NSLoadFile :)
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm, 1); // the function that called NSLoadFile :)
if (mod == nullptr)
{
g_pSquirrel<context>->raiseerror(sqvm, "Has to be called from a mod function!");
g_pSquirrel[context]->raiseerror(sqvm, "Has to be called from a mod function!");
return SQRESULT_ERROR;
}
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string fileName = g_pSquirrel<context>->getstring(sqvm, 1);
std::string fileName = g_pSquirrel[context]->getstring(sqvm, 1);
if (!IsPathSafe(fileName, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -384,7 +384,7 @@ ADD_SQFUNC("int", NS_InternalLoadFile, "string file", "", ScriptContext::SERVER
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushinteger(sqvm, g_pSaveFileManager->LoadFileAsync<context>(dir / fileName));
g_pSquirrel[context]->pushinteger(sqvm, g_pSaveFileManager->LoadFileAsync<context>(dir / fileName));
return SQRESULT_NOTNULL;
}
@ -392,13 +392,13 @@ ADD_SQFUNC("int", NS_InternalLoadFile, "string file", "", ScriptContext::SERVER
// bool NSDoesFileExist(string file)
ADD_SQFUNC("bool", NSDoesFileExist, "string file", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string fileName = g_pSquirrel<context>->getstring(sqvm, 1);
std::string fileName = g_pSquirrel[context]->getstring(sqvm, 1);
if (!IsPathSafe(fileName, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -409,20 +409,20 @@ ADD_SQFUNC("bool", NSDoesFileExist, "string file", "", ScriptContext::SERVER | S
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushbool(sqvm, fs::exists(dir / (fileName)));
g_pSquirrel[context]->pushbool(sqvm, fs::exists(dir / (fileName)));
return SQRESULT_NOTNULL;
}
// int NSGetFileSize(string file)
ADD_SQFUNC("int", NSGetFileSize, "string file", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string fileName = g_pSquirrel<context>->getstring(sqvm, 1);
std::string fileName = g_pSquirrel[context]->getstring(sqvm, 1);
if (!IsPathSafe(fileName, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -436,12 +436,12 @@ ADD_SQFUNC("int", NSGetFileSize, "string file", "", ScriptContext::SERVER | Scri
{
// throws if file does not exist
// we don't want stuff such as "file does not exist, file is unavailable" to be lethal, so we just try/catch fs errors
g_pSquirrel<context>->pushinteger(sqvm, (int)(fs::file_size(dir / fileName) / 1024));
g_pSquirrel[context]->pushinteger(sqvm, (int)(fs::file_size(dir / fileName) / 1024));
}
catch (std::filesystem::filesystem_error const& ex)
{
spdlog::error("GET FILE SIZE FAILED! Is the path valid?");
g_pSquirrel<context>->raiseerror(sqvm, ex.what());
g_pSquirrel[context]->raiseerror(sqvm, ex.what());
return SQRESULT_ERROR;
}
return SQRESULT_NOTNULL;
@ -450,13 +450,13 @@ ADD_SQFUNC("int", NSGetFileSize, "string file", "", ScriptContext::SERVER | Scri
// void NSDeleteFile(string file)
ADD_SQFUNC("void", NSDeleteFile, "string file", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string fileName = g_pSquirrel<context>->getstring(sqvm, 1);
std::string fileName = g_pSquirrel[context]->getstring(sqvm, 1);
if (!IsPathSafe(fileName, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -475,15 +475,15 @@ ADD_SQFUNC("void", NSDeleteFile, "string file", "", ScriptContext::SERVER | Scri
ADD_SQFUNC("array<string>", NS_InternalGetAllFiles, "string path", "", ScriptContext::CLIENT | ScriptContext::UI | ScriptContext::SERVER)
{
// depth 1 because this should always get called from Northstar.Custom
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm, 1);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm, 1);
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string pathStr = g_pSquirrel<context>->getstring(sqvm, 1);
std::string pathStr = g_pSquirrel[context]->getstring(sqvm, 1);
fs::path path = dir;
if (pathStr != "")
path = dir / pathStr;
if (!IsPathSafe(pathStr, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -495,33 +495,33 @@ ADD_SQFUNC("array<string>", NS_InternalGetAllFiles, "string path", "", ScriptCon
}
try
{
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
for (const auto& entry : fs::directory_iterator(path))
{
g_pSquirrel<context>->pushstring(sqvm, entry.path().filename().string().c_str());
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushstring(sqvm, entry.path().filename().string().c_str());
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
return SQRESULT_NOTNULL;
}
catch (std::exception ex)
{
spdlog::error("DIR ITERATE FAILED! Is the path valid?");
g_pSquirrel<context>->raiseerror(sqvm, ex.what());
g_pSquirrel[context]->raiseerror(sqvm, ex.what());
return SQRESULT_ERROR;
}
}
ADD_SQFUNC("bool", NSIsFolder, "string path", "", ScriptContext::CLIENT | ScriptContext::UI | ScriptContext::SERVER)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
std::string pathStr = g_pSquirrel<context>->getstring(sqvm, 1);
std::string pathStr = g_pSquirrel[context]->getstring(sqvm, 1);
fs::path path = dir;
if (pathStr != "")
path = dir / pathStr;
if (!IsPathSafe(pathStr, dir))
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"File name invalid ({})! Make sure it does not contain any non-ASCII character, and results in a path inside your mod's "
@ -533,14 +533,14 @@ ADD_SQFUNC("bool", NSIsFolder, "string path", "", ScriptContext::CLIENT | Script
}
try
{
g_pSquirrel<context>->pushbool(sqvm, fs::is_directory(path));
g_pSquirrel[context]->pushbool(sqvm, fs::is_directory(path));
return SQRESULT_NOTNULL;
}
catch (std::exception ex)
{
spdlog::error("DIR READ FAILED! Is the path valid?");
spdlog::info(path.string());
g_pSquirrel<context>->raiseerror(sqvm, ex.what());
g_pSquirrel[context]->raiseerror(sqvm, ex.what());
return SQRESULT_ERROR;
}
}
@ -548,9 +548,9 @@ ADD_SQFUNC("bool", NSIsFolder, "string path", "", ScriptContext::CLIENT | Script
// side note, expensive.
ADD_SQFUNC("int", NSGetTotalSpaceRemaining, "", "", ScriptContext::CLIENT | ScriptContext::UI | ScriptContext::SERVER)
{
Mod* mod = g_pSquirrel<context>->getcallingmod(sqvm);
Mod* mod = g_pSquirrel[context]->getcallingmod(sqvm);
fs::path dir = savePath / fs::path(mod->m_ModDirectory).filename();
g_pSquirrel<context>->pushinteger(sqvm, (MAX_FOLDER_SIZE - GetSizeOfFolder(dir)) / 1024);
g_pSquirrel[context]->pushinteger(sqvm, (MAX_FOLDER_SIZE - GetSizeOfFolder(dir)) / 1024);
return SQRESULT_NOTNULL;
}

View file

@ -28,7 +28,7 @@ static void __fastcall h_CHudChat__AddGameLine(void* self, const char* message,
RemoveAsciiControlSequences(const_cast<char*>(message), true);
SQRESULT result = g_pSquirrel<ScriptContext::CLIENT>->Call(
SQRESULT result = g_pSquirrel[ScriptContext::CLIENT]->Call(
"CHudChat_ProcessMessageStartThread", static_cast<int>(senderId) - 1, payload, isTeam, isDead, type);
if (result == SQRESULT_ERROR)
for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
@ -37,8 +37,8 @@ static void __fastcall h_CHudChat__AddGameLine(void* self, const char* message,
ADD_SQFUNC("void", NSChatWrite, "int context, string text", "", ScriptContext::CLIENT)
{
int chatContext = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1);
const char* str = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2);
int chatContext = g_pSquirrel[ScriptContext::CLIENT]->getinteger(sqvm, 1);
const char* str = g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 2);
LocalChatWriter((LocalChatWriter::Context)chatContext).Write(str);
return SQRESULT_NULL;
@ -46,8 +46,8 @@ ADD_SQFUNC("void", NSChatWrite, "int context, string text", "", ScriptContext::C
ADD_SQFUNC("void", NSChatWriteRaw, "int context, string text", "", ScriptContext::CLIENT)
{
int chatContext = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1);
const char* str = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2);
int chatContext = g_pSquirrel[ScriptContext::CLIENT]->getinteger(sqvm, 1);
const char* str = g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 2);
LocalChatWriter((LocalChatWriter::Context)chatContext).InsertText(str);
return SQRESULT_NULL;
@ -55,8 +55,8 @@ ADD_SQFUNC("void", NSChatWriteRaw, "int context, string text", "", ScriptContext
ADD_SQFUNC("void", NSChatWriteLine, "int context, string text", "", ScriptContext::CLIENT)
{
int chatContext = g_pSquirrel<ScriptContext::CLIENT>->getinteger(sqvm, 1);
const char* str = g_pSquirrel<ScriptContext::CLIENT>->getstring(sqvm, 2);
int chatContext = g_pSquirrel[ScriptContext::CLIENT]->getinteger(sqvm, 1);
const char* str = g_pSquirrel[ScriptContext::CLIENT]->getstring(sqvm, 2);
LocalChatWriter((LocalChatWriter::Context)chatContext).WriteLine(str);
return SQRESULT_NULL;

View file

@ -10,13 +10,13 @@ ADD_SQFUNC("vector ornull", NSGetCursorPosition, "", "", ScriptContext::UI)
if (GetAncestor(GetForegroundWindow(), GA_ROOTOWNER) != *g_gameHWND)
return SQRESULT_NULL;
g_pSquirrel<context>->pushvector(
g_pSquirrel[context]->pushvector(
sqvm,
{p.x > 0 ? p.x > rcClient.right ? rcClient.right : (float)p.x : 0,
p.y > 0 ? p.y > rcClient.bottom ? rcClient.bottom : (float)p.y : 0,
0});
return SQRESULT_NOTNULL;
}
g_pSquirrel<context>->raiseerror(sqvm, "Failed retrieving cursor position of game window");
g_pSquirrel[context]->raiseerror(sqvm, "Failed retrieving cursor position of game window");
return SQRESULT_ERROR;
}

View file

@ -30,7 +30,7 @@ ADD_SQFUNC("void", NSRequestCustomMainMenuPromos, "", "", ScriptContext::UI)
ADD_SQFUNC("bool", NSHasCustomMainMenuPromoData, "", "", ScriptContext::UI)
{
g_pSquirrel<ScriptContext::UI>->pushbool(sqvm, g_pMasterServerManager->m_bHasMainMenuPromoData);
g_pSquirrel[ScriptContext::UI]->pushbool(sqvm, g_pMasterServerManager->m_bHasMainMenuPromoData);
return SQRESULT_NOTNULL;
}
@ -39,83 +39,83 @@ ADD_SQFUNC("var", NSGetCustomMainMenuPromoData, "int promoDataKey", "", ScriptCo
if (!g_pMasterServerManager->m_bHasMainMenuPromoData)
return SQRESULT_NULL;
switch (g_pSquirrel<ScriptContext::UI>->getinteger(sqvm, 1))
switch (g_pSquirrel[ScriptContext::UI]->getinteger(sqvm, 1))
{
case eMainMenuPromoDataProperty::newInfoTitle1:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle1.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle1.c_str());
break;
}
case eMainMenuPromoDataProperty::newInfoTitle2:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle2.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle2.c_str());
break;
}
case eMainMenuPromoDataProperty::newInfoTitle3:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle3.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.newInfoTitle3.c_str());
break;
}
case eMainMenuPromoDataProperty::largeButtonTitle:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonTitle.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonTitle.c_str());
break;
}
case eMainMenuPromoDataProperty::largeButtonText:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonText.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonText.c_str());
break;
}
case eMainMenuPromoDataProperty::largeButtonUrl:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonUrl.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonUrl.c_str());
break;
}
case eMainMenuPromoDataProperty::largeButtonImageIndex:
{
g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonImageIndex);
g_pSquirrel[ScriptContext::UI]->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.largeButtonImageIndex);
break;
}
case eMainMenuPromoDataProperty::smallButton1Title:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1Title.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1Title.c_str());
break;
}
case eMainMenuPromoDataProperty::smallButton1Url:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1Url.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1Url.c_str());
break;
}
case eMainMenuPromoDataProperty::smallButton1ImageIndex:
{
g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1ImageIndex);
g_pSquirrel[ScriptContext::UI]->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton1ImageIndex);
break;
}
case eMainMenuPromoDataProperty::smallButton2Title:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2Title.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2Title.c_str());
break;
}
case eMainMenuPromoDataProperty::smallButton2Url:
{
g_pSquirrel<ScriptContext::UI>->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2Url.c_str());
g_pSquirrel[ScriptContext::UI]->pushstring(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2Url.c_str());
break;
}
case eMainMenuPromoDataProperty::smallButton2ImageIndex:
{
g_pSquirrel<ScriptContext::UI>->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2ImageIndex);
g_pSquirrel[ScriptContext::UI]->pushinteger(sqvm, g_pMasterServerManager->m_sMainMenuPromoData.smallButton2ImageIndex);
break;
}
}

View file

@ -3,56 +3,56 @@
template <ScriptContext context> void ModToSquirrel(HSQUIRRELVM sqvm, Mod& mod)
{
g_pSquirrel<context>->pushnewstructinstance(sqvm, 9);
g_pSquirrel[context]->pushnewstructinstance(sqvm, 9);
// name
g_pSquirrel<context>->pushstring(sqvm, mod.Name.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 0);
g_pSquirrel[context]->pushstring(sqvm, mod.Name.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 0);
// description
g_pSquirrel<context>->pushstring(sqvm, mod.Description.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 1);
g_pSquirrel[context]->pushstring(sqvm, mod.Description.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 1);
// version
g_pSquirrel<context>->pushstring(sqvm, mod.Version.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 2);
g_pSquirrel[context]->pushstring(sqvm, mod.Version.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 2);
// download link
g_pSquirrel<context>->pushstring(sqvm, mod.DownloadLink.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 3);
g_pSquirrel[context]->pushstring(sqvm, mod.DownloadLink.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 3);
// load priority
g_pSquirrel<context>->pushinteger(sqvm, mod.LoadPriority);
g_pSquirrel<context>->sealstructslot(sqvm, 4);
g_pSquirrel[context]->pushinteger(sqvm, mod.LoadPriority);
g_pSquirrel[context]->sealstructslot(sqvm, 4);
// enabled
g_pSquirrel<context>->pushbool(sqvm, mod.m_bEnabled);
g_pSquirrel<context>->sealstructslot(sqvm, 5);
g_pSquirrel[context]->pushbool(sqvm, mod.m_bEnabled);
g_pSquirrel[context]->sealstructslot(sqvm, 5);
// required on client
g_pSquirrel<context>->pushbool(sqvm, mod.RequiredOnClient);
g_pSquirrel<context>->sealstructslot(sqvm, 6);
g_pSquirrel[context]->pushbool(sqvm, mod.RequiredOnClient);
g_pSquirrel[context]->sealstructslot(sqvm, 6);
// is remote
g_pSquirrel<context>->pushbool(sqvm, mod.m_bIsRemote);
g_pSquirrel<context>->sealstructslot(sqvm, 7);
g_pSquirrel[context]->pushbool(sqvm, mod.m_bIsRemote);
g_pSquirrel[context]->sealstructslot(sqvm, 7);
// convars
g_pSquirrel<context>->newarray(sqvm);
g_pSquirrel[context]->newarray(sqvm);
for (ModConVar* cvar : mod.ConVars)
{
g_pSquirrel<context>->pushstring(sqvm, cvar->Name.c_str());
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushstring(sqvm, cvar->Name.c_str());
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
g_pSquirrel<context>->sealstructslot(sqvm, 8);
g_pSquirrel[context]->sealstructslot(sqvm, 8);
// add current object to squirrel array
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
ADD_SQFUNC("array<ModInfo>", NSGetModsInformation, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
for (Mod& mod : g_pModManager->m_LoadedMods)
{
@ -64,8 +64,8 @@ ADD_SQFUNC("array<ModInfo>", NSGetModsInformation, "", "", ScriptContext::SERVER
ADD_SQFUNC("array<ModInfo>", NSGetModInformation, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
const SQChar* modName = g_pSquirrel<context>->getstring(sqvm, 1);
g_pSquirrel<context>->newarray(sqvm, 0);
const SQChar* modName = g_pSquirrel[context]->getstring(sqvm, 1);
g_pSquirrel[context]->newarray(sqvm, 0);
for (Mod& mod : g_pModManager->m_LoadedMods)
{
@ -81,12 +81,12 @@ ADD_SQFUNC("array<ModInfo>", NSGetModInformation, "string modName", "", ScriptCo
ADD_SQFUNC("array<string>", NSGetModNames, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
for (Mod& mod : g_pModManager->m_LoadedMods)
{
g_pSquirrel<context>->pushstring(sqvm, mod.Name.c_str());
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushstring(sqvm, mod.Name.c_str());
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
return SQRESULT_NOTNULL;
@ -99,9 +99,9 @@ ADD_SQFUNC(
"",
ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
const SQChar* modName = g_pSquirrel<context>->getstring(sqvm, 1);
const SQChar* modVersion = g_pSquirrel<context>->getstring(sqvm, 2);
const SQBool enabled = g_pSquirrel<context>->getbool(sqvm, 3);
const SQChar* modName = g_pSquirrel[context]->getstring(sqvm, 1);
const SQChar* modVersion = g_pSquirrel[context]->getstring(sqvm, 2);
const SQBool enabled = g_pSquirrel[context]->getbool(sqvm, 3);
// manual lookup, not super performant but eh not a big deal
for (Mod& mod : g_pModManager->m_LoadedMods)

View file

@ -5,7 +5,7 @@
ADD_SQFUNC("bool", NSIsMasterServerAuthenticated, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bOriginAuthWithMasterServerDone);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bOriginAuthWithMasterServerDone);
return SQRESULT_NOTNULL;
}
@ -20,16 +20,16 @@ global struct MasterServerAuthResult
ADD_SQFUNC("MasterServerAuthResult", NSGetMasterServerAuthResult, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushnewstructinstance(sqvm, 3);
g_pSquirrel[context]->pushnewstructinstance(sqvm, 3);
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bOriginAuthWithMasterServerSuccessful);
g_pSquirrel<context>->sealstructslot(sqvm, 0);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bOriginAuthWithMasterServerSuccessful);
g_pSquirrel[context]->sealstructslot(sqvm, 0);
g_pSquirrel<context>->pushstring(sqvm, g_pMasterServerManager->m_sOriginAuthWithMasterServerErrorCode.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 1);
g_pSquirrel[context]->pushstring(sqvm, g_pMasterServerManager->m_sOriginAuthWithMasterServerErrorCode.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 1);
g_pSquirrel<context>->pushstring(sqvm, g_pMasterServerManager->m_sOriginAuthWithMasterServerErrorMessage.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 2);
g_pSquirrel[context]->pushstring(sqvm, g_pMasterServerManager->m_sOriginAuthWithMasterServerErrorMessage.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 2);
return SQRESULT_NOTNULL;
}

View file

@ -15,19 +15,19 @@ ADD_SQFUNC("void", NSRequestServerList, "", "", ScriptContext::UI)
ADD_SQFUNC("bool", NSIsRequestingServerList, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bScriptRequestingServerList);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bScriptRequestingServerList);
return SQRESULT_NOTNULL;
}
ADD_SQFUNC("bool", NSMasterServerConnectionSuccessful, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bSuccessfullyConnected);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bSuccessfullyConnected);
return SQRESULT_NOTNULL;
}
ADD_SQFUNC("int", NSGetServerCount, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushinteger(sqvm, (SQInteger)g_pMasterServerManager->m_vRemoteServers.size());
g_pSquirrel[context]->pushinteger(sqvm, (SQInteger)g_pMasterServerManager->m_vRemoteServers.size());
return SQRESULT_NOTNULL;
}
@ -42,12 +42,12 @@ ADD_SQFUNC("void", NSClearRecievedServerList, "", "", ScriptContext::UI)
ADD_SQFUNC("void", NSTryAuthWithServer, "int serverIndex, string password = ''", "", ScriptContext::UI)
{
SQInteger serverIndex = g_pSquirrel<context>->getinteger(sqvm, 1);
const SQChar* password = g_pSquirrel<context>->getstring(sqvm, 2);
SQInteger serverIndex = g_pSquirrel[context]->getinteger(sqvm, 1);
const SQChar* password = g_pSquirrel[context]->getstring(sqvm, 2);
if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"Tried to auth with server index {} when only {} servers are available",
@ -74,13 +74,13 @@ ADD_SQFUNC("void", NSTryAuthWithServer, "int serverIndex, string password = ''",
ADD_SQFUNC("bool", NSIsAuthenticatingWithServer, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bScriptAuthenticatingWithGameServer);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bScriptAuthenticatingWithGameServer);
return SQRESULT_NOTNULL;
}
ADD_SQFUNC("bool", NSWasAuthSuccessful, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bSuccessfullyAuthenticatedWithGameServer);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bSuccessfullyAuthenticatedWithGameServer);
return SQRESULT_NOTNULL;
}
@ -88,7 +88,7 @@ ADD_SQFUNC("void", NSConnectToAuthedServer, "", "", ScriptContext::UI)
{
if (!g_pMasterServerManager->m_bHasPendingConnectionInfo)
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm, fmt::format("Tried to connect to authed server before any pending connection info was available").c_str());
return SQRESULT_ERROR;
}
@ -136,78 +136,78 @@ ADD_SQFUNC("void", NSCompleteAuthWithLocalServer, "", "", ScriptContext::UI)
ADD_SQFUNC("string", NSGetAuthFailReason, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushstring(sqvm, g_pMasterServerManager->m_sAuthFailureReason.c_str(), -1);
g_pSquirrel[context]->pushstring(sqvm, g_pMasterServerManager->m_sAuthFailureReason.c_str(), -1);
return SQRESULT_NOTNULL;
}
ADD_SQFUNC("array<ServerInfo>", NSGetGameServers, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
for (size_t i = 0; i < g_pMasterServerManager->m_vRemoteServers.size(); i++)
{
const RemoteServerInfo& remoteServer = g_pMasterServerManager->m_vRemoteServers[i];
g_pSquirrel<context>->pushnewstructinstance(sqvm, 11);
g_pSquirrel[context]->pushnewstructinstance(sqvm, 11);
// index
g_pSquirrel<context>->pushinteger(sqvm, (SQInteger)i);
g_pSquirrel<context>->sealstructslot(sqvm, 0);
g_pSquirrel[context]->pushinteger(sqvm, (SQInteger)i);
g_pSquirrel[context]->sealstructslot(sqvm, 0);
// id
g_pSquirrel<context>->pushstring(sqvm, remoteServer.id, -1);
g_pSquirrel<context>->sealstructslot(sqvm, 1);
g_pSquirrel[context]->pushstring(sqvm, remoteServer.id, -1);
g_pSquirrel[context]->sealstructslot(sqvm, 1);
// name
g_pSquirrel<context>->pushstring(sqvm, remoteServer.name, -1);
g_pSquirrel<context>->sealstructslot(sqvm, 2);
g_pSquirrel[context]->pushstring(sqvm, remoteServer.name, -1);
g_pSquirrel[context]->sealstructslot(sqvm, 2);
// description
g_pSquirrel<context>->pushstring(sqvm, remoteServer.description.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 3);
g_pSquirrel[context]->pushstring(sqvm, remoteServer.description.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 3);
// map
g_pSquirrel<context>->pushstring(sqvm, remoteServer.map, -1);
g_pSquirrel<context>->sealstructslot(sqvm, 4);
g_pSquirrel[context]->pushstring(sqvm, remoteServer.map, -1);
g_pSquirrel[context]->sealstructslot(sqvm, 4);
// playlist
g_pSquirrel<context>->pushstring(sqvm, remoteServer.playlist, -1);
g_pSquirrel<context>->sealstructslot(sqvm, 5);
g_pSquirrel[context]->pushstring(sqvm, remoteServer.playlist, -1);
g_pSquirrel[context]->sealstructslot(sqvm, 5);
// playerCount
g_pSquirrel<context>->pushinteger(sqvm, remoteServer.playerCount);
g_pSquirrel<context>->sealstructslot(sqvm, 6);
g_pSquirrel[context]->pushinteger(sqvm, remoteServer.playerCount);
g_pSquirrel[context]->sealstructslot(sqvm, 6);
// maxPlayerCount
g_pSquirrel<context>->pushinteger(sqvm, remoteServer.maxPlayers);
g_pSquirrel<context>->sealstructslot(sqvm, 7);
g_pSquirrel[context]->pushinteger(sqvm, remoteServer.maxPlayers);
g_pSquirrel[context]->sealstructslot(sqvm, 7);
// requiresPassword
g_pSquirrel<context>->pushbool(sqvm, remoteServer.requiresPassword);
g_pSquirrel<context>->sealstructslot(sqvm, 8);
g_pSquirrel[context]->pushbool(sqvm, remoteServer.requiresPassword);
g_pSquirrel[context]->sealstructslot(sqvm, 8);
// region
g_pSquirrel<context>->pushstring(sqvm, remoteServer.region, -1);
g_pSquirrel<context>->sealstructslot(sqvm, 9);
g_pSquirrel[context]->pushstring(sqvm, remoteServer.region, -1);
g_pSquirrel[context]->sealstructslot(sqvm, 9);
// requiredMods
g_pSquirrel<context>->newarray(sqvm);
g_pSquirrel[context]->newarray(sqvm);
for (const RemoteModInfo& mod : remoteServer.requiredMods)
{
g_pSquirrel<context>->pushnewstructinstance(sqvm, 2);
g_pSquirrel[context]->pushnewstructinstance(sqvm, 2);
// name
g_pSquirrel<context>->pushstring(sqvm, mod.Name.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 0);
g_pSquirrel[context]->pushstring(sqvm, mod.Name.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 0);
// version
g_pSquirrel<context>->pushstring(sqvm, mod.Version.c_str(), -1);
g_pSquirrel<context>->sealstructslot(sqvm, 1);
g_pSquirrel[context]->pushstring(sqvm, mod.Version.c_str(), -1);
g_pSquirrel[context]->sealstructslot(sqvm, 1);
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
g_pSquirrel<context>->sealstructslot(sqvm, 10);
g_pSquirrel[context]->sealstructslot(sqvm, 10);
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
return SQRESULT_NOTNULL;
}

View file

@ -4,8 +4,8 @@
void ConCommand_ns_script_servertoclientstringcommand(const CCommand& arg)
{
if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM)
g_pSquirrel<ScriptContext::CLIENT>->Call("NSClientCodeCallback_RecievedServerToClientStringCommand", arg.ArgS());
if (g_pSquirrel[ScriptContext::CLIENT]->m_pSQVM)
g_pSquirrel[ScriptContext::CLIENT]->Call("NSClientCodeCallback_RecievedServerToClientStringCommand", arg.ArgS());
}
ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptServerToClientStringCommand, ClientSquirrel, (CModule module))

View file

@ -63,16 +63,16 @@ std::unordered_map<std::string, CSVData> CSVCache;
REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER))
{
const char* pAssetName;
g_pSquirrel<context>->getasset(sqvm, 2, &pAssetName);
g_pSquirrel[context]->getasset(sqvm, 2, &pAssetName);
if (strncmp(pAssetName, "datatable/", 10))
{
g_pSquirrel<context>->raiseerror(sqvm, fmt::format("Asset \"{}\" doesn't start with \"datatable/\"", pAssetName).c_str());
g_pSquirrel[context]->raiseerror(sqvm, fmt::format("Asset \"{}\" doesn't start with \"datatable/\"", pAssetName).c_str());
return SQRESULT_ERROR;
}
else if (!Cvar_ns_prefer_datatable_from_disk->GetBool() && g_pPakLoadManager->OpenFile(pAssetName))
{
return g_pSquirrel<context>->m_funcOriginals["GetDataTable"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTable"](sqvm);
}
else // either we prefer disk datatables, or we're loading a datatable that wasn't found in rpak
{
@ -81,8 +81,8 @@ REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | Script
// first, check the cache
if (CSVCache.find(pAssetName) != CSVCache.end())
{
CSVData** pUserdata = g_pSquirrel<context>->template createuserdata<CSVData*>(sqvm, sizeof(CSVData*));
g_pSquirrel<context>->setuserdatatypeid(sqvm, -1, USERDATA_TYPE_DATATABLE_CUSTOM);
CSVData** pUserdata = g_pSquirrel[context]->template createuserdata<CSVData*>(sqvm, sizeof(CSVData*));
g_pSquirrel[context]->setuserdatatypeid(sqvm, -1, USERDATA_TYPE_DATATABLE_CUSTOM);
*pUserdata = &CSVCache[pAssetName];
return SQRESULT_NOTNULL;
@ -102,7 +102,7 @@ REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | Script
std::string sTableCSV = ReadVPKFile(sDiskAssetPath.c_str());
if (!sTableCSV.size())
{
g_pSquirrel<context>->raiseerror(sqvm, fmt::format("Datatable \"{}\" is empty", pAssetName).c_str());
g_pSquirrel[context]->raiseerror(sqvm, fmt::format("Datatable \"{}\" is empty", pAssetName).c_str());
return SQRESULT_ERROR;
}
@ -145,7 +145,7 @@ REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | Script
// shouldn't have newline in string
if (bInQuotes)
{
g_pSquirrel<context>->raiseerror(sqvm, "Unexpected \\n in string");
g_pSquirrel[context]->raiseerror(sqvm, "Unexpected \\n in string");
return SQRESULT_ERROR;
}
@ -180,7 +180,7 @@ REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | Script
// shouldn't have quoted strings in column names
if (!bHasColumns)
{
g_pSquirrel<context>->raiseerror(sqvm, "Unexpected \" in column name");
g_pSquirrel[context]->raiseerror(sqvm, "Unexpected \" in column name");
return SQRESULT_ERROR;
}
@ -216,8 +216,8 @@ REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | Script
}
// add to cache and return
CSVData** pUserdata = g_pSquirrel<context>->template createuserdata<CSVData*>(sqvm, sizeof(CSVData*));
g_pSquirrel<context>->setuserdatatypeid(sqvm, -1, USERDATA_TYPE_DATATABLE_CUSTOM);
CSVData** pUserdata = g_pSquirrel[context]->template createuserdata<CSVData*>(sqvm, sizeof(CSVData*));
g_pSquirrel[context]->setuserdatatypeid(sqvm, -1, USERDATA_TYPE_DATATABLE_CUSTOM);
CSVCache[pAssetName] = csv;
*pUserdata = &CSVCache[pAssetName];
@ -225,11 +225,11 @@ REPLACE_SQFUNC(GetDataTable, (ScriptContext::UI | ScriptContext::CLIENT | Script
}
// the file doesn't exist on disk, check rpak if we haven't already
else if (Cvar_ns_prefer_datatable_from_disk->GetBool() && g_pPakLoadManager->OpenFile(pAssetName))
return g_pSquirrel<context>->m_funcOriginals["GetDataTable"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTable"](sqvm);
// the file doesn't exist at all, error
else
{
g_pSquirrel<context>->raiseerror(sqvm, fmt::format("Datatable {} not found", pAssetName).c_str());
g_pSquirrel[context]->raiseerror(sqvm, fmt::format("Datatable {} not found", pAssetName).c_str());
return SQRESULT_ERROR;
}
}
@ -240,25 +240,25 @@ REPLACE_SQFUNC(GetDataTableColumnByName, (ScriptContext::UI | ScriptContext::CLI
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableColumnByName"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableColumnByName"](sqvm);
CSVData* csv = *pData;
const char* pColumnName = g_pSquirrel<context>->getstring(sqvm, 2);
const char* pColumnName = g_pSquirrel[context]->getstring(sqvm, 2);
for (int i = 0; i < csv->columns.size(); i++)
{
if (!strcmp(csv->columns[i], pColumnName))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
// column not found
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -268,13 +268,13 @@ REPLACE_SQFUNC(GetDatatableRowCount, (ScriptContext::UI | ScriptContext::CLIENT
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDatatableRowCount"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDatatableRowCount"](sqvm);
CSVData* csv = *pData;
g_pSquirrel<context>->pushinteger(sqvm, (SQInteger)csv->dataPointers.size());
g_pSquirrel[context]->pushinteger(sqvm, (SQInteger)csv->dataPointers.size());
return SQRESULT_NOTNULL;
}
@ -283,17 +283,17 @@ REPLACE_SQFUNC(GetDataTableString, (ScriptContext::UI | ScriptContext::CLIENT |
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableString"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableString"](sqvm);
CSVData* csv = *pData;
const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3);
const int nRow = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nCol = g_pSquirrel[context]->getinteger(sqvm, 3);
if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size())
@ -301,7 +301,7 @@ REPLACE_SQFUNC(GetDataTableString, (ScriptContext::UI | ScriptContext::CLIENT |
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushstring(sqvm, csv->dataPointers[nRow][nCol], -1);
g_pSquirrel[context]->pushstring(sqvm, csv->dataPointers[nRow][nCol], -1);
return SQRESULT_NOTNULL;
}
@ -310,17 +310,17 @@ REPLACE_SQFUNC(GetDataTableAsset, (ScriptContext::UI | ScriptContext::CLIENT | S
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableAsset"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableAsset"](sqvm);
CSVData* csv = *pData;
const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3);
const int nRow = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nCol = g_pSquirrel[context]->getinteger(sqvm, 3);
if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size())
@ -328,7 +328,7 @@ REPLACE_SQFUNC(GetDataTableAsset, (ScriptContext::UI | ScriptContext::CLIENT | S
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushasset(sqvm, csv->dataPointers[nRow][nCol], -1);
g_pSquirrel[context]->pushasset(sqvm, csv->dataPointers[nRow][nCol], -1);
return SQRESULT_NOTNULL;
}
@ -337,17 +337,17 @@ REPLACE_SQFUNC(GetDataTableInt, (ScriptContext::UI | ScriptContext::CLIENT | Scr
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableInt"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableInt"](sqvm);
CSVData* csv = *pData;
const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3);
const int nRow = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nCol = g_pSquirrel[context]->getinteger(sqvm, 3);
if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size())
@ -355,7 +355,7 @@ REPLACE_SQFUNC(GetDataTableInt, (ScriptContext::UI | ScriptContext::CLIENT | Scr
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushinteger(sqvm, std::stoi(csv->dataPointers[nRow][nCol]));
g_pSquirrel[context]->pushinteger(sqvm, std::stoi(csv->dataPointers[nRow][nCol]));
return SQRESULT_NOTNULL;
}
@ -364,17 +364,17 @@ REPLACE_SQFUNC(GetDataTableFloat, (ScriptContext::UI | ScriptContext::CLIENT | S
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableFloat"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableFloat"](sqvm);
CSVData* csv = *pData;
const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3);
const int nRow = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nCol = g_pSquirrel[context]->getinteger(sqvm, 3);
if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size())
@ -382,7 +382,7 @@ REPLACE_SQFUNC(GetDataTableFloat, (ScriptContext::UI | ScriptContext::CLIENT | S
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushfloat(sqvm, std::stof(csv->dataPointers[nRow][nCol]));
g_pSquirrel[context]->pushfloat(sqvm, std::stof(csv->dataPointers[nRow][nCol]));
return SQRESULT_NOTNULL;
}
@ -391,17 +391,17 @@ REPLACE_SQFUNC(GetDataTableBool, (ScriptContext::UI | ScriptContext::CLIENT | Sc
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableBool"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableBool"](sqvm);
CSVData* csv = *pData;
const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3);
const int nRow = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nCol = g_pSquirrel[context]->getinteger(sqvm, 3);
if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size())
@ -409,7 +409,7 @@ REPLACE_SQFUNC(GetDataTableBool, (ScriptContext::UI | ScriptContext::CLIENT | Sc
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushbool(sqvm, std::stoi(csv->dataPointers[nRow][nCol]));
g_pSquirrel[context]->pushbool(sqvm, std::stoi(csv->dataPointers[nRow][nCol]));
return SQRESULT_NOTNULL;
}
@ -418,17 +418,17 @@ REPLACE_SQFUNC(GetDataTableVector, (ScriptContext::UI | ScriptContext::CLIENT |
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableVector"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableVector"](sqvm);
CSVData* csv = *pData;
const int nRow = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nCol = g_pSquirrel<context>->getinteger(sqvm, 3);
const int nRow = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nCol = g_pSquirrel[context]->getinteger(sqvm, 3);
if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size())
{
g_pSquirrel<context>->raiseerror(
g_pSquirrel[context]->raiseerror(
sqvm,
fmt::format(
"row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size())
@ -436,7 +436,7 @@ REPLACE_SQFUNC(GetDataTableVector, (ScriptContext::UI | ScriptContext::CLIENT |
return SQRESULT_ERROR;
}
g_pSquirrel<context>->pushvector(sqvm, StringToVector(csv->dataPointers[nRow][nCol]));
g_pSquirrel[context]->pushvector(sqvm, StringToVector(csv->dataPointers[nRow][nCol]));
return SQRESULT_NOTNULL;
}
@ -445,24 +445,24 @@ REPLACE_SQFUNC(GetDataTableRowMatchingStringValue, (ScriptContext::UI | ScriptCo
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingStringValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowMatchingStringValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const char* pStringVal = g_pSquirrel<context>->getstring(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const char* pStringVal = g_pSquirrel[context]->getstring(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (!strcmp(csv->dataPointers[i][nCol], pStringVal))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -471,25 +471,25 @@ REPLACE_SQFUNC(GetDataTableRowMatchingAssetValue, (ScriptContext::UI | ScriptCon
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingAssetValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowMatchingAssetValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const char* pStringVal;
g_pSquirrel<context>->getasset(sqvm, 3, &pStringVal);
g_pSquirrel[context]->getasset(sqvm, 3, &pStringVal);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (!strcmp(csv->dataPointers[i][nCol], pStringVal))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -498,24 +498,24 @@ REPLACE_SQFUNC(GetDataTableRowMatchingFloatValue, (ScriptContext::UI | ScriptCon
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingFloatValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowMatchingFloatValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const float flFloatVal = g_pSquirrel<context>->getfloat(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const float flFloatVal = g_pSquirrel[context]->getfloat(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (flFloatVal == std::stof(csv->dataPointers[i][nCol]))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -524,24 +524,24 @@ REPLACE_SQFUNC(GetDataTableRowMatchingIntValue, (ScriptContext::UI | ScriptConte
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingIntValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowMatchingIntValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nIntVal = g_pSquirrel<context>->getinteger(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nIntVal = g_pSquirrel[context]->getinteger(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (nIntVal == std::stoi(csv->dataPointers[i][nCol]))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -550,25 +550,25 @@ REPLACE_SQFUNC(GetDataTableRowMatchingVectorValue, (ScriptContext::UI | ScriptCo
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowMatchingVectorValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowMatchingVectorValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const Vector3 vVectorVal = g_pSquirrel<context>->getvector(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const Vector3 vVectorVal = g_pSquirrel[context]->getvector(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (vVectorVal == StringToVector(csv->dataPointers[i][nCol]))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -577,25 +577,25 @@ REPLACE_SQFUNC(GetDataTableRowGreaterThanOrEqualToIntValue, (ScriptContext::UI |
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowGreaterThanOrEqualToIntValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowGreaterThanOrEqualToIntValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nIntVal = g_pSquirrel<context>->getinteger(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nIntVal = g_pSquirrel[context]->getinteger(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (nIntVal >= std::stoi(csv->dataPointers[i][nCol]))
{
spdlog::info("datatable not loaded");
g_pSquirrel<context>->pushinteger(sqvm, 1);
g_pSquirrel[context]->pushinteger(sqvm, 1);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -604,24 +604,24 @@ REPLACE_SQFUNC(GetDataTableRowLessThanOrEqualToIntValue, (ScriptContext::UI | Sc
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowLessThanOrEqualToIntValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowLessThanOrEqualToIntValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const int nIntVal = g_pSquirrel<context>->getinteger(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const int nIntVal = g_pSquirrel[context]->getinteger(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (nIntVal <= std::stoi(csv->dataPointers[i][nCol]))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -630,24 +630,24 @@ REPLACE_SQFUNC(GetDataTableRowGreaterThanOrEqualToFloatValue, (ScriptContext::UI
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowGreaterThanOrEqualToFloatValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowGreaterThanOrEqualToFloatValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const float flFloatVal = g_pSquirrel<context>->getfloat(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const float flFloatVal = g_pSquirrel[context]->getfloat(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (flFloatVal >= std::stof(csv->dataPointers[i][nCol]))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -656,24 +656,24 @@ REPLACE_SQFUNC(GetDataTableRowLessThanOrEqualToFloatValue, (ScriptContext::UI |
{
CSVData** pData;
uint64_t typeId;
g_pSquirrel<context>->getuserdata(sqvm, 2, &pData, &typeId);
g_pSquirrel[context]->getuserdata(sqvm, 2, &pData, &typeId);
if (typeId != USERDATA_TYPE_DATATABLE_CUSTOM)
return g_pSquirrel<context>->m_funcOriginals["GetDataTableRowLessThanOrEqualToFloatValue"](sqvm);
return g_pSquirrel[context]->m_funcOriginals["GetDataTableRowLessThanOrEqualToFloatValue"](sqvm);
CSVData* csv = *pData;
int nCol = g_pSquirrel<context>->getinteger(sqvm, 2);
const float flFloatVal = g_pSquirrel<context>->getfloat(sqvm, 3);
int nCol = g_pSquirrel[context]->getinteger(sqvm, 2);
const float flFloatVal = g_pSquirrel[context]->getfloat(sqvm, 3);
for (int i = 0; i < csv->dataPointers.size(); i++)
{
if (flFloatVal <= std::stof(csv->dataPointers[i][nCol]))
{
g_pSquirrel<context>->pushinteger(sqvm, i);
g_pSquirrel[context]->pushinteger(sqvm, i);
return SQRESULT_NOTNULL;
}
}
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}

View file

@ -243,7 +243,7 @@ template <ScriptContext context> int HttpRequestHandler::MakeHttpRequest(const H
spdlog::warn(
"HttpRequestHandler::MakeHttpRequest attempted to make a request to a private network. This is only allowed when "
"running the game with -allowlocalhttp.");
g_pSquirrel<context>->AsyncCall(
g_pSquirrel[context]->AsyncCall(
"NSHandleFailedHttpRequest",
handle,
(int)0,
@ -257,7 +257,7 @@ template <ScriptContext context> int HttpRequestHandler::MakeHttpRequest(const H
if (!curl)
{
spdlog::error("HttpRequestHandler::MakeHttpRequest failed to init libcurl for request.");
g_pSquirrel<context>->AsyncCall(
g_pSquirrel[context]->AsyncCall(
"NSHandleFailedHttpRequest", handle, static_cast<int>(CURLE_FAILED_INIT), curl_easy_strerror(CURLE_FAILED_INIT));
return;
}
@ -419,7 +419,7 @@ template <ScriptContext context> int HttpRequestHandler::MakeHttpRequest(const H
// Squirrel side will handle firing the correct callback.
long httpCode = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
g_pSquirrel<context>->AsyncCall(
g_pSquirrel[context]->AsyncCall(
"NSHandleSuccessfulHttpRequest", handle, static_cast<int>(httpCode), bodyBuffer, headerBuffer);
}
else
@ -436,7 +436,7 @@ template <ScriptContext context> int HttpRequestHandler::MakeHttpRequest(const H
"Keep in mind this is potentially dangerous!");
}
g_pSquirrel<context>->AsyncCall(
g_pSquirrel[context]->AsyncCall(
"NSHandleFailedHttpRequest", handle, static_cast<int>(result), curl_easy_strerror(result));
}
}
@ -457,7 +457,7 @@ template <ScriptContext context> SQRESULT SQ_InternalMakeHttpRequest(HSQUIRRELVM
if (!g_httpRequestHandler || !g_httpRequestHandler->IsRunning())
{
spdlog::warn("NS_InternalMakeHttpRequest called while the http request handler isn't running.");
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
@ -465,13 +465,13 @@ template <ScriptContext context> SQRESULT SQ_InternalMakeHttpRequest(HSQUIRRELVM
{
spdlog::warn("NS_InternalMakeHttpRequest called while the game is running with -disablehttprequests."
" Please check if requests are allowed using NSIsHttpEnabled() first.");
g_pSquirrel<context>->pushinteger(sqvm, -1);
g_pSquirrel[context]->pushinteger(sqvm, -1);
return SQRESULT_NOTNULL;
}
HttpRequest request;
request.method = static_cast<HttpRequestMethod::Type>(g_pSquirrel<context>->getinteger(sqvm, 1));
request.baseUrl = g_pSquirrel<context>->getstring(sqvm, 2);
request.method = static_cast<HttpRequestMethod::Type>(g_pSquirrel[context]->getinteger(sqvm, 1));
request.baseUrl = g_pSquirrel[context]->getstring(sqvm, 2);
// Read the tables for headers and query parameters.
SQTable* headerTable = sqvm->_stackOfCurrentFunction[3]._VAL.asTable;
@ -518,33 +518,33 @@ template <ScriptContext context> SQRESULT SQ_InternalMakeHttpRequest(HSQUIRRELVM
}
}
request.contentType = g_pSquirrel<context>->getstring(sqvm, 5);
request.body = g_pSquirrel<context>->getstring(sqvm, 6);
request.timeout = g_pSquirrel<context>->getinteger(sqvm, 7);
request.userAgent = g_pSquirrel<context>->getstring(sqvm, 8);
request.contentType = g_pSquirrel[context]->getstring(sqvm, 5);
request.body = g_pSquirrel[context]->getstring(sqvm, 6);
request.timeout = g_pSquirrel[context]->getinteger(sqvm, 7);
request.userAgent = g_pSquirrel[context]->getstring(sqvm, 8);
int handle = g_httpRequestHandler->MakeHttpRequest<context>(request);
g_pSquirrel<context>->pushinteger(sqvm, handle);
g_pSquirrel[context]->pushinteger(sqvm, handle);
return SQRESULT_NOTNULL;
}
// bool NSIsHttpEnabled()
template <ScriptContext context> SQRESULT SQ_IsHttpEnabled(HSQUIRRELVM sqvm)
{
g_pSquirrel<context>->pushbool(sqvm, !IsHttpDisabled());
g_pSquirrel[context]->pushbool(sqvm, !IsHttpDisabled());
return SQRESULT_NOTNULL;
}
// bool NSIsLocalHttpAllowed()
template <ScriptContext context> SQRESULT SQ_IsLocalHttpAllowed(HSQUIRRELVM sqvm)
{
g_pSquirrel<context>->pushbool(sqvm, IsLocalHttpAllowed());
g_pSquirrel[context]->pushbool(sqvm, IsLocalHttpAllowed());
return SQRESULT_NOTNULL;
}
template <ScriptContext context> void HttpRequestHandler::RegisterSQFuncs()
{
g_pSquirrel<context>->AddFuncRegistration(
g_pSquirrel[context]->AddFuncRegistration(
"int",
"NS_InternalMakeHttpRequest",
"int method, string baseUrl, table<string, array<string> > headers, table<string, array<string> > queryParams, string contentType, "
@ -553,14 +553,14 @@ template <ScriptContext context> void HttpRequestHandler::RegisterSQFuncs()
"[Internal use only] Passes the HttpRequest struct fields to be reconstructed in native and used for an http request",
SQ_InternalMakeHttpRequest<context>);
g_pSquirrel<context>->AddFuncRegistration(
g_pSquirrel[context]->AddFuncRegistration(
"bool",
"NSIsHttpEnabled",
"",
"Whether or not HTTP requests are enabled. You can opt-out by starting the game with -disablehttprequests.",
SQ_IsHttpEnabled<context>);
g_pSquirrel<context>->AddFuncRegistration(
g_pSquirrel[context]->AddFuncRegistration(
"bool",
"NSIsLocalHttpAllowed",
"",

View file

@ -1,6 +1,6 @@
#pragma once
enum class ScriptContext;
enum class ScriptContext : int;
// These definitions below should match on the Squirrel side so we can easily pass them along through a function.

View file

@ -12,7 +12,7 @@
template <ScriptContext context>
void DecodeJsonArray(HSQUIRRELVM sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr)
{
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
for (auto& itr : arr->GetArray())
{
@ -20,27 +20,27 @@ void DecodeJsonArray(HSQUIRRELVM sqvm, rapidjson::GenericValue<rapidjson::UTF8<c
{
case rapidjson::kObjectType:
DecodeJsonTable<context>(sqvm, &itr);
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->arrayappend(sqvm, -2);
break;
case rapidjson::kArrayType:
DecodeJsonArray<context>(sqvm, &itr);
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->arrayappend(sqvm, -2);
break;
case rapidjson::kStringType:
g_pSquirrel<context>->pushstring(sqvm, itr.GetString(), -1);
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushstring(sqvm, itr.GetString(), -1);
g_pSquirrel[context]->arrayappend(sqvm, -2);
break;
case rapidjson::kTrueType:
case rapidjson::kFalseType:
g_pSquirrel<context>->pushbool(sqvm, itr.GetBool());
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushbool(sqvm, itr.GetBool());
g_pSquirrel[context]->arrayappend(sqvm, -2);
break;
case rapidjson::kNumberType:
if (itr.IsDouble() || itr.IsFloat())
g_pSquirrel<context>->pushfloat(sqvm, itr.GetFloat());
g_pSquirrel[context]->pushfloat(sqvm, itr.GetFloat());
else
g_pSquirrel<context>->pushinteger(sqvm, itr.GetInt());
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushinteger(sqvm, itr.GetInt());
g_pSquirrel[context]->arrayappend(sqvm, -2);
break;
case rapidjson::kNullType:
break;
@ -51,48 +51,48 @@ void DecodeJsonArray(HSQUIRRELVM sqvm, rapidjson::GenericValue<rapidjson::UTF8<c
template <ScriptContext context>
void DecodeJsonTable(HSQUIRRELVM sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj)
{
g_pSquirrel<context>->newtable(sqvm);
g_pSquirrel[context]->newtable(sqvm);
for (auto itr = obj->MemberBegin(); itr != obj->MemberEnd(); itr++)
{
switch (itr->value.GetType())
{
case rapidjson::kObjectType:
g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel[context]->pushstring(sqvm, itr->name.GetString(), -1);
DecodeJsonTable<context>(
sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr->value);
g_pSquirrel<context>->newslot(sqvm, -3, false);
g_pSquirrel[context]->newslot(sqvm, -3, false);
break;
case rapidjson::kArrayType:
g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel[context]->pushstring(sqvm, itr->name.GetString(), -1);
DecodeJsonArray<context>(
sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr->value);
g_pSquirrel<context>->newslot(sqvm, -3, false);
g_pSquirrel[context]->newslot(sqvm, -3, false);
break;
case rapidjson::kStringType:
g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel<context>->pushstring(sqvm, itr->value.GetString(), -1);
g_pSquirrel[context]->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel[context]->pushstring(sqvm, itr->value.GetString(), -1);
g_pSquirrel<context>->newslot(sqvm, -3, false);
g_pSquirrel[context]->newslot(sqvm, -3, false);
break;
case rapidjson::kTrueType:
case rapidjson::kFalseType:
g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel<context>->pushbool(sqvm, itr->value.GetBool());
g_pSquirrel<context>->newslot(sqvm, -3, false);
g_pSquirrel[context]->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel[context]->pushbool(sqvm, itr->value.GetBool());
g_pSquirrel[context]->newslot(sqvm, -3, false);
break;
case rapidjson::kNumberType:
if (itr->value.IsDouble() || itr->value.IsFloat())
{
g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel<context>->pushfloat(sqvm, itr->value.GetFloat());
g_pSquirrel[context]->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel[context]->pushfloat(sqvm, itr->value.GetFloat());
}
else
{
g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel<context>->pushinteger(sqvm, itr->value.GetInt());
g_pSquirrel[context]->pushstring(sqvm, itr->name.GetString(), -1);
g_pSquirrel[context]->pushinteger(sqvm, itr->value.GetInt());
}
g_pSquirrel<context>->newslot(sqvm, -3, false);
g_pSquirrel[context]->newslot(sqvm, -3, false);
break;
case rapidjson::kNullType:
break;
@ -201,14 +201,14 @@ ADD_SQFUNC(
"converts a json string to a squirrel table",
ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER)
{
const char* pJson = g_pSquirrel<context>->getstring(sqvm, 1);
const bool bFatalParseErrors = g_pSquirrel<context>->getbool(sqvm, 2);
const char* pJson = g_pSquirrel[context]->getstring(sqvm, 1);
const bool bFatalParseErrors = g_pSquirrel[context]->getbool(sqvm, 2);
rapidjson_document doc;
doc.Parse(pJson);
if (doc.HasParseError())
{
g_pSquirrel<context>->newtable(sqvm);
g_pSquirrel[context]->newtable(sqvm);
std::string sErrorString = fmt::format(
"Failed parsing json file: encountered parse error \"{}\" at offset {}",
@ -217,7 +217,7 @@ ADD_SQFUNC(
if (bFatalParseErrors)
{
g_pSquirrel<context>->raiseerror(sqvm, sErrorString.c_str());
g_pSquirrel[context]->raiseerror(sqvm, sErrorString.c_str());
return SQRESULT_ERROR;
}
@ -249,6 +249,6 @@ ADD_SQFUNC(
doc.Accept(writer);
const char* pJsonString = buffer.GetString();
g_pSquirrel<context>->pushstring(sqvm, pJsonString, -1);
g_pSquirrel[context]->pushstring(sqvm, pJsonString, -1);
return SQRESULT_NOTNULL;
}

View file

@ -10,7 +10,7 @@ ADD_SQFUNC(
"converts a given string to an asset",
ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER)
{
g_pSquirrel<context>->pushasset(sqvm, g_pSquirrel<context>->getstring(sqvm, 1), -1);
g_pSquirrel[context]->pushasset(sqvm, g_pSquirrel[context]->getstring(sqvm, 1), -1);
return SQRESULT_NOTNULL;
}
@ -20,7 +20,7 @@ ADD_SQFUNC(
{
if (g_pLocalPlayerUserID)
{
g_pSquirrel<context>->pushstring(sqvm, g_pLocalPlayerUserID);
g_pSquirrel[context]->pushstring(sqvm, g_pLocalPlayerUserID);
return SQRESULT_NOTNULL;
}

View file

@ -9,19 +9,19 @@
ADD_SQFUNC("void", NSEarlyWritePlayerPersistenceForLeave, "entity player", "", ScriptContext::SERVER)
{
const CBasePlayer* pPlayer = g_pSquirrel<context>->template getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[context]->template getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
spdlog::warn("NSEarlyWritePlayerPersistenceForLeave got null player");
g_pSquirrel<context>->pushbool(sqvm, false);
g_pSquirrel[context]->pushbool(sqvm, false);
return SQRESULT_NOTNULL;
}
CBaseClient* pClient = &g_pClientArray[pPlayer->m_nPlayerIndex - 1];
if (g_pServerAuthentication->m_PlayerAuthenticationData.find(pClient) == g_pServerAuthentication->m_PlayerAuthenticationData.end())
{
g_pSquirrel<context>->pushbool(sqvm, false);
g_pSquirrel[context]->pushbool(sqvm, false);
return SQRESULT_NOTNULL;
}
@ -32,29 +32,29 @@ ADD_SQFUNC("void", NSEarlyWritePlayerPersistenceForLeave, "entity player", "", S
ADD_SQFUNC("bool", NSIsWritingPlayerPersistence, "", "", ScriptContext::SERVER)
{
g_pSquirrel<context>->pushbool(sqvm, g_pMasterServerManager->m_bSavingPersistentData);
g_pSquirrel[context]->pushbool(sqvm, g_pMasterServerManager->m_bSavingPersistentData);
return SQRESULT_NOTNULL;
}
ADD_SQFUNC("bool", NSIsPlayerLocalPlayer, "entity player", "", ScriptContext::SERVER)
{
const CBasePlayer* pPlayer = g_pSquirrel<ScriptContext::SERVER>->template getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[ScriptContext::SERVER]->template getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
spdlog::warn("NSIsPlayerLocalPlayer got null player");
g_pSquirrel<context>->pushbool(sqvm, false);
g_pSquirrel[context]->pushbool(sqvm, false);
return SQRESULT_NOTNULL;
}
CBaseClient* pClient = &g_pClientArray[pPlayer->m_nPlayerIndex - 1];
g_pSquirrel<context>->pushbool(sqvm, !strcmp(g_pLocalPlayerUserID, pClient->m_UID));
g_pSquirrel[context]->pushbool(sqvm, !strcmp(g_pLocalPlayerUserID, pClient->m_UID));
return SQRESULT_NOTNULL;
}
ADD_SQFUNC("bool", NSIsDedicated, "", "", ScriptContext::SERVER)
{
g_pSquirrel<context>->pushbool(sqvm, IsDedicatedServer());
g_pSquirrel[context]->pushbool(sqvm, IsDedicatedServer());
return SQRESULT_NOTNULL;
}
@ -65,14 +65,14 @@ ADD_SQFUNC(
"Disconnects the player from the server with the given reason",
ScriptContext::SERVER)
{
const CBasePlayer* pPlayer = g_pSquirrel<context>->template getentity<CBasePlayer>(sqvm, 1);
const char* reason = g_pSquirrel<context>->getstring(sqvm, 2);
const CBasePlayer* pPlayer = g_pSquirrel[context]->template getentity<CBasePlayer>(sqvm, 1);
const char* reason = g_pSquirrel[context]->getstring(sqvm, 2);
if (!pPlayer)
{
spdlog::warn("Attempted to call NSDisconnectPlayer() with null player.");
g_pSquirrel<context>->pushbool(sqvm, false);
g_pSquirrel[context]->pushbool(sqvm, false);
return SQRESULT_NOTNULL;
}
@ -82,7 +82,7 @@ ADD_SQFUNC(
{
spdlog::warn("NSDisconnectPlayer(): player entity has null CBaseClient!");
g_pSquirrel<context>->pushbool(sqvm, false);
g_pSquirrel[context]->pushbool(sqvm, false);
return SQRESULT_NOTNULL;
}
@ -95,6 +95,6 @@ ADD_SQFUNC(
CBaseClient__Disconnect(pClient, 1, "Disconnected by the server.");
}
g_pSquirrel<context>->pushbool(sqvm, true);
g_pSquirrel[context]->pushbool(sqvm, true);
return SQRESULT_NOTNULL;
}

View file

@ -7,18 +7,18 @@ ADD_SQFUNC("string", GetUserInfoKVString_Internal, "entity player, string key, s
"Gets the string value of a given player's userinfo convar by name", ScriptContext::SERVER)
// clang-format on
{
const CBasePlayer* pPlayer = g_pSquirrel<ScriptContext::SERVER>->template getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[ScriptContext::SERVER]->template getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, "player is null");
g_pSquirrel[ScriptContext::SERVER]->raiseerror(sqvm, "player is null");
return SQRESULT_ERROR;
}
const char* pKey = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2);
const char* pDefaultValue = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 3);
const char* pKey = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 2);
const char* pDefaultValue = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 3);
const char* pResult = g_pClientArray[pPlayer->m_nPlayerIndex - 1].m_ConVars->GetString(pKey, pDefaultValue);
g_pSquirrel<ScriptContext::SERVER>->pushstring(sqvm, pResult);
g_pSquirrel[ScriptContext::SERVER]->pushstring(sqvm, pResult);
return SQRESULT_NOTNULL;
}
@ -27,19 +27,19 @@ ADD_SQFUNC("asset", GetUserInfoKVAsset_Internal, "entity player, string key, ass
"Gets the asset value of a given player's userinfo convar by name", ScriptContext::SERVER)
// clang-format on
{
const CBasePlayer* pPlayer = g_pSquirrel<ScriptContext::SERVER>->template getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[ScriptContext::SERVER]->template getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, "player is null");
g_pSquirrel[ScriptContext::SERVER]->raiseerror(sqvm, "player is null");
return SQRESULT_ERROR;
}
const char* pKey = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2);
const char* pKey = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 2);
const char* pDefaultValue;
g_pSquirrel<ScriptContext::SERVER>->getasset(sqvm, 3, &pDefaultValue);
g_pSquirrel[ScriptContext::SERVER]->getasset(sqvm, 3, &pDefaultValue);
const char* pResult = g_pClientArray[pPlayer->m_nPlayerIndex - 1].m_ConVars->GetString(pKey, pDefaultValue);
g_pSquirrel<ScriptContext::SERVER>->pushasset(sqvm, pResult);
g_pSquirrel[ScriptContext::SERVER]->pushasset(sqvm, pResult);
return SQRESULT_NOTNULL;
}
@ -48,18 +48,18 @@ ADD_SQFUNC("int", GetUserInfoKVInt_Internal, "entity player, string key, int def
"Gets the int value of a given player's userinfo convar by name", ScriptContext::SERVER)
// clang-format on
{
const CBasePlayer* pPlayer = g_pSquirrel<ScriptContext::SERVER>->template getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[ScriptContext::SERVER]->template getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, "player is null");
g_pSquirrel[ScriptContext::SERVER]->raiseerror(sqvm, "player is null");
return SQRESULT_ERROR;
}
const char* pKey = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2);
const int iDefaultValue = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 3);
const char* pKey = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 2);
const int iDefaultValue = g_pSquirrel[ScriptContext::SERVER]->getinteger(sqvm, 3);
const int iResult = g_pClientArray[pPlayer->m_nPlayerIndex - 1].m_ConVars->GetInt(pKey, iDefaultValue);
g_pSquirrel<ScriptContext::SERVER>->pushinteger(sqvm, iResult);
g_pSquirrel[ScriptContext::SERVER]->pushinteger(sqvm, iResult);
return SQRESULT_NOTNULL;
}
@ -68,18 +68,18 @@ ADD_SQFUNC("float", GetUserInfoKVFloat_Internal, "entity player, string key, flo
"Gets the float value of a given player's userinfo convar by name", ScriptContext::SERVER)
// clang-format on
{
const CBasePlayer* pPlayer = g_pSquirrel<ScriptContext::SERVER>->getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[ScriptContext::SERVER]->getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, "player is null");
g_pSquirrel[ScriptContext::SERVER]->raiseerror(sqvm, "player is null");
return SQRESULT_ERROR;
}
const char* pKey = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2);
const float flDefaultValue = g_pSquirrel<ScriptContext::SERVER>->getfloat(sqvm, 3);
const char* pKey = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 2);
const float flDefaultValue = g_pSquirrel[ScriptContext::SERVER]->getfloat(sqvm, 3);
const float flResult = g_pClientArray[pPlayer->m_nPlayerIndex - 1].m_ConVars->GetFloat(pKey, flDefaultValue);
g_pSquirrel<ScriptContext::SERVER>->pushfloat(sqvm, flResult);
g_pSquirrel[ScriptContext::SERVER]->pushfloat(sqvm, flResult);
return SQRESULT_NOTNULL;
}
@ -88,17 +88,17 @@ ADD_SQFUNC("bool", GetUserInfoKVBool_Internal, "entity player, string key, bool
"Gets the bool value of a given player's userinfo convar by name", ScriptContext::SERVER)
// clang-format on
{
const CBasePlayer* pPlayer = g_pSquirrel<ScriptContext::SERVER>->getentity<CBasePlayer>(sqvm, 1);
const CBasePlayer* pPlayer = g_pSquirrel[ScriptContext::SERVER]->getentity<CBasePlayer>(sqvm, 1);
if (!pPlayer)
{
g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, "player is null");
g_pSquirrel[ScriptContext::SERVER]->raiseerror(sqvm, "player is null");
return SQRESULT_ERROR;
}
const char* pKey = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2);
const bool bDefaultValue = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 3);
const char* pKey = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 2);
const bool bDefaultValue = g_pSquirrel[ScriptContext::SERVER]->getbool(sqvm, 3);
const bool bResult = g_pClientArray[pPlayer->m_nPlayerIndex - 1].m_ConVars->GetInt(pKey, bDefaultValue);
g_pSquirrel<ScriptContext::SERVER>->pushbool(sqvm, bResult);
g_pSquirrel[ScriptContext::SERVER]->pushbool(sqvm, bResult);
return SQRESULT_NOTNULL;
}

View file

@ -51,7 +51,7 @@ static void __fastcall h_CServerGameDLL__OnReceivedSayTextMessage(
if (!g_pServerLimits->CheckChatLimits(&g_pClientArray[senderPlayerId - 1]))
return;
SQRESULT result = g_pSquirrel<ScriptContext::SERVER>->Call(
SQRESULT result = g_pSquirrel[ScriptContext::SERVER]->Call(
"CServerGameDLL_ProcessMessageStartThread", static_cast<int>(senderPlayerId) - 1, text, isTeam);
if (result == SQRESULT_ERROR)
@ -111,9 +111,9 @@ void ChatBroadcastMessage(int fromPlayerIndex, int toPlayerIndex, const char* te
ADD_SQFUNC("void", NSSendMessage, "int playerIndex, string text, bool isTeam", "", ScriptContext::SERVER)
{
int playerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 1);
const char* text = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 2);
bool isTeam = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 3);
int playerIndex = g_pSquirrel[ScriptContext::SERVER]->getinteger(sqvm, 1);
const char* text = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 2);
bool isTeam = g_pSquirrel[ScriptContext::SERVER]->getbool(sqvm, 3);
ChatSendMessage(playerIndex, text, isTeam);
@ -127,16 +127,16 @@ ADD_SQFUNC(
"",
ScriptContext::SERVER)
{
int fromPlayerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 1);
int toPlayerIndex = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 2);
const char* text = g_pSquirrel<ScriptContext::SERVER>->getstring(sqvm, 3);
bool isTeam = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 4);
bool isDead = g_pSquirrel<ScriptContext::SERVER>->getbool(sqvm, 5);
int messageType = g_pSquirrel<ScriptContext::SERVER>->getinteger(sqvm, 6);
int fromPlayerIndex = g_pSquirrel[ScriptContext::SERVER]->getinteger(sqvm, 1);
int toPlayerIndex = g_pSquirrel[ScriptContext::SERVER]->getinteger(sqvm, 2);
const char* text = g_pSquirrel[ScriptContext::SERVER]->getstring(sqvm, 3);
bool isTeam = g_pSquirrel[ScriptContext::SERVER]->getbool(sqvm, 4);
bool isDead = g_pSquirrel[ScriptContext::SERVER]->getbool(sqvm, 5);
int messageType = g_pSquirrel[ScriptContext::SERVER]->getinteger(sqvm, 6);
if (messageType < 1)
{
g_pSquirrel<ScriptContext::SERVER>->raiseerror(sqvm, fmt::format("Invalid message type {}", messageType).c_str());
g_pSquirrel[ScriptContext::SERVER]->raiseerror(sqvm, fmt::format("Invalid message type {}", messageType).c_str());
return SQRESULT_ERROR;
}

View file

@ -34,7 +34,7 @@ void ConCommand_ns_end_reauth_and_leave_to_lobby(const CCommand& arg)
g_pCVar->FindVar("serverfilter")->SetValue(g_pServerAuthentication->m_RemoteAuthenticationData.begin()->first.c_str());
// weird way of checking, but check if client script vm is initialised, mainly just to allow players to cancel this
if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM)
if (g_pSquirrel[ScriptContext::CLIENT]->m_pSQVM)
{
g_pServerAuthentication->m_bNeedLocalAuthForNewgame = true;

View file

@ -17,6 +17,8 @@
AUTOHOOK_INIT()
SquirrelManagerManager g_pSquirrel;
std::shared_ptr<ColoredLogger> getSquirrelLoggerByContext(ScriptContext context)
{
switch (context)
@ -35,14 +37,19 @@ std::shared_ptr<ColoredLogger> getSquirrelLoggerByContext(ScriptContext context)
namespace NS::log
{
template <ScriptContext context> std::shared_ptr<spdlog::logger> squirrel_logger()
std::shared_ptr<spdlog::logger> squirrel_logger(ScriptContext context)
{
// 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
switch (context)
{
case ScriptContext::UI:
return SCRIPT_UI;
case ScriptContext::CLIENT:
return SCRIPT_CL;
case ScriptContext::SERVER:
return SCRIPT_SV;
default:
return std::shared_ptr<spdlog::logger>(nullptr);
}
}
}; // namespace NS::log
@ -159,13 +166,13 @@ const char* SQTypeNameFromID(int type)
return "";
}
template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquirrelVM* newSqvm)
void SquirrelManager::VMCreated(CSquirrelVM* newSqvm)
{
m_pSQVM = newSqvm;
for (SQFuncRegistration* funcReg : m_funcRegistrations)
{
spdlog::info("Registering {} function {}", GetContextName(context), funcReg->squirrelFuncName);
spdlog::info("Registering {} function {}", GetContextName(m_context), funcReg->squirrelFuncName);
RegisterSquirrelFunc(m_pSQVM, funcReg, 1);
}
@ -207,16 +214,16 @@ 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());
g_pSquirrel<context>->messageBuffer = new SquirrelMessageBuffer();
m_messageBuffer = new SquirrelMessageBuffer();
g_pPluginManager->InformSqvmCreated(newSqvm);
}
template <ScriptContext context> void SquirrelManager<context>::VMDestroyed()
void SquirrelManager::VMDestroyed()
{
// Call all registered mod Destroy callbacks.
if (g_pModManager)
{
NS::log::squirrel_logger<context>()->info("Calling Destroy callbacks for all loaded mods.");
m_logger->info("Calling Destroy callbacks for all loaded mods.");
for (const Mod& loadedMod : g_pModManager->m_LoadedMods)
{
@ -224,13 +231,13 @@ template <ScriptContext context> void SquirrelManager<context>::VMDestroyed()
{
for (const ModScriptCallback& callback : script.Callbacks)
{
if (callback.Context != context || callback.DestroyCallback.length() == 0)
if (callback.Context != m_context || callback.DestroyCallback.length() == 0)
{
continue;
}
Call(callback.DestroyCallback.c_str());
NS::log::squirrel_logger<context>()->info("Executed Destroy callback {}.", callback.DestroyCallback);
m_logger->info("Executed Destroy callback {}.", callback.DestroyCallback);
}
}
}
@ -241,19 +248,19 @@ template <ScriptContext context> void SquirrelManager<context>::VMDestroyed()
// Discard the previous vm and delete the message buffer.
m_pSQVM = nullptr;
delete g_pSquirrel<context>->messageBuffer;
g_pSquirrel<context>->messageBuffer = nullptr;
delete m_messageBuffer;
m_messageBuffer = nullptr;
}
template <ScriptContext context> void SquirrelManager<context>::ExecuteCode(const char* pCode)
void SquirrelManager::ExecuteCode(const char* pCode)
{
if (!m_pSQVM || !m_pSQVM->sqvm)
{
spdlog::error("Cannot execute code, {} squirrel vm is not initialised", GetContextName(context));
spdlog::error("Cannot execute code, {} squirrel vm is not initialised", GetContextName(m_context));
return;
}
spdlog::info("Executing {} script code {} ", GetContextName(context), pCode);
spdlog::info("Executing {} script code {} ", GetContextName(m_context), pCode);
// NOTE: SQBufferState doesn't strdup pCode!
SQBufferState bufferState = SQBufferState(pCode);
@ -269,7 +276,7 @@ template <ScriptContext context> void SquirrelManager<context>::ExecuteCode(cons
}
}
template <ScriptContext context> void SquirrelManager<context>::AddFuncRegistration(
void SquirrelManager::AddFuncRegistration(
std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func)
{
SQFuncRegistration* reg = new SQFuncRegistration;
@ -293,7 +300,7 @@ template <ScriptContext context> void SquirrelManager<context>::AddFuncRegistrat
m_funcRegistrations.push_back(reg);
}
template <ScriptContext context> SQRESULT SquirrelManager<context>::setupfunc(const SQChar* funcname)
SQRESULT SquirrelManager::setupfunc(const SQChar* funcname)
{
pushroottable(m_pSQVM->sqvm);
pushstring(m_pSQVM->sqvm, funcname, -1);
@ -305,7 +312,7 @@ template <ScriptContext context> SQRESULT SquirrelManager<context>::setupfunc(co
return result;
}
template <ScriptContext context> void SquirrelManager<context>::AddFuncOverride(std::string name, SQFunction func)
void SquirrelManager::AddFuncOverride(std::string name, SQFunction func)
{
m_funcOverrides[name] = func;
}
@ -322,9 +329,9 @@ template <ScriptContext context> void* __fastcall sq_compiler_createHook(HSQUIRR
{
// store whether errors generated from this compile should be fatal
if (IsUIVM(context, sqvm))
g_pSquirrel<ScriptContext::UI>->m_bFatalCompilationErrors = bShouldThrowError;
g_pSquirrel[ScriptContext::UI]->m_bFatalCompilationErrors = bShouldThrowError;
else
g_pSquirrel<context>->m_bFatalCompilationErrors = bShouldThrowError;
g_pSquirrel[context]->m_bFatalCompilationErrors = bShouldThrowError;
return sq_compiler_create<context>(sqvm, a2, a3, bShouldThrowError);
}
@ -344,7 +351,7 @@ template <ScriptContext context> SQInteger SQPrintHook(HSQUIRRELVM sqvm, const c
{
if (buf[charsWritten - 1] == '\n')
buf[charsWritten - 1] = '\0';
g_pSquirrel<context>->logger->info("{}", buf);
g_pSquirrel[context]->m_logger->info("{}", buf);
}
va_end(va);
@ -356,9 +363,9 @@ template <ScriptContext context> CSquirrelVM* __fastcall CreateNewVMHook(void* a
{
CSquirrelVM* sqvm = CreateNewVM<context>(a1, realContext);
if (realContext == ScriptContext::UI)
g_pSquirrel<ScriptContext::UI>->VMCreated(sqvm);
g_pSquirrel[ScriptContext::UI]->VMCreated(sqvm);
else
g_pSquirrel<context>->VMCreated(sqvm);
g_pSquirrel[context]->VMCreated(sqvm);
spdlog::info("CreateNewVM {} {}", GetContextName(realContext), (void*)sqvm);
return sqvm;
@ -374,8 +381,8 @@ template <ScriptContext context> bool __fastcall CSquirrelVM_initHook(CSquirrelV
{
std::string name = mod.initScript.substr(mod.initScript.find_last_of('/') + 1);
std::string path = std::string("scripts/vscripts/") + mod.initScript;
if (g_pSquirrel<context>->compilefile(vm, path.c_str(), name.c_str(), 0))
g_pSquirrel<context>->compilefile(vm, path.c_str(), name.c_str(), 1);
if (g_pSquirrel[context]->compilefile(vm, path.c_str(), name.c_str(), 0))
g_pSquirrel[context]->compilefile(vm, path.c_str(), name.c_str(), 1);
}
}
return ret;
@ -388,12 +395,12 @@ template <ScriptContext context> void __fastcall DestroyVMHook(void* a1, CSquirr
if (IsUIVM(context, sqvm->sqvm))
{
realContext = ScriptContext::UI;
g_pSquirrel<ScriptContext::UI>->VMDestroyed();
g_pSquirrel[ScriptContext::UI]->VMDestroyed();
DestroyVM<ScriptContext::CLIENT>(a1, sqvm); // If we pass UI here it crashes
}
else
{
g_pSquirrel<context>->VMDestroyed();
g_pSquirrel[context]->VMDestroyed();
DestroyVM<context>(a1, sqvm);
}
@ -404,12 +411,12 @@ template <ScriptContext context> void (*SQCompileError)(HSQUIRRELVM sqvm, const
template <ScriptContext context>
void __fastcall ScriptCompileErrorHook(HSQUIRRELVM sqvm, const char* error, const char* file, int line, int column)
{
bool bIsFatalError = g_pSquirrel<context>->m_bFatalCompilationErrors;
bool bIsFatalError = g_pSquirrel[context]->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<ScriptContext::UI>->m_bFatalCompilationErrors;
bIsFatalError = g_pSquirrel[ScriptContext::UI]->m_bFatalCompilationErrors;
}
auto logger = getSquirrelLoggerByContext(realContext);
@ -454,32 +461,32 @@ int64_t __fastcall RegisterSquirrelFunctionHook(CSquirrelVM* sqvm, SQFuncRegistr
{
if (IsUIVM(context, sqvm->sqvm))
{
if (g_pSquirrel<ScriptContext::UI>->m_funcOverrides.count(funcReg->squirrelFuncName))
if (g_pSquirrel[ScriptContext::UI]->m_funcOverrides.count(funcReg->squirrelFuncName))
{
g_pSquirrel<ScriptContext::UI>->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr;
funcReg->funcPtr = g_pSquirrel<ScriptContext::UI>->m_funcOverrides[funcReg->squirrelFuncName];
g_pSquirrel[ScriptContext::UI]->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr;
funcReg->funcPtr = g_pSquirrel[ScriptContext::UI]->m_funcOverrides[funcReg->squirrelFuncName];
spdlog::info("Replacing {} in UI", std::string(funcReg->squirrelFuncName));
}
return g_pSquirrel<ScriptContext::UI>->RegisterSquirrelFunc(sqvm, funcReg, unknown);
return g_pSquirrel[ScriptContext::UI]->RegisterSquirrelFunc(sqvm, funcReg, unknown);
}
if (g_pSquirrel<context>->m_funcOverrides.find(funcReg->squirrelFuncName) != g_pSquirrel<context>->m_funcOverrides.end())
if (g_pSquirrel[context]->m_funcOverrides.find(funcReg->squirrelFuncName) != g_pSquirrel[context]->m_funcOverrides.end())
{
g_pSquirrel<context>->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr;
funcReg->funcPtr = g_pSquirrel<context>->m_funcOverrides[funcReg->squirrelFuncName];
g_pSquirrel[context]->m_funcOriginals[funcReg->squirrelFuncName] = funcReg->funcPtr;
funcReg->funcPtr = g_pSquirrel[context]->m_funcOverrides[funcReg->squirrelFuncName];
spdlog::info("Replacing {} in Client", std::string(funcReg->squirrelFuncName));
}
return g_pSquirrel<context>->RegisterSquirrelFunc(sqvm, funcReg, unknown);
return g_pSquirrel[context]->RegisterSquirrelFunc(sqvm, funcReg, unknown);
}
template <ScriptContext context> void CheckFuncOverrides()
{
for (auto& [name, func] : g_pSquirrel<context>->m_funcOverrides)
for (auto& [name, func] : g_pSquirrel[context]->m_funcOverrides)
{
if (!g_pSquirrel<context>->m_funcOriginals.count(name))
g_pSquirrel<context>->logger->error("Failed to replace SQ function '{}' as it doesn't exist.", name);
if (!g_pSquirrel[context]->m_funcOriginals.count(name))
g_pSquirrel[context]->m_logger->error("Failed to replace SQ function '{}' as it doesn't exist.", name);
}
}
@ -558,13 +565,13 @@ template <ScriptContext context> bool __fastcall CallScriptInitCallbackHook(void
template <ScriptContext context> void ConCommand_script(const CCommand& args)
{
g_pSquirrel<context>->ExecuteCode(args.ArgS());
g_pSquirrel[context]->ExecuteCode(args.ArgS());
}
template <ScriptContext context> SQRESULT SQ_StubbedFunc(HSQUIRRELVM sqvm)
{
SQStackInfos si;
g_pSquirrel<context>->sq_stackinfos(sqvm, 0, si);
g_pSquirrel[context]->sq_stackinfos(sqvm, 0, si);
spdlog::warn("Blocking call to stubbed function {} in {}", si._name, GetContextName(context));
return SQRESULT_NULL;
@ -574,18 +581,18 @@ template <ScriptContext context> void StubUnsafeSQFuncs()
{
if (!CommandLine()->CheckParm("-allowunsafesqfuncs"))
{
g_pSquirrel<context>->AddFuncOverride("DevTextBufferWrite", SQ_StubbedFunc<context>);
g_pSquirrel<context>->AddFuncOverride("DevTextBufferClear", SQ_StubbedFunc<context>);
g_pSquirrel<context>->AddFuncOverride("DevTextBufferDumpToFile", SQ_StubbedFunc<context>);
g_pSquirrel<context>->AddFuncOverride("Dev_CommandLineAddParm", SQ_StubbedFunc<context>);
g_pSquirrel<context>->AddFuncOverride("DevP4Checkout", SQ_StubbedFunc<context>);
g_pSquirrel<context>->AddFuncOverride("DevP4Add", SQ_StubbedFunc<context>);
g_pSquirrel[context]->AddFuncOverride("DevTextBufferWrite", SQ_StubbedFunc<context>);
g_pSquirrel[context]->AddFuncOverride("DevTextBufferClear", SQ_StubbedFunc<context>);
g_pSquirrel[context]->AddFuncOverride("DevTextBufferDumpToFile", SQ_StubbedFunc<context>);
g_pSquirrel[context]->AddFuncOverride("Dev_CommandLineAddParm", SQ_StubbedFunc<context>);
g_pSquirrel[context]->AddFuncOverride("DevP4Checkout", SQ_StubbedFunc<context>);
g_pSquirrel[context]->AddFuncOverride("DevP4Add", SQ_StubbedFunc<context>);
}
}
template <ScriptContext context> void SquirrelManager<context>::ProcessMessageBuffer()
void SquirrelManager::ProcessMessageBuffer()
{
while (std::optional<SquirrelMessage> maybeMessage = messageBuffer->pop())
while (std::optional<SquirrelMessage> maybeMessage = m_messageBuffer->pop())
{
SquirrelMessage message = maybeMessage.value();
@ -593,8 +600,7 @@ template <ScriptContext context> void SquirrelManager<context>::ProcessMessageBu
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<context>()->error(
"ProcessMessageBuffer was unable to find function with name '{}'. Is it global?", message.functionName);
m_logger->error("ProcessMessageBuffer was unable to find function with name '{}'. Is it global?", message.functionName);
continue;
}
@ -620,15 +626,15 @@ ADD_SQFUNC(
"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)
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");
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());
g_pSquirrel[context]->pushstring(sqvm, mod->Name.c_str());
}
return SQRESULT_NOTNULL;
}
@ -640,14 +646,14 @@ ADD_SQFUNC(
"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)
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");
g_pSquirrel[context]->pushstring(sqvm, "Unknown");
}
else
{
g_pSquirrel<context>->pushstring(sqvm, mod->Name.c_str());
g_pSquirrel[context]->pushstring(sqvm, mod->Name.c_str());
}
return SQRESULT_NOTNULL;
}
@ -656,100 +662,97 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientSquirrel, ConCommand, (CModule module))
{
AUTOHOOK_DISPATCH_MODULE(client.dll)
g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst = module.Offset(0x12120).RCast<sq_defconstType>();
g_pSquirrel<ScriptContext::UI>->__sq_defconst = g_pSquirrel<ScriptContext::CLIENT>->__sq_defconst;
g_pSquirrel[ScriptContext::CLIENT]->__sq_defconst = module.Offset(0x12120).RCast<sq_defconstType>();
g_pSquirrel[ScriptContext::UI]->__sq_defconst = g_pSquirrel[ScriptContext::CLIENT]->__sq_defconst;
g_pSquirrel<ScriptContext::CLIENT>->__sq_compilebuffer = module.Offset(0x3110).RCast<sq_compilebufferType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushroottable = module.Offset(0x5860).RCast<sq_pushroottableType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_compilefile = module.Offset(0xF950).RCast<sq_compilefileType>();
g_pSquirrel<ScriptContext::UI>->__sq_compilebuffer = g_pSquirrel<ScriptContext::CLIENT>->__sq_compilebuffer;
g_pSquirrel<ScriptContext::UI>->__sq_pushroottable = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushroottable;
g_pSquirrel<ScriptContext::UI>->__sq_compilefile = g_pSquirrel<ScriptContext::CLIENT>->__sq_compilefile;
g_pSquirrel[ScriptContext::CLIENT]->__sq_compilebuffer = module.Offset(0x3110).RCast<sq_compilebufferType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushroottable = module.Offset(0x5860).RCast<sq_pushroottableType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_compilefile = module.Offset(0xF950).RCast<sq_compilefileType>();
g_pSquirrel[ScriptContext::UI]->__sq_compilebuffer = g_pSquirrel[ScriptContext::CLIENT]->__sq_compilebuffer;
g_pSquirrel[ScriptContext::UI]->__sq_pushroottable = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushroottable;
g_pSquirrel[ScriptContext::UI]->__sq_compilefile = g_pSquirrel[ScriptContext::CLIENT]->__sq_compilefile;
g_pSquirrel<ScriptContext::CLIENT>->__sq_call = module.Offset(0x8650).RCast<sq_callType>();
g_pSquirrel<ScriptContext::UI>->__sq_call = g_pSquirrel<ScriptContext::CLIENT>->__sq_call;
g_pSquirrel[ScriptContext::CLIENT]->__sq_call = module.Offset(0x8650).RCast<sq_callType>();
g_pSquirrel[ScriptContext::UI]->__sq_call = g_pSquirrel[ScriptContext::CLIENT]->__sq_call;
g_pSquirrel<ScriptContext::CLIENT>->__sq_newarray = module.Offset(0x39F0).RCast<sq_newarrayType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_arrayappend = module.Offset(0x3C70).RCast<sq_arrayappendType>();
g_pSquirrel<ScriptContext::UI>->__sq_newarray = g_pSquirrel<ScriptContext::CLIENT>->__sq_newarray;
g_pSquirrel<ScriptContext::UI>->__sq_arrayappend = g_pSquirrel<ScriptContext::CLIENT>->__sq_arrayappend;
g_pSquirrel[ScriptContext::CLIENT]->__sq_newarray = module.Offset(0x39F0).RCast<sq_newarrayType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_arrayappend = module.Offset(0x3C70).RCast<sq_arrayappendType>();
g_pSquirrel[ScriptContext::UI]->__sq_newarray = g_pSquirrel[ScriptContext::CLIENT]->__sq_newarray;
g_pSquirrel[ScriptContext::UI]->__sq_arrayappend = g_pSquirrel[ScriptContext::CLIENT]->__sq_arrayappend;
g_pSquirrel<ScriptContext::CLIENT>->__sq_newtable = module.Offset(0x3960).RCast<sq_newtableType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_newslot = module.Offset(0x70B0).RCast<sq_newslotType>();
g_pSquirrel<ScriptContext::UI>->__sq_newtable = g_pSquirrel<ScriptContext::CLIENT>->__sq_newtable;
g_pSquirrel<ScriptContext::UI>->__sq_newslot = g_pSquirrel<ScriptContext::CLIENT>->__sq_newslot;
g_pSquirrel[ScriptContext::CLIENT]->__sq_newtable = module.Offset(0x3960).RCast<sq_newtableType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_newslot = module.Offset(0x70B0).RCast<sq_newslotType>();
g_pSquirrel[ScriptContext::UI]->__sq_newtable = g_pSquirrel[ScriptContext::CLIENT]->__sq_newtable;
g_pSquirrel[ScriptContext::UI]->__sq_newslot = g_pSquirrel[ScriptContext::CLIENT]->__sq_newslot;
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushstring = module.Offset(0x3440).RCast<sq_pushstringType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushinteger = module.Offset(0x36A0).RCast<sq_pushintegerType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushfloat = module.Offset(0x3800).RCast<sq_pushfloatType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushbool = module.Offset(0x3710).RCast<sq_pushboolType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushasset = module.Offset(0x3560).RCast<sq_pushassetType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushvector = module.Offset(0x3780).RCast<sq_pushvectorType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushobject = module.Offset(0x83D0).RCast<sq_pushobjectType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_raiseerror = module.Offset(0x8470).RCast<sq_raiseerrorType>();
g_pSquirrel<ScriptContext::UI>->__sq_pushstring = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushstring;
g_pSquirrel<ScriptContext::UI>->__sq_pushinteger = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushinteger;
g_pSquirrel<ScriptContext::UI>->__sq_pushfloat = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushfloat;
g_pSquirrel<ScriptContext::UI>->__sq_pushbool = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushbool;
g_pSquirrel<ScriptContext::UI>->__sq_pushvector = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushvector;
g_pSquirrel<ScriptContext::UI>->__sq_pushasset = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushasset;
g_pSquirrel<ScriptContext::UI>->__sq_pushobject = g_pSquirrel<ScriptContext::CLIENT>->__sq_pushobject;
g_pSquirrel<ScriptContext::UI>->__sq_raiseerror = g_pSquirrel<ScriptContext::CLIENT>->__sq_raiseerror;
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushstring = module.Offset(0x3440).RCast<sq_pushstringType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushinteger = module.Offset(0x36A0).RCast<sq_pushintegerType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushfloat = module.Offset(0x3800).RCast<sq_pushfloatType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushbool = module.Offset(0x3710).RCast<sq_pushboolType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushasset = module.Offset(0x3560).RCast<sq_pushassetType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushvector = module.Offset(0x3780).RCast<sq_pushvectorType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_pushobject = module.Offset(0x83D0).RCast<sq_pushobjectType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_raiseerror = module.Offset(0x8470).RCast<sq_raiseerrorType>();
g_pSquirrel[ScriptContext::UI]->__sq_pushstring = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushstring;
g_pSquirrel[ScriptContext::UI]->__sq_pushinteger = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushinteger;
g_pSquirrel[ScriptContext::UI]->__sq_pushfloat = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushfloat;
g_pSquirrel[ScriptContext::UI]->__sq_pushbool = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushbool;
g_pSquirrel[ScriptContext::UI]->__sq_pushvector = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushvector;
g_pSquirrel[ScriptContext::UI]->__sq_pushasset = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushasset;
g_pSquirrel[ScriptContext::UI]->__sq_pushobject = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushobject;
g_pSquirrel[ScriptContext::UI]->__sq_raiseerror = g_pSquirrel[ScriptContext::CLIENT]->__sq_raiseerror;
g_pSquirrel<ScriptContext::CLIENT>->__sq_getstring = module.Offset(0x60C0).RCast<sq_getstringType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getinteger = module.Offset(0x60E0).RCast<sq_getintegerType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getfloat = module.Offset(0x6100).RCast<sq_getfloatType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getbool = module.Offset(0x6130).RCast<sq_getboolType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_get = module.Offset(0x7C30).RCast<sq_getType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getasset = module.Offset(0x6010).RCast<sq_getassetType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getuserdata = module.Offset(0x63D0).RCast<sq_getuserdataType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getvector = module.Offset(0x6140).RCast<sq_getvectorType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getthisentity = module.Offset(0x12F80).RCast<sq_getthisentityType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getobject = module.Offset(0x6160).RCast<sq_getobjectType>();
g_pSquirrel<ScriptContext::UI>->__sq_getstring = g_pSquirrel<ScriptContext::CLIENT>->__sq_getstring;
g_pSquirrel<ScriptContext::UI>->__sq_getinteger = g_pSquirrel<ScriptContext::CLIENT>->__sq_getinteger;
g_pSquirrel<ScriptContext::UI>->__sq_getfloat = g_pSquirrel<ScriptContext::CLIENT>->__sq_getfloat;
g_pSquirrel<ScriptContext::UI>->__sq_getbool = g_pSquirrel<ScriptContext::CLIENT>->__sq_getbool;
g_pSquirrel<ScriptContext::UI>->__sq_get = g_pSquirrel<ScriptContext::CLIENT>->__sq_get;
g_pSquirrel<ScriptContext::UI>->__sq_getasset = g_pSquirrel<ScriptContext::CLIENT>->__sq_getasset;
g_pSquirrel<ScriptContext::UI>->__sq_getuserdata = g_pSquirrel<ScriptContext::CLIENT>->__sq_getuserdata;
g_pSquirrel<ScriptContext::UI>->__sq_getvector = g_pSquirrel<ScriptContext::CLIENT>->__sq_getvector;
g_pSquirrel<ScriptContext::UI>->__sq_getthisentity = g_pSquirrel<ScriptContext::CLIENT>->__sq_getthisentity;
g_pSquirrel<ScriptContext::UI>->__sq_getobject = g_pSquirrel<ScriptContext::CLIENT>->__sq_getobject;
g_pSquirrel[ScriptContext::CLIENT]->__sq_getstring = module.Offset(0x60C0).RCast<sq_getstringType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getinteger = module.Offset(0x60E0).RCast<sq_getintegerType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getfloat = module.Offset(0x6100).RCast<sq_getfloatType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getbool = module.Offset(0x6130).RCast<sq_getboolType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_get = module.Offset(0x7C30).RCast<sq_getType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getasset = module.Offset(0x6010).RCast<sq_getassetType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getuserdata = module.Offset(0x63D0).RCast<sq_getuserdataType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getvector = module.Offset(0x6140).RCast<sq_getvectorType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getthisentity = module.Offset(0x12F80).RCast<sq_getthisentityType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getobject = module.Offset(0x6160).RCast<sq_getobjectType>();
g_pSquirrel[ScriptContext::UI]->__sq_getstring = g_pSquirrel[ScriptContext::CLIENT]->__sq_getstring;
g_pSquirrel[ScriptContext::UI]->__sq_getinteger = g_pSquirrel[ScriptContext::CLIENT]->__sq_getinteger;
g_pSquirrel[ScriptContext::UI]->__sq_getfloat = g_pSquirrel[ScriptContext::CLIENT]->__sq_getfloat;
g_pSquirrel[ScriptContext::UI]->__sq_getbool = g_pSquirrel[ScriptContext::CLIENT]->__sq_getbool;
g_pSquirrel[ScriptContext::UI]->__sq_get = g_pSquirrel[ScriptContext::CLIENT]->__sq_get;
g_pSquirrel[ScriptContext::UI]->__sq_getasset = g_pSquirrel[ScriptContext::CLIENT]->__sq_getasset;
g_pSquirrel[ScriptContext::UI]->__sq_getuserdata = g_pSquirrel[ScriptContext::CLIENT]->__sq_getuserdata;
g_pSquirrel[ScriptContext::UI]->__sq_getvector = g_pSquirrel[ScriptContext::CLIENT]->__sq_getvector;
g_pSquirrel[ScriptContext::UI]->__sq_getthisentity = g_pSquirrel[ScriptContext::CLIENT]->__sq_getthisentity;
g_pSquirrel[ScriptContext::UI]->__sq_getobject = g_pSquirrel[ScriptContext::CLIENT]->__sq_getobject;
g_pSquirrel<ScriptContext::CLIENT>->__sq_createuserdata = module.Offset(0x38D0).RCast<sq_createuserdataType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_setuserdatatypeid = module.Offset(0x6490).RCast<sq_setuserdatatypeidType>();
g_pSquirrel<ScriptContext::UI>->__sq_createuserdata = g_pSquirrel<ScriptContext::CLIENT>->__sq_createuserdata;
g_pSquirrel<ScriptContext::UI>->__sq_setuserdatatypeid = g_pSquirrel<ScriptContext::CLIENT>->__sq_setuserdatatypeid;
g_pSquirrel[ScriptContext::CLIENT]->__sq_createuserdata = module.Offset(0x38D0).RCast<sq_createuserdataType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_setuserdatatypeid = module.Offset(0x6490).RCast<sq_setuserdatatypeidType>();
g_pSquirrel[ScriptContext::UI]->__sq_createuserdata = g_pSquirrel[ScriptContext::CLIENT]->__sq_createuserdata;
g_pSquirrel[ScriptContext::UI]->__sq_setuserdatatypeid = g_pSquirrel[ScriptContext::CLIENT]->__sq_setuserdatatypeid;
g_pSquirrel<ScriptContext::CLIENT>->__sq_GetEntityConstant_CBaseEntity = module.Offset(0x3E49B0).RCast<sq_GetEntityConstantType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_getentityfrominstance = module.Offset(0x114F0).RCast<sq_getentityfrominstanceType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_createscriptinstance = module.Offset(0xC20E0).RCast<sq_createscriptinstanceType>();
g_pSquirrel<ScriptContext::UI>->__sq_GetEntityConstant_CBaseEntity =
g_pSquirrel<ScriptContext::CLIENT>->__sq_GetEntityConstant_CBaseEntity;
g_pSquirrel<ScriptContext::UI>->__sq_getentityfrominstance = g_pSquirrel<ScriptContext::CLIENT>->__sq_getentityfrominstance;
g_pSquirrel[ScriptContext::CLIENT]->__sq_GetEntityConstant_CBaseEntity = module.Offset(0x3E49B0).RCast<sq_GetEntityConstantType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_getentityfrominstance = module.Offset(0x114F0).RCast<sq_getentityfrominstanceType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_createscriptinstance = module.Offset(0xC20E0).RCast<sq_createscriptinstanceType>();
g_pSquirrel[ScriptContext::UI]->__sq_GetEntityConstant_CBaseEntity =
g_pSquirrel[ScriptContext::CLIENT]->__sq_GetEntityConstant_CBaseEntity;
g_pSquirrel[ScriptContext::UI]->__sq_getentityfrominstance = g_pSquirrel[ScriptContext::CLIENT]->__sq_getentityfrominstance;
// Message buffer stuff
g_pSquirrel<ScriptContext::UI>->messageBuffer = g_pSquirrel<ScriptContext::CLIENT>->messageBuffer;
g_pSquirrel<ScriptContext::CLIENT>->__sq_getfunction = module.Offset(0x6CB0).RCast<sq_getfunctionType>();
g_pSquirrel<ScriptContext::UI>->__sq_getfunction = g_pSquirrel<ScriptContext::CLIENT>->__sq_getfunction;
g_pSquirrel<ScriptContext::CLIENT>->__sq_stackinfos = module.Offset(0x35970).RCast<sq_stackinfosType>();
g_pSquirrel<ScriptContext::UI>->__sq_stackinfos = g_pSquirrel<ScriptContext::CLIENT>->__sq_stackinfos;
g_pSquirrel[ScriptContext::UI]->m_messageBuffer = g_pSquirrel[ScriptContext::CLIENT]->m_messageBuffer;
g_pSquirrel[ScriptContext::CLIENT]->__sq_getfunction = module.Offset(0x6CB0).RCast<sq_getfunctionType>();
g_pSquirrel[ScriptContext::UI]->__sq_getfunction = g_pSquirrel[ScriptContext::CLIENT]->__sq_getfunction;
g_pSquirrel[ScriptContext::CLIENT]->__sq_stackinfos = module.Offset(0x35970).RCast<sq_stackinfosType>();
g_pSquirrel[ScriptContext::UI]->__sq_stackinfos = g_pSquirrel[ScriptContext::CLIENT]->__sq_stackinfos;
// Structs
g_pSquirrel<ScriptContext::CLIENT>->__sq_pushnewstructinstance = module.Offset(0x5400).RCast<sq_pushnewstructinstanceType>();
g_pSquirrel<ScriptContext::CLIENT>->__sq_sealstructslot = module.Offset(0x5530).RCast<sq_sealstructslotType>();
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_pushnewstructinstance = module.Offset(0x5400).RCast<sq_pushnewstructinstanceType>();
g_pSquirrel[ScriptContext::CLIENT]->__sq_sealstructslot = module.Offset(0x5530).RCast<sq_sealstructslotType>();
g_pSquirrel[ScriptContext::UI]->__sq_pushnewstructinstance = g_pSquirrel[ScriptContext::CLIENT]->__sq_pushnewstructinstance;
g_pSquirrel[ScriptContext::UI]->__sq_sealstructslot = g_pSquirrel[ScriptContext::CLIENT]->__sq_sealstructslot;
MAKEHOOK(
module.Offset(0x108E0),
&RegisterSquirrelFunctionHook<ScriptContext::CLIENT>,
&g_pSquirrel<ScriptContext::CLIENT>->RegisterSquirrelFunc);
g_pSquirrel<ScriptContext::UI>->RegisterSquirrelFunc = g_pSquirrel<ScriptContext::CLIENT>->RegisterSquirrelFunc;
g_pSquirrel<ScriptContext::CLIENT>->logger = NS::log::SCRIPT_CL;
g_pSquirrel<ScriptContext::UI>->logger = NS::log::SCRIPT_UI;
&g_pSquirrel[ScriptContext::CLIENT]->RegisterSquirrelFunc);
g_pSquirrel[ScriptContext::UI]->RegisterSquirrelFunc = g_pSquirrel[ScriptContext::CLIENT]->RegisterSquirrelFunc;
// uiscript_reset concommand: don't loop forever if compilation fails
module.Offset(0x3C6E4C).NOP(6);
@ -778,61 +781,60 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module))
{
AUTOHOOK_DISPATCH_MODULE(server.dll)
g_pSquirrel<ScriptContext::SERVER>->__sq_defconst = module.Offset(0x1F550).RCast<sq_defconstType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_defconst = module.Offset(0x1F550).RCast<sq_defconstType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_compilebuffer = module.Offset(0x3110).RCast<sq_compilebufferType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushroottable = module.Offset(0x5840).RCast<sq_pushroottableType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_call = module.Offset(0x8620).RCast<sq_callType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_compilefile = module.Offset(0x1CD80).RCast<sq_compilefileType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_compilebuffer = module.Offset(0x3110).RCast<sq_compilebufferType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushroottable = module.Offset(0x5840).RCast<sq_pushroottableType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_call = module.Offset(0x8620).RCast<sq_callType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_compilefile = module.Offset(0x1CD80).RCast<sq_compilefileType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_newarray = module.Offset(0x39F0).RCast<sq_newarrayType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_arrayappend = module.Offset(0x3C70).RCast<sq_arrayappendType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_newarray = module.Offset(0x39F0).RCast<sq_newarrayType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_arrayappend = module.Offset(0x3C70).RCast<sq_arrayappendType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_newtable = module.Offset(0x3960).RCast<sq_newtableType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_newslot = module.Offset(0x7080).RCast<sq_newslotType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_newtable = module.Offset(0x3960).RCast<sq_newtableType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_newslot = module.Offset(0x7080).RCast<sq_newslotType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushstring = module.Offset(0x3440).RCast<sq_pushstringType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushinteger = module.Offset(0x36A0).RCast<sq_pushintegerType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushfloat = module.Offset(0x3800).RCast<sq_pushfloatType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushbool = module.Offset(0x3710).RCast<sq_pushboolType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushasset = module.Offset(0x3560).RCast<sq_pushassetType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushvector = module.Offset(0x3780).RCast<sq_pushvectorType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_pushobject = module.Offset(0x83A0).RCast<sq_pushobjectType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushstring = module.Offset(0x3440).RCast<sq_pushstringType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushinteger = module.Offset(0x36A0).RCast<sq_pushintegerType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushfloat = module.Offset(0x3800).RCast<sq_pushfloatType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushbool = module.Offset(0x3710).RCast<sq_pushboolType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushasset = module.Offset(0x3560).RCast<sq_pushassetType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushvector = module.Offset(0x3780).RCast<sq_pushvectorType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_pushobject = module.Offset(0x83A0).RCast<sq_pushobjectType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_raiseerror = module.Offset(0x8440).RCast<sq_raiseerrorType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_raiseerror = module.Offset(0x8440).RCast<sq_raiseerrorType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getstring = module.Offset(0x60A0).RCast<sq_getstringType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getinteger = module.Offset(0x60C0).RCast<sq_getintegerType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getfloat = module.Offset(0x60E0).RCast<sq_getfloatType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getbool = module.Offset(0x6110).RCast<sq_getboolType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getasset = module.Offset(0x5FF0).RCast<sq_getassetType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getuserdata = module.Offset(0x63B0).RCast<sq_getuserdataType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getvector = module.Offset(0x6120).RCast<sq_getvectorType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_get = module.Offset(0x7C00).RCast<sq_getType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getstring = module.Offset(0x60A0).RCast<sq_getstringType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getinteger = module.Offset(0x60C0).RCast<sq_getintegerType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getfloat = module.Offset(0x60E0).RCast<sq_getfloatType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getbool = module.Offset(0x6110).RCast<sq_getboolType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getasset = module.Offset(0x5FF0).RCast<sq_getassetType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getuserdata = module.Offset(0x63B0).RCast<sq_getuserdataType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getvector = module.Offset(0x6120).RCast<sq_getvectorType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_get = module.Offset(0x7C00).RCast<sq_getType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getthisentity = module.Offset(0x203B0).RCast<sq_getthisentityType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getobject = module.Offset(0x6140).RCast<sq_getobjectType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getthisentity = module.Offset(0x203B0).RCast<sq_getthisentityType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getobject = module.Offset(0x6140).RCast<sq_getobjectType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_createuserdata = module.Offset(0x38D0).RCast<sq_createuserdataType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_setuserdatatypeid = module.Offset(0x6470).RCast<sq_setuserdatatypeidType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_createuserdata = module.Offset(0x38D0).RCast<sq_createuserdataType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_setuserdatatypeid = module.Offset(0x6470).RCast<sq_setuserdatatypeidType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_GetEntityConstant_CBaseEntity = module.Offset(0x418AF0).RCast<sq_GetEntityConstantType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_getentityfrominstance = module.Offset(0x1E920).RCast<sq_getentityfrominstanceType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_createscriptinstance = module.Offset(0x43F2F0).RCast<sq_createscriptinstanceType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_GetEntityConstant_CBaseEntity = module.Offset(0x418AF0).RCast<sq_GetEntityConstantType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getentityfrominstance = module.Offset(0x1E920).RCast<sq_getentityfrominstanceType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_createscriptinstance = module.Offset(0x43F2F0).RCast<sq_createscriptinstanceType>();
g_pSquirrel<ScriptContext::SERVER>->logger = NS::log::SCRIPT_SV;
// Message buffer stuff
g_pSquirrel<ScriptContext::SERVER>->__sq_getfunction = module.Offset(0x6C80).RCast<sq_getfunctionType>();
g_pSquirrel<ScriptContext::SERVER>->__sq_stackinfos = module.Offset(0x35920).RCast<sq_stackinfosType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_getfunction = module.Offset(0x6C80).RCast<sq_getfunctionType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_stackinfos = module.Offset(0x35920).RCast<sq_stackinfosType>();
// Structs
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_pushnewstructinstance = module.Offset(0x53e0).RCast<sq_pushnewstructinstanceType>();
g_pSquirrel[ScriptContext::SERVER]->__sq_sealstructslot = module.Offset(0x5510).RCast<sq_sealstructslotType>();
MAKEHOOK(
module.Offset(0x1DD10),
&RegisterSquirrelFunctionHook<ScriptContext::SERVER>,
&g_pSquirrel<ScriptContext::SERVER>->RegisterSquirrelFunc);
&g_pSquirrel[ScriptContext::SERVER]->RegisterSquirrelFunc);
MAKEHOOK(module.Offset(0x8AA0), &sq_compiler_createHook<ScriptContext::SERVER>, &sq_compiler_create<ScriptContext::SERVER>);
@ -852,19 +854,3 @@ ON_DLL_LOAD_RELIESON("server.dll", ServerSquirrel, ConCommand, (CModule module))
StubUnsafeSQFuncs<ScriptContext::SERVER>();
}
void InitialiseSquirrelManagers()
{
g_pSquirrel<ScriptContext::CLIENT> = new SquirrelManager<ScriptContext::CLIENT>;
g_pSquirrel<ScriptContext::UI> = new SquirrelManager<ScriptContext::UI>;
g_pSquirrel<ScriptContext::SERVER> = new SquirrelManager<ScriptContext::SERVER>;
}
// needed to define implementations for squirrelmanager outside of squirrel.h without compiler errors
template class SquirrelManager<ScriptContext::SERVER>;
template class SquirrelManager<ScriptContext::CLIENT>;
template class SquirrelManager<ScriptContext::UI>;
template std::shared_ptr<spdlog::logger> NS::log::squirrel_logger<ScriptContext::SERVER>();
template std::shared_ptr<spdlog::logger> NS::log::squirrel_logger<ScriptContext::CLIENT>();
template std::shared_ptr<spdlog::logger> NS::log::squirrel_logger<ScriptContext::UI>();

View file

@ -4,6 +4,7 @@
#include "squirrelautobind.h"
#include "core/math/vector.h"
#include "mods/modmanager.h"
#include <vscript/languages/squirrel_re/vsquirrel.h>
namespace fs = std::filesystem;
@ -12,9 +13,9 @@ namespace fs = std::filesystem;
required to function
*/
template <ScriptContext context, typename T> inline void SqRecurseArgs(FunctionVector& v, T& arg);
template <typename T> inline void SqRecurseArgs(FunctionVector& v, T& arg);
template <ScriptContext context, typename T, typename... Args> inline void SqRecurseArgs(FunctionVector& v, T& arg, Args... args);
template <typename T, typename... Args> inline void SqRecurseArgs(FunctionVector& v, T& arg, Args... args);
/*
sanity below
@ -56,24 +57,38 @@ ScriptContext ScriptContextFromString(std::string string);
namespace NS::log
{
template <ScriptContext context> std::shared_ptr<spdlog::logger> squirrel_logger();
std::shared_ptr<spdlog::logger> squirrel_logger(ScriptContext context);
}; // namespace NS::log
// This base class means that only the templated functions have to be rebuilt for each template instance
// Cuts down on compile time by ~5 seconds
class SquirrelManagerBase
class SquirrelManager
{
protected:
std::vector<SQFuncRegistration*> m_funcRegistrations;
public:
ScriptContext m_context;
std::shared_ptr<spdlog::logger> m_logger;
CSquirrelVM* m_pSQVM;
std::map<std::string, SQFunction> m_funcOverrides = {};
std::map<std::string, SQFunction> m_funcOriginals = {};
bool m_bFatalCompilationErrors = false;
std::shared_ptr<spdlog::logger> logger;
public:
SquirrelManager(ScriptContext context)
{
m_pSQVM = nullptr;
m_context = context;
m_logger = NS::log::squirrel_logger(m_context);
}
void VMCreated(CSquirrelVM* newSqvm);
void VMDestroyed();
void ExecuteCode(const char* code);
void AddFuncRegistration(std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func);
SQRESULT setupfunc(const SQChar* funcname);
void AddFuncOverride(std::string name, SQFunction func);
void ProcessMessageBuffer();
#pragma region SQVM funcs
RegisterSquirrelFuncType RegisterSquirrelFunc;
@ -243,13 +258,9 @@ public:
inline SQRESULT sealstructslot(HSQUIRRELVM sqvm, const int fieldIndex) { return __sq_sealstructslot(sqvm, fieldIndex); }
#pragma endregion
};
template <ScriptContext context> class SquirrelManager : public virtual SquirrelManagerBase
{
public:
#pragma region MessageBuffer
SquirrelMessageBuffer* messageBuffer;
SquirrelMessageBuffer* m_messageBuffer;
template <typename... Args> SquirrelMessage AsyncCall(std::string funcname, Args... args)
{
@ -257,13 +268,13 @@ public:
// This is useful for things like threads and plugins, which do not run on the main thread
if (!m_pSQVM || !m_pSQVM->sqvm)
{
spdlog::error("AsyncCall {} was called on context {} while VM was not initialized.", funcname, GetContextName(context));
spdlog::error("AsyncCall {} was called on context {} while VM was not initialized.", funcname, GetContextName(m_context));
return SquirrelMessage();
}
FunctionVector functionVector;
SqRecurseArgs<context>(functionVector, args...);
SqRecurseArgs(this, functionVector, args...);
SquirrelMessage message = {funcname, functionVector};
messageBuffer->push(message);
m_messageBuffer->push(message);
return message;
}
@ -273,12 +284,12 @@ public:
// This is useful for things like threads and plugins, which do not run on the main thread
if (!m_pSQVM || !m_pSQVM->sqvm)
{
spdlog::error("AsyncCall {} was called on context {} while VM was not initialized.", funcname, GetContextName(context));
spdlog::error("AsyncCall {} was called on context {} while VM was not initialized.", funcname, GetContextName(m_context));
return SquirrelMessage();
}
FunctionVector functionVector = {};
SquirrelMessage message = {funcname, functionVector};
messageBuffer->push(message);
m_messageBuffer->push(message);
return message;
}
@ -291,7 +302,7 @@ public:
if (!m_pSQVM || !m_pSQVM->sqvm)
{
spdlog::error("{} was called on context {} while VM was not initialized.", __FUNCTION__, GetContextName(context));
spdlog::error("{} was called on context {} while VM was not initialized.", __FUNCTION__, GetContextName(m_context));
return SQRESULT_ERROR;
}
@ -299,7 +310,7 @@ public:
int result = sq_getfunction(m_pSQVM->sqvm, funcname, &functionobj, 0);
if (result != 0) // This func returns 0 on success for some reason
{
NS::log::squirrel_logger<context>()->error("Call was unable to find function with name '{}'. Is it global?", funcname);
m_logger->error("Call was unable to find function with name '{}'. Is it global?", funcname);
return SQRESULT_ERROR;
}
pushobject(m_pSQVM->sqvm, &functionobj); // Push the function object
@ -315,21 +326,21 @@ public:
// If you want to call into squirrel asynchronously, use `schedule_call` instead
if (!m_pSQVM || !m_pSQVM->sqvm)
{
spdlog::error("{} was called on context {} while VM was not initialized.", __FUNCTION__, GetContextName(context));
spdlog::error("{} was called on context {} while VM was not initialized.", __FUNCTION__, GetContextName(m_context));
return SQRESULT_ERROR;
}
SQObject functionobj {};
int result = sq_getfunction(m_pSQVM->sqvm, funcname, &functionobj, 0);
if (result != 0) // This func returns 0 on success for some reason
{
NS::log::squirrel_logger<context>()->error("Call was unable to find function with name '{}'. Is it global?", funcname);
m_logger->error("Call was unable to find function with name '{}'. Is it global?", funcname);
return SQRESULT_ERROR;
}
pushobject(m_pSQVM->sqvm, &functionobj); // Push the function object
pushroottable(m_pSQVM->sqvm); // Push root table
FunctionVector functionVector;
SqRecurseArgs<context>(functionVector, args...);
SqRecurseArgs(this, functionVector, args...);
for (auto& v : functionVector)
{
@ -341,22 +352,26 @@ public:
}
#pragma endregion
public:
SquirrelManager() { m_pSQVM = nullptr; }
void VMCreated(CSquirrelVM* newSqvm);
void VMDestroyed();
void ExecuteCode(const char* code);
void AddFuncRegistration(std::string returnType, std::string name, std::string argTypes, std::string helpText, SQFunction func);
SQRESULT setupfunc(const SQChar* funcname);
void AddFuncOverride(std::string name, SQFunction func);
void ProcessMessageBuffer();
};
template <ScriptContext context> SquirrelManager<context>* g_pSquirrel;
// just a wrapper that lets us still access SquirrelManagers using [] operators
class SquirrelManagerManager
{
public:
void InitialiseSquirrelManagers()
{
m_pSquirrel[static_cast<int>(ScriptContext::CLIENT)] = new SquirrelManager(ScriptContext::CLIENT);
m_pSquirrel[static_cast<int>(ScriptContext::UI)] = new SquirrelManager(ScriptContext::UI);
m_pSquirrel[static_cast<int>(ScriptContext::SERVER)] = new SquirrelManager(ScriptContext::SERVER);
}
void InitialiseSquirrelManagers();
SquirrelManager* operator[](ScriptContext context) { return m_pSquirrel[static_cast<int>(context)]; }
private:
SquirrelManager* m_pSquirrel[3] = {};
};
extern SquirrelManagerManager g_pSquirrel;
/*
Beware all ye who enter below.
@ -372,86 +387,83 @@ void InitialiseSquirrelManagers();
#ifndef MessageBufferFuncs
#define MessageBufferFuncs
// Bools
template <ScriptContext context, typename T>
template <typename T>
requires std::convertible_to<T, bool> && (!std::is_floating_point_v<T>) && (!std::convertible_to<T, std::string>) && (!std::convertible_to<T, int>)
inline VoidFunction SQMessageBufferPushArg(T& arg) {
return [arg]{ g_pSquirrel<context>->pushbool(g_pSquirrel<context>->m_pSQVM->sqvm, static_cast<bool>(arg)); };
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, T& arg) {
return [squirrel, arg]{ squirrel->pushbool(squirrel->m_pSQVM->sqvm, static_cast<bool>(arg)); };
}
// Vectors
template <ScriptContext context>
inline VoidFunction SQMessageBufferPushArg(Vector3& arg) {
return [arg]{ g_pSquirrel<context>->pushvector(g_pSquirrel<context>->m_pSQVM->sqvm, arg); };
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, Vector3& arg) {
return [squirrel, arg]{ squirrel->pushvector(squirrel->m_pSQVM->sqvm, arg); };
}
// Vectors
template <ScriptContext context>
inline VoidFunction SQMessageBufferPushArg(SQObject* arg) {
return [arg]{ g_pSquirrel<context>->pushobject(g_pSquirrel<context>->m_pSQVM->sqvm, arg); };
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, SQObject* arg) {
return [squirrel, arg]{ squirrel->pushobject(squirrel->m_pSQVM->sqvm, arg); };
}
// Ints
template <ScriptContext context, typename T>
template <typename T>
requires std::convertible_to<T, int> && (!std::is_floating_point_v<T>)
inline VoidFunction SQMessageBufferPushArg(T& arg) {
return [arg]{ g_pSquirrel<context>->pushinteger(g_pSquirrel<context>->m_pSQVM->sqvm, static_cast<int>(arg)); };
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, T& arg) {
return [squirrel, arg]{ squirrel->pushinteger(squirrel->m_pSQVM->sqvm, static_cast<int>(arg)); };
}
// Floats
template <ScriptContext context, typename T>
template <typename T>
requires std::convertible_to<T, float> && (std::is_floating_point_v<T>)
inline VoidFunction SQMessageBufferPushArg(T& arg) {
return [arg]{ g_pSquirrel<context>->pushfloat(g_pSquirrel<context>->m_pSQVM->sqvm, static_cast<float>(arg)); };
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, T& arg) {
return [squirrel, arg]{ squirrel->pushfloat(squirrel->m_pSQVM->sqvm, static_cast<float>(arg)); };
}
// Strings
template <ScriptContext context, typename T>
template <typename T>
requires (std::convertible_to<T, std::string> || std::is_constructible_v<std::string, T>)
inline VoidFunction SQMessageBufferPushArg(T& arg) {
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, T& arg) {
auto converted = std::string(arg);
return [converted]{ g_pSquirrel<context>->pushstring(g_pSquirrel<context>->m_pSQVM->sqvm, converted.c_str(), (int)converted.length()); };
return [squirrel, converted]{ squirrel->pushstring(squirrel->m_pSQVM->sqvm, converted.c_str(), (int)converted.length()); };
}
// Assets
template <ScriptContext context>
inline VoidFunction SQMessageBufferPushArg(SquirrelAsset& arg) {
return [arg]{ g_pSquirrel<context>->pushasset(g_pSquirrel<context>->m_pSQVM->sqvm, arg.path.c_str(), arg.path.length()); };
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, SquirrelAsset& arg) {
return [squirrel, arg]{ squirrel->pushasset(squirrel->m_pSQVM->sqvm, arg.path.c_str(), arg.path.length()); };
}
// Maps
template <ScriptContext context, typename T>
template <typename T>
requires is_iterable<T>
inline VoidFunction SQMessageBufferPushArg(T& arg) {
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, T& arg) {
FunctionVector localv = {};
localv.push_back([]{g_pSquirrel<context>->newarray(g_pSquirrel<context>->m_pSQVM->sqvm, 0);});
localv.push_back([squirrel]{squirrel->newarray(squirrel->m_pSQVM->sqvm, 0);});
for (const auto& item : arg) {
localv.push_back(SQMessageBufferPushArg<context>(item));
localv.push_back([]{g_pSquirrel<context>->arrayappend(g_pSquirrel<context>->m_pSQVM->sqvm, -2);});
localv.push_back(SQMessageBufferPushArg(squirrel, item));
localv.push_back([squirrel]{squirrel->arrayappend(squirrel->m_pSQVM->sqvm, -2);});
}
return [localv] { for (auto& func : localv) { func(); } };
}
// Vectors
template <ScriptContext context, typename T>
template <typename T>
requires is_map<T>
inline VoidFunction SQMessageBufferPushArg(T& map) {
inline VoidFunction SQMessageBufferPushArg(SquirrelManager* squirrel, T& map) {
FunctionVector localv = {};
localv.push_back([]{g_pSquirrel<context>->newtable(g_pSquirrel<context>->m_pSQVM->sqvm);});
localv.push_back([squirrel]{squirrel->newtable(squirrel->m_pSQVM->sqvm);});
for (const auto& item : map) {
localv.push_back(SQMessageBufferPushArg<context>(item.first));
localv.push_back(SQMessageBufferPushArg<context>(item.second));
localv.push_back([]{g_pSquirrel<context>->newslot(g_pSquirrel<context>->m_pSQVM->sqvm, -3, false);});
localv.push_back(SQMessageBufferPushArg(squirrel,item.first));
localv.push_back(SQMessageBufferPushArg(squirrel,item.second));
localv.push_back([squirrel]{squirrel->newslot(squirrel->m_pSQVM->sqvm, -3, false);});
}
return [localv]{ for (auto& func : localv) { func(); } };
}
template <ScriptContext context, typename T>
inline void SqRecurseArgs(FunctionVector& v, T& arg) {
v.push_back(SQMessageBufferPushArg<context>(arg));
template <typename T>
inline void SqRecurseArgs(SquirrelManager* squirrel, FunctionVector& v, T& arg) {
v.push_back(SQMessageBufferPushArg(squirrel, arg));
}
// This function is separated from the PushArg function so as to not generate too many template instances
// This is the main function responsible for unrolling the argument pack
template <ScriptContext context, typename T, typename... Args>
inline void SqRecurseArgs(FunctionVector& v, T& arg, Args... args) {
v.push_back(SQMessageBufferPushArg<context>(arg));
SqRecurseArgs<context>(v, args...);
template <typename T, typename... Args>
inline void SqRecurseArgs(SquirrelManager* squirrel, FunctionVector& v, T& arg, Args... args) {
v.push_back(SQMessageBufferPushArg(squirrel, arg));
SqRecurseArgs(squirrel, v, args...);
}
// clang-format on

View file

@ -22,16 +22,16 @@ class __squirrelautobind;
[]() \
{ \
if constexpr ((runOnContext)&ScriptContext::UI) \
g_pSquirrel<ScriptContext::UI>->AddFuncRegistration( \
g_pSquirrel[ScriptContext::UI]->AddFuncRegistration( \
returnType, __STR(funcName), argTypes, helpText, CONCAT2(Script_, funcName) < ScriptContext::UI >); \
if constexpr ((runOnContext)&ScriptContext::CLIENT) \
g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration( \
g_pSquirrel[ScriptContext::CLIENT]->AddFuncRegistration( \
returnType, __STR(funcName), argTypes, helpText, CONCAT2(Script_, funcName) < ScriptContext::CLIENT >); \
}, \
[]() \
{ \
if constexpr ((runOnContext)&ScriptContext::SERVER) \
g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration( \
g_pSquirrel[ScriptContext::SERVER]->AddFuncRegistration( \
returnType, __STR(funcName), argTypes, helpText, CONCAT2(Script_, funcName) < ScriptContext::SERVER >); \
}); \
} \
@ -45,15 +45,15 @@ class __squirrelautobind;
[]() \
{ \
if constexpr ((runOnContext)&ScriptContext::UI) \
g_pSquirrel<ScriptContext::UI>->AddFuncOverride(__STR(funcName), CONCAT2(Script_, funcName) < ScriptContext::UI >); \
g_pSquirrel[ScriptContext::UI]->AddFuncOverride(__STR(funcName), CONCAT2(Script_, funcName) < ScriptContext::UI >); \
if constexpr ((runOnContext)&ScriptContext::CLIENT) \
g_pSquirrel<ScriptContext::CLIENT>->AddFuncOverride( \
g_pSquirrel[ScriptContext::CLIENT]->AddFuncOverride( \
__STR(funcName), CONCAT2(Script_, funcName) < ScriptContext::CLIENT >); \
}, \
[]() \
{ \
if constexpr ((runOnContext)&ScriptContext::SERVER) \
g_pSquirrel<ScriptContext::SERVER>->AddFuncOverride( \
g_pSquirrel[ScriptContext::SERVER]->AddFuncOverride( \
__STR(funcName), CONCAT2(Script_, funcName) < ScriptContext::SERVER >); \
}); \
} \

View file

@ -167,12 +167,12 @@ ADD_SQFUNC(
// Maybe we should call this on mods reload instead
RefreshMapList();
g_pSquirrel<context>->newarray(sqvm, 0);
g_pSquirrel[context]->newarray(sqvm, 0);
for (MapVPKInfo& map : vMapList)
{
g_pSquirrel<context>->pushstring(sqvm, map.name.c_str());
g_pSquirrel<context>->arrayappend(sqvm, -2);
g_pSquirrel[context]->pushstring(sqvm, map.name.c_str());
g_pSquirrel[context]->arrayappend(sqvm, -2);
}
return SQRESULT_NOTNULL;