mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 12:05:11 +00:00
Added ability for sync tables to contain tables
This commit is contained in:
parent
5e8db3de00
commit
9a3796f0b8
10 changed files with 444 additions and 205 deletions
|
@ -9,10 +9,6 @@ HOOK_ON_SET_MARIO_ACTION = 3
|
||||||
HOOK_BEFORE_PHYS_STEP = 4
|
HOOK_BEFORE_PHYS_STEP = 4
|
||||||
HOOK_MAX = 5
|
HOOK_MAX = 5
|
||||||
|
|
||||||
LST_GLOBAL = 0
|
|
||||||
LST_PLAYER = 1
|
|
||||||
LST_MAX = 2
|
|
||||||
|
|
||||||
_CObject = {
|
_CObject = {
|
||||||
__index = function (t,k)
|
__index = function (t,k)
|
||||||
return _get_field(t['_lot'], t['_pointer'], k)
|
return _get_field(t['_lot'], t['_pointer'], k)
|
||||||
|
@ -37,6 +33,15 @@ _SyncTable = {
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ReadOnlyTable = {
|
||||||
|
__index = function (t,k)
|
||||||
|
local _table = rawget(t, '_table')
|
||||||
|
return _table[k]
|
||||||
|
end,
|
||||||
|
__newindex = function (t,k,v)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
function vec3f_copy(dest, src)
|
function vec3f_copy(dest, src)
|
||||||
dest.x = src.x
|
dest.x = src.x
|
||||||
dest.y = src.y
|
dest.y = src.y
|
||||||
|
|
|
@ -24,9 +24,9 @@ $FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||||
exit
|
exit
|
||||||
|
|
||||||
# debug on server
|
# debug on server
|
||||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt & > /dev/null
|
$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt & > /dev/null
|
||||||
#winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_server.txt' -ex 'quit'
|
winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_server.txt' -ex 'quit'
|
||||||
#exit
|
exit
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# debug on client #
|
# debug on client #
|
||||||
|
|
|
@ -619,12 +619,6 @@
|
||||||
- HOOK_BEFORE_PHYS_STEP
|
- HOOK_BEFORE_PHYS_STEP
|
||||||
- HOOK_MAX
|
- HOOK_MAX
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
- LST_GLOBAL
|
|
||||||
- LST_PLAYER
|
|
||||||
- LST_MAX
|
|
||||||
|
|
||||||
[:arrow_up_small:](#)
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -4,9 +4,6 @@ char gSmluaConstants[] = "HOOK_UPDATE = 0\n"
|
||||||
"HOOK_ON_SET_MARIO_ACTION = 3\n"
|
"HOOK_ON_SET_MARIO_ACTION = 3\n"
|
||||||
"HOOK_BEFORE_PHYS_STEP = 4\n"
|
"HOOK_BEFORE_PHYS_STEP = 4\n"
|
||||||
"HOOK_MAX = 5\n"
|
"HOOK_MAX = 5\n"
|
||||||
"LST_GLOBAL = 0\n"
|
|
||||||
"LST_PLAYER = 1\n"
|
|
||||||
"LST_MAX = 2\n"
|
|
||||||
"_CObject = {\n"
|
"_CObject = {\n"
|
||||||
" __index = function (t,k)\n"
|
" __index = function (t,k)\n"
|
||||||
" return _get_field(t['_lot'], t['_pointer'], k)\n"
|
" return _get_field(t['_lot'], t['_pointer'], k)\n"
|
||||||
|
@ -29,6 +26,14 @@ char gSmluaConstants[] = "HOOK_UPDATE = 0\n"
|
||||||
" _set_sync_table_field(t, k, v)\n"
|
" _set_sync_table_field(t, k, v)\n"
|
||||||
" end\n"
|
" end\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
"_ReadOnlyTable = {\n"
|
||||||
|
" __index = function (t,k)\n"
|
||||||
|
" local _table = rawget(t, '_table')\n"
|
||||||
|
" return _table[k]\n"
|
||||||
|
" end,\n"
|
||||||
|
" __newindex = function (t,k,v)\n"
|
||||||
|
" end\n"
|
||||||
|
"}\n"
|
||||||
"function vec3f_copy(dest, src)\n"
|
"function vec3f_copy(dest, src)\n"
|
||||||
" dest.x = src.x\n"
|
" dest.x = src.x\n"
|
||||||
" dest.y = src.y\n"
|
" dest.y = src.y\n"
|
||||||
|
|
|
@ -3,65 +3,114 @@
|
||||||
#include "pc/network/network.h"
|
#include "pc/network/network.h"
|
||||||
#include "pc/network/network_player.h"
|
#include "pc/network/network_player.h"
|
||||||
|
|
||||||
static bool smlua_value_to_lnt(int index, struct LSTNetworkType* lnt) {
|
#define MAX_UNWOUND_SIZE 256
|
||||||
|
static struct LSTNetworkType sUnwoundLnts[MAX_UNWOUND_LNT] = { 0 };
|
||||||
|
u16 sUnwoundLntsCount = 0;
|
||||||
|
|
||||||
|
static void smlua_sync_table_create(u16 modRemoteIndex, enum LuaSyncTableType lst, int* parentIndex, int* keyIndex) {
|
||||||
lua_State* L = gLuaState;
|
lua_State* L = gLuaState;
|
||||||
int valueType = lua_type(L, index);
|
lua_newtable(L);
|
||||||
|
int t = lua_gettop(L);
|
||||||
|
|
||||||
if (valueType == LUA_TNUMBER) {
|
// push fields
|
||||||
lnt->type = LST_NETWORK_TYPE_INTEGER;
|
smlua_push_integer_field(t, "_remoteIndex", modRemoteIndex);
|
||||||
lnt->value.integer = lua_tointeger(L, index);
|
smlua_push_integer_field(t, "_type", lst);
|
||||||
|
smlua_push_table_field(t, "_seq");
|
||||||
|
smlua_push_table_field(t, "_table");
|
||||||
|
|
||||||
if (lnt->value.integer == 0) {
|
// set parent
|
||||||
lnt->type = LST_NETWORK_TYPE_NUMBER;
|
lua_pushstring(L, "_parent");
|
||||||
lnt->value.number = lua_tonumber(L, index);
|
if (parentIndex == NULL) { lua_pushnil(L); } else { lua_pushvalue(L, *parentIndex); }
|
||||||
}
|
lua_settable(L, -3);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueType == LUA_TBOOLEAN) {
|
// set key name
|
||||||
lnt->type = LST_NETWORK_TYPE_BOOLEAN;
|
lua_pushstring(L, "_name");
|
||||||
lnt->value.boolean = lua_toboolean(L, index);
|
if (keyIndex == NULL) { lua_pushnil(L); } else { lua_pushvalue(L, *keyIndex); }
|
||||||
return true;
|
lua_settable(L, -3);
|
||||||
}
|
|
||||||
|
|
||||||
if (valueType == LUA_TSTRING) {
|
// attach metatable
|
||||||
lnt->type = LST_NETWORK_TYPE_STRING;
|
lua_pushglobaltable(L);
|
||||||
lnt->value.string = lua_tostring(L, index);
|
lua_getfield(L, -1, "_SyncTable");
|
||||||
if (lnt->value.string == NULL || strlen(lnt->value.string) > 256) {
|
lua_setmetatable(L, -3);
|
||||||
LOG_LUA("smlua_value_to_lnt on invalid string value: '%s'", (lnt->value.string == NULL) ? "<null>" : lnt->value.string);
|
lua_pop(L, 1); // pop global table
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueType == LUA_TNIL) {
|
|
||||||
lnt->type = LST_NETWORK_TYPE_NIL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smlua_push_lnt(struct LSTNetworkType* lnt) {
|
static bool smlua_sync_table_unwind(int syncTableIndex, int keyIndex) {
|
||||||
|
LUA_STACK_CHECK_BEGIN();
|
||||||
lua_State* L = gLuaState;
|
lua_State* L = gLuaState;
|
||||||
switch (lnt->type) {
|
sUnwoundLntsCount = 0;
|
||||||
case LST_NETWORK_TYPE_INTEGER:
|
|
||||||
lua_pushinteger(L, lnt->value.integer);
|
// get key
|
||||||
break;
|
sUnwoundLnts[sUnwoundLntsCount++] = smlua_to_lnt(L, keyIndex);
|
||||||
case LST_NETWORK_TYPE_NUMBER:
|
if (!gSmLuaConvertSuccess) {
|
||||||
lua_pushnumber(L, lnt->value.number);
|
LOG_LUA("attempted to unwind sync table with invalid key type");
|
||||||
break;
|
return false;
|
||||||
case LST_NETWORK_TYPE_BOOLEAN:
|
|
||||||
lua_pushboolean(L, lnt->value.boolean);
|
|
||||||
break;
|
|
||||||
case LST_NETWORK_TYPE_STRING:
|
|
||||||
lua_pushstring(L, lnt->value.string);
|
|
||||||
break;
|
|
||||||
case LST_NETWORK_TYPE_NIL:
|
|
||||||
lua_pushnil(L);
|
|
||||||
break;
|
|
||||||
default: SOFT_ASSERT(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// duplicate sync table for iteration
|
||||||
|
lua_pushvalue(L, syncTableIndex);
|
||||||
|
syncTableIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// make sure we remain within limits
|
||||||
|
if (sUnwoundLntsCount >= MAX_UNWOUND_LNT) {
|
||||||
|
LOG_LUA("attempted to unwind sync table past its limit");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get name of table
|
||||||
|
lua_pushstring(L, "_name");
|
||||||
|
lua_gettable(L, syncTableIndex);
|
||||||
|
sUnwoundLnts[sUnwoundLntsCount++] = smlua_to_lnt(L, -1);
|
||||||
|
|
||||||
|
// translate player index
|
||||||
|
lua_getfield(L, syncTableIndex, "_type");
|
||||||
|
lua_Integer lst = lua_tointeger(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
if (lst == LST_PLAYER) {
|
||||||
|
struct LSTNetworkType* n = &sUnwoundLnts[sUnwoundLntsCount - 1];
|
||||||
|
assert(n->type == LST_NETWORK_TYPE_INTEGER);
|
||||||
|
n->value.integer = network_player_global_index_from_local(n->value.integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1); // pop _name value
|
||||||
|
if (!gSmLuaConvertSuccess) {
|
||||||
|
LOG_LUA("attempted to unwind sync table with invalid parent");
|
||||||
|
lua_pop(L, 1); // pop iterative _parent
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get parent of table
|
||||||
|
lua_pushstring(L, "_parent");
|
||||||
|
lua_gettable(L, syncTableIndex);
|
||||||
|
int parentType = lua_type(L, -1);
|
||||||
|
lua_replace(L, syncTableIndex);
|
||||||
|
|
||||||
|
// validate parent type
|
||||||
|
if (parentType != LUA_TTABLE) {
|
||||||
|
if (parentType != LUA_TNIL) {
|
||||||
|
LOG_LUA("attempted to unwind sync table into an invalid parent");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1); // pop iterative _parent
|
||||||
|
|
||||||
|
// check size
|
||||||
|
size_t unwoundSize = 0;
|
||||||
|
for (int i = 0; i < sUnwoundLntsCount; i++) {
|
||||||
|
unwoundSize += sUnwoundLnts[i].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unwoundSize >= MAX_UNWOUND_SIZE) {
|
||||||
|
LOG_LUA("attempted to unwind sync table with too long of a key/parent length");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LUA_STACK_CHECK_END();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool alterSeq) {
|
static void smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool alterSeq) {
|
||||||
|
@ -75,29 +124,70 @@ static void smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool al
|
||||||
// get modRemoteIndex
|
// get modRemoteIndex
|
||||||
u16 modRemoteIndex = smlua_get_integer_field(syncTableIndex, "_remoteIndex");
|
u16 modRemoteIndex = smlua_get_integer_field(syncTableIndex, "_remoteIndex");
|
||||||
if (!gSmLuaConvertSuccess) {
|
if (!gSmLuaConvertSuccess) {
|
||||||
LOG_LUA("smlua_sync_table_send_field on invalid modRemoteIndex: %u", modRemoteIndex);
|
LOG_LUA("Error: tried to alter sync table with an invalid modRemoteIndex: %u", modRemoteIndex);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get lst
|
|
||||||
enum LuaSyncTableType lst = smlua_get_integer_field(syncTableIndex, "_type");
|
|
||||||
if (!gSmLuaConvertSuccess || lst >= LST_MAX) {
|
|
||||||
LOG_LUA("smlua_sync_table_send_field on invalid LST: %u", lst);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get key
|
// get key
|
||||||
struct LSTNetworkType lntKey = { 0 };
|
struct LSTNetworkType lntKey = smlua_to_lnt(L, keyIndex);
|
||||||
if (!smlua_value_to_lnt(keyIndex, &lntKey)) { return; }
|
if (!gSmLuaConvertSuccess) {
|
||||||
|
LOG_LUA("Error: tried to alter sync table with an invalid key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lntKey = lntKey;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
// prev value //
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
lua_getfield(L, syncTableIndex, "_table");
|
||||||
|
lua_pushvalue(L, keyIndex);
|
||||||
|
lua_rawget(L, -2);
|
||||||
|
int prevValueType = lua_type(L, -1);
|
||||||
|
lua_pop(L, 1); // pop prev value
|
||||||
|
lua_pop(L, 1); // pop _table
|
||||||
|
|
||||||
|
if (prevValueType == LUA_TTABLE) {
|
||||||
|
LOG_LUA("Error: tried to assign on top of sync table");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// value //
|
// value //
|
||||||
///////////
|
///////////
|
||||||
|
|
||||||
// get value
|
// get value
|
||||||
struct LSTNetworkType lntValue = { 0 };
|
int valueType = lua_type(L, valueIndex);
|
||||||
if (!smlua_value_to_lnt(valueIndex, &lntValue)) { return; }
|
if (valueType == LUA_TTABLE) {
|
||||||
|
if (prevValueType != LUA_TNIL) {
|
||||||
|
LOG_LUA("Error: tried to set a sync table field to a different sync table");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smlua_is_table_empty(valueIndex)) {
|
||||||
|
LOG_LUA("Error: tried to generate a sync table with a non-empty table");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create sync table
|
||||||
|
int modRemoteIndex = smlua_get_integer_field(syncTableIndex, "_remoteIndex");
|
||||||
|
|
||||||
|
// set table
|
||||||
|
lua_getfield(L, syncTableIndex, "_table");
|
||||||
|
lua_pushvalue(L, keyIndex);
|
||||||
|
smlua_sync_table_create(modRemoteIndex, LST_NORMAL, &syncTableIndex, &keyIndex);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
lua_pop(L, 1); // pop _table
|
||||||
|
|
||||||
|
LUA_STACK_CHECK_END();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct LSTNetworkType lntValue = smlua_to_lnt(L, valueIndex);
|
||||||
|
if (!gSmLuaConvertSuccess) {
|
||||||
|
LOG_LUA("Error: tried to alter sync table with an invalid value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// set value
|
// set value
|
||||||
lua_getfield(L, syncTableIndex, "_table");
|
lua_getfield(L, syncTableIndex, "_table");
|
||||||
|
@ -128,22 +218,19 @@ static void smlua_sync_table_send_field(u8 toLocalIndex, int stackIndex, bool al
|
||||||
lua_pop(L, 1); // pop seq table
|
lua_pop(L, 1); // pop seq table
|
||||||
|
|
||||||
|
|
||||||
///////////
|
|
||||||
// index //
|
|
||||||
///////////
|
|
||||||
|
|
||||||
// get index
|
|
||||||
u16 index = smlua_get_integer_field(syncTableIndex, "_index");
|
|
||||||
index = network_player_global_index_from_local(index);
|
|
||||||
|
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// network //
|
// network //
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
|
// unwind key + parent tables
|
||||||
|
if (!smlua_sync_table_unwind(syncTableIndex, keyIndex)) {
|
||||||
|
LOG_LUA("Error: failed to unwind sync table for sending over the network");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// send over the network
|
// send over the network
|
||||||
if (!gLuaInitializingScript && seq > 0) {
|
if (!gLuaInitializingScript && seq > 0) {
|
||||||
network_send_lua_sync_table(toLocalIndex, seq, modRemoteIndex, lst, index, &lntKey, &lntValue);
|
network_send_lua_sync_table(toLocalIndex, seq, modRemoteIndex, sUnwoundLntsCount, sUnwoundLnts, &lntValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
LUA_STACK_CHECK_END();
|
LUA_STACK_CHECK_END();
|
||||||
|
@ -155,11 +242,11 @@ static int smlua__set_sync_table_field(UNUSED lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 lst, u16 index, struct LSTNetworkType* lntKey, struct LSTNetworkType* lntValue) {
|
void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 lntKeyCount, struct LSTNetworkType* lntKeys, struct LSTNetworkType* lntValue) {
|
||||||
LUA_STACK_CHECK_BEGIN();
|
LUA_STACK_CHECK_BEGIN();
|
||||||
lua_State* L = gLuaState;
|
lua_State* L = gLuaState;
|
||||||
|
|
||||||
// figure out table
|
// figure out mod table
|
||||||
struct ModTable* table = NULL;
|
struct ModTable* table = NULL;
|
||||||
if (gNetworkType == NT_SERVER) {
|
if (gNetworkType == NT_SERVER) {
|
||||||
table = &gModTableLocal;
|
table = &gModTableLocal;
|
||||||
|
@ -183,12 +270,6 @@ void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 ls
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanity check lst
|
|
||||||
if (lst >= LST_MAX) {
|
|
||||||
LOG_ERROR("Received sync table field packet with an invalid LST: %u", lst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sanity check lntValue
|
// sanity check lntValue
|
||||||
if (lntValue->type >= LST_NETWORK_TYPE_MAX) {
|
if (lntValue->type >= LST_NETWORK_TYPE_MAX) {
|
||||||
LOG_ERROR("Received sync table field packet with an invalid lnt type: %u", lntValue->type);
|
LOG_ERROR("Received sync table field packet with an invalid lnt type: %u", lntValue->type);
|
||||||
|
@ -197,28 +278,61 @@ void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 ls
|
||||||
|
|
||||||
lua_getglobal(L, "_G"); // get global table
|
lua_getglobal(L, "_G"); // get global table
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, entry->path); // get the file's "global" table
|
lua_getfield(L, LUA_REGISTRYINDEX, entry->path); // get the file's "global" table
|
||||||
|
int fileGlobalIndex = lua_gettop(L);
|
||||||
|
|
||||||
// get sync table
|
// push global sync table
|
||||||
u16 syncTableSize = 0;
|
u16 syncTableSize = 1;
|
||||||
switch (lst) {
|
smlua_push_lnt(&lntKeys[lntKeyCount - 1]);
|
||||||
case LST_GLOBAL:
|
lua_gettable(L, fileGlobalIndex);
|
||||||
syncTableSize = 1;
|
int syncTableIndex = lua_gettop(L);
|
||||||
lua_getfield(L, -1, "gGlobalSyncTable");
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||||
break;
|
LOG_ERROR("Received sync table field packet with an invalid table");
|
||||||
case LST_PLAYER:
|
return;
|
||||||
syncTableSize = 2;
|
}
|
||||||
lua_getfield(L, -1, "gPlayerSyncTable");
|
|
||||||
lua_pushinteger(L, network_player_local_index_from_global(index));
|
for (int i = lntKeyCount - 2; i >= 1; i--) {
|
||||||
|
// get child sync table
|
||||||
|
smlua_push_lnt(&lntKeys[i]);
|
||||||
|
lua_gettable(L, -2);
|
||||||
|
|
||||||
|
// create missing tables
|
||||||
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||||
|
lua_pop(L, 1); // pop non-table
|
||||||
|
|
||||||
|
// push internal table of parent
|
||||||
|
lua_pushstring(L, "_table");
|
||||||
|
lua_gettable(L, syncTableIndex);
|
||||||
|
|
||||||
|
// set internal[key] = new sync table
|
||||||
|
smlua_push_lnt(&lntKeys[i]);
|
||||||
|
int keyIndex = lua_gettop(L);
|
||||||
|
smlua_sync_table_create(modRemoteIndex, LST_NORMAL, &syncTableIndex, &keyIndex);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
|
||||||
|
// get new sync table
|
||||||
|
smlua_push_lnt(&lntKeys[i]);
|
||||||
lua_gettable(L, -2);
|
lua_gettable(L, -2);
|
||||||
break;
|
|
||||||
default: assert(false);
|
lua_remove(L, -2); // remove paren'ts internal table
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// translate player index
|
||||||
|
if (smlua_get_integer_field(-1, "_type") == LST_PLAYER) {
|
||||||
|
lua_pop(L, 1); // pop wrong table
|
||||||
|
assert(lntKeys[i].type == LST_NETWORK_TYPE_INTEGER);
|
||||||
|
lua_pushinteger(L, network_player_local_index_from_global(lntKeys[i].value.integer));
|
||||||
|
lua_gettable(L, -2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_remove(L, -2); // remove parent table
|
||||||
}
|
}
|
||||||
|
|
||||||
// get seq table
|
// get seq table
|
||||||
lua_getfield(L, -1, "_seq");
|
lua_getfield(L, -1, "_seq");
|
||||||
|
|
||||||
// get seq number
|
// get seq number
|
||||||
smlua_push_lnt(lntKey);
|
smlua_push_lnt(&lntKeys[0]);
|
||||||
lua_gettable(L, -2);
|
lua_gettable(L, -2);
|
||||||
u64 readSeq = lua_tointeger(L, -1);
|
u64 readSeq = lua_tointeger(L, -1);
|
||||||
lua_pop(L, 1); // pop seq value
|
lua_pop(L, 1); // pop seq value
|
||||||
|
@ -234,7 +348,7 @@ void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 ls
|
||||||
}
|
}
|
||||||
|
|
||||||
// set seq number
|
// set seq number
|
||||||
smlua_push_lnt(lntKey);
|
smlua_push_lnt(&lntKeys[0]);
|
||||||
lua_pushinteger(L, seq);
|
lua_pushinteger(L, seq);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
lua_pop(L, 1); // pop seq table
|
lua_pop(L, 1); // pop seq table
|
||||||
|
@ -245,7 +359,7 @@ void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 ls
|
||||||
int t = lua_gettop(L);
|
int t = lua_gettop(L);
|
||||||
|
|
||||||
// set key/value
|
// set key/value
|
||||||
smlua_push_lnt(lntKey);
|
smlua_push_lnt(&lntKeys[0]);
|
||||||
smlua_push_lnt(lntValue);
|
smlua_push_lnt(lntValue);
|
||||||
lua_rawset(L, t);
|
lua_rawset(L, t);
|
||||||
|
|
||||||
|
@ -271,56 +385,45 @@ void smlua_sync_table_init_globals(char* path, u16 modRemoteIndex) {
|
||||||
lua_State* L = gLuaState;
|
lua_State* L = gLuaState;
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, path);
|
lua_getfield(L, LUA_REGISTRYINDEX, path);
|
||||||
int base = lua_gettop(L);
|
int fileGlobalIndex = lua_gettop(L);
|
||||||
{
|
{
|
||||||
|
// create and attach global sync table
|
||||||
|
lua_pushstring(L, "gGlobalSyncTable");
|
||||||
|
int keyIndex = lua_gettop(L);
|
||||||
|
smlua_sync_table_create(modRemoteIndex, LST_NORMAL, NULL, &keyIndex);
|
||||||
|
lua_settable(L, fileGlobalIndex);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// create player sync table
|
||||||
|
lua_pushstring(L, "gPlayerSyncTable");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
int t = lua_gettop(L);
|
int tableIndex = lua_gettop(L);
|
||||||
|
smlua_push_string_field(tableIndex, "_name", "gPlayerSyncTable");
|
||||||
|
|
||||||
// push fields
|
// create internal table
|
||||||
smlua_push_integer_field(t, "_remoteIndex", modRemoteIndex);
|
lua_pushstring(L, "_table");
|
||||||
smlua_push_integer_field(t, "_type", LST_GLOBAL);
|
lua_newtable(L);
|
||||||
smlua_push_integer_field(t, "_index", 0);
|
int internalTableIndex = lua_gettop(L);
|
||||||
smlua_push_table_field(t, "_seq");
|
|
||||||
smlua_push_table_field(t, "_table");
|
// create player sync tables
|
||||||
smlua_push_string_field(t, "_name", "gGlobalSyncTable");
|
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||||
smlua_push_nil_field(t, "_parent");
|
lua_pushinteger(L, i);
|
||||||
|
int keyIndex = lua_gettop(L);
|
||||||
|
smlua_sync_table_create(modRemoteIndex, LST_PLAYER, &tableIndex, &keyIndex);
|
||||||
|
lua_settable(L, internalTableIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// attach internal table
|
||||||
|
lua_settable(L, tableIndex);
|
||||||
|
|
||||||
// attach metatable
|
// attach metatable
|
||||||
lua_pushglobaltable(L);
|
lua_pushglobaltable(L);
|
||||||
lua_getfield(L, -1, "_SyncTable");
|
lua_getfield(L, -1, "_ReadOnlyTable");
|
||||||
lua_setmetatable(L, -3);
|
lua_setmetatable(L, tableIndex);
|
||||||
lua_pop(L, 1); // pop global table
|
lua_pop(L, 1); // pop global table
|
||||||
|
|
||||||
// attach sync table to file's "globals"
|
// attach player sync table
|
||||||
lua_setfield(L, base, "gGlobalSyncTable");
|
lua_settable(L, fileGlobalIndex);
|
||||||
}
|
|
||||||
{
|
|
||||||
lua_newtable(L);
|
|
||||||
int playerTop = lua_gettop(L);
|
|
||||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
|
||||||
lua_pushinteger(L, i);
|
|
||||||
|
|
||||||
lua_newtable(L);
|
|
||||||
int t = lua_gettop(L);
|
|
||||||
|
|
||||||
smlua_push_integer_field(t, "_remoteIndex", modRemoteIndex);
|
|
||||||
smlua_push_integer_field(t, "_type", LST_PLAYER);
|
|
||||||
smlua_push_integer_field(t, "_index", i);
|
|
||||||
smlua_push_table_field(t, "_seq");
|
|
||||||
smlua_push_table_field(t, "_table");
|
|
||||||
smlua_push_string_field(t, "_name", "gPlayerSyncTable"); // <--- incorrect
|
|
||||||
smlua_push_nil_field(t, "_parent"); // <--- incorrect
|
|
||||||
|
|
||||||
// attach metatable
|
|
||||||
lua_pushglobaltable(L);
|
|
||||||
lua_getfield(L, -1, "_SyncTable");
|
|
||||||
lua_setmetatable(L, -3);
|
|
||||||
lua_pop(L, 1); // pop global table
|
|
||||||
|
|
||||||
// attach table to gPlayerSyncTable
|
|
||||||
lua_settable(L, playerTop);
|
|
||||||
}
|
|
||||||
lua_setfield(L, base, "gPlayerSyncTable");
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1); // pop file's "global" table
|
lua_pop(L, 1); // pop file's "global" table
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#ifndef SMLUA_SYNC_TABLE_H
|
#ifndef SMLUA_SYNC_TABLE_H
|
||||||
#define SMLUA_SYNC_TABLE_H
|
#define SMLUA_SYNC_TABLE_H
|
||||||
|
|
||||||
|
#define MAX_UNWOUND_LNT 16
|
||||||
|
|
||||||
enum LuaSyncTableType {
|
enum LuaSyncTableType {
|
||||||
LST_GLOBAL,
|
LST_NORMAL,
|
||||||
LST_PLAYER,
|
LST_PLAYER,
|
||||||
LST_MAX,
|
LST_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LSTNetworkType;
|
struct LSTNetworkType;
|
||||||
|
void smlua_set_sync_table_field_from_network(u64 seq, u16 modRemoteIndex, u16 lntKeyCount, struct LSTNetworkType* lntKeys, struct LSTNetworkType* lntValue);
|
||||||
void smlua_set_sync_table_field_from_network(u64 seq, u16 remoteIndex, u16 lst, u16 index, struct LSTNetworkType* lntKey, struct LSTNetworkType* lntValue);
|
|
||||||
void smlua_sync_table_init_globals(char* path, u16 remoteIndex);
|
void smlua_sync_table_init_globals(char* path, u16 remoteIndex);
|
||||||
void smlua_bind_sync_table(void);
|
void smlua_bind_sync_table(void);
|
||||||
void smlua_sync_table_send_all(u8 toLocalIndex);
|
void smlua_sync_table_send_all(u8 toLocalIndex);
|
||||||
|
|
|
@ -20,25 +20,24 @@ s16* smlua_get_vec3s_from_buffer(void) {
|
||||||
return sVec3sBuffer[sVec3sBufferIndex++];
|
return sVec3sBuffer[sVec3sBufferIndex++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void smlua_bind_function(lua_State* L, const char* name, void* func) {
|
void smlua_bind_function(lua_State* L, const char* name, void* func) {
|
||||||
lua_pushcfunction(L, func);
|
lua_pushcfunction(L, func);
|
||||||
lua_setglobal(L, name);
|
lua_setglobal(L, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void smlua_logline(void) {
|
|
||||||
lua_State* L = gLuaState;
|
bool smlua_is_table_empty(int index) {
|
||||||
lua_Debug info;
|
lua_pushnil(gLuaState); // key
|
||||||
int level = 0;
|
if (lua_next(gLuaState, index)) {
|
||||||
while (lua_getstack(L, level, &info)) {
|
lua_pop(gLuaState, 2);
|
||||||
lua_getinfo(L, "nSl", &info);
|
return false;
|
||||||
LOG_INFO(" [%d] %s:%d -- %s [%s]",
|
|
||||||
level, info.short_src, info.currentline,
|
|
||||||
(info.name ? info.name : "<unknown>"), info.what);
|
|
||||||
++level;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
lua_Integer smlua_to_integer(lua_State* L, int index) {
|
lua_Integer smlua_to_integer(lua_State* L, int index) {
|
||||||
if (lua_type(L, index) == LUA_TBOOLEAN) {
|
if (lua_type(L, index) == LUA_TBOOLEAN) {
|
||||||
|
@ -121,7 +120,63 @@ void* smlua_to_cobject(lua_State* L, int index, u16 lot) {
|
||||||
return pointer;
|
return pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
struct LSTNetworkType smlua_to_lnt(lua_State* L, int index) {
|
||||||
|
struct LSTNetworkType lnt = { 0 };
|
||||||
|
int valueType = lua_type(L, index);
|
||||||
|
|
||||||
|
if (valueType == LUA_TNUMBER) {
|
||||||
|
lnt.type = LST_NETWORK_TYPE_INTEGER;
|
||||||
|
lnt.value.integer = lua_tointeger(L, index);
|
||||||
|
lnt.size = sizeof(u8) + sizeof(long long);
|
||||||
|
|
||||||
|
if (lnt.value.integer == 0) {
|
||||||
|
lnt.type = LST_NETWORK_TYPE_NUMBER;
|
||||||
|
lnt.value.number = lua_tonumber(L, index);
|
||||||
|
lnt.size = sizeof(u8) + sizeof(double);
|
||||||
|
|
||||||
|
if (lnt.value.number == 0) {
|
||||||
|
lnt.type = LST_NETWORK_TYPE_INTEGER;
|
||||||
|
lnt.size = sizeof(u8) + sizeof(long long);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gSmLuaConvertSuccess = true;
|
||||||
|
return lnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueType == LUA_TBOOLEAN) {
|
||||||
|
lnt.type = LST_NETWORK_TYPE_BOOLEAN;
|
||||||
|
lnt.value.boolean = lua_toboolean(L, index);
|
||||||
|
lnt.size = sizeof(u8) + sizeof(u8);
|
||||||
|
gSmLuaConvertSuccess = true;
|
||||||
|
return lnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueType == LUA_TSTRING) {
|
||||||
|
lnt.type = LST_NETWORK_TYPE_STRING;
|
||||||
|
lnt.value.string = (char*)lua_tostring(L, index);
|
||||||
|
if (lnt.value.string == NULL || strlen(lnt.value.string) > 256) {
|
||||||
|
LOG_LUA("smlua_to_lnt on invalid string value: '%s'", (lnt.value.string == NULL) ? "<null>" : lnt.value.string);
|
||||||
|
gSmLuaConvertSuccess = false;
|
||||||
|
return lnt;
|
||||||
|
}
|
||||||
|
lnt.size = sizeof(u8) + sizeof(u16) + sizeof(u8) * strlen(lnt.value.string);
|
||||||
|
gSmLuaConvertSuccess = true;
|
||||||
|
return lnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueType == LUA_TNIL) {
|
||||||
|
lnt.type = LST_NETWORK_TYPE_NIL;
|
||||||
|
lnt.size = sizeof(u8);
|
||||||
|
gSmLuaConvertSuccess = true;
|
||||||
|
return lnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_LUA("smlua_to_lnt on invalid type: '%d'", valueType);
|
||||||
|
gSmLuaConvertSuccess = false;
|
||||||
|
return lnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void smlua_push_object(lua_State* L, u16 lot, void* p) {
|
void smlua_push_object(lua_State* L, u16 lot, void* p) {
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
|
@ -166,6 +221,32 @@ void smlua_push_table_field(int index, char* name) {
|
||||||
lua_setfield(gLuaState, index, name);
|
lua_setfield(gLuaState, index, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void smlua_push_lnt(struct LSTNetworkType* lnt) {
|
||||||
|
lua_State* L = gLuaState;
|
||||||
|
switch (lnt->type) {
|
||||||
|
case LST_NETWORK_TYPE_INTEGER:
|
||||||
|
lua_pushinteger(L, lnt->value.integer);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_NUMBER:
|
||||||
|
lua_pushnumber(L, lnt->value.number);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_BOOLEAN:
|
||||||
|
lua_pushboolean(L, lnt->value.boolean);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_STRING:
|
||||||
|
lua_pushstring(L, lnt->value.string);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_NIL:
|
||||||
|
lua_pushnil(L);
|
||||||
|
break;
|
||||||
|
default: SOFT_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
lua_Integer smlua_get_integer_field(int index, char* name) {
|
lua_Integer smlua_get_integer_field(int index, char* name) {
|
||||||
if (lua_type(gLuaState, index) != LUA_TTABLE) {
|
if (lua_type(gLuaState, index) != LUA_TTABLE) {
|
||||||
LOG_LUA("smlua_get_integer_field received improper type '%d'", lua_type(gLuaState, index));
|
LOG_LUA("smlua_get_integer_field received improper type '%d'", lua_type(gLuaState, index));
|
||||||
|
@ -190,13 +271,29 @@ lua_Number smlua_get_number_field(int index, char* name) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool smlua_is_table_empty(int index) {
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
lua_pushnil(gLuaState); // key
|
|
||||||
if (lua_next(gLuaState, index)) {
|
char* smlua_lnt_to_str(struct LSTNetworkType* lnt) {
|
||||||
lua_pop(gLuaState, 2);
|
static char sLntStr[32] = "";
|
||||||
return false;
|
switch (lnt->type) {
|
||||||
|
case LST_NETWORK_TYPE_INTEGER:
|
||||||
|
snprintf(sLntStr, 32, "%lld", lnt->value.integer);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_NUMBER:
|
||||||
|
snprintf(sLntStr, 32, "%f", lnt->value.number);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_BOOLEAN:
|
||||||
|
snprintf(sLntStr, 32, "%u", lnt->value.boolean);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_STRING:
|
||||||
|
snprintf(sLntStr, 32, "%s", lnt->value.string);
|
||||||
|
break;
|
||||||
|
case LST_NETWORK_TYPE_NIL:
|
||||||
|
snprintf(sLntStr, 32, "<NIL>");
|
||||||
|
break;
|
||||||
|
default: SOFT_ASSERT(false);
|
||||||
}
|
}
|
||||||
return true;
|
return sLntStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smlua_dump_stack(void) {
|
void smlua_dump_stack(void) {
|
||||||
|
@ -274,4 +371,17 @@ void smlua_dump_table(int index) {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
printf("--------------\n");
|
printf("--------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void smlua_logline(void) {
|
||||||
|
lua_State* L = gLuaState;
|
||||||
|
lua_Debug info;
|
||||||
|
int level = 0;
|
||||||
|
while (lua_getstack(L, level, &info)) {
|
||||||
|
lua_getinfo(L, "nSl", &info);
|
||||||
|
LOG_INFO(" [%d] %s:%d -- %s [%s]",
|
||||||
|
level, info.short_src, info.currentline,
|
||||||
|
(info.name ? info.name : "<unknown>"), info.what);
|
||||||
|
++level;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,12 +7,14 @@ f32* smlua_get_vec3f_from_buffer(void);
|
||||||
s16* smlua_get_vec3s_from_buffer(void);
|
s16* smlua_get_vec3s_from_buffer(void);
|
||||||
|
|
||||||
void smlua_bind_function(lua_State* L, const char* name, void* func);
|
void smlua_bind_function(lua_State* L, const char* name, void* func);
|
||||||
void smlua_logline(void);
|
bool smlua_is_table_empty(int index);
|
||||||
|
|
||||||
|
|
||||||
lua_Integer smlua_to_integer(lua_State* L, int index);
|
lua_Integer smlua_to_integer(lua_State* L, int index);
|
||||||
lua_Number smlua_to_number(lua_State* L, int index);
|
lua_Number smlua_to_number(lua_State* L, int index);
|
||||||
const char* smlua_to_string(lua_State* L, int index);
|
const char* smlua_to_string(lua_State* L, int index);
|
||||||
void* smlua_to_cobject(lua_State* L, int index, u16 lot);
|
void* smlua_to_cobject(lua_State* L, int index, u16 lot);
|
||||||
|
struct LSTNetworkType smlua_to_lnt(lua_State* L, int index);
|
||||||
|
|
||||||
void smlua_push_object(lua_State* L, u16 lot, void* p);
|
void smlua_push_object(lua_State* L, u16 lot, void* p);
|
||||||
void smlua_push_integer_field(int index, char* name, lua_Integer val);
|
void smlua_push_integer_field(int index, char* name, lua_Integer val);
|
||||||
|
@ -21,11 +23,13 @@ void smlua_push_string_field(int index, char* name, const char* val);
|
||||||
void smlua_push_nil_field(int index, char* name);
|
void smlua_push_nil_field(int index, char* name);
|
||||||
void smlua_push_table_field(int index, char* name);
|
void smlua_push_table_field(int index, char* name);
|
||||||
|
|
||||||
|
void smlua_push_lnt(struct LSTNetworkType* lnt);
|
||||||
|
|
||||||
lua_Integer smlua_get_integer_field(int index, char* name);
|
lua_Integer smlua_get_integer_field(int index, char* name);
|
||||||
lua_Number smlua_get_number_field(int index, char* name);
|
lua_Number smlua_get_number_field(int index, char* name);
|
||||||
|
|
||||||
bool smlua_is_table_empty(int index);
|
char* smlua_lnt_to_str(struct LSTNetworkType* lnt);
|
||||||
|
void smlua_logline(void);
|
||||||
void smlua_dump_stack(void);
|
void smlua_dump_stack(void);
|
||||||
void smlua_dump_globals(void);
|
void smlua_dump_globals(void);
|
||||||
void smlua_dump_table(int index);
|
void smlua_dump_table(int index);
|
||||||
|
|
|
@ -118,8 +118,10 @@ struct LSTNetworkType {
|
||||||
long long integer;
|
long long integer;
|
||||||
double number;
|
double number;
|
||||||
u8 boolean;
|
u8 boolean;
|
||||||
const char* string;
|
char* string;
|
||||||
} value;
|
} value;
|
||||||
|
|
||||||
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// packet.c
|
// packet.c
|
||||||
|
@ -329,7 +331,8 @@ void network_receive_download(struct Packet* p);
|
||||||
// packet_lua_sync_table.c
|
// packet_lua_sync_table.c
|
||||||
void network_send_lua_sync_table_request(void);
|
void network_send_lua_sync_table_request(void);
|
||||||
void network_receive_lua_sync_table_request(struct Packet* p);
|
void network_receive_lua_sync_table_request(struct Packet* p);
|
||||||
void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 remoteIndex, u16 lst, u16 index, struct LSTNetworkType* lntKey, struct LSTNetworkType* lntValue);
|
|
||||||
|
void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 remoteIndex, u16 lntKeyCount, struct LSTNetworkType* lntKey, struct LSTNetworkType* lntValue);
|
||||||
void network_receive_lua_sync_table(struct Packet* p);
|
void network_receive_lua_sync_table(struct Packet* p);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
#include "pc/lua/smlua.h"
|
#include "pc/lua/smlua.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
|
|
||||||
static char sLuaStrValue[257] = { 0 };
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void network_send_lua_sync_table_request(void) {
|
void network_send_lua_sync_table_request(void) {
|
||||||
|
@ -25,8 +23,8 @@ void network_receive_lua_sync_table_request(struct Packet* p) {
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
static bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||||
u16 lntType = lnt->type;
|
u8 lntType = lnt->type;
|
||||||
packet_write(p, &lntType, sizeof(u16));
|
packet_write(p, &lntType, sizeof(u8));
|
||||||
|
|
||||||
switch (lnt->type) {
|
switch (lnt->type) {
|
||||||
case LST_NETWORK_TYPE_NUMBER: {
|
case LST_NETWORK_TYPE_NUMBER: {
|
||||||
|
@ -47,10 +45,13 @@ static bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case LST_NETWORK_TYPE_STRING: {
|
case LST_NETWORK_TYPE_STRING: {
|
||||||
snprintf(sLuaStrValue, 256, "%s", lnt->value.string);
|
u16 valueLength = strlen(lnt->value.string);
|
||||||
u16 valueLength = strlen(sLuaStrValue);
|
if (valueLength < 1 || valueLength > 256) {
|
||||||
|
LOG_ERROR("attempted to send lua sync table with invalid string length: %u", valueLength);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
packet_write(p, &valueLength, sizeof(u16));
|
packet_write(p, &valueLength, sizeof(u16));
|
||||||
packet_write(p, &sLuaStrValue, valueLength * sizeof(u8));
|
packet_write(p, lnt->value.string, valueLength * sizeof(u8));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ static bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
static bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||||
packet_read(p, &lnt->type, sizeof(u16));
|
packet_read(p, &lnt->type, sizeof(u8));
|
||||||
|
|
||||||
switch (lnt->type) {
|
switch (lnt->type) {
|
||||||
case LST_NETWORK_TYPE_NUMBER:
|
case LST_NETWORK_TYPE_NUMBER:
|
||||||
|
@ -86,14 +87,12 @@ static bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||||
case LST_NETWORK_TYPE_STRING: {
|
case LST_NETWORK_TYPE_STRING: {
|
||||||
u16 valueLength = 0;
|
u16 valueLength = 0;
|
||||||
packet_read(p, &valueLength, sizeof(u16));
|
packet_read(p, &valueLength, sizeof(u16));
|
||||||
if (valueLength > 256) {
|
if (valueLength < 1 || valueLength > 256) {
|
||||||
LOG_ERROR("received lua sync table with invalid value length: %d", valueLength);
|
LOG_ERROR("received lua sync table with invalid value length: %d", valueLength);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
lnt->value.string = calloc(valueLength + 1, sizeof(u8));
|
||||||
packet_read(p, &sLuaStrValue, valueLength * sizeof(u8));
|
packet_read(p, lnt->value.string, valueLength * sizeof(u8));
|
||||||
sLuaStrValue[valueLength] = 0;
|
|
||||||
lnt->value.string = sLuaStrValue;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,16 +110,18 @@ static bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 modRemoteIndex, u16 lst, u16 index, struct LSTNetworkType* lntKey, struct LSTNetworkType* lntValue) {
|
void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 modRemoteIndex, u16 lntKeyCount, struct LSTNetworkType* lntKeys, struct LSTNetworkType* lntValue) {
|
||||||
|
|
||||||
struct Packet p = { 0 };
|
struct Packet p = { 0 };
|
||||||
packet_init(&p, PACKET_LUA_SYNC_TABLE, true, PLMT_NONE);
|
packet_init(&p, PACKET_LUA_SYNC_TABLE, true, PLMT_NONE);
|
||||||
packet_write(&p, &seq, sizeof(u64));
|
packet_write(&p, &seq, sizeof(u64));
|
||||||
packet_write(&p, &modRemoteIndex, sizeof(u16));
|
packet_write(&p, &modRemoteIndex, sizeof(u16));
|
||||||
packet_write(&p, &lst, sizeof(u16));
|
|
||||||
packet_write(&p, &index, sizeof(u16));
|
|
||||||
|
|
||||||
if (!packet_write_lnt(&p, lntKey)) { return; }
|
packet_write(&p, &lntKeyCount, sizeof(u16));
|
||||||
|
for (int i = 0; i < lntKeyCount; i++) {
|
||||||
|
if (!packet_write_lnt(&p, &lntKeys[i])) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
if (!packet_write_lnt(&p, lntValue)) { return; }
|
if (!packet_write_lnt(&p, lntValue)) { return; }
|
||||||
|
|
||||||
if (toLocalIndex == 0 || toLocalIndex >= MAX_PLAYERS) {
|
if (toLocalIndex == 0 || toLocalIndex >= MAX_PLAYERS) {
|
||||||
|
@ -133,18 +134,31 @@ void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 modRemoteIndex, u
|
||||||
void network_receive_lua_sync_table(struct Packet* p) {
|
void network_receive_lua_sync_table(struct Packet* p) {
|
||||||
u64 seq = 0;
|
u64 seq = 0;
|
||||||
u16 modRemoteIndex = 0;
|
u16 modRemoteIndex = 0;
|
||||||
u16 lst = 0;
|
u16 lntKeyCount = 0;
|
||||||
u16 index = 0;
|
struct LSTNetworkType lntKeys[MAX_UNWOUND_LNT] = { 0 };
|
||||||
struct LSTNetworkType lntKey = { 0 };
|
|
||||||
struct LSTNetworkType lntValue = { 0 };
|
struct LSTNetworkType lntValue = { 0 };
|
||||||
|
|
||||||
packet_read(p, &seq, sizeof(u64));
|
packet_read(p, &seq, sizeof(u64));
|
||||||
packet_read(p, &modRemoteIndex, sizeof(u16));
|
packet_read(p, &modRemoteIndex, sizeof(u16));
|
||||||
packet_read(p, &lst, sizeof(u16));
|
|
||||||
packet_read(p, &index, sizeof(u16));
|
|
||||||
|
|
||||||
if (!packet_read_lnt(p, &lntKey)) { return; }
|
packet_read(p, &lntKeyCount, sizeof(u16));
|
||||||
if (!packet_read_lnt(p, &lntValue)) { return; }
|
for (int i = 0; i < lntKeyCount; i++) {
|
||||||
|
if (!packet_read_lnt(p, &lntKeys[i])) { goto cleanup; }
|
||||||
|
}
|
||||||
|
|
||||||
smlua_set_sync_table_field_from_network(seq, modRemoteIndex, lst, index, &lntKey, &lntValue);
|
if (!packet_read_lnt(p, &lntValue)) { goto cleanup; }
|
||||||
|
|
||||||
|
smlua_set_sync_table_field_from_network(seq, modRemoteIndex, lntKeyCount, lntKeys, &lntValue);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
for (int i = 0; i < lntKeyCount; i++) {
|
||||||
|
if (lntKeys[i].type != LST_NETWORK_TYPE_STRING) { continue; }
|
||||||
|
if (lntKeys[i].value.string == NULL) { continue; }
|
||||||
|
free(lntKeys[i].value.string);
|
||||||
|
lntKeys[i].value.string = NULL;
|
||||||
|
}
|
||||||
|
if (lntValue.type == LST_NETWORK_TYPE_STRING && lntValue.value.string != NULL) {
|
||||||
|
free(lntValue.value.string);
|
||||||
|
lntValue.value.string = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue