diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 0575631668..5a382ede62 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -935,22 +935,23 @@ void handleTimeout(SceNetAdhocMatchingContext * context) SceNetAdhocMatchingMemberInternal * next = peer->next; u64_le now = CoreTiming::GetGlobalTimeUsScaled(); //real_time_now()*1000000.0 - // Timeout!, may be we shouldn't kick timedout members ourself and let the game do it - if (peer->state != 0 && (now - peer->lastping) >= context->timeout) + // Timeout! + if (peer->state != 0 && (now - peer->lastping) > context->timeout) { // Spawn Timeout Event - if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && (/*peer->state == PSP_ADHOC_MATCHING_PEER_CHILD ||*/ peer->state == PSP_ADHOC_MATCHING_PEER_PARENT)) || + if ((context->mode == PSP_ADHOC_MATCHING_MODE_CHILD && peer->state == PSP_ADHOC_MATCHING_PEER_PARENT) || (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT && peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) || (context->mode == PSP_ADHOC_MATCHING_MODE_P2P && peer->state == PSP_ADHOC_MATCHING_PEER_P2P)) { // FIXME: TIMEOUT event should only be triggered on Parent/P2P mode and for Parent/P2P peer? spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_TIMEOUT, &peer->mac, 0, NULL); + + INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout / 1000)); + + if (context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) + sendDeathMessage(context, peer); + else + sendCancelMessage(context, peer, 0, NULL); } - - INFO_LOG(SCENET, "TimedOut Member Peer %s (%lldms)", mac2str(&peer->mac).c_str(), (context->timeout/1000)); - - // Delete Peer from List - deletePeer(context, peer); - //peer->lastping = 0; //Let's just make the game kick timedout members during sceNetAdhocMatchingGetMembers } // Move Pointer diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7024529b96..398d328521 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -4415,6 +4415,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) auto friendpeer = findFriend(&p2p->mac); if (p2p->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) p2p->lastping = CoreTiming::GetGlobalTimeUsScaled(); + else + p2p->lastping = 0; // Add P2P Brother MAC buf2[filledpeers++].mac_addr = p2p->mac; @@ -4433,6 +4435,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) auto friendpeer = findFriend(&parentpeer->mac); if (parentpeer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) parentpeer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + else + parentpeer->lastping = 0; // Add Parent MAC buf2[filledpeers++].mac_addr = parentpeer->mac; @@ -4453,6 +4457,8 @@ static int sceNetAdhocMatchingGetMembers(int matchingId, u32 sizeAddr, u32 buf) auto friendpeer = findFriend(&peer->mac); if (peer->lastping != 0 && friendpeer != NULL && friendpeer->last_recv != 0) peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + else + peer->lastping = 0; // Add Peer MAC sortedPeers.push_front(peer); @@ -5517,9 +5523,6 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac // Packet Buffer uint8_t packet[7]; - // Set Opcode - packet[0] = PSP_ADHOC_MATCHING_PACKET_DEATH; - // Set abandoned Child MAC memcpy(packet + 1, mac, sizeof(SceNetEtherAddr)); @@ -5527,18 +5530,32 @@ void sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for (; peer != NULL; peer = peer->next) { - // Skip dead Child - if (peer == deadkid) continue; + // Skip dead Child? Or May be we should also tells the disconnected Child, that they have been disconnected from the Host (in the case they were disconnected because they went to PPSSPP settings for too long) + if (peer == deadkid) { + // Set Opcode + packet[0] = PSP_ADHOC_MATCHING_PACKET_BYE; - // Send only to children + // Send Bye Packet + context->socketlock->lock(); + sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet[0]), 0, ADHOC_F_NONBLOCK); + context->socketlock->unlock(); + } + else + // Send to other children if (peer->state == PSP_ADHOC_MATCHING_PEER_CHILD) { - // Send Packet + // Set Opcode + packet[0] = PSP_ADHOC_MATCHING_PACKET_DEATH; + + // Send Death Packet context->socketlock->lock(); sceNetAdhocPdpSend(context->socket, (const char*)&peer->mac, context->port, packet, sizeof(packet), 0, ADHOC_F_NONBLOCK); context->socketlock->unlock(); } } + + // Delete Peer + deletePeer(context, deadkid); } } @@ -5692,7 +5709,7 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen // If we got the peer in the table already and are a parent, there is nothing left to be done. // This is because the only way a parent can know of a child is via a join request... // If we thus know of a possible child, then we already had a previous join request thus no need for double tapping. - if (peer != NULL && context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { + if (peer != NULL && peer->lastping != 0 && context->mode == PSP_ADHOC_MATCHING_MODE_PARENT) { WARN_LOG(SCENET, "Join Event(2) Ignored"); return; } @@ -5738,6 +5755,9 @@ void actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sen // Set Peer State peer->state = PSP_ADHOC_MATCHING_PEER_INCOMING_REQUEST; + // Initialize Ping Timer + peer->lastping = CoreTiming::GetGlobalTimeUsScaled(); + // Spawn Request Event spawnLocalEvent(context, PSP_ADHOC_MATCHING_EVENT_REQUEST, sendermac, optlen, opt); @@ -6217,7 +6237,7 @@ int matchingEventThread(int matchingId) sleep_ms(10); //1 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->eventRunning) sleep_ms(10); } // Process Last Messages @@ -6371,6 +6391,9 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi // Send Birth Packet else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_BIRTH) sendBirthPacket(context, &msg->mac); + // Send Death Packet + else if (msg->opcode == PSP_ADHOC_MATCHING_PACKET_DEATH) sendDeathPacket(context, &msg->mac); + // Cancel Bulk Data Transfer (does nothing as of now as we fire and forget anyway) // Do we need to check DeathPacket and ByePacket here? //else if(msg->opcode == PSP_ADHOC_MATCHING_PACKET_BULK_ABORT) sendAbortBulkDataPacket(context, &msg->mac, msg->optlen, opt); @@ -6456,7 +6479,7 @@ int matchingInputThread(int matchingId) // TODO: The MatchingInput thread is usi sleep_ms(10); //1 //sceKernelDelayThread(10000); // Don't do anything if it's paused, otherwise the log will be flooded - while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->inputRunning) sleep_ms(1); + while (Core_IsStepping() && coreState != CORE_POWERDOWN && contexts != NULL && context->inputRunning) sleep_ms(10); } if (contexts != NULL) {