mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2026-04-25 19:42:20 +00:00
Added custom mod packets
This commit is contained in:
parent
ef7dc41560
commit
bc7821a1e9
16 changed files with 391 additions and 96 deletions
|
|
@ -159,6 +159,8 @@ manual_index_documentation = """
|
|||
- [define_custom_obj_fields](#define_custom_obj_fields)
|
||||
- [network_init_object](#network_init_object)
|
||||
- [network_send_object](#network_send_object)
|
||||
- [network_send_to](#network_send_to)
|
||||
- [network_send](#network_send)
|
||||
|
||||
<br />
|
||||
|
||||
|
|
@ -236,6 +238,55 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
|||
|
||||
<br />
|
||||
|
||||
## [network_send_to](#network_send_to)
|
||||
|
||||
Sends a packet to a particular player (using their local index) containing whatever data you want.
|
||||
|
||||
`dataTable` can only contain strings, integers, numbers, booleans, and nil
|
||||
|
||||
The `reliable` field will ensure that the packet arrives, but should be used sparingly and only when missing a packet would cause a desync.
|
||||
|
||||
### Lua Example
|
||||
`network_send_to(localPlayerIndex, reliable, { data1 = 'hello', data2 = 10})`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| localPlayerIndex | `integer` |
|
||||
| reliable | `bool` |
|
||||
| dataTable | `table` |
|
||||
|
||||
### C Prototype
|
||||
`N/A`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [network_send](#network_send)
|
||||
|
||||
Sends a packet to all players containing whatever data you want.
|
||||
|
||||
`dataTable` can only contain strings, integers, numbers, booleans, and nil
|
||||
|
||||
The `reliable` field will ensure that the packet arrives, but should be used sparingly and only when missing a packet would cause a desync.
|
||||
|
||||
### Lua Example
|
||||
`network_send(reliable, { data1 = 'hello', data2 = 10})`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| reliable | `bool` |
|
||||
| dataTable | `table` |
|
||||
|
||||
### C Prototype
|
||||
`N/A`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
"""
|
||||
|
||||
############################################################################
|
||||
|
|
|
|||
|
|
@ -7852,7 +7852,10 @@ HOOK_ON_OBJECT_RENDER = 19
|
|||
HOOK_ON_DEATH = 20
|
||||
|
||||
--- @type LuaHookedEventType
|
||||
HOOK_MAX = 21
|
||||
HOOK_ON_PACKET_RECEIVE = 21
|
||||
|
||||
--- @type LuaHookedEventType
|
||||
HOOK_MAX = 22
|
||||
|
||||
--- @class ModelExtendedId
|
||||
|
||||
|
|
|
|||
|
|
@ -120,3 +120,17 @@ function network_send_object(object, reliable)
|
|||
-- ...
|
||||
end
|
||||
|
||||
--- @param reliable boolean
|
||||
--- @param dataTable table
|
||||
--- @return nil
|
||||
function network_send(reliable, dataTable)
|
||||
-- ...
|
||||
end
|
||||
|
||||
--- @param toLocalIndex integer
|
||||
--- @param reliable boolean
|
||||
--- @param dataTable table
|
||||
--- @return nil
|
||||
function network_send_to(toLocalIndex, reliable, dataTable)
|
||||
-- ...
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2755,7 +2755,8 @@
|
|||
| HOOK_ON_SET_CAMERA_MODE | 18 |
|
||||
| HOOK_ON_OBJECT_RENDER | 19 |
|
||||
| HOOK_ON_DEATH | 20 |
|
||||
| HOOK_MAX | 21 |
|
||||
| HOOK_ON_PACKET_RECEIVE | 21 |
|
||||
| HOOK_MAX | 22 |
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
- [define_custom_obj_fields](#define_custom_obj_fields)
|
||||
- [network_init_object](#network_init_object)
|
||||
- [network_send_object](#network_send_object)
|
||||
- [network_send_to](#network_send_to)
|
||||
- [network_send](#network_send)
|
||||
|
||||
<br />
|
||||
|
||||
|
|
@ -1500,6 +1502,55 @@ The `reliable` field will ensure that the packet arrives, but should be used spa
|
|||
|
||||
<br />
|
||||
|
||||
## [network_send_to](#network_send_to)
|
||||
|
||||
Sends a packet to a particular player (using their local index) containing whatever data you want.
|
||||
|
||||
`dataTable` can only contain strings, integers, numbers, booleans, and nil
|
||||
|
||||
The `reliable` field will ensure that the packet arrives, but should be used sparingly and only when missing a packet would cause a desync.
|
||||
|
||||
### Lua Example
|
||||
`network_send_to(localPlayerIndex, reliable, { data1 = 'hello', data2 = 10})`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| localPlayerIndex | `integer` |
|
||||
| reliable | `bool` |
|
||||
| dataTable | `table` |
|
||||
|
||||
### C Prototype
|
||||
`N/A`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
## [network_send](#network_send)
|
||||
|
||||
Sends a packet to all players containing whatever data you want.
|
||||
|
||||
`dataTable` can only contain strings, integers, numbers, booleans, and nil
|
||||
|
||||
The `reliable` field will ensure that the packet arrives, but should be used sparingly and only when missing a packet would cause a desync.
|
||||
|
||||
### Lua Example
|
||||
`network_send(reliable, { data1 = 'hello', data2 = 10})`
|
||||
|
||||
### Parameters
|
||||
| Field | Type |
|
||||
| ----- | ---- |
|
||||
| reliable | `bool` |
|
||||
| dataTable | `table` |
|
||||
|
||||
### C Prototype
|
||||
`N/A`
|
||||
|
||||
[:arrow_up_small:](#)
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
---
|
||||
# functions from behavior_actions.h
|
||||
|
|
|
|||
|
|
@ -105,8 +105,9 @@ The lua functions sent to `hook_event()` will be automatically called by SM64 wh
|
|||
| HOOK_ON_PAUSE_EXIT | Called when the local player exits through the pause screen, return `false` to prevent the exit | `boolean` usedExitToCastle |
|
||||
| HOOK_GET_STAR_COLLECTION_DIALOG | Called when the local player collects a star, return a [DialogId](constants.md#enum-DialogId) to show a message | None |
|
||||
| HOOK_ON_SET_CAMERA_MODE | Called when the camera mode gets set, return `false` to prevent the camera mode from being set | [Camera](structs.md#Camera), `integer` mode, `integer` frames |
|
||||
| HOOK_ON_OBJECT_RENDER | Called right before an object is rendered. **Note:** You must set the `hookRender` field of the object to a non-zero value | [Object](structs.md#Object) |
|
||||
| HOOK_ON_DEATH | Called when the local player dies, return `false` to prevent normal death sequence | [MarioState](structs.md#MarioState) |
|
||||
| HOOK_ON_OBJECT_RENDER | Called right before an object is rendered. **Note:** You must set the `hookRender` field of the object to a non-zero value | [Object](structs.md#Object) renderedObj |
|
||||
| HOOK_ON_DEATH | Called when the local player dies, return `false` to prevent normal death sequence | [MarioState](structs.md#MarioState) localMario |
|
||||
| HOOK_ON_PACKET_RECEIVE | Called when the mod receives a packet that used `network_send()` or `network_send_to()` | `table` dataTable |
|
||||
|
||||
### Parameters
|
||||
|
||||
|
|
|
|||
|
|
@ -2798,7 +2798,8 @@ char gSmluaConstants[] = ""
|
|||
"HOOK_ON_SET_CAMERA_MODE = 18\n"
|
||||
"HOOK_ON_OBJECT_RENDER = 19\n"
|
||||
"HOOK_ON_DEATH = 20\n"
|
||||
"HOOK_MAX = 21\n"
|
||||
"HOOK_ON_PACKET_RECEIVE = 21\n"
|
||||
"HOOK_MAX = 22\n"
|
||||
"E_MODEL_NONE = 0\n"
|
||||
"E_MODEL_MARIO = 1\n"
|
||||
"E_MODEL_SMOKE = 2\n"
|
||||
|
|
|
|||
|
|
@ -176,6 +176,16 @@ int smlua_func_network_send_object(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int smlua_func_network_send(lua_State* L) {
|
||||
if (!smlua_functions_valid_param_count(L, 2)) { return 0; }
|
||||
network_send_lua_custom(true);
|
||||
}
|
||||
|
||||
int smlua_func_network_send_to(lua_State* L) {
|
||||
if (!smlua_functions_valid_param_count(L, 3)) { return 0; }
|
||||
network_send_lua_custom(false);
|
||||
}
|
||||
|
||||
//////////
|
||||
// bind //
|
||||
//////////
|
||||
|
|
@ -191,4 +201,6 @@ void smlua_bind_functions(void) {
|
|||
smlua_bind_function(L, "network_init_object", smlua_func_network_init_object);
|
||||
smlua_bind_function(L, "network_send_object", smlua_func_network_send_object);
|
||||
smlua_bind_function(L, "reset_level", smlua_func_reset_level);
|
||||
smlua_bind_function(L, "network_send", smlua_func_network_send);
|
||||
smlua_bind_function(L, "network_send_to", smlua_func_network_send_to);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "smlua.h"
|
||||
#include "pc/mods/mod.h"
|
||||
#include "src/game/object_list_processor.h"
|
||||
#include "pc/djui/djui_chat_message.h"
|
||||
#include "pc/crash_handler.h"
|
||||
|
|
@ -454,6 +455,27 @@ void smlua_call_event_hooks_set_camera_mode_params(enum LuaHookedEventType hookT
|
|||
}
|
||||
}
|
||||
|
||||
void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int modIndex, int valueIndex) {
|
||||
lua_State* L = gLuaState;
|
||||
if (L == NULL) { return; }
|
||||
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
|
||||
for (int i = 0; i < hook->count; i++) {
|
||||
if (hook->mod[i]->index != modIndex) { continue; }
|
||||
// push the callback onto the stack
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
|
||||
|
||||
// push value
|
||||
lua_pushvalue(L, valueIndex);
|
||||
|
||||
// call the callback
|
||||
if (0 != smlua_call_hook(L, 1, 0, 0, hook->mod[i])) {
|
||||
LOG_LUA("Failed to call the callback: %u, %s", hookType, lua_tostring(L, -1));
|
||||
smlua_logline();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// hooked actions //
|
||||
////////////////////
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ enum LuaHookedEventType {
|
|||
HOOK_ON_SET_CAMERA_MODE,
|
||||
HOOK_ON_OBJECT_RENDER,
|
||||
HOOK_ON_DEATH,
|
||||
HOOK_ON_PACKET_RECEIVE,
|
||||
HOOK_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -54,6 +55,7 @@ static char* LuaHookedEventTypeName[] = {
|
|||
"HOOK_ON_SET_CAMERA_MODE",
|
||||
"HOOK_ON_OBJECT_RENDER",
|
||||
"HOOK_ON_DEATH",
|
||||
"HOOK_ON_PACKET_RECEIVE",
|
||||
"HOOK_MAX"
|
||||
};
|
||||
|
||||
|
|
@ -70,6 +72,7 @@ void smlua_call_event_hooks_interact_params(enum LuaHookedEventType hookType, st
|
|||
void smlua_call_event_hooks_object_param(enum LuaHookedEventType hookType, struct Object* obj);
|
||||
bool smlua_call_event_hooks_ret_int(enum LuaHookedEventType hookType, s32* returnValue);
|
||||
void smlua_call_event_hooks_set_camera_mode_params(enum LuaHookedEventType hookType, struct Camera *c, s16 mode, s16 frames, bool* returnValue);
|
||||
void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int modIndex, int valueIndex);
|
||||
|
||||
enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior);
|
||||
const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);
|
||||
|
|
|
|||
|
|
@ -260,6 +260,94 @@ struct LSTNetworkType smlua_to_lnt(lua_State* L, int index) {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||
u8 lntType = lnt->type;
|
||||
packet_write(p, &lntType, sizeof(u8));
|
||||
|
||||
switch (lnt->type) {
|
||||
case LST_NETWORK_TYPE_NUMBER: {
|
||||
f64 number = lnt->value.number;
|
||||
packet_write(p, &number, sizeof(f64));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_INTEGER: {
|
||||
s64 integer = lnt->value.integer;
|
||||
packet_write(p, &integer, sizeof(s64));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_BOOLEAN: {
|
||||
packet_write(p, &lnt->value.boolean, sizeof(u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_STRING: {
|
||||
u16 valueLength = strlen(lnt->value.string);
|
||||
if (valueLength < 1 || valueLength > 256) {
|
||||
LOG_ERROR("attempted to send lua variable with invalid string length: %u", valueLength);
|
||||
return false;
|
||||
}
|
||||
packet_write(p, &valueLength, sizeof(u16));
|
||||
packet_write(p, lnt->value.string, valueLength * sizeof(u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_NIL: {
|
||||
// no-op
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR("attempted to send lua variable with invalid lnt type: %d", lnt->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||
packet_read(p, &lnt->type, sizeof(u8));
|
||||
|
||||
switch (lnt->type) {
|
||||
case LST_NETWORK_TYPE_NUMBER:
|
||||
packet_read(p, &lnt->value.number, sizeof(f64));
|
||||
return true;
|
||||
|
||||
case LST_NETWORK_TYPE_INTEGER:
|
||||
packet_read(p, &lnt->value.integer, sizeof(s64));
|
||||
return true;
|
||||
|
||||
case LST_NETWORK_TYPE_BOOLEAN:
|
||||
packet_read(p, &lnt->value.boolean, sizeof(u8));
|
||||
return true;
|
||||
|
||||
case LST_NETWORK_TYPE_STRING: {
|
||||
u16 valueLength = 0;
|
||||
packet_read(p, &valueLength, sizeof(u16));
|
||||
if (valueLength < 1 || valueLength > 256) {
|
||||
LOG_ERROR("received lua variable with invalid value length: %d", valueLength);
|
||||
return false;
|
||||
}
|
||||
lnt->value.string = calloc(valueLength + 1, sizeof(char));
|
||||
packet_read(p, lnt->value.string, valueLength * sizeof(u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_NIL:
|
||||
// no-op
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR("received lua variable with invalid type: %d", lnt->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void smlua_push_object(lua_State* L, u16 lot, void* p) {
|
||||
if (p == NULL) {
|
||||
lua_pushnil(L);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
extern u8 gSmLuaConvertSuccess;
|
||||
typedef int LuaFunction;
|
||||
struct Packet;
|
||||
struct LSTNetworkType;
|
||||
|
||||
f32* smlua_get_vec3f_from_buffer(void);
|
||||
s16* smlua_get_vec3s_from_buffer(void);
|
||||
|
|
@ -19,6 +21,9 @@ void* smlua_to_cobject(lua_State* L, int index, u16 lot);
|
|||
void* smlua_to_cpointer(lua_State* L, int index, u16 lvt);
|
||||
struct LSTNetworkType smlua_to_lnt(lua_State* L, int index);
|
||||
|
||||
bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt);
|
||||
bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt);
|
||||
|
||||
void smlua_push_object(lua_State* L, u16 lot, void* p);
|
||||
void smlua_push_pointer(lua_State* L, u16 lvt, void* p);
|
||||
void smlua_push_integer_field(int index, char* name, lua_Integer val);
|
||||
|
|
|
|||
|
|
@ -92,7 +92,9 @@ void packet_process(struct Packet* p) {
|
|||
|
||||
case PACKET_NETWORK_PLAYERS_REQUEST: network_receive_network_players_request(p); break;
|
||||
|
||||
case PACKET_REQUEST_FAILED: network_receive_request_failed(p); break;
|
||||
case PACKET_REQUEST_FAILED: network_receive_request_failed(p); break;
|
||||
|
||||
case PACKET_LUA_CUSTOM: network_receive_lua_custom(p); break;
|
||||
|
||||
// custom
|
||||
case PACKET_CUSTOM: network_receive_custom(p); break;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ enum PacketType {
|
|||
|
||||
PACKET_REQUEST_FAILED,
|
||||
|
||||
PACKET_LUA_CUSTOM,
|
||||
|
||||
///
|
||||
PACKET_CUSTOM = 255,
|
||||
};
|
||||
|
|
@ -353,4 +355,8 @@ void network_receive_lua_sync_table(struct Packet* p);
|
|||
void network_send_request_failed(struct NetworkPlayer* toNp, u8 requestType);
|
||||
void network_receive_request_failed(struct Packet* p);
|
||||
|
||||
// packet_lua_custom.c
|
||||
void network_send_lua_custom(bool broadcast);
|
||||
void network_receive_lua_custom(struct Packet* p);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
125
src/pc/network/packets/packet_lua_custom.c
Normal file
125
src/pc/network/packets/packet_lua_custom.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "pc/mods/mod.h"
|
||||
#include "pc/lua/smlua.h"
|
||||
#include "pc/lua/smlua_utils.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
void network_send_lua_custom(bool broadcast) {
|
||||
LOG_INFO("Sending lua custom packet");
|
||||
lua_State* L = gLuaState;
|
||||
u16 zero = 0;
|
||||
s32 paramIndex = 1;
|
||||
|
||||
// figure out mod index
|
||||
if (gLuaActiveMod == NULL) {
|
||||
LOG_LUA("Could not figure out the current active mod!");
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
u16 modIndex = gLuaActiveMod->index;
|
||||
|
||||
// get local index
|
||||
s32 toLocalIndex = 0;
|
||||
if (!broadcast) {
|
||||
s32 toLocalIndex = smlua_to_integer(L, paramIndex++);
|
||||
if (toLocalIndex <= 0 || toLocalIndex >= MAX_PLAYERS) {
|
||||
LOG_LUA("Tried to send packet to invalid local index: %d", toLocalIndex)
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
if (!gSmLuaConvertSuccess) { return; }
|
||||
}
|
||||
|
||||
// get reliability
|
||||
bool reliability = smlua_to_boolean(L, paramIndex++);
|
||||
if (!gSmLuaConvertSuccess) { return; }
|
||||
|
||||
// write packet header
|
||||
struct Packet p = { 0 };
|
||||
packet_init(&p, PACKET_LUA_CUSTOM, reliability, PLMT_NONE);
|
||||
packet_write(&p, &modIndex, sizeof(u16));
|
||||
u8* keyCount = &p.buffer[p.cursor];
|
||||
packet_write(&p, &zero, sizeof(u8));
|
||||
|
||||
// make sure value passed in is a table
|
||||
s32 tableIndex = paramIndex;
|
||||
if (lua_type(L, tableIndex) != LUA_TTABLE) {
|
||||
LOG_LUA("Tried to send a packet with a non-table");
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
|
||||
// iterate table
|
||||
s32 iterateIndex = lua_gettop(L);
|
||||
lua_pushnil(L); // first key
|
||||
while (lua_next(L, iterateIndex) != 0) {
|
||||
// convert and write key
|
||||
struct LSTNetworkType lntKey = smlua_to_lnt(L, -2);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA("Failed to convert key to LNT (tx)");
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
if (!packet_write_lnt(&p, &lntKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// convert and write value
|
||||
struct LSTNetworkType lntValue = smlua_to_lnt(L, -1);
|
||||
if (!gSmLuaConvertSuccess) {
|
||||
LOG_LUA("Failed to convert value to LNT (tx)");
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
if (!packet_write_lnt(&p, &lntValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// increment key count
|
||||
*keyCount = *keyCount + 1;
|
||||
lua_pop(L, 1); // pop value
|
||||
}
|
||||
lua_pop(L, 1); // pop key
|
||||
|
||||
// send packet
|
||||
if (broadcast) {
|
||||
network_send(&p);
|
||||
} else {
|
||||
network_send_to(toLocalIndex, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void network_receive_lua_custom(struct Packet* p) {
|
||||
LOG_INFO("Receiving lua custom packet");
|
||||
lua_State* L = gLuaState;
|
||||
u16 modIndex = 0;
|
||||
u8 keyCount = 0;
|
||||
packet_read(p, &modIndex, sizeof(u16));
|
||||
packet_read(p, &keyCount, sizeof(u8));
|
||||
|
||||
lua_newtable(L);
|
||||
s32 tableIndex = lua_gettop(L);
|
||||
for(u16 i = 0; i < keyCount; i++) {
|
||||
struct LSTNetworkType lntKey = { 0 };
|
||||
if (!packet_read_lnt(p, &lntKey)) {
|
||||
LOG_LUA("Failed to convert key to LNT (rx)");
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
smlua_push_lnt(&lntKey);
|
||||
|
||||
struct LSTNetworkType lntValue = { 0 };
|
||||
if (!packet_read_lnt(p, &lntValue)) {
|
||||
LOG_LUA("Failed to convert value to LNT (rx)");
|
||||
smlua_logline();
|
||||
return;
|
||||
}
|
||||
smlua_push_lnt(&lntValue);
|
||||
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
smlua_call_event_hooks_value_param(HOOK_ON_PACKET_RECEIVE, modIndex, tableIndex);
|
||||
lua_pop(L, 1); // pop table
|
||||
}
|
||||
|
|
@ -20,96 +20,6 @@ void network_receive_lua_sync_table_request(struct Packet* p) {
|
|||
LOG_INFO("received lua sync table request");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
static bool packet_write_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||
u8 lntType = lnt->type;
|
||||
packet_write(p, &lntType, sizeof(u8));
|
||||
|
||||
switch (lnt->type) {
|
||||
case LST_NETWORK_TYPE_NUMBER: {
|
||||
f64 number = lnt->value.number;
|
||||
packet_write(p, &number, sizeof(f64));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_INTEGER: {
|
||||
s64 integer = lnt->value.integer;
|
||||
packet_write(p, &integer, sizeof(s64));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_BOOLEAN: {
|
||||
packet_write(p, &lnt->value.boolean, sizeof(u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_STRING: {
|
||||
u16 valueLength = strlen(lnt->value.string);
|
||||
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, lnt->value.string, valueLength * sizeof(u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_NIL: {
|
||||
// no-op
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR("attempted to send lua sync table with invalid lnt type: %d", lnt->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool packet_read_lnt(struct Packet* p, struct LSTNetworkType* lnt) {
|
||||
packet_read(p, &lnt->type, sizeof(u8));
|
||||
|
||||
switch (lnt->type) {
|
||||
case LST_NETWORK_TYPE_NUMBER:
|
||||
packet_read(p, &lnt->value.number, sizeof(f64));
|
||||
return true;
|
||||
|
||||
case LST_NETWORK_TYPE_INTEGER:
|
||||
packet_read(p, &lnt->value.integer, sizeof(s64));
|
||||
return true;
|
||||
|
||||
case LST_NETWORK_TYPE_BOOLEAN:
|
||||
packet_read(p, &lnt->value.boolean, sizeof(u8));
|
||||
return true;
|
||||
|
||||
case LST_NETWORK_TYPE_STRING: {
|
||||
u16 valueLength = 0;
|
||||
packet_read(p, &valueLength, sizeof(u16));
|
||||
if (valueLength < 1 || valueLength > 256) {
|
||||
LOG_ERROR("received lua sync table with invalid value length: %d", valueLength);
|
||||
return false;
|
||||
}
|
||||
lnt->value.string = calloc(valueLength + 1, sizeof(char));
|
||||
packet_read(p, lnt->value.string, valueLength * sizeof(u8));
|
||||
return true;
|
||||
}
|
||||
|
||||
case LST_NETWORK_TYPE_NIL:
|
||||
// no-op
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_ERROR("received lua sync table with invalid type: %d", lnt->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
void network_send_lua_sync_table(u8 toLocalIndex, u64 seq, u16 modRemoteIndex, u16 lntKeyCount, struct LSTNetworkType* lntKeys, struct LSTNetworkType* lntValue) {
|
||||
if (gLuaState == NULL) { return; }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue