mirror of
https://github.com/UberGames/lilium-voyager.git
synced 2024-12-13 13:40:56 +00:00
Changed the protocol for VoIP packets to support legacy clients.
Previously, a legacy client wouldn't get a VoIP packet, but if they did, they'd panic and disconnect. Now they ignore them and continue on. This also gives us the framework to add other features legacy clients can ignore. Oh, this also has the benefit of allowing us to store incoming VoIP for playback in recorded demos. They'll play the chatter on VoIP clients, and be ignored on legacy ones. Huge win.
This commit is contained in:
parent
e0ebde0b27
commit
8ab3f7af8d
6 changed files with 79 additions and 16 deletions
|
@ -760,6 +760,8 @@ void CL_WritePacket( void ) {
|
||||||
|
|
||||||
#if USE_VOIP
|
#if USE_VOIP
|
||||||
if (clc.voipOutgoingDataSize > 0) { // only send if data.
|
if (clc.voipOutgoingDataSize > 0) { // only send if data.
|
||||||
|
MSG_WriteByte (&buf, clc_EOF); // placate legacy servers.
|
||||||
|
MSG_WriteByte (&buf, clc_extension);
|
||||||
MSG_WriteByte (&buf, clc_voip);
|
MSG_WriteByte (&buf, clc_voip);
|
||||||
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
|
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
|
||||||
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
|
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
|
||||||
|
|
|
@ -34,10 +34,8 @@ char *svc_strings[256] = {
|
||||||
"svc_download",
|
"svc_download",
|
||||||
"svc_snapshot",
|
"svc_snapshot",
|
||||||
"svc_EOF",
|
"svc_EOF",
|
||||||
|
"svc_extension",
|
||||||
#if USE_VOIP
|
"svc_voip",
|
||||||
"svc_voip"
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void SHOWNET( msg_t *msg, char *s) {
|
void SHOWNET( msg_t *msg, char *s) {
|
||||||
|
@ -854,13 +852,26 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
||||||
|
|
||||||
cmd = MSG_ReadByte( msg );
|
cmd = MSG_ReadByte( msg );
|
||||||
|
|
||||||
if ( cmd == svc_EOF) {
|
// See if this is an extension command after the EOF, which means we
|
||||||
|
// got data that a legacy client should ignore.
|
||||||
|
if ((cmd == svc_EOF) && (MSG_LookaheadByte( msg ) == svc_extension)) {
|
||||||
|
SHOWNET( msg, "EXTENSION" );
|
||||||
|
MSG_ReadByte( msg ); // throw the svc_extension byte away.
|
||||||
|
cmd = MSG_ReadByte( msg ); // something legacy clients can't do!
|
||||||
|
// sometimes you get a svc_extension at end of stream...dangling
|
||||||
|
// bits in the huffman decoder giving a bogus value?
|
||||||
|
if (cmd == -1) {
|
||||||
|
cmd = svc_EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == svc_EOF) {
|
||||||
SHOWNET( msg, "END OF MESSAGE" );
|
SHOWNET( msg, "END OF MESSAGE" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cl_shownet->integer >= 2 ) {
|
if ( cl_shownet->integer >= 2 ) {
|
||||||
if ( !svc_strings[cmd] ) {
|
if ( (cmd < 0) || (!svc_strings[cmd]) ) {
|
||||||
Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd );
|
Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd );
|
||||||
} else {
|
} else {
|
||||||
SHOWNET( msg, svc_strings[cmd] );
|
SHOWNET( msg, svc_strings[cmd] );
|
||||||
|
@ -886,11 +897,11 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
||||||
case svc_download:
|
case svc_download:
|
||||||
CL_ParseDownload( msg );
|
CL_ParseDownload( msg );
|
||||||
break;
|
break;
|
||||||
#if USE_VOIP
|
|
||||||
case svc_voip:
|
case svc_voip:
|
||||||
|
#if USE_VOIP
|
||||||
CL_ParseVoip( msg );
|
CL_ParseVoip( msg );
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,16 @@ void Huff_putBit( int bit, byte *fout, int *offset) {
|
||||||
*offset = bloc;
|
*offset = bloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Huff_getBloc(void)
|
||||||
|
{
|
||||||
|
return bloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Huff_setBloc(int _bloc)
|
||||||
|
{
|
||||||
|
bloc = _bloc;
|
||||||
|
}
|
||||||
|
|
||||||
int Huff_getBit( byte *fin, int *offset) {
|
int Huff_getBit( byte *fin, int *offset) {
|
||||||
int t;
|
int t;
|
||||||
bloc = *offset;
|
bloc = *offset;
|
||||||
|
|
|
@ -389,6 +389,17 @@ int MSG_ReadByte( msg_t *msg ) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MSG_LookaheadByte( msg_t *msg ) {
|
||||||
|
const int bloc = Huff_getBloc();
|
||||||
|
const int readcount = msg->readcount;
|
||||||
|
const int bit = msg->bit;
|
||||||
|
int c = MSG_ReadByte(msg);
|
||||||
|
Huff_setBloc(bloc);
|
||||||
|
msg->readcount = readcount;
|
||||||
|
msg->bit = bit;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
int MSG_ReadShort( msg_t *msg ) {
|
int MSG_ReadShort( msg_t *msg ) {
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ char *MSG_ReadBigString (msg_t *sb);
|
||||||
char *MSG_ReadStringLine (msg_t *sb);
|
char *MSG_ReadStringLine (msg_t *sb);
|
||||||
float MSG_ReadAngle16 (msg_t *sb);
|
float MSG_ReadAngle16 (msg_t *sb);
|
||||||
void MSG_ReadData (msg_t *sb, void *buffer, int size);
|
void MSG_ReadData (msg_t *sb, void *buffer, int size);
|
||||||
|
int MSG_LookaheadByte (msg_t *msg);
|
||||||
|
|
||||||
void MSG_WriteDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
void MSG_WriteDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||||
void MSG_ReadDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
void MSG_ReadDeltaUsercmd( msg_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||||
|
@ -276,9 +276,10 @@ enum svc_ops_e {
|
||||||
svc_snapshot,
|
svc_snapshot,
|
||||||
svc_EOF,
|
svc_EOF,
|
||||||
|
|
||||||
#if USE_VOIP
|
// svc_extension follows a svc_EOF, followed by another svc_* ...
|
||||||
svc_voip
|
// this keeps legacy clients compatible.
|
||||||
#endif
|
svc_extension,
|
||||||
|
svc_voip, // not wrapped in USE_VOIP, so this value is reserved.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,9 +294,10 @@ enum clc_ops_e {
|
||||||
clc_clientCommand, // [string] message
|
clc_clientCommand, // [string] message
|
||||||
clc_EOF,
|
clc_EOF,
|
||||||
|
|
||||||
#if USE_VOIP
|
// clc_extension follows a clc_EOF, followed by another clc_* ...
|
||||||
clc_voip, // packet of voice data.
|
// this keeps legacy servers compatible.
|
||||||
#endif
|
clc_extension,
|
||||||
|
clc_voip, // not wrapped in USE_VOIP, so this value is reserved.
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1112,6 +1114,11 @@ void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset);
|
||||||
void Huff_putBit( int bit, byte *fout, int *offset);
|
void Huff_putBit( int bit, byte *fout, int *offset);
|
||||||
int Huff_getBit( byte *fout, int *offset);
|
int Huff_getBit( byte *fout, int *offset);
|
||||||
|
|
||||||
|
// don't use if you don't know what you're doing.
|
||||||
|
int Huff_getBloc(void);
|
||||||
|
void Huff_setBloc(int _bloc);
|
||||||
|
|
||||||
|
|
||||||
extern huffman_t clientHuffTables;
|
extern huffman_t clientHuffTables;
|
||||||
|
|
||||||
#define SV_ENCODE_START 4
|
#define SV_ENCODE_START 4
|
||||||
|
|
|
@ -1108,6 +1108,14 @@ void SV_WriteVoipToClient( client_t *cl, msg_t *msg )
|
||||||
if (totalbytes > MAX_DOWNLOAD_BLKSIZE)
|
if (totalbytes > MAX_DOWNLOAD_BLKSIZE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// You have to start with a svc_EOF, so legacy clients drop the
|
||||||
|
// rest of this packet. Otherwise, those without VoIP support will
|
||||||
|
// see the svc_voip command, then panic and disconnect.
|
||||||
|
// Generally we don't send VoIP packets to legacy clients, but this
|
||||||
|
// serves as both a safety measure and a means to keep demo files
|
||||||
|
// compatible.
|
||||||
|
MSG_WriteByte( msg, svc_EOF );
|
||||||
|
MSG_WriteByte( msg, svc_extension );
|
||||||
MSG_WriteByte( msg, svc_voip );
|
MSG_WriteByte( msg, svc_voip );
|
||||||
MSG_WriteShort( msg, packet->sender );
|
MSG_WriteShort( msg, packet->sender );
|
||||||
MSG_WriteByte( msg, (byte) packet->generation );
|
MSG_WriteByte( msg, (byte) packet->generation );
|
||||||
|
@ -1880,9 +1888,23 @@ void SV_ExecuteClientMessage( client_t *cl, msg_t *msg ) {
|
||||||
// read optional clientCommand strings
|
// read optional clientCommand strings
|
||||||
do {
|
do {
|
||||||
c = MSG_ReadByte( msg );
|
c = MSG_ReadByte( msg );
|
||||||
|
|
||||||
|
// See if this is an extension command after the EOF, which means we
|
||||||
|
// got data that a legacy server should ignore.
|
||||||
|
if ((c == clc_EOF) && (MSG_LookaheadByte( msg ) == clc_extension)) {
|
||||||
|
MSG_ReadByte( msg ); // throw the clc_extension byte away.
|
||||||
|
c = MSG_ReadByte( msg ); // something legacy servers can't do!
|
||||||
|
// sometimes you get a clc_extension at end of stream...dangling
|
||||||
|
// bits in the huffman decoder giving a bogus value?
|
||||||
|
if (c == -1) {
|
||||||
|
c = clc_EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( c == clc_EOF ) {
|
if ( c == clc_EOF ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( c != clc_clientCommand ) {
|
if ( c != clc_clientCommand ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1899,8 +1921,8 @@ void SV_ExecuteClientMessage( client_t *cl, msg_t *msg ) {
|
||||||
SV_UserMove( cl, msg, qtrue );
|
SV_UserMove( cl, msg, qtrue );
|
||||||
} else if ( c == clc_moveNoDelta ) {
|
} else if ( c == clc_moveNoDelta ) {
|
||||||
SV_UserMove( cl, msg, qfalse );
|
SV_UserMove( cl, msg, qfalse );
|
||||||
#if USE_VOIP
|
|
||||||
} else if ( c == clc_voip ) {
|
} else if ( c == clc_voip ) {
|
||||||
|
#if USE_VOIP
|
||||||
SV_UserVoip( cl, msg );
|
SV_UserVoip( cl, msg );
|
||||||
#endif
|
#endif
|
||||||
} else if ( c != clc_EOF ) {
|
} else if ( c != clc_EOF ) {
|
||||||
|
|
Loading…
Reference in a new issue