diff --git a/lang/English.ini b/lang/English.ini index 40fcadd6d..e0cf3deb3 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -19,6 +19,8 @@ IMPORT_MOD_SUCCESS = "\\#a0ffa0\\Imported mod\n\\#c8c8c8\\'@'" IMPORT_DYNOS_SUCCESS = "\\#a0ffa0\\Imported DynOS pack\n\\#c8c8c8\\'@'" IMPORT_FAIL = "\\#ffa0a0\\Failed to import\n\\#c8c8c8\\'@'" IMPORT_FAIL_INGAME = "\\#ffa0a0\\Can not import while in-game" +COOPNET_CONNECTION_FAILED = "\\#ffa0a0\\Could not connect to CoopNet!" +COOPNET_DISCONNECTED = "\\#ffa0a0\\Lost connection to CoopNet!" [CHAT] KICKING = "Kicking '@'!" diff --git a/lib/coopnet/include/libcoopnet.h b/lib/coopnet/include/libcoopnet.h index 3a760e06f..f38ef5c3c 100644 --- a/lib/coopnet/include/libcoopnet.h +++ b/lib/coopnet/include/libcoopnet.h @@ -20,16 +20,17 @@ enum MPacketErrorNumber { MERR_LOBBY_NOT_FOUND, MERR_LOBBY_JOIN_FULL, MERR_LOBBY_JOIN_FAILED, + MERR_LOBBY_PASSWORD_INCORRECT, MERR_MAX, }; typedef struct { void (*OnConnected)(uint64_t aUserId); void (*OnDisconnected)(void); - void (*OnLobbyCreated)(uint64_t aLobbyId, const char* aGame, const char* aVersion, const char* aTitle, uint16_t aMaxConnections); + void (*OnLobbyCreated)(uint64_t aLobbyId, const char* aGame, const char* aVersion, const char* aHostName, const char* aMode, uint16_t aMaxConnections); void (*OnLobbyJoined)(uint64_t aLobbyId, uint64_t aUserId, uint64_t aOwnerId); void (*OnLobbyLeft)(uint64_t aLobbyId, uint64_t aUserId); - void (*OnLobbyListGot)(uint64_t aLobbyId, uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, const char* aGame, const char* aVersion, const char* aTitle); + void (*OnLobbyListGot)(uint64_t aLobbyId, uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, const char* aGame, const char* aVersion, const char* aHostName, const char* aMode); void (*OnReceive)(uint64_t aFromUserId, const uint8_t* aData, uint64_t aSize); void (*OnError)(enum MPacketErrorNumber aErrorNumber); void (*OnPeerConnected)(uint64_t aPeerId); @@ -47,10 +48,10 @@ bool coopnet_is_connected(void); CoopNetRc coopnet_begin(const char* aHost, uint32_t aPort); CoopNetRc coopnet_shutdown(void); CoopNetRc coopnet_update(void); -CoopNetRc coopnet_lobby_create(const char* aGame, const char* aVersion, const char* aTitle, uint16_t aMaxConnections); -CoopNetRc coopnet_lobby_join(uint64_t aLobbyId); +CoopNetRc coopnet_lobby_create(const char* aGame, const char* aVersion, const char* aHostName, const char* aMode, uint16_t aMaxConnections, const char* aPassword); +CoopNetRc coopnet_lobby_join(uint64_t aLobbyId, const char* aPassword); CoopNetRc coopnet_lobby_leave(uint64_t aLobbyId); -CoopNetRc coopnet_lobby_list_get(const char* aGame); +CoopNetRc coopnet_lobby_list_get(const char* aGame, const char* aPassword); CoopNetRc coopnet_send(const uint8_t* aData, uint64_t aDataLength); CoopNetRc coopnet_send_to(uint64_t aPeerId, const uint8_t* aData, uint64_t aDataLength); CoopNetRc coopnet_unpeer(uint64_t aPeerId); diff --git a/lib/coopnet/linux/libcoopnet.a b/lib/coopnet/linux/libcoopnet.a index 98d1badbb..1b3822920 100644 Binary files a/lib/coopnet/linux/libcoopnet.a and b/lib/coopnet/linux/libcoopnet.a differ diff --git a/src/pc/djui/djui_panel_join.c b/src/pc/djui/djui_panel_join.c index 376d43002..a1ea1bf02 100644 --- a/src/pc/djui/djui_panel_join.c +++ b/src/pc/djui/djui_panel_join.c @@ -161,23 +161,23 @@ void djui_panel_join_lobby(struct DjuiBase* caller) { djui_panel_join_message_create(caller); } -void djui_panel_join_query(uint64_t aLobbyId, UNUSED uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, UNUSED const char* aGame, UNUSED const char* aVersion, const char* aTitle) { +void djui_panel_join_query(uint64_t aLobbyId, UNUSED uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, UNUSED const char* aGame, UNUSED const char* aVersion, const char* aHostName, const char* aMode) { char playerText[64]; snprintf(playerText, 63, "%u/%u", aConnections, aMaxConnections); struct DjuiBase* layoutBase = &sLobbyLayout->base; - struct DjuiLobbyEntry* entry = djui_lobby_entry_create(layoutBase, (char*)aTitle, "Super Mario 64", playerText, djui_panel_join_lobby); + struct DjuiLobbyEntry* entry = djui_lobby_entry_create(layoutBase, (char*)aHostName, (char*)aMode, playerText, djui_panel_join_lobby); entry->base.tag = (s64)aLobbyId; - struct DjuiPaginated* paginated = (struct DjuiPaginated*)layoutBase->parent; - djui_paginated_calculate_height(paginated); + /*struct DjuiPaginated* paginated = (struct DjuiPaginated*)layoutBase->parent; + djui_paginated_calculate_height(paginated);*/ } #endif void djui_panel_join_create(struct DjuiBase* caller) { #ifdef COOPNET - ns_coopnet_query(djui_panel_join_query); + ns_coopnet_query(djui_panel_join_query, ""); #endif struct DjuiBase* defaultBase = NULL; @@ -191,15 +191,15 @@ void djui_panel_join_create(struct DjuiBase* caller) { #if 0 struct DjuiBase* layoutBase = &sLobbyLayout->base; - for (int i = 0; i < 4; i++) { - djui_lobby_entry_create(layoutBase, "MysterD", "Super Mario 64", "15/16"); - djui_lobby_entry_create(layoutBase, "djoslin0", "Star Road", "1/16"); - djui_lobby_entry_create(layoutBase, "abcdefghijklmnopqrs", "Snowstorm Avalanche", "16/16"); - djui_lobby_entry_create(layoutBase, "Prince Frizzy", "Hide and Seek", "4/16"); - djui_lobby_entry_create(layoutBase, "Sunk", "Super Mario 74 (+EE)", "5/8"); + for (int i = 0; i < 1; i++) { + djui_lobby_entry_create(layoutBase, "MysterD", "Super Mario 64", "15/16", NULL); + djui_lobby_entry_create(layoutBase, "djoslin0", "Star Road", "1/16", NULL); + djui_lobby_entry_create(layoutBase, "abcdefghijklmnopqrs", "Snowstorm Avalanche", "16/16", NULL); + djui_lobby_entry_create(layoutBase, "Prince Frizzy", "Hide and Seek", "4/16", NULL); + djui_lobby_entry_create(layoutBase, "Sunk", "Super Mario 74 (+EE)", "5/8", NULL); } + djui_paginated_calculate_height(paginated); #endif - //djui_paginated_calculate_height(paginated); /* #ifdef DISCORD_SDK diff --git a/src/pc/network/coopnet/coopnet.c b/src/pc/network/coopnet/coopnet.c index d39e7d607..31b42d348 100644 --- a/src/pc/network/coopnet/coopnet.c +++ b/src/pc/network/coopnet/coopnet.c @@ -1,7 +1,10 @@ #include "libcoopnet.h" #include "coopnet.h" +#include "coopnet_id.h" #include "pc/network/network.h" #include "pc/network/version.h" +#include "pc/djui/djui_language.h" +#include "pc/djui/djui_popup.h" #include "pc/debuglog.h" #ifdef COOPNET @@ -12,31 +15,26 @@ uint64_t gCoopNetDesiredLobby = 0; -static uint64_t sLocalUserId = 0; static uint64_t sLocalLobbyId = 0; 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) { +void ns_coopnet_query(QueryCallbackPtr callback, const char* password) { 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) { - return i; - } - } - return UNKNOWN_LOCAL_INDEX; + coopnet_lobby_list_get(CN_GAME_STR, password); } static void coopnet_on_connected(uint64_t userId) { - sLocalUserId = userId; + coopnet_set_local_user_id(userId); +} + +static void coopnet_on_disconnected(void) { + LOG_INFO("Coopnet shutdown!"); + djui_popup_create(DLANG(NOTIF, COOPNET_DISCONNECTED), 2); + coopnet_shutdown(); } static void coopnet_on_peer_disconnected(uint64_t peerId) { @@ -47,24 +45,24 @@ static void coopnet_on_peer_disconnected(uint64_t peerId) { } static void coopnet_on_receive(uint64_t userId, const uint8_t* data, uint64_t dataLength) { - sNetworkUserIds[0] = userId; + coopnet_set_user_id(0, userId); u8 localIndex = coopnet_user_id_to_local_index(userId); network_receive(localIndex, &userId, (u8*)data, dataLength); } static void coopnet_on_lobby_joined(uint64_t lobbyId, uint64_t userId, uint64_t ownerId) { LOG_INFO("coopnet_on_lobby_joined!"); - sNetworkUserIds[0] = ownerId; + coopnet_set_user_id(0, ownerId); sLocalLobbyId = lobbyId; sLocalLobbyOwnerId = ownerId; - if (userId == sLocalUserId && gNetworkType == NT_CLIENT) { + if (userId == coopnet_get_local_user_id() && gNetworkType == NT_CLIENT) { network_send_mod_list_request(); } } static void coopnet_on_lobby_left(uint64_t lobbyId, uint64_t userId) { LOG_INFO("coopnet_on_lobby_left!"); - if (lobbyId == sLocalLobbyId && userId == sLocalUserId) { + if (lobbyId == sLocalLobbyId && userId == coopnet_get_local_user_id()) { network_shutdown(false, false, true); } } @@ -76,11 +74,6 @@ static bool ns_coopnet_initialize(enum NetworkType networkType) { : (coopnet_initialize() == COOPNET_OK); } -static s64 ns_coopnet_get_id(u8 localIndex) { - if (localIndex == 0) { return (s64)sLocalUserId; } - return (s64)sNetworkUserIds[localIndex]; -} - static char* ns_coopnet_get_id_str(u8 localIndex) { static char id_str[22] = { 0 }; if (localIndex == UNKNOWN_LOCAL_INDEX) { @@ -91,24 +84,6 @@ static char* ns_coopnet_get_id_str(u8 localIndex) { return id_str; } -static void ns_coopnet_save_id(u8 localIndex, s64 networkId) { - SOFT_ASSERT(localIndex > 0); - SOFT_ASSERT(localIndex < MAX_PLAYERS); - sNetworkUserIds[localIndex] = (networkId == 0) ? sNetworkUserIds[0] : (u64)networkId; -} - -static void ns_coopnet_clear_id(u8 localIndex) { - if (localIndex == 0) { return; } - SOFT_ASSERT(localIndex < MAX_PLAYERS); - sNetworkUserIds[localIndex] = 0; -} - -static void* ns_coopnet_dup_addr(u8 localIndex) { - void* address = malloc(sizeof(u64)); - memcpy(address, &sNetworkUserIds[localIndex], sizeof(u64)); - return address; -} - static bool ns_coopnet_match_addr(void* addr1, void* addr2) { return !memcmp(addr1, addr2, sizeof(u64)); } @@ -124,10 +99,10 @@ void ns_coopnet_update(void) { 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); + coopnet_lobby_create(CN_GAME_STR, get_version(), configPlayerName, "Super Mario 64", (uint16_t)configAmountofPlayers, ""); } else if (sNetworkType == NT_CLIENT) { LOG_INFO("Join lobby"); - coopnet_lobby_join(gCoopNetDesiredLobby); + coopnet_lobby_join(gCoopNetDesiredLobby, ""); } sNetworkType = NT_NONE; } @@ -136,8 +111,7 @@ void ns_coopnet_update(void) { static int ns_coopnet_network_send(u8 localIndex, void* address, u8* data, u16 dataLength) { if (!coopnet_is_connected()) { return 1; } //if (gCurLobbyId == 0) { return 2; } - - u64 userId = sNetworkUserIds[localIndex]; + u64 userId = ns_coopnet_get_id(localIndex); if (localIndex == 0 && address != NULL) { userId = *(u64*)address; } coopnet_send_to(userId, data, dataLength); @@ -153,12 +127,17 @@ static CoopNetRc coopnet_initialize(void) { if (coopnet_is_connected()) { return COOPNET_OK; } gCoopNetCallbacks.OnConnected = coopnet_on_connected; + gCoopNetCallbacks.OnDisconnected = coopnet_on_disconnected; 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); + CoopNetRc rc = coopnet_begin(CN_HOST, CN_PORT); + if (rc == COOPNET_FAILED) { + djui_popup_create(DLANG(NOTIF, COOPNET_CONNECTION_FAILED), 2); + } + return rc; } struct NetworkSystem gNetworkSystemCoopNet = { diff --git a/src/pc/network/coopnet/coopnet.h b/src/pc/network/coopnet/coopnet.h index ab55ae016..253de6538 100644 --- a/src/pc/network/coopnet/coopnet.h +++ b/src/pc/network/coopnet/coopnet.h @@ -2,11 +2,11 @@ #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); +typedef void (*QueryCallbackPtr)(uint64_t aLobbyId, uint64_t aOwnerId, uint16_t aConnections, uint16_t aMaxConnections, const char* aGame, const char* aVersion, const char* aHostName, const char* aMode); extern struct NetworkSystem gNetworkSystemCoopNet; extern uint64_t gCoopNetDesiredLobby; -void ns_coopnet_query(QueryCallbackPtr callback); +void ns_coopnet_query(QueryCallbackPtr callback, const char* password); bool ns_coopnet_is_connected(void); void ns_coopnet_update(void); diff --git a/src/pc/network/coopnet/coopnet_id.c b/src/pc/network/coopnet/coopnet_id.c new file mode 100644 index 000000000..699c9801e --- /dev/null +++ b/src/pc/network/coopnet/coopnet_id.c @@ -0,0 +1,51 @@ +#include "libcoopnet.h" +#include "coopnet.h" +#include "pc/network/network.h" +#include "pc/debuglog.h" + +static uint64_t sLocalUserId = 0; +static uint64_t sNetworkUserIds[MAX_PLAYERS] = { 0 }; + +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) { + return i; + } + } + return UNKNOWN_LOCAL_INDEX; +} + +void coopnet_set_user_id(uint8_t localIndex, uint64_t userId) { + sNetworkUserIds[localIndex] = userId; +} + +uint64_t coopnet_get_local_user_id(void) { + return sLocalUserId; +} + +void coopnet_set_local_user_id(uint64_t userId) { + sLocalUserId = userId; +} + +s64 ns_coopnet_get_id(u8 localIndex) { + if (localIndex == 0) { return (s64)sLocalUserId; } + return (s64)sNetworkUserIds[localIndex]; +} + +void ns_coopnet_save_id(u8 localIndex, s64 networkId) { + SOFT_ASSERT(localIndex > 0); + SOFT_ASSERT(localIndex < MAX_PLAYERS); + sNetworkUserIds[localIndex] = (networkId == 0) ? sNetworkUserIds[0] : (u64)networkId; +} + +void ns_coopnet_clear_id(u8 localIndex) { + if (localIndex == 0) { return; } + SOFT_ASSERT(localIndex < MAX_PLAYERS); + sNetworkUserIds[localIndex] = 0; +} + +void* ns_coopnet_dup_addr(u8 localIndex) { + void* address = malloc(sizeof(u64)); + memcpy(address, &sNetworkUserIds[localIndex], sizeof(u64)); + return address; +} diff --git a/src/pc/network/coopnet/coopnet_id.h b/src/pc/network/coopnet/coopnet_id.h new file mode 100644 index 000000000..1978c3791 --- /dev/null +++ b/src/pc/network/coopnet/coopnet_id.h @@ -0,0 +1,13 @@ +#pragma once + +#include "PR/ultratypes.h" + +u8 coopnet_user_id_to_local_index(uint64_t userId); +void coopnet_set_user_id(uint8_t localIndex, uint64_t userId); +uint64_t coopnet_get_local_user_id(void); +void coopnet_set_local_user_id(uint64_t userId); + +s64 ns_coopnet_get_id(u8 localIndex); +void ns_coopnet_save_id(u8 localIndex, s64 networkId); +void ns_coopnet_clear_id(u8 localIndex); +void* ns_coopnet_dup_addr(u8 localIndex); \ No newline at end of file