123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- #include "quakedef.h"
- #ifdef _WIN32
- #include "winquake.h"
- #endif
- #define PACKET_HEADER 8
- int net_drop;
- cvar_t showpackets = {"showpackets", "0"};
- cvar_t showdrop = {"showdrop", "0"};
- cvar_t qport = {"qport", "0"};
- void Netchan_Init (void)
- {
- int port;
-
- #ifdef _WIN32
- port = ((int)(timeGetTime()*1000) * time(NULL)) & 0xffff;
- #else
- port = ((int)(getpid()+getuid()*1000) * time(NULL)) & 0xffff;
- #endif
- Cvar_RegisterVariable (&showpackets);
- Cvar_RegisterVariable (&showdrop);
- Cvar_RegisterVariable (&qport);
- Cvar_SetValue("qport", port);
- }
- void Netchan_OutOfBand (netadr_t adr, int length, byte *data)
- {
- sizebuf_t send;
- byte send_buf[MAX_MSGLEN + PACKET_HEADER];
- send.data = send_buf;
- send.maxsize = sizeof(send_buf);
- send.cursize = 0;
-
- MSG_WriteLong (&send, -1);
- SZ_Write (&send, data, length);
-
- #ifndef SERVERONLY
- if (!cls.demoplayback)
- #endif
- NET_SendPacket (send.cursize, send.data, adr);
- }
- void Netchan_OutOfBandPrint (netadr_t adr, char *format, ...)
- {
- va_list argptr;
- static char string[8192];
-
- va_start (argptr, format);
- vsprintf (string, format,argptr);
- va_end (argptr);
- Netchan_OutOfBand (adr, strlen(string), (byte *)string);
- }
- void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport)
- {
- memset (chan, 0, sizeof(*chan));
-
- chan->remote_address = adr;
- chan->last_received = realtime;
-
- chan->message.data = chan->message_buf;
- chan->message.allowoverflow = true;
- chan->message.maxsize = sizeof(chan->message_buf);
- chan->qport = qport;
-
- chan->rate = 1.0/2500;
- }
- #define MAX_BACKUP 200
- qboolean Netchan_CanPacket (netchan_t *chan)
- {
- if (chan->cleartime < realtime + MAX_BACKUP*chan->rate)
- return true;
- return false;
- }
- qboolean Netchan_CanReliable (netchan_t *chan)
- {
- if (chan->reliable_length)
- return false;
- return Netchan_CanPacket (chan);
- }
- #ifdef SERVERONLY
- qboolean ServerPaused(void);
- #endif
- void Netchan_Transmit (netchan_t *chan, int length, byte *data)
- {
- sizebuf_t send;
- byte send_buf[MAX_MSGLEN + PACKET_HEADER];
- qboolean send_reliable;
- unsigned w1, w2;
- int i;
- if (chan->message.overflowed)
- {
- chan->fatal_error = true;
- Con_Printf ("%s:Outgoing message overflow\n"
- , NET_AdrToString (chan->remote_address));
- return;
- }
- send_reliable = false;
- if (chan->incoming_acknowledged > chan->last_reliable_sequence
- && chan->incoming_reliable_acknowledged != chan->reliable_sequence)
- send_reliable = true;
- if (!chan->reliable_length && chan->message.cursize)
- {
- memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
- chan->reliable_length = chan->message.cursize;
- chan->message.cursize = 0;
- chan->reliable_sequence ^= 1;
- send_reliable = true;
- }
- send.data = send_buf;
- send.maxsize = sizeof(send_buf);
- send.cursize = 0;
- w1 = chan->outgoing_sequence | (send_reliable<<31);
- w2 = chan->incoming_sequence | (chan->incoming_reliable_sequence<<31);
- chan->outgoing_sequence++;
- MSG_WriteLong (&send, w1);
- MSG_WriteLong (&send, w2);
-
- #ifndef SERVERONLY
- MSG_WriteShort (&send, cls.qport);
- #endif
- if (send_reliable)
- {
- SZ_Write (&send, chan->reliable_buf, chan->reliable_length);
- chan->last_reliable_sequence = chan->outgoing_sequence;
- }
-
- if (send.maxsize - send.cursize >= length)
- SZ_Write (&send, data, length);
- i = chan->outgoing_sequence & (MAX_LATENT-1);
- chan->outgoing_size[i] = send.cursize;
- chan->outgoing_time[i] = realtime;
-
- #ifndef SERVERONLY
- if (!cls.demoplayback)
- #endif
- NET_SendPacket (send.cursize, send.data, chan->remote_address);
- if (chan->cleartime < realtime)
- chan->cleartime = realtime + send.cursize*chan->rate;
- else
- chan->cleartime += send.cursize*chan->rate;
- #ifdef SERVERONLY
- if (ServerPaused())
- chan->cleartime = realtime;
- #endif
- if (showpackets.value)
- Con_Printf ("--> s=%i(%i) a=%i(%i) %i\n"
- , chan->outgoing_sequence
- , send_reliable
- , chan->incoming_sequence
- , chan->incoming_reliable_sequence
- , send.cursize);
- }
- qboolean Netchan_Process (netchan_t *chan)
- {
- unsigned sequence, sequence_ack;
- unsigned reliable_ack, reliable_message;
- #ifdef SERVERONLY
- int qport;
- #endif
- int i;
- if (
- #ifndef SERVERONLY
- !cls.demoplayback &&
- #endif
- !NET_CompareAdr (net_from, chan->remote_address))
- return false;
-
- MSG_BeginReading ();
- sequence = MSG_ReadLong ();
- sequence_ack = MSG_ReadLong ();
-
- #ifdef SERVERONLY
- qport = MSG_ReadShort ();
- #endif
- reliable_message = sequence >> 31;
- reliable_ack = sequence_ack >> 31;
- sequence &= ~(1<<31);
- sequence_ack &= ~(1<<31);
- if (showpackets.value)
- Con_Printf ("<-- s=%i(%i) a=%i(%i) %i\n"
- , sequence
- , reliable_message
- , sequence_ack
- , reliable_ack
- , net_message.cursize);
- #if 0
- if (chan->outgoing_sequence - sequence_ack < MAX_LATENT)
- {
- int i;
- double time, rate;
-
- i = sequence_ack & (MAX_LATENT - 1);
- time = realtime - chan->outgoing_time[i];
- time -= 0.1;
- if (time <= 0)
- {
- if (chan->rate > 1.0/5000)
- chan->rate = 1.0/5000;
- }
- else
- {
- if (chan->outgoing_size[i] < 512)
- {
- rate = chan->outgoing_size[i]/time;
- if (rate > 5000)
- rate = 5000;
- rate = 1.0/rate;
- if (chan->rate > rate)
- chan->rate = rate;
- }
- }
- }
- #endif
- if (sequence <= (unsigned)chan->incoming_sequence)
- {
- if (showdrop.value)
- Con_Printf ("%s:Out of order packet %i at %i\n"
- , NET_AdrToString (chan->remote_address)
- , sequence
- , chan->incoming_sequence);
- return false;
- }
- net_drop = sequence - (chan->incoming_sequence+1);
- if (net_drop > 0)
- {
- chan->drop_count += 1;
- if (showdrop.value)
- Con_Printf ("%s:Dropped %i packets at %i\n"
- , NET_AdrToString (chan->remote_address)
- , sequence-(chan->incoming_sequence+1)
- , sequence);
- }
- if (reliable_ack == (unsigned)chan->reliable_sequence)
- chan->reliable_length = 0;
-
- chan->incoming_sequence = sequence;
- chan->incoming_acknowledged = sequence_ack;
- chan->incoming_reliable_acknowledged = reliable_ack;
- if (reliable_message)
- chan->incoming_reliable_sequence ^= 1;
- chan->frame_latency = chan->frame_latency*OLD_AVG
- + (chan->outgoing_sequence-sequence_ack)*(1.0-OLD_AVG);
- chan->frame_rate = chan->frame_rate*OLD_AVG
- + (realtime-chan->last_received)*(1.0-OLD_AVG);
- chan->good_count += 1;
- chan->last_received = realtime;
- return true;
- }
|