diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index 4860d8688b4a8b998b59523c6cf52502c69d10ca..6e6e95674f755af422b8ce00c9becf4208549432 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -307,6 +307,52 @@ static void RemoveAck(INT32 i) Net_CloseConnection(node); } +static void CreateAckpak(node_t *node) +{ + UINT8 hm1; // head - 1 + boolean change = true; + + // Is a good packet so increment the acknowledge number, + // Then search for a "hole" in the queue + UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); + if (!nextfirstack) + nextfirstack = 1; + + node->firstacktosend = nextfirstack++; + if (!nextfirstack) + nextfirstack = 1; + hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND); + while (change) + { + change = false; + for (INT32 i = node->acktosend_tail; i != node->acktosend_head; + i = (i+1) % MAXACKTOSEND) + { + if (cmpack(node->acktosend[i], nextfirstack) <= 0) + { + if (node->acktosend[i] == nextfirstack) + { + node->firstacktosend = nextfirstack++; + if (!nextfirstack) + nextfirstack = 1; + change = true; + } + if (i == node->acktosend_tail) + { + node->acktosend[node->acktosend_tail] = 0; + node->acktosend_tail = (UINT8)((i+1) % MAXACKTOSEND); + } + else if (i == hm1) + { + node->acktosend[hm1] = 0; + node->acktosend_head = hm1; + hm1 = (UINT8)((hm1-1+MAXACKTOSEND) % MAXACKTOSEND); + } + } + } + } +} + // We have got a packet, proceed the ack request and ack return static int Processackpak(void) { @@ -331,76 +377,38 @@ static int Processackpak(void) { UINT8 ack = netbuffer->ack; getackpacket++; - if (cmpack(ack, node->firstacktosend) <= 0) - { - DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); - duppacket++; - goodpacket = 1; // Discard packet (duplicate) - } - else - { - // Check if it is not already in the queue - for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) - if (node->acktosend[i] == ack) - { - DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); - duppacket++; - goodpacket = 1; // Discard packet (duplicate) - break; - } - if (goodpacket == 0) + // Check if it is not already in the queue + for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) + if (node->acktosend[i] == ack) { - // Is a good packet so increment the acknowledge number, - // Then search for a "hole" in the queue - UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); - if (!nextfirstack) - nextfirstack = 1; + DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); + duppacket++; + goodpacket = 1; // Discard packet (duplicate) + break; + } - if (ack == nextfirstack) + if (goodpacket == 0) + { + if (cmpack(ack, node->firstacktosend) <= 0) + { + // even if this is a duplicate packet, register it in acktosend so we can respond to it + CreateAckpak(node); + DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); + duppacket++; + goodpacket = 1; // Discard packet (duplicate) + } + else + { + if (ack == node->firstacktosend + 1) { - UINT8 hm1; // head - 1 - boolean change = true; - - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - hm1 = (UINT8)((node->acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND); - while (change) - { - change = false; - for (INT32 i = node->acktosend_tail; i != node->acktosend_head; - i = (i+1) % MAXACKTOSEND) - { - if (cmpack(node->acktosend[i], nextfirstack) <= 0) - { - if (node->acktosend[i] == nextfirstack) - { - node->firstacktosend = nextfirstack++; - if (!nextfirstack) - nextfirstack = 1; - change = true; - } - if (i == node->acktosend_tail) - { - node->acktosend[node->acktosend_tail] = 0; - node->acktosend_tail = (UINT8)((i+1) % MAXACKTOSEND); - } - else if (i == hm1) - { - node->acktosend[hm1] = 0; - node->acktosend_head = hm1; - hm1 = (UINT8)((hm1-1+MAXACKTOSEND) % MAXACKTOSEND); - } - } - } - } + CreateAckpak(node); } else // Out of order packet { // Don't increment firsacktosend, put it in asktosend queue // Will be incremented when the nextfirstack comes (code above) UINT8 newhead = (UINT8)((node->acktosend_head+1) % MAXACKTOSEND); - DEBFILE(va("out of order packet (%d expected)\n", nextfirstack)); + DEBFILE(va("out of order packet (%d expected)\n", node->firstacktosend + 1)); if (newhead != node->acktosend_tail) { node->acktosend[node->acktosend_head] = ack;