From f5df2917b896456555a477b0435666b06f2de449 Mon Sep 17 00:00:00 2001 From: MysterD Date: Thu, 17 Feb 2022 18:13:43 -0800 Subject: [PATCH] Prevented race condition that caused all objects to disappear in rare circumstances --- src/pc/controller/controller_keyboard_debug.c | 2 +- src/pc/network/packets/packet.c | 2 + src/pc/network/packets/packet.h | 6 +++ .../packets/packet_level_area_request.c | 9 ++++ src/pc/network/packets/packet_level_request.c | 9 ++++ .../network/packets/packet_request_failed.c | 41 +++++++++++++++++++ 6 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/pc/network/packets/packet_request_failed.c diff --git a/src/pc/controller/controller_keyboard_debug.c b/src/pc/controller/controller_keyboard_debug.c index 6910309d..960496ad 100644 --- a/src/pc/controller/controller_keyboard_debug.c +++ b/src/pc/controller/controller_keyboard_debug.c @@ -14,7 +14,7 @@ #ifdef DEBUG #include "pc/lua/smlua.h" -static u8 warpToLevel = LEVEL_SSL; +static u8 warpToLevel = LEVEL_BOB; static u8 warpToArea = 27; // warpToArea: 26 = basement // warpToArea: 27 = upstairs diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index 20f2ed27..d1179c06 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -89,6 +89,8 @@ 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; + // custom case PACKET_CUSTOM: network_receive_custom(p); break; default: LOG_ERROR("received unknown packet: %d", p->buffer[0]); diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index 91a27f66..3886fc6b 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -64,6 +64,8 @@ enum PacketType { PACKET_NETWORK_PLAYERS_REQUEST, + PACKET_REQUEST_FAILED, + /// PACKET_CUSTOM = 255, }; @@ -337,4 +339,8 @@ void network_receive_lua_sync_table_request(struct Packet* p); 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); +// packet_request_failed.c +void network_send_request_failed(struct NetworkPlayer* toNp, u8 requestType); +void network_receive_request_failed(struct Packet* p); + #endif diff --git a/src/pc/network/packets/packet_level_area_request.c b/src/pc/network/packets/packet_level_area_request.c index 95f3be1d..132dfd1d 100644 --- a/src/pc/network/packets/packet_level_area_request.c +++ b/src/pc/network/packets/packet_level_area_request.c @@ -35,12 +35,21 @@ void network_receive_level_area_request(struct Packet* p) { struct NetworkPlayer* toNp = network_player_from_global_index(globalIndex); if (toNp == NULL || toNp->localIndex == UNKNOWN_LOCAL_INDEX || !toNp->connected) { LOG_ERROR("Receiving level area request from inactive player!"); + if (toNp != NULL) { network_send_request_failed(toNp, 1); } return; } extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || areaIndex != gCurrAreaIndex) { LOG_ERROR("rx level area request: received an improper location"); + if (toNp != NULL) { network_send_request_failed(toNp, 1); } + return; + } + + struct NetworkPlayer* np = gNetworkPlayerLocal; + if (np == NULL || !np->currAreaSyncValid || !np->currLevelSyncValid) { + LOG_ERROR("rx level area request: received when we're not synchronized"); + if (toNp != NULL) { network_send_request_failed(toNp, 1); } return; } diff --git a/src/pc/network/packets/packet_level_request.c b/src/pc/network/packets/packet_level_request.c index 008f931b..dee5c413 100644 --- a/src/pc/network/packets/packet_level_request.c +++ b/src/pc/network/packets/packet_level_request.c @@ -33,12 +33,21 @@ void network_receive_level_request(struct Packet* p) { struct NetworkPlayer* toNp = network_player_from_global_index(globalIndex); if (toNp == NULL || toNp->localIndex == UNKNOWN_LOCAL_INDEX || !toNp->connected) { LOG_ERROR("Receiving level request from inactive player!"); + if (toNp != NULL) { network_send_request_failed(toNp, 0); } return; } extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum; if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum) { LOG_ERROR("rx level request: received an improper location"); + if (toNp != NULL) { network_send_request_failed(toNp, 0); } + return; + } + + struct NetworkPlayer* np = gNetworkPlayerLocal; + if (np == NULL || !np->currLevelSyncValid) { + LOG_ERROR("rx level request: received when we're not synchronized"); + if (toNp != NULL) { network_send_request_failed(toNp, 0); } return; } diff --git a/src/pc/network/packets/packet_request_failed.c b/src/pc/network/packets/packet_request_failed.c new file mode 100644 index 00000000..2c97d45c --- /dev/null +++ b/src/pc/network/packets/packet_request_failed.c @@ -0,0 +1,41 @@ +#include +#include "../network.h" +#define DISABLE_MODULE_LOG 1 +#include "pc/debuglog.h" + +void network_send_request_failed(struct NetworkPlayer* toNp, u8 requestType) { + if (gNetworkType == NT_SERVER && toNp == gNetworkPlayerLocal) { + struct NetworkPlayer* np = gNetworkPlayerLocal; + if (requestType == 0 && !np->currLevelSyncValid) { + LOG_INFO("re-requesting level"); + network_send_change_level(); + } else if (requestType == 1 && (!np->currAreaSyncValid || !np->currLevelSyncValid)) { + LOG_INFO("re-requesting area"); + network_send_change_area(); + } + return; + } + + struct Packet p = { 0 }; + packet_init(&p, PACKET_REQUEST_FAILED, true, PLMT_NONE); + packet_write(&p, &requestType, sizeof(u8)); + + network_send_to(toNp->localIndex, &p); + LOG_INFO("tx request failed"); +} + +void network_receive_request_failed(struct Packet* p) { + LOG_INFO("rx request failed"); + + u8 requestType; + packet_read(p, &requestType, sizeof(u8)); + + struct NetworkPlayer* np = gNetworkPlayerLocal; + if (requestType == 0 && !np->currLevelSyncValid) { + LOG_INFO("re-requesting level"); + network_send_change_level(); + } else if (requestType == 1 && (!np->currAreaSyncValid || !np->currLevelSyncValid)) { + LOG_INFO("re-requesting area"); + network_send_change_area(); + } +}