sceNetAdhoc: Ignore the server's answer to a timed-out game mode join

When entering game mode timed out before the server's group BSSID came
back, the late BSSID was taken for a normal group's, and the state went
to CONNECTED: every later CreateEnterGameMode then got ALREADY_CONNECTED.
At the ad hoc tests' 8x speed the 1 s timeouts in net/adhoc/gamemode are
125 ms of wall time, short enough for that on Windows; at 50x it happens
on macOS too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-30 11:21:57 +01:00
1 parent 043875a607
commit 9d8ef5e8f5
3 files changed
+13

No files matched your search

+7
View File
@@ -86,6 +86,7 @@ SceNetAdhocctlScanInfo * networks = NULL;
SceNetAdhocctlScanInfo * newnetworks = NULL;
u64 adhocctlStartTime = 0;
u64 gameModeEnterTimeUs = 0;
bool dropLateGroupReply = false;
std::atomic<bool> isAdhocctlNeedLogin = false;
bool isAdhocctlBusy = false;
int adhocctlState = ADHOCCTL_STATE_DISCONNECTED;
@@ -1696,6 +1697,12 @@ void friendFinderPoll() {
break;
case ADHOCCTL_CLIENT_EVENT_LEADER_MAC:{
INFO_LOG(Log::sceNet, "FriendFinder: Incoming OPCODE_CONNECT_BSSID [%s]", mac2str((SceNetEtherAddr *)adhocctl_event.leader_mac.mac).c_str());
if (dropLateGroupReply) {
// The game mode it was for has timed out (we've already left the group again).
dropLateGroupReply = false;
INFO_LOG(Log::sceNet, "FriendFinder: Ignoring the group BSSID, game mode timed out before it came");
break;
}
// Update Group BSSID
memcpy(parameter.bssid.mac_addr.data, adhocctl_event.leader_mac.mac, 6); // This packet seems to contains Adhoc Group Creator's BSSID (similar to AP's BSSID) so it shouldn't get mixed up with local MAC address. Note: On JPCSP + prx files params.bssid is hardcoded to "Jpcsp\0" and doesn't match to any of player's mac
+3
View File
@@ -820,6 +820,9 @@ extern SceNetAdhocctlScanInfo * networks;
extern u64 adhocctlStartTime;
// When CreateEnterGameMode or JoinEnterGameMode was called, in emulated time: its timeout is a PSP-side one.
extern u64 gameModeEnterTimeUs;
// Set when entering game mode timed out, until the next group join is sent: the server's answer to the
// timed-out join may still be on its way, and must not connect us to the group.
extern bool dropLateGroupReply;
extern std::atomic<bool> isAdhocctlNeedLogin;
extern bool isAdhocctlBusy;
extern int adhocctlState;
+3
View File
@@ -626,6 +626,7 @@ static void __AdhocctlNotify(u64 userdata, int cyclesLate) {
call_status = adhocctl_connect(adhocctlHandle, (char *)req.group.data);
if (call_status == ADHOCCTL_CALL_SUCCESS) {
adhocctlInServerGroup = true;
dropLateGroupReply = false;
}
break;
}
@@ -2271,6 +2272,8 @@ void __UpdateAdhocctlHandlers(u32 flag, u32 error) {
}
void NetAdhocctl_GameModeTimedOut() {
// If the server's BSSID came in time, there's nothing to drop, and the next join clears this.
dropLateGroupReply = true;
if (adhocctlInServerGroup) {
const std::lock_guard<std::mutex> adhocctl_guard(adhocctlMutex);
if (adhocctlHandle != NULL) {