diff options
author | BobTheBob <32057864+BobTheBob9@users.noreply.github.com> | 2022-10-17 23:26:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-17 23:26:07 +0100 |
commit | 841881af9ea6ec73b1d505d5a8f7c1f766273724 (patch) | |
tree | 91feb40fe810984b59d2d2da440e289370b0a137 /NorthstarDLL/scriptjson.cpp | |
parent | dc0934d29caacc8da1e7df8b775d24b4e99c381c (diff) | |
download | NorthstarLauncher-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.cpp | 601 |
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>); } |