diff options
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>); } |