From 4508f72ff7a14ce162ffe89a54d396a2a37ecbd8 Mon Sep 17 00:00:00 2001 From: znajder Date: Sat, 13 Jan 2024 21:56:45 +0100 Subject: [PATCH] Fix backwards compatibility for old resources --- Client/mods/deathmatch/logic/CRemoteCalls.cpp | 6 ++++-- .../deathmatch/logic/lua/CLuaArguments.cpp | 17 ++++++++++++++++- .../mods/deathmatch/logic/lua/CLuaArguments.h | 6 +++--- Server/mods/deathmatch/logic/CElement.cpp | 4 +++- Server/mods/deathmatch/logic/CRemoteCalls.cpp | 9 +++++---- Server/mods/deathmatch/logic/CResource.cpp | 4 +++- .../deathmatch/logic/lua/CLuaArguments.cpp | 18 ++++++++++++++++-- .../mods/deathmatch/logic/lua/CLuaArguments.h | 2 +- .../logic/luadefs/CLuaFunctionDefs.Server.cpp | 11 ++++++----- 9 files changed, 57 insertions(+), 20 deletions(-) diff --git a/Client/mods/deathmatch/logic/CRemoteCalls.cpp b/Client/mods/deathmatch/logic/CRemoteCalls.cpp index 9c0188b407..2541e06e36 100644 --- a/Client/mods/deathmatch/logic/CRemoteCalls.cpp +++ b/Client/mods/deathmatch/logic/CRemoteCalls.cpp @@ -180,8 +180,10 @@ void CRemoteCall::DownloadFinishedCallback(const SHttpDownloadResult& result) arguments.PushNumber(0); } else - // @todo: test - arguments.ReadJSONString(result.pData); + { + if (arguments.ReadJSONString(result.pData)) + arguments.PushArguments(arguments); + } } else { diff --git a/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp b/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp index b6a969d9b6..03fbf212e0 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -492,8 +492,23 @@ bool CLuaArguments::WriteToBitStream(NetBitStreamInterface& bitStream, CFastHash return bSuccess; } -bool CLuaArguments::ReadJSONString(const char* szJSON) +bool CLuaArguments::ReadJSONString(const char* szJSON, bool bBackwardsCompatibility) { + if (bBackwardsCompatibility) + { + // Backwards compatibility with old resources using function get() + // Fast isJSON check: Check first non-white space character is '[' or '{' + for (const char* ptr = szJSON; true;) + { + char c = *ptr++; + if (c == '[' || c == '{') + break; + if (isspace((uchar)c)) + continue; + return false; + } + } + rapidjson::Document doc; rapidjson::ParseResult result = doc.Parse(szJSON); diff --git a/Client/mods/deathmatch/logic/lua/CLuaArguments.h b/Client/mods/deathmatch/logic/lua/CLuaArguments.h index 19cb92707e..38fa92fb0f 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/Client/mods/deathmatch/logic/lua/CLuaArguments.h @@ -80,9 +80,9 @@ class CLuaArguments std::vector::const_iterator IterEnd() const { return m_Arguments.end(); }; // json parse - bool ReadJSONString(const char* szJSON); - bool ReadJSONArray(const rapidjson::Value& obj, std::vector* pKnownTables = NULL); - bool ReadJSONObject(const rapidjson::Value& obj, std::vector* pKnownTables = NULL); + bool ReadJSONString(const char* szJSON, bool bBackwardsCompatibility = false); + bool ReadJSONArray(const rapidjson::Value& obj, std::vector* pKnownTables = NULL); + bool ReadJSONObject(const rapidjson::Value& obj, std::vector* pKnownTables = NULL); // json writer bool SerializeToJSONString(rapidjson::StringBuffer* buffer, bool bSerialize = false, int flags = 1, bool bBackwardsCompatibility = false); diff --git a/Server/mods/deathmatch/logic/CElement.cpp b/Server/mods/deathmatch/logic/CElement.cpp index 70736fc4cd..b64eb97008 100644 --- a/Server/mods/deathmatch/logic/CElement.cpp +++ b/Server/mods/deathmatch/logic/CElement.cpp @@ -499,8 +499,10 @@ void CElement::ReadCustomData(CEvents* pEvents, CXMLNode& Node) // Make a lua argument from it and set the content CLuaArguments args; - if (!args.ReadJSONString(pAttribute->GetValue().c_str())) + if (!args.ReadJSONString(pAttribute->GetValue().c_str(), true)) args.PushString(pAttribute->GetValue().c_str()); + else + args.PushArguments(args); // Don't trigger onElementDataChanged event ESyncType syncType = g_pGame->GetConfig()->GetSyncMapElementData() ? ESyncType::BROADCAST : ESyncType::LOCAL; diff --git a/Server/mods/deathmatch/logic/CRemoteCalls.cpp b/Server/mods/deathmatch/logic/CRemoteCalls.cpp index 009830828a..51384dfa7f 100644 --- a/Server/mods/deathmatch/logic/CRemoteCalls.cpp +++ b/Server/mods/deathmatch/logic/CRemoteCalls.cpp @@ -237,13 +237,14 @@ void CRemoteCall::DownloadFinishedCallback(const SHttpDownloadResult& result) if (result.bSuccess) { if (pCall->IsFetch()) + { arguments.PushString(std::string(result.pData, result.dataSize)); + arguments.PushNumber(0); + } else { - // @todo: test - arguments.ReadJSONString(result.pData); - - arguments.PushNumber(0); + if (arguments.ReadJSONString(result.pData)) + arguments.PushArguments(arguments); } } else diff --git a/Server/mods/deathmatch/logic/CResource.cpp b/Server/mods/deathmatch/logic/CResource.cpp index 4104ec96b0..a9fc71898b 100644 --- a/Server/mods/deathmatch/logic/CResource.cpp +++ b/Server/mods/deathmatch/logic/CResource.cpp @@ -2565,7 +2565,9 @@ ResponseCode CResource::HandleRequestCall(HttpRequest* ipoHttpRequest, HttpRespo else if (ipoHttpRequest->nRequestMethod == REQUESTMETHOD_POST) { const char* szRequestBody = ipoHttpRequest->sBody.c_str(); - Arguments.ReadJSONString(szRequestBody); + if (Arguments.ReadJSONString(szRequestBody)) + Arguments.PushArguments(Arguments); + } CLuaArguments FormData; diff --git a/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp b/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp index 70ce639b00..cb734c0578 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaArguments.cpp @@ -569,10 +569,24 @@ bool CLuaArguments::WriteToBitStream(NetBitStreamInterface& bitStream, CFastHash return bSuccess; } -bool CLuaArguments::ReadJSONString(const char* szJSON) +bool CLuaArguments::ReadJSONString(const char* szJSON, bool bBackwardsCompatibility) { - // allow comments? + if (bBackwardsCompatibility) + { + // Backwards compatibility with old resources using function get() + // Fast isJSON check: Check first non-white space character is '[' or '{' + for (const char* ptr = szJSON; true;) + { + char c = *ptr++; + if (c == '[' || c == '{') + break; + if (isspace((uchar)c)) + continue; + return false; + } + } + // allow comments? rapidjson::Document doc; rapidjson::ParseResult result = doc.Parse(szJSON); diff --git a/Server/mods/deathmatch/logic/lua/CLuaArguments.h b/Server/mods/deathmatch/logic/lua/CLuaArguments.h index 32c1cf4c9a..d10ac53f49 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaArguments.h +++ b/Server/mods/deathmatch/logic/lua/CLuaArguments.h @@ -102,7 +102,7 @@ class CLuaArguments bool IsEqualTo(const CLuaArguments& compareTo, std::set* knownTables = nullptr) const; // json parse - bool ReadJSONString(const char* szJSON); + bool ReadJSONString(const char* szJSON, bool bBackwardsCompatibility = false); bool ReadJSONArray(const rapidjson::Value& obj, std::vector* pKnownTables = NULL); bool ReadJSONObject(const rapidjson::Value& obj, std::vector* pKnownTables = NULL); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp index cff58f02c4..8c96e75eb4 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaFunctionDefs.Server.cpp @@ -261,13 +261,14 @@ int CLuaFunctionDefs::Get(lua_State* luaVM) } // We only have a single entry for a specific setting, so output a string const std::string& strDataValue = pAttribute->GetValue(); - if (!Args.ReadJSONString(strDataValue.c_str())) + if (!Args.ReadJSONString(strDataValue.c_str(), true)) { // No valid JSON? Parse as plain text Args.PushString(strDataValue); } + else + Args.PushArguments(luaVM); - Args.PushArguments(luaVM); uiArgCount = Args.Count(); /* Don't output a table because although it is more consistent with the multiple values output below, @@ -286,14 +287,14 @@ int CLuaFunctionDefs::Get(lua_State* luaVM) CXMLAttributes& attributes = pSubNode->GetAttributes(); Args.PushString(attributes.Find("name")->GetValue()); const std::string& strDataValue = attributes.Find("value")->GetValue(); - if (!Args.ReadJSONString(strDataValue.c_str())) + if (!Args.ReadJSONString(strDataValue.c_str(), true)) { Args.PushString(strDataValue); } } + // Push a table and return - // @todo: test that - Args.PushArguments(luaVM); // Args.PushAsTable(luaVM); + Args.PushAsTable(luaVM); uiArgCount = Args.Count(); }