From f60b861d731b9de1bda43dc78d63e90d8b5fc9eb Mon Sep 17 00:00:00 2001 From: MysterD Date: Tue, 15 Jun 2021 21:01:28 -0700 Subject: [PATCH] BBH bookshelf manager no longer requires the server to be in BBH Instead of only allowing the server to update the bookshelf manager, allow the lowest global ID player to update it. --- developer/debug.sh | 2 +- .../behaviors/flying_bookend_switch.inc.c | 60 ++++++++++------ src/pc/controller/controller_keyboard_debug.c | 26 ++++--- src/pc/network/network.c | 3 +- src/pc/network/network_player.c | 68 +++++++++++++------ src/pc/network/network_player.h | 1 + src/pc/network/packets/packet_change_area.c | 4 +- src/pc/network/packets/packet_change_level.c | 3 +- .../packets/packet_level_area_inform.c | 37 ++++++---- .../packets/packet_level_respawn_info.c | 10 +-- .../network/packets/packet_network_players.c | 9 ++- src/pc/network/packets/packet_sync_valid.c | 12 +++- 12 files changed, 160 insertions(+), 75 deletions(-) diff --git a/developer/debug.sh b/developer/debug.sh index bfdb0d1ef..432f59290 100644 --- a/developer/debug.sh +++ b/developer/debug.sh @@ -1,2 +1,2 @@ #!/bin/bash -make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1 DEVELOPMENT=1 STRICT=1 && winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' \ No newline at end of file +winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'break debug_breakpoint_here' diff --git a/src/game/behaviors/flying_bookend_switch.inc.c b/src/game/behaviors/flying_bookend_switch.inc.c index 425eeaee8..17a0a5182 100644 --- a/src/game/behaviors/flying_bookend_switch.inc.c +++ b/src/game/behaviors/flying_bookend_switch.inc.c @@ -146,7 +146,6 @@ void bhv_bookend_spawn_loop(void) { if (book != NULL) { book->oAction = 3; - network_set_sync_id(book); struct Object* spawn_objects[] = { book }; u32 models[] = { MODEL_BOOKEND }; network_send_spawn_objects(spawn_objects, models, 1); @@ -159,6 +158,8 @@ void bhv_bookend_spawn_loop(void) { } void bookshelf_manager_act_0(void) { + // spawn book switches + s32 val04; //if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { @@ -171,13 +172,15 @@ void bookshelf_manager_act_0(void) { } void bookshelf_manager_act_1(void) { + // wait until mario is near + struct MarioState* marioState = nearest_mario_state_to_object(o); if (o->oBookSwitchManagerUnkF8 == 0) { - if (gNetworkType == NT_SERVER && obj_is_near_to_and_facing_mario(marioState, 500.0f, 0x3000)) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && obj_is_near_to_and_facing_mario(marioState, 500.0f, 0x3000)) { o->oBookSwitchManagerUnkF8 = 1; network_send_object(o); } - } else if (o->oTimer > 60 && gNetworkType == NT_SERVER) { + } else if (o->oTimer > 60 && o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oAction = 2; o->oBookSwitchManagerUnkF8 = 0; network_send_object(o); @@ -185,15 +188,17 @@ void bookshelf_manager_act_1(void) { } void bookshelf_manager_act_2(void) { + // detect if we can open, and open bookshelf if we should + //if (!(o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { if (o->oBookSwitchManagerUnkF4 < 0) { if (o->oTimer > 30) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oBookSwitchManagerUnkF4 = o->oBookSwitchManagerUnkF8 = 0; network_send_object(o); } } else if (o->oTimer > 10) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oBookSwitchManagerUnkF8 = 1; network_send_object(o); } @@ -201,7 +206,7 @@ void bookshelf_manager_act_2(void) { } else { if (o->oBookSwitchManagerUnkF4 >= 3) { if (o->oTimer > 100) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->parentObj = cur_obj_nearest_object_with_behavior(bhvHauntedBookshelf); o->parentObj->oAction = 1; o->oPosX = o->parentObj->oPosX; @@ -216,18 +221,17 @@ void bookshelf_manager_act_2(void) { o->oTimer = 0; } } - /*} else if (gNetworkType == NT_SERVER) { - o->oAction = 4; - network_send_object(o); - }*/ + //} } void bookshelf_manager_act_3(void) { + // opening bookshelf + if (o->parentObj == NULL || o->parentObj->behavior != bhvHauntedBookshelf) { o->parentObj = cur_obj_nearest_object_with_behavior(bhvHauntedBookshelf); } if (o->oTimer > 85) { - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oAction = 4; network_send_object(o); } @@ -238,18 +242,32 @@ void bookshelf_manager_act_3(void) { } void bookshelf_manager_act_4(void) { + // bookshelf is done opening + if (o->oBookSwitchManagerUnkF4 >= 3) { obj_mark_for_deletion(o); - } else if (gNetworkType == NT_SERVER) { + } else if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->oAction = 0; network_send_object(o); } } +void bhv_haunted_bookshelf_manager_override_ownership(u8* shouldOverride, u8* shouldOwn) { + *shouldOverride = TRUE; + *shouldOwn = get_network_player_smallest_global() == gNetworkPlayerLocal; +} + +static u8 bhv_haunted_bookshelf_manager_ignore_if_true(void) { + if (o->oSyncID == 0) { return true; } + return gSyncObjects[o->oSyncID].owned; +} + void bhv_haunted_bookshelf_manager_loop(void) { if (!network_sync_object_initialized(o)) { struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); so->syncDeathEvent = FALSE; + so->override_ownership = bhv_haunted_bookshelf_manager_override_ownership; + so->ignore_if_true = bhv_haunted_bookshelf_manager_ignore_if_true; network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->activeFlags); network_init_object_field(o, &o->oBookSwitchManagerUnkF8); @@ -280,7 +298,10 @@ void bhv_haunted_bookshelf_manager_loop(void) { void bhv_book_switch_loop(void) { if (!network_sync_object_initialized(o)) { - network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + struct SyncObject* so = network_init_object(o, SYNC_DISTANCE_ONLY_EVENTS); + so->override_ownership = bhv_haunted_bookshelf_manager_override_ownership; + so->ignore_if_true = bhv_haunted_bookshelf_manager_ignore_if_true; + network_init_object_field(o, &o->oAction); network_init_object_field(o, &o->oBookSwitchUnkF4); network_init_object_field(o, &o->oIntangibleTimer); @@ -312,7 +333,7 @@ void bhv_book_switch_loop(void) { cur_obj_become_intangible(); } - if (gNetworkType == NT_SERVER && o->oAction != 1) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && o->oAction != 1) { o->oAction = 1; network_send_object(o); } @@ -324,7 +345,7 @@ void bhv_book_switch_loop(void) { if (approach_f32_ptr(&o->oBookSwitchUnkF4, 50.0f, 20.0f)) { if (o->parentObj->oBookSwitchManagerUnkF4 >= 0 && o->oTimer > 60) { if (sp3C == 1 || sp3C == 2 || sp3C == 6) { - if (gNetworkType == NT_SERVER && o->oAction != 2) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && o->oAction != 2) { o->oAction = 2; network_send_object(o); } @@ -339,7 +360,7 @@ void bhv_book_switch_loop(void) { if (o->oAction != 0) { if (o->parentObj->oBookSwitchManagerUnkF4 == o->oBehParams2ndByte) { play_sound(SOUND_GENERAL2_RIGHT_ANSWER, gDefaultSoundArgs); - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->parentObj->oBookSwitchManagerUnkF4 += 1; network_send_object(o->parentObj); } @@ -352,26 +373,25 @@ void bhv_book_switch_loop(void) { sp34 = 0; } - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { book = spawn_object_abs_with_rot(o, 0, MODEL_BOOKEND, bhvFlyingBookend, 0x1FC * sp36 - 0x8CA, 890, sp34, 0, 0x8000 * sp36 + 0x4000, 0); if (book != NULL) { book->oAction = 3; - network_set_sync_id(book); struct Object* spawn_objects[] = { book }; u32 models[] = { MODEL_BOOKEND }; network_send_spawn_objects(spawn_objects, models, 1); } } - if (gNetworkType == NT_SERVER) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned) { o->parentObj->oBookSwitchManagerUnkF4 = -1; network_send_object(o->parentObj); } } - if (gNetworkType == NT_SERVER && o->oAction != 0) { + if (o->oSyncID != 0 && gSyncObjects[o->oSyncID].owned && o->oAction != 0) { o->oAction = 0; network_send_object(o); } diff --git a/src/pc/controller/controller_keyboard_debug.c b/src/pc/controller/controller_keyboard_debug.c index 57d91dccc..b9fdd1818 100644 --- a/src/pc/controller/controller_keyboard_debug.c +++ b/src/pc/controller/controller_keyboard_debug.c @@ -13,7 +13,12 @@ #ifdef DEBUG -static u8 warpToLevel = LEVEL_BOB; +static u8 warpToLevel = LEVEL_BBH; +static u8 warpToArea = 29; +// warpToArea: 26 = basement +// warpToArea: 27 = upstairs +// warpToArea: 29 = courtyard + #define SCANCODE_0 0x0B #define SCANCODE_1 0x02 @@ -82,17 +87,20 @@ static void debug_warp_area() { if (sCurrPlayMode == PLAY_MODE_CHANGE_LEVEL) { return; } struct ObjectWarpNode* objectNode = gCurrentArea->warpNodes; + u8 onArea = 0; while (objectNode != NULL) { struct WarpNode* node = &objectNode->node; - if (node->destLevel == gCurrLevelNum && node->destArea != gCurrAreaIndex) { - sWarpDest.type = WARP_TYPE_CHANGE_AREA; - sWarpDest.levelNum = node->destLevel; - sWarpDest.areaIdx = node->destArea; - sWarpDest.nodeId = node->destNode; - sWarpDest.arg = 0; + if (gCurrCourseNum == 0 || (node->destLevel == gCurrLevelNum && node->destArea != gCurrAreaIndex)) { + if (gCurrCourseNum != 0 || ++onArea == warpToArea) { + sWarpDest.type = WARP_TYPE_CHANGE_AREA; + sWarpDest.levelNum = node->destLevel; + sWarpDest.areaIdx = node->destArea; + sWarpDest.nodeId = node->destNode; + sWarpDest.arg = 0; - sCurrPlayMode = PLAY_MODE_CHANGE_LEVEL; - return; + sCurrPlayMode = PLAY_MODE_CHANGE_LEVEL; + return; + } } objectNode = objectNode->next; } diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 87cdcd01e..2c7b92bed 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -77,8 +77,7 @@ bool network_init(enum NetworkType inNetworkType) { network_player_connected(NPT_LOCAL, 0); extern u8* gOverrideEeprom; gOverrideEeprom = NULL; - } - else if (gNetworkType == NT_CLIENT) { + } else if (gNetworkType == NT_CLIENT) { network_player_connected(NPT_SERVER, 0); } diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index a0e6bb011..025dda785 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -37,11 +37,11 @@ struct NetworkPlayer* network_player_from_global_index(u8 globalIndex) { struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s16 levelNum) { for (int i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - if (!np->currLevelSyncValid) { continue; } + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } if (np->currCourseNum != courseNum) { continue; } - if (np->currActNum != actNum) { continue; } - if (np->currLevelNum != levelNum) { continue; } + if (np->currActNum != actNum) { continue; } + if (np->currLevelNum != levelNum) { continue; } return np; } return NULL; @@ -50,18 +50,35 @@ struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s struct NetworkPlayer* get_network_player_from_area(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex) { for (int i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - if (!np->currLevelSyncValid) { continue; } - if (!np->currAreaSyncValid) { continue; } + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } + if (!np->currAreaSyncValid) { continue; } if (np->currCourseNum != courseNum) { continue; } - if (np->currActNum != actNum) { continue; } - if (np->currLevelNum != levelNum) { continue; } + if (np->currActNum != actNum) { continue; } + if (np->currLevelNum != levelNum) { continue; } if (np->currAreaIndex != areaIndex) { continue; } return np; } return NULL; } +struct NetworkPlayer* get_network_player_smallest_global(void) { + struct NetworkPlayer* lNp = gNetworkPlayerLocal; + struct NetworkPlayer* smallest = gNetworkPlayerLocal; + for (int i = 0; i < MAX_PLAYERS; i++) { + struct NetworkPlayer* np = &gNetworkPlayers[i]; + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } + if (!np->currAreaSyncValid) { continue; } + if (np->currCourseNum != lNp->currCourseNum) { continue; } + if (np->currActNum != lNp->currActNum) { continue; } + if (np->currLevelNum != lNp->currLevelNum) { continue; } + if (np->currAreaIndex != lNp->currAreaIndex) { continue; } + if (np->globalIndex < smallest->globalIndex) { smallest = np; } + } + return smallest; +} + void network_player_update(void) { float elapsed = (clock() - gLastNetworkSend) / (float)CLOCKS_PER_SEC; if (elapsed > NETWORK_PLAYER_TIMEOUT / 3.0f) { @@ -109,11 +126,15 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { np->localIndex = 0; np->globalIndex = globalIndex; np->currLevelAreaSeqId = 0; - np->currCourseNum = -1; - np->currActNum = -1; - np->currLevelNum = -1; - np->currAreaIndex = -1; - np->currAreaSyncValid = false; + + extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex; + np->currCourseNum = gCurrCourseNum; + np->currActNum = gCurrActStarNum; + np->currLevelNum = gCurrLevelNum; + np->currAreaIndex = gCurrAreaIndex; + np->currLevelSyncValid = false; + np->currAreaSyncValid = false; + gNetworkPlayerLocal = np; if (gNetworkType == NT_SERVER) { @@ -142,11 +163,14 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { memset(np, 0, sizeof(struct NetworkPlayer)); np->connected = true; np->currLevelAreaSeqId = 0; - np->currCourseNum = -1; - np->currActNum = -1; - np->currLevelNum = -1; - np->currAreaIndex = -1; - np->currAreaSyncValid = false; + if (!np->currAreaSyncValid) { + np->currCourseNum = -1; + np->currActNum = -1; + np->currLevelNum = -1; + np->currAreaIndex = -1; + np->currLevelSyncValid = false; + np->currAreaSyncValid = false; + } np->fadeOpacity = 0; np->localIndex = i; np->globalIndex = (gNetworkType == NT_SERVER) ? i : globalIndex; @@ -186,6 +210,12 @@ u8 network_player_disconnected(u8 globalIndex) { if (np->globalIndex != globalIndex) { continue; } if (gNetworkType == NT_SERVER) { network_send_leaving(np->globalIndex); } np->connected = false; + np->currCourseNum = -1; + np->currActNum = -1; + np->currLevelNum = -1; + np->currAreaIndex = -1; + np->currLevelSyncValid = false; + np->currAreaSyncValid = false; gNetworkSystem->clear_id(i); for (int j = 0; j < MAX_SYNC_OBJECTS; j++) { gSyncObjects[j].rxEventId[i] = 0; } LOG_INFO("player disconnected, local %d, global %d", i, globalIndex); diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 6e5f7b231..7da84bce9 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -44,6 +44,7 @@ u8 network_player_connected_count(void); struct NetworkPlayer* network_player_from_global_index(u8 globalIndex); struct NetworkPlayer* get_network_player_from_level(s16 courseNum, s16 actNum, s16 levelNum); struct NetworkPlayer* get_network_player_from_area(s16 courseNum, s16 actNum, s16 levelNum, s16 areaIndex); +struct NetworkPlayer* get_network_player_smallest_global(void); void network_player_update(void); u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex); u8 network_player_disconnected(u8 globalIndex); diff --git a/src/pc/network/packets/packet_change_area.c b/src/pc/network/packets/packet_change_area.c index 7534c0d18..8082126df 100644 --- a/src/pc/network/packets/packet_change_area.c +++ b/src/pc/network/packets/packet_change_area.c @@ -12,7 +12,6 @@ static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 act np->currLevelNum = levelNum; np->currAreaIndex = areaIndex; np->currAreaSyncValid = false; - network_send_level_area_inform(np); reservation_area_change(np); // find a NetworkPlayer at that area @@ -21,11 +20,14 @@ static void player_changed_area(struct NetworkPlayer* np, s16 courseNum, s16 act if (npLevelAreaMatch == NULL) { // no NetworkPlayer in the level network_send_sync_valid(np); + 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) { diff --git a/src/pc/network/packets/packet_change_level.c b/src/pc/network/packets/packet_change_level.c index 73f98381c..b1264c577 100644 --- a/src/pc/network/packets/packet_change_level.c +++ b/src/pc/network/packets/packet_change_level.c @@ -13,7 +13,6 @@ static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 ac np->currAreaIndex = areaIndex; np->currLevelSyncValid = false; np->currAreaSyncValid = false; - network_send_level_area_inform(np); reservation_area_change(np); // find a NetworkPlayer around that location @@ -24,6 +23,7 @@ static void player_changed_level(struct NetworkPlayer* np, s16 courseNum, s16 ac if (npAny == NULL) { // no NetworkPlayer in the level network_send_sync_valid(np); + network_send_level_area_inform(np); return; } @@ -33,6 +33,7 @@ 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) { diff --git a/src/pc/network/packets/packet_level_area_inform.c b/src/pc/network/packets/packet_level_area_inform.c index 254ca8d0d..104009cf6 100644 --- a/src/pc/network/packets/packet_level_area_inform.c +++ b/src/pc/network/packets/packet_level_area_inform.c @@ -9,11 +9,13 @@ void network_send_level_area_inform(struct NetworkPlayer* np) { struct Packet p; packet_init(&p, PACKET_LEVEL_AREA_INFORM, true, false); - 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->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"); @@ -26,11 +28,14 @@ void network_receive_level_area_inform(struct Packet* p) { u8 globalIndex; s16 courseNum, actNum, levelNum, areaIndex; - packet_read(p, &globalIndex, sizeof(u8)); - packet_read(p, &courseNum, sizeof(s16)); - packet_read(p, &actNum, sizeof(s16)); - packet_read(p, &levelNum, sizeof(s16)); - packet_read(p, &areaIndex, sizeof(s16)); + u8 levelSyncValid, areaSyncValid; + packet_read(p, &globalIndex, sizeof(u8)); + 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, &levelSyncValid, sizeof(u8)); + packet_read(p, &areaSyncValid, sizeof(u8)); struct NetworkPlayer* np = network_player_from_global_index(globalIndex); if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) { @@ -38,8 +43,12 @@ void network_receive_level_area_inform(struct Packet* p) { return; } - np->currCourseNum = courseNum; - np->currActNum = actNum; - np->currLevelNum = levelNum; - np->currAreaIndex = areaIndex; + if (np == gNetworkPlayerLocal) { return; } + + np->currCourseNum = courseNum; + np->currActNum = actNum; + np->currLevelNum = levelNum; + np->currAreaIndex = areaIndex; + np->currLevelSyncValid = levelSyncValid; + np->currAreaSyncValid = areaSyncValid; } diff --git a/src/pc/network/packets/packet_level_respawn_info.c b/src/pc/network/packets/packet_level_respawn_info.c index 08b9f7832..a79e1b745 100644 --- a/src/pc/network/packets/packet_level_respawn_info.c +++ b/src/pc/network/packets/packet_level_respawn_info.c @@ -128,12 +128,12 @@ void network_send_level_respawn_info(struct Object* o, u8 respawnInfoBits) { // broadcast for (int i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; - if (!np->connected) { continue; } - if (!np->currLevelSyncValid) { continue; } + if (!np->connected) { continue; } + if (!np->currLevelSyncValid) { continue; } if (np->currCourseNum != gCurrCourseNum) { continue; } - if (np->currActNum != gCurrActStarNum) { continue; } - if (np->currLevelNum != gCurrLevelNum) { continue; } - if (np == gNetworkPlayerLocal) { continue; } + if (np->currActNum != gCurrActStarNum) { continue; } + if (np->currLevelNum != gCurrLevelNum) { continue; } + if (np == gNetworkPlayerLocal) { continue; } struct Packet p2; packet_duplicate(&p, &p2); network_send_to(np->localIndex, &p2); diff --git a/src/pc/network/packets/packet_network_players.c b/src/pc/network/packets/packet_network_players.c index e6344a5a3..104d757ab 100644 --- a/src/pc/network/packets/packet_network_players.c +++ b/src/pc/network/packets/packet_network_players.c @@ -20,13 +20,15 @@ static void network_send_to_network_players(u8 sendToLocalIndex) { if (npType == NPT_LOCAL) { npType = NPT_SERVER; } else if (i == sendToLocalIndex) { npType = NPT_LOCAL; } s64 networkId = gNetworkSystem->get_id(i); - packet_write(&p, &npType, sizeof(u8)); + packet_write(&p, &npType, sizeof(u8)); packet_write(&p, &gNetworkPlayers[i].globalIndex, sizeof(u8)); packet_write(&p, &gNetworkPlayers[i].currLevelAreaSeqId, sizeof(u16)); packet_write(&p, &gNetworkPlayers[i].currCourseNum, sizeof(s16)); packet_write(&p, &gNetworkPlayers[i].currActNum, sizeof(s16)); packet_write(&p, &gNetworkPlayers[i].currLevelNum, sizeof(s16)); packet_write(&p, &gNetworkPlayers[i].currAreaIndex, sizeof(s16)); + packet_write(&p, &gNetworkPlayers[i].currLevelSyncValid, sizeof(u8)); + packet_write(&p, &gNetworkPlayers[i].currAreaSyncValid, sizeof(u8)); packet_write(&p, &networkId, sizeof(s64)); LOG_INFO("send network player [%d == %d]", gNetworkPlayers[i].globalIndex, npType); } @@ -56,6 +58,7 @@ void network_receive_network_players(struct Packet* p) { u8 npType, globalIndex; u16 levelAreaSeqId; s16 courseNum, actNum, levelNum, areaIndex; + u8 levelSyncValid, areaSyncValid; s64 networkId; packet_read(p, &npType, sizeof(u8)); packet_read(p, &globalIndex, sizeof(u8)); @@ -64,6 +67,8 @@ void network_receive_network_players(struct Packet* p) { packet_read(p, &actNum, sizeof(s16)); packet_read(p, &levelNum, sizeof(s16)); packet_read(p, &areaIndex, sizeof(s16)); + packet_read(p, &levelSyncValid, sizeof(u8)); + packet_read(p, &areaSyncValid, sizeof(u8)); packet_read(p, &networkId, sizeof(s64)); u8 localIndex = network_player_connected(npType, globalIndex); @@ -75,6 +80,8 @@ void network_receive_network_players(struct Packet* p) { np->currActNum = actNum; np->currLevelNum = levelNum; np->currAreaIndex = areaIndex; + np->currLevelSyncValid = levelSyncValid; + np->currAreaSyncValid = areaSyncValid; 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 49ddf1ce6..a8553aeac 100644 --- a/src/pc/network/packets/packet_sync_valid.c +++ b/src/pc/network/packets/packet_sync_valid.c @@ -8,9 +8,12 @@ void network_send_sync_valid(struct NetworkPlayer* toNp) { toNp->currLevelSyncValid = true; toNp->currAreaSyncValid = true; - if (toNp == gNetworkPlayerLocal) { - // the player is the server, no need to send it + if (gNetworkType == NT_SERVER && toNp == gNetworkPlayerLocal) { + // the player is the server, no need to send sync valid gNetworkAreaSyncing = false; + + // but we do need to send level area inform + network_send_level_area_inform(toNp); return; } @@ -61,6 +64,11 @@ void network_receive_sync_valid(struct Packet* p) { network_send_sync_valid(gNetworkPlayerServer); } + // inform everyone that this player is valid + if (gNetworkType == NT_SERVER) { + network_send_level_area_inform(np); + } + // we're no longer syncing gNetworkAreaSyncing = false; }