From b31b192a39bb66a68ba65185d7516549d018c4cf Mon Sep 17 00:00:00 2001 From: Walace Date: Mon, 23 Dec 2024 12:30:12 -0300 Subject: [PATCH] Add CMatrix 4x4 lua table in ArgumentParser (#3849) * Add CMatrix 4x4 lua table in ArgumentParse * Update due to code revision --------- Co-authored-by: Uladzislau Nikalayevich Co-authored-by: TEDERIs --- .../logic/lua/CLuaFunctionParseHelpers.cpp | 36 +++++++++++++++++++ .../logic/lua/CLuaFunctionParseHelpers.h | 1 + .../logic/lua/CLuaFunctionParseHelpers.cpp | 36 +++++++++++++++++++ .../logic/lua/CLuaFunctionParseHelpers.h | 1 + .../deathmatch/logic/lua/CLuaFunctionParser.h | 18 +++++++++- 5 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 209bcbc1a2..6fc425fa83 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -1125,6 +1125,42 @@ void MixedReadMaterialString(CScriptArgReader& argStream, CClientMaterial*& pMat } } +// +// Check 4x4 lua table +// +bool IsValidMatrixLuaTable(lua_State* luaVM, std::uint32_t argIndex) noexcept +{ + std::uint32_t cell = 0; + + if (lua_type(luaVM, argIndex) == LUA_TTABLE) + { + lua_pushnil(luaVM); + for (std::uint32_t row = 0; lua_next(luaVM, argIndex) != 0; lua_pop(luaVM, 1), ++row) + { + if (lua_type(luaVM, -1) != LUA_TTABLE) + return false; + + std::uint32_t col = 0; + + lua_pushnil(luaVM); + for (; lua_next(luaVM, -2) != 0; lua_pop(luaVM, 1), ++col, ++cell) + { + int argumentType = lua_type(luaVM, -1); + if (argumentType != LUA_TNUMBER && argumentType != LUA_TSTRING) + return false; + } + + if (col != 4) + return false; + } + } + + if (cell != 16) + return false; + + return true; +} + // // 4x4 matrix into CMatrix // diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index d755b4e5e3..818ebeb308 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -587,6 +587,7 @@ class CScriptArgReader; void MixedReadDxFontString(CScriptArgReader& argStream, eFontType& outFontType, eFontType defaultFontType, CClientDxFont*& poutDxFontElement); void MixedReadGuiFontString(CScriptArgReader& argStream, SString& strFontName, const char* szDefaultFontName, CClientGuiFont*& poutGuiFontElement); void MixedReadMaterialString(CScriptArgReader& argStream, CClientMaterial*& pMaterialElement); +bool IsValidMatrixLuaTable(lua_State* luaVM, std::uint32_t argIndex) noexcept; bool ReadMatrix(lua_State* luaVM, uint uiArgIndex, CMatrix& outMatrix); void MinClientReqCheck(lua_State* luaVM, const char* szVersionReq, const char* szReason); bool MinClientReqCheck(CScriptArgReader& argStream, const char* szVersionReq, const char* szReason = nullptr); diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 76540327af..27afc8510e 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -646,6 +646,42 @@ void ReadPregFlags(CScriptArgReader& argStream, pcrecpp::RE_Options& pOptions) } } +// +// Check 4x4 lua table +// +bool IsValidMatrixLuaTable(lua_State* luaVM, std::uint32_t argIndex) noexcept +{ + std::uint32_t cell = 0; + + if (lua_type(luaVM, argIndex) == LUA_TTABLE) + { + lua_pushnil(luaVM); + for (std::uint32_t row = 0; lua_next(luaVM, argIndex) != 0; lua_pop(luaVM, 1), ++row) + { + if (lua_type(luaVM, -1) != LUA_TTABLE) + return false; + + std::uint32_t col = 0; + + lua_pushnil(luaVM); + for (; lua_next(luaVM, -2) != 0; lua_pop(luaVM, 1), ++col, ++cell) + { + int argumentType = lua_type(luaVM, -1); + if (argumentType != LUA_TNUMBER && argumentType != LUA_TSTRING) + return false; + } + + if (col != 4) + return false; + } + } + + if (cell != 16) + return false; + + return true; +} + // // 4x4 matrix into CMatrix // diff --git a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 796ca3c702..62d4312c51 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -390,6 +390,7 @@ void MixedReadResourceString(CScriptArgReader& argStream, CResource*& pOutRes bool StringToBool(const SString& strText); void MinServerReqCheck(CScriptArgReader& argStream, const char* szVersionReq, const char* szReason); void ReadPregFlags(CScriptArgReader& argStream, pcrecpp::RE_Options& pOptions); +bool IsValidMatrixLuaTable(lua_State* luaVM, std::uint32_t argIndex) noexcept; bool ReadMatrix(lua_State* luaVM, uint uiArgIndex, CMatrix& outMatrix); // diff --git a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h index b31b5cba4a..d6d1cc3297 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h @@ -283,9 +283,12 @@ struct CLuaFunctionParserBase return true; return iArgument == LUA_TUSERDATA || iArgument == LUA_TLIGHTUSERDATA; } - // CMatrix may either be represented by 3 CLuaVector or by 12 numbers + // CMatrix can be represented either by 3 CLuaVectors, 12 numbers, or a 4x4 Lua table else if constexpr (std::is_same_v) { + if (IsValidMatrixLuaTable(L, index)) + return true; + for (int i = 0; i < sizeof(CMatrix) / sizeof(float); i++) { if (!lua_isnumber(L, index + i)) @@ -639,6 +642,19 @@ struct CLuaFunctionParserBase return matrix; } + if (lua_istable(L, index)) + { + CMatrix matrix; + + if (!ReadMatrix(L, index, matrix)) + { + SetBadArgumentError(L, "matrix", index, "table"); + return T{}; + } + + return matrix; + } + int iType = lua_type(L, index); bool isLightUserData = iType == LUA_TLIGHTUSERDATA; void* pValue = lua::PopPrimitive(L, index);