Clients shouldn't try to detects timeout of other clients, because most of the time the client side doesn't have timeout information given, better wait for the host to tells them if a client got disconnected.

This commit is contained in:
ANR2ME 2020-09-11 13:08:01 +07:00
parent 2e9952cf6e
commit 3eeb48bb40
2 changed files with 43 additions and 19 deletions

View File

@ -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

View File

@ -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) {