Allow the ability to change server settings/mods while hosting

This commit is contained in:
MysterD 2023-03-29 17:36:13 -07:00
parent 2acb51b314
commit 341953390c
17 changed files with 189 additions and 24 deletions

View file

@ -185,7 +185,6 @@ const Gfx dl_font_normal_display_list[] = {
static void djui_font_normal_render_char(char c) { static void djui_font_normal_render_char(char c) {
extern const u8* const font_normal_chars[]; extern const u8* const font_normal_chars[];
// replace undisplayable characters // replace undisplayable characters
//if ((u8)c < ' ' || (u8)c > ('~' + 3)) { c = '?'; }
if (!djui_font_valid_smcode(c)) { c = '?'; } if (!djui_font_valid_smcode(c)) { c = '?'; }
if (c == ' ') { return; } if (c == ' ') { return; }
void* fontChar = (void*)font_normal_chars[(u8)c - '!']; void* fontChar = (void*)font_normal_chars[(u8)c - '!'];

View file

@ -56,14 +56,22 @@ static void djui_panel_host_do_host(struct DjuiBase* caller) {
} }
configHostPort = atoi(sInputboxPort->buffer); 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) { void djui_panel_host_create(struct DjuiBase* caller) {
f32 bodyHeight = 32 * 4 + 64 * 4 + 16 * 5; f32 bodyHeight = 32 * 4 + 64 * 4 + 16 * 5;
struct DjuiBase* defaultBase = NULL; 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); struct DjuiFlowLayout* body = (struct DjuiFlowLayout*)djui_three_panel_get_body(panel);
{ {
#ifdef DISCORD_SDK #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_type(&selectionbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&selectionbox1->base, 1.0f, 32); djui_base_set_size(&selectionbox1->base, 1.0f, 32);
djui_interactable_hook_value_change(&selectionbox1->base, djui_panel_host_network_system_change); 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 #endif
struct DjuiRect* rect1 = djui_rect_create(&body->base); 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_color(&text1->base, 200, 200, 200, 255);
djui_base_set_size(&text1->base, 0.485f, 64); djui_base_set_size(&text1->base, 0.485f, 64);
djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); 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); struct DjuiInputbox* inputbox1 = djui_inputbox_create(&rect1->base, 32);
djui_base_set_size_type(&inputbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); 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_size(&rect3->base, 1.0f, 64);
djui_base_set_color(&rect3->base, 0, 0, 0, 0); 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_type(&button1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button1->base, 0.485f, 64); djui_base_set_size(&button1->base, 0.485f, 64);
djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); djui_base_set_alignment(&button1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
djui_button_set_style(button1, 1); djui_button_set_style(button1, 1);
djui_interactable_hook_click(&button1->base, djui_panel_menu_back); 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_type(&button2->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
djui_base_set_size(&button2->base, 0.485f, 64); djui_base_set_size(&button2->base, 0.485f, 64);
djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP);
djui_interactable_hook_click(&button2->base, djui_panel_host_do_host); djui_interactable_hook_click(&button2->base, djui_panel_host_do_host);
defaultBase = &button2->base;
defaultBase = (gNetworkType == NT_SERVER)
? &button1->base
: &button2->base;
} }
} }

View file

