summaryrefslogtreecommitdiff
path: root/src/client/cl_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/cl_main.c')
-rw-r--r--src/client/cl_main.c754
1 files changed, 572 insertions, 182 deletions
diff --git a/src/client/cl_main.c b/src/client/cl_main.c
index 326bc5f6..444b877d 100644
--- a/src/client/cl_main.c
+++ b/src/client/cl_main.c
@@ -25,6 +25,26 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "client.h"
#include <limits.h>
+#ifdef USE_MUMBLE
+#include "libmumblelink.h"
+#endif
+
+#ifdef USE_MUMBLE
+cvar_t *cl_useMumble;
+cvar_t *cl_mumbleScale;
+#endif
+
+#ifdef USE_VOIP
+cvar_t *cl_voipUseVAD;
+cvar_t *cl_voipVADThreshold;
+cvar_t *cl_voipSend;
+cvar_t *cl_voipSendTarget;
+cvar_t *cl_voipGainDuringCapture;
+cvar_t *cl_voipCaptureMult;
+cvar_t *cl_voipShowMeter;
+cvar_t *cl_voip;
+#endif
+
cvar_t *cl_nodelta;
cvar_t *cl_debugMove;
@@ -37,7 +57,6 @@ cvar_t *rconAddress;
cvar_t *cl_timeout;
cvar_t *cl_maxpackets;
cvar_t *cl_packetdup;
-cvar_t *cl_master;
cvar_t *cl_timeNudge;
cvar_t *cl_showTimeDelta;
cvar_t *cl_freezeDemo;
@@ -123,6 +142,284 @@ void CL_CDDialog( void ) {
cls.cddialog = qtrue; // start it next frame
}
+#ifdef USE_MUMBLE
+static
+void CL_UpdateMumble(void)
+{
+ vec3_t pos, forward, up;
+ float scale = cl_mumbleScale->value;
+ float tmp;
+
+ if(!cl_useMumble->integer)
+ return;
+
+ // !!! FIXME: not sure if this is even close to correct.
+ AngleVectors( cl.snap.ps.viewangles, forward, NULL, up);
+
+ pos[0] = cl.snap.ps.origin[0] * scale;
+ pos[1] = cl.snap.ps.origin[2] * scale;
+ pos[2] = cl.snap.ps.origin[1] * scale;
+
+ tmp = forward[1];
+ forward[1] = forward[2];
+ forward[2] = tmp;
+
+ tmp = up[1];
+ up[1] = up[2];
+ up[2] = tmp;
+
+ if(cl_useMumble->integer > 1) {
+ fprintf(stderr, "%f %f %f, %f %f %f, %f %f %f\n",
+ pos[0], pos[1], pos[2],
+ forward[0], forward[1], forward[2],
+ up[0], up[1], up[2]);
+ }
+
+ mumble_update_coordinates(pos, forward, up);
+}
+#endif
+
+
+#ifdef USE_VOIP
+static
+void CL_UpdateVoipIgnore(const char *idstr, qboolean ignore)
+{
+ if ((*idstr >= '0') && (*idstr <= '9')) {
+ const int id = atoi(idstr);
+ if ((id >= 0) && (id < MAX_CLIENTS)) {
+ clc.voipIgnore[id] = ignore;
+ CL_AddReliableCommand(va("voip %s %d",
+ ignore ? "ignore" : "unignore", id));
+ Com_Printf("VoIP: %s ignoring player #%d\n",
+ ignore ? "Now" : "No longer", id);
+ }
+ }
+}
+
+static
+void CL_UpdateVoipGain(const char *idstr, float gain)
+{
+ if ((*idstr >= '0') && (*idstr <= '9')) {
+ const int id = atoi(idstr);
+ if (gain < 0.0f)
+ gain = 0.0f;
+ if ((id >= 0) && (id < MAX_CLIENTS)) {
+ clc.voipGain[id] = gain;
+ Com_Printf("VoIP: player #%d gain now set to %f\n", id, gain);
+ }
+ }
+}
+
+void CL_Voip_f( void )
+{
+ const char *cmd = Cmd_Argv(1);
+ const char *reason = NULL;
+
+ if (cls.state != CA_ACTIVE)
+ reason = "Not connected to a server";
+ else if (!clc.speexInitialized)
+ reason = "Speex not initialized";
+ else if (!cl_connectedToVoipServer)
+ reason = "Server doesn't support VoIP";
+
+ if (reason != NULL) {
+ Com_Printf("VoIP: command ignored: %s\n", reason);
+ return;
+ }
+
+ if (strcmp(cmd, "ignore") == 0) {
+ CL_UpdateVoipIgnore(Cmd_Argv(2), qtrue);
+ } else if (strcmp(cmd, "unignore") == 0) {
+ CL_UpdateVoipIgnore(Cmd_Argv(2), qfalse);
+ } else if (strcmp(cmd, "gain") == 0) {
+ CL_UpdateVoipGain(Cmd_Argv(2), atof(Cmd_Argv(3)));
+ } else if (strcmp(cmd, "muteall") == 0) {
+ Com_Printf("VoIP: muting incoming voice\n");
+ CL_AddReliableCommand("voip muteall");
+ clc.voipMuteAll = qtrue;
+ } else if (strcmp(cmd, "unmuteall") == 0) {
+ Com_Printf("VoIP: unmuting incoming voice\n");
+ CL_AddReliableCommand("voip unmuteall");
+ clc.voipMuteAll = qfalse;
+ }
+}
+
+
+static
+void CL_VoipNewGeneration(void)
+{
+ // don't have a zero generation so new clients won't match, and don't
+ // wrap to negative so MSG_ReadLong() doesn't "fail."
+ clc.voipOutgoingGeneration++;
+ if (clc.voipOutgoingGeneration <= 0)
+ clc.voipOutgoingGeneration = 1;
+ clc.voipPower = 0.0f;
+ clc.voipOutgoingSequence = 0;
+}
+
+/*
+===============
+CL_CaptureVoip
+
+Record more audio from the hardware if required and encode it into Speex
+ data for later transmission.
+===============
+*/
+static
+void CL_CaptureVoip(void)
+{
+ const float audioMult = cl_voipCaptureMult->value;
+ const qboolean useVad = (cl_voipUseVAD->integer != 0);
+ qboolean initialFrame = qfalse;
+ qboolean finalFrame = qfalse;
+
+#if USE_MUMBLE
+ // if we're using Mumble, don't try to handle VoIP transmission ourselves.
+ if (cl_useMumble->integer)
+ return;
+#endif
+
+ if (!clc.speexInitialized)
+ return; // just in case this gets called at a bad time.
+
+ if (clc.voipOutgoingDataSize > 0)
+ return; // packet is pending transmission, don't record more yet.
+
+ if (cl_voipUseVAD->modified) {
+ Cvar_Set("cl_voipSend", (useVad) ? "1" : "0");
+ cl_voipUseVAD->modified = qfalse;
+ }
+
+ if ((useVad) && (!cl_voipSend->integer))
+ Cvar_Set("cl_voipSend", "1"); // lots of things reset this.
+
+ if (cl_voipSend->modified) {
+ qboolean dontCapture = qfalse;
+ if (cls.state != CA_ACTIVE)
+ dontCapture = qtrue; // not connected to a server.
+ else if (!cl_connectedToVoipServer)
+ dontCapture = qtrue; // server doesn't support VoIP.
+ else if (clc.demoplaying)
+ dontCapture = qtrue; // playing back a demo.
+ else if ( cl_voip->integer == 0 )
+ dontCapture = qtrue; // client has VoIP support disabled.
+ else if ( audioMult == 0.0f )
+ dontCapture = qtrue; // basically silenced incoming audio.
+
+ cl_voipSend->modified = qfalse;
+
+ if (dontCapture) {
+ cl_voipSend->integer = 0;
+ return;
+ }
+
+ if (cl_voipSend->integer) {
+ initialFrame = qtrue;
+ } else {
+ finalFrame = qtrue;
+ }
+ }
+
+ // try to get more audio data from the sound card...
+
+ if (initialFrame) {
+ float gain = cl_voipGainDuringCapture->value;
+ if (gain < 0.0f) gain = 0.0f; else if (gain >= 1.0f) gain = 1.0f;
+ S_MasterGain(cl_voipGainDuringCapture->value);
+ S_StartCapture();
+ CL_VoipNewGeneration();
+ }
+
+ if ((cl_voipSend->integer) || (finalFrame)) { // user wants to capture audio?
+ int samples = S_AvailableCaptureSamples();
+ const int mult = (finalFrame) ? 1 : 12; // 12 == 240ms of audio.
+
+ // enough data buffered in audio hardware to process yet?
+ if (samples >= (clc.speexFrameSize * mult)) {
+ // audio capture is always MONO16 (and that's what speex wants!).
+ // 2048 will cover 12 uncompressed frames in narrowband mode.
+ static int16_t sampbuffer[2048];
+ float voipPower = 0.0f;
+ int speexFrames = 0;
+ int wpos = 0;
+ int pos = 0;
+
+ if (samples > (clc.speexFrameSize * 12))
+ samples = (clc.speexFrameSize * 12);
+
+ // !!! FIXME: maybe separate recording from encoding, so voipPower
+ // !!! FIXME: updates faster than 4Hz?
+
+ samples -= samples % clc.speexFrameSize;
+ S_Capture(samples, (byte *) sampbuffer); // grab from audio card.
+
+ // this will probably generate multiple speex packets each time.
+ while (samples > 0) {
+ int16_t *sampptr = &sampbuffer[pos];
+ int i, bytes;
+
+ // preprocess samples to remove noise...
+ speex_preprocess_run(clc.speexPreprocessor, sampptr);
+
+ // check the "power" of this packet...
+ for (i = 0; i < clc.speexFrameSize; i++) {
+ const float flsamp = (float) sampptr[i];
+ const float s = fabs(flsamp);
+ voipPower += s * s;
+ sampptr[i] = (int16_t) ((flsamp) * audioMult);
+ }
+
+ // encode raw audio samples into Speex data...
+ speex_bits_reset(&clc.speexEncoderBits);
+ speex_encode_int(clc.speexEncoder, sampptr,
+ &clc.speexEncoderBits);
+ bytes = speex_bits_write(&clc.speexEncoderBits,
+ (char *) &clc.voipOutgoingData[wpos+1],
+ sizeof (clc.voipOutgoingData) - (wpos+1));
+ assert((bytes > 0) && (bytes < 256));
+ clc.voipOutgoingData[wpos] = (byte) bytes;
+ wpos += bytes + 1;
+
+ // look at the data for the next packet...
+ pos += clc.speexFrameSize;
+ samples -= clc.speexFrameSize;
+ speexFrames++;
+ }
+
+ clc.voipPower = (voipPower / (32768.0f * 32768.0f *
+ ((float) (clc.speexFrameSize * speexFrames)))) *
+ 100.0f;
+
+ if ((useVad) && (clc.voipPower < cl_voipVADThreshold->value)) {
+ CL_VoipNewGeneration(); // no "talk" for at least 1/4 second.
+ } else {
+ clc.voipOutgoingDataSize = wpos;
+ clc.voipOutgoingDataFrames = speexFrames;
+
+ Com_DPrintf("VoIP: Send %d frames, %d bytes, %f power\n",
+ speexFrames, wpos, clc.voipPower);
+
+ #if 0
+ static FILE *encio = NULL;
+ if (encio == NULL) encio = fopen("voip-outgoing-encoded.bin", "wb");
+ if (encio != NULL) { fwrite(clc.voipOutgoingData, wpos, 1, encio); fflush(encio); }
+ static FILE *decio = NULL;
+ if (decio == NULL) decio = fopen("voip-outgoing-decoded.bin", "wb");
+ if (decio != NULL) { fwrite(sampbuffer, speexFrames * clc.speexFrameSize * 2, 1, decio); fflush(decio); }
+ #endif
+ }
+ }
+ }
+
+ // User requested we stop recording, and we've now processed the last of
+ // any previously-buffered data. Pause the capture device, etc.
+ if (finalFrame) {
+ S_StopCapture();
+ S_MasterGain(1.0f);
+ clc.voipPower = 0.0f; // force this value so it doesn't linger.
+ }
+}
+#endif
/*
=======================================================================
@@ -825,7 +1122,7 @@ void CL_MapLoading( void ) {
Key_SetCatcher( 0 );
SCR_UpdateScreen();
clc.connectTime = -RETRANSMIT_TIMEOUT;
- NET_StringToAdr( cls.servername, &clc.serverAddress);
+ NET_StringToAdr( cls.servername, &clc.serverAddress, NA_UNSPEC);
// we don't need a challenge on the localhost
CL_CheckForResend();
@@ -853,7 +1150,7 @@ CL_UpdateGUID
update cl_guid using QKEY_FILE and optional prefix
====================
*/
-static void CL_UpdateGUID( char *prefix, int prefix_len )
+static void CL_UpdateGUID( const char *prefix, int prefix_len )
{
fileHandle_t f;
int len;
@@ -898,6 +1195,36 @@ void CL_Disconnect( qboolean showMainMenu ) {
*clc.downloadTempName = *clc.downloadName = 0;
Cvar_Set( "cl_downloadName", "" );
+#ifdef USE_MUMBLE
+ if (cl_useMumble->integer && mumble_islinked()) {
+ Com_Printf("Mumble: Unlinking from Mumble application\n");
+ mumble_unlink();
+ }
+#endif
+
+#ifdef USE_VOIP
+ if (cl_voipSend->integer) {
+ int tmp = cl_voipUseVAD->integer;
+ cl_voipUseVAD->integer = 0; // disable this for a moment.
+ clc.voipOutgoingDataSize = 0; // dump any pending VoIP transmission.
+ Cvar_Set("cl_voipSend", "0");
+ CL_CaptureVoip(); // clean up any state...
+ cl_voipUseVAD->integer = tmp;
+ }
+
+ if (clc.speexInitialized) {
+ int i;
+ speex_bits_destroy(&clc.speexEncoderBits);
+ speex_encoder_destroy(clc.speexEncoder);
+ speex_preprocess_state_destroy(clc.speexPreprocessor);
+ for (i = 0; i < MAX_CLIENTS; i++) {
+ speex_bits_destroy(&clc.speexDecoderBits[i]);
+ speex_decoder_destroy(clc.speexDecoder[i]);
+ }
+ }
+ Cmd_RemoveCommand ("voip");
+#endif
+
if ( clc.demofile ) {
FS_FCloseFile( clc.demofile );
clc.demofile = 0;
@@ -932,6 +1259,11 @@ void CL_Disconnect( qboolean showMainMenu ) {
// not connected to a pure server anymore
cl_connectedToPureServer = qfalse;
+#ifdef USE_VOIP
+ // not connected to voip server anymore.
+ cl_connectedToVoipServer = qfalse;
+#endif
+
// Stop recording any video
if( CL_VideoRecording( ) ) {
// Finish rendering current frame
@@ -986,7 +1318,7 @@ void CL_RequestMotd( void ) {
return;
}
Com_Printf( "Resolving %s\n", MASTER_SERVER_NAME );
- if ( !NET_StringToAdr( MASTER_SERVER_NAME, &cls.updateServer ) ) {
+ if ( !NET_StringToAdr( MASTER_SERVER_NAME, &cls.updateServer, NA_IP ) ) {
Com_Printf( "Couldn't resolve address\n" );
return;
}
@@ -1109,12 +1441,28 @@ CL_Connect_f
*/
void CL_Connect_f( void ) {
char *server;
- char serverString[ 22 ];
+ const char *serverString;
+ int argc = Cmd_Argc();
+ netadrtype_t family = NA_UNSPEC;
- if ( Cmd_Argc() != 2 ) {
- Com_Printf( "usage: connect [server]\n");
+ if ( argc != 2 && argc != 3 ) {
+ Com_Printf( "usage: connect [-4|-6] server\n");
return;
}
+
+ if(argc == 2)
+ server = Cmd_Argv(1);
+ else
+ {
+ if(!strcmp(Cmd_Argv(1), "-4"))
+ family = NA_IP;
+ else if(!strcmp(Cmd_Argv(1), "-6"))
+ family = NA_IP6;
+ else
+ Com_Printf( "warning: only -4 or -6 as address type understood.\n");
+
+ server = Cmd_Argv(2);
+ }
Cvar_Set("ui_singlePlayerActive", "0");
@@ -1124,8 +1472,6 @@ void CL_Connect_f( void ) {
// clear any previous "server full" type messages
clc.serverMessage[0] = 0;
- server = Cmd_Argv (1);
-
if ( com_sv_running->integer && !strcmp( server, "localhost" ) ) {
// if running a local server, kill it
SV_Shutdown( "Server quit" );
@@ -1138,13 +1484,9 @@ void CL_Connect_f( void ) {
CL_Disconnect( qtrue );
Con_Close();
- /* MrE: 2000-09-13: now called in CL_DownloadsComplete
- CL_FlushMemory( );
- */
-
Q_strncpyz( cls.servername, server, sizeof(cls.servername) );
- if (!NET_StringToAdr( cls.servername, &clc.serverAddress) ) {
+ if (!NET_StringToAdr(cls.servername, &clc.serverAddress, family) ) {
Com_Printf ("Bad server address\n");
cls.state = CA_DISCONNECTED;
return;
@@ -1152,12 +1494,10 @@ void CL_Connect_f( void ) {
if (clc.serverAddress.port == 0) {
clc.serverAddress.port = BigShort( PORT_SERVER );
}
- Com_sprintf( serverString, sizeof( serverString ), "%i.%i.%i.%i:%i",
- clc.serverAddress.ip[0], clc.serverAddress.ip[1],
- clc.serverAddress.ip[2], clc.serverAddress.ip[3],
- BigShort( clc.serverAddress.port ) );
-
- Com_Printf( "%s resolved to %s\n", cls.servername, serverString );
+
+ serverString = NET_AdrToStringwPort(clc.serverAddress);
+
+ Com_Printf( "%s resolved to %s\n", cls.servername, serverString);
if( cl_guidServerUniq->integer )
CL_UpdateGUID( serverString, strlen( serverString ) );
@@ -1224,7 +1564,7 @@ void CL_Rcon_f( void ) {
return;
}
- NET_StringToAdr (rconAddress->string, &to);
+ NET_StringToAdr (rconAddress->string, &to, NA_UNSPEC);
if (to.port == 0) {
to.port = BigShort (PORT_SERVER);
}
@@ -1239,21 +1579,11 @@ CL_SendPureChecksums
=================
*/
void CL_SendPureChecksums( void ) {
- const char *pChecksums;
char cMsg[MAX_INFO_VALUE];
- int i;
// if we are pure we need to send back a command with our referenced pk3 checksums
- pChecksums = FS_ReferencedPakPureChecksums();
+ Com_sprintf(cMsg, sizeof(cMsg), "cp %d %s", cl.serverId, FS_ReferencedPakPureChecksums());
- // "cp"
- // "Yf"
- Com_sprintf(cMsg, sizeof(cMsg), "Yf ");
- Q_strcat(cMsg, sizeof(cMsg), va("%d ", cl.serverId) );
- Q_strcat(cMsg, sizeof(cMsg), pChecksums);
- for (i = 0; i < 2; i++) {
- cMsg[i] += 10;
- }
CL_AddReliableCommand( cMsg );
}
@@ -1774,13 +2104,8 @@ void CL_MotdPacket( netadr_t from, const char *info ) {
CL_InitServerInfo
===================
*/
-void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
- server->adr.type = NA_IP;
- server->adr.ip[0] = address->ip[0];
- server->adr.ip[1] = address->ip[1];
- server->adr.ip[2] = address->ip[2];
- server->adr.ip[3] = address->ip[3];
- server->adr.port = address->port;
+void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
+ server->adr = *address;
server->clients = 0;
server->hostName[0] = '\0';
server->mapName[0] = '\0';
@@ -1801,8 +2126,8 @@ CL_ServersResponsePacket
===================
*/
void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
- int i, count, max, total;
- serverAddress_t addresses[MAX_SERVERSPERPACKET];
+ int i, count, total;
+ netadr_t addresses[MAX_SERVERSPERPACKET];
int numservers;
byte* buffptr;
byte* buffend;
@@ -1815,71 +2140,66 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
cls.numGlobalServerAddresses = 0;
}
- if (cls.nummplayerservers == -1) {
- cls.nummplayerservers = 0;
- }
-
// parse through server response string
numservers = 0;
buffptr = msg->data;
buffend = buffptr + msg->cursize;
- while (buffptr+1 < buffend) {
- // advance to initial token
- do {
- if (*buffptr++ == '\\')
- break;
- }
- while (buffptr < buffend);
- if ( buffptr >= buffend - 6 ) {
+ // advance to initial token
+ do
+ {
+ if(*buffptr == '\\' || *buffptr == '/')
break;
- }
+
+ buffptr++;
+ } while (buffptr < buffend);
- // parse out ip
- addresses[numservers].ip[0] = *buffptr++;
- addresses[numservers].ip[1] = *buffptr++;
- addresses[numservers].ip[2] = *buffptr++;
- addresses[numservers].ip[3] = *buffptr++;
+ while (buffptr + 1 < buffend)
+ {
+ if (*buffptr == '\\')
+ {
+ buffptr++;
+
+ if (buffend - buffptr < sizeof(addresses[numservers].ip) + sizeof(addresses[numservers].port) + 1)
+ break;
+ for(i = 0; i < sizeof(addresses[numservers].ip); i++)
+ addresses[numservers].ip[i] = *buffptr++;
+
+ addresses[numservers].type = NA_IP;
+ }
+ else
+ {
+ buffptr++;
+
+ if (buffend - buffptr < sizeof(addresses[numservers].ip6) + sizeof(addresses[numservers].port) + 1)
+ break;
+
+ for(i = 0; i < sizeof(addresses[numservers].ip6); i++)
+ addresses[numservers].ip6[i] = *buffptr++;
+
+ addresses[numservers].type = NA_IP6;
+ }
+
// parse out port
- addresses[numservers].port = (*buffptr++)<<8;
+ addresses[numservers].port = (*buffptr++) << 8;
addresses[numservers].port += *buffptr++;
addresses[numservers].port = BigShort( addresses[numservers].port );
// syntax check
- if (*buffptr != '\\') {
+ if (*buffptr != '\\' && *buffptr != '/')
break;
- }
-
- Com_DPrintf( "server: %d ip: %d.%d.%d.%d:%d\n",numservers,
- addresses[numservers].ip[0],
- addresses[numservers].ip[1],
- addresses[numservers].ip[2],
- addresses[numservers].ip[3],
- BigShort( addresses[numservers].port ) );
-
+
numservers++;
- if (numservers >= MAX_SERVERSPERPACKET) {
+ if (numservers >= MAX_SERVERSPERPACKET)
break;
- }
-
- // parse out EOT
- if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') {
- break;
- }
}
- if (cls.masterNum == 0) {
- count = cls.numglobalservers;
- max = MAX_GLOBAL_SERVERS;
- } else {
- count = cls.nummplayerservers;
- max = MAX_OTHER_SERVERS;
- }
+ count = cls.numglobalservers;
- for (i = 0; i < numservers && count < max; i++) {
+ for (i = 0; i < numservers && count < MAX_GLOBAL_SERVERS; i++) {
// build net address
- serverInfo_t *server = (cls.masterNum == 0) ? &cls.globalServers[count] : &cls.mplayerServers[count];
+ serverInfo_t *server = &cls.globalServers[count];
CL_InitServerInfo( server, &addresses[i] );
// advance to next slot
@@ -1887,29 +2207,18 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
}
// if getting the global list
- if (cls.masterNum == 0) {
- if ( cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) {
- // if we couldn't store the servers in the main list anymore
- for (; i < numservers && count >= max; i++) {
- serverAddress_t *addr;
- // just store the addresses in an additional list
- addr = &cls.globalServerAddresses[cls.numGlobalServerAddresses++];
- addr->ip[0] = addresses[i].ip[0];
- addr->ip[1] = addresses[i].ip[1];
- addr->ip[2] = addresses[i].ip[2];
- addr->ip[3] = addresses[i].ip[3];
- addr->port = addresses[i].port;
- }
+ if ( count >= MAX_GLOBAL_SERVERS && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS )
+ {
+ // if we couldn't store the servers in the main list anymore
+ for (; i < numservers && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS; i++)
+ {
+ // just store the addresses in an additional list
+ cls.globalServerAddresses[cls.numGlobalServerAddresses++] = addresses[i];
}
}
- if (cls.masterNum == 0) {
- cls.numglobalservers = count;
- total = count + cls.numGlobalServerAddresses;
- } else {
- cls.nummplayerservers = count;
- total = count;
- }
+ cls.numglobalservers = count;
+ total = count + cls.numGlobalServerAddresses;
Com_Printf("%d servers parsed (total %d)\n", numservers, total);
}
@@ -1936,12 +2245,12 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
Q_strncpyz( c, Cmd_Argv( 0 ), BIG_INFO_STRING );
Q_strncpyz( arg1, Cmd_Argv( 1 ), BIG_INFO_STRING );
- Com_DPrintf ("CL packet %s: %s\n", NET_AdrToString(from), c);
+ Com_DPrintf ("CL packet %s: %s\n", NET_AdrToStringwPort(from), c);
// challenge from the server we are connecting to
if ( !Q_stricmp(c, "challengeResponse") ) {
if ( cls.state != CA_CONNECTING ) {
- Com_Printf( "Unwanted challenge response received. Ignored.\n" );
+ Com_DPrintf( "Unwanted challenge response received. Ignored.\n" );
} else {
// start sending challenge repsonse instead of challenge request packets
clc.challenge = atoi(arg1);
@@ -1969,8 +2278,8 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
}
if ( !NET_CompareBaseAdr( from, clc.serverAddress ) ) {
Com_Printf( "connectResponse from a different address. Ignored.\n" );
- Com_Printf( "%s should have been %s\n", NET_AdrToString( from ),
- NET_AdrToString( clc.serverAddress ) );
+ Com_Printf( "%s should have been %s\n", NET_AdrToStringwPort( from ),
+ NET_AdrToStringwPort( clc.serverAddress ) );
return;
}
Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableValue( "net_qport" ) );
@@ -2055,7 +2364,7 @@ void CL_PacketEvent( netadr_t from, msg_t *msg ) {
}
if ( msg->cursize < 4 ) {
- Com_Printf ("%s: Runt packet\n",NET_AdrToString( from ));
+ Com_Printf ("%s: Runt packet\n", NET_AdrToStringwPort( from ));
return;
}
@@ -2064,7 +2373,7 @@ void CL_PacketEvent( netadr_t from, msg_t *msg ) {
//
if ( !NET_CompareAdr( from, clc.netchan.remoteAddress ) ) {
Com_DPrintf ("%s:sequenced packet without connection\n"
- ,NET_AdrToString( from ) );
+ , NET_AdrToStringwPort( from ) );
// FIXME: send a client disconnect?
return;
}
@@ -2190,7 +2499,7 @@ void CL_Frame ( int msec ) {
#endif
if ( cls.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI )
- && !com_sv_running->integer ) {
+ && !com_sv_running->integer && uivm ) {
// if disconnected, bring up the menu
S_StopAllSounds();
VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN );
@@ -2282,6 +2591,14 @@ void CL_Frame ( int msec ) {
// update audio
S_Update();
+#ifdef USE_VOIP
+ CL_CaptureVoip();
+#endif
+
+#ifdef USE_MUMBLE
+ CL_UpdateMumble();
+#endif
+
// advance local effects for next frame
SCR_RunCinematic();
@@ -2385,6 +2702,10 @@ void CL_StartHunkUsers( qboolean rendererOnly ) {
S_BeginRegistration();
}
+ if( com_dedicated->integer ) {
+ return;
+ }
+
if ( !cls.uiStarted ) {
cls.uiStarted = qtrue;
CL_InitUI();
@@ -2442,6 +2763,7 @@ void CL_InitRef( void ) {
ri.FS_FileExists = FS_FileExists;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
+ ri.Cvar_CheckRange = Cvar_CheckRange;
// cinematic stuff
@@ -2608,7 +2930,7 @@ CL_Init
void CL_Init( void ) {
Com_Printf( "----- Client Initialization -----\n" );
- Con_Init ();
+ Con_Init ();
CL_ClearState ();
@@ -2626,7 +2948,6 @@ void CL_Init( void ) {
cl_timeout = Cvar_Get ("cl_timeout", "200", 0);
- cl_master = Cvar_Get ("cl_master", MASTER_SERVER_NAME, CVAR_ARCHIVE);
cl_timeNudge = Cvar_Get ("cl_timeNudge", "0", CVAR_TEMP );
cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_TEMP );
cl_showSend = Cvar_Get ("cl_showSend", "0", CVAR_TEMP );
@@ -2666,7 +2987,7 @@ void CL_Init( void ) {
cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0);
#ifdef MACOS_X
- // In game video is REALLY slow in Mac OS X right now due to driver slowness
+ // In game video is REALLY slow in Mac OS X right now due to driver slowness
cl_inGameVideo = Cvar_Get ("r_inGameVideo", "0", CVAR_ARCHIVE);
#else
cl_inGameVideo = Cvar_Get ("r_inGameVideo", "1", CVAR_ARCHIVE);
@@ -2683,7 +3004,7 @@ void CL_Init( void ) {
m_forward = Cvar_Get ("m_forward", "0.25", CVAR_ARCHIVE);
m_side = Cvar_Get ("m_side", "0.25", CVAR_ARCHIVE);
#ifdef MACOS_X
- // Input is jittery on OS X w/o this
+ // Input is jittery on OS X w/o this
m_filter = Cvar_Get ("m_filter", "1", CVAR_ARCHIVE);
#else
m_filter = Cvar_Get ("m_filter", "0", CVAR_ARCHIVE);
@@ -2709,9 +3030,42 @@ void CL_Init( void ) {
Cvar_Get ("password", "", CVAR_USERINFO);
+#ifdef USE_MUMBLE
+ cl_useMumble = Cvar_Get ("cl_useMumble", "0", CVAR_ARCHIVE | CVAR_LATCH);
+ cl_mumbleScale = Cvar_Get ("cl_mumbleScale", "0.0254", CVAR_ARCHIVE);
+#endif
+
+#ifdef USE_VOIP
+ cl_voipSend = Cvar_Get ("cl_voipSend", "0", 0);
+ cl_voipSendTarget = Cvar_Get ("cl_voipSendTarget", "all", 0);
+ cl_voipGainDuringCapture = Cvar_Get ("cl_voipGainDuringCapture", "0.2", CVAR_ARCHIVE);
+ cl_voipCaptureMult = Cvar_Get ("cl_voipCaptureMult", "2.0", CVAR_ARCHIVE);
+ cl_voipUseVAD = Cvar_Get ("cl_voipUseVAD", "0", CVAR_ARCHIVE);
+ cl_voipVADThreshold = Cvar_Get ("cl_voipVADThreshold", "0.25", CVAR_ARCHIVE);
+ cl_voipShowMeter = Cvar_Get ("cl_voipShowMeter", "1", CVAR_ARCHIVE);
+
+ // This is a protocol version number.
+ cl_voip = Cvar_Get ("cl_voip", "1", CVAR_USERINFO | CVAR_ARCHIVE | CVAR_LATCH);
+ Cvar_CheckRange( cl_voip, 0, 1, qtrue );
+
+ // If your data rate is too low, you'll get Connection Interrupted warnings
+ // when VoIP packets arrive, even if you have a broadband connection.
+ // This might work on rates lower than 25000, but for safety's sake, we'll
+ // just demand it. Who doesn't have at least a DSL line now, anyhow? If
+ // you don't, you don't need VoIP. :)
+ if ((cl_voip->integer) && (Cvar_VariableIntegerValue("rate") < 25000)) {
+ Com_Printf("Your network rate is too slow for VoIP.\n");
+ Com_Printf("Set 'Data Rate' to 'LAN/Cable/xDSL' in 'Setup/System/Network' and restart.\n");
+ Com_Printf("Until then, VoIP is disabled.\n");
+ Cvar_Set("cl_voip", "0");
+ }
+#endif
+
// cgame might not be initialized before menu is used
Cvar_Get ("cg_viewsize", "100", CVAR_ARCHIVE );
+ // Make sure cg_stereoSeparation is zero as that variable is deprecated and should not be used anymore.
+ Cvar_Get ("cg_stereoSeparation", "0", CVAR_ROM);
//
// register our commands
@@ -2744,11 +3098,11 @@ void CL_Init( void ) {
SCR_Init ();
- Cbuf_Execute ();
+// Cbuf_Execute ();
Cvar_Set( "cl_running", "1" );
- CL_GenerateQKey();
+ CL_GenerateQKey();
Cvar_Get( "cl_guid", "", CVAR_USERINFO | CVAR_ROM );
CL_UpdateGUID( NULL, 0 );
@@ -2843,12 +3197,6 @@ static void CL_SetServerInfoByAddress(netadr_t from, const char *info, int ping)
}
}
- for (i = 0; i < MAX_OTHER_SERVERS; i++) {
- if (NET_CompareAdr(from, cls.mplayerServers[i].adr)) {
- CL_SetServerInfo(&cls.mplayerServers[i], info, ping);
- }
- }
-
for (i = 0; i < MAX_GLOBAL_SERVERS; i++) {
if (NET_CompareAdr(from, cls.globalServers[i].adr)) {
CL_SetServerInfo(&cls.globalServers[i], info, ping);
@@ -2871,7 +3219,6 @@ CL_ServerInfoPacket
void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
int i, type;
char info[MAX_INFO_STRING];
- char* str;
char *infoString;
int prot;
@@ -2902,12 +3249,12 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
{
case NA_BROADCAST:
case NA_IP:
- str = "udp";
type = 1;
break;
-
+ case NA_IP6:
+ type = 2;
+ break;
default:
- str = "???";
type = 0;
break;
}
@@ -2959,7 +3306,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
if (info[strlen(info)-1] != '\n') {
strncat(info, "\n", sizeof(info) - 1);
}
- Com_Printf( "%s: %s", NET_AdrToString( from ), info );
+ Com_Printf( "%s: %s", NET_AdrToStringwPort( from ), info );
}
}
@@ -3017,7 +3364,7 @@ int CL_ServerStatus( char *serverAddress, char *serverStatusString, int maxLen )
return qfalse;
}
// get the address
- if ( !NET_StringToAdr( serverAddress, &to ) ) {
+ if ( !NET_StringToAdr( serverAddress, &to, NA_UNSPEC) ) {
return qfalse;
}
serverStatus = CL_GetServerStatus( to );
@@ -3192,6 +3539,8 @@ void CL_LocalServers_f( void ) {
to.type = NA_BROADCAST;
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
+ to.type = NA_MULTICAST6;
+ NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
}
}
}
@@ -3203,43 +3552,49 @@ CL_GlobalServers_f
*/
void CL_GlobalServers_f( void ) {
netadr_t to;
- int i;
- int count;
- char *buffptr;
- char command[1024];
+ int count, i, masterNum;
+ char command[1024], *masteraddress;
- if ( Cmd_Argc() < 3) {
- Com_Printf( "usage: globalservers <master# 0-1> <protocol> [keywords]\n");
+ if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > 4)
+ {
+ Com_Printf( "usage: globalservers <master# 0-4> <protocol> [keywords]\n");
return;
}
- cls.masterNum = atoi( Cmd_Argv(1) );
-
- Com_Printf( "Requesting servers from the master...\n");
+ sprintf(command, "sv_master%d", masterNum + 1);
+ masteraddress = Cvar_VariableString(command);
+
+ if(!*masteraddress)
+ {
+ Com_Printf( "CL_GlobalServers_f: Error: No master server address given.\n");
+ return;
+ }
// reset the list, waiting for response
// -1 is used to distinguish a "no response"
- NET_StringToAdr( cl_master->string, &to );
-
- if( cls.masterNum == 1 ) {
- cls.nummplayerservers = -1;
- cls.pingUpdateSource = AS_MPLAYER;
- }
- else {
- cls.numglobalservers = -1;
- cls.pingUpdateSource = AS_GLOBAL;
+ i = NET_StringToAdr(masteraddress, &to, NA_UNSPEC);
+
+ if(!i)
+ {
+ Com_Printf( "CL_GlobalServers_f: Error: could not resolve address of master %s\n", masteraddress);
+ return;
}
- to.type = NA_IP;
- to.port = BigShort(PORT_MASTER);
+ else if(i == 2)
+ to.port = BigShort(PORT_MASTER);
+
+ Com_Printf("Requesting servers from master %s...\n", masteraddress);
- sprintf( command, "getservers %s", Cmd_Argv(2) );
+ cls.numglobalservers = -1;
+ cls.pingUpdateSource = AS_GLOBAL;
- // tack on keywords
- buffptr = command + strlen( command );
- count = Cmd_Argc();
- for (i=3; i<count; i++)
- buffptr += sprintf( buffptr, " %s", Cmd_Argv(i) );
+ Com_sprintf( command, sizeof(command), "getservers %s", Cmd_Argv(2) );
+
+ for (i=3; i < count; i++)
+ {
+ Q_strcat(command, sizeof(command), " ");
+ Q_strcat(command, sizeof(command), Cmd_Argv(i));
+ }
NET_OutOfBandPrint( NS_SERVER, to, "%s", command );
}
@@ -3264,7 +3619,7 @@ void CL_GetPing( int n, char *buf, int buflen, int *pingtime )
return;
}
- str = NET_AdrToString( cl_pinglist[n].adr );
+ str = NET_AdrToStringwPort( cl_pinglist[n].adr );
Q_strncpyz( buf, str, buflen );
time = cl_pinglist[n].time;
@@ -3423,17 +3778,33 @@ void CL_Ping_f( void ) {
netadr_t to;
ping_t* pingptr;
char* server;
+ int argc;
+ netadrtype_t family = NA_UNSPEC;
+
+ argc = Cmd_Argc();
- if ( Cmd_Argc() != 2 ) {
- Com_Printf( "usage: ping [server]\n");
+ if ( argc != 2 && argc != 3 ) {
+ Com_Printf( "usage: ping [-4|-6] server\n");
return;
}
+
+ if(argc == 2)
+ server = Cmd_Argv(1);
+ else
+ {
+ if(!strcmp(Cmd_Argv(1), "-4"))
+ family = NA_IP;
+ else if(!strcmp(Cmd_Argv(1), "-6"))
+ family = NA_IP6;
+ else
+ Com_Printf( "warning: only -4 or -6 as address type understood.\n");
+
+ server = Cmd_Argv(2);
+ }
Com_Memset( &to, 0, sizeof(netadr_t) );
- server = Cmd_Argv(1);
-
- if ( !NET_StringToAdr( server, &to ) ) {
+ if ( !NET_StringToAdr( server, &to, family ) ) {
return;
}
@@ -3476,10 +3847,6 @@ qboolean CL_UpdateVisiblePings_f(int source) {
server = &cls.localServers[0];
max = cls.numlocalservers;
break;
- case AS_MPLAYER :
- server = &cls.mplayerServers[0];
- max = cls.nummplayerservers;
- break;
case AS_GLOBAL :
server = &cls.globalServers[0];
max = cls.numglobalservers;
@@ -3488,6 +3855,8 @@ qboolean CL_UpdateVisiblePings_f(int source) {
server = &cls.favoriteServers[0];
max = cls.numfavoriteservers;
break;
+ default:
+ return qfalse;
}
for (i = 0; i < max; i++) {
if (server[i].visible) {
@@ -3561,32 +3930,53 @@ CL_ServerStatus_f
==================
*/
void CL_ServerStatus_f(void) {
- netadr_t to;
+ netadr_t to, *toptr = NULL;
char *server;
serverStatus_t *serverStatus;
+ int argc;
+ netadrtype_t family = NA_UNSPEC;
- Com_Memset( &to, 0, sizeof(netadr_t) );
+ argc = Cmd_Argc();
- if ( Cmd_Argc() != 2 ) {
- if ( cls.state != CA_ACTIVE || clc.demoplaying ) {
+ if ( argc != 2 && argc != 3 )
+ {
+ if (cls.state != CA_ACTIVE || clc.demoplaying)
+ {
Com_Printf ("Not connected to a server.\n");
- Com_Printf( "Usage: serverstatus [server]\n");
- return;
+ Com_Printf( "usage: serverstatus [-4|-6] server\n");
+ return;
}
- server = cls.servername;
- }
- else {
- server = Cmd_Argv(1);
+
+ toptr = &clc.serverAddress;
}
+
+ if(!toptr)
+ {
+ Com_Memset( &to, 0, sizeof(netadr_t) );
+
+ if(argc == 2)
+ server = Cmd_Argv(1);
+ else
+ {
+ if(!strcmp(Cmd_Argv(1), "-4"))
+ family = NA_IP;
+ else if(!strcmp(Cmd_Argv(1), "-6"))
+ family = NA_IP6;
+ else
+ Com_Printf( "warning: only -4 or -6 as address type understood.\n");
+
+ server = Cmd_Argv(2);
+ }
- if ( !NET_StringToAdr( server, &to ) ) {
- return;
+ toptr = &to;
+ if ( !NET_StringToAdr( server, toptr, family ) )
+ return;
}
- NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
+ NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
- serverStatus = CL_GetServerStatus( to );
- serverStatus->address = to;
+ serverStatus = CL_GetServerStatus( *toptr );
+ serverStatus->address = *toptr;
serverStatus->print = qtrue;
serverStatus->pending = qtrue;
}