From b4768dd8d54517fb43cbe3878dcb31ec872b69a1 Mon Sep 17 00:00:00 2001 From: Walace Date: Sat, 9 Nov 2024 10:25:43 -0300 Subject: [PATCH] Add CMatrix 4x4 lua table in ArgumentParse --- .../logic/lua/CLuaFunctionParseHelpers.cpp | 35 +++++++++++++++++++ .../logic/lua/CLuaFunctionParseHelpers.h | 1 + .../logic/lua/CLuaFunctionParseHelpers.cpp | 35 +++++++++++++++++++ .../logic/lua/CLuaFunctionParseHelpers.h | 1 + .../deathmatch/logic/lua/CLuaFunctionParser.h | 18 +++++++++- 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 64708dea0c..2695042388 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -1109,6 +1109,41 @@ void MixedReadMaterialString(CScriptArgReader& argStream, CClientMaterial*& pMat } } +// +// Check 4x4 lua table +// +bool IsValidMatrixLuaTable(lua_State* luaVM, uint uiArgIndex) +{ + uint uiRow = 0; + uint uiCell = 0; + + if (lua_type(luaVM, uiArgIndex) == LUA_TTABLE) + { + for (lua_pushnil(luaVM); lua_next(luaVM, uiArgIndex) != 0; lua_pop(luaVM, 1), uiRow++) + { + if (lua_type(luaVM, -1) != LUA_TTABLE) + return false; + + uint uiCol = 0; + + for (lua_pushnil(luaVM); lua_next(luaVM, -2) != 0; lua_pop(luaVM, 1), uiCol++, uiCell++) + { + int iArgumentType = lua_type(luaVM, -1); + if (iArgumentType != LUA_TNUMBER && iArgumentType != LUA_TSTRING) + return false; + } + + if (uiCol != 4) + return false; + } + } + + if (uiRow != 4 || uiCell != 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 e134a73bea..a08e5a32d5 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -584,6 +584,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, uint uiArgIndex); 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 ef25750c05..1830d9a3a1 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -640,6 +640,41 @@ void ReadPregFlags(CScriptArgReader& argStream, pcrecpp::RE_Options& pOptions) } } +// +// Check 4x4 lua table +// +bool IsValidMatrixLuaTable(lua_State* luaVM, uint uiArgIndex) +{ + uint uiRow = 0; + uint uiCell = 0; + + if (lua_type(luaVM, uiArgIndex) == LUA_TTABLE) + { + for (lua_pushnil(luaVM); lua_next(luaVM, uiArgIndex) != 0; lua_pop(luaVM, 1), uiRow++) + { + if (lua_type(luaVM, -1) != LUA_TTABLE) + return false; + + uint uiCol = 0; + + for (lua_pushnil(luaVM); lua_next(luaVM, -2) != 0; lua_pop(luaVM, 1), uiCol++, uiCell++) + { + int iArgumentType = lua_type(luaVM, -1); + if (iArgumentType != LUA_TNUMBER && iArgumentType != LUA_TSTRING) + return false; + } + + if (uiCol != 4) + return false; + } + } + + if (uiRow != 4 || uiCell != 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 52a4536012..4ab65efed9 100644 --- a/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Server/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -389,6 +389,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, uint uiArgIndex); 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 fef13d708b..af9457ac63 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)) @@ -618,6 +621,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);