Fix server list refresh and add cancellable non-blocking connection

Server list: edits and deletions now update the UI immediately by
calling SearchForGames() in ForceFriendsSessionRefresh() and
UpdateGamesList() on nav-back to LoadOrJoinMenu.

Connection: moved WinsockNetLayer::JoinGame() to a background thread
with non-blocking sockets (5s timeout, 3 retries). Users can cancel
with B/Escape during the attempt. Failed connections always show an
error dialog.
This commit is contained in:
itsRevela
2026-03-24 11:30:14 -05:00
parent d4d5ffe403
commit 5dad6c24f7
10 changed files with 297 additions and 11 deletions
@@ -69,6 +69,12 @@ public:
static bool HostGame(int port, const char* bindIp = nullptr);
static bool JoinGame(const char* ip, int port);
// Async join: runs JoinGame on a background thread so the UI stays responsive
static bool StartJoinGameAsync(const char* ip, int port);
static bool IsJoinComplete();
static bool GetJoinResult();
static void CancelJoinGame();
static bool SendToSmallId(BYTE targetSmallId, const void* data, int dataSize);
static bool SendOnSocket(SOCKET sock, const void* data, int dataSize);
@@ -112,6 +118,7 @@ private:
static DWORD WINAPI SplitScreenRecvThreadProc(LPVOID param);
static DWORD WINAPI AdvertiseThreadProc(LPVOID param);
static DWORD WINAPI DiscoveryThreadProc(LPVOID param);
static DWORD WINAPI JoinGameThreadProc(LPVOID param);
static SOCKET s_listenSocket;
static SOCKET s_hostConnectionSocket;
@@ -154,6 +161,14 @@ private:
static SOCKET s_smallIdToSocket[256];
static CRITICAL_SECTION s_smallIdToSocketLock;
// Async join state
static volatile bool s_joinCancelled;
static volatile bool s_joinComplete;
static bool s_joinResult;
static HANDLE s_joinGameThread;
static char s_joinIP[256];
static int s_joinPort;
// Per-pad split-screen TCP connections (client-side, non-host only)
static SOCKET s_splitScreenSocket[XUSER_MAX_COUNT];
static BYTE s_splitScreenSmallId[XUSER_MAX_COUNT];