From 666951dee2b1d0c304cd51cf0fd4110920b31f64 Mon Sep 17 00:00:00 2001 From: 4z0t Date: Sun, 10 Nov 2024 12:29:57 +0300 Subject: [PATCH 1/9] initial fix for `table.getsize2` --- section/GetTableSize.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/section/GetTableSize.cpp b/section/GetTableSize.cpp index 5ba4332c..7430f0b7 100644 --- a/section/GetTableSize.cpp +++ b/section/GetTableSize.cpp @@ -1,6 +1,7 @@ void GetTableSize() { asm( + "PushNumber = 0x0090CD40;" "MOV EAX,[ESI+0xC];" "CMP EAX,[ESI+0x8];" "JAE Err;" @@ -40,12 +41,19 @@ void GetTableSize() "SUB ESP,0x4;" "MOVSS [ESP],XMM0;" "PUSH ESI;" - "CALL 0x0090CD40;" //PushNumber + "CALL PushNumber;" "ADD ESP,0x8;" "MOV EAX,0x1;" "RET;" "Err:;" - "XOR EAX,EAX;" + "SUB ESP,0x4;" + "XORPS XMM0, XMM0;" + "MOVSS [ESP],XMM0;" + "PUSH ESI;" + "CALL PushNumber;" + "ADD ESP,0x8;" + "MOV EAX,0x1;" + "RET;" ); } From bac292af5b56207c51eb9bc5ef0c227884d9aaf4 Mon Sep 17 00:00:00 2001 From: 4z0t Date: Sun, 10 Nov 2024 13:14:20 +0300 Subject: [PATCH 2/9] implement in C++ --- section/GetTableSize.cpp | 278 +++++++++++++++++++++------------------ 1 file changed, 153 insertions(+), 125 deletions(-) diff --git a/section/GetTableSize.cpp b/section/GetTableSize.cpp index 7430f0b7..716878ce 100644 --- a/section/GetTableSize.cpp +++ b/section/GetTableSize.cpp @@ -1,109 +1,133 @@ -void GetTableSize() +#include "include/LuaAPI.h" +namespace lua +{ + struct TObject + { + int tt; + void *value; + }; + + struct Node + { + TObject i_key; + TObject i_val; + Node *next; + }; + + struct Table + { + /* lua::GCObject*/ void *next; + uint8_t tt; + uint8_t marked; + uint16_t gap; + uint8_t flags; + uint8_t lsizenode; + // padding byte + // padding byte + Table *metatable; + TObject *array; + lua::Node *node; + lua::Node *firstfree; + /*lua::GCObject*/ void *gclist; + int sizearray; + }; + +} // namespace lua + +VALIDATE_SIZE(lua::Table, 0x24); + +int lua_tablesize(lua_State *L) { - asm( - "PushNumber = 0x0090CD40;" - "MOV EAX,[ESI+0xC];" - "CMP EAX,[ESI+0x8];" - "JAE Err;" - "CMP DWORD PTR [EAX],0x5;" - "JNE Err;" - "MOV EAX,[EAX+0x4];" - "XOR EBX,EBX;" - "MOV CL,[EAX+0x9];" - "TEST CL,CL;" - "JZ GTS_L2;" - "MOV EDX,1;" - "SHL EDX,CL;" - "MOV ECX,[EAX+0x14];" - "GTS_L3:;" - "CMP DWORD PTR [ECX+0x8],0x0;" - "JE GTS_L4;" - "ADD EBX,0x1;" - "GTS_L4:;" - "ADD ECX,0x14;" - "DEC EDX;" - "JNZ GTS_L3;" - "GTS_L2:;" - "MOV EDX,[EAX+0x20];" - "TEST EDX,EDX;" - "JZ GTS_L7;" - "MOV ECX,[EAX+0x10];" - "GTS_L5:;" - "CMP DWORD PTR [ECX],0x0;" - "JE GTS_L6;" - "ADD EBX,0x1;" - "GTS_L6:;" - "ADD ECX,0x8;" - "DEC EDX;" - "JNZ GTS_L5;" - "GTS_L7:;" - "CVTSI2SS XMM0,EBX;" - "SUB ESP,0x4;" - "MOVSS [ESP],XMM0;" - "PUSH ESI;" - "CALL PushNumber;" - "ADD ESP,0x8;" - "MOV EAX,0x1;" - "RET;" - "Err:;" - "SUB ESP,0x4;" - "XORPS XMM0, XMM0;" - "MOVSS [ESP],XMM0;" - "PUSH ESI;" - "CALL PushNumber;" - "ADD ESP,0x8;" - "MOV EAX,0x1;" - "RET;" - ); + int size = 0; + auto base = GetField(L, 0xC); + auto top = GetField(L, 0x8); + if (base >= top || base->tt != LUA_TTABLE) + { + lua_pushnumber(L, size); + return 1; + } + + auto table = (lua::Table *)base->value; + uint8_t lsizenode = table->lsizenode; + if (lsizenode) + { + uint32_t num_nodes = 1 << lsizenode; + auto node = table->node; + do + { + if (node->i_val.tt) + ++size; + ++node; + --num_nodes; + } while (num_nodes); + } + int sizearray = table->sizearray; + if (sizearray) + { + auto array = table->array; + do + { + if (array->tt) + ++size; + ++array; + --sizearray; + } while (sizearray); + } + + lua_pushnumber(L, size); + return 1; } -void IsTableEmpty() +int lua_tableempty(lua_State *L) { - asm( - "MOV EAX,[ESI+0xC];" - "CMP EAX,[ESI+0x8];" - "JAE ITE_L72;" - "CMP DWORD PTR [EAX],0x5;" - "JNE ITE_L72;" - "MOV EAX,[EAX+0x4];" - "MOV CL,[EAX+0x9];" - "TEST CL,CL;" - "JZ ITE_L22;" - "MOV EDX,1;" - "SHL EDX,CL;" - "MOV ECX,[EAX+0x14];" - "ITE_L32:;" - "CMP DWORD PTR [ECX+0x8],0x0;" - "JNE ITE_L62;" - "ADD ECX,0x14;" - "DEC EDX;" - "JNZ ITE_L32;" - "ITE_L22:;" - "MOV EDX,[EAX+0x20];" - "TEST EDX,EDX;" - "JZ ITE_L72;" - "MOV ECX,[EAX+0x10];" - "ITE_L5:;" - "CMP DWORD PTR [ECX],0x0;" - "JNE ITE_L62;" - "ADD ECX,0x8;" - "DEC EDX;" - "JNZ ITE_L5;" - "ITE_L72:;" - "PUSH 0x1;" - "JMP ITE_L12;" - "ITE_L62:;" - "PUSH 0x0;" - "ITE_L12:;" - "PUSH ESI;" - "CALL 0x0090CF80;" //PushBool - "ADD ESP,0x8;" - "MOV EAX,0x1;" - ); + auto base = GetField(L, 0xC); + auto top = GetField(L, 0x8); + if (base >= top || base->tt != LUA_TTABLE) + { + lua_pushboolean(L, true); + return 1; + } + + auto table = (lua::Table *)base->value; + constexpr auto has_nodes = [](lua::Table *t) + { + uint8_t lsizenode = t->lsizenode; + if (!lsizenode) + return false; + + uint32_t num_nodes = 1 << lsizenode; + auto node = t->node; + while (node->i_val.tt == LUA_TNIL) + { + ++node; + if (!--num_nodes) + return false; + } + return true; + }; + + constexpr auto has_array = [](lua::Table *t) + { + int sizearray = t->sizearray; + if (!sizearray) + return false; + + auto array = t->array; + while (array->tt == LUA_TNIL) + { + ++array; + if (!--sizearray) + return false; + } + return true; + }; + + lua_pushboolean(L, !(has_nodes(table) || has_array(table))); + return 1; } #include "include/LuaAPI.h" -int TableClone(lua_State* L) +int TableClone(lua_State *L) { LuaObject obj{L->LuaState, 1}; LuaObject cloned{}; @@ -119,32 +143,36 @@ int TableClone(lua_State* L) // UI_Lua reprsl({table.unpack2({1,2,3,4},-1000)}) // UI_Lua reprsl({table.unpack2({1,2,3,4},0, 1000000)}) //stack overflow -int lua_unpack(lua_State *l) { - luaL_checktype(l, 1, LUA_TTABLE); - const int n = lua_getn(l, 1); - const int start_i = luaL_optnumber(l, 2, 1); - const int end_i = luaL_optnumber(l, 3, n); - if(start_i > end_i) return 0; - - const int n_stack = end_i - start_i + 1; - luaL_checkstack(l, n_stack, "too many results to unpack"); - for (int i = start_i; i <= end_i; i++) { - lua_rawgeti(l, 1, i); - } - return n_stack; +int lua_unpack(lua_State *l) +{ + luaL_checktype(l, 1, LUA_TTABLE); + const int n = lua_getn(l, 1); + const int start_i = luaL_optnumber(l, 2, 1); + const int end_i = luaL_optnumber(l, 3, n); + if (start_i > end_i) + return 0; + + const int n_stack = end_i - start_i + 1; + luaL_checkstack(l, n_stack, "too many results to unpack"); + for (int i = start_i; i <= end_i; i++) + { + lua_rawgeti(l, 1, i); + } + return n_stack; } -int RegTableFuncsDesc[] = {"getsize2",&GetTableSize, "empty2", &IsTableEmpty, - "getn2", 0x00927C20, "clone", &TableClone, - "unpack", &lua_unpack, 0, 0}; - -void RegTableFuncs() { - asm("CALL 0x0090DE00;" - "MOV DWORD PTR [ESP+0x8],%[RegTableFuncsDesc];" - "MOV DWORD PTR [ESP+0xC],0x0;" - "CALL 0x0090DE00;" - "JMP 0x009283B6;" - : - : [RegTableFuncsDesc] "i"(RegTableFuncsDesc) - :); +int RegTableFuncsDesc[] = {"getsize2", &lua_tablesize, "empty2", &lua_tableempty, + "getn2", 0x00927C20, "clone", &TableClone, + "unpack", &lua_unpack, 0, 0}; + +void RegTableFuncs() +{ + asm("CALL 0x0090DE00;" + "MOV DWORD PTR [ESP+0x8],%[RegTableFuncsDesc];" + "MOV DWORD PTR [ESP+0xC],0x0;" + "CALL 0x0090DE00;" + "JMP 0x009283B6;" + : + : [RegTableFuncsDesc] "i"(RegTableFuncsDesc) + :); } \ No newline at end of file From 1c57c00afac807413a1fe3f5bcf965938d2dd326 Mon Sep 17 00:00:00 2001 From: 4z0t Date: Sun, 10 Nov 2024 13:26:47 +0300 Subject: [PATCH 3/9] proper type for array --- section/GetTableSize.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/section/GetTableSize.cpp b/section/GetTableSize.cpp index 716878ce..35534bed 100644 --- a/section/GetTableSize.cpp +++ b/section/GetTableSize.cpp @@ -161,9 +161,12 @@ int lua_unpack(lua_State *l) return n_stack; } -int RegTableFuncsDesc[] = {"getsize2", &lua_tablesize, "empty2", &lua_tableempty, - "getn2", 0x00927C20, "clone", &TableClone, - "unpack", &lua_unpack, 0, 0}; +luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, + {"empty2", &lua_tableempty}, + {"getn2", (lua_CFunction)0x00927C20}, + {"clone", &TableClone}, + {"unpack", &lua_unpack}, + {nullptr, nullptr}}; void RegTableFuncs() { From fe070195435155a94a1b24bf1af8ed7cb0e00993 Mon Sep 17 00:00:00 2001 From: Alexander <84857900+4z0t@users.noreply.github.com> Date: Thu, 14 Nov 2024 15:21:13 +0300 Subject: [PATCH 4/9] proper include path --- section/GetTableSize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/section/GetTableSize.cpp b/section/GetTableSize.cpp index 35534bed..70f5e916 100644 --- a/section/GetTableSize.cpp +++ b/section/GetTableSize.cpp @@ -1,4 +1,4 @@ -#include "include/LuaAPI.h" +#include "LuaAPI.h" namespace lua { struct TObject From f5f4c0d294b8845e92ed4f398f02359c47e668ec Mon Sep 17 00:00:00 2001 From: 4z0t Date: Fri, 15 Nov 2024 15:09:56 +0300 Subject: [PATCH 5/9] refactor --- asm.h | 1 + hooks/GetTableSize.cpp | 5 ----- hooks/TableFunc.hook | 2 ++ section/GetTableSize.cpp | 18 ++++++++---------- 4 files changed, 11 insertions(+), 15 deletions(-) create mode 100644 asm.h delete mode 100644 hooks/GetTableSize.cpp create mode 100644 hooks/TableFunc.hook diff --git a/asm.h b/asm.h new file mode 100644 index 00000000..73a97a4e --- /dev/null +++ b/asm.h @@ -0,0 +1 @@ +#define SECTION(index, address) ".section h"#index"; .set h"#index","#address";" \ No newline at end of file diff --git a/hooks/GetTableSize.cpp b/hooks/GetTableSize.cpp deleted file mode 100644 index b201a87a..00000000 --- a/hooks/GetTableSize.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "../define.h" -asm( - ".section h0; .set h0,0x9283B1;" - "JMP "QU(RegTableFuncs)";" -); \ No newline at end of file diff --git a/hooks/TableFunc.hook b/hooks/TableFunc.hook new file mode 100644 index 00000000..106a422b --- /dev/null +++ b/hooks/TableFunc.hook @@ -0,0 +1,2 @@ +0x0090AB1F: + call @lua_openlibtable \ No newline at end of file diff --git a/section/GetTableSize.cpp b/section/GetTableSize.cpp index 5f5920ae..55d1df8a 100644 --- a/section/GetTableSize.cpp +++ b/section/GetTableSize.cpp @@ -126,7 +126,7 @@ int lua_tableempty(lua_State *L) return 1; } -int TableClone(lua_State* L) +int TableClone(lua_State *L) { LuaObject obj{L->LuaState, 1}; LuaObject cloned{}; @@ -167,14 +167,12 @@ luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, {"unpack", &lua_unpack}, {nullptr, nullptr}}; -void RegTableFuncs() + +extern const luaL_reg original_table_funcs[] asm("0x00D47418"); + +int __cdecl lua_openlibtable(lua_State *L) { - asm("CALL 0x0090DE00;" - "MOV DWORD PTR [ESP+0x8],%[RegTableFuncsDesc];" - "MOV DWORD PTR [ESP+0xC],0x0;" - "CALL 0x0090DE00;" - "JMP 0x009283B6;" - : - : [RegTableFuncsDesc] "i"(RegTableFuncsDesc) - :); + luaL_openlib(L, "table", original_table_funcs, 0); + luaL_openlib(L, "table", RegTableFuncsDesc, 0); + return 1; } \ No newline at end of file From 7603a9d4d4b1ae34bfad8935403a789ec1911911 Mon Sep 17 00:00:00 2001 From: 4z0t Date: Fri, 15 Nov 2024 15:16:11 +0300 Subject: [PATCH 6/9] make const --- section/GetTableSize.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/section/GetTableSize.cpp b/section/GetTableSize.cpp index 55d1df8a..c623d23a 100644 --- a/section/GetTableSize.cpp +++ b/section/GetTableSize.cpp @@ -160,7 +160,7 @@ int lua_unpack(lua_State *l) return n_stack; } -luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, +const luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, {"empty2", &lua_tableempty}, {"getn2", (lua_CFunction)0x00927C20}, {"clone", &TableClone}, From 2e99d8e0f36fe00f5a2180a79a4b4ee09c7a5716 Mon Sep 17 00:00:00 2001 From: 4z0t Date: Fri, 15 Nov 2024 15:28:36 +0300 Subject: [PATCH 7/9] organize fixed files --- hooks/{TableFunc.hook => TableFunc.shook} | 0 .../{GetTableSize.cpp => Lua/TableFuncs.cpp} | 354 +++++++++--------- 2 files changed, 177 insertions(+), 177 deletions(-) rename hooks/{TableFunc.hook => TableFunc.shook} (100%) rename section/{GetTableSize.cpp => Lua/TableFuncs.cpp} (95%) diff --git a/hooks/TableFunc.hook b/hooks/TableFunc.shook similarity index 100% rename from hooks/TableFunc.hook rename to hooks/TableFunc.shook diff --git a/section/GetTableSize.cpp b/section/Lua/TableFuncs.cpp similarity index 95% rename from section/GetTableSize.cpp rename to section/Lua/TableFuncs.cpp index c623d23a..14241b91 100644 --- a/section/GetTableSize.cpp +++ b/section/Lua/TableFuncs.cpp @@ -1,178 +1,178 @@ -#include "LuaAPI.h" -namespace lua -{ - struct TObject - { - int tt; - void *value; - }; - - struct Node - { - TObject i_key; - TObject i_val; - Node *next; - }; - - struct Table - { - /* lua::GCObject*/ void *next; - uint8_t tt; - uint8_t marked; - uint16_t gap; - uint8_t flags; - uint8_t lsizenode; - // padding byte - // padding byte - Table *metatable; - TObject *array; - lua::Node *node; - lua::Node *firstfree; - /*lua::GCObject*/ void *gclist; - int sizearray; - }; - -} // namespace lua - -VALIDATE_SIZE(lua::Table, 0x24); - -int lua_tablesize(lua_State *L) -{ - int size = 0; - auto base = GetField(L, 0xC); - auto top = GetField(L, 0x8); - if (base >= top || base->tt != LUA_TTABLE) - { - lua_pushnumber(L, size); - return 1; - } - - auto table = (lua::Table *)base->value; - uint8_t lsizenode = table->lsizenode; - if (lsizenode) - { - uint32_t num_nodes = 1 << lsizenode; - auto node = table->node; - do - { - if (node->i_val.tt) - ++size; - ++node; - --num_nodes; - } while (num_nodes); - } - int sizearray = table->sizearray; - if (sizearray) - { - auto array = table->array; - do - { - if (array->tt) - ++size; - ++array; - --sizearray; - } while (sizearray); - } - - lua_pushnumber(L, size); - return 1; -} - -int lua_tableempty(lua_State *L) -{ - auto base = GetField(L, 0xC); - auto top = GetField(L, 0x8); - if (base >= top || base->tt != LUA_TTABLE) - { - lua_pushboolean(L, true); - return 1; - } - - auto table = (lua::Table *)base->value; - constexpr auto has_nodes = [](lua::Table *t) - { - uint8_t lsizenode = t->lsizenode; - if (!lsizenode) - return false; - - uint32_t num_nodes = 1 << lsizenode; - auto node = t->node; - while (node->i_val.tt == LUA_TNIL) - { - ++node; - if (!--num_nodes) - return false; - } - return true; - }; - - constexpr auto has_array = [](lua::Table *t) - { - int sizearray = t->sizearray; - if (!sizearray) - return false; - - auto array = t->array; - while (array->tt == LUA_TNIL) - { - ++array; - if (!--sizearray) - return false; - } - return true; - }; - - lua_pushboolean(L, !(has_nodes(table) || has_array(table))); - return 1; -} - -int TableClone(lua_State *L) -{ - LuaObject obj{L->LuaState, 1}; - LuaObject cloned{}; - obj.Clone(&cloned); - cloned.PushStack(L); - return 1; -} - -// UI_Lua reprsl({table.unpack2({1,2,3,4},2,3)}) -// UI_Lua reprsl({table.unpack2({1,2,3,4},2)}) -// UI_Lua reprsl({table.unpack2({1,2,3,4})}) -// UI_Lua reprsl({table.unpack2({1,2,3,4},-1)}) -// UI_Lua reprsl({table.unpack2({1,2,3,4},-1000)}) -// UI_Lua reprsl({table.unpack2({1,2,3,4},0, 1000000)}) //stack overflow - -int lua_unpack(lua_State *l) -{ - luaL_checktype(l, 1, LUA_TTABLE); - const int n = lua_getn(l, 1); - const int start_i = luaL_optnumber(l, 2, 1); - const int end_i = luaL_optnumber(l, 3, n); - if (start_i > end_i) - return 0; - - const int n_stack = end_i - start_i + 1; - luaL_checkstack(l, n_stack, "too many results to unpack"); - for (int i = start_i; i <= end_i; i++) - { - lua_rawgeti(l, 1, i); - } - return n_stack; -} - -const luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, - {"empty2", &lua_tableempty}, - {"getn2", (lua_CFunction)0x00927C20}, - {"clone", &TableClone}, - {"unpack", &lua_unpack}, - {nullptr, nullptr}}; - - -extern const luaL_reg original_table_funcs[] asm("0x00D47418"); - -int __cdecl lua_openlibtable(lua_State *L) -{ - luaL_openlib(L, "table", original_table_funcs, 0); - luaL_openlib(L, "table", RegTableFuncsDesc, 0); - return 1; +#include +namespace lua +{ + struct TObject + { + int tt; + void *value; + }; + + struct Node + { + TObject i_key; + TObject i_val; + Node *next; + }; + + struct Table + { + /* lua::GCObject*/ void *next; + uint8_t tt; + uint8_t marked; + uint16_t gap; + uint8_t flags; + uint8_t lsizenode; + // padding byte + // padding byte + Table *metatable; + TObject *array; + lua::Node *node; + lua::Node *firstfree; + /*lua::GCObject*/ void *gclist; + int sizearray; + }; + +} // namespace lua + +VALIDATE_SIZE(lua::Table, 0x24); + +int lua_tablesize(lua_State *L) +{ + int size = 0; + auto base = GetField(L, 0xC); + auto top = GetField(L, 0x8); + if (base >= top || base->tt != LUA_TTABLE) + { + lua_pushnumber(L, size); + return 1; + } + + auto table = (lua::Table *)base->value; + uint8_t lsizenode = table->lsizenode; + if (lsizenode) + { + uint32_t num_nodes = 1 << lsizenode; + auto node = table->node; + do + { + if (node->i_val.tt) + ++size; + ++node; + --num_nodes; + } while (num_nodes); + } + int sizearray = table->sizearray; + if (sizearray) + { + auto array = table->array; + do + { + if (array->tt) + ++size; + ++array; + --sizearray; + } while (sizearray); + } + + lua_pushnumber(L, size); + return 1; +} + +int lua_tableempty(lua_State *L) +{ + auto base = GetField(L, 0xC); + auto top = GetField(L, 0x8); + if (base >= top || base->tt != LUA_TTABLE) + { + lua_pushboolean(L, true); + return 1; + } + + auto table = (lua::Table *)base->value; + constexpr auto has_nodes = [](lua::Table *t) + { + uint8_t lsizenode = t->lsizenode; + if (!lsizenode) + return false; + + uint32_t num_nodes = 1 << lsizenode; + auto node = t->node; + while (node->i_val.tt == LUA_TNIL) + { + ++node; + if (!--num_nodes) + return false; + } + return true; + }; + + constexpr auto has_array = [](lua::Table *t) + { + int sizearray = t->sizearray; + if (!sizearray) + return false; + + auto array = t->array; + while (array->tt == LUA_TNIL) + { + ++array; + if (!--sizearray) + return false; + } + return true; + }; + + lua_pushboolean(L, !(has_nodes(table) || has_array(table))); + return 1; +} + +int TableClone(lua_State *L) +{ + LuaObject obj{L->LuaState, 1}; + LuaObject cloned{}; + obj.Clone(&cloned); + cloned.PushStack(L); + return 1; +} + +// UI_Lua reprsl({table.unpack2({1,2,3,4},2,3)}) +// UI_Lua reprsl({table.unpack2({1,2,3,4},2)}) +// UI_Lua reprsl({table.unpack2({1,2,3,4})}) +// UI_Lua reprsl({table.unpack2({1,2,3,4},-1)}) +// UI_Lua reprsl({table.unpack2({1,2,3,4},-1000)}) +// UI_Lua reprsl({table.unpack2({1,2,3,4},0, 1000000)}) //stack overflow + +int lua_unpack(lua_State *l) +{ + luaL_checktype(l, 1, LUA_TTABLE); + const int n = lua_getn(l, 1); + const int start_i = luaL_optnumber(l, 2, 1); + const int end_i = luaL_optnumber(l, 3, n); + if (start_i > end_i) + return 0; + + const int n_stack = end_i - start_i + 1; + luaL_checkstack(l, n_stack, "too many results to unpack"); + for (int i = start_i; i <= end_i; i++) + { + lua_rawgeti(l, 1, i); + } + return n_stack; +} + +const luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, + {"empty2", &lua_tableempty}, + {"getn2", (lua_CFunction)0x00927C20}, + {"clone", &TableClone}, + {"unpack", &lua_unpack}, + {nullptr, nullptr}}; + + +extern const luaL_reg original_table_funcs[] asm("0x00D47418"); + +int __cdecl lua_openlibtable(lua_State *L) +{ + luaL_openlib(L, "table", original_table_funcs, 0); + luaL_openlib(L, "table", RegTableFuncsDesc, 0); + return 1; } \ No newline at end of file From d3bce47f687856feb19bc01601269c22ef30a7f3 Mon Sep 17 00:00:00 2001 From: 4z0t Date: Fri, 15 Nov 2024 15:32:04 +0300 Subject: [PATCH 8/9] fix typo --- hooks/{TableFunc.shook => TableFuncs.hook} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename hooks/{TableFunc.shook => TableFuncs.hook} (100%) diff --git a/hooks/TableFunc.shook b/hooks/TableFuncs.hook similarity index 100% rename from hooks/TableFunc.shook rename to hooks/TableFuncs.hook From 07ae1f9dc270760a144f37124b32fb726bbbc3aa Mon Sep 17 00:00:00 2001 From: 4z0t Date: Fri, 15 Nov 2024 15:35:00 +0300 Subject: [PATCH 9/9] fix format --- section/Lua/TableFuncs.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/section/Lua/TableFuncs.cpp b/section/Lua/TableFuncs.cpp index 14241b91..8053466d 100644 --- a/section/Lua/TableFuncs.cpp +++ b/section/Lua/TableFuncs.cpp @@ -161,12 +161,11 @@ int lua_unpack(lua_State *l) } const luaL_reg RegTableFuncsDesc[] = {{"getsize2", &lua_tablesize}, - {"empty2", &lua_tableempty}, - {"getn2", (lua_CFunction)0x00927C20}, - {"clone", &TableClone}, - {"unpack", &lua_unpack}, - {nullptr, nullptr}}; - + {"empty2", &lua_tableempty}, + {"getn2", (lua_CFunction)0x00927C20}, + {"clone", &TableClone}, + {"unpack", &lua_unpack}, + {nullptr, nullptr}}; extern const luaL_reg original_table_funcs[] asm("0x00D47418");