mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +00:00
- Added selective compression of network packets. Interestingly, most packets
don't actually compress all that well, even the ones that aren't too short to possibly compress. (Maybe make the whole thing one long, never-ending zlib data stream with Z_SYNC_FLUSH used to chunk things at packet boundaries? That would probably help the compression ratio, but it would require changing the way the netcode determines sequence, which would be a much more invasive change.) SVN r1438 (trunk)
This commit is contained in:
parent
b246d79c8b
commit
10c31b82cb
4 changed files with 108 additions and 38 deletions
|
@ -1,4 +1,13 @@
|
||||||
February 21, 2009 (Changes by Graf Zahl)
|
February 21, 2009
|
||||||
|
- Added selective compression of network packets. Interestingly, most packets
|
||||||
|
don't actually compress all that well, even the ones that aren't too short
|
||||||
|
to possibly compress. (Maybe make the whole thing one long, never-ending
|
||||||
|
zlib data stream with Z_SYNC_FLUSH used to chunk things at packet
|
||||||
|
boundaries? That would probably help the compression ratio, but it would
|
||||||
|
require changing the way the netcode determines sequence, which would be
|
||||||
|
a much more invasive change.)
|
||||||
|
|
||||||
|
February 21, 2009 (Changes by Graf Zahl)
|
||||||
- Fixed: Heretic's fullscreen HUD crashed when the player had armor without
|
- Fixed: Heretic's fullscreen HUD crashed when the player had armor without
|
||||||
a valid icon.
|
a valid icon.
|
||||||
- Fixed: The StrifePlayer was missing a RunHealth setting.
|
- Fixed: The StrifePlayer was missing a RunHealth setting.
|
||||||
|
|
|
@ -67,35 +67,6 @@ EXTERN_CVAR (Int, autosavecount)
|
||||||
//#define SIMULATEERRORS (RAND_MAX/3)
|
//#define SIMULATEERRORS (RAND_MAX/3)
|
||||||
#define SIMULATEERRORS 0
|
#define SIMULATEERRORS 0
|
||||||
|
|
||||||
#define NCMD_EXIT 0x80
|
|
||||||
#define NCMD_RETRANSMIT 0x40
|
|
||||||
#define NCMD_SETUP 0x20
|
|
||||||
#define NCMD_MULTI 0x10 // multiple players in this packet
|
|
||||||
#define NCMD_QUITTERS 0x08 // one or more players just quit (packet server only)
|
|
||||||
|
|
||||||
#define NCMD_XTICS 0x03 // packet contains >2 tics
|
|
||||||
#define NCMD_2TICS 0x02 // packet contains 2 tics
|
|
||||||
#define NCMD_1TICS 0x01 // packet contains 1 tic
|
|
||||||
#define NCMD_0TICS 0x00 // packet contains 0 tics
|
|
||||||
|
|
||||||
// [RH]
|
|
||||||
// New generic packet structure:
|
|
||||||
//
|
|
||||||
// Header:
|
|
||||||
// One byte with above flags.
|
|
||||||
// One byte with starttic
|
|
||||||
// One byte with master's maketic (master -> slave only!)
|
|
||||||
// If NCMD_RETRANSMIT set, one byte with retransmitfrom
|
|
||||||
// If NCMD_XTICS set, one byte with number of tics (minus 3, so theoretically up to 258 tics in one packet)
|
|
||||||
// If NCMD_QUITTERS, one byte with number of players followed by one byte with each player's consolenum
|
|
||||||
// If NCMD_MULTI, one byte with number of players followed by one byte with each player's consolenum
|
|
||||||
// - The first player's consolenum is not included in this list, because it always matches the sender
|
|
||||||
//
|
|
||||||
// For each tic:
|
|
||||||
// Two bytes with consistancy check, followed by tic data
|
|
||||||
//
|
|
||||||
// Setup packets are different, and are described just before D_ArbitrateNetStart().
|
|
||||||
|
|
||||||
extern BYTE *demo_p; // [RH] Special "ticcmds" get recorded in demos
|
extern BYTE *demo_p; // [RH] Special "ticcmds" get recorded in demos
|
||||||
extern char savedescription[SAVESTRINGSIZE];
|
extern char savedescription[SAVESTRINGSIZE];
|
||||||
extern FString savegamefile;
|
extern FString savegamefile;
|
||||||
|
|
32
src/d_net.h
32
src/d_net.h
|
@ -48,7 +48,7 @@
|
||||||
// Probably not enough.
|
// Probably not enough.
|
||||||
#define MAX_MSGLEN (BACKUPTICS*10)
|
#define MAX_MSGLEN (BACKUPTICS*10)
|
||||||
#else
|
#else
|
||||||
#define MAX_MSGLEN 1400
|
#define MAX_MSGLEN 14000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CMD_SEND 1
|
#define CMD_SEND 1
|
||||||
|
@ -144,4 +144,34 @@ extern int nettics[MAXNETNODES];
|
||||||
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
||||||
extern int ticdup;
|
extern int ticdup;
|
||||||
|
|
||||||
|
// [RH]
|
||||||
|
// New generic packet structure:
|
||||||
|
//
|
||||||
|
// Header:
|
||||||
|
// One byte with following flags.
|
||||||
|
// One byte with starttic
|
||||||
|
// One byte with master's maketic (master -> slave only!)
|
||||||
|
// If NCMD_RETRANSMIT set, one byte with retransmitfrom
|
||||||
|
// If NCMD_XTICS set, one byte with number of tics (minus 3, so theoretically up to 258 tics in one packet)
|
||||||
|
// If NCMD_QUITTERS, one byte with number of players followed by one byte with each player's consolenum
|
||||||
|
// If NCMD_MULTI, one byte with number of players followed by one byte with each player's consolenum
|
||||||
|
// - The first player's consolenum is not included in this list, because it always matches the sender
|
||||||
|
//
|
||||||
|
// For each tic:
|
||||||
|
// Two bytes with consistancy check, followed by tic data
|
||||||
|
//
|
||||||
|
// Setup packets are different, and are described just before D_ArbitrateNetStart().
|
||||||
|
|
||||||
|
#define NCMD_EXIT 0x80
|
||||||
|
#define NCMD_RETRANSMIT 0x40
|
||||||
|
#define NCMD_SETUP 0x20
|
||||||
|
#define NCMD_MULTI 0x10 // multiple players in this packet
|
||||||
|
#define NCMD_QUITTERS 0x08 // one or more players just quit (packet server only)
|
||||||
|
#define NCMD_COMPRESSED 0x04 // remainder of packet is compressed
|
||||||
|
|
||||||
|
#define NCMD_XTICS 0x03 // packet contains >2 tics
|
||||||
|
#define NCMD_2TICS 0x02 // packet contains 2 tics
|
||||||
|
#define NCMD_1TICS 0x01 // packet contains 1 tic
|
||||||
|
#define NCMD_0TICS 0x00 // packet contains 0 tics
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -64,7 +64,9 @@
|
||||||
|
|
||||||
#include "i_net.h"
|
#include "i_net.h"
|
||||||
|
|
||||||
|
// As per http://support.microsoft.com/kb/q192599/ the standard
|
||||||
|
// size for network buffers is 8k.
|
||||||
|
#define TRANSMIT_SIZE 8000
|
||||||
|
|
||||||
/* [Petteri] Get more portable: */
|
/* [Petteri] Get more portable: */
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
|
@ -133,6 +135,8 @@ struct PreGamePacket
|
||||||
} machines[MAXNETNODES];
|
} machines[MAXNETNODES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BYTE TransmitBuffer[TRANSMIT_SIZE];
|
||||||
|
|
||||||
//
|
//
|
||||||
// UDPsocket
|
// UDPsocket
|
||||||
//
|
//
|
||||||
|
@ -191,11 +195,47 @@ void PacketSend (void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
//printf ("sending %i\n",gametic);
|
// FIXME: Catch this before we've overflown the buffer. With long chat
|
||||||
c = sendto (mysocket , (const char*)doomcom.data, doomcom.datalength
|
// text and lots of backup tics, it could conceivably happen. (Though
|
||||||
,0,(sockaddr *)&sendaddress[doomcom.remotenode]
|
// apparently it hasn't yet, which is good.)
|
||||||
,sizeof(sendaddress[doomcom.remotenode]));
|
if (doomcom.datalength > MAX_MSGLEN)
|
||||||
|
{
|
||||||
|
I_FatalError("Netbuffer overflow!");
|
||||||
|
}
|
||||||
|
|
||||||
|
uLong size = TRANSMIT_SIZE - 1;
|
||||||
|
if (doomcom.datalength >= 10)
|
||||||
|
{
|
||||||
|
assert(!(doomcom.data[0] & NCMD_COMPRESSED));
|
||||||
|
TransmitBuffer[0] = doomcom.data[0] | NCMD_COMPRESSED;
|
||||||
|
c = compress2(TransmitBuffer + 1, &size, doomcom.data + 1, doomcom.datalength - 1, 9);
|
||||||
|
size += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = -1; // Just some random error code to avoid sending the compressed buffer.
|
||||||
|
}
|
||||||
|
if (c == Z_OK && size < (uLong)doomcom.datalength)
|
||||||
|
{
|
||||||
|
// Printf("send %lu/%d\n", size, doomcom.datalength);
|
||||||
|
c = sendto(mysocket, (char *)TransmitBuffer, size,
|
||||||
|
0, (sockaddr *)&sendaddress[doomcom.remotenode],
|
||||||
|
sizeof(sendaddress[doomcom.remotenode]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (doomcom.datalength > TRANSMIT_SIZE)
|
||||||
|
{
|
||||||
|
I_Error("Net compression failed (zlib error %d)", c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Printf("send %d\n", doomcom.datalength);
|
||||||
|
c = sendto(mysocket, (char *)doomcom.data, doomcom.datalength,
|
||||||
|
0, (sockaddr *)&sendaddress[doomcom.remotenode],
|
||||||
|
sizeof(sendaddress[doomcom.remotenode]));
|
||||||
|
}
|
||||||
|
}
|
||||||
// if (c == -1)
|
// if (c == -1)
|
||||||
// I_Error ("SendPacket error: %s",strerror(errno));
|
// I_Error ("SendPacket error: %s",strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -212,8 +252,8 @@ void PacketGet (void)
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
fromlen = sizeof(fromaddress);
|
fromlen = sizeof(fromaddress);
|
||||||
c = recvfrom (mysocket, (char*)doomcom.data, MAX_MSGLEN, 0
|
c = recvfrom (mysocket, (char*)TransmitBuffer, TRANSMIT_SIZE, 0,
|
||||||
, (sockaddr *)&fromaddress, &fromlen);
|
(sockaddr *)&fromaddress, &fromlen);
|
||||||
node = FindNode (&fromaddress);
|
node = FindNode (&fromaddress);
|
||||||
|
|
||||||
if (node >= 0 && c == SOCKET_ERROR)
|
if (node >= 0 && c == SOCKET_ERROR)
|
||||||
|
@ -239,6 +279,26 @@ void PacketGet (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (c > 0)
|
||||||
|
{
|
||||||
|
doomcom.data[0] = TransmitBuffer[0] & ~NCMD_COMPRESSED;
|
||||||
|
if (TransmitBuffer[0] & NCMD_COMPRESSED)
|
||||||
|
{
|
||||||
|
uLongf msgsize = MAX_MSGLEN - 1;
|
||||||
|
int err = uncompress(doomcom.data + 1, &msgsize, TransmitBuffer + 1, c - 1);
|
||||||
|
// Printf("recv %d/%lu\n", c, msgsize + 1);
|
||||||
|
if (err != Z_OK)
|
||||||
|
{
|
||||||
|
I_Error("Net decompression failed (zlib error %d)\n", err);
|
||||||
|
}
|
||||||
|
c = msgsize + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Printf("recv %d\n", c);
|
||||||
|
memcpy(doomcom.data + 1, TransmitBuffer + 1, c - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
doomcom.remotenode = node;
|
doomcom.remotenode = node;
|
||||||
doomcom.datalength = (short)c;
|
doomcom.datalength = (short)c;
|
||||||
|
|
Loading…
Reference in a new issue