From 0bb48cb6e7f9733f703f1bc79d8b6b938410a322 Mon Sep 17 00:00:00 2001 From: MysterD Date: Sun, 27 Mar 2022 18:21:53 -0700 Subject: [PATCH] Rewrote structure of packet_level_area_inform - should fix 'Peach's Castle' bug --- src/game/area.c | 2 + src/pc/network/network_player.c | 19 ++++++- src/pc/network/packets/packet.h | 2 +- src/pc/network/packets/packet_change_area.c | 9 ++-- src/pc/network/packets/packet_change_level.c | 8 ++- .../packets/packet_level_area_inform.c | 54 ++++++++----------- .../network/packets/packet_network_players.c | 2 +- src/pc/network/packets/packet_sync_valid.c | 20 +++---- 8 files changed, 55 insertions(+), 61 deletions(-) diff --git a/src/game/area.c b/src/game/area.c index f6b88ec21..d9daa2a2b 100644 --- a/src/game/area.c +++ b/src/game/area.c @@ -196,6 +196,7 @@ void clear_areas(void) { if (np != NULL) { np->currAreaSyncValid = false; np->currLevelSyncValid = false; + network_send_level_area_inform(); } gCurrentArea = NULL; @@ -268,6 +269,7 @@ void unload_area(void) { struct NetworkPlayer* np = gNetworkPlayerLocal; if (np != NULL) { np->currAreaSyncValid = false; + network_send_level_area_inform(); } network_clear_sync_objects(); diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index ebce324f8..6e50f3622 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -217,9 +217,9 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex, u8 mode // update course/level np->currLevelAreaSeqId = 0; - network_player_update_course_level(np, 0, 0, 16, 1); np->currLevelSyncValid = false; np->currAreaSyncValid = false; + network_player_update_course_level(np, 0, 0, 16, 1); // update visuals np->fadeOpacity = 0; @@ -313,7 +313,13 @@ u8 network_player_disconnected(u8 globalIndex) { return UNKNOWN_GLOBAL_INDEX; } -void network_player_update_course_level(struct NetworkPlayer *np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { +void network_player_update_course_level(struct NetworkPlayer* np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { + // prevent sync valid packets from corrupting areaIndex + if (areaIndex == -1) { + areaIndex = np->currAreaIndex; + } + + // display popup bool inCredits = (np->currActNum == 99); if (np->currCourseNum != courseNum && np->localIndex != 0 && !inCredits) { @@ -335,10 +341,19 @@ void network_player_update_course_level(struct NetworkPlayer *np, s16 courseNum, } } + bool mismatch = (np->currCourseNum != courseNum) + || (np->currActNum != actNum) + || (np->currLevelNum != levelNum) + || (np->currAreaIndex != areaIndex); + np->currCourseNum = courseNum; np->currActNum = actNum; np->currLevelNum = levelNum; np->currAreaIndex = areaIndex; + + if (mismatch && (np == gNetworkPlayerLocal)) { + network_send_level_area_inform(); + } } void network_player_shutdown(void) { diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index dd7afb69d..6549a7273 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -293,7 +293,7 @@ void network_send_level_macro(struct NetworkPlayer* destNp); void network_receive_level_macro(struct Packet* p); // packet_level_area_inform.c -void network_send_level_area_inform(struct NetworkPlayer* np); +void network_send_level_area_inform(void); void network_receive_level_area_inform(struct Packet* p); // packet_level_respawn_info.c diff --git a/src/pc/network/packets/packet_change_area.c b/src/pc/network/packets/packet_change_area.c index 6bfb30412..fb4df553b 100644 --- a/src/pc/network/packets/packet_change_area.c +++ b/src/pc/network/packets/packet_change_area.c @@ -7,8 +7,8 @@ static void player_changed_area(struct NetworkPlayer *np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { // set NetworkPlayer variables - network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currAreaSyncValid = false; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); reservation_area_change(np); // find a NetworkPlayer at that area @@ -18,14 +18,11 @@ static void player_changed_area(struct NetworkPlayer *np, s16 courseNum, s16 act if (npLevelAreaMatch == NULL || inCredits) { // no NetworkPlayer in the level network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex); - network_send_level_area_inform(np); return; } // matching NetworkPlayer is client network_send_area_request(np, npLevelAreaMatch); - - network_send_level_area_inform(np); } void network_send_change_area(void) { @@ -52,9 +49,9 @@ void network_send_change_area(void) { packet_write(&p, &gCurrAreaIndex, sizeof(s16)); network_send_to(gNetworkPlayerServer->localIndex, &p); - struct NetworkPlayer *np = gNetworkPlayerLocal; - network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); + struct NetworkPlayer* np = gNetworkPlayerLocal; np->currAreaSyncValid = false; + network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); LOG_INFO("tx change area"); } diff --git a/src/pc/network/packets/packet_change_level.c b/src/pc/network/packets/packet_change_level.c index 7a78cdf7c..1832d3bf2 100644 --- a/src/pc/network/packets/packet_change_level.c +++ b/src/pc/network/packets/packet_change_level.c @@ -7,9 +7,9 @@ static void player_changed_level(struct NetworkPlayer *np, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { // set NetworkPlayer variables - network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currLevelSyncValid = false; np->currAreaSyncValid = false; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); reservation_area_change(np); // find a NetworkPlayer around that location @@ -21,7 +21,6 @@ static void player_changed_level(struct NetworkPlayer *np, s16 courseNum, s16 ac if (npAny == NULL || inCredits) { // no NetworkPlayer in the level network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex); - network_send_level_area_inform(np); return; } @@ -31,7 +30,6 @@ static void player_changed_level(struct NetworkPlayer *np, s16 courseNum, s16 ac } else { network_send_level_request(np, npAny); } - network_send_level_area_inform(np); } void network_send_change_level(void) { @@ -58,10 +56,10 @@ void network_send_change_level(void) { packet_write(&p, &gCurrAreaIndex, sizeof(s16)); network_send_to(gNetworkPlayerServer->localIndex, &p); - struct NetworkPlayer *np = gNetworkPlayerLocal; - network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); + struct NetworkPlayer* np = gNetworkPlayerLocal; np->currAreaSyncValid = false; np->currLevelSyncValid = false; + network_player_update_course_level(np, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); LOG_INFO("tx change level"); } diff --git a/src/pc/network/packets/packet_level_area_inform.c b/src/pc/network/packets/packet_level_area_inform.c index 42eadb0e9..c1bdc256d 100644 --- a/src/pc/network/packets/packet_level_area_inform.c +++ b/src/pc/network/packets/packet_level_area_inform.c @@ -8,37 +8,27 @@ #include "game/level_info.h" #include "game/mario_misc.h" -static u16 sLevelAreaInformSeq[MAX_PLAYERS][MAX_PLAYERS] = { 0 }; +void network_send_level_area_inform(void) { + struct NetworkPlayer* np = gNetworkPlayerLocal; + if (np == NULL) { return; } + np->currLevelAreaSeqId++; -void network_send_level_area_inform(struct NetworkPlayer *np) { - SOFT_ASSERT(gNetworkType == NT_SERVER); - - for (s32 i = 1; i < MAX_PLAYERS; i++) { - struct NetworkPlayer *np2 = &gNetworkPlayers[i]; - if (!np2->connected) { continue; } - if (np2->localIndex == np->localIndex) { continue; } - - u16 seq = ++sLevelAreaInformSeq[np->globalIndex][i]; - - struct Packet p = { 0 }; - packet_init(&p, PACKET_LEVEL_AREA_INFORM, true, PLMT_NONE); - packet_write(&p, &seq, sizeof(u16)); - packet_write(&p, &np->globalIndex, sizeof(u8)); - packet_write(&p, &np->currCourseNum, sizeof(s16)); - packet_write(&p, &np->currActNum, sizeof(s16)); - packet_write(&p, &np->currLevelNum, sizeof(s16)); - packet_write(&p, &np->currAreaIndex, sizeof(s16)); - packet_write(&p, &np->currLevelSyncValid, sizeof(u8)); - packet_write(&p, &np->currAreaSyncValid, sizeof(u8)); - network_send_to(np2->localIndex, &p); - } + struct Packet p = { 0 }; + packet_init(&p, PACKET_LEVEL_AREA_INFORM, true, PLMT_NONE); + packet_write(&p, &np->currLevelAreaSeqId, sizeof(u16)); + packet_write(&p, &np->globalIndex, sizeof(u8)); + packet_write(&p, &np->currCourseNum, sizeof(s16)); + packet_write(&p, &np->currActNum, sizeof(s16)); + packet_write(&p, &np->currLevelNum, sizeof(s16)); + packet_write(&p, &np->currAreaIndex, sizeof(s16)); + packet_write(&p, &np->currLevelSyncValid, sizeof(u8)); + packet_write(&p, &np->currAreaSyncValid, sizeof(u8)); + network_send(&p); LOG_INFO("tx level area inform for global %d: (%d, %d, %d, %d)", np->globalIndex, np->currCourseNum, np->currActNum, np->currLevelNum, np->currAreaIndex); } -void network_receive_level_area_inform(struct Packet *p) { - SOFT_ASSERT(gNetworkType != NT_SERVER); - +void network_receive_level_area_inform(struct Packet* p) { u16 seq; u8 globalIndex; s16 courseNum, actNum, levelNum, areaIndex; @@ -61,14 +51,14 @@ void network_receive_level_area_inform(struct Packet *p) { } if (np == gNetworkPlayerLocal) { return; } - if (sLevelAreaInformSeq[0][globalIndex] >= seq && abs(sLevelAreaInformSeq[0][globalIndex] - seq) < 256) { - LOG_INFO("Received old level area inform seq: %d vs %d", sLevelAreaInformSeq[0][globalIndex], seq); + + if (np->currLevelAreaSeqId >= seq && abs(np->currLevelAreaSeqId - seq) < 256) { + LOG_INFO("Received old level area inform seq: %d vs %d", np->currLevelAreaSeqId, seq); return; } - sLevelAreaInformSeq[0][globalIndex] = seq; - - network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); + np->currLevelAreaSeqId = seq; np->currLevelSyncValid = levelSyncValid; np->currAreaSyncValid = areaSyncValid; -} \ No newline at end of file + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); +} diff --git a/src/pc/network/packets/packet_network_players.c b/src/pc/network/packets/packet_network_players.c index 047aa00e1..f0913947a 100644 --- a/src/pc/network/packets/packet_network_players.c +++ b/src/pc/network/packets/packet_network_players.c @@ -106,9 +106,9 @@ void network_receive_network_players(struct Packet *p) { struct NetworkPlayer *np = &gNetworkPlayers[localIndex]; if (localIndex != 0) { np->currLevelAreaSeqId = levelAreaSeqId; - network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); np->currLevelSyncValid = levelSyncValid; np->currAreaSyncValid = areaSyncValid; + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); LOG_INFO("received network player location (%d, %d, %d, %d)", courseNum, actNum, levelNum, areaIndex); if (gNetworkType == NT_CLIENT && globalIndex != 0 && localIndex != 0) { gNetworkSystem->save_id(localIndex, networkId); diff --git a/src/pc/network/packets/packet_sync_valid.c b/src/pc/network/packets/packet_sync_valid.c index 32d787bcc..eb13c5044 100644 --- a/src/pc/network/packets/packet_sync_valid.c +++ b/src/pc/network/packets/packet_sync_valid.c @@ -5,7 +5,7 @@ #include "pc/debuglog.h" void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { - bool wasAreaSyncValid = toNp->currAreaSyncValid; + bool wasSyncValid = (toNp->currLevelSyncValid && toNp->currAreaSyncValid); // set the NetworkPlayers sync valid toNp->currLevelSyncValid = true; @@ -16,13 +16,10 @@ void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actN gNetworkAreaSyncing = false; // call hooks - if (toNp == gNetworkPlayerLocal && !wasAreaSyncValid) { - network_player_update_course_level(toNp, courseNum, actNum, levelNum, (areaIndex != -1) ? areaIndex : toNp->currAreaIndex); + if (!wasSyncValid) { + network_player_update_course_level(toNp, courseNum, actNum, levelNum, areaIndex); smlua_call_event_hooks(HOOK_ON_SYNC_VALID); } - - // but we do need to send level area inform - network_send_level_area_inform(toNp); return; } @@ -64,12 +61,12 @@ void network_receive_sync_valid(struct Packet* p) { return; } - bool wasAreaSyncValid = np->currAreaSyncValid; + bool wasSyncValid = (np->currLevelSyncValid && np->currAreaSyncValid); np->currLevelSyncValid = true; np->currAreaSyncValid = true; - if (np == gNetworkPlayerLocal && !wasAreaSyncValid) { - network_player_update_course_level(np, courseNum, actNum, levelNum, (areaIndex != -1) ? areaIndex : np->currAreaIndex); + if (np == gNetworkPlayerLocal && !wasSyncValid) { + network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); smlua_call_event_hooks(HOOK_ON_SYNC_VALID); } @@ -79,11 +76,6 @@ void network_receive_sync_valid(struct Packet* p) { network_send_sync_valid(gNetworkPlayerServer, courseNum, actNum, levelNum, areaIndex); } - // inform everyone that this player is valid - if (gNetworkType == NT_SERVER) { - network_send_level_area_inform(np); - } - // we're no longer syncing gNetworkAreaSyncing = false; }