Q2PRO Shitfuck Netchan
This thing sucks, lol, Q2 "PRO" my ass, suck my dick and lick my hairy balls.unknown
c_cpp
3 years ago
11 kB
6
Indexable
/* =============== Netchan_TransmitNextFragment ================ */ size_t Netchan_TransmitNextFragment(netchan_t *netchan) { sizebuf_t send; byte send_buf[MAX_PACKETLEN]; qboolean send_reliable; uint32_t w1, w2; uint16_t offset; size_t fragment_length; qboolean more_fragments; // Should we send a reliable message, or not? send_reliable = netchan->reliableLength ? true : false; // Write the packet header w1 = (netchan->outgoingSequence & 0x3FFFFFFF) | (1 << 30) | (send_reliable << 31); w2 = (netchan->incomingSequence & 0x3FFFFFFF) | (0 << 30) | (netchan->incomingReliableSequence << 31); SZ_TagInit(&send, send_buf, sizeof(send_buf), SZ_NC_SEND_FRG); SZ_WriteLong(&send, w1); SZ_WriteLong(&send, w2); #if USE_CLIENT // Send the qport if we are a client if (netchan->sock == NS_CLIENT && netchan->qport) { SZ_WriteByte(&send, netchan->qport); } #endif // Calculate Fragment length based on how much has been read so far. // Ensure we do not exceed the max packet length. fragment_length = netchan->outFragment.cursize - netchan->outFragment.readcount; if (fragment_length > netchan->maxpacketlen) { fragment_length = netchan->maxpacketlen; } // More more_fragments = true; if (netchan->outFragment.readcount + fragment_length == netchan->outFragment.cursize) { more_fragments = false; } // Write fragment offset offset = (netchan->outFragment.readcount & 0x7FFF) | (more_fragments << 15); SZ_WriteShort(&send, offset); // Write fragment contents SZ_Write(&send, netchan->outFragment.data + netchan->outFragment.readcount, fragment_length); SHOWPACKET("send %4" PRIz " : s=%d ack=%d rack=%d " "fragment_offset=%" PRIz " more_fragments=%d", send.cursize, netchan->outgoingSequence, netchan->incomingSequence, netchan->incomingReliableSequence, netchan->outFragment.readcount, more_fragments); if (send_reliable) { SHOWPACKET(" reliable=%i ", netchan->reliableSequence); } SHOWPACKET("\n"); // Increment read count with fragment length and store whether one more is pending or not. netchan->outFragment.readcount += fragment_length; netchan->fragmentPending = more_fragments; // If the message has been sent completely, clear the fragment buffer if (!netchan->fragmentPending) { netchan->outgoingSequence++; netchan->lastSent = com_localTime; SZ_Clear(&netchan->outFragment); } // Send the datagram NET_SendPacket(netchan->sock, send.data, send.cursize, &netchan->remoteAddress); return send.cursize; } /* =============== Netchan_Transmit ================ */ size_t Netchan_Transmit(netchan_t *netchan, size_t length, const void *data, int numpackets) { sizebuf_t send; byte send_buf[MAX_PACKETLEN]; qboolean send_reliable; uint32_t w1, w2; int i; // check for message overflow if (netchan->message.overflowed) { netchan->fatal_error = true; Com_WPrintf("%s: outgoing message overflow\n", NET_AdrToString(&netchan->remoteAddress)); return 0; } if (netchan->fragmentPending) { return Netchan_TransmitNextFragment(netchan); } send_reliable = false; // if the remote side dropped the last reliable message, resend it if (netchan->incomingAcknowledged > netchan->lastReliableSequence && netchan->incomingReliableAcknowledged != netchan->reliableSequence) { send_reliable = true; } // if the reliable transmit buffer is empty, copy the current message out if (!netchan->reliableLength && netchan->message.cursize) { send_reliable = true; memcpy(netchan->reliableBuffer, netchan->messageBuffer, netchan->message.cursize); netchan->reliableLength = netchan->message.cursize; netchan->message.cursize = 0; netchan->reliableSequence ^= 1; } if (length > netchan->maxpacketlen || (send_reliable && (netchan->reliableLength + length > netchan->maxpacketlen))) { if (send_reliable) { netchan->lastReliableSequence = netchan->outgoingSequence; SZ_Write(&netchan->outFragment, netchan->reliableBuffer, netchan->reliableLength); } // add the unreliable part if space is available if (netchan->outFragment.maxsize - netchan->outFragment.cursize >= length) SZ_Write(&netchan->outFragment, data, length); else Com_WPrintf("%s: dumped unreliable\n", NET_AdrToString(&netchan->remoteAddress)); return Netchan_TransmitNextFragment(netchan); } // write the packet header w1 = (netchan->outgoingSequence & 0x3FFFFFFF) | (send_reliable << 31); w2 = (netchan->incomingSequence & 0x3FFFFFFF) | (netchan->incomingReliableSequence << 31); SZ_TagInit(&send, send_buf, sizeof(send_buf), SZ_NC_SEND_NEW); SZ_WriteLong(&send, w1); SZ_WriteLong(&send, w2); #if USE_CLIENT // send the qport if we are a client if (netchan->sock == NS_CLIENT && netchan->qport) { SZ_WriteByte(&send, netchan->qport); } #endif // copy the reliable message to the packet first if (send_reliable) { netchan->lastReliableSequence = netchan->outgoingSequence; SZ_Write(&send, netchan->reliableBuffer, netchan->reliableLength); } // add the unreliable part SZ_Write(&send, data, length); SHOWPACKET("send %4" PRIz " : s=%d ack=%d rack=%d", send.cursize, netchan->outgoingSequence, netchan->incomingSequence, netchan->incomingReliableSequence); if (send_reliable) { SHOWPACKET(" reliable=%d", netchan->reliableSequence); } SHOWPACKET("\n"); // send the datagram for (i = 0; i < numpackets; i++) { NET_SendPacket(netchan->sock, send.data, send.cursize, &netchan->remoteAddress); } netchan->outgoingSequence++; netchan->reliableAckPending = false; netchan->lastSent = com_localTime; return send.cursize * numpackets; } /* ================= Netchan_Process ================= */ qboolean Netchan_Process(netchan_t *netchan) { uint32_t sequence, sequence_ack, reliable_ack; qboolean reliable_message, fragmented_message, more_fragments; uint16_t fragment_offset; size_t length; // get sequence numbers MSG_BeginReading(); sequence = MSG_ReadLong(); sequence_ack = MSG_ReadLong(); // read the qport if we are a server #if USE_CLIENT if (netchan->sock == NS_SERVER) #endif if (netchan->qport) { MSG_ReadByte(); } reliable_message = sequence >> 31; reliable_ack = sequence_ack >> 31; fragmented_message = (sequence >> 30) & 1; sequence &= 0x3FFFFFFF; sequence_ack &= 0x3FFFFFFF; fragment_offset = 0; more_fragments = false; if (fragmented_message) { fragment_offset = MSG_ReadShort(); more_fragments = fragment_offset >> 15; fragment_offset &= 0x7FFF; } SHOWPACKET("recv %4" PRIz " : s=%d ack=%d rack=%d", msg_read.cursize, sequence, sequence_ack, reliable_ack); if (fragmented_message) { SHOWPACKET(" fragment_offset=%d more_fragments=%d", fragment_offset, more_fragments); } if (reliable_message) { SHOWPACKET(" reliable=%d", netchan->incomingReliableSequence ^ 1); } SHOWPACKET("\n"); // // discard stale or duplicated packets // if (sequence <= netchan->incomingSequence) { SHOWDROP("%s: out of order packet %i at %i\n", NET_AdrToString(&netchan->remoteAddress), sequence, netchan->incomingSequence); return false; } // // dropped packets don't keep the message from being used // netchan->dropped = sequence - (netchan->incomingSequence + 1); if (netchan->dropped > 0) { SHOWDROP("%s: dropped %i packets at %i\n", NET_AdrToString(&netchan->remoteAddress), netchan->dropped, sequence); } // // if the current outgoing reliable message has been acknowledged // clear the buffer to make way for the next // netchan->incomingReliableAcknowledged = reliable_ack; if (reliable_ack == netchan->reliableSequence) { netchan->reliableLength = 0; // it has been received } // // parse fragment header, if any // if (fragmented_message) { if (netchan->fragmentSequence != sequence) { // start new receive sequence netchan->fragmentSequence = sequence; SZ_Clear(&netchan->inFragment); } if (fragment_offset < netchan->inFragment.cursize) { SHOWDROP("%s: out of order fragment at %i\n", NET_AdrToString(&netchan->remoteAddress), sequence); return false; } if (fragment_offset > netchan->inFragment.cursize) { SHOWDROP("%s: dropped fragment(s) at %i\n", NET_AdrToString(&netchan->remoteAddress), sequence); return false; } length = msg_read.cursize - msg_read.readcount; if (netchan->inFragment.cursize + length > netchan->inFragment.maxsize) { SHOWDROP("%s: oversize fragment at %i\n", NET_AdrToString(&netchan->remoteAddress), sequence); return false; } SZ_Write(&netchan->inFragment, msg_read.data + msg_read.readcount, length); if (more_fragments) { return false; } // message has been sucessfully assembled SZ_Clear(&msg_read); SZ_Write(&msg_read, netchan->inFragment.data, netchan->inFragment.cursize); SZ_Clear(&netchan->inFragment); } netchan->incomingSequence = sequence; netchan->incomingAcknowledged = sequence_ack; // // if this message contains a reliable message, bump incomingReliableSequence // if (reliable_message) { netchan->reliableAckPending = true; netchan->incomingReliableSequence ^= 1; } // // the message can now be read from the current message pointer // netchan->lastReceived = com_localTime; netchan->totalDropped += netchan->dropped; netchan->totalReceived += netchan->dropped + 1; return true; }
Editor is loading...