diff options
author | Thilo Schulz <arny@ats.s.bawue.de> | 2011-07-27 15:47:29 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-10 22:36:32 +0000 |
commit | 34e5d1056d0cd83648db904549a368ef904e2be8 (patch) | |
tree | 94f69d7546b28b8b8854b06526b70934a65c0dc0 /src/server | |
parent | d28ee7e3da161ae9a9e9f339291001948672dae7 (diff) |
- Apply parts of Ben Millwood's target bitfield patch (#3787) - Fix Ryan's FIXME and have voip packet buffer on the server dynamically allocated via Z_Malloc and store pointers in a circular buffer - Improve voip target parsing on top of Ben Millwood's patch - Add new "spatial" target where speaker is spatialized in 3d space and can be heard by all clients in hearing range (s_alMaxDistance) (#4467) - Decrease voip sound lengths from 240ms to 80ms per voip packet to mitigate udp packet loss and decrease latency - Protocol version incremented to 71
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/server.h | 5 | ||||
-rw-r--r-- | src/server/sv_client.c | 116 | ||||
-rw-r--r-- | src/server/sv_init.c | 4 | ||||
-rw-r--r-- | src/server/sv_snapshot.c | 55 |
4 files changed, 86 insertions, 94 deletions
diff --git a/src/server/server.h b/src/server/server.h index daa0dee7..de4ecc27 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -44,6 +44,7 @@ typedef struct voipServerPacket_s int frames; int len; int sender; + int flags; byte data[1024]; } voipServerPacket_t; #endif @@ -345,10 +346,6 @@ int SV_WriteDownloadToClient(client_t *cl , msg_t *msg); int SV_SendDownloadMessages(void); int SV_SendQueuedMessages(void); -#ifdef USE_VOIP -void SV_WriteVoipToClient( client_t *cl, msg_t *msg ); -#endif - // // sv_ccmds.c diff --git a/src/server/sv_client.c b/src/server/sv_client.c index 379826a2..25bf69f9 100644 --- a/src/server/sv_client.c +++ b/src/server/sv_client.c @@ -925,56 +925,6 @@ int SV_SendDownloadMessages(void) return numDLs; } -#ifdef USE_VOIP -/* -================== -SV_WriteVoipToClient - -Check to see if there is any VoIP queued for a client, and send if there is. -================== -*/ -void SV_WriteVoipToClient( client_t *cl, msg_t *msg ) -{ - if(*cl->downloadName) - { - cl->queuedVoipPackets = 0; - return; // no VoIP allowed if download is going, to save bandwidth. - } - - if(cl->queuedVoipPackets) - { - int totalbytes = 0; - int i; - voipServerPacket_t *packet; - - // Write as many VoIP packets as we reasonably can... - for(i = cl->queuedVoipIndex; i < cl->queuedVoipPackets; i++) - { - packet = cl->voipPacket[i % ARRAY_LEN(cl->voipPacket)]; - - totalbytes += packet->len; - if (totalbytes > (msg->maxsize - msg->cursize) / 2) - break; - - MSG_WriteByte(msg, svc_voip); - MSG_WriteShort(msg, packet->sender); - MSG_WriteByte(msg, (byte) packet->generation); - MSG_WriteLong(msg, packet->sequence); - MSG_WriteByte(msg, packet->frames); - MSG_WriteShort(msg, packet->len); - MSG_WriteData(msg, packet->data, packet->len); - - Z_Free(packet); - } - - cl->queuedVoipPackets -= i; - cl->queuedVoipIndex += i; - cl->queuedVoipIndex %= ARRAY_LEN(cl->voipPacket); - } -} -#endif - - /* ================= SV_Disconnect_f @@ -1555,8 +1505,15 @@ static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) { #ifdef USE_VOIP -static -qboolean SV_ShouldIgnoreVoipSender(const client_t *cl) +/* +================== +SV_ShouldIgnoreVoipSender + +Blocking of voip packets based on source client +================== +*/ + +static qboolean SV_ShouldIgnoreVoipSender(const client_t *cl) { if (!sv_voip->integer) return qtrue; // VoIP disabled on this server. @@ -1569,33 +1526,25 @@ qboolean SV_ShouldIgnoreVoipSender(const client_t *cl) } static -void SV_UserVoip( client_t *cl, msg_t *msg ) { - const int sender = (int) (cl - svs.clients); - const int generation = MSG_ReadByte(msg); - const int sequence = MSG_ReadLong(msg); - const int frames = MSG_ReadByte(msg); - const int recip1 = MSG_ReadLong(msg); - const int recip2 = MSG_ReadLong(msg); - const int recip3 = MSG_ReadLong(msg); - const int packetsize = MSG_ReadShort(msg); +void SV_UserVoip(client_t *cl, msg_t *msg) +{ + int sender, generation, sequence, frames, packetsize; + uint8_t recips[(MAX_CLIENTS + 7) / 8]; + int flags; byte encoded[sizeof(cl->voipPacket[0]->data)]; client_t *client = NULL; voipServerPacket_t *packet = NULL; int i; - if (generation < 0) - return; // short/invalid packet, bail. - else if (sequence < 0) - return; // short/invalid packet, bail. - else if (frames < 0) - return; // short/invalid packet, bail. - else if (recip1 < 0) - return; // short/invalid packet, bail. - else if (recip2 < 0) - return; // short/invalid packet, bail. - else if (recip3 < 0) - return; // short/invalid packet, bail. - else if (packetsize < 0) + sender = cl - svs.clients; + generation = MSG_ReadByte(msg); + sequence = MSG_ReadLong(msg); + frames = MSG_ReadByte(msg); + MSG_ReadData(msg, recips, sizeof(recips)); + flags = MSG_ReadByte(msg); + packetsize = MSG_ReadShort(msg); + + if (msg->readcount > msg->cursize) return; // short/invalid packet, bail. if (packetsize > sizeof (encoded)) { // overlarge packet? @@ -1620,10 +1569,6 @@ void SV_UserVoip( client_t *cl, msg_t *msg ) { // !!! FIXME: reject if not speex narrowband codec. // !!! FIXME: decide if this is bogus data? - // (the three recip* values are 31 bits each (ignores sign bit so we can - // get a -1 error from MSG_ReadLong() ... ), allowing for 93 clients.) - assert( sv_maxclients->integer < 93 ); - // decide who needs this VoIP packet sent to them... for (i = 0, client = svs.clients; i < sv_maxclients->integer ; i++, client++) { if (client->state != CS_ACTIVE) @@ -1631,18 +1576,20 @@ void SV_UserVoip( client_t *cl, msg_t *msg ) { else if (i == sender) continue; // don't send voice packet back to original author. else if (!client->hasVoip) - continue; // no VoIP support, or support disabled. + continue; // no VoIP support, or unsupported protocol else if (client->muteAllVoip) continue; // client is ignoring everyone. else if (client->ignoreVoipFromClient[sender]) continue; // client is ignoring this talker. else if (*cl->downloadName) // !!! FIXME: possible to DoS? continue; // no VoIP allowed if downloading, to save bandwidth. - else if ( ((i >= 0) && (i < 31)) && ((recip1 & (1 << (i-0))) == 0) ) - continue; // not addressed to this player. - else if ( ((i >= 31) && (i < 62)) && ((recip2 & (1 << (i-31))) == 0) ) - continue; // not addressed to this player. - else if ( ((i >= 62) && (i < 93)) && ((recip3 & (1 << (i-62))) == 0) ) + + if(Com_IsVoipTarget(recips, sizeof(recips), i)) + flags |= VOIP_DIRECT; + else + flags &= ~VOIP_DIRECT; + + if (!(flags & (VOIP_SPATIAL | VOIP_DIRECT))) continue; // not addressed to this player. // Transmit this packet to the client. @@ -1657,6 +1604,7 @@ void SV_UserVoip( client_t *cl, msg_t *msg ) { packet->len = packetsize; packet->generation = generation; packet->sequence = sequence; + packet->flags = flags; memcpy(packet->data, encoded, packetsize); client->voipPacket[(client->queuedVoipIndex + client->queuedVoipPackets) % ARRAY_LEN(client->voipPacket)] = packet; diff --git a/src/server/sv_init.c b/src/server/sv_init.c index c5d11e74..d2326db5 100644 --- a/src/server/sv_init.c +++ b/src/server/sv_init.c @@ -643,8 +643,8 @@ void SV_Init (void) sv_serverid = Cvar_Get ("sv_serverid", "0", CVAR_SYSTEMINFO | CVAR_ROM ); sv_pure = Cvar_Get ("sv_pure", "1", CVAR_SYSTEMINFO ); #ifdef USE_VOIP - sv_voip = Cvar_Get ("sv_voip", "1", CVAR_SYSTEMINFO | CVAR_LATCH); - Cvar_CheckRange( sv_voip, 0, 1, qtrue ); + sv_voip = Cvar_Get("sv_voip", "1", CVAR_SYSTEMINFO | CVAR_LATCH); + Cvar_CheckRange(sv_voip, 0, 1, qtrue); #endif Cvar_Get ("sv_paks", "", CVAR_SYSTEMINFO | CVAR_ROM ); Cvar_Get ("sv_pakNames", "", CVAR_SYSTEMINFO | CVAR_ROM ); diff --git a/src/server/sv_snapshot.c b/src/server/sv_snapshot.c index ddd87cc6..a16b6b2c 100644 --- a/src/server/sv_snapshot.c +++ b/src/server/sv_snapshot.c @@ -522,6 +522,53 @@ static void SV_BuildClientSnapshot( client_t *client ) { } } +#ifdef USE_VOIP +/* +================== +SV_WriteVoipToClient + +Check to see if there is any VoIP queued for a client, and send if there is. +================== +*/ +static void SV_WriteVoipToClient(client_t *cl, msg_t *msg) +{ + int totalbytes = 0; + int i; + voipServerPacket_t *packet; + + if(cl->queuedVoipPackets) + { + // Write as many VoIP packets as we reasonably can... + for(i = 0; i < cl->queuedVoipPackets; i++) + { + packet = cl->voipPacket[(i + cl->queuedVoipIndex) % ARRAY_LEN(cl->voipPacket)]; + + if(!*cl->downloadName) + { + totalbytes += packet->len; + if (totalbytes > (msg->maxsize - msg->cursize) / 2) + break; + + MSG_WriteByte(msg, svc_voip); + MSG_WriteShort(msg, packet->sender); + MSG_WriteByte(msg, (byte) packet->generation); + MSG_WriteLong(msg, packet->sequence); + MSG_WriteByte(msg, packet->frames); + MSG_WriteShort(msg, packet->len); + MSG_WriteBits(msg, packet->flags, VOIP_FLAGCNT); + MSG_WriteData(msg, packet->data, packet->len); + } + + Z_Free(packet); + } + + cl->queuedVoipPackets -= i; + cl->queuedVoipIndex += i; + cl->queuedVoipIndex %= ARRAY_LEN(cl->voipPacket); + } +} +#endif + /* ======================= SV_SendMessageToClient @@ -605,11 +652,11 @@ void SV_SendClientMessages(void) if(*c->downloadName) continue; // Client is downloading, don't send snapshots - if(c->netchan.unsentFragments || c->netchan_start_queue) - { - c->rateDelayed = qtrue; + if(c->netchan.unsentFragments || c->netchan_start_queue) + { + c->rateDelayed = qtrue; continue; // Drop this snapshot if the packet queue is still full or delta compression will break - } + } if(!(c->netchan.remoteAddress.type == NA_LOOPBACK || (sv_lanForceRate->integer && Sys_IsLANAddress(c->netchan.remoteAddress)))) |