From 86ea43ef2c32104f92e12c80231ff9271ebeb6e2 Mon Sep 17 00:00:00 2001 From: BobTheBob9 Date: Mon, 22 Aug 2022 23:42:43 +0100 Subject: i swear i committed these how are they not there --- NorthstarDLL/scriptjson.cpp | 278 +++++++++++++++++++++++++++++++++++++++++ NorthstarDLL/scriptutility.cpp | 23 ++++ 2 files changed, 301 insertions(+) create mode 100644 NorthstarDLL/scriptjson.cpp create mode 100644 NorthstarDLL/scriptutility.cpp diff --git a/NorthstarDLL/scriptjson.cpp b/NorthstarDLL/scriptjson.cpp new file mode 100644 index 00000000..ff6d5284 --- /dev/null +++ b/NorthstarDLL/scriptjson.cpp @@ -0,0 +1,278 @@ +#include "pch.h" +#include "squirrel.h" + +#include "rapidjson/error/en.h" +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" + +#ifdef _MSC_VER +#undef GetObject // fuck microsoft developers +#endif + +template +void DecodeJsonArray(void* sqvm, rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* arr) +{ + g_pSquirrel->newarray(sqvm, 0); + + for (auto& itr : arr->GetArray()) + { + switch (itr.GetType()) + { + case rapidjson::kObjectType: + DecodeJsonTable(sqvm, &itr); + g_pSquirrel->arrayappend(sqvm, -2); + break; + case rapidjson::kArrayType: + DecodeJsonArray(sqvm, &itr); + g_pSquirrel->arrayappend(sqvm, -2); + break; + case rapidjson::kStringType: + g_pSquirrel->pushstring(sqvm, itr.GetString(), -1); + g_pSquirrel->arrayappend(sqvm, -2); + break; + case rapidjson::kTrueType: + case rapidjson::kFalseType: + g_pSquirrel->pushbool(sqvm, itr.GetBool()); + g_pSquirrel->arrayappend(sqvm, -2); + break; + case rapidjson::kNumberType: + if (itr.IsDouble() || itr.IsFloat()) + g_pSquirrel->pushfloat(sqvm, itr.GetFloat()); + else + g_pSquirrel->pushinteger(sqvm, itr.GetInt()); + g_pSquirrel->arrayappend(sqvm, -2); + break; + } + } +} + +template +void DecodeJsonTable(void* sqvm, rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj) +{ + g_pSquirrel->newtable(sqvm); + + for (auto itr = obj->MemberBegin(); itr != obj->MemberEnd(); itr++) + { + switch (itr->value.GetType()) + { + case rapidjson::kObjectType: + g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); + DecodeJsonTable( + sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&itr->value); + g_pSquirrel->newslot(sqvm, -3, false); + break; + case rapidjson::kArrayType: + g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); + DecodeJsonArray( + sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&itr->value); + g_pSquirrel->newslot(sqvm, -3, false); + break; + case rapidjson::kStringType: + g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel->pushstring(sqvm, itr->value.GetString(), -1); + + g_pSquirrel->newslot(sqvm, -3, false); + break; + case rapidjson::kTrueType: + case rapidjson::kFalseType: + g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel->pushbool(sqvm, itr->value.GetBool()); + g_pSquirrel->newslot(sqvm, -3, false); + break; + case rapidjson::kNumberType: + if (itr->value.IsDouble() || itr->value.IsFloat()) + { + g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel->pushfloat(sqvm, itr->value.GetFloat()); + } + else + { + g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); + g_pSquirrel->pushinteger(sqvm, itr->value.GetInt()); + } + g_pSquirrel->newslot(sqvm, -3, false); + break; + } + } +} + +template +void EncodeJSONTable(SQTable* table, rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, rapidjson::MemoryPoolAllocator& allocator) +{ + for (int i = 0; i < table->_numOfNodes; i++) + { + tableNode* node = &table->_nodes[i]; + if (node->key._Type == OT_STRING) + { + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator> newObj(rapidjson::kObjectType); + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator> 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), allocator); + break; + case OT_INTEGER: + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>( + (int)node->val._VAL.asInteger), + allocator); + break; + case OT_FLOAT: + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>(node->val._VAL.asFloat), + allocator); + break; + case OT_BOOL: + if (node->val._VAL.asInteger) + { + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>(true), + allocator); + } + else + { + obj->AddMember( + rapidjson::StringRef(node->key._VAL.asString->_val), + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>(false), + allocator); + } + break; + case OT_TABLE: + EncodeJSONTable(node->val._VAL.asTable, &newObj, allocator); + obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newObj, allocator); + break; + case OT_ARRAY: + EncodeJSONArray(node->val._VAL.asArray, &newArray, allocator); + obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), newArray, allocator); + break; + default: + spdlog::warn("SQ_EncodeJSON: squirrel type {} not supported", SQTypeNameFromID(node->val._Type)); + break; + } + } + } +} + +template void EncodeJSONArray( + SQArray* arr, + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, + rapidjson::MemoryPoolAllocator& allocator) +{ + for (int i = 0; i < arr->_usedSlots; i++) + { + SQObject* node = &arr->_values[i]; + + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator> newObj(rapidjson::kObjectType); + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator> newArray(rapidjson::kArrayType); + + switch (node->_Type) + { + case OT_STRING: + obj->PushBack(rapidjson::StringRef(node->_VAL.asString->_val), allocator); + break; + case OT_INTEGER: + obj->PushBack( + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>((int)node->_VAL.asInteger), + allocator); + break; + case OT_FLOAT: + obj->PushBack( + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>(node->_VAL.asFloat), + allocator); + break; + case OT_BOOL: + if (node->_VAL.asInteger) + obj->PushBack(rapidjson::StringRef("true"), allocator); + else + obj->PushBack(rapidjson::StringRef("false"), allocator); + break; + case OT_TABLE: + EncodeJSONTable(node->_VAL.asTable, &newObj, allocator); + obj->PushBack(newObj, allocator); + break; + case OT_ARRAY: + EncodeJSONArray(node->_VAL.asArray, &newArray, allocator); + obj->PushBack(newArray, allocator); + break; + default: + spdlog::info("SQ encode Json type {} not supported", SQTypeNameFromID(node->_Type)); + } + } +} + + +// table function DecodeJSON( string json, bool fatalParseErrors = false ) +template SQRESULT SQ_DecodeJSON(void* sqvm) +{ + const char* pJson = g_pSquirrel->getstring(sqvm, 1); + const bool bFatalParseErrors = g_pSquirrel->getbool(sqvm, 2); + + rapidjson_document doc; + doc.Parse(pJson); + if (doc.HasParseError()) + { + g_pSquirrel->newtable(sqvm); + + std::string sErrorString = fmt::format( + "Failed parsing json file: encountered parse error \"{}\" at offset {}", + GetParseError_En(doc.GetParseError()), + doc.GetErrorOffset()); + + if (bFatalParseErrors) + g_pSquirrel->raiseerror(sqvm, sErrorString.c_str()); + else + spdlog::warn(sErrorString); + + return SQRESULT_NOTNULL; + } + + DecodeJsonTable(sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&doc); +} + + +// string function EncodeJSON( table data ) +template SQRESULT SQ_EncodeJSON(void* sqvm) +{ + rapidjson_document doc; + doc.SetObject(); + + // temp until this is just the func parameter type + HSquirrelVM* vm = (HSquirrelVM*)sqvm; + SQTable* table = vm->_stackOfCurrentFunction[1]._VAL.asTable; + EncodeJSONTable(table, &doc, doc.GetAllocator()); + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + doc.Accept(writer); + const char* pJsonString = buffer.GetString(); + + g_pSquirrel->pushstring(sqvm, pJsonString, -1); + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientScriptJSON, ClientSquirrel, (CModule module)) +{ + g_pSquirrel->AddFuncRegistration( + "table", "DecodeJSON", "string json, bool fatalParseErrors = false", "converts a json string to a squirrel table", SQ_DecodeJSON); + g_pSquirrel->AddFuncRegistration( + "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON); + + g_pSquirrel->AddFuncRegistration( + "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON); + g_pSquirrel->AddFuncRegistration( + "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerScriptJSON, ServerSquirrel, (CModule module)) +{ + g_pSquirrel->AddFuncRegistration( + "table", "DecodeJSON", "string json", "converts a json string to a squirrel table", SQ_DecodeJSON); + g_pSquirrel->AddFuncRegistration( + "string", "EncodeJSON", "table data", "converts a squirrel table to a json string", SQ_EncodeJSON); +} \ No newline at end of file diff --git a/NorthstarDLL/scriptutility.cpp b/NorthstarDLL/scriptutility.cpp new file mode 100644 index 00000000..1acd8599 --- /dev/null +++ b/NorthstarDLL/scriptutility.cpp @@ -0,0 +1,23 @@ +#include "pch.h" +#include "squirrel.h" + +// asset function StringToAsset( string assetName ) +template SQRESULT SQ_StringToAsset(void* sqvm) +{ + g_pSquirrel->pushasset(sqvm, g_pSquirrel->getstring(sqvm, 1), -1); + return SQRESULT_NOTNULL; +} + +ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientSharedScriptUtility, ClientSquirrel, (CModule module)) +{ + g_pSquirrel->AddFuncRegistration( + "asset", "StringToAsset", "string assetName", "converts a given string to an asset", SQ_StringToAsset); + g_pSquirrel->AddFuncRegistration( + "asset", "StringToAsset", "string assetName", "converts a given string to an asset", SQ_StringToAsset); +} + +ON_DLL_LOAD_RELIESON("server.dll", ServerSharedScriptUtility, ServerSquirrel, (CModule module)) +{ + g_pSquirrel->AddFuncRegistration( + "asset", "StringToAsset", "string assetName", "converts a given string to an asset", SQ_StringToAsset); +} \ No newline at end of file -- cgit v1.2.3