@ -27,12 +27,13 @@ Direct connections \\#ffa0a0\\require you\\#c8c8c8\\ to configure port forwardin
Forward port '\\#d0d0ff\\%d\\#c8c8c8\\' for UDP.\ 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); stop_demo(NULL);
djui_panel_shutdown(); djui_panel_shutdown();
extern s16 gCurrSaveFileNum; extern s16 gCurrSaveFileNum;
gCurrSaveFileNum = configHostSaveSlot; gCurrSaveFileNum = configHostSaveSlot;
update_all_mario_stars(); update_all_mario_stars();
#ifndef DISCORD_SDK #ifndef DISCORD_SDK
configNetworkSystem = 1; configNetworkSystem = 1;
network_set_system(NS_SOCKET); 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); network_set_system(NS_SOCKET);
} }
#endif #endif
network_init(NT_SERVER); network_init(NT_SERVER);
djui_panel_modlist_create(NULL); djui_panel_modlist_create(NULL);
fake_lvl_init_from_save_file(); fake_lvl_init_from_save_file();
extern s16 gChangeLevelTransition; extern s16 gChangeLevelTransition;
gChangeLevelTransition = gLevelValues.entryLevel; gChangeLevelTransition = gLevelValues.entryLevel;
if (gMarioState->marioObj) vec3f_copy(gMarioState->marioObj->header.gfx.cameraToObject, gGlobalSoundSource); if (gMarioState->marioObj) vec3f_copy(gMarioState->marioObj->header.gfx.cameraToObject, gGlobalSoundSource);
play_character_sound(gMarioState, CHAR_SOUND_OKEY_DOKEY); play_character_sound(gMarioState, CHAR_SOUND_OKEY_DOKEY);
extern void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue); extern void play_transition(s16 transType, s16 time, u8 red, u8 green, u8 blue);
play_transition(0x09, 0x14, 0x00, 0x00, 0x00); 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) { void djui_panel_host_message_create(struct DjuiBase* caller) {
f32 warningLines = 0; f32 warningLines = 0;
char* warningMessage = NULL; char* warningMessage = NULL;

View file

@ -149,6 +149,7 @@ void djui_panel_join_do_join(struct DjuiBase* caller) {
djui_inputbox_select_all(sInputboxIp); djui_inputbox_select_all(sInputboxIp);
return; return;
} }
network_reset_reconnect_and_rehost();
djui_panel_join_ip_text_set_new(); djui_panel_join_ip_text_set_new();
network_set_system(NS_SOCKET); network_set_system(NS_SOCKET);
network_init(NT_CLIENT); network_init(NT_CLIENT);

View file

@ -16,6 +16,8 @@ void djui_panel_join_message_error(char* message) {
} }
void djui_panel_join_message_cancel(struct DjuiBase* caller) { void djui_panel_join_message_cancel(struct DjuiBase* caller) {
if (network_is_reconnecting()) { return; }
network_reset_reconnect_and_rehost();
network_shutdown(true, false, false); network_shutdown(true, false, false);
djui_panel_menu_back(caller); djui_panel_menu_back(caller);
} }

View file

