diff --git a/Makefile b/Makefile index 5297a2a2..e2c754fe 100644 --- a/Makefile +++ b/Makefile @@ -1093,6 +1093,12 @@ ifeq ($(DISCORD_SDK),1) CFLAGS += -DDISCORD_SDK endif +# Check for COOPNET option +ifeq ($(COOPNET),1) + CC_CHECK_CFLAGS += -DCOOPNET + CFLAGS += -DCOOPNET +endif + # Check for development option ifeq ($(DEVELOPMENT),1) CC_CHECK_CFLAGS += -DDEVELOPMENT diff --git a/src/pc/djui/djui_base.h b/src/pc/djui/djui_base.h index 0c40ea0b..6f8e6eff 100644 --- a/src/pc/djui/djui_base.h +++ b/src/pc/djui/djui_base.h @@ -41,7 +41,7 @@ struct DjuiBase { struct DjuiInteractable* interactable; bool addChildrenToHead; bool abandonAfterChildRenderFail; - s32 tag; + s64 tag; bool bTag; void (*get_cursor_hover_location)(struct DjuiBase*, f32* x, f32* y); void (*on_child_render)(struct DjuiBase*, struct DjuiBase*); diff --git a/src/pc/djui/djui_panel_join.c b/src/pc/djui/djui_panel_join.c index bdd7fb01..bc076ba5 100644 --- a/src/pc/djui/djui_panel_join.c +++ b/src/pc/djui/djui_panel_join.c @@ -6,11 +6,13 @@ #include "djui_panel_modlist.h" #include "src/pc/network/network.h" #include "src/pc/network/socket/socket.h" +#include "src/pc/network/coopnet/coopnet.h" #include "src/pc/network/socket/domain_res.h" #include "src/pc/utils/misc.h" #include "src/pc/configfile.h" #include "src/pc/debuglog.h" +static struct DjuiFlowLayout* sLobbyLayout = NULL; static struct DjuiInputbox* sInputboxIp = NULL; static bool djui_panel_join_ip_parse_numbers(char** msg) { @@ -143,17 +145,48 @@ void djui_panel_join_do_join(struct DjuiBase* caller) { } network_reset_reconnect_and_rehost(); djui_panel_join_ip_text_set_new(); - network_set_system(NS_COOPNET); // DO NOT COMMIT + network_set_system(NS_SOCKET); network_init(NT_CLIENT); djui_panel_join_message_create(caller); } +#ifdef COOPNET +void djui_panel_join_lobby(struct DjuiBase* caller) { + gCoopNetDesiredLobby = (uint64_t)caller->tag; + network_reset_reconnect_and_rehost(); + network_set_system(NS_COOPNET); + network_init(NT_CLIENT); + djui_panel_join_message_create(caller); +} + +void djui_panel_join_query(uint64_t aLobbyId, uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, const char* aGame, const char* aVersion, const char* aTitle) { + char text[256]; + snprintf(text, 255, "%s - %u/%u", aTitle, aConnections, aMaxConnections); + + bool btrue = TRUE; + struct DjuiBase* layoutBase = &sLobbyLayout->base; + struct DjuiButton* button = djui_button_create(layoutBase, text, DJUI_BUTTON_STYLE_NORMAL, djui_panel_join_lobby); + button->base.tag = (s64)aLobbyId; + djui_base_set_size_type(&button->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&button->base, 1.0f, 32); +} +#endif + void djui_panel_join_create(struct DjuiBase* caller) { +#ifdef COOPNET + ns_coopnet_query(djui_panel_join_query); +#endif + struct DjuiBase* defaultBase = NULL; struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(JOIN, JOIN_TITLE)); struct DjuiBase* body = djui_three_panel_get_body(panel); { + + struct DjuiPaginated* paginated = djui_paginated_create(body, 8); + sLobbyLayout = paginated->layout; + + /* #ifdef DISCORD_SDK struct DjuiText* text1 = djui_text_create(body, DLANG(JOIN, JOIN_DISCORD)); djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); @@ -176,7 +209,7 @@ void djui_panel_join_create(struct DjuiBase* caller) { u16 directLines = djui_text_count_lines(text2, 12); f32 directTextHeight = 32 * 0.8125f * directLines + 8; djui_base_set_size(&text2->base, 1.0f, directTextHeight); - djui_base_set_color(&text2->base, 200, 200, 200, 255); + djui_base_set_color(&text2->base, 200, 200, 200, 255);*/ struct DjuiInputbox* inputbox1 = djui_inputbox_create(body, 256); djui_base_set_size_type(&inputbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); diff --git a/src/pc/network/coopnet/coopnet.c b/src/pc/network/coopnet/coopnet.c index 322150e9..d39e7d60 100644 --- a/src/pc/network/coopnet/coopnet.c +++ b/src/pc/network/coopnet/coopnet.c @@ -1,12 +1,16 @@ #include "libcoopnet.h" #include "coopnet.h" #include "pc/network/network.h" +#include "pc/network/version.h" #include "pc/debuglog.h" #ifdef COOPNET -#define HOST "localhost" -#define PORT 34197 +#define CN_HOST "localhost" +#define CN_PORT 34197 +#define CN_GAME_STR "sm64ex-coop" + +uint64_t gCoopNetDesiredLobby = 0; static uint64_t sLocalUserId = 0; static uint64_t sLocalLobbyId = 0; @@ -14,6 +18,14 @@ static uint64_t sLocalLobbyOwnerId = 0; static uint64_t sNetworkUserIds[MAX_PLAYERS] = { 0 }; static enum NetworkType sNetworkType; +static CoopNetRc coopnet_initialize(void); + +void ns_coopnet_query(QueryCallbackPtr callback) { + gCoopNetCallbacks.OnLobbyListGot = callback; + if (coopnet_initialize() != COOPNET_OK) { return; } + coopnet_lobby_list_get(CN_GAME_STR); +} + static u8 coopnet_user_id_to_local_index(uint64_t userId) { for (int i = 1; i < MAX_PLAYERS; i++) { if (gNetworkPlayers[i].connected && sNetworkUserIds[i] == userId) { @@ -25,11 +37,6 @@ static u8 coopnet_user_id_to_local_index(uint64_t userId) { static void coopnet_on_connected(uint64_t userId) { sLocalUserId = userId; - if (sNetworkType == NT_SERVER) { - coopnet_lobby_create("sm64ex-coop", "beta 999", "n/a", 16); - } else { - coopnet_lobby_join(1); - } } static void coopnet_on_peer_disconnected(uint64_t peerId) { @@ -50,7 +57,7 @@ static void coopnet_on_lobby_joined(uint64_t lobbyId, uint64_t userId, uint64_t sNetworkUserIds[0] = ownerId; sLocalLobbyId = lobbyId; sLocalLobbyOwnerId = ownerId; - if (userId == sLocalUserId && sNetworkType == NT_CLIENT) { + if (userId == sLocalUserId && gNetworkType == NT_CLIENT) { network_send_mod_list_request(); } } @@ -63,18 +70,10 @@ static void coopnet_on_lobby_left(uint64_t lobbyId, uint64_t userId) { } static bool ns_coopnet_initialize(enum NetworkType networkType) { - if (coopnet_is_connected()) { - coopnet_shutdown(); - } - - gCoopNetCallbacks.OnConnected = coopnet_on_connected; - gCoopNetCallbacks.OnReceive = coopnet_on_receive; - gCoopNetCallbacks.OnLobbyJoined = coopnet_on_lobby_joined; - gCoopNetCallbacks.OnLobbyLeft = coopnet_on_lobby_left; - gCoopNetCallbacks.OnPeerDisconnected = coopnet_on_peer_disconnected; sNetworkType = networkType; - - return (coopnet_begin(HOST, PORT) == COOPNET_OK); + return coopnet_is_connected() + ? true + : (coopnet_initialize() == COOPNET_OK); } static s64 ns_coopnet_get_id(u8 localIndex) { @@ -114,8 +113,24 @@ static bool ns_coopnet_match_addr(void* addr1, void* addr2) { return !memcmp(addr1, addr2, sizeof(u64)); } -static void ns_coopnet_update(void) { +bool ns_coopnet_is_connected(void) { + return coopnet_is_connected(); +} + +void ns_coopnet_update(void) { + if (!coopnet_is_connected()) { return; } + coopnet_update(); + if (gNetworkType != NT_NONE && sNetworkType != NT_NONE) { + if (sNetworkType == NT_SERVER) { + LOG_INFO("Create lobby"); + coopnet_lobby_create(CN_GAME_STR, get_version(), "The lobby's title", configAmountofPlayers); + } else if (sNetworkType == NT_CLIENT) { + LOG_INFO("Join lobby"); + coopnet_lobby_join(gCoopNetDesiredLobby); + } + sNetworkType = NT_NONE; + } } static int ns_coopnet_network_send(u8 localIndex, void* address, u8* data, u16 dataLength) { @@ -130,9 +145,22 @@ static int ns_coopnet_network_send(u8 localIndex, void* address, u8* data, u16 d } static void ns_coopnet_shutdown(void) { + LOG_INFO("Coopnet shutdown!"); coopnet_shutdown(); } +static CoopNetRc coopnet_initialize(void) { + if (coopnet_is_connected()) { return COOPNET_OK; } + + gCoopNetCallbacks.OnConnected = coopnet_on_connected; + gCoopNetCallbacks.OnReceive = coopnet_on_receive; + gCoopNetCallbacks.OnLobbyJoined = coopnet_on_lobby_joined; + gCoopNetCallbacks.OnLobbyLeft = coopnet_on_lobby_left; + gCoopNetCallbacks.OnPeerDisconnected = coopnet_on_peer_disconnected; + + return coopnet_begin(CN_HOST, CN_PORT); +} + struct NetworkSystem gNetworkSystemCoopNet = { .initialize = ns_coopnet_initialize, .get_id = ns_coopnet_get_id, diff --git a/src/pc/network/coopnet/coopnet.h b/src/pc/network/coopnet/coopnet.h index a6804e80..ab55ae01 100644 --- a/src/pc/network/coopnet/coopnet.h +++ b/src/pc/network/coopnet/coopnet.h @@ -2,7 +2,13 @@ #define COOPNET_H #ifdef COOPNET +typedef void (*QueryCallbackPtr)(uint64_t aLobbyId, uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, const char* aGame, const char* aVersion, const char* aTitle); extern struct NetworkSystem gNetworkSystemCoopNet; +extern uint64_t gCoopNetDesiredLobby; + +void ns_coopnet_query(QueryCallbackPtr callback); +bool ns_coopnet_is_connected(void); +void ns_coopnet_update(void); #endif #endif \ No newline at end of file diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 39045a27..7a2fec19 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -517,6 +517,14 @@ static void network_update_area_timer(void) { } } +#ifdef COOPNET +void network_update_coopnet(void) { + if (gNetworkType != NT_NONE) { return; } + if (!ns_coopnet_is_connected()) { return; } + ns_coopnet_update(); +} +#endif + void network_update(void) { if (gNetworkStartupTimer > 0) { @@ -526,6 +534,10 @@ void network_update(void) { network_rehost_update(); network_reconnect_update(); +#ifdef COOPNET + network_update_coopnet(); +#endif + // check for level loaded event if (networkLoadingLevel < LOADING_LEVEL_THRESHOLD) { networkLoadingLevel++;