Try to fix issues with clients locking up due to never receiving acks back in case of dropped packets

https://github.com/Indev450/SRB2Kart-Saturn/pull/151
This commit is contained in:
NepDisk 2025-06-28 22:53:20 -04:00
parent 7acf64fba8
commit 6ac11da6e4

View file

@ -324,11 +324,18 @@ static void RemoveAck(INT32 i)
Net_CloseConnection(node); Net_CloseConnection(node);
} }
typedef enum
{
GPACK_OK = 0,
GPACK_DUPLICATE,
GPACK_OUTOFORDER,
} goodpacket_e;
// We have got a packet, proceed the ack request and ack return // We have got a packet, proceed the ack request and ack return
static boolean Processackpak(void) static int Processackpak(void)
{ {
INT32 i; INT32 i;
boolean goodpacket = true; int goodpacket = GPACK_OK;
netnode_t *node = &nodes[doomcom->remotenode]; netnode_t *node = &nodes[doomcom->remotenode];
// Received an ack return, so remove the ack in the list // Received an ack return, so remove the ack in the list
@ -353,7 +360,7 @@ static boolean Processackpak(void)
{ {
DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack));
duppacket++; duppacket++;
goodpacket = false; // Discard packet (duplicate) goodpacket = GPACK_DUPLICATE; // Discard packet (duplicate)
} }
else else
{ {
@ -363,10 +370,10 @@ static boolean Processackpak(void)
{ {
DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack));
duppacket++; duppacket++;
goodpacket = false; // Discard packet (duplicate) goodpacket = GPACK_DUPLICATE; // Discard packet (duplicate)
break; break;
} }
if (goodpacket) if (goodpacket == GPACK_OK)
{ {
// Is a good packet so increment the acknowledge number, // Is a good packet so increment the acknowledge number,
// Then search for a "hole" in the queue // Then search for a "hole" in the queue
@ -427,12 +434,13 @@ static boolean Processackpak(void)
else // Buffer full discard packet, sender will resend it else // Buffer full discard packet, sender will resend it
{ // We can admit the packet but we will not detect the duplication after :( { // We can admit the packet but we will not detect the duplication after :(
DEBFILE("no more freeackret\n"); DEBFILE("no more freeackret\n");
goodpacket = false; goodpacket = GPACK_OUTOFORDER;
} }
} }
} }
} }
} }
// return values: 0 = ok, 1 = duplicate, 2 = out of order
return goodpacket; return goodpacket;
} }
@ -1125,6 +1133,7 @@ boolean HGetPacket(void)
while(true) while(true)
{ {
//nodejustjoined = I_NetGet(); //nodejustjoined = I_NetGet();
int goodpacket;
I_NetGet(); I_NetGet();
if (doomcom->remotenode == -1) // No packet received if (doomcom->remotenode == -1) // No packet received
@ -1170,8 +1179,15 @@ boolean HGetPacket(void)
}*/ }*/
// Proceed the ack and ackreturn field // Proceed the ack and ackreturn field
if (!Processackpak()) goodpacket = Processackpak();
if (goodpacket != GPACK_OK)
{
// resend the ACK in case the previous ACK didn't reach the client.
// prevents the client's netbuffer from locking up.
if (goodpacket == GPACK_DUPLICATE)
Net_SendAcks(doomcom->remotenode);
continue; // discarded (duplicated) continue; // discarded (duplicated)
}
// A packet with just ackreturn // A packet with just ackreturn
if (netbuffer->packettype == PT_NOTHING) if (netbuffer->packettype == PT_NOTHING)