aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/scriptjson.cpp
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2022-10-17 23:26:07 +0100
committerGitHub <noreply@github.com>2022-10-17 23:26:07 +0100
commit841881af9ea6ec73b1d505d5a8f7c1f766273724 (patch)
tree91feb40fe810984b59d2d2da440e289370b0a137 /NorthstarDLL/scriptjson.cpp
parentdc0934d29caacc8da1e7df8b775d24b4e99c381c (diff)
downloadNorthstarLauncher-841881af9ea6ec73b1d505d5a8f7c1f766273724.tar.gz
NorthstarLauncher-841881af9ea6ec73b1d505d5a8f7c1f766273724.zip
big refactor (#171)v1.10.0-rc1
* use in-file macros rather than global funcs for registering dll load callbacks * move more things to macros * fix debug crashes * move sqvm funcs to sq managers * get rid of context file * refactor some squirrel stuff and ingame compilation error message * move tier0 and playlist funcs to namespaces * uiscript_reset concommand: don't loop forever if compilation fails * improve showing console for ui script compile errors * standardise concommand func naming in c++ * use lambdas for dll load callbacks so intellisense shits itself less * use cvar change callbacks for unescaping ns_server_name and ns_server_desc * add proper helpstrings to masterserver cvars * add cvar help and find * allow parsing of convar flags from string * normalise mod fs paths to be lowercase * move hoststate to its own file and add host_init hooks * better IsFlagSet def * replace files in ReadFromCache * rename g_ModManager to g_pModManager * formatting changes * make cvar print work on dedi, move demo fix stuff, add findflags * add proper map autocompletes and maps command * formatting changes * separate gameutils into multiple r2 headers * Update keyvalues.cpp * move sqvm funcs into wrappers in the manager class * remove unnecessary header files * lots of cleanup and starting moving to new hooking macros * update more stuff to new hook macros * rename project folder (:tf: commit log) * fix up postbuild commands to use relative dir * almost fully replaced hooking lib * completely remove old hooking * add nsprefix because i forgot to include it * move exploit prevention and limits code out of serverauthentication, and have actual defs for CBasePlayer * use modular ServerPresence system for registering servers * add new memory lib * accidentally pushed broke code oops * lots of stuff idk * implement some more prs * improve rpakfilesystem * fix line endings on vcxproj * Revert "fix line endings on vcxproj" This reverts commit 4ff7d022d2602c2dba37beba8b8df735cf5cd7d9. * add more prs * i swear i committed these how are they not there * Add ability to load Datatables from files (#238) * first version of kinda working custom datatables * Fix copy error * Finish custom datatables * Fix Merge * Fix line endings * Add fallback to rpak when ns_prefere_datatable_from_disk is true * fix typo * Bug fixess * Fix Function Registration hook * Set convar value * Fix Client and Ui VM * enable server auth with ms agian * Add Filters * FIx unused import * Merge remote-tracking branch 'upsteam/bobs-big-refactor-pr' into datatables Co-authored-by: RoyalBlue1 <realEmail@veryRealURL.com> * Add some changes from main to refactor (#243) * Add PR template * Update CI folder location * Delete startup args txt files * Fix line endings (hopefully) (#244) * Fix line endings (hopefully) * Fix more line endings * Update refactor (#250) * Add PR template * Update CI folder location * Delete startup args txt files * Add editorconfig file (#246) * Add editorconfig file It's a cross-editor compatible config file that defines certain editor behaviour (e.g. adding/removing newline at end of file) It is supported by major editors like Visual Studio (Code) and by version control providers like GitHub. Should end the constant adding/removing of final newline in PRs * More settings - unicode by default - trim newlines - use tabs for indentation (ugh) * Ignore folder rename (#245) * Hot reload banlist on player join (#233) * added banlist hotreload * fix formatting * didnt append, cleared whole file oopsie * unfuckedunban not rewriting file * fixed not checking for new line Co-authored-by: ScureX <47725553+ScureX@users.noreply.github.com> * Refactor cleanup (#256) * Fix indentation * Fix path in clang-format command in readme * Refactor cleanup (some formatting fixes) (#257) * Fix some formatting * More formatting fixes * add scriptdatatable.cpp rewrite * Some formatting fixes (#260) * More formatting stuff (#261) * various formatting changes and fixes * Fix changed icon (#264) * clang format, fix issues with server registration and rpak loading * fix more formatting * update postbuild step * set launcher directory and error on fail creating log files * change some stuff in exploitfixes * only unrestrict dev commands when commandline flag is present * fix issues with cvar flag commit * fixup command flags better and reformat * bring up to date with main * fixup formatting * improve cvar flag fixup and remove temp thing from findflags * set serverfilter better * avoid ptr decay when setting auth token * add more entity functions * Fix the MS server registration issues. (#285) * Port ms presence reporter to std::async * Fix crash due to std::optional being assigned nullptr. * Fix formatting. * Wait 20 seconds if MS returns DUPLICATE_SERVER. * Change PERSISTENCE_MAX_SIZE to fix player authentication (#287) The size check added in the refactor was incorrect: - 56306: expected pdata size based on the pdef - 512: allowance for trailing junk (r2 adds 137 bytes of trailing junk) - 100: for some wiggle room Co-Authored-By: pg9182 <96569817+pg9182@users.noreply.github.com> * change miscserverscript to use actual entity arguments rather than player index jank * Fix token clearing hook (#290) A certain someone forgot to put an `0x` in front of their hex number, meaning the offset is wrong. This would cause token to be leaked again Co-authored-by: Maya <malte.hoermeyer@web.de> Co-authored-by: RoyalBlue1 <realEmail@veryRealURL.com> Co-authored-by: GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> Co-authored-by: ScureX <47725553+ScureX@users.noreply.github.com> Co-authored-by: Erlite <ys.aameziane@gmail.com> Co-authored-by: Emma Miler <emma.pi@protonmail.com> Co-authored-by: pg9182 <96569817+pg9182@users.noreply.github.com>
Diffstat (limited to 'NorthstarDLL/scriptjson.cpp')
-rw-r--r--NorthstarDLL/scriptjson.cpp601
1 files changed, 137 insertions, 464 deletions
diff --git a/NorthstarDLL/scriptjson.cpp b/NorthstarDLL/scriptjson.cpp
index bc65a5c1..a9767615 100644
--- a/NorthstarDLL/scriptjson.cpp
+++ b/NorthstarDLL/scriptjson.cpp
@@ -1,502 +1,133 @@
#include "pch.h"
-#include "scriptjson.h"
+#include "squirrel.h"
+
+#include "rapidjson/error/en.h"
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
-#include "squirrel.h"
-
#ifdef _MSC_VER
#undef GetObject // fuck microsoft developers
#endif
-void SQ_EncodeJSON_Table(
- rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
- SQTable* sqTable,
- rapidjson_document* allocatorDoc);
-void SQ_EncodeJSON_Array(
- rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
- SQArray* sqArray,
- rapidjson_document* allocatorDoc);
-void ServerSq_DecodeJSON_Table(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj);
-void ServerSq_DecodeJSON_Array(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr);
-void ClientSq_DecodeJSON_Table(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj);
-void ClientSq_DecodeJSON_Array(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr);
-
-SQRESULT ServerSq_DecodeJSON(void* sqvm)
-{
- const char* json = ServerSq_getstring(sqvm, 1);
- rapidjson_document doc;
- doc.Parse(json);
- if (doc.HasParseError())
- {
- ServerSq_newTable(sqvm);
- return SQRESULT_NOTNULL;
- }
- ServerSq_newTable(sqvm);
-
- for (int i = 0; i < doc.MemberCount(); i++)
- {
-
- rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = doc.MemberBegin()[i];
-
- switch (itr.value.GetType())
- {
- case rapidjson::kObjectType:
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_DecodeJSON_Table(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kArrayType:
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_DecodeJSON_Array(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kStringType:
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushstring(sqvm, itr.value.GetString(), -1);
-
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kTrueType:
- if ((long long)itr.name.GetString() == -1)
- {
- spdlog::info("Neagative String decoding True");
- continue;
- }
-
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushbool(sqvm, true);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kFalseType:
- if ((long long)itr.name.GetString() == -1)
- {
-
- continue;
- }
-
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushbool(sqvm, false);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kNumberType:
- if (itr.value.IsDouble() || itr.value.IsFloat())
- {
-
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushfloat(sqvm, itr.value.GetFloat());
- }
- else
- {
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushinteger(sqvm, itr.value.GetInt());
- }
- ServerSq_newSlot(sqvm, -3, false);
- break;
- }
- }
- return SQRESULT_NOTNULL;
-}
-
-void ServerSq_DecodeJSON_Table(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj)
+template <ScriptContext context> void
+DecodeJsonArray(HSquirrelVM* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr)
{
- ServerSq_newTable(sqvm);
-
- for (int i = 0; i < obj->MemberCount(); i++)
- {
- rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = obj->MemberBegin()[i];
- if (!itr.name.IsString())
- {
- spdlog::info("Decoding table with non-string key");
- continue;
- }
- const char* key = itr.name.GetString();
- switch (itr.value.GetType())
- {
- case rapidjson::kObjectType:
- ServerSq_pushstring(sqvm, key, -1);
- ServerSq_DecodeJSON_Table(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kArrayType:
- ServerSq_pushstring(sqvm, key, -1);
- ServerSq_DecodeJSON_Array(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kStringType:
- ServerSq_pushstring(sqvm, key, -1);
- ServerSq_pushstring(sqvm, itr.value.GetString(), -1);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kTrueType:
-
- ServerSq_pushstring(sqvm, key, -1);
- ServerSq_pushbool(sqvm, true);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kFalseType:
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushbool(sqvm, false);
- ServerSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kNumberType:
- if (itr.value.IsDouble() || itr.value.IsFloat())
- {
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushfloat(sqvm, itr.value.GetFloat());
- }
- else
- {
- ServerSq_pushstring(sqvm, itr.name.GetString(), -1);
- ServerSq_pushinteger(sqvm, itr.value.GetInt());
- }
- ServerSq_newSlot(sqvm, -3, false);
- break;
- }
- }
-}
+ g_pSquirrel<context>->newarray(sqvm, 0);
-void ServerSq_DecodeJSON_Array(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr)
-{
- int usedType = arr->GetArray().Begin()->GetType();
- bool isFloat = arr->GetArray().Begin()->IsDouble() || arr->GetArray().Begin()->IsFloat();
- ServerSq_newarray(sqvm, 0);
for (auto& itr : arr->GetArray())
{
switch (itr.GetType())
{
case rapidjson::kObjectType:
-
- if (usedType != itr.GetType())
- continue;
- ServerSq_DecodeJSON_Table(sqvm, &itr);
- ServerSq_arrayappend(sqvm, -2);
+ DecodeJsonTable<context>(sqvm, &itr);
+ g_pSquirrel<context>->arrayappend(sqvm, -2);
break;
case rapidjson::kArrayType:
-
- if (usedType != itr.GetType())
- continue;
- ServerSq_DecodeJSON_Array(sqvm, &itr);
- ServerSq_arrayappend(sqvm, -2);
+ DecodeJsonArray<context>(sqvm, &itr);
+ g_pSquirrel<context>->arrayappend(sqvm, -2);
break;
case rapidjson::kStringType:
- if ((long long)itr.GetString() == -1)
- {
-
- continue;
- }
- if (usedType != itr.GetType())
- continue;
- ServerSq_pushstring(sqvm, itr.GetString(), -1);
- ServerSq_arrayappend(sqvm, -2);
+ g_pSquirrel<context>->pushstring(sqvm, itr.GetString(), -1);
+ g_pSquirrel<context>->arrayappend(sqvm, -2);
break;
case rapidjson::kTrueType:
- if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
- continue;
- ServerSq_pushbool(sqvm, true);
- ServerSq_arrayappend(sqvm, -2);
- break;
case rapidjson::kFalseType:
- if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
- continue;
- ServerSq_pushbool(sqvm, false);
- ServerSq_arrayappend(sqvm, -2);
+ g_pSquirrel<context>->pushbool(sqvm, itr.GetBool());
+ g_pSquirrel<context>->arrayappend(sqvm, -2);
break;
case rapidjson::kNumberType:
- if (usedType != itr.GetType())
- continue;
if (itr.IsDouble() || itr.IsFloat())
- {
-
- if (!isFloat)
- continue;
- ServerSq_pushfloat(sqvm, itr.GetFloat());
- }
+ g_pSquirrel<context>->pushfloat(sqvm, itr.GetFloat());
else
- {
- if (isFloat)
- continue;
- ServerSq_pushinteger(sqvm, itr.GetInt());
- }
- ServerSq_arrayappend(sqvm, -2);
+ g_pSquirrel<context>->pushinteger(sqvm, itr.GetInt());
+ g_pSquirrel<context>->arrayappend(sqvm, -2);
break;
}
}
}
-SQRESULT ClientSq_DecodeJSON(void* sqvm)
+template <ScriptContext context> void
+DecodeJsonTable(HSquirrelVM* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj)
{
- const char* json = ClientSq_getstring(sqvm, 1);
- rapidjson_document doc;
- doc.Parse(json);
- if (doc.HasParseError())
- {
- ClientSq_newTable(sqvm);
- return SQRESULT_NOTNULL;
- }
- ClientSq_newTable(sqvm);
+ g_pSquirrel<context>->newtable(sqvm);
- for (int i = 0; i < doc.MemberCount(); i++)
+ for (auto itr = obj->MemberBegin(); itr != obj->MemberEnd(); itr++)
{
-
- rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = doc.MemberBegin()[i];
-
- switch (itr.value.GetType())
+ switch (itr->value.GetType())
{
case rapidjson::kObjectType:
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_DecodeJSON_Table(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ClientSq_newSlot(sqvm, -3, false);
+ 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);
break;
case rapidjson::kArrayType:
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_DecodeJSON_Array(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ClientSq_newSlot(sqvm, -3, false);
+ 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);
break;
case rapidjson::kStringType:
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushstring(sqvm, itr.value.GetString(), -1);
+ g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
+ g_pSquirrel<context>->pushstring(sqvm, itr->value.GetString(), -1);
- ClientSq_newSlot(sqvm, -3, false);
+ g_pSquirrel<context>->newslot(sqvm, -3, false);
break;
case rapidjson::kTrueType:
- if ((long long)itr.name.GetString() == -1)
- {
- spdlog::info("Neagative String decoding True");
- continue;
- }
-
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushbool(sqvm, true);
- ClientSq_newSlot(sqvm, -3, false);
- break;
case rapidjson::kFalseType:
- if ((long long)itr.name.GetString() == -1)
- {
-
- continue;
- }
-
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushbool(sqvm, false);
- ClientSq_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())
+ if (itr->value.IsDouble() || itr->value.IsFloat())
{
-
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushfloat(sqvm, itr.value.GetFloat());
+ g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
+ g_pSquirrel<context>->pushfloat(sqvm, itr->value.GetFloat());
}
else
{
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushinteger(sqvm, itr.value.GetInt());
+ g_pSquirrel<context>->pushstring(sqvm, itr->name.GetString(), -1);
+ g_pSquirrel<context>->pushinteger(sqvm, itr->value.GetInt());
}
- ClientSq_newSlot(sqvm, -3, false);
+ g_pSquirrel<context>->newslot(sqvm, -3, false);
break;
}
}
- return SQRESULT_NOTNULL;
}
-void ClientSq_DecodeJSON_Table(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj)
-{
- ClientSq_newTable(sqvm);
-
- for (int i = 0; i < obj->MemberCount(); i++)
- {
- rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>& itr = obj->MemberBegin()[i];
- if (!itr.name.IsString())
- {
- spdlog::info("Decoding table with non-string key");
- continue;
- }
- const char* key = itr.name.GetString();
-
- switch (itr.value.GetType())
- {
- case rapidjson::kObjectType:
- ClientSq_pushstring(sqvm, key, -1);
- ClientSq_DecodeJSON_Table(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ClientSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kArrayType:
- ClientSq_pushstring(sqvm, key, -1);
- ClientSq_DecodeJSON_Array(
- sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&itr.value);
- ClientSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kStringType:
- ClientSq_pushstring(sqvm, key, -1);
- ClientSq_pushstring(sqvm, itr.value.GetString(), -1);
- ClientSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kTrueType:
-
- ClientSq_pushstring(sqvm, key, -1);
- ClientSq_pushbool(sqvm, true);
- ClientSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kFalseType:
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushbool(sqvm, false);
- ClientSq_newSlot(sqvm, -3, false);
- break;
- case rapidjson::kNumberType:
- if (itr.value.IsDouble() || itr.value.IsFloat())
- {
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushfloat(sqvm, itr.value.GetFloat());
- }
- else
- {
- ClientSq_pushstring(sqvm, itr.name.GetString(), -1);
- ClientSq_pushinteger(sqvm, itr.value.GetInt());
- }
- ClientSq_newSlot(sqvm, -3, false);
- break;
- }
- }
-}
-
-void ClientSq_DecodeJSON_Array(
- void* sqvm, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* arr)
-{
- int usedType = arr->GetArray().Begin()->GetType();
- bool isFloat = arr->GetArray().Begin()->IsDouble() || arr->GetArray().Begin()->IsFloat();
- ClientSq_newarray(sqvm, 0);
- for (auto& itr : arr->GetArray())
- {
- switch (itr.GetType())
- {
- case rapidjson::kObjectType:
-
- if (usedType != itr.GetType())
- continue;
- ClientSq_DecodeJSON_Table(sqvm, &itr);
- ClientSq_arrayappend(sqvm, -2);
- break;
- case rapidjson::kArrayType:
-
- if (usedType != itr.GetType())
- continue;
- ClientSq_DecodeJSON_Array(sqvm, &itr);
- ClientSq_arrayappend(sqvm, -2);
- break;
- case rapidjson::kStringType:
- if ((long long)itr.GetString() == -1)
- {
-
- continue;
- }
- if (usedType != itr.GetType())
- continue;
- ClientSq_pushstring(sqvm, itr.GetString(), -1);
- ClientSq_arrayappend(sqvm, -2);
- break;
- case rapidjson::kTrueType:
- if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
- continue;
- ClientSq_pushbool(sqvm, true);
- ClientSq_arrayappend(sqvm, -2);
- break;
- case rapidjson::kFalseType:
- if (usedType != rapidjson::kTrueType && usedType != rapidjson::kFalseType)
- continue;
- ClientSq_pushbool(sqvm, false);
- ClientSq_arrayappend(sqvm, -2);
- break;
- case rapidjson::kNumberType:
- if (usedType != itr.GetType())
- continue;
- if (itr.IsDouble() || itr.IsFloat())
- {
-
- if (!isFloat)
- continue;
- ClientSq_pushfloat(sqvm, itr.GetFloat());
- }
- else
- {
- if (isFloat)
- continue;
- ClientSq_pushinteger(sqvm, itr.GetInt());
- }
- ClientSq_arrayappend(sqvm, -2);
- break;
- }
- }
-}
-
-SQRESULT SQ_EncodeJSON(void* sqvm)
-{
- rapidjson_document doc;
- doc.SetObject();
-
- HSquirrelVM* vm = (HSquirrelVM*)sqvm;
- SQTable* table = vm->_stackOfCurrentFunction[1]._VAL.asTable;
- SQ_EncodeJSON_Table(&doc, table, &doc);
- rapidjson::StringBuffer buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
- doc.Accept(writer);
- const char* json = buffer.GetString();
-
- ServerSq_pushstring(sqvm, json, -1);
- return SQRESULT_NOTNULL;
-}
-
-void SQ_EncodeJSON_Table(
- rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
+template <ScriptContext context> void EncodeJSONTable(
SQTable* table,
- rapidjson_document* allocatorDoc)
+ rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
+ rapidjson::MemoryPoolAllocator<SourceAllocator>& allocator)
{
for (int i = 0; i < table->_numOfNodes; i++)
{
tableNode* node = &table->_nodes[i];
if (node->key._Type == OT_STRING)
{
-
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newObj(rapidjson::kObjectType);
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newArray(rapidjson::kArrayType);
switch (node->val._Type)
{
case OT_STRING:
-
obj->AddMember(
- rapidjson::StringRef(node->key._VAL.asString->_val),
- rapidjson::StringRef(node->val._VAL.asString->_val),
- allocatorDoc->GetAllocator());
+ rapidjson::StringRef(node->key._VAL.asString->_val), rapidjson::StringRef(node->val._VAL.asString->_val), allocator);
break;
case OT_INTEGER:
obj->AddMember(
rapidjson::StringRef(node->key._VAL.asString->_val),
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(
(int)node->val._VAL.asInteger),
- allocatorDoc->GetAllocator());
+ allocator);
break;
case OT_FLOAT:
-
obj->AddMember(
rapidjson::StringRef(node->key._VAL.asString->_val),
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(node->val._VAL.asFloat),
- allocatorDoc->GetAllocator());
+ allocator);
break;
case OT_BOOL:
if (node->val._VAL.asInteger)
@@ -504,106 +135,148 @@ void SQ_EncodeJSON_Table(
obj->AddMember(
rapidjson::StringRef(node->key._VAL.asString->_val),
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(true),
- allocatorDoc->GetAllocator());
+ allocator);
}
else
{
obj->AddMember(
rapidjson::StringRef(node->key._VAL.asString->_val),
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(false),
- allocatorDoc->GetAllocator());
+ allocator);
}
break;
case OT_TABLE:
-
- SQ_EncodeJSON_Table(&newObj, node->val._VAL.asTable, allocatorDoc);
- obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newObj, allocatorDoc->GetAllocator());
+ EncodeJSONTable<context>(node->val._VAL.asTable, &newObj, allocator);
+ obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newObj, allocator);
break;
case OT_ARRAY:
-
- SQ_EncodeJSON_Array(&newArray, node->val._VAL.asArray, allocatorDoc);
- obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newArray, allocatorDoc->GetAllocator());
+ EncodeJSONArray<context>(node->val._VAL.asArray, &newArray, allocator);
+ obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newArray, allocator);
break;
default:
- spdlog::info("SQ encode Json type {} not supported", sq_getTypeName(node->val._Type));
+ spdlog::warn("SQ_EncodeJSON: squirrel type {} not supported", SQTypeNameFromID(node->val._Type));
break;
}
}
}
}
-void SQ_EncodeJSON_Array(
+template <ScriptContext context> void EncodeJSONArray(
+ SQArray* arr,
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>* obj,
- SQArray* sqArray,
- rapidjson_document* allocatorDoc)
+ rapidjson::MemoryPoolAllocator<SourceAllocator>& allocator)
{
- int usedType = sqArray->_values->_Type;
- for (int i = 0; i < sqArray->_usedSlots; i++)
+ for (int i = 0; i < arr->_usedSlots; i++)
{
- SQObject* node = &sqArray->_values[i];
- if (node->_Type != usedType)
- {
- const char* typeName = sq_getTypeName(node->_Type);
- const char* usedTypeName = sq_getTypeName(usedType);
- spdlog::info("SQ encode Json array not same type got %s expected %s", typeName, usedTypeName);
- continue;
- }
+ SQObject* node = &arr->_values[i];
+
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newObj(rapidjson::kObjectType);
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>> newArray(rapidjson::kArrayType);
+
switch (node->_Type)
{
case OT_STRING:
- obj->PushBack(rapidjson::StringRef(node->_VAL.asString->_val), allocatorDoc->GetAllocator());
+ obj->PushBack(rapidjson::StringRef(node->_VAL.asString->_val), allocator);
break;
case OT_INTEGER:
obj->PushBack(
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>((int)node->_VAL.asInteger),
- allocatorDoc->GetAllocator());
+ allocator);
break;
case OT_FLOAT:
obj->PushBack(
rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>(node->_VAL.asFloat),
- allocatorDoc->GetAllocator());
+ allocator);
break;
case OT_BOOL:
if (node->_VAL.asInteger)
- {
- obj->PushBack(rapidjson::StringRef("true"), allocatorDoc->GetAllocator());
- }
+ obj->PushBack(rapidjson::StringRef("true"), allocator);
else
- {
- obj->PushBack(rapidjson::StringRef("false"), allocatorDoc->GetAllocator());
- }
+ obj->PushBack(rapidjson::StringRef("false"), allocator);
break;
case OT_TABLE:
-
- SQ_EncodeJSON_Table(&newObj, node->_VAL.asTable, allocatorDoc);
- obj->PushBack(newObj, allocatorDoc->GetAllocator());
+ EncodeJSONTable<context>(node->_VAL.asTable, &newObj, allocator);
+ obj->PushBack(newObj, allocator);
break;
case OT_ARRAY:
-
- SQ_EncodeJSON_Array(&newArray, node->_VAL.asArray, allocatorDoc);
- obj->PushBack(newArray, allocatorDoc->GetAllocator());
+ EncodeJSONArray<context>(node->_VAL.asArray, &newArray, allocator);
+ obj->PushBack(newArray, allocator);
break;
default:
-
- spdlog::info("SQ encode Json type {} not supported", sq_getTypeName(node->_Type));
+ spdlog::info("SQ encode Json type {} not supported", SQTypeNameFromID(node->_Type));
}
}
}
-void InitialiseServerSquirrelJson(HMODULE baseAddress)
+// table function DecodeJSON( string json, bool fatalParseErrors = false )
+template <ScriptContext context> SQRESULT SQ_DecodeJSON(HSquirrelVM* sqvm)
{
+ 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);
+
+ std::string sErrorString = fmt::format(
+ "Failed parsing json file: encountered parse error \"{}\" at offset {}",
+ GetParseError_En(doc.GetParseError()),
+ doc.GetErrorOffset());
- g_ServerSquirrelManager->AddFuncRegistration("table", "DecodeJSON", "string json", "", ServerSq_DecodeJSON);
- g_ServerSquirrelManager->AddFuncRegistration("string", "EncodeJSON", "table data", "", SQ_EncodeJSON);
+ if (bFatalParseErrors)
+ g_pSquirrel<context>->raiseerror(sqvm, sErrorString.c_str());
+ else
+ spdlog::warn(sErrorString);
+
+ return SQRESULT_NOTNULL;
+ }
+
+ DecodeJsonTable<context>(sqvm, (rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<SourceAllocator>>*)&doc);
}
-void InitialiseClientSquirrelJson(HMODULE baseAddress)
+// string function EncodeJSON( table data )
+template <ScriptContext context> SQRESULT SQ_EncodeJSON(HSquirrelVM* sqvm)
{
- g_ClientSquirrelManager->AddFuncRegistration("table", "DecodeJSON", "string json", "", ClientSq_DecodeJSON);
- g_ClientSquirrelManager->AddFuncRegistration("string", "EncodeJSON", "table data", "", SQ_EncodeJSON);
+ rapidjson_document doc;
+ doc.SetObject();
- g_UISquirrelManager->AddFuncRegistration("table", "DecodeJSON", "string json", "", ClientSq_DecodeJSON);
- g_UISquirrelManager->AddFuncRegistration("string", "EncodeJSON", "table data", "", SQ_EncodeJSON);
+ // temp until this is just the func parameter type
+ HSquirrelVM* vm = (HSquirrelVM*)sqvm;
+ SQTable* table = vm->_stackOfCurrentFunction[1]._VAL.asTable;
+ EncodeJSONTable<context>(table, &doc, doc.GetAllocator());
+
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ doc.Accept(writer);
+ const char* pJsonString = buffer.GetString();
+
+ g_pSquirrel<context>->pushstring(sqvm, pJsonString, -1);
+ return SQRESULT_NOTNULL;
+}
+
+ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientScriptJSON, ClientSquirrel, (CModule module))
+{
+ g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration(
+ "table",
+ "DecodeJSON",
+ "string json, bool fatalParseErrors = false",
+ "converts a json string to a squirrel table",
+ SQ_DecodeJSON<ScriptContext::CLIENT>);
+ g_pSquirrel<ScriptContext::CLIENT>->AddFuncRegistration(
+ "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::CLIENT>);
+
+ g_pSquirrel<ScriptContext::UI>->AddFuncRegistration(
+ "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON<ScriptContext::UI>);
+ g_pSquirrel<ScriptContext::UI>->AddFuncRegistration(
+ "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::UI>);
+}
+
+ON_DLL_LOAD_RELIESON("server.dll", ServerScriptJSON, ServerSquirrel, (CModule module))
+{
+ g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration(
+ "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON<ScriptContext::SERVER>);
+ g_pSquirrel<ScriptContext::SERVER>->AddFuncRegistration(
+ "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON<ScriptContext::SERVER>);
}