From 6ac11da6e4d9b3121ccf42a5b3d260c69c672d1c Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sat, 28 Jun 2025 22:53:20 -0400 Subject: [PATCH] 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 --- src/d_net.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/d_net.c b/src/d_net.c index 703f10cde..9e8ab5c57 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -324,11 +324,18 @@ static void RemoveAck(INT32 i) 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 -static boolean Processackpak(void) +static int Processackpak(void) { INT32 i; - boolean goodpacket = true; + int goodpacket = GPACK_OK; netnode_t *node = &nodes[doomcom->remotenode]; // 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)); duppacket++; - goodpacket = false; // Discard packet (duplicate) + goodpacket = GPACK_DUPLICATE; // Discard packet (duplicate) } else { @@ -363,10 +370,10 @@ static boolean Processackpak(void) { DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); duppacket++; - goodpacket = false; // Discard packet (duplicate) + goodpacket = GPACK_DUPLICATE; // Discard packet (duplicate) break; } - if (goodpacket) + if (goodpacket == GPACK_OK) { // Is a good packet so increment the acknowledge number, // 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 { // We can admit the packet but we will not detect the duplication after :( DEBFILE("no more freeackret\n"); - goodpacket = false; + goodpacket = GPACK_OUTOFORDER; } } } } } + // return values: 0 = ok, 1 = duplicate, 2 = out of order return goodpacket; } @@ -1125,6 +1133,7 @@ boolean HGetPacket(void) while(true) { //nodejustjoined = I_NetGet(); + int goodpacket; I_NetGet(); if (doomcom->remotenode == -1) // No packet received @@ -1170,8 +1179,15 @@ boolean HGetPacket(void) }*/ // 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) + } // A packet with just ackreturn if (netbuffer->packettype == PT_NOTHING)