From 341953390c92150d2bb3104cb0756c3531a31199 Mon Sep 17 00:00:00 2001 From: MysterD Date: Wed, 29 Mar 2023 17:36:13 -0700 Subject: [PATCH] Allow the ability to change server settings/mods while hosting --- src/pc/djui/djui_font.c | 1 - src/pc/djui/djui_panel_host.c | 28 +++++-- src/pc/djui/djui_panel_host_message.c | 12 ++- src/pc/djui/djui_panel_join.c | 1 + src/pc/djui/djui_panel_join_message.c | 2 + src/pc/djui/djui_panel_pause.c | 27 ++++--- src/pc/network/discord/activity.c | 1 + src/pc/network/discord/discord.c | 3 + src/pc/network/discord/discord.h | 1 + src/pc/network/network.c | 91 +++++++++++++++++++++- src/pc/network/network.h | 5 ++ src/pc/network/network_player.c | 3 - src/pc/network/packets/packet.c | 4 + src/pc/network/packets/packet.h | 2 + src/pc/network/packets/packet_kick.c | 18 ++++- src/pc/network/packets/packet_read_write.c | 1 + src/pc/network/packets/packet_reliable.c | 13 +++- 17 files changed, 189 insertions(+), 24 deletions(-) diff --git a/src/pc/djui/djui_font.c b/src/pc/djui/djui_font.c index db6abebf..af8bd364 100644 --- a/src/pc/djui/djui_font.c +++ b/src/pc/djui/djui_font.c @@ -185,7 +185,6 @@ const Gfx dl_font_normal_display_list[] = { static void djui_font_normal_render_char(char c) { extern const u8* const font_normal_chars[]; // replace undisplayable characters - //if ((u8)c < ' ' || (u8)c > ('~' + 3)) { c = '?'; } if (!djui_font_valid_smcode(c)) { c = '?'; } if (c == ' ') { return; } void* fontChar = (void*)font_normal_chars[(u8)c - '!']; diff --git a/src/pc/djui/djui_panel_host.c b/src/pc/djui/djui_panel_host.c index a638bc6d..d0cf9cfa 100644 --- a/src/pc/djui/djui_panel_host.c +++ b/src/pc/djui/djui_panel_host.c @@ -56,14 +56,22 @@ static void djui_panel_host_do_host(struct DjuiBase* caller) { } configHostPort = atoi(sInputboxPort->buffer); - djui_panel_host_message_create(caller); + + if (gNetworkType == NT_SERVER) { + network_rehost_begin(); + } else { + djui_panel_host_message_create(caller); + } } void djui_panel_host_create(struct DjuiBase* caller) { f32 bodyHeight = 32 * 4 + 64 * 4 + 16 * 5; struct DjuiBase* defaultBase = NULL; - struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\H\\#1be700\\O\\#00b3ff\\S\\#ffef00\\T"); + struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, + (gNetworkType == NT_SERVER) + ? "\\#ff0800\\S\\#1be700\\E\\#00b3ff\\R\\#ffef00\\V\\#ff0800\\E\\#1be700\\R" + : "\\#ff0800\\H\\#1be700\\O\\#00b3ff\\S\\#ffef00\\T"); struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel); { #ifdef DISCORD_SDK @@ -72,6 +80,10 @@ void djui_panel_host_create(struct DjuiBase* caller) { djui_base_set_size_type(&selectionbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&selectionbox1->base, 1.0f, 32); djui_interactable_hook_value_change(&selectionbox1->base, djui_panel_host_network_system_change); + if (gNetworkType == NT_SERVER) { + djui_base_set_enabled(&selectionbox1->base, false); + } + #endif struct DjuiRect* rect1 = djui_rect_create(&body->base); @@ -84,6 +96,9 @@ void djui_panel_host_create(struct DjuiBase* caller) { djui_base_set_color(&text1->base, 200, 200, 200, 255); djui_base_set_size(&text1->base, 0.485f, 64); djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); + if (gNetworkType == NT_SERVER) { + djui_base_set_enabled(&text1->base, false); + } struct DjuiInputbox* inputbox1 = djui_inputbox_create(&rect1->base, 32); djui_base_set_size_type(&inputbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); @@ -144,19 +159,22 @@ void djui_panel_host_create(struct DjuiBase* caller) { djui_base_set_size(&rect3->base, 1.0f, 64); djui_base_set_color(&rect3->base, 0, 0, 0, 0); { - struct DjuiButton* button1 = djui_button_create(&rect3->base, "Back"); + struct DjuiButton* button1 = djui_button_create(&rect3->base, (gNetworkType == NT_SERVER) ? "Cancel" : "Back"); djui_base_set_size_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button1->base, 0.485f, 64); djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); djui_button_set_style(button1, 1); djui_interactable_hook_click(&button1->base, djui_panel_menu_back); - struct DjuiButton* button2 = djui_button_create(&rect3->base, "Host"); + struct DjuiButton* button2 = djui_button_create(&rect3->base, (gNetworkType == NT_SERVER) ? "Apply" : "Host"); djui_base_set_size_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); djui_base_set_size(&button2->base, 0.485f, 64); djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); djui_interactable_hook_click(&button2->base, djui_panel_host_do_host); - defaultBase = &button2->base; + + defaultBase = (gNetworkType == NT_SERVER) + ? &button1->base + : &button2->base; } } diff --git a/src/pc/djui/djui_panel_host_message.c b/src/pc/djui/djui_panel_host_message.c index fda41f5e..52e0c095 100644 --- a/src/pc/djui/djui_panel_host_message.c +++ b/src/pc/djui/djui_panel_host_message.c @@ -27,12 +27,13 @@ Direct connections \\#ffa0a0\\require you\\#c8c8c8\\ to configure port forwardin Forward port '\\#d0d0ff\\%d\\#c8c8c8\\' for UDP.\ "; -void djui_panel_host_message_do_host(UNUSED struct DjuiBase* caller) { +void djui_panel_do_host(void) { stop_demo(NULL); djui_panel_shutdown(); extern s16 gCurrSaveFileNum; gCurrSaveFileNum = configHostSaveSlot; update_all_mario_stars(); + #ifndef DISCORD_SDK configNetworkSystem = 1; network_set_system(NS_SOCKET); @@ -43,17 +44,26 @@ void djui_panel_host_message_do_host(UNUSED struct DjuiBase* caller) { network_set_system(NS_SOCKET); } #endif + network_init(NT_SERVER); djui_panel_modlist_create(NULL); fake_lvl_init_from_save_file(); + extern s16 gChangeLevelTransition; gChangeLevelTransition = gLevelValues.entryLevel; + if (gMarioState->marioObj) vec3f_copy(gMarioState->marioObj->header.gfx.cameraToObject, gGlobalSoundSource); + play_character_sound(gMarioState, CHAR_SOUND_OKEY_DOKEY); extern void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue); play_transition(0x09, 0x14, 0x00, 0x00, 0x00); } +void djui_panel_host_message_do_host(UNUSED struct DjuiBase* caller) { + network_reset_reconnect_and_rehost(); + djui_panel_do_host(); +} + void djui_panel_host_message_create(struct DjuiBase* caller) { f32 warningLines = 0; char* warningMessage = NULL; diff --git a/src/pc/djui/djui_panel_join.c b/src/pc/djui/djui_panel_join.c index 63af6879..a67b7315 100644 --- a/src/pc/djui/djui_panel_join.c +++ b/src/pc/djui/djui_panel_join.c @@ -149,6 +149,7 @@ void djui_panel_join_do_join(struct DjuiBase* caller) { djui_inputbox_select_all(sInputboxIp); return; } + network_reset_reconnect_and_rehost(); djui_panel_join_ip_text_set_new(); network_set_system(NS_SOCKET); network_init(NT_CLIENT); diff --git a/src/pc/djui/djui_panel_join_message.c b/src/pc/djui/djui_panel_join_message.c index 8436f26e..123fd5ea 100644 --- a/src/pc/djui/djui_panel_join_message.c +++ b/src/pc/djui/djui_panel_join_message.c @@ -16,6 +16,8 @@ void djui_panel_join_message_error(char* message) { } void djui_panel_join_message_cancel(struct DjuiBase* caller) { + if (network_is_reconnecting()) { return; } + network_reset_reconnect_and_rehost(); network_shutdown(true, false, false); djui_panel_menu_back(caller); } diff --git a/src/pc/djui/djui_panel_pause.c b/src/pc/djui/djui_panel_pause.c index 526b31ab..cec860c0 100644 --- a/src/pc/djui/djui_panel_pause.c +++ b/src/pc/djui/djui_panel_pause.c @@ -13,6 +13,7 @@ static void djui_panel_pause_resume(UNUSED struct DjuiBase* caller) { } static void djui_panel_pause_quit_yes(UNUSED struct DjuiBase* caller) { + network_reset_reconnect_and_rehost(); network_shutdown(true, false, false); } @@ -35,8 +36,9 @@ static void djui_panel_pause_quit(struct DjuiBase* caller) { void djui_panel_pause_create(struct DjuiBase* caller) { if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); } - f32 bodyHeight = 64 * 5 + 16 * 4; + f32 bodyHeight = 64 * 4 + 16 * 3; if (gServerSettings.enableCheats) { bodyHeight += 64 + 16; } + if (gNetworkType == NT_SERVER) { bodyHeight += 64 + 16; } struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\P\\#1be700\\A\\#00b3ff\\U\\#ffef00\\S\\#ff0800\\E"); @@ -77,16 +79,23 @@ void djui_panel_pause_create(struct DjuiBase* caller) { djui_base_set_size(&button5->base, 1.0f, 64); djui_interactable_hook_click(&button5->base, djui_panel_pause_resume); - struct DjuiButton* button6; if (gNetworkType == NT_SERVER) { - button6 = djui_button_create(&body->base, "Stop Hosting"); - } else { - button6 = djui_button_create(&body->base, "Disconnect"); + struct DjuiButton* button6 = djui_button_create(&body->base, "Server Settings"); + djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button6->base, 1.0f, 64); + djui_interactable_hook_click(&button6->base, djui_panel_host_create); } - djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); - djui_base_set_size(&button6->base, 1.0f, 64); - djui_interactable_hook_click(&button6->base, djui_panel_pause_quit); - djui_button_set_style(button6, 1); + + struct DjuiButton* button7; + if (gNetworkType == NT_SERVER) { + button7 = djui_button_create(&body->base, "Stop Hosting"); + } else { + button7 = djui_button_create(&body->base, "Disconnect"); + } + djui_base_set_size_type(&button7->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button7->base, 1.0f, 64); + djui_interactable_hook_click(&button7->base, djui_panel_pause_quit); + djui_button_set_style(button7, 1); } djui_panel_add(caller, &panel->base, defaultBase); diff --git a/src/pc/network/discord/activity.c b/src/pc/network/discord/activity.c index 2e4d6176..2806ec94 100644 --- a/src/pc/network/discord/activity.c +++ b/src/pc/network/discord/activity.c @@ -24,6 +24,7 @@ static void on_activity_join_callback(UNUSED void* data, enum EDiscordResult res LOGFILE_ERROR(LFT_DISCORD, "Joined lobby when already connected somewhere!"); return; } + network_reset_reconnect_and_rehost(); network_init(NT_CLIENT); gCurActivity.type = DiscordActivityType_Playing; diff --git a/src/pc/network/discord/discord.c b/src/pc/network/discord/discord.c index b5021485..fe89bf24 100644 --- a/src/pc/network/discord/discord.c +++ b/src/pc/network/discord/discord.c @@ -22,6 +22,7 @@ struct DiscordApplication app = { 0 }; bool gDiscordInitialized = false; bool gDiscordFailed = false; bool alreadyRun = false; +bool gDiscordReconnecting = false; static void discord_sdk_log_callback(UNUSED void* hook_data, enum EDiscordLogLevel level, const char* message) { LOGFILE_INFO(LFT_DISCORD, "callback (%d): %s", level, message); @@ -107,6 +108,7 @@ static void ns_discord_update(void) { } static bool ns_discord_initialize(enum NetworkType networkType) { + if (gDiscordReconnecting) { return true; } #ifdef DEBUG set_instance_env_variable(); #endif @@ -179,6 +181,7 @@ static bool ns_discord_initialize(enum NetworkType networkType) { } static void ns_discord_shutdown(void) { + if (gDiscordReconnecting) { return; } if (!gDiscordInitialized) { return; } discord_lobby_leave(); gActivityLock = false; diff --git a/src/pc/network/discord/discord.h b/src/pc/network/discord/discord.h index 25a86cc5..a9e0189b 100644 --- a/src/pc/network/discord/discord.h +++ b/src/pc/network/discord/discord.h @@ -29,6 +29,7 @@ void discord_fatal(int rc); extern struct NetworkSystem gNetworkSystemDiscord; extern bool gDiscordInitialized; extern bool gDiscordFailed; +extern bool gDiscordReconnecting; struct DiscordApplication { struct IDiscordCore* core; diff --git a/src/pc/network/network.c b/src/pc/network/network.c index f695952c..9ddc1db0 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -59,6 +59,11 @@ u8 gDebugPacketIdBuffer[256] = { 0xFF }; u8 gDebugPacketSentBuffer[256] = { 0 }; u8 gDebugPacketOnBuffer = 0; +u32 gNetworkStartupTimer = 0; +u32 sNetworkReconnectTimer = 0; +u32 sNetworkRehostTimer = 0; +enum NetworkSystemType sNetworkReconnectType = NT_NONE; + struct StringLinkedList gRegisteredMods = { 0 }; struct ServerSettings gServerSettings = { @@ -88,6 +93,7 @@ bool network_init(enum NetworkType inNetworkType) { // reset override hide hud extern u8 gOverrideHideHud; gOverrideHideHud = 0; + gNetworkStartupTimer = 5 * 30; // sanity check network system if (gNetworkSystem == NULL) { @@ -287,6 +293,9 @@ void network_send_to(u8 localIndex, struct Packet* p) { // send if (!tooManyPackets) { + if (p->keepSendingAfterDisconnect) { + localIndex = 0; // Force this type of packet to use the saved addr + } int rc = gNetworkSystem->send(localIndex, p->addr, p->buffer, p->cursor + sizeof(u32)); if (rc == SOCKET_ERROR) { LOG_ERROR("send error %d", rc); return; } } @@ -377,6 +386,76 @@ void* network_duplicate_address(u8 localIndex) { return gNetworkSystem->dup_addr(localIndex); } +void network_reset_reconnect_and_rehost(void) { + gNetworkStartupTimer = 0; + sNetworkReconnectTimer = 0; + sNetworkRehostTimer = 0; + sNetworkReconnectType = NT_NONE; + gDiscordReconnecting = false; +} + +void network_reconnect_begin(void) { + if (sNetworkReconnectTimer > 0) { + return; + } + + sNetworkReconnectTimer = 2 * 30; + sNetworkReconnectType = (gNetworkSystem == &gNetworkSystemDiscord) + ? NS_DISCORD + : NS_SOCKET; + + gDiscordReconnecting = true; + network_shutdown(false, false, false); + gDiscordReconnecting = false; + + djui_connect_menu_open(); +} + +static void network_reconnect_update(void) { + if (sNetworkReconnectTimer <= 0) { return; } + if (--sNetworkReconnectTimer != 0) { return; } + + if (sNetworkReconnectType == NS_SOCKET) { + network_set_system(NS_SOCKET); + } + + gDiscordReconnecting = true; + network_init(NT_CLIENT); + gDiscordReconnecting = false; + + network_send_mod_list_request(); +} + +bool network_is_reconnecting(void) { + return sNetworkReconnectTimer > 0; +} + +void network_rehost_begin(void) { + for (int i = 1; i < MAX_PLAYERS; i++) { + struct NetworkPlayer* np = &gNetworkPlayers[i]; + if (!np->connected) { continue; } + + network_send_kick(i, EKT_REJOIN); + network_player_disconnected(i); + } + + gDiscordReconnecting = true; + network_shutdown(false, false, false); + gDiscordReconnecting = false; + + sNetworkRehostTimer = 2; +} + +static void network_rehost_update(void) { + extern void djui_panel_do_host(void); + if (sNetworkRehostTimer <= 0) { return; } + if (--sNetworkRehostTimer != 0) { return; } + + gDiscordReconnecting = true; + djui_panel_do_host(); + gDiscordReconnecting = false; +} + static void network_update_area_timer(void) { bool brokenClock = false; #ifdef DEVELOPMENT @@ -410,6 +489,14 @@ static void network_update_area_timer(void) { } void network_update(void) { + + if (gNetworkStartupTimer > 0) { + gNetworkStartupTimer--; + } + + network_rehost_update(); + network_reconnect_update(); + // check for level loaded event if (networkLoadingLevel < LOADING_LEVEL_THRESHOLD) { networkLoadingLevel++; @@ -499,7 +586,9 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup) { } gNetworkPlayerServer = NULL; - gNetworkType = NT_NONE; + if (sNetworkReconnectTimer <= 0 || sNetworkReconnectType != NS_DISCORD) { + gNetworkType = NT_NONE; + } #ifdef DISCORD_SDK diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 40966af0..8d28b13a 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -88,6 +88,7 @@ extern u16 gNetworkRequestLocationTimer; extern u8 gDebugPacketIdBuffer[]; extern u8 gDebugPacketSentBuffer[]; extern u8 gDebugPacketOnBuffer; +extern u32 gNetworkStartupTimer; // network.c void network_set_system(enum NetworkSystemType nsType); @@ -99,6 +100,10 @@ void network_send_to(u8 localIndex, struct Packet* p); void network_send(struct Packet* p); void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength); void* network_duplicate_address(u8 localIndex); +void network_reset_reconnect_and_rehost(void); +void network_reconnect_begin(void); +bool network_is_reconnecting(void); +void network_rehost_begin(void); void network_update(void); void network_register_mod(char* modName); void network_shutdown(bool sendLeaving, bool exiting, bool popup); diff --git a/src/pc/network/network_player.c b/src/pc/network/network_player.c index da815d4e..088425cd 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -148,9 +148,6 @@ void network_player_palette_to_color(struct NetworkPlayer *np, enum PlayerParts void network_player_update(void) { for (s32 i = 0; i < MAX_PLAYERS; i++) { struct NetworkPlayer *np = &gNetworkPlayers[i]; - if (np->connected && gMarioStates[np->localIndex].interactObj) { - //LOG_INFO("%u :: %u", np->globalIndex, gMarioStates[np->localIndex].interactObj->oSyncID); // DO NOT COMMIT - } if (!np->connected && i > 0) { continue; } network_player_update_model(i); diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index 12c328c2..09aa3f75 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -130,6 +130,10 @@ void packet_receive(struct Packet* p) { // refuse packets from unknown players other than join request if (gNetworkType == NT_SERVER && p->localIndex == UNKNOWN_LOCAL_INDEX && !network_allow_unknown_local_index(packetType)) { + if (gNetworkStartupTimer > 0) { + LOG_INFO("refusing packet from unknown player on startup, packetType: %d", packetType); + return; + } if (packetType != PACKET_PLAYER) { LOG_INFO("closing connection for packetType: %d", packetType); network_send_kick(0, EKT_CLOSE_CONNECTION); diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index 03b09c19..8dfe3d78 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -96,6 +96,7 @@ struct Packet { bool levelAreaMustMatch; bool levelMustMatch; bool requestBroadcast; + bool keepSendingAfterDisconnect; u8 destGlobalId; u16 seqId; bool sent; @@ -114,6 +115,7 @@ enum KickReasonType { EKT_FULL_PARTY, EKT_KICKED, EKT_BANNED, + EKT_REJOIN, }; enum ChatConfirmCommand { diff --git a/src/pc/network/packets/packet_kick.c b/src/pc/network/packets/packet_kick.c index 9d44939f..c69106ac 100644 --- a/src/pc/network/packets/packet_kick.c +++ b/src/pc/network/packets/packet_kick.c @@ -2,11 +2,15 @@ #include "../network.h" #include "pc/debuglog.h" #include "pc/djui/djui.h" +#include "pc/utils/misc.h" + +f32 lastReconnectTime = -9999999; void network_send_kick(u8 localIndex, enum KickReasonType kickReason) { u8 kickReasonType = kickReason; struct Packet p = { 0 }; - packet_init(&p, PACKET_KICK, false, PLMT_NONE); + packet_init(&p, PACKET_KICK, true, PLMT_NONE); + p.keepSendingAfterDisconnect = (kickReason == EKT_REJOIN); packet_write(&p, &kickReasonType, sizeof(u8)); network_send_to(localIndex, &p); } @@ -30,7 +34,17 @@ void network_receive_kick(struct Packet* p) { case EKT_FULL_PARTY: djui_popup_create("\\#ffa0a0\\Disconnected:\\#c8c8c8\\ The party is full.", 1); break; case EKT_KICKED: djui_popup_create("\\#ffa0a0\\Disconnected:\\#c8c8c8\\ The server kicked you.", 1); break; case EKT_BANNED: djui_popup_create("\\#ffa0a0\\Disconnected:\\#c8c8c8\\ The server banned you.", 1); break; + case EKT_REJOIN: djui_popup_create("\\#ffa0a0\\Disconnected:\\#c8c8c8\\ Rejoining...", 1); break; default: djui_popup_create("\\#ffa0a0\\Disconnected:\\#c8c8c8\\ Host has closed the connection.", 1); break; } - network_shutdown(false, false, false); + + if (kickReason == EKT_REJOIN) { + f32 now = clock_elapsed(); + if ((now - lastReconnectTime) > 3) { + lastReconnectTime = now; + network_reconnect_begin(); + } + } else { + network_shutdown(false, false, false); + } } diff --git a/src/pc/network/packets/packet_read_write.c b/src/pc/network/packets/packet_read_write.c index 053303bd..f6169f0f 100644 --- a/src/pc/network/packets/packet_read_write.c +++ b/src/pc/network/packets/packet_read_write.c @@ -27,6 +27,7 @@ void packet_init(struct Packet* packet, enum PacketType packetType, bool reliabl packet->orderedFromGlobalId = sOrderedPackets ? gNetworkPlayerLocal->globalIndex : 0; packet->orderedGroupId = sOrderedPackets ? sCurrentOrderedGroupId : 0; packet->orderedSeqId = 0; + packet->keepSendingAfterDisconnect = false; packet_write(packet, &packetType, sizeof(u8)); diff --git a/src/pc/network/packets/packet_reliable.c b/src/pc/network/packets/packet_reliable.c index 45fc6849..6c79b73d 100644 --- a/src/pc/network/packets/packet_reliable.c +++ b/src/pc/network/packets/packet_reliable.c @@ -35,7 +35,14 @@ static void remove_node_from_list(struct PacketLinkedList* node) { } void network_forget_all_reliable(void) { - while (head != NULL) { remove_node_from_list(head); } + struct PacketLinkedList* node = head; + while (node != NULL) { + struct PacketLinkedList* next = node->next; + if (!node->p.keepSendingAfterDisconnect) { + remove_node_from_list(head); + } + node = next; + } } void network_forget_all_reliable_from(u8 localIndex) { @@ -44,7 +51,9 @@ void network_forget_all_reliable_from(u8 localIndex) { while (node != NULL) { struct PacketLinkedList* next = node->next; if (node->p.localIndex == localIndex) { - remove_node_from_list(node); + if (!node->p.keepSendingAfterDisconnect) { + remove_node_from_list(node); + } } node = next; }