diff options
author | Tim Angus <tim@ngus.net> | 2009-10-13 17:17:27 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:16:49 +0000 |
commit | 6efd4cef3cfcc44d6727cb0e54da26fbb74a7533 (patch) | |
tree | fdb5ee764999ac868d00c54cefb8c290f1735fd6 | |
parent | fafe107646105e680e2bd4a82d9330dffaf69c9a (diff) |
* Merge ioq3-r1666
-rw-r--r-- | Makefile | 62 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 1 | ||||
-rw-r--r-- | src/client/cl_cgame.c | 2 | ||||
-rw-r--r-- | src/client/cl_curl.c | 2 | ||||
-rw-r--r-- | src/client/cl_input.c | 2 | ||||
-rw-r--r-- | src/client/cl_keys.c | 239 | ||||
-rw-r--r-- | src/client/cl_main.c | 85 | ||||
-rw-r--r-- | src/client/cl_parse.c | 6 | ||||
-rw-r--r-- | src/client/client.h | 2 | ||||
-rw-r--r-- | src/client/snd_dma.c | 8 | ||||
-rw-r--r-- | src/client/snd_openal.c | 27 | ||||
-rw-r--r-- | src/qcommon/common.c | 82 | ||||
-rw-r--r-- | src/qcommon/files.c | 13 | ||||
-rw-r--r-- | src/qcommon/msg.c | 23 | ||||
-rw-r--r-- | src/qcommon/q_shared.h | 18 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 2 | ||||
-rw-r--r-- | src/qcommon/vm_x86_64_assembler.c | 2 | ||||
-rw-r--r-- | src/server/server.h | 1 | ||||
-rw-r--r-- | src/server/sv_client.c | 53 |
19 files changed, 317 insertions, 313 deletions
@@ -106,11 +106,7 @@ USE_OPENAL=1 endif ifndef USE_OPENAL_DLOPEN - ifeq ($(PLATFORM),mingw32) - USE_OPENAL_DLOPEN=1 - else - USE_OPENAL_DLOPEN=0 - endif +USE_OPENAL_DLOPEN=1 endif ifndef USE_CURL @@ -176,22 +172,25 @@ LIBSDIR=$(MOUNT_DIR)/libs MASTERDIR=$(MOUNT_DIR)/master TEMPDIR=/tmp -# set PKG_CONFIG_PATH to influence this, e.g. -# PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig -ifeq ($(shell which pkg-config > /dev/null; echo $$?),0) - CURL_CFLAGS=$(shell pkg-config --cflags libcurl) - CURL_LIBS=$(shell pkg-config --libs libcurl) - OPENAL_CFLAGS=$(shell pkg-config --cflags openal) - OPENAL_LIBS=$(shell pkg-config --libs openal) - # FIXME: introduce CLIENT_CFLAGS - SDL_CFLAGS=$(shell pkg-config --cflags sdl|sed 's/-Dmain=SDL_main//') - SDL_LIBS=$(shell pkg-config --libs sdl) -endif -# Use sdl-config if all else fails -ifeq ($(SDL_CFLAGS),) - ifeq ($(shell which sdl-config > /dev/null; echo $$?),0) - SDL_CFLAGS=$(shell sdl-config --cflags) - SDL_LIBS=$(shell sdl-config --libs) +# We won't need this if we only build the server +ifneq ($(BUILD_CLIENT),0) + # set PKG_CONFIG_PATH to influence this, e.g. + # PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig + ifeq ($(shell which pkg-config > /dev/null; echo $$?),0) + CURL_CFLAGS=$(shell pkg-config --silence-errors --cflags libcurl) + CURL_LIBS=$(shell pkg-config --silence-errors --libs libcurl) + OPENAL_CFLAGS=$(shell pkg-config --silence-errors --cflags openal) + OPENAL_LIBS=$(shell pkg-config --silence-errors --libs openal) + # FIXME: introduce CLIENT_CFLAGS + SDL_CFLAGS=$(shell pkg-config --silence-errors --cflags sdl|sed 's/-Dmain=SDL_main//') + SDL_LIBS=$(shell pkg-config --silence-errors --libs sdl) + endif + # Use sdl-config if all else fails + ifeq ($(SDL_CFLAGS),) + ifeq ($(shell which sdl-config > /dev/null; echo $$?),0) + SDL_CFLAGS=$(shell sdl-config --cflags) + SDL_LIBS=$(shell sdl-config --libs) + endif endif endif @@ -428,6 +427,10 @@ else # ifeq darwin ifeq ($(PLATFORM),mingw32) + # Some MinGW installations define CC to cc, but don't actually provide cc, + # so explicitly use gcc instead (which is the only option anyway) + CC=gcc + ifndef WINDRES WINDRES=windres endif @@ -1141,17 +1144,17 @@ endef define DO_CGAME_Q3LCC $(echo_cmd) "CGAME_Q3LCC $<" -$(Q)$(Q3LCC) -DPRODUCT_VERSION=\\\"$(VERSION)\\\" -DCGAME -o $@ $< +$(Q)$(Q3LCC) -DPRODUCT_VERSION=\"$(VERSION)\" -DCGAME -o $@ $< endef define DO_GAME_Q3LCC $(echo_cmd) "GAME_Q3LCC $<" -$(Q)$(Q3LCC) -DPRODUCT_VERSION=\\\"$(VERSION)\\\" -DGAME -o $@ $< +$(Q)$(Q3LCC) -DPRODUCT_VERSION=\"$(VERSION)\" -DGAME -o $@ $< endef define DO_UI_Q3LCC $(echo_cmd) "UI_Q3LCC $<" -$(Q)$(Q3LCC) -DPRODUCT_VERSION=\\\"$(VERSION)\\\" -DUI -o $@ $< +$(Q)$(Q3LCC) -DPRODUCT_VERSION=\"$(VERSION)\" -DUI -o $@ $< endef @@ -1809,11 +1812,14 @@ dist: # DEPENDENCIES ############################################################################# -OBJ_D_FILES=$(filter %.d,$(OBJ:%.o=%.d)) -TOOLSOBJ_D_FILES=$(filter %.d,$(TOOLSOBJ:%.o=%.d)) --include $(OBJ_D_FILES) $(TOOLSOBJ_D_FILES) +ifneq ($(B),) + OBJ_D_FILES=$(filter %.d,$(OBJ:%.o=%.d)) + TOOLSOBJ_D_FILES=$(filter %.d,$(TOOLSOBJ:%.o=%.d)) + -include $(OBJ_D_FILES) $(TOOLSOBJ_D_FILES) +endif .PHONY: all clean clean2 clean-debug clean-release copyfiles \ debug default dist distclean makedirs \ release targets \ - toolsclean toolsclean2 toolsclean-debug toolsclean-release + toolsclean toolsclean2 toolsclean-debug toolsclean-release \ + $(OBJ_D_FILES) $(TOOLSOBJ_D_FILES) diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index da607deb..89082cee 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -1894,3 +1894,4 @@ static char *CG_VoIPString( void ) return voipString; } + diff --git a/src/client/cl_cgame.c b/src/client/cl_cgame.c index 8bf10f6d..ef61834c 100644 --- a/src/client/cl_cgame.c +++ b/src/client/cl_cgame.c @@ -469,7 +469,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) { Cmd_RemoveCommand( VMA(1) ); return 0; case CG_SENDCLIENTCOMMAND: - CL_AddReliableCommand( VMA(1) ); + CL_AddReliableCommand(VMA(1), qfalse); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop diff --git a/src/client/cl_curl.c b/src/client/cl_curl.c index 4c34667c..10d09bd5 100644 --- a/src/client/cl_curl.c +++ b/src/client/cl_curl.c @@ -292,7 +292,7 @@ void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ) if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) && !clc.cURLDisconnected) { - CL_AddReliableCommand("disconnect"); + CL_AddReliableCommand("disconnect", qtrue); CL_WritePacket(); CL_WritePacket(); CL_WritePacket(); diff --git a/src/client/cl_input.c b/src/client/cl_input.c index d3c38868..49551662 100644 --- a/src/client/cl_input.c +++ b/src/client/cl_input.c @@ -824,7 +824,7 @@ void CL_WritePacket( void ) { // also use the message acknowledge key ^= clc.serverMessageSequence; // also use the last acknowledged server command in the key - key ^= Com_HashKey(clc.serverCommands[ clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS-1) ], 32); + key ^= MSG_HashKey(clc.serverCommands[ clc.serverCommandSequence & (MAX_RELIABLE_COMMANDS-1) ], 32); // write all the commands, including the predicted command for ( i = 0 ; i < count ; i++ ) { diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c index 10abefc2..4c36485b 100644 --- a/src/client/cl_keys.c +++ b/src/client/cl_keys.c @@ -1070,94 +1070,72 @@ void CL_InitKeyCommands( void ) { /* =================== -CL_AddKeyUpCommands +CL_ParseBinding + +Execute the commands in the bind string =================== */ -void CL_AddKeyUpCommands( int key, char *kb, unsigned time) { - int i; - char button[1024], *buttonPtr; - char cmd[1024]; - qboolean keyevent; +void CL_ParseBinding( int key, qboolean down, unsigned time ) +{ + char buf[ MAX_STRING_CHARS ], *p = buf, *end; - if ( !kb ) { + if( !keys[key].binding || !keys[key].binding[0] ) return; - } - keyevent = qfalse; - buttonPtr = button; - for ( i = 0; ; i++ ) { - if ( kb[i] == ';' || !kb[i] ) { - *buttonPtr = '\0'; - if ( button[0] == '+') { - // button commands add keynum and time as parms so that multiple - // sources can be discriminated and subframe corrected - Com_sprintf (cmd, sizeof(cmd), "-%s %i %i\n", button+1, key, time); - Cbuf_AddText (cmd); - keyevent = qtrue; - } else { - if (keyevent) { - // down-only command - Cbuf_AddText (button); - Cbuf_AddText ("\n"); - } - } - buttonPtr = button; - while ( (kb[i] <= ' ' || kb[i] == ';') && kb[i] != 0 ) { - i++; - } + Q_strncpyz( buf, keys[key].binding, sizeof( buf ) ); + + while( 1 ) + { + while( isspace( *p ) ) + p++; + end = strchr( p, ';' ); + if( end ) + *end = '\0'; + if( *p == '+' ) + { + // button commands add keynum and time as parameters + // so that multiple sources can be discriminated and + // subframe corrected + char cmd[1024]; + Com_sprintf( cmd, sizeof( cmd ), "%c%s %d %d\n", + ( down ) ? '+' : '-', p + 1, key, time ); + Cbuf_AddText( cmd ); } - *buttonPtr++ = kb[i]; - if ( !kb[i] ) { - break; + else if( down ) + { + // normal commands only execute on key press + Cbuf_AddText( p ); + Cbuf_AddText( "\n" ); } + if( !end ) + break; + p = end + 1; } } /* =================== -CL_KeyEvent +CL_KeyDownEvent -Called by the system for both key up and key down events +Called by CL_KeyEvent to handle a keypress =================== */ -void CL_KeyEvent (int key, qboolean down, unsigned time) { - char *kb; - char cmd[1024]; - - // update auto-repeat status and BUTTON_ANY status - keys[key].down = down; - - if (down) { - keys[key].repeats++; - if ( keys[key].repeats == 1) { - anykeydown++; - } - } else { - keys[key].repeats = 0; - anykeydown--; - if (anykeydown < 0) { - anykeydown = 0; - } - } +void CL_KeyDownEvent( int key, unsigned time ) +{ + keys[key].down = qtrue; + keys[key].repeats++; + if( keys[key].repeats == 1 ) + anykeydown++; - if (key == K_ENTER) + if( keys[K_ALT].down && key == K_ENTER ) { - if (down) - { - if (keys[K_ALT].down) - { - Cvar_SetValue( "r_fullscreen", - !Cvar_VariableIntegerValue( "r_fullscreen" ) ); - return; - } - } + Cvar_SetValue( "r_fullscreen", + !Cvar_VariableIntegerValue( "r_fullscreen" ) ); + return; } // console key is hardcoded, so the user can never unbind it - if (key == K_CONSOLE || - ( key == K_ESCAPE && keys[K_SHIFT].down ) ) { - if (!down) { - return; - } + if( key == K_CONSOLE || ( keys[K_SHIFT].down && key == K_ESCAPE ) ) + { Con_ToggleConsole_f (); Key_ClearStates (); return; @@ -1165,7 +1143,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) { // keys can still be used for bound actions - if ( down && ( key < 128 || key == K_MOUSE1 ) && + if ( ( key < 128 || key == K_MOUSE1 ) && ( clc.demoplaying || cls.state == CA_CINEMATIC ) && Key_GetCatcher( ) == 0 ) { if (Cvar_VariableValue ("com_cameraMode") == 0) { @@ -1174,9 +1152,8 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) { } } - // escape is always handled special - if ( key == K_ESCAPE && down ) { + if ( key == K_ESCAPE ) { // escape always gets out of CGAME stuff if (Key_GetCatcher( ) & KEYCATCH_CGAME) { Key_SetCatcher( Key_GetCatcher( ) & ~KEYCATCH_CGAME ); @@ -1196,89 +1173,79 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) { return; } - VM_Call( uivm, UI_KEY_EVENT, key, down ); + VM_Call( uivm, UI_KEY_EVENT, key, qtrue ); return; } - // - // key up events only perform actions if the game key binding is - // a button command (leading + sign). These will be processed even in - // console mode and menu mode, to keep the character from continuing - // an action started before a mode switch. - // - if (!down ) { - if ( cls.state != CA_DISCONNECTED ) { - kb = keys[key].binding; - - CL_AddKeyUpCommands( key, kb, time ); - } - - if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) { - VM_Call( uivm, UI_KEY_EVENT, key, down ); - } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME && cgvm ) { - VM_Call( cgvm, CG_KEY_EVENT, key, down ); - } - - return; - } - - // distribute the key down event to the apropriate handler if ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) { Console_Key( key ); } else if ( Key_GetCatcher( ) & KEYCATCH_UI ) { if ( uivm ) { - VM_Call( uivm, UI_KEY_EVENT, key, down ); + VM_Call( uivm, UI_KEY_EVENT, key, qtrue ); } } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME ) { if ( cgvm ) { - VM_Call( cgvm, CG_KEY_EVENT, key, down ); + VM_Call( cgvm, CG_KEY_EVENT, key, qtrue ); } } else if ( cls.state == CA_DISCONNECTED ) { Console_Key( key ); } else { // send the bound action - kb = keys[key].binding; - if ( !kb ) { - if (key >= 200) { - Com_Printf ("%s is unbound, use controls menu to set.\n" - , Key_KeynumToString( key ) ); - } - } else if (kb[0] == '+') { - int i; - char button[1024], *buttonPtr; - buttonPtr = button; - for ( i = 0; ; i++ ) { - if ( kb[i] == ';' || !kb[i] ) { - *buttonPtr = '\0'; - if ( button[0] == '+') { - // button commands add keynum and time as parms so that multiple - // sources can be discriminated and subframe corrected - Com_sprintf (cmd, sizeof(cmd), "%s %i %i\n", button, key, time); - Cbuf_AddText (cmd); - } else { - // down-only command - Cbuf_AddText (button); - Cbuf_AddText ("\n"); - } - buttonPtr = button; - while ( (kb[i] <= ' ' || kb[i] == ';') && kb[i] != 0 ) { - i++; - } - } - *buttonPtr++ = kb[i]; - if ( !kb[i] ) { - break; - } - } - } else { - // down-only command - Cbuf_AddText (kb); - Cbuf_AddText ("\n"); - } + CL_ParseBinding( key, qtrue, time ); + } + return; +} + +/* +=================== +CL_KeyUpEvent + +Called by CL_KeyEvent to handle a keyrelease +=================== +*/ +void CL_KeyUpEvent( int key, unsigned time ) +{ + keys[key].repeats = 0; + keys[key].down = qfalse; + anykeydown--; + if (anykeydown < 0) { + anykeydown = 0; + } + + // don't process key-up events for the console key + if ( key == K_CONSOLE || ( key == K_ESCAPE && keys[K_SHIFT].down ) ) + return; + + // + // key up events only perform actions if the game key binding is + // a button command (leading + sign). These will be processed even in + // console mode and menu mode, to keep the character from continuing + // an action started before a mode switch. + // + if( cls.state != CA_DISCONNECTED ) + CL_ParseBinding( key, qfalse, time ); + + if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) { + VM_Call( uivm, UI_KEY_EVENT, key, qfalse ); + } else if ( Key_GetCatcher( ) & KEYCATCH_CGAME && cgvm ) { + VM_Call( cgvm, CG_KEY_EVENT, key, qfalse ); } } +/* +=================== +CL_KeyEvent + +Called by the system for both key up and key down events +=================== +*/ +void CL_KeyEvent (int key, qboolean down, unsigned time) { + if( down ) + CL_KeyDownEvent( key, time ); + else + CL_KeyUpEvent( key, time ); +} /* =================== diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 0aafa529..a8b59c27 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -191,7 +191,7 @@ void CL_UpdateVoipIgnore(const char *idstr, qboolean ignore) if ((id >= 0) && (id < MAX_CLIENTS)) { clc.voipIgnore[id] = ignore; CL_AddReliableCommand(va("voip %s %d", - ignore ? "ignore" : "unignore", id)); + ignore ? "ignore" : "unignore", id), qfalse); Com_Printf("VoIP: %s ignoring player #%d\n", ignore ? "Now" : "No longer", id); return; @@ -303,11 +303,11 @@ void CL_Voip_f( void ) } } else if (strcmp(cmd, "muteall") == 0) { Com_Printf("VoIP: muting incoming voice\n"); - CL_AddReliableCommand("voip muteall"); + CL_AddReliableCommand("voip muteall", qfalse); clc.voipMuteAll = qtrue; } else if (strcmp(cmd, "unmuteall") == 0) { Com_Printf("VoIP: unmuting incoming voice\n"); - CL_AddReliableCommand("voip unmuteall"); + CL_AddReliableCommand("voip unmuteall", qfalse); clc.voipMuteAll = qfalse; } else { Com_Printf("usage: voip [un]ignore <playerID#>\n" @@ -510,17 +510,25 @@ The given command will be transmitted to the server, and is gauranteed to not have future usercmd_t executed before it is executed ====================== */ -void CL_AddReliableCommand( const char *cmd ) { - int index; - +void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd) +{ + int unacknowledged = clc.reliableSequence - clc.reliableAcknowledge; + // if we would be losing an old command that hasn't been acknowledged, // we must drop the connection - if ( clc.reliableSequence - clc.reliableAcknowledge > MAX_RELIABLE_COMMANDS ) { - Com_Error( ERR_DROP, "Client command overflow" ); + // also leave one slot open for the disconnect command in this case. + + if ((isDisconnectCmd && unacknowledged > MAX_RELIABLE_COMMANDS) || + (!isDisconnectCmd && unacknowledged >= MAX_RELIABLE_COMMANDS)) + { + if(com_errorEntered) + return; + else + Com_Error(ERR_DROP, "Client command overflow"); } - clc.reliableSequence++; - index = clc.reliableSequence & ( MAX_RELIABLE_COMMANDS - 1 ); - Q_strncpyz( clc.reliableCommands[ index ], cmd, sizeof( clc.reliableCommands[ index ] ) ); + + Q_strncpyz(clc.reliableCommands[++clc.reliableSequence & (MAX_RELIABLE_COMMANDS - 1)], + cmd, sizeof(*clc.reliableCommands)); } /* @@ -1329,7 +1337,7 @@ void CL_Disconnect( qboolean showMainMenu ) { // send a disconnect message to the server // send it a few times in case one is dropped if ( cls.state >= CA_CONNECTED ) { - CL_AddReliableCommand( "disconnect" ); + CL_AddReliableCommand("disconnect", qtrue); CL_WritePacket(); CL_WritePacket(); CL_WritePacket(); @@ -1388,9 +1396,9 @@ void CL_ForwardCommandToServer( const char *string ) { } if ( Cmd_Argc() > 1 ) { - CL_AddReliableCommand( string ); + CL_AddReliableCommand(string, qfalse); } else { - CL_AddReliableCommand( cmd ); + CL_AddReliableCommand(cmd, qfalse); } } @@ -1457,45 +1465,10 @@ void CL_ForwardToServer_f( void ) { // don't forward the first argument if ( Cmd_Argc() > 1 ) { - CL_AddReliableCommand( Cmd_Args() ); - } -} - -/* -================== -CL_Setenv_f - -Mostly for controlling voodoo environment variables -================== -*/ -void CL_Setenv_f( void ) { - int argc = Cmd_Argc(); - - if ( argc > 2 ) { - char buffer[1024]; - int i; - - strcpy( buffer, Cmd_Argv(1) ); - strcat( buffer, "=" ); - - for ( i = 2; i < argc; i++ ) { - strcat( buffer, Cmd_Argv( i ) ); - strcat( buffer, " " ); - } - - putenv( buffer ); - } else if ( argc == 2 ) { - char *env = getenv( Cmd_Argv(1) ); - - if ( env ) { - Com_Printf( "%s=%s\n", Cmd_Argv(1), env ); - } else { - Com_Printf( "%s undefined\n", Cmd_Argv(1)); - } + CL_AddReliableCommand(Cmd_Args(), qfalse); } } - /* ================== CL_Disconnect_f @@ -1697,7 +1670,7 @@ void CL_SendPureChecksums( void ) { // if we are pure we need to send back a command with our referenced pk3 checksums Com_sprintf(cMsg, sizeof(cMsg), "cp %d %s", cl.serverId, FS_ReferencedPakPureChecksums()); - CL_AddReliableCommand( cMsg ); + CL_AddReliableCommand(cMsg, qfalse); } /* @@ -1706,7 +1679,7 @@ CL_ResetPureClientAtServer ================= */ void CL_ResetPureClientAtServer( void ) { - CL_AddReliableCommand( va("vdr") ); + CL_AddReliableCommand("vdr", qfalse); } /* @@ -1888,7 +1861,7 @@ void CL_DownloadsComplete( void ) { FS_Restart(clc.checksumFeed); // We possibly downloaded a pak, restart the file system to load it // inform the server so we get new gamestate info - CL_AddReliableCommand( "donedl" ); + CL_AddReliableCommand("donedl", qfalse); // by sending the donedl command we request a new gamestate // so we don't want to load stuff yet @@ -1958,7 +1931,7 @@ void CL_BeginDownload( const char *localName, const char *remoteName ) { // Stop any errant looping sounds that may be playing S_ClearLoopingSounds( qtrue ); - CL_AddReliableCommand( va("download %s", remoteName) ); + CL_AddReliableCommand( va("download %s", remoteName), qfalse ); } /* @@ -2809,7 +2782,7 @@ void CL_CheckUserinfo( void ) { if(cvar_modifiedFlags & CVAR_USERINFO) { cvar_modifiedFlags &= ~CVAR_USERINFO; - CL_AddReliableCommand( va("userinfo \"%s\"", Cvar_InfoString( CVAR_USERINFO ) ) ); + CL_AddReliableCommand(va("userinfo \"%s\"", Cvar_InfoString( CVAR_USERINFO ) ), qfalse); } } @@ -3455,7 +3428,6 @@ void CL_Init( void ) { Cmd_AddCommand ("globalservers", CL_GlobalServers_f); Cmd_AddCommand ("rcon", CL_Rcon_f); Cmd_SetCommandCompletionFunc( "rcon", CL_CompleteRcon ); - Cmd_AddCommand ("setenv", CL_Setenv_f ); Cmd_AddCommand ("ping", CL_Ping_f ); Cmd_AddCommand ("serverstatus", CL_ServerStatus_f ); Cmd_AddCommand ("showip", CL_ShowIP_f ); @@ -3522,7 +3494,6 @@ void CL_Shutdown( void ) { Cmd_RemoveCommand ("localservers"); Cmd_RemoveCommand ("globalservers"); Cmd_RemoveCommand ("rcon"); - Cmd_RemoveCommand ("setenv"); Cmd_RemoveCommand ("ping"); Cmd_RemoveCommand ("serverstatus"); Cmd_RemoveCommand ("showip"); diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c index 96d4f799..08fab5a9 100644 --- a/src/client/cl_parse.c +++ b/src/client/cl_parse.c @@ -553,7 +553,7 @@ void CL_ParseDownload ( msg_t *msg ) { if (!*clc.downloadTempName) { Com_Printf("Server sending download, but no download was requested\n"); - CL_AddReliableCommand( "stopdl" ); + CL_AddReliableCommand("stopdl", qfalse); return; } @@ -595,7 +595,7 @@ void CL_ParseDownload ( msg_t *msg ) { if (!clc.download) { Com_Printf( "Could not create %s\n", clc.downloadTempName ); - CL_AddReliableCommand( "stopdl" ); + CL_AddReliableCommand("stopdl", qfalse); CL_NextDownload(); return; } @@ -604,7 +604,7 @@ void CL_ParseDownload ( msg_t *msg ) { if (size) FS_Write( data, size, clc.download ); - CL_AddReliableCommand( va("nextdl %d", clc.downloadBlock) ); + CL_AddReliableCommand(va("nextdl %d", clc.downloadBlock), qfalse); clc.downloadBlock++; clc.downloadCount += size; diff --git a/src/client/client.h b/src/client/client.h index a6d61950..4d5cd522 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -439,7 +439,7 @@ extern cvar_t *cl_voip; void CL_Init (void); void CL_FlushMemory(void); void CL_ShutdownAll(void); -void CL_AddReliableCommand( const char *cmd ); +void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd); void CL_StartHunkUsers( qboolean rendererOnly ); diff --git a/src/client/snd_dma.c b/src/client/snd_dma.c index c8df2daf..472af0d8 100644 --- a/src/client/snd_dma.c +++ b/src/client/snd_dma.c @@ -932,7 +932,7 @@ void S_ByteSwapRawSamples( int samples, int width, int s_channels, const byte *d /* ============ -S_RawSamples +S_Base_RawSamples Music streaming ============ @@ -953,10 +953,10 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan } rawsamples = s_rawsamples[stream]; - intVolume = 256 * volume; + intVolume = 256 * volume * s_volume->value; if ( s_rawend[stream] < s_soundtime ) { - Com_DPrintf( "S_RawSamples: resetting minimum: %i < %i\n", s_rawend[stream], s_soundtime ); + Com_DPrintf( "S_Base_RawSamples: resetting minimum: %i < %i\n", s_rawend[stream], s_soundtime ); s_rawend[stream] = s_soundtime; } @@ -1034,7 +1034,7 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan } if ( s_rawend[stream] > s_soundtime + MAX_RAW_SAMPLES ) { - Com_DPrintf( "S_RawSamples: overflowed %i > %i\n", s_rawend[stream], s_soundtime ); + Com_DPrintf( "S_Base_RawSamples: overflowed %i > %i\n", s_rawend[stream], s_soundtime ); } } diff --git a/src/client/snd_openal.c b/src/client/snd_openal.c index 1f91ae95..be064697 100644 --- a/src/client/snd_openal.c +++ b/src/client/snd_openal.c @@ -99,6 +99,22 @@ static const char *S_AL_ErrorMsg(ALenum error) } } +/* +================= +S_AL_ClearError +================= +*/ +static void S_AL_ClearError( qboolean quiet ) +{ + int error = qalGetError(); + + if( quiet ) + return; + if(error != AL_NO_ERROR) + Com_Printf(S_COLOR_YELLOW "WARNING: unhandled AL error: %s\n", + S_AL_ErrorMsg(error)); +} + //=========================================================================== @@ -219,7 +235,8 @@ static void S_AL_BufferUnload(sfxHandle_t sfx) if(!knownSfx[sfx].inMemory) return; - // Delete it + // Delete it + S_AL_ClearError( qfalse ); qalDeleteBuffers(1, &knownSfx[sfx].buffer); if((error = qalGetError()) != AL_NO_ERROR) Com_Printf( S_COLOR_RED "ERROR: Can't delete sound buffer for %s\n", @@ -303,6 +320,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx) format = S_AL_Format(info.width, info.channels); // Create a buffer + S_AL_ClearError( qfalse ); qalGenBuffers(1, &knownSfx[sfx].buffer); if((error = qalGetError()) != AL_NO_ERROR) { @@ -636,7 +654,8 @@ qboolean S_AL_SrcInit( void ) limit = MAX_SRC; else if(limit < 16) limit = 16; - + + S_AL_ClearError( qfalse ); // Allocate as many sources as possible for(i = 0; i < limit; i++) { @@ -1559,6 +1578,8 @@ void S_AL_MusicProcess(ALuint b) ALuint format; snd_stream_t *curstream; + S_AL_ClearError( qfalse ); + if(intro_stream) curstream = intro_stream; else @@ -1741,7 +1762,7 @@ static cvar_t *s_alCapture; #elif defined(MACOS_X) #define ALDRIVER_DEFAULT "/System/Library/Frameworks/OpenAL.framework/OpenAL" #else -#define ALDRIVER_DEFAULT "libopenal.so.0" +#define ALDRIVER_DEFAULT "libopenal.so.1" #endif /* diff --git a/src/qcommon/common.c b/src/qcommon/common.c index b97626ed..d4593e08 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -672,22 +672,6 @@ int Com_FilterPath(char *filter, char *name, int casesensitive) } /* -============ -Com_HashKey -============ -*/ -int Com_HashKey(char *string, int maxlen) { - int register hash, i; - - hash = 0; - for (i = 0; i < maxlen && string[i] != '\0'; i++) { - hash += string[i] * (119 + i); - } - hash = (hash ^ (hash >> 10) ^ (hash >> 20)); - return hash; -} - -/* ================ Com_RealTime ================ @@ -2361,6 +2345,43 @@ static void Com_Crash_f( void ) { * ( int * ) 0 = 0x12345678; } +/* +================== +Com_Setenv_f + +For controlling environment variables +================== +*/ +void Com_Setenv_f(void) +{ + int argc = Cmd_Argc(); + char *arg1 = Cmd_Argv(1); + + if(argc > 2) + { + char *arg2 = Cmd_ArgsFrom(2); + +#ifdef _WIN32 + // windows already removes env variable if value is an empty string + _putenv(va("%s=%s", arg1, arg2)); +#else + if(!*arg2) + unsetenv(arg1); + else + setenv(arg1, arg2, 1); +#endif + } + else if(argc == 2) + { + char *env = getenv(arg1); + + if(env) + Com_Printf("%s=%s\n", arg1, env); + else + Com_Printf("%s undefined\n", arg1); + } +} + static void Com_DetectAltivec(void) { // Only detect if user hasn't forcibly disabled it. @@ -2445,12 +2466,25 @@ void Com_Init( char *commandLine ) { Com_InitJournaling(); + // Add some commands here already so users can use them from config files + Cmd_AddCommand ("setenv", Com_Setenv_f); + if (com_developer && com_developer->integer) + { + Cmd_AddCommand ("error", Com_Error_f); + Cmd_AddCommand ("crash", Com_Crash_f); + Cmd_AddCommand ("freeze", Com_Freeze_f); + } + Cmd_AddCommand ("quit", Com_Quit_f); + Cmd_AddCommand ("changeVectors", MSG_ReportChangeVectors_f ); + Cmd_AddCommand ("writeconfig", Com_WriteConfig_f ); + Cmd_SetCommandCompletionFunc( "writeconfig", Cmd_CompleteCfgName ); + + // Make it execute the configuration files Cbuf_AddText ("exec default.cfg\n"); // skip the autogen.cfg if "safe" is on the command line - if ( !Com_SafeMode() ) { - Cbuf_AddText ("exec " Q3CONFIG_CFG "\n"); - } + if (!Com_SafeMode()) + Cbuf_AddText("exec " Q3CONFIG_CFG "\n"); Cbuf_AddText ("exec autoexec.cfg\n"); @@ -2506,16 +2540,6 @@ void Com_Init( char *commandLine ) { com_minimized = Cvar_Get( "com_minimized", "0", CVAR_ROM ); com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE ); - if ( com_developer && com_developer->integer ) { - Cmd_AddCommand ("error", Com_Error_f); - Cmd_AddCommand ("crash", Com_Crash_f ); - Cmd_AddCommand ("freeze", Com_Freeze_f); - } - Cmd_AddCommand ("quit", Com_Quit_f); - Cmd_AddCommand ("changeVectors", MSG_ReportChangeVectors_f ); - Cmd_AddCommand ("writeconfig", Com_WriteConfig_f ); - Cmd_SetCommandCompletionFunc( "writeconfig", Cmd_CompleteCfgName ); - s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ ); com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO ); diff --git a/src/qcommon/files.c b/src/qcommon/files.c index db7e79d4..75686111 100644 --- a/src/qcommon/files.c +++ b/src/qcommon/files.c @@ -250,7 +250,6 @@ static int fs_loadCount; // total files read static int fs_loadStack; // total files in memory static int fs_packFiles; // total number of files in packs -static int fs_fakeChkSum; static int fs_checksumFeed; typedef union qfile_gus { @@ -1175,14 +1174,6 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF continue; } - if ( Q_stricmp( filename + l - 4, ".cfg" ) // for config files - && Q_stricmp( filename + l - 5, ".menu" ) // menu files - && Q_stricmp( filename + l - 5, ".game" ) // menu files - && Q_stricmp( filename + l - strlen(demoExt), demoExt ) // menu files - && Q_stricmp( filename + l - 4, ".dat" ) ) { // for journal files - fs_fakeChkSum = random(); - } - Q_strncpyz( fsh[*file].name, filename, sizeof( fsh[*file].name ) ); fsh[*file].zipFile = qfalse; if ( fs_debug->integer ) { @@ -2994,10 +2985,6 @@ const char *FS_ReferencedPakPureChecksums( void ) { numPaks++; } } - if (fs_fakeChkSum != 0) { - // only added if a non-pure file is referenced - Q_strcat( info, sizeof( info ), va("%i ", fs_fakeChkSum ) ); - } } // last checksum is the encoded number of referenced pk3s checksum ^= numPaks; diff --git a/src/qcommon/msg.c b/src/qcommon/msg.c index 3d3355ec..9893a65a 100644 --- a/src/qcommon/msg.c +++ b/src/qcommon/msg.c @@ -312,9 +312,9 @@ void MSG_WriteString( msg_t *sb, const char *s ) { } Q_strncpyz( string, s, sizeof( string ) ); - // get rid of 0xff chars, because old clients don't like them + // get rid of 0x80+ and '%' chars, because old clients don't like them for ( i = 0 ; i < l ; i++ ) { - if ( ((byte *)string)[i] > 127 ) { + if ( ((byte *)string)[i] > 127 || string[i] == '%' ) { string[i] = '.'; } } @@ -338,9 +338,9 @@ void MSG_WriteBigString( msg_t *sb, const char *s ) { } Q_strncpyz( string, s, sizeof( string ) ); - // get rid of 0xff chars, because old clients don't like them + // get rid of 0x80+ and '%' chars, because old clients don't like them for ( i = 0 ; i < l ; i++ ) { - if ( ((byte *)string)[i] > 127 ) { + if ( ((byte *)string)[i] > 127 || string[i] == '%' ) { string[i] = '.'; } } @@ -514,6 +514,21 @@ void MSG_ReadData( msg_t *msg, void *data, int len ) { } } +// a string hasher which gives the same hash value even if the +// string is later modified via the legacy MSG read/write code +int MSG_HashKey(const char *string, int maxlen) { + int hash, i; + + hash = 0; + for (i = 0; i < maxlen && string[i] != '\0'; i++) { + if (string[i] & 0x80 || string[i] == '%') + hash += '.' * (119 + i); + else + hash += string[i] * (119 + i); + } + hash = (hash ^ (hash >> 10) ^ (hash >> 20)); + return hash; +} /* ============================================================================= diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index 59c5b91d..0cf4ca91 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -368,20 +368,20 @@ extern vec4_t colorMdGrey; extern vec4_t colorDkGrey; #define Q_COLOR_ESCAPE '^' -#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1)) ) // ^[0-9a-zA-Z] +#define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1))) // ^[0-9a-zA-Z] -#define COLOR_BLACK '0' -#define COLOR_RED '1' -#define COLOR_GREEN '2' +#define COLOR_BLACK '0' +#define COLOR_RED '1' +#define COLOR_GREEN '2' #define COLOR_YELLOW '3' -#define COLOR_BLUE '4' -#define COLOR_CYAN '5' +#define COLOR_BLUE '4' +#define COLOR_CYAN '5' #define COLOR_MAGENTA '6' -#define COLOR_WHITE '7' -#define ColorIndex(c) ( ( (c) - '0' ) & 7 ) +#define COLOR_WHITE '7' +#define ColorIndex(c) (((c) - '0') & 0x07) #define S_COLOR_BLACK "^0" -#define S_COLOR_RED "^1" +#define S_COLOR_RED "^1" #define S_COLOR_GREEN "^2" #define S_COLOR_YELLOW "^3" #define S_COLOR_BLUE "^4" diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index bcfd60b9..d240c2d1 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -75,6 +75,7 @@ void MSG_WriteFloat (msg_t *sb, float f); void MSG_WriteString (msg_t *sb, const char *s); void MSG_WriteBigString (msg_t *sb, const char *s); void MSG_WriteAngle16 (msg_t *sb, float f); +int MSG_HashKey(const char *string, int maxlen); void MSG_BeginReading (msg_t *sb); void MSG_BeginReadingOOB(msg_t *sb); @@ -786,7 +787,6 @@ void Com_Quit_f( void ); int Com_Milliseconds( void ); // will be journaled properly unsigned Com_BlockChecksum( const void *buffer, int length ); char *Com_MD5File(const char *filename, int length, const char *prefix, int prefix_len); -int Com_HashKey(char *string, int maxlen); int Com_Filter(char *filter, char *name, int casesensitive); int Com_FilterPath(char *filter, char *name, int casesensitive); int Com_RealTime(qtime_t *qtime); diff --git a/src/qcommon/vm_x86_64_assembler.c b/src/qcommon/vm_x86_64_assembler.c index be295e3a..5747626a 100644 --- a/src/qcommon/vm_x86_64_assembler.c +++ b/src/qcommon/vm_x86_64_assembler.c @@ -593,7 +593,7 @@ static void emit_mov(const char* mnemonic, arg_t arg1, arg_t arg2, void* data) crap("value too large for 16bit register"); emit1(0x66); } - else if(!arg2.v.reg & R_64) + else if(!(arg2.v.reg & R_64)) { if(!isu32(arg1.v.imm)) crap("value too large for 32bit register"); diff --git a/src/server/server.h b/src/server/server.h index fca29aae..a41dba91 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -216,6 +216,7 @@ typedef struct { int time; // time the last packet was sent to the autherize server int pingTime; // time the challenge response was sent to client int firstTime; // time the adr was first used, for authorize timeout checks + qboolean wasrefused; qboolean connected; } challenge_t; diff --git a/src/server/sv_client.c b/src/server/sv_client.c index 319f865e..92c4d5f1 100644 --- a/src/server/sv_client.c +++ b/src/server/sv_client.c @@ -65,7 +65,7 @@ void SV_GetChallenge(netadr_t from) // see if we already have a challenge for this ip challenge = &svs.challenges[0]; for (i = 0 ; i < MAX_CHALLENGES ; i++, challenge++) { - if ( !challenge->connected && NET_CompareAdr( from, challenge->adr ) ) { + if (!challenge->connected && NET_CompareAdr( from, challenge->adr ) ) { break; } if ( challenge->time < oldestTime ) { @@ -78,7 +78,6 @@ void SV_GetChallenge(netadr_t from) { // this is the first time this client has asked for a challenge challenge = &svs.challenges[oldest]; - challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time; challenge->clientChallenge = 0; challenge->adr = from; challenge->firstTime = svs.time; @@ -86,9 +85,9 @@ void SV_GetChallenge(netadr_t from) challenge->connected = qfalse; } - // send the challengeResponse - challenge->pingTime = svs.time; - NET_OutOfBandPrint( NS_SERVER, from, "challengeResponse %i", challenge->challenge ); + // always generate a new challenge number, so the client cannot circumvent sv_maxping + challenge->challenge = ( (rand() << 16) ^ rand() ) ^ svs.time; + challenge->wasrefused = qfalse; challenge->pingTime = svs.time; NET_OutOfBandPrint( NS_SERVER, challenge->adr, "challengeResponse %i %s", challenge->challenge, clientChallenge); @@ -162,41 +161,53 @@ void SV_DirectConnect( netadr_t from ) { Info_SetValueForKey( userinfo, "ip", ip ); // see if the challenge is valid (LAN clients don't need to challenge) - if ( !NET_IsLocalAddress (from) ) { - int ping; + if (!NET_IsLocalAddress(from)) + { + int ping; + challenge_t *challengeptr; - for (i=0 ; i<MAX_CHALLENGES ; i++) { - if (NET_CompareAdr(from, svs.challenges[i].adr)) { - if ( challenge == svs.challenges[i].challenge ) + for (i=0; i<MAX_CHALLENGES; i++) + { + if (NET_CompareAdr(from, svs.challenges[i].adr)) + { + if(challenge == svs.challenges[i].challenge) break; } } - if (i == MAX_CHALLENGES) { - NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address\n" ); + if (i == MAX_CHALLENGES) + { + NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for your address.\n" ); + return; + } + + challengeptr = &svs.challenges[i]; + + if(challengeptr->wasrefused) + { + // Return silently, so that error messages written by the server keep being displayed. return; } - ping = svs.time - svs.challenges[i].pingTime; - Com_Printf( "Client %i connecting with %i challenge ping\n", i, ping ); - svs.challenges[i].connected = qtrue; + ping = svs.time - challengeptr->pingTime; // never reject a LAN client based on ping if ( !Sys_IsLANAddress( from ) ) { if ( sv_minPing->value && ping < sv_minPing->value ) { - // don't let them keep trying until they get a big delay NET_OutOfBandPrint( NS_SERVER, from, "print\nServer is for high pings only\n" ); Com_DPrintf ("Client %i rejected on a too low ping\n", i); - // reset the address otherwise their ping will keep increasing - // with each connect message and they'd eventually be able to connect - svs.challenges[i].adr.port = 0; + challengeptr->wasrefused = qtrue; return; } if ( sv_maxPing->value && ping > sv_maxPing->value ) { NET_OutOfBandPrint( NS_SERVER, from, "print\nServer is for low pings only\n" ); Com_DPrintf ("Client %i rejected on a too high ping\n", i); + challengeptr->wasrefused = qtrue; return; } } + + Com_Printf("Client %i connecting with %i challenge ping\n", i, ping); + challengeptr->connected = qtrue; } newcl = &temp; @@ -1197,7 +1208,7 @@ void SV_UpdateVoipIgnore(client_t *cl, const char *idstr, qboolean ignore) /* ================== -SV_UpdateUserinfo_f +SV_Voip_f ================== */ static void SV_Voip_f( client_t *cl ) { @@ -1390,7 +1401,7 @@ static void SV_UserMove( client_t *cl, msg_t *msg, qboolean delta ) { // also use the message acknowledge key ^= cl->messageAcknowledge; // also use the last acknowledged server command in the key - key ^= Com_HashKey(cl->reliableCommands[ cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ], 32); + key ^= MSG_HashKey(cl->reliableCommands[ cl->reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ], 32); Com_Memset( &nullcmd, 0, sizeof(nullcmd) ); oldcmd = &nullcmd; |