From 149cb101530c4058cbc8aed17be6a53952882a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emily=E2=99=A5?= <77174187+EmilyEmmi@users.noreply.github.com> Date: Thu, 7 May 2026 11:23:57 -0400 Subject: [PATCH] Fix sync valid packet issues for the server (#1228) * Fix erroneous sync valid packets When the server received a sync valid packet from another player, it would also set the server player's level. This simple fix makes this no longer happen. * Fix sync valid packets with host Okay, so it turns out that the host was unable to differentiate between packets meant to validate other players, and packets meant to validate itself (sent when entering a level another player is already in). I changed so that the packet also includes who the sync packet is validating. Requires an additional byte, as well as adding an argument to network_send_sync_valid. * Don't have server inform itself Fixes HOOK_ON_SYNC_VALID being called twice --- src/pc/network/network.c | 2 +- src/pc/network/packets/packet.h | 2 +- src/pc/network/packets/packet_area.c | 2 +- src/pc/network/packets/packet_change_area.c | 2 +- src/pc/network/packets/packet_change_level.c | 2 +- src/pc/network/packets/packet_level.c | 2 +- src/pc/network/packets/packet_sync_valid.c | 34 +++++++++++--------- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 6bd1d4882..ff5ce1d5e 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -617,7 +617,7 @@ void network_update(void) { bool inCredits = (np->currActNum == 99); if (gNetworkType == NT_SERVER && (npAny == NULL || inCredits)) { // no NetworkPlayer in the level - network_send_sync_valid(np, np->currCourseNum, np->currActNum, np->currLevelNum, np->currAreaIndex); + network_send_sync_valid(np, np->currCourseNum, np->currActNum, np->currLevelNum, np->currAreaIndex, false); return; } diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index 5ab859760..ca0bf368a 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -315,7 +315,7 @@ void network_send_area(struct NetworkPlayer* toNp); void network_receive_area(struct Packet* p); // packet_sync_valid.c -void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex); +void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex, bool informServer); void network_receive_sync_valid(struct Packet* p); // packet_level_spawn_info.c diff --git a/src/pc/network/packets/packet_area.c b/src/pc/network/packets/packet_area.c index 001183f00..a19c813ea 100644 --- a/src/pc/network/packets/packet_area.c +++ b/src/pc/network/packets/packet_area.c @@ -121,7 +121,7 @@ void network_send_area(struct NetworkPlayer* toNp) { } // send sync valid - network_send_sync_valid(toNp, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex); + network_send_sync_valid(toNp, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex, false); } packet_ordered_end(); diff --git a/src/pc/network/packets/packet_change_area.c b/src/pc/network/packets/packet_change_area.c index ff5e99ffd..68906d922 100644 --- a/src/pc/network/packets/packet_change_area.c +++ b/src/pc/network/packets/packet_change_area.c @@ -15,7 +15,7 @@ static void player_changed_area(struct NetworkPlayer *np, s16 courseNum, s16 act bool inCredits = (np->currActNum == 99); if (npLevelAreaMatch == NULL || inCredits) { // no NetworkPlayer in the level - network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex); + network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex, false); return; } diff --git a/src/pc/network/packets/packet_change_level.c b/src/pc/network/packets/packet_change_level.c index 6ac4992f9..b1bf62bb1 100644 --- a/src/pc/network/packets/packet_change_level.c +++ b/src/pc/network/packets/packet_change_level.c @@ -17,7 +17,7 @@ static void player_changed_level(struct NetworkPlayer *np, s16 courseNum, s16 ac bool inCredits = (np->currActNum == 99); if (npAny == NULL || inCredits) { // no NetworkPlayer in the level - network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex); + network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex, false); return; } diff --git a/src/pc/network/packets/packet_level.c b/src/pc/network/packets/packet_level.c index eab22bb60..3d550db74 100644 --- a/src/pc/network/packets/packet_level.c +++ b/src/pc/network/packets/packet_level.c @@ -46,7 +46,7 @@ void network_send_level(struct NetworkPlayer* toNp, bool sendArea) { network_send_area(toNp); } else { // send sync valid - network_send_sync_valid(toNp, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, -1); + network_send_sync_valid(toNp, gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, -1, false); } } packet_ordered_end(); diff --git a/src/pc/network/packets/packet_sync_valid.c b/src/pc/network/packets/packet_sync_valid.c index eb13c5044..67514e4a5 100644 --- a/src/pc/network/packets/packet_sync_valid.c +++ b/src/pc/network/packets/packet_sync_valid.c @@ -4,7 +4,7 @@ //#define DISABLE_MODULE_LOG 1 #include "pc/debuglog.h" -void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { +void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex, bool informServer) { bool wasSyncValid = (toNp->currLevelSyncValid && toNp->currAreaSyncValid); // set the NetworkPlayers sync valid @@ -24,30 +24,34 @@ void network_send_sync_valid(struct NetworkPlayer* toNp, s16 courseNum, s16 actN } u8 myGlobalIndex = gNetworkPlayerLocal->globalIndex; + u8 forGlobalIndex = toNp->globalIndex; struct Packet p = { 0 }; packet_init(&p, PACKET_SYNC_VALID, true, PLMT_NONE); - packet_write(&p, &courseNum, sizeof(s16)); - packet_write(&p, &actNum, sizeof(s16)); - packet_write(&p, &levelNum, sizeof(s16)); - packet_write(&p, &areaIndex, sizeof(s16)); - packet_write(&p, &myGlobalIndex, sizeof(u8)); - network_send_to(toNp->localIndex, &p); + packet_write(&p, &courseNum, sizeof(s16)); + packet_write(&p, &actNum, sizeof(s16)); + packet_write(&p, &levelNum, sizeof(s16)); + packet_write(&p, &areaIndex, sizeof(s16)); + packet_write(&p, &myGlobalIndex, sizeof(u8)); + packet_write(&p, &forGlobalIndex, sizeof(u8)); + network_send_to((informServer ? gNetworkPlayerServer->localIndex : toNp->localIndex), &p); LOG_INFO("tx sync valid"); } void network_receive_sync_valid(struct Packet* p) { - LOG_INFO("rx sync valid"); - s16 courseNum, actNum, levelNum, areaIndex; - u8 fromGlobalIndex; + u8 fromGlobalIndex, forGlobalIndex; packet_read(p, &courseNum, sizeof(s16)); packet_read(p, &actNum, sizeof(s16)); packet_read(p, &levelNum, sizeof(s16)); packet_read(p, &areaIndex, sizeof(s16)); packet_read(p, &fromGlobalIndex, sizeof(u8)); + packet_read(p, &forGlobalIndex, sizeof(u8)); + + LOG_INFO("rx sync valid: from global %d, for global %d", fromGlobalIndex, forGlobalIndex); - if (gNetworkType != NT_SERVER) { + bool isOurSyncValid = (forGlobalIndex == gNetworkPlayerLocal->globalIndex); + if (isOurSyncValid) { extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || (areaIndex != gCurrAreaIndex && areaIndex != -1)) { LOG_ERROR("rx sync valid: received an improper location"); @@ -55,7 +59,7 @@ void network_receive_sync_valid(struct Packet* p) { } } - struct NetworkPlayer* np = (gNetworkType != NT_SERVER) ? gNetworkPlayerLocal : &gNetworkPlayers[p->localIndex]; + struct NetworkPlayer* np = network_player_from_global_index(forGlobalIndex); if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) { LOG_ERROR("Receiving sync valid from inactive player!"); return; @@ -65,15 +69,15 @@ void network_receive_sync_valid(struct Packet* p) { np->currLevelSyncValid = true; np->currAreaSyncValid = true; - if (np == gNetworkPlayerLocal && !wasSyncValid) { + if (isOurSyncValid && !wasSyncValid) { network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex); smlua_call_event_hooks(HOOK_ON_SYNC_VALID); } // inform server - if (fromGlobalIndex != gNetworkPlayerServer->globalIndex) { + if (gNetworkType != NT_SERVER && fromGlobalIndex != gNetworkPlayerServer->globalIndex) { LOG_INFO("informing server of sync valid"); - network_send_sync_valid(gNetworkPlayerServer, courseNum, actNum, levelNum, areaIndex); + network_send_sync_valid(np, courseNum, actNum, levelNum, areaIndex, true); } // we're no longer syncing