From a8a63fa11ddea926375bdd7ef9c234864d6cede9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 29 Oct 2026 19:20:06 +0100 Subject: [PATCH] sceNetAdhoc: Start socket IDs over at 1 after sceNetAdhocTerm A PSP hands out socket IDs from 1 again after sceNetAdhocTerm and sceNetAdhocInit (net/adhoc/socketids, recorded on a PSP). We kept counting up. Pangya: Fantasy Golf tears down the network between its room and the round, and then keeps using socket 1 without looking at what PdpCreate returned, so every send and receive failed with INVALID_SOCKET_ID and each player saw the other as "Off-line". Co-Authored-By: Claude Opus 5.5 --- Core/HLE/sceNetAdhoc.cpp | 11 +++++++---- pspautotests | 2 +- test.py | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index a4104cbed6..b8cb9c3c15 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -374,6 +374,9 @@ static AdhocDataMode AdhocGetServerDataMode(std::string_view server) { int AcceptPtpSocket(int ptpId, int newsocket, sockaddr_in& peeraddr, SceNetEtherAddr* addr, u16_le* port); int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock); static int FindFreeAdhocSocketSlot(); +// A PSP hands out socket IDs in increasing order (pspautotests net/adhoc/ptp), starting over from 1 +// after sceNetAdhocTerm (pspautotests net/adhoc/socketids). +static int nextAdhocSocketSlot = 0; int FlushPtpSocket(int socketId); int RecreatePtpSocket(int ptpId); int NetAdhocGameMode_DeleteMaster(); @@ -2289,6 +2292,7 @@ static void aemu_postoffice_server_log(const char *format, ...) { } void __NetAdhocInit() { + nextAdhocSocketSlot = 0; friendFinderRunning = false; netAdhocInited = false; netAdhocctlInited = false; @@ -2503,10 +2507,8 @@ static int pdp_create_postoffice(const SceNetEtherAddr *saddr, int sport, int bu } // Out of socket IDs is its own error (pspautotests net/adhoc/limits). -// A PSP hands out socket IDs in increasing order (pspautotests net/adhoc/ptp), so the search for a free -// slot starts after the last one handed out, and wraps around. Returns MAX_SOCKET when all are taken. -static int nextAdhocSocketSlot = 0; - +// The search for a free slot starts after the last one handed out, and wraps around (see +// nextAdhocSocketSlot). Returns MAX_SOCKET when all are taken. static int FindFreeAdhocSocketSlot() { for (int n = 0; n < MAX_SOCKET; n++) { int i = (nextAdhocSocketSlot + n) % MAX_SOCKET; @@ -4513,6 +4515,7 @@ int NetAdhoc_Term() { // Delete Adhoc Sockets deleteAllAdhocSockets(); + nextAdhocSocketSlot = 0; // Terminate Internet Library //sceNetInetTerm(); diff --git a/pspautotests b/pspautotests index 8d093e7e67..976112725f 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 8d093e7e67c65f5076913d0d09de2c34873b4679 +Subproject commit 976112725faea2b417bc5f0fd206fd0ba2fb62a9 diff --git a/test.py b/test.py index 415c5c7e72..a79f18064d 100755 --- a/test.py +++ b/test.py @@ -680,6 +680,7 @@ tests_next = [ "net/adhoc/poll", "net/adhoc/ptp", "net/adhoc/self", + "net/adhoc/socketids", "net/inet/bind", "net/inet/poll", "net/inet/errors",