@ -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) { static void djui_panel_pause_quit_yes(UNUSED struct DjuiBase* caller) {
network_reset_reconnect_and_rehost();
network_shutdown(true, false, false); 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) { void djui_panel_pause_create(struct DjuiBase* caller) {
if (gDjuiChatBoxFocus) { djui_chat_box_toggle(); } 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 (gServerSettings.enableCheats) { bodyHeight += 64 + 16; }
if (gNetworkType == NT_SERVER) { bodyHeight += 64 + 16; }
struct DjuiBase* defaultBase = NULL; struct DjuiBase* defaultBase = NULL;
struct DjuiThreePanel* panel = djui_panel_menu_create(bodyHeight, "\\#ff0800\\P\\#1be700\\A\\#00b3ff\\U\\#ffef00\\S\\#ff0800\\E"); 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_base_set_size(&button5->base, 1.0f, 64);
djui_interactable_hook_click(&button5->base, djui_panel_pause_resume); djui_interactable_hook_click(&button5->base, djui_panel_pause_resume);
struct DjuiButton* button6;
if (gNetworkType == NT_SERVER) { if (gNetworkType == NT_SERVER) {
button6 = djui_button_create(&body->base, "Stop Hosting"); struct DjuiButton* button6 = djui_button_create(&body->base, "Server Settings");
} else { djui_base_set_size_type(&button6->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
button6 = djui_button_create(&body->base, "Disconnect"); 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); struct DjuiButton* button7;
djui_interactable_hook_click(&button6->base, djui_panel_pause_quit); if (gNetworkType == NT_SERVER) {
djui_button_set_style(button6, 1); 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); djui_panel_add(caller, &panel->base, defaultBase);

View file

@ -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!"); LOGFILE_ERROR(LFT_DISCORD, "Joined lobby when already connected somewhere!");
return; return;
} }
network_reset_reconnect_and_rehost();
network_init(NT_CLIENT); network_init(NT_CLIENT);
gCurActivity.type = DiscordActivityType_Playing; gCurActivity.type = DiscordActivityType_Playing;

View file

@ -22,6 +22,7 @@ struct DiscordApplication app = { 0 };
bool gDiscordInitialized = false; bool gDiscordInitialized = false;
bool gDiscordFailed = false; bool gDiscordFailed = false;
bool alreadyRun = false; bool alreadyRun = false;
bool gDiscordReconnecting = false;
static void discord_sdk_log_callback(UNUSED void* hook_data, enum EDiscordLogLevel level, const char* message) { 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); 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) { static bool ns_discord_initialize(enum NetworkType networkType) {
if (gDiscordReconnecting) { return true; }
#ifdef DEBUG #ifdef DEBUG
set_instance_env_variable(); set_instance_env_variable();
#endif #endif
@ -179,6 +181,7 @@ static bool ns_discord_initialize(enum NetworkType networkType) {
} }
static void ns_discord_shutdown(void) { static void ns_discord_shutdown(void) {
if (gDiscordReconnecting) { return; }
if (!gDiscordInitialized) { return; } if (!gDiscordInitialized) { return; }
discord_lobby_leave(); discord_lobby_leave();
gActivityLock = false; gActivityLock = false;

View file

@ -29,6 +29,7 @@ void discord_fatal(int rc);
extern struct NetworkSystem gNetworkSystemDiscord; extern struct NetworkSystem gNetworkSystemDiscord;
extern bool gDiscordInitialized; extern bool gDiscordInitialized;
extern bool gDiscordFailed; extern bool gDiscordFailed;
extern bool gDiscordReconnecting;
struct DiscordApplication { struct DiscordApplication {
struct IDiscordCore* core; struct IDiscordCore* core;

View file

@ -59,6 +59,11 @@ u8 gDebugPacketIdBuffer[256] = { 0xFF };
u8 gDebugPacketSentBuffer[256] = { 0 }; u8 gDebugPacketSentBuffer[256] = { 0 };
u8 gDebugPacketOnBuffer = 0; u8 gDebugPacketOnBuffer = 0;
u32 gNetworkStartupTimer = 0;
u32 sNetworkReconnectTimer = 0;
u32 sNetworkRehostTimer = 0;
enum NetworkSystemType sNetworkReconnectType = NT_NONE;
struct StringLinkedList gRegisteredMods = { 0 }; struct StringLinkedList gRegisteredMods = { 0 };
struct ServerSettings gServerSettings = { struct ServerSettings gServerSettings = {
@ -88,6 +93,7 @@ bool network_init(enum NetworkType inNetworkType) {
// reset override hide hud // reset override hide hud
extern u8 gOverrideHideHud; extern u8 gOverrideHideHud;
gOverrideHideHud = 0; gOverrideHideHud = 0;
gNetworkStartupTimer = 5 * 30;
// sanity check network system // sanity check network system
if (gNetworkSystem == NULL) { if (gNetworkSystem == NULL) {
@ -287,6 +293,9 @@ void network_send_to(u8 localIndex, struct Packet* p) {
// send // send
if (!tooManyPackets) { 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)); int rc = gNetworkSystem->send(localIndex, p->addr, p->buffer, p->cursor + sizeof(u32));
if (rc == SOCKET_ERROR) { LOG_ERROR("send error %d", rc); return; } 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); 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) { static void network_update_area_timer(void) {
bool brokenClock = false; bool brokenClock = false;
#ifdef DEVELOPMENT #ifdef DEVELOPMENT
@ -410,6 +489,14 @@ static void network_update_area_timer(void) {
} }
void network_update(void) { void network_update(void) {
if (gNetworkStartupTimer > 0) {
gNetworkStartupTimer--;
}
network_rehost_update();
network_reconnect_update();
// check for level loaded event // check for level loaded event
if (networkLoadingLevel < LOADING_LEVEL_THRESHOLD) { if (networkLoadingLevel < LOADING_LEVEL_THRESHOLD) {
networkLoadingLevel++; networkLoadingLevel++;
@ -499,7 +586,9 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup) {
} }
gNetworkPlayerServer = NULL; gNetworkPlayerServer = NULL;
gNetworkType = NT_NONE; if (sNetworkReconnectTimer <= 0 || sNetworkReconnectType != NS_DISCORD) {
gNetworkType = NT_NONE;
}
#ifdef DISCORD_SDK #ifdef DISCORD_SDK

View file

@ -88,6 +88,7 @@ extern u16 gNetworkRequestLocationTimer;
extern u8 gDebugPacketIdBuffer[]; extern u8 gDebugPacketIdBuffer[];
extern u8 gDebugPacketSentBuffer[]; extern u8 gDebugPacketSentBuffer[];
extern u8 gDebugPacketOnBuffer; extern u8 gDebugPacketOnBuffer;
extern u32 gNetworkStartupTimer;
// network.c // network.c
void network_set_system(enum NetworkSystemType nsType); 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_send(struct Packet* p);
void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength); void network_receive(u8 localIndex, void* addr, u8* data, u16 dataLength);
void* network_duplicate_address(u8 localIndex); 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_update(void);
void network_register_mod(char* modName); void network_register_mod(char* modName);
void network_shutdown(bool sendLeaving, bool exiting, bool popup); void network_shutdown(bool sendLeaving, bool exiting, bool popup);

View file

@ -148,9 +148,6 @@ void network_player_palette_to_color(struct NetworkPlayer *np, enum PlayerParts
void network_player_update(void) { void network_player_update(void) {
for (s32 i = 0; i < MAX_PLAYERS; i++) { for (s32 i = 0; i < MAX_PLAYERS; i++) {
struct NetworkPlayer *np = &gNetworkPlayers[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; } if (!np->connected && i > 0) { continue; }
network_player_update_model(i); network_player_update_model(i);

View file

@ -130,6 +130,10 @@ void packet_receive(struct Packet* p) {
// refuse packets from unknown players other than join request // 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 (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) { if (packetType != PACKET_PLAYER) {
LOG_INFO("closing connection for packetType: %d", packetType); LOG_INFO("closing connection for packetType: %d", packetType);
network_send_kick(0, EKT_CLOSE_CONNECTION); network_send_kick(0, EKT_CLOSE_CONNECTION);

View file

@ -96,6 +96,7 @@ struct Packet {
bool levelAreaMustMatch; bool levelAreaMustMatch;
bool levelMustMatch; bool levelMustMatch;
bool requestBroadcast; bool requestBroadcast;
bool keepSendingAfterDisconnect;
u8 destGlobalId; u8 destGlobalId;
u16 seqId; u16 seqId;
bool sent; bool sent;
@ -114,6 +115,7 @@ enum KickReasonType {
EKT_FULL_PARTY, EKT_FULL_PARTY,
EKT_KICKED, EKT_KICKED,
EKT_BANNED, EKT_BANNED,
EKT_REJOIN,
}; };
enum ChatConfirmCommand { enum ChatConfirmCommand {

View file

@ -2,11 +2,15 @@
#include "../network.h" #include "../network.h"
#include "pc/debuglog.h" #include "pc/debuglog.h"
#include "pc/djui/djui.h" #include "pc/djui/djui.h"
#include "pc/utils/misc.h"
f32 lastReconnectTime = -9999999;
void network_send_kick(u8 localIndex, enum KickReasonType kickReason) { void network_send_kick(u8 localIndex, enum KickReasonType kickReason) {
u8 kickReasonType = kickReason; u8 kickReasonType = kickReason;
struct Packet p = { 0 }; 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)); packet_write(&p, &kickReasonType, sizeof(u8));
network_send_to(localIndex, &p); 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_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_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_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; 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);
}
} }

View file

@ -27,6 +27,7 @@ void packet_init(struct Packet* packet, enum PacketType packetType, bool reliabl
packet->orderedFromGlobalId = sOrderedPackets ? gNetworkPlayerLocal->globalIndex : 0; packet->orderedFromGlobalId = sOrderedPackets ? gNetworkPlayerLocal->globalIndex : 0;
packet->orderedGroupId = sOrderedPackets ? sCurrentOrderedGroupId : 0; packet->orderedGroupId = sOrderedPackets ? sCurrentOrderedGroupId : 0;
packet->orderedSeqId = 0; packet->orderedSeqId = 0;
packet->keepSendingAfterDisconnect = false;
packet_write(packet, &packetType, sizeof(u8)); packet_write(packet, &packetType, sizeof(u8));

View file

@ -35,7 +35,14 @@ static void remove_node_from_list(struct PacketLinkedList* node) {
} }
void network_forget_all_reliable(void) { 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) { void network_forget_all_reliable_from(u8 localIndex) {
@ -44,7 +51,9 @@ void network_forget_all_reliable_from(u8 localIndex) {
while (node != NULL) { while (node != NULL) {
struct PacketLinkedList* next = node->next; struct PacketLinkedList* next = node->next;
if (node->p.localIndex == localIndex) { if (node->p.localIndex == localIndex) {
remove_node_from_list(node); if (!node->p.keepSendingAfterDisconnect) {
remove_node_from_list(node);
}
} }
node = next; node = next;
} }