Initial foundation for lua networking
This commit is contained in:
parent
2f9c0abc1e
commit
e9d3bf49da
|
@ -9,18 +9,36 @@ HOOK_ON_SET_MARIO_ACTION = 3
|
|||
HOOK_BEFORE_PHYS_STEP = 4
|
||||
HOOK_MAX = 5
|
||||
|
||||
LST_GLOBAL = 0
|
||||
LST_PLAYER = 1
|
||||
LST_MAX = 2
|
||||
|
||||
_CObject = {
|
||||
__index = function (t,k)
|
||||
return _get_field(t['_lot'], t['_pointer'], k);
|
||||
return _get_field(t['_lot'], t['_pointer'], k)
|
||||
end,
|
||||
__newindex = function (t,k,v)
|
||||
_set_field(t['_lot'], t['_pointer'], k, v);
|
||||
_set_field(t['_lot'], t['_pointer'], k, v)
|
||||
end,
|
||||
__eq = function (a, b)
|
||||
return a['_pointer'] == b['_pointer'] and a['_lot'] == b['_lot'] and a['_pointer'] ~= nil and a['_lot'] ~= nil
|
||||
end
|
||||
}
|
||||
|
||||
_SyncTable = {
|
||||
__index = function (t,k)
|
||||
local _table = rawget(t, '_table')
|
||||
return _table[k]
|
||||
end,
|
||||
__newindex = function (t,k,v)
|
||||
local _table = rawget(t, '_table')
|
||||
if _table[k] == v then return end
|
||||
if _set_sync_table_field(t, k, v) ~= 0 then
|
||||
_table[k] = v
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
function vec3f_copy(dest, src)
|
||||
dest.x = src.x
|
||||
dest.y = src.y
|
||||
|
|
|
@ -519,6 +519,7 @@
|
|||
<ClCompile Include="..\src\pc\lua\smlua_functions.c" />
|
||||
<ClCompile Include="..\src\pc\lua\smlua_functions_autogen.c" />
|
||||
<ClCompile Include="..\src\pc\lua\smlua_hooks.c" />
|
||||
<ClCompile Include="..\src\pc\lua\smlua_sync_table.c" />
|
||||
<ClCompile Include="..\src\pc\lua\smlua_utils.c" />
|
||||
<ClCompile Include="..\src\pc\mixer.c" />
|
||||
<ClCompile Include="..\src\pc\mod_list.c" />
|
||||
|
@ -975,6 +976,7 @@
|
|||
<ClInclude Include="..\src\pc\lua\smlua_functions.h" />
|
||||
<ClInclude Include="..\src\pc\lua\smlua_functions_autogen.h" />
|
||||
<ClInclude Include="..\src\pc\lua\smlua_hooks.h" />
|
||||
<ClInclude Include="..\src\pc\lua\smlua_sync_table.h" />
|
||||
<ClInclude Include="..\src\pc\lua\smlua_utils.h" />
|
||||
<ClInclude Include="..\src\pc\mod_list.h" />
|
||||
<ClInclude Include="..\src\pc\network\branch.h" />
|
||||
|
|
|
@ -4866,6 +4866,9 @@
|
|||
<ClCompile Include="..\src\pc\lua\smlua_cobject_autogen.c">
|
||||
<Filter>Source Files\src\pc\lua</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\lua\smlua_sync_table.c">
|
||||
<Filter>Source Files\src\pc\lua</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h">
|
||||
|
@ -6013,5 +6016,8 @@
|
|||
<ClInclude Include="..\src\pc\lua\smlua_cobject_autogen.h">
|
||||
<Filter>Source Files\src\pc\lua</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\lua\smlua_sync_table.h">
|
||||
<Filter>Source Files\src\pc\lua</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -19,12 +19,12 @@ fi
|
|||
|
||||
# no debug, direct
|
||||
$FILE --server 27015 --configfile sm64config_server.txt &
|
||||
sleep 7
|
||||
sleep 5
|
||||
$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
exit
|
||||
|
||||
# debug on server
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
#$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'
|
||||
#exit
|
||||
|
||||
|
|
|
@ -619,6 +619,12 @@
|
|||
- HOOK_BEFORE_PHYS_STEP
|
||||
- HOOK_MAX
|
||||
|
||||
<br />
|
||||
|
||||
- LST_GLOBAL
|
||||
- LST_PLAYER
|
||||
- LST_MAX
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
|
|
@ -21,7 +21,7 @@ static void smlua_exec_str(char* str) {
|
|||
lua_pop(L, lua_gettop(L));
|
||||
}
|
||||
|
||||
static void smlua_load_script(char* path) {
|
||||
static void smlua_load_script(char* path, u16 remoteIndex) {
|
||||
lua_State* L = gLuaState;
|
||||
if (luaL_loadfile(L, path) != LUA_OK) {
|
||||
LOG_LUA("Failed to load lua script '%s'.", path);
|
||||
|
@ -42,6 +42,9 @@ static void smlua_load_script(char* path) {
|
|||
lua_getfield(L, LUA_REGISTRYINDEX, path);
|
||||
lua_setupvalue(L, 1, 1); // set upvalue (_ENV)
|
||||
|
||||
// load per-file globals
|
||||
smlua_sync_table_init_globals(path, remoteIndex);
|
||||
|
||||
// run chunks
|
||||
if (lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK) {
|
||||
LOG_LUA("Failed to execute lua script '%s'.", path);
|
||||
|
@ -74,6 +77,7 @@ void smlua_init(void) {
|
|||
smlua_bind_cobject();
|
||||
smlua_bind_functions();
|
||||
smlua_bind_functions_autogen();
|
||||
smlua_bind_sync_table();
|
||||
|
||||
extern char gSmluaConstants[];
|
||||
smlua_exec_str(gSmluaConstants);
|
||||
|
@ -87,7 +91,7 @@ void smlua_init(void) {
|
|||
struct ModListEntry* entry = &table->entries[i];
|
||||
if (!entry->enabled) { continue; }
|
||||
LOG_INFO(" %s", entry->path);
|
||||
smlua_load_script(entry->path);
|
||||
smlua_load_script(entry->path, entry->remoteIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,11 +15,20 @@
|
|||
#include "smlua_functions.h"
|
||||
#include "smlua_functions_autogen.h"
|
||||
#include "smlua_hooks.h"
|
||||
#include "smlua_sync_table.h"
|
||||
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#define LOG_LUA(...) ( _debuglog_print_log("LUA ", __FILE__), printf(__VA_ARGS__), printf("\n") )
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
#define LUA_STACK_CHECK_BEGIN() int __LUA_STACK_TOP = lua_gettop(gLuaState)
|
||||
#define LUA_STACK_CHECK_END() if (__LUA_STACK_TOP != lua_gettop(gLuaState)) { smlua_dump_stack(); fflush(stdout); } assert(__LUA_STACK_TOP == lua_gettop(gLuaState))
|
||||
#else
|
||||
#define LUA_STACK_CHECK_BEGIN()
|
||||
#define LUA_STACK_CHECK_END()
|
||||
#endif
|
||||
|
||||
extern lua_State* gLuaState;
|
||||
|
||||
void smlua_init(void);
|
||||
|
|
|
@ -48,6 +48,8 @@ bool smlua_valid_lot(u16 lot) {
|
|||
}
|
||||
|
||||
static int smlua__get_field(lua_State* L) {
|
||||
if (!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
|
||||
enum LuaObjectType lot = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
|
@ -98,6 +100,8 @@ static int smlua__get_field(lua_State* L) {
|
|||
}
|
||||
|
||||
static int smlua__set_field(lua_State* L) {
|
||||
if (!smlua_functions_valid_param_count(L, 4)) { return 0; }
|
||||
|
||||
enum LuaObjectType lot = smlua_to_integer(L, 1);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
|
|
|
@ -4,17 +4,33 @@ char gSmluaConstants[] = "HOOK_UPDATE = 0\n"
|
|||
"HOOK_ON_SET_MARIO_ACTION = 3\n"
|
||||
"HOOK_BEFORE_PHYS_STEP = 4\n"
|
||||
"HOOK_MAX = 5\n"
|
||||
"LST_GLOBAL = 0\n"
|
||||
"LST_PLAYER = 1\n"
|
||||
"LST_MAX = 2\n"
|
||||
"_CObject = {\n"
|
||||
" __index = function (t,k)\n"
|
||||
" return _get_field(t['_lot'], t['_pointer'], k);\n"
|
||||
" return _get_field(t['_lot'], t['_pointer'], k)\n"
|
||||
" end,\n"
|
||||
" __newindex = function (t,k,v)\n"
|
||||
" _set_field(t['_lot'], t['_pointer'], k, v);\n"
|
||||
" _set_field(t['_lot'], t['_pointer'], k, v)\n"
|
||||
" end,\n"
|
||||
" __eq = function (a, b)\n"
|
||||
" return a['_pointer'] == b['_pointer'] and a['_lot'] == b['_lot'] and a['_pointer'] ~= nil and a['_lot'] ~= nil\n"
|
||||
" end\n"
|
||||
"}\n"
|
||||
"_SyncTable = {\n"
|
||||
" __index = function (t,k)\n"
|
||||
" local _table = rawget(t, '_table')\n"
|
||||
" return _table[k]\n"
|
||||
" end,\n"
|
||||
" __newindex = function (t,k,v)\n"
|
||||
" local _table = rawget(t, '_table')\n"
|
||||
" if _table[k] == v then return end\n"
|
||||
" if _set_sync_table_field(t, k, v) ~= 0 then\n"
|
||||
" _table[k] = v\n"
|
||||
" end\n"
|
||||
" end\n"
|
||||
"}\n"
|
||||
"function vec3f_copy(dest, src)\n"
|
||||
" dest.x = src.x\n"
|
||||
" dest.y = src.y\n"
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
#include "smlua.h"
|
||||
#include "pc/mod_list.h"
|
||||
#include "pc/network/network.h"
|
||||
|
||||
static int smlua__set_sync_table_field(UNUSED lua_State* L) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
if (!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
|
||||
// get remoteIndex
|
||||
u16 remoteIndex = smlua_get_integer_field(1, "_remoteIndex");
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
|
||||
// get lst
|
||||
enum LuaSyncTableType lst = smlua_get_integer_field(1, "_type");
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
if (lst >= LST_MAX) {
|
||||
LOG_LUA("_set_sync_table_field on invalid LST: %u", lst);
|
||||
lua_pushinteger(L, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get key
|
||||
const char* key = smlua_to_string(L, 2);
|
||||
if (!gSmLuaConvertSuccess) { return 0; }
|
||||
if (key == NULL || strlen(key) == 0 || strlen(key) > 64) {
|
||||
LOG_LUA("_set_sync_table_field on invalid key: '%s'", (key == NULL) ? "<null>" : key);
|
||||
lua_pushinteger(L, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get value
|
||||
union LSTNetworkUnion lUnion = { 0 };
|
||||
enum LSTNetworkType lUnionType = LST_NETWORK_TYPE_MAX;
|
||||
int valueType = lua_type(L, 3);
|
||||
if (valueType == LUA_TNUMBER) {
|
||||
lUnion.integer = lua_tointeger(L, 3);
|
||||
lUnionType = LST_NETWORK_TYPE_INTEGER;
|
||||
|
||||
if (lUnion.integer == 0) {
|
||||
lUnion.number = lua_tonumber(L, 3);
|
||||
lUnionType = LST_NETWORK_TYPE_NUMBER;
|
||||
}
|
||||
} else {
|
||||
LOG_LUA("_set_sync_table_field on invalid type: '%d'", valueType);
|
||||
lua_pushinteger(L, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get seq table
|
||||
lua_getfield(L, 1, "_seq");
|
||||
int seqT = lua_gettop(L);
|
||||
|
||||
// get seq number
|
||||
lua_getfield(L, -1, key);
|
||||
u64 seq = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// set seq number
|
||||
seq += MAX_PLAYERS + (MAX_PLAYERS - gNetworkPlayers[0].globalIndex);
|
||||
smlua_push_number_field(seqT, (char*)key, seq);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// get index
|
||||
u16 index = smlua_get_integer_field(1, "_index");
|
||||
// TODO: translate to global index
|
||||
|
||||
network_send_lua_sync_table(seq, remoteIndex, lst, index, key, lUnionType, lUnion);
|
||||
|
||||
LUA_STACK_CHECK_END();
|
||||
lua_pushinteger(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void smlua_set_sync_table_field_from_network(u64 seq, u16 remoteIndex, u16 lst, u16 index, const char* key, u16 lUnionType, union LSTNetworkUnion lUnion) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
lua_State* L = gLuaState;
|
||||
|
||||
// figure out table
|
||||
struct ModTable* table = NULL;
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
table = &gModTableLocal;
|
||||
} else if (gNetworkType == NT_CLIENT) {
|
||||
table = &gModTableRemote;
|
||||
} else {
|
||||
LOG_ERROR("Received sync table field packet with an unknown network type: %d", gNetworkType);
|
||||
return;
|
||||
}
|
||||
|
||||
// figure out entry
|
||||
struct ModListEntry* entry = NULL;
|
||||
for (int i = 0; i < table->entryCount; i++) {
|
||||
if (table->entries[i].remoteIndex == remoteIndex) {
|
||||
entry = &table->entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry == NULL) {
|
||||
LOG_ERROR("Could not find mod list entry for remoteIndex: %u", remoteIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// sanity check lst
|
||||
if (lst >= LST_MAX) {
|
||||
LOG_LUA("Received sync table field packet with an invalid LST: %u", lst);
|
||||
return;
|
||||
}
|
||||
|
||||
// sanity check lUnionType
|
||||
if (lUnionType >= LST_NETWORK_TYPE_MAX) {
|
||||
LOG_LUA("Received sync table field packet with an invalid lUnionType: %u", lUnionType);
|
||||
return;
|
||||
}
|
||||
|
||||
lua_getglobal(L, "_G"); // get global table
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, entry->path); // get the file's "global" table
|
||||
|
||||
// get sync table
|
||||
u16 syncTableSize = 0;
|
||||
switch (lst) {
|
||||
case LST_GLOBAL:
|
||||
syncTableSize = 1;
|
||||
lua_getfield(L, -1, "gGlobalSyncTable");
|
||||
break;
|
||||
case LST_PLAYER:
|
||||
syncTableSize = 2;
|
||||
lua_getfield(L, -1, "gPlayerSyncTable");
|
||||
lua_pushinteger(L, index);
|
||||
lua_gettable(L, -2);
|
||||
// TODO: translate to local index
|
||||
break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
// get seq table
|
||||
lua_getfield(L, -1, "_seq");
|
||||
int seqT = lua_gettop(L);
|
||||
|
||||
// get seq number
|
||||
lua_getfield(L, -1, key);
|
||||
u64 readSeq = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// validate seq
|
||||
if (seq <= readSeq) {
|
||||
LOG_INFO("Received outdated sync table field packet: %llu <= %llu", seq, readSeq);
|
||||
lua_pop(L, 1); // pop seq table
|
||||
lua_pop(L, syncTableSize); // pop sync table
|
||||
lua_pop(L, 1); // pop file's "global" table
|
||||
lua_pop(L, 1); // pop global table
|
||||
return;
|
||||
}
|
||||
|
||||
// set seq number
|
||||
smlua_push_number_field(seqT, (char*)key, seq);
|
||||
lua_pop(L, 1); // pop seq table
|
||||
|
||||
// get internal table
|
||||
lua_pushstring(L, "_table");
|
||||
lua_rawget(L, -2);
|
||||
int t = lua_gettop(L);
|
||||
|
||||
// set key/value
|
||||
switch (lUnionType) {
|
||||
case LST_NETWORK_TYPE_INTEGER:
|
||||
lua_pushstring(L, key);
|
||||
lua_pushinteger(L, lUnion.integer);
|
||||
lua_rawset(L, t);
|
||||
break;
|
||||
case LST_NETWORK_TYPE_NUMBER:
|
||||
lua_pushstring(L, key);
|
||||
lua_pushnumber(L, lUnion.number);
|
||||
lua_rawset(L, t);
|
||||
break;
|
||||
default: SOFT_ASSERT(false);
|
||||
}
|
||||
|
||||
lua_pop(L, 1); // pop internal table
|
||||
lua_pop(L, syncTableSize); // pop sync table
|
||||
lua_pop(L, 1); // pop file's "global" table
|
||||
lua_pop(L, 1); // pop global table
|
||||
LUA_STACK_CHECK_END();
|
||||
}
|
||||
|
||||
static void smlua_exec_str(char* str) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
lua_State* L = gLuaState;
|
||||
if (luaL_dostring(L, str) != LUA_OK) {
|
||||
LOG_LUA("Failed to load lua string.");
|
||||
puts(smlua_to_string(L, lua_gettop(L)));
|
||||
}
|
||||
LUA_STACK_CHECK_END();
|
||||
}
|
||||
|
||||
void smlua_sync_table_init_globals(char* path, u16 remoteIndex) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
lua_State* L = gLuaState;
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, path);
|
||||
int base = lua_gettop(L);
|
||||
{
|
||||
lua_newtable(L);
|
||||
int t = lua_gettop(L);
|
||||
|
||||
smlua_push_integer_field(t, "_remoteIndex", remoteIndex);
|
||||
smlua_push_integer_field(t, "_type", LST_GLOBAL);
|
||||
smlua_push_integer_field(t, "_index", 0);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, t, "_seq");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, t, "_table");
|
||||
|
||||
lua_pushglobaltable(L);
|
||||
lua_getfield(L, -1, "_SyncTable");
|
||||
lua_setmetatable(L, -3);
|
||||
lua_pop(L, 1); // pop global table
|
||||
lua_setfield(L, base, "gGlobalSyncTable");
|
||||
}
|
||||
{
|
||||
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", remoteIndex);
|
||||
smlua_push_integer_field(t, "_type", LST_PLAYER);
|
||||
smlua_push_integer_field(t, "_index", i);
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, t, "_seq");
|
||||
|
||||
lua_newtable(L);
|
||||
lua_setfield(L, t, "_table");
|
||||
|
||||
lua_pushglobaltable(L);
|
||||
lua_getfield(L, -1, "_SyncTable");
|
||||
lua_setmetatable(L, -3);
|
||||
lua_pop(L, 1); // pop global table
|
||||
|
||||
lua_settable(L, playerTop);
|
||||
}
|
||||
lua_setfield(L, base, "gPlayerSyncTable");
|
||||
}
|
||||
lua_pop(L, 1); // pop file's "global" table
|
||||
|
||||
LUA_STACK_CHECK_END();
|
||||
}
|
||||
|
||||
void smlua_bind_sync_table(void) {
|
||||
LUA_STACK_CHECK_BEGIN();
|
||||
lua_State* L = gLuaState;
|
||||
smlua_bind_function(L, "_set_sync_table_field", smlua__set_sync_table_field);
|
||||
LUA_STACK_CHECK_END();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef SMLUA_SYNC_TABLE_H
|
||||
#define SMLUA_SYNC_TABLE_H
|
||||
|
||||
enum LuaSyncTableType {
|
||||
LST_GLOBAL,
|
||||
LST_PLAYER,
|
||||
LST_MAX,
|
||||
};
|
||||
|
||||
union LSTNetworkUnion;
|
||||
|
||||
void smlua_set_sync_table_field_from_network(u64 seq, u16 remoteIndex, u16 lst, u16 index, const char* key, u16 lUnionType, union LSTNetworkUnion lUnion);
|
||||
void smlua_sync_table_init_globals(char* path, u16 remoteIndex);
|
||||
void smlua_bind_sync_table(void);
|
||||
|
||||
#endif
|
|
@ -236,7 +236,7 @@ void smlua_dump_table(int index) {
|
|||
lua_pushnil(L); // first key
|
||||
while (lua_next(L, index) != 0) {
|
||||
// uses 'key' (at index -2) and 'value' (at index -1)
|
||||
if (lua_type(L, index) == LUA_TSTRING) {
|
||||
if (lua_type(L, -2) == LUA_TSTRING) {
|
||||
printf("%s - %s\n",
|
||||
lua_tostring(L, -2),
|
||||
lua_typename(L, lua_type(L, -1)));
|
||||
|
|
|
@ -149,6 +149,7 @@ static void mod_list_add_local(u16 index, const char* path, char* name) {
|
|||
table->totalSize += entry->size;
|
||||
fseek(entry->fp, 0, SEEK_SET);
|
||||
|
||||
entry->remoteIndex = index;
|
||||
entry->complete = true;
|
||||
entry->enabled = false;
|
||||
entry->selectable = true;
|
||||
|
@ -263,14 +264,15 @@ static void mod_list_load_local(const char* path) {
|
|||
count++;
|
||||
}
|
||||
|
||||
u16 totalCount = table->entryCount;
|
||||
u16 index = 0;
|
||||
if (table->entries == NULL) {
|
||||
if (count == 0) { closedir(d); return; }
|
||||
mod_list_alloc(table, count);
|
||||
} else {
|
||||
index = table->entryCount;
|
||||
table->entryCount += count;
|
||||
table->entries = (struct ModListEntry*)realloc(table->entries, table->entryCount * sizeof(struct ModListEntry));
|
||||
totalCount += count;
|
||||
table->entries = (struct ModListEntry*)realloc(table->entries, totalCount * sizeof(struct ModListEntry));
|
||||
}
|
||||
|
||||
rewinddir(d);
|
||||
|
@ -281,6 +283,7 @@ static void mod_list_load_local(const char* path) {
|
|||
if (mod_list_contains(table, dir->d_name)) { continue; }
|
||||
LOG_INFO(" %s", dir->d_name);
|
||||
mod_list_add_local(index++, path, dir->d_name);
|
||||
if (index > table->entryCount) { table->entryCount = index; }
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
|
|
@ -83,6 +83,8 @@ void packet_process(struct Packet* p) {
|
|||
case PACKET_DOWNLOAD_REQUEST: network_receive_download_request(p); break;
|
||||
case PACKET_DOWNLOAD: network_receive_download(p); break;
|
||||
|
||||
case PACKET_LUA_SYNC_TABLE: network_receive_lua_sync_table(p); break;
|
||||
|
||||
// custom
|
||||
case PACKET_CUSTOM: network_receive_custom(p); break;
|
||||
default: LOG_ERROR("received unknown packet: %d", p->buffer[0]);
|
||||
|
|
|
@ -59,6 +59,8 @@ enum PacketType {
|
|||
PACKET_DOWNLOAD_REQUEST,
|
||||
PACKET_DOWNLOAD,
|
||||
|
||||
PACKET_LUA_SYNC_TABLE,
|
||||
|
||||
///
|
||||
PACKET_CUSTOM = 255,
|
||||
};
|
||||
|
@ -99,6 +101,17 @@ enum KickReasonType {
|
|||
EKT_FULL_PARTY,
|
||||
};
|
||||
|
||||
union LSTNetworkUnion {
|
||||
long long integer;
|
||||
double number;
|
||||
};
|
||||
|
||||
enum LSTNetworkType {
|
||||
LST_NETWORK_TYPE_INTEGER,
|
||||
LST_NETWORK_TYPE_NUMBER,
|
||||
LST_NETWORK_TYPE_MAX
|
||||
};
|
||||
|
||||
// packet.c
|
||||
void packet_process(struct Packet* p);
|
||||
void packet_receive(struct Packet* packet);
|
||||
|
@ -301,5 +314,8 @@ void network_receive_download_request(struct Packet* p);
|
|||
void network_send_download(u16 clientIndex, u16 serverIndex, u64 offset);
|
||||
void network_receive_download(struct Packet* p);
|
||||
|
||||
// packet_lua_sync_table.c
|
||||
void network_send_lua_sync_table(u64 seq, u16 remoteIndex, u16 lst, u16 index, const char* key, enum LSTNetworkType lUnionType, union LSTNetworkUnion lUnion);
|
||||
void network_receive_lua_sync_table(struct Packet* p);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "pc/lua/smlua.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
void network_send_lua_sync_table(u64 seq, u16 remoteIndex, u16 lst, u16 index, const char* key, enum LSTNetworkType lUnionType, union LSTNetworkUnion lUnion) {
|
||||
u16 keyLength = strlen(key);
|
||||
|
||||
struct Packet p = { 0 };
|
||||
packet_init(&p, PACKET_LUA_SYNC_TABLE, true, PLMT_NONE);
|
||||
packet_write(&p, &seq, sizeof(u64));
|
||||
packet_write(&p, &remoteIndex, sizeof(u16));
|
||||
packet_write(&p, &lst, sizeof(u16));
|
||||
packet_write(&p, &index, sizeof(u16));
|
||||
|
||||
packet_write(&p, &keyLength, sizeof(u16));
|
||||
packet_write(&p, (char*)key, keyLength * sizeof(u8));
|
||||
|
||||
packet_write(&p, &lUnionType, sizeof(u16));
|
||||
switch (lUnionType) {
|
||||
case LST_NETWORK_TYPE_NUMBER: {
|
||||
f64 number = lUnion.number;
|
||||
packet_write(&p, &number, sizeof(f64));
|
||||
//LOG_INFO("sent lua_sync_table: %llu, %u, %u, %s, %u, %f", seq, remoteIndex, lst, key, lUnionType, number);
|
||||
break;
|
||||
}
|
||||
case LST_NETWORK_TYPE_INTEGER: {
|
||||
s64 integer = lUnion.integer;
|
||||
packet_write(&p, &integer, sizeof(s64));
|
||||
//LOG_INFO("sent lua_sync_table: %llu, %u, %u, %s, %u, %llu", seq, remoteIndex, lst, key, lUnionType, integer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("attempted to send lua sync table with invalid type: %d", lUnionType);
|
||||
return;
|
||||
}
|
||||
|
||||
network_send(&p);
|
||||
}
|
||||
|
||||
void network_receive_lua_sync_table(struct Packet* p) {
|
||||
u64 seq = 0;
|
||||
u16 remoteIndex = 0;
|
||||
u16 lst = 0;
|
||||
u16 index = 0;
|
||||
u16 keyLength = 0;
|
||||
char key[65] = { 0 };
|
||||
u16 lUnionType = 0;
|
||||
union LSTNetworkUnion lUnion;
|
||||
|
||||
packet_read(p, &seq, sizeof(u64));
|
||||
packet_read(p, &remoteIndex, sizeof(u16));
|
||||
packet_read(p, &lst, sizeof(u16));
|
||||
packet_read(p, &index, sizeof(u16));
|
||||
|
||||
packet_read(p, &keyLength, sizeof(u16));
|
||||
if (keyLength > 64) {
|
||||
LOG_ERROR("received lua sync table with invalid key length: %d", keyLength);
|
||||
return;
|
||||
}
|
||||
packet_read(p, &key, keyLength * sizeof(u8));
|
||||
|
||||
packet_read(p, &lUnionType, sizeof(u16));
|
||||
switch (lUnionType) {
|
||||
case LST_NETWORK_TYPE_NUMBER:
|
||||
packet_read(p, &lUnion.number, sizeof(f64));
|
||||
//LOG_INFO("rx lua_sync_table: %llu, %u, %u, %s, %u, %f", seq, remoteIndex, lst, key, lUnionType, lUnion.number);
|
||||
break;
|
||||
case LST_NETWORK_TYPE_INTEGER:
|
||||
packet_read(p, &lUnion.integer, sizeof(s64));
|
||||
//LOG_INFO("rx lua_sync_table: %llu, %u, %u, %s, %u, %llu", seq, remoteIndex, lst, key, lUnionType, lUnion.integer);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("received lua sync table with invalid type: %d", lUnionType);
|
||||
return;
|
||||
}
|
||||
|
||||
smlua_set_sync_table_field_from_network(seq, remoteIndex, lst, index, key, lUnionType, lUnion);
|
||||
}
|
Loading…
Reference in New Issue