16 Feb 2018
This commit is contained in:
parent
69910228a0
commit
3090953beb
|
@ -80,9 +80,9 @@ void CL_PlayCDTrack_f( void )
|
|||
if( Q_isdigit( pszTrack ))
|
||||
{
|
||||
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], NULL, 0 );
|
||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], NULL, 0, false );
|
||||
}
|
||||
else S_StartBackgroundTrack( pszTrack, NULL, 0 );
|
||||
else S_StartBackgroundTrack( pszTrack, NULL, 0, true );
|
||||
paused = false;
|
||||
looped = false;
|
||||
}
|
||||
|
@ -91,9 +91,9 @@ void CL_PlayCDTrack_f( void )
|
|||
if( Q_isdigit( pszTrack ))
|
||||
{
|
||||
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0 );
|
||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0, false );
|
||||
}
|
||||
else S_StartBackgroundTrack( pszTrack, pszTrack, 0 );
|
||||
else S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
|
||||
paused = false;
|
||||
looped = true;
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ so that we can play the demo correctly.
|
|||
*/
|
||||
void CL_WriteDemoSequence( file_t *file )
|
||||
{
|
||||
Assert( file );
|
||||
Assert( file != NULL );
|
||||
|
||||
FS_Write( file, &cls.netchan.incoming_sequence, sizeof( int ));
|
||||
FS_Write( file, &cls.netchan.incoming_acknowledged, sizeof( int ));
|
||||
|
|
|
@ -28,7 +28,7 @@ CL_ResetEvent
|
|||
void CL_ResetEvent( event_info_t *ei )
|
||||
{
|
||||
ei->index = 0;
|
||||
memset( &ei->args, 0, sizeof( ei->args ) );
|
||||
memset( &ei->args, 0, sizeof( ei->args ));
|
||||
ei->fire_time = 0.0;
|
||||
ei->flags = 0;
|
||||
}
|
||||
|
|
|
@ -801,7 +801,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
|||
// delta from previous state
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
CL_DeltaEntity( msg, newframe, newnum, oldent, true );
|
||||
if( CL_IsPlayerIndex( newnum ) )
|
||||
if( CL_IsPlayerIndex( newnum ))
|
||||
playerbytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
oldindex++;
|
||||
|
||||
|
@ -822,7 +822,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
|||
// delta from baseline ?
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
CL_DeltaEntity( msg, newframe, newnum, NULL, true );
|
||||
if( CL_IsPlayerIndex( newnum ) )
|
||||
if( CL_IsPlayerIndex( newnum ))
|
||||
playerbytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ cl_entity_t *CL_GetEntityByIndex( int index )
|
|||
return NULL;
|
||||
|
||||
if( index == 0 )
|
||||
return cl.world;
|
||||
return clgame.entities;
|
||||
|
||||
return CL_EDICT_NUM( index );
|
||||
}
|
||||
|
@ -1057,19 +1057,21 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize )
|
|||
|
||||
void CL_FreeEntity( cl_entity_t *pEdict )
|
||||
{
|
||||
Assert( pEdict );
|
||||
Assert( pEdict != NULL );
|
||||
R_RemoveEfrags( pEdict );
|
||||
CL_KillDeadBeams( pEdict );
|
||||
}
|
||||
|
||||
void CL_ClearWorld( void )
|
||||
{
|
||||
cl.world = clgame.entities;
|
||||
cl.world->curstate.modelindex = 1; // world model
|
||||
cl.world->curstate.solid = SOLID_BSP;
|
||||
cl.world->curstate.movetype = MOVETYPE_PUSH;
|
||||
cl.world->model = cl.worldmodel;
|
||||
cl.world->index = 0;
|
||||
cl_entity_t *world;
|
||||
|
||||
world = clgame.entities;
|
||||
world->curstate.modelindex = 1; // world model
|
||||
world->curstate.solid = SOLID_BSP;
|
||||
world->curstate.movetype = MOVETYPE_PUSH;
|
||||
world->model = cl.worldmodel;
|
||||
world->index = 0;
|
||||
|
||||
clgame.ds.cullMode = GL_FRONT;
|
||||
clgame.numStatics = 0;
|
||||
|
@ -1615,7 +1617,7 @@ pfnServerCmd
|
|||
*/
|
||||
static int pfnServerCmd( const char *szCmdString )
|
||||
{
|
||||
string buf;
|
||||
string buf;
|
||||
|
||||
if( !szCmdString || !szCmdString[0] )
|
||||
return 0;
|
||||
|
@ -2553,7 +2555,7 @@ void PlayerInfo_SetValueForKey( const char *key, const char *value )
|
|||
convar_t *var;
|
||||
|
||||
if( !Q_strcmp( Info_ValueForKey( cls.userinfo, key ), value ))
|
||||
return; // not changes ?
|
||||
return; // no changes ?
|
||||
|
||||
var = Cvar_FindVar( key );
|
||||
|
||||
|
@ -2576,10 +2578,15 @@ pfnGetPlayerUniqueID
|
|||
*/
|
||||
qboolean pfnGetPlayerUniqueID( int iPlayer, char playerID[16] )
|
||||
{
|
||||
// TODO: implement
|
||||
if( iPlayer < 1 || iPlayer > cl.maxclients )
|
||||
return false;
|
||||
|
||||
playerID[0] = '\0';
|
||||
return false;
|
||||
// make sure there is a player here..
|
||||
if( !cl.players[iPlayer-1].userinfo[0] || !cl.players[iPlayer-1].name[0] )
|
||||
return false;
|
||||
|
||||
memcpy( playerID, cl.players[iPlayer-1].hashedcdkey, 16 );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3674,7 +3681,7 @@ void CL_UnloadProgs( void )
|
|||
VGui_Shutdown();
|
||||
|
||||
// NOTE: HLFX 0.5 has strange bug: hanging on exit if no map was loaded
|
||||
if( !( !Q_stricmp( GI->gamedir, "hlfx" ) && GI->version == 0.5f ))
|
||||
if( Q_stricmp( GI->gamedir, "hlfx" ) || GI->version != 0.5f )
|
||||
clgame.dllFuncs.pfnShutdown();
|
||||
|
||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
|
@ -3705,10 +3712,6 @@ qboolean CL_LoadProgs( const char *name )
|
|||
clgame.mempool = Mem_AllocPool( "Client Edicts Zone" );
|
||||
clgame.entities = NULL;
|
||||
|
||||
// NOTE: important stuff! vgui must startup BEFORE loading client.dll
|
||||
// to avoid get error ERROR_NOACESS during LoadLibrary
|
||||
VGui_Startup ();
|
||||
|
||||
clgame.hInstance = Com_LoadLibrary( name, false );
|
||||
if( !clgame.hInstance ) return false;
|
||||
|
||||
|
@ -3804,6 +3807,9 @@ qboolean CL_LoadProgs( const char *name )
|
|||
|
||||
CL_InitStudioAPI( );
|
||||
|
||||
// initialize VGui
|
||||
VGui_Startup ();
|
||||
|
||||
// trying to grab them from client.dll
|
||||
cl_righthand = Cvar_FindVar( "cl_righthand" );
|
||||
|
||||
|
|
|
@ -896,7 +896,7 @@ pfnStartBackgroundTrack
|
|||
*/
|
||||
static void pfnStartBackgroundTrack( const char *introTrack, const char *mainTrack )
|
||||
{
|
||||
S_StartBackgroundTrack( introTrack, mainTrack, 0 );
|
||||
S_StartBackgroundTrack( introTrack, mainTrack, 0, false );
|
||||
|
||||
// HACKHACK to remove glitches from background track while new game is started.
|
||||
if( !introTrack && !mainTrack )
|
||||
|
|
|
@ -148,75 +148,6 @@ int CL_IsDevOverviewMode( void )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_ChangeGame
|
||||
|
||||
This is experiment. Use with precaution
|
||||
===============
|
||||
*/
|
||||
qboolean CL_ChangeGame( const char *gamefolder, qboolean bReset )
|
||||
{
|
||||
if( host.type == HOST_DEDICATED )
|
||||
return false;
|
||||
|
||||
if( Q_stricmp( host.gamefolder, gamefolder ))
|
||||
{
|
||||
kbutton_t *mlook, *jlook;
|
||||
qboolean mlook_active = false, jlook_active = false;
|
||||
string mapname, maptitle;
|
||||
int maxEntities;
|
||||
|
||||
mlook = (kbutton_t *)clgame.dllFuncs.KB_Find( "in_mlook" );
|
||||
jlook = (kbutton_t *)clgame.dllFuncs.KB_Find( "in_jlook" );
|
||||
|
||||
if( mlook && ( mlook->state & 1 ))
|
||||
mlook_active = true;
|
||||
|
||||
if( jlook && ( jlook->state & 1 ))
|
||||
jlook_active = true;
|
||||
|
||||
// so reload all images (remote connect)
|
||||
Mod_ClearAll( true );
|
||||
R_ShutdownImages();
|
||||
FS_LoadGameInfo( (bReset) ? host.gamefolder : gamefolder );
|
||||
R_InitImages();
|
||||
|
||||
// save parms
|
||||
maxEntities = clgame.maxEntities;
|
||||
Q_strncpy( mapname, clgame.mapname, MAX_STRING );
|
||||
Q_strncpy( maptitle, clgame.maptitle, MAX_STRING );
|
||||
|
||||
if( !CL_LoadProgs( va( "%s/client.dll", GI->dll_path )))
|
||||
Host_Error( "can't initialize client.dll\n" );
|
||||
|
||||
// restore parms
|
||||
clgame.maxEntities = maxEntities;
|
||||
Q_strncpy( clgame.mapname, mapname, MAX_STRING );
|
||||
Q_strncpy( clgame.maptitle, maptitle, MAX_STRING );
|
||||
|
||||
// invalidate fonts so we can reloading them again
|
||||
memset( &cls.creditsFont, 0, sizeof( cls.creditsFont ));
|
||||
SCR_InstallParticlePalette();
|
||||
SCR_LoadCreditsFont();
|
||||
Con_InvalidateFonts();
|
||||
|
||||
SCR_RegisterTextures ();
|
||||
CL_FreeEdicts ();
|
||||
SCR_VidInit ();
|
||||
|
||||
if( cls.key_dest == key_game ) // restore mouse state
|
||||
clgame.dllFuncs.IN_ActivateMouse();
|
||||
|
||||
// restore mlook state
|
||||
if( mlook_active ) Cmd_ExecuteString( "+mlook\n" );
|
||||
if( jlook_active ) Cmd_ExecuteString( "+jlook\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_CheckClientState
|
||||
|
@ -231,13 +162,17 @@ void CL_CheckClientState( void )
|
|||
{
|
||||
// first update is the final signon stage
|
||||
cls.state = ca_active;
|
||||
cls.changelevel = false;
|
||||
cls.changedemo = false;
|
||||
cls.changelevel = false; // changelevel is done
|
||||
cls.changedemo = false; // changedemo is done
|
||||
cl.first_frame = true;
|
||||
|
||||
Cvar_SetValue( "scr_loading", 0.0f );
|
||||
SCR_MakeLevelShot(); // make levelshot if needs
|
||||
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
|
||||
Netchan_ReportFlow( &cls.netchan );
|
||||
SCR_MakeLevelShot();
|
||||
|
||||
if(( cls.demoplayback || cls.disable_servercount != cl.servercount ) && cl.video_prepped )
|
||||
SCR_EndLoadingPlaque(); // get rid of loading plaque
|
||||
cl.first_frame = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +201,7 @@ static float CL_LerpPoint( void )
|
|||
return 1.0f;
|
||||
}
|
||||
|
||||
if( cl_interp->value > 0.001f )
|
||||
if( cl_interp->value > 0.001f && !FBitSet( host.features, ENGINE_FIXED_FRAMERATE ))
|
||||
{
|
||||
// manual lerp value (goldsrc mode)
|
||||
frac = ( cl.time - cl.mtime[0] ) / cl_interp->value;
|
||||
|
@ -623,13 +558,13 @@ void CL_CreateCmd( void )
|
|||
// message we are constructing.
|
||||
i = cls.netchan.outgoing_sequence & CL_UPDATE_MASK;
|
||||
pcmd = &cl.commands[i];
|
||||
pcmd->processedfuncs = false;
|
||||
|
||||
if( !cls.demoplayback )
|
||||
{
|
||||
pcmd->senttime = host.realtime;
|
||||
memset( &pcmd->cmd, 0, sizeof( pcmd->cmd ));
|
||||
pcmd->receivedtime = -1.0;
|
||||
pcmd->processedfuncs = false;
|
||||
pcmd->heldback = false;
|
||||
pcmd->sendsize = 0;
|
||||
CL_ApplyAddAngle();
|
||||
|
@ -910,6 +845,38 @@ void CL_Drop( void )
|
|||
CL_Disconnect();
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
CL_GetCDKeyHash()
|
||||
|
||||
Connections will now use a hashed cd key value
|
||||
=======================
|
||||
*/
|
||||
char *CL_GetCDKeyHash( void )
|
||||
{
|
||||
const char *keyBuffer;
|
||||
static char szHashedKeyBuffer[256];
|
||||
int nKeyLength = 0;
|
||||
byte digest[17]; // The MD5 Hash
|
||||
MD5Context_t ctx;
|
||||
|
||||
keyBuffer = Sys_GetMachineKey( &nKeyLength );
|
||||
|
||||
// now get the md5 hash of the key
|
||||
memset( &ctx, 0, sizeof( ctx ));
|
||||
memset( digest, 0, sizeof( digest ));
|
||||
|
||||
MD5Init( &ctx );
|
||||
MD5Update( &ctx, (byte *)keyBuffer, nKeyLength );
|
||||
MD5Final( digest, &ctx );
|
||||
digest[16] = '\0';
|
||||
|
||||
memset( szHashedKeyBuffer, 0, 256 );
|
||||
Q_strncpy( szHashedKeyBuffer, MD5_Print( digest ), sizeof( szHashedKeyBuffer ));
|
||||
|
||||
return szHashedKeyBuffer;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
CL_SendConnectPacket
|
||||
|
@ -920,8 +887,10 @@ connect.
|
|||
*/
|
||||
void CL_SendConnectPacket( void )
|
||||
{
|
||||
char protinfo[MAX_INFO_STRING];
|
||||
char *qport;
|
||||
char *key;
|
||||
netadr_t adr;
|
||||
int port;
|
||||
|
||||
if( !NET_StringToAdr( cls.servername, &adr ))
|
||||
{
|
||||
|
@ -931,9 +900,14 @@ void CL_SendConnectPacket( void )
|
|||
}
|
||||
|
||||
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
|
||||
port = Cvar_VariableValue( "net_qport" );
|
||||
qport = Cvar_VariableString( "net_qport" );
|
||||
key = CL_GetCDKeyHash();
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i %i \"%s\"\n", PROTOCOL_VERSION, port, cls.challenge, cls.userinfo );
|
||||
memset( protinfo, 0, sizeof( protinfo ));
|
||||
Info_SetValueForKey( protinfo, "uuid", key, sizeof( protinfo ));
|
||||
Info_SetValueForKey( protinfo, "qport", qport, sizeof( protinfo ));
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i \"%s\" \"%s\"\n", PROTOCOL_VERSION, cls.challenge, protinfo, cls.userinfo );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1167,9 +1141,6 @@ void CL_Disconnect( void )
|
|||
cls.state = ca_disconnected;
|
||||
cls.signon = 0;
|
||||
|
||||
// restore gamefolder here (in case client was connected to another game)
|
||||
CL_ChangeGame( GI->gamefolder, true );
|
||||
|
||||
// back to menu if developer mode set to "player" or "mapper"
|
||||
if( host.developer > 2 || CL_IsInMenu( ))
|
||||
return;
|
||||
|
@ -1179,7 +1150,9 @@ void CL_Disconnect( void )
|
|||
|
||||
void CL_Disconnect_f( void )
|
||||
{
|
||||
Host_Error( "Disconnected from server\n" );
|
||||
if( Host_IsLocalClient( ))
|
||||
Host_EndGame( "disconnected from server\n" );
|
||||
else CL_Disconnect();
|
||||
}
|
||||
|
||||
void CL_Crashed( void )
|
||||
|
@ -1660,9 +1633,9 @@ void CL_PrepVideo( void )
|
|||
if( host.developer <= 2 )
|
||||
Con_ClearNotify(); // clear any lines of console text
|
||||
|
||||
SCR_UpdateScreen ();
|
||||
|
||||
cl.video_prepped = true;
|
||||
|
||||
SCR_UpdateScreen ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1743,7 +1716,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
else if( !Q_strcmp( c, "print" ))
|
||||
{
|
||||
// print command from somewhere
|
||||
Msg( "remote: %s\n", MSG_ReadString( msg ));
|
||||
Msg( "%s", MSG_ReadString( msg ));
|
||||
}
|
||||
else if( !Q_strcmp( c, "ping" ))
|
||||
{
|
||||
|
@ -1766,7 +1739,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
{
|
||||
// a disconnect message from the server, which will happen if the server
|
||||
// dropped the connection but it is still getting packets from us
|
||||
CL_Disconnect();
|
||||
CL_Disconnect_f();
|
||||
}
|
||||
else if( !Q_strcmp( c, "f" ))
|
||||
{
|
||||
|
@ -2222,6 +2195,7 @@ void CL_InitLocal( void )
|
|||
cl_lw = Cvar_Get( "cl_lw", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
|
||||
Cvar_Get( "cl_lc", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable lag compensation" );
|
||||
Cvar_Get( "msg", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "message filter for server notifications" );
|
||||
Cvar_Get( "password", "", FCVAR_USERINFO, "server password" );
|
||||
Cvar_Get( "team", "", FCVAR_USERINFO, "player team" );
|
||||
Cvar_Get( "skin", "", FCVAR_USERINFO, "player skin" );
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ const char *svc_strings[256] =
|
|||
"svc_updateuserinfo",
|
||||
"svc_deltatable",
|
||||
"svc_clientdata",
|
||||
"svc_stopsound",
|
||||
"svc_studiodecal",
|
||||
"svc_pings",
|
||||
"svc_particle",
|
||||
"svc_restoresound",
|
||||
|
@ -58,7 +58,7 @@ const char *svc_strings[256] =
|
|||
"svc_centerprint",
|
||||
"svc_modelindex",
|
||||
"svc_soundindex",
|
||||
"svc_ambientsound",
|
||||
"svc_eventindex",
|
||||
"svc_intermission",
|
||||
"svc_finale",
|
||||
"svc_cdtrack",
|
||||
|
@ -81,9 +81,9 @@ const char *svc_strings[256] =
|
|||
"svc_filetxferfailed",
|
||||
"svc_hltv",
|
||||
"svc_director",
|
||||
"svc_studiodecal",
|
||||
"svc_voiceinit",
|
||||
"svc_voicedata",
|
||||
"svc_eventindex",
|
||||
"svc_unused54",
|
||||
"svc_unused55",
|
||||
"svc_resourcelocation",
|
||||
"svc_querycvarvalue",
|
||||
|
@ -267,15 +267,15 @@ void CL_ParseSoundPacket( sizebuf_t *msg )
|
|||
sound = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
||||
chan = MSG_ReadUBitLong( msg, MAX_SND_CHAN_BITS );
|
||||
|
||||
if( flags & SND_VOLUME )
|
||||
if( FBitSet( flags, SND_VOLUME ))
|
||||
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
else volume = VOL_NORM;
|
||||
|
||||
if( flags & SND_ATTENUATION )
|
||||
if( FBitSet( flags, SND_ATTENUATION ))
|
||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
|
||||
if( flags & SND_PITCH )
|
||||
if( FBitSet( flags, SND_PITCH ))
|
||||
pitch = MSG_ReadByte( msg );
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
|
@ -285,11 +285,11 @@ void CL_ParseSoundPacket( sizebuf_t *msg )
|
|||
// positioned in space
|
||||
MSG_ReadVec3Coord( msg, pos );
|
||||
|
||||
if( flags & SND_SENTENCE )
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
|
||||
if( flags & SND_SEQUENCE )
|
||||
if( FBitSet( flags, SND_SEQUENCE ))
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound );
|
||||
else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
|
||||
|
@ -303,6 +303,7 @@ void CL_ParseSoundPacket( sizebuf_t *msg )
|
|||
return; // too early
|
||||
}
|
||||
|
||||
// g-cont. sound and ambient sound have only difference with channel
|
||||
if( chan == CHAN_STATIC )
|
||||
{
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
|
@ -658,6 +659,28 @@ void CL_ParseCustomization( sizebuf_t *msg )
|
|||
// TODO: ???
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseResourceRequest
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseResourceRequest( sizebuf_t *msg )
|
||||
{
|
||||
// TODO: ???
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseFileTransferFailed
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseFileTransferFailed( sizebuf_t *msg )
|
||||
{
|
||||
// TODO: ???
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
|
@ -729,6 +752,9 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
// multiplayer game?
|
||||
if( cl.maxclients != 1 )
|
||||
{
|
||||
// loading user settings
|
||||
CSCR_LoadDefaultCVars( "user.scr" );
|
||||
|
||||
if( r_decals->value > mp_decals.value )
|
||||
Cvar_SetValue( "r_decals", mp_decals.value );
|
||||
}
|
||||
|
@ -752,10 +778,7 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
// continue playing if we are changing level
|
||||
S_StopBackgroundTrack ();
|
||||
}
|
||||
#if 0
|
||||
// NOTE: this is not tested as well. Use with precaution
|
||||
CL_ChangeGame( gamefolder, false );
|
||||
#endif
|
||||
|
||||
if( !cls.changedemo )
|
||||
UI_SetActiveMenu( cl.background );
|
||||
else if( !cls.demoplayback )
|
||||
|
@ -1084,6 +1107,33 @@ void CL_ParseCrosshairAngle( sizebuf_t *msg )
|
|||
cl.crosshairangle[2] = 0.0f; // not used for screen space
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ParseRestore
|
||||
|
||||
reading decals, etc.
|
||||
================
|
||||
*/
|
||||
void CL_ParseRestore( sizebuf_t *msg )
|
||||
{
|
||||
string filename;
|
||||
int i, mapCount;
|
||||
char *pMapName;
|
||||
|
||||
// mapname.HL2
|
||||
Q_strncpy( filename, MSG_ReadString( msg ), sizeof( filename ));
|
||||
mapCount = MSG_ReadByte( msg );
|
||||
|
||||
// g-cont. acutally in Xash3D this does nothing.
|
||||
// decals already restored on a server, and correctly transferred through levels
|
||||
// but i'm leave this message for backward compatibility
|
||||
for( i = 0; i < mapCount; i++ )
|
||||
{
|
||||
pMapName = MSG_ReadString( msg );
|
||||
MsgDev( D_INFO, "Loading decals from %s\n", pMapName );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_RegisterUserMessage
|
||||
|
@ -1137,6 +1187,7 @@ void CL_UpdateUserinfo( sizebuf_t *msg )
|
|||
player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" ));
|
||||
player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" ));
|
||||
player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" ));
|
||||
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
|
||||
if( slot == cl.playernum ) memcpy( &gameui.playerinfo, player, sizeof( player_info_t ));
|
||||
}
|
||||
|
@ -1322,6 +1373,39 @@ void CL_ParseResourceList( sizebuf_t *msg )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseVoiceInit
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseVoiceInit( sizebuf_t *msg )
|
||||
{
|
||||
// TODO: ???
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseVoiceData
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseVoiceData( sizebuf_t *msg )
|
||||
{
|
||||
// TODO: ???
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseResLocation
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseResLocation( sizebuf_t *msg )
|
||||
{
|
||||
// TODO: ???
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CL_ParseHLTV
|
||||
|
@ -1675,6 +1759,8 @@ ACTION MESSAGES
|
|||
/*
|
||||
=====================
|
||||
CL_ParseServerMessage
|
||||
|
||||
INTERNAL RESOURCE
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
|
@ -1712,7 +1798,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
// mark start position
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
// end of message
|
||||
// end of message (align bits)
|
||||
if( MSG_GetNumBitsLeft( msg ) < 8 )
|
||||
break;
|
||||
|
||||
|
@ -1734,6 +1820,10 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
CL_Drop ();
|
||||
Host_AbortCurrentFrame ();
|
||||
break;
|
||||
case svc_event:
|
||||
CL_ParseEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_changing:
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
|
@ -1763,7 +1853,6 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
case svc_ambientsound:
|
||||
CL_ParseSoundPacket( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
|
@ -1772,16 +1861,18 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
break;
|
||||
case svc_print:
|
||||
i = MSG_ReadByte( msg );
|
||||
MsgDev( D_INFO, "^6%s", MSG_ReadString( msg ));
|
||||
if( i == PRINT_CHAT ) S_StartLocalSound( "common/menu2.wav", VOL_NORM, false );
|
||||
MsgDev( D_INFO, "^5%s", MSG_ReadString( msg ));
|
||||
if( i == PRINT_CHAT )
|
||||
{
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
S_StartLocalSound( "misc/talk.wav", VOL_NORM, false );
|
||||
else S_StartLocalSound( "common/menu2.wav", VOL_NORM, false );
|
||||
}
|
||||
break;
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
Cbuf_AddText( s );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
break;
|
||||
|
@ -1789,29 +1880,25 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg );
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
break;
|
||||
case svc_clientdata:
|
||||
CL_ParseClientData( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
case svc_studiodecal:
|
||||
CL_ParseStudioDecal( msg );
|
||||
break;
|
||||
case svc_pings:
|
||||
CL_UpdateUserPings( msg );
|
||||
break;
|
||||
case svc_usermessage:
|
||||
CL_RegisterUserMessage( msg );
|
||||
break;
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg );
|
||||
break;
|
||||
|
@ -1822,8 +1909,9 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
case svc_spawnstatic:
|
||||
CL_ParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
case svc_event_reliable:
|
||||
CL_ParseReliableEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
CL_ParseBaseline( msg );
|
||||
|
@ -1838,56 +1926,36 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
case svc_signonnum:
|
||||
CL_ParseSignon( msg );
|
||||
break;
|
||||
case svc_deltamovevars:
|
||||
CL_ParseMovevars( msg );
|
||||
break;
|
||||
case svc_customization:
|
||||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_event:
|
||||
CL_ParseEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
CL_ParseReliableEvent( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg );
|
||||
break;
|
||||
case svc_intermission:
|
||||
cl.intermission = 1;
|
||||
break;
|
||||
case svc_finale:
|
||||
CL_ParseFinaleCutscene( msg, 2 );
|
||||
break;
|
||||
case svc_cutscene:
|
||||
CL_ParseFinaleCutscene( msg, 3 );
|
||||
break;
|
||||
case svc_modelindex:
|
||||
CL_PrecacheModel( msg );
|
||||
break;
|
||||
case svc_soundindex:
|
||||
CL_PrecacheSound( msg );
|
||||
break;
|
||||
case svc_soundfade:
|
||||
CL_ParseSoundFade( msg );
|
||||
case svc_eventindex:
|
||||
CL_PrecacheEvent( msg );
|
||||
break;
|
||||
case svc_intermission:
|
||||
cl.intermission = 1;
|
||||
break;
|
||||
case svc_finale:
|
||||
CL_ParseFinaleCutscene( msg, 2 );
|
||||
break;
|
||||
case svc_cdtrack:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
|
||||
param2 = MSG_ReadByte( msg );
|
||||
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
|
||||
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0 );
|
||||
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
|
||||
break;
|
||||
case svc_eventindex:
|
||||
CL_PrecacheEvent( msg );
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
case svc_cutscene:
|
||||
CL_ParseFinaleCutscene( msg, 3 );
|
||||
break;
|
||||
case svc_weaponanim:
|
||||
param1 = MSG_ReadByte( msg ); // iAnim
|
||||
|
@ -1901,6 +1969,22 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
param1 = MSG_ReadShort( msg );
|
||||
Cvar_SetValue( "room_type", param1 );
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_usermessage:
|
||||
CL_RegisterUserMessage( msg );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_choke:
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||
|
@ -1908,14 +1992,38 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
case svc_resourcelist:
|
||||
CL_ParseResourceList( msg );
|
||||
break;
|
||||
case svc_director:
|
||||
CL_ParseDirector( msg );
|
||||
case svc_deltamovevars:
|
||||
CL_ParseMovevars( msg );
|
||||
break;
|
||||
case svc_resourcerequest:
|
||||
CL_ParseResourceRequest( msg );
|
||||
break;
|
||||
case svc_customization:
|
||||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
case svc_soundfade:
|
||||
CL_ParseSoundFade( msg );
|
||||
break;
|
||||
case svc_filetxferfailed:
|
||||
CL_ParseFileTransferFailed( msg );
|
||||
break;
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_studiodecal:
|
||||
CL_ParseStudioDecal( msg );
|
||||
case svc_director:
|
||||
CL_ParseDirector( msg );
|
||||
break;
|
||||
case svc_voiceinit:
|
||||
CL_ParseVoiceInit( msg );
|
||||
break;
|
||||
case svc_voicedata:
|
||||
CL_ParseVoiceData( msg );
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg );
|
||||
|
|
|
@ -1219,8 +1219,8 @@ void CL_PredictMovement( qboolean repredicting )
|
|||
frame_t *frame = NULL;
|
||||
int i, stoppoint;
|
||||
qboolean runfuncs;
|
||||
double f = 1.0;
|
||||
double time;
|
||||
float f;
|
||||
|
||||
if( cls.state != ca_active || cls.spectator )
|
||||
return;
|
||||
|
@ -1284,6 +1284,11 @@ void CL_PredictMovement( qboolean repredicting )
|
|||
|
||||
if( to_cmd->senttime >= host.realtime )
|
||||
break;
|
||||
|
||||
// now interpolate some fraction of the final frame
|
||||
if( to_cmd->senttime != from_cmd->senttime )
|
||||
f = (host.realtime - from_cmd->senttime) / (to_cmd->senttime - from_cmd->senttime) * 0.1;
|
||||
|
||||
from = to;
|
||||
from_cmd = to_cmd;
|
||||
}
|
||||
|
@ -1316,18 +1321,8 @@ void CL_PredictMovement( qboolean repredicting )
|
|||
return;
|
||||
}
|
||||
|
||||
// now interpolate some fraction of the final frame
|
||||
if( to_cmd->senttime == from_cmd->senttime )
|
||||
{
|
||||
f = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = (host.realtime - from_cmd->senttime) / (to_cmd->senttime - from_cmd->senttime);
|
||||
f = bound( 0.0f, f, 1.0f );
|
||||
}
|
||||
|
||||
if( f != 1.0f && f != 0.0f ) Msg( "Predict interp: %g\n", f );
|
||||
f = bound( 0.0f, f, 1.0f );
|
||||
f = 0.0; // FIXME: make work, do revision
|
||||
|
||||
if( CL_PlayerTeleported( from, to ))
|
||||
{
|
||||
|
|
|
@ -2412,7 +2412,7 @@ void CL_SetLightstyle( int style, const char *s, float f )
|
|||
lightstyle_t *ls;
|
||||
float val1, val2;
|
||||
|
||||
Assert( s );
|
||||
Assert( s != NULL );
|
||||
Assert( style >= 0 && style < MAX_LIGHTSTYLES );
|
||||
|
||||
ls = &cl.lightstyles[style];
|
||||
|
|
|
@ -239,6 +239,9 @@ typedef struct
|
|||
int maxclients;
|
||||
int num_custombeams; // server beams count
|
||||
|
||||
entity_state_t instanced_baseline[MAX_CUSTOM_BASELINES];
|
||||
int instanced_baseline_count;
|
||||
|
||||
char model_precache[MAX_MODELS][MAX_QPATH];
|
||||
char sound_precache[MAX_SOUNDS][MAX_QPATH];
|
||||
char event_precache[MAX_EVENTS][MAX_QPATH];
|
||||
|
@ -247,7 +250,6 @@ typedef struct
|
|||
short sound_index[MAX_SOUNDS];
|
||||
short decal_index[MAX_DECALS];
|
||||
|
||||
cl_entity_t *world;
|
||||
model_t *worldmodel; // pointer to world
|
||||
} client_t;
|
||||
|
||||
|
@ -936,7 +938,7 @@ void Con_FastClose( void );
|
|||
// s_main.c
|
||||
//
|
||||
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop, long position );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop, long position, qboolean fullpath );
|
||||
void S_StopBackgroundTrack( void );
|
||||
void S_StreamSetPause( int pause );
|
||||
void S_StartStreaming( void );
|
||||
|
|
|
@ -1180,11 +1180,16 @@ void R_SetupAliasFrame( cl_entity_t *e, aliashdr_t *paliashdr )
|
|||
oldframe = e->latched.prevframe;
|
||||
newframe = e->curstate.frame;
|
||||
|
||||
if(( newframe >= paliashdr->numframes ) || ( newframe < 0 ))
|
||||
if( newframe < 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "R_SetupAliasFrame: no such frame %d\n", newframe );
|
||||
newframe = 0;
|
||||
}
|
||||
else if( newframe >= paliashdr->numframes )
|
||||
{
|
||||
if( newframe > paliashdr->numframes )
|
||||
MsgDev( D_WARN, "R_GetAliasFrame: no such frame %d (%s)\n", newframe, e->model->name );
|
||||
newframe = paliashdr->numframes - 1;
|
||||
}
|
||||
|
||||
if(( oldframe >= paliashdr->numframes ) || ( oldframe < 0 ))
|
||||
oldframe = newframe;
|
||||
|
|
|
@ -693,7 +693,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo )
|
|||
mplane_t *splitplane;
|
||||
float dist;
|
||||
|
||||
Assert( node );
|
||||
Assert( node != NULL );
|
||||
|
||||
if( node->contents < 0 )
|
||||
{
|
||||
|
|
|
@ -2037,7 +2037,8 @@ void GL_RebuildLightmaps( void )
|
|||
int i, j;
|
||||
model_t *m;
|
||||
|
||||
if( !cl.world ) return; // wait for worldmodel
|
||||
if( !cl.video_prepped )
|
||||
return; // wait for worldmodel
|
||||
|
||||
ClearBits( vid_brightness->flags, FCVAR_CHANGED );
|
||||
ClearBits( vid_gamma->flags, FCVAR_CHANGED );
|
||||
|
|
|
@ -477,7 +477,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
|
|||
int i, numframes;
|
||||
float targettime;
|
||||
|
||||
Assert( pModel );
|
||||
Assert( pModel != NULL );
|
||||
psprite = pModel->cache.data;
|
||||
|
||||
if( frame < 0 )
|
||||
|
@ -486,7 +486,8 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
|
|||
}
|
||||
else if( frame >= psprite->numframes )
|
||||
{
|
||||
MsgDev( D_WARN, "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name );
|
||||
if( frame > psprite->numframes )
|
||||
MsgDev( D_WARN, "R_GetSpriteFrame: no such frame %d (%s)\n", frame, pModel->name );
|
||||
frame = psprite->numframes - 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1400,7 +1400,7 @@ void R_StudioBuildNormalTable( void )
|
|||
mstudiomesh_t *pmesh;
|
||||
int i, j;
|
||||
|
||||
Assert( m_pSubModel );
|
||||
Assert( m_pSubModel != NULL );
|
||||
|
||||
// reset chrome cache
|
||||
for( i = 0; i < m_pStudioHeader->numbones; i++ )
|
||||
|
@ -1452,7 +1452,7 @@ void R_StudioGenerateNormals( void )
|
|||
mstudiomesh_t *pmesh;
|
||||
int i, j;
|
||||
|
||||
Assert( m_pSubModel );
|
||||
Assert( m_pSubModel != NULL );
|
||||
|
||||
for( i = 0; i < m_pSubModel->numverts; i++ )
|
||||
VectorClear( g_studio.norms[i] );
|
||||
|
@ -3583,6 +3583,8 @@ void R_DrawStudioModel( cl_entity_t *e )
|
|||
{
|
||||
RI.currententity = parent;
|
||||
R_StudioDrawModelInternal( RI.currententity, 0 );
|
||||
VectorCopy( parent->curstate.origin, e->curstate.origin );
|
||||
VectorCopy( parent->origin, e->origin );
|
||||
RI.currententity = e;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2084,13 +2084,13 @@ void S_Music_f( void )
|
|||
if( FS_FileExists( intro_path, false ) && FS_FileExists( main_path, false ))
|
||||
{
|
||||
// combined track with introduction and main loop theme
|
||||
S_StartBackgroundTrack( intro, main, 0 );
|
||||
S_StartBackgroundTrack( intro, main, 0, false );
|
||||
break;
|
||||
}
|
||||
else if( FS_FileExists( va( "media/%s.%s", track, ext[i] ), false ))
|
||||
{
|
||||
// single non-looped theme
|
||||
S_StartBackgroundTrack( track, NULL, 0 );
|
||||
S_StartBackgroundTrack( track, NULL, 0, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2098,12 +2098,12 @@ void S_Music_f( void )
|
|||
}
|
||||
else if( c == 3 )
|
||||
{
|
||||
S_StartBackgroundTrack( Cmd_Argv( 1 ), Cmd_Argv( 2 ), 0 );
|
||||
S_StartBackgroundTrack( Cmd_Argv( 1 ), Cmd_Argv( 2 ), 0, false );
|
||||
}
|
||||
else if( c == 4 && Q_atoi( Cmd_Argv( 3 )) != 0 )
|
||||
{
|
||||
// restore command for singleplayer: all arguments are valid
|
||||
S_StartBackgroundTrack( Cmd_Argv( 1 ), Cmd_Argv( 2 ), Q_atoi( Cmd_Argv( 3 )));
|
||||
S_StartBackgroundTrack( Cmd_Argv( 1 ), Cmd_Argv( 2 ), Q_atoi( Cmd_Argv( 3 )), false );
|
||||
}
|
||||
else Msg( "Usage: music <musicfile> [loopfile]\n" );
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ float S_GetMusicVolume( void )
|
|||
S_StartBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, long position )
|
||||
void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, long position, qboolean fullpath )
|
||||
{
|
||||
S_StopBackgroundTrack();
|
||||
|
||||
|
@ -89,7 +89,7 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, long
|
|||
|
||||
if( !mainTrack || !*mainTrack ) s_bgTrack.loopName[0] = '\0';
|
||||
else Q_strncpy( s_bgTrack.loopName, mainTrack, sizeof( s_bgTrack.loopName ));
|
||||
|
||||
if( fullpath ) Msg( "MP3:Playing: %s\n", introTrack );
|
||||
// open stream
|
||||
s_bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack ));
|
||||
Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current ));
|
||||
|
|
|
@ -457,7 +457,7 @@ void CEngineSurface :: popMakeCurrent( Panel *panel )
|
|||
Assert( top >= 0 );
|
||||
|
||||
// didn't pop in reverse order of push?
|
||||
Assert( paintStack[top]->m_pPanel == panel );
|
||||
Assert( paintStack[top].m_pPanel == panel );
|
||||
|
||||
staticPaintStackPos--;
|
||||
|
||||
|
|
|
@ -700,6 +700,9 @@ void Con_Printf( char *szFmt, ... )
|
|||
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
|
||||
va_end( args );
|
||||
|
||||
if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' )
|
||||
return; // hlrally spam
|
||||
|
||||
Sys_Print( buffer );
|
||||
}
|
||||
|
||||
|
@ -721,6 +724,9 @@ void Con_DPrintf( char *szFmt, ... )
|
|||
Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args );
|
||||
va_end( args );
|
||||
|
||||
if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' )
|
||||
return; // hlrally spam
|
||||
|
||||
Sys_Print( buffer );
|
||||
}
|
||||
|
||||
|
|
|
@ -655,7 +655,6 @@ void Host_EndGame( const char *message, ... );
|
|||
void Host_AbortCurrentFrame( void );
|
||||
void Host_RestartAmbientSounds( void );
|
||||
void Host_RestartDecals( void );
|
||||
qboolean CL_ChangeGame( const char *gamefolder, qboolean bReset );
|
||||
void Host_WriteServerConfig( const char *name );
|
||||
void Host_WriteOpenGLConfig( void );
|
||||
void Host_WriteVideoConfig( void );
|
||||
|
@ -747,6 +746,7 @@ void MD5Update( MD5Context_t *ctx, const byte *buf, uint len );
|
|||
void MD5Final( byte digest[16], MD5Context_t *ctx );
|
||||
qboolean MD5_HashFile( byte digest[16], const char *pszFileName, uint seed[4] );
|
||||
uint Com_HashKey( const char *string, uint hashSize );
|
||||
char *MD5_Print( byte hash[16] );
|
||||
|
||||
//
|
||||
// cfgscript.c
|
||||
|
|
|
@ -960,7 +960,6 @@ void Host_WriteServerConfig( const char *name )
|
|||
|
||||
// FIXME: move this out until menu parser is done
|
||||
CSCR_LoadDefaultCVars( "settings.scr" );
|
||||
CSCR_LoadDefaultCVars( "user.scr" );
|
||||
|
||||
if(( f = FS_Open( name, "w", false )) != NULL )
|
||||
{
|
||||
|
@ -969,7 +968,6 @@ void Host_WriteServerConfig( const char *name )
|
|||
FS_Printf( f, "//\t\tgame.cfg - multiplayer server temporare config\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
Cvar_WriteVariables( f, FCVAR_SERVER );
|
||||
CSCR_WriteGameCVars( f, "user.scr" );
|
||||
CSCR_WriteGameCVars( f, "settings.scr" );
|
||||
FS_Close( f );
|
||||
}
|
||||
|
|
|
@ -562,6 +562,30 @@ qboolean MD5_HashFile( byte digest[16], const char *pszFileName, uint seed[4] )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
MD5_Print
|
||||
|
||||
transform hash to hexadecimal printable symbols
|
||||
=================
|
||||
*/
|
||||
char *MD5_Print( byte hash[16] )
|
||||
{
|
||||
static char szReturn[64];
|
||||
byte szChunk[10];
|
||||
int i;
|
||||
|
||||
memset( szReturn, 0, 64 );
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
{
|
||||
Q_snprintf( szChunk, sizeof( szChunk ), "%02X", hash[i] );
|
||||
Q_strncat( szReturn, szChunk, sizeof( szReturn ));
|
||||
}
|
||||
|
||||
return szReturn;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Com_HashKey
|
||||
|
|
|
@ -517,6 +517,10 @@ void Key_Event( int key, qboolean down )
|
|||
const char *kb;
|
||||
char cmd[1024];
|
||||
|
||||
// key was pressed before engine was run
|
||||
if( !keys[key].down && !down )
|
||||
return;
|
||||
|
||||
// update auto-repeat status and BUTTON_ANY status
|
||||
keys[key].down = down;
|
||||
|
||||
|
|
|
@ -517,7 +517,8 @@ static void FreeNameFuncGlobals( dll_user_t *hInst )
|
|||
|
||||
char *GetMSVCName( const char *in_name )
|
||||
{
|
||||
char *pos, *out_name;
|
||||
static string out_name;
|
||||
char *pos;
|
||||
|
||||
if( in_name[0] == '?' ) // is this a MSVC C++ mangled name?
|
||||
{
|
||||
|
@ -526,12 +527,15 @@ char *GetMSVCName( const char *in_name )
|
|||
int len = pos - in_name;
|
||||
|
||||
// strip off the leading '?'
|
||||
out_name = copystring( in_name + 1 );
|
||||
Q_strncpy( out_name, in_name + 1, sizeof( out_name ));
|
||||
out_name[len-1] = 0; // terminate string at the "@@"
|
||||
return out_name;
|
||||
}
|
||||
}
|
||||
return copystring( in_name );
|
||||
|
||||
Q_strncpy( out_name, in_name, sizeof( out_name ));
|
||||
|
||||
return out_name;
|
||||
}
|
||||
|
||||
qboolean LibraryLoadSymbols( dll_user_t *hInst )
|
||||
|
@ -718,7 +722,7 @@ qboolean LibraryLoadSymbols( dll_user_t *hInst )
|
|||
if( FS_Seek( f, name_offset, SEEK_SET ) != -1 )
|
||||
{
|
||||
FsGetString( f, function_name );
|
||||
hInst->names[i] = GetMSVCName( function_name );
|
||||
hInst->names[i] = copystring( GetMSVCName( function_name ));
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
@ -819,7 +823,7 @@ void *Com_GetProcAddress( void *hInstance, const char *name )
|
|||
|
||||
if( hInst->custom_loader )
|
||||
return (void *)MemoryGetProcAddress( hInst->hInstance, name );
|
||||
return (void *)GetProcAddress( hInst->hInstance, name );
|
||||
return (void *)GetProcAddress( hInst->hInstance, GetMSVCName( name ));
|
||||
}
|
||||
|
||||
void Com_FreeLibrary( void *hInstance )
|
||||
|
|
|
@ -427,7 +427,9 @@ static void SV_StudioSetupBones( model_t *pModel, float frame, int sequence, con
|
|||
|
||||
if( sequence < 0 || sequence >= mod_studiohdr->numseq )
|
||||
{
|
||||
MsgDev( D_WARN, "SV_StudioSetupBones: sequence %i/%i out of range for model %s\n", sequence, mod_studiohdr->numseq, mod_studiohdr->name );
|
||||
// only show warn if sequence that out of range was specified intentionally
|
||||
if( sequence > mod_studiohdr->numseq )
|
||||
MsgDev( D_WARN, "SV_StudioSetupBones: sequence %i/%i out of range for model %s\n", sequence, mod_studiohdr->numseq, mod_studiohdr->name );
|
||||
sequence = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ GNU General Public License for more details.
|
|||
#define CMD_BACKUP 64 // allow a lot of command backups for very fast systems
|
||||
#define CMD_MASK (CMD_BACKUP - 1)
|
||||
#define NUM_PACKET_ENTITIES 256 // 170 Mb for multiplayer with 32 players
|
||||
#define MAX_CUSTOM_BASELINES 64
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
|
|
@ -35,7 +35,7 @@ GNU General Public License for more details.
|
|||
#define svc_updateuserinfo 13 // [byte] playernum, [string] userinfo
|
||||
#define svc_deltatable 14 // [table header][...]
|
||||
#define svc_clientdata 15 // [...]
|
||||
#define svc_stopsound 16 // <see code>
|
||||
#define svc_studiodecal 16 // [float*3][float*3][short][short][byte]
|
||||
#define svc_pings 17 // [bit][idx][ping][packet_loss]
|
||||
#define svc_particle 18 // [float*3][char*3][byte][byte]
|
||||
#define svc_restoresound 19 // <see code>
|
||||
|
@ -48,7 +48,7 @@ GNU General Public License for more details.
|
|||
#define svc_centerprint 26 // [string] to put in center of the screen
|
||||
#define svc_modelindex 27 // [index][modelpath]
|
||||
#define svc_soundindex 28 // [index][soundpath]
|
||||
#define svc_ambientsound 29 // <see code>
|
||||
#define svc_eventindex 29 // [index][eventname]
|
||||
#define svc_intermission 30 // empty message (event)
|
||||
#define svc_finale 31 // empty message (event)
|
||||
#define svc_cdtrack 32 // [string] trackname
|
||||
|
@ -71,9 +71,9 @@ GNU General Public License for more details.
|
|||
#define svc_filetxferfailed 49 // [string]
|
||||
#define svc_hltv 50 // sending from the game.dll
|
||||
#define svc_director 51 // <variable sized>
|
||||
#define svc_studiodecal 52 // [float*3][float*3][short][short][byte]
|
||||
#define svc_voiceinit 52 // <see code>
|
||||
#define svc_voicedata 53 // [byte][short][...]
|
||||
#define svc_eventindex 54 // [index][eventname]
|
||||
// reserved
|
||||
// reserved
|
||||
#define svc_resourcelocation 56 // [string]
|
||||
#define svc_querycvarvalue 57 // [string]
|
||||
|
|
|
@ -143,6 +143,33 @@ char *Sys_GetCurrentUser( void )
|
|||
return sys_user_name;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_GetMachineKey
|
||||
=================
|
||||
*/
|
||||
const char *Sys_GetMachineKey( int *nLength )
|
||||
{
|
||||
HINSTANCE rpcrt4_dll = LoadLibrary( "rpcrt4.dll" );
|
||||
RPC_STATUS (_stdcall *pUuidCreateSequential)( UUID __RPC_FAR *Uuid ) = NULL;
|
||||
static byte key[32];
|
||||
byte mac[8];
|
||||
UUID uuid;
|
||||
int i;
|
||||
|
||||
if( rpcrt4_dll ) pUuidCreateSequential = (void *)GetProcAddress( rpcrt4_dll, "UuidCreateSequential" );
|
||||
if( pUuidCreateSequential ) pUuidCreateSequential( &uuid ); // ask OS to create UUID
|
||||
if( rpcrt4_dll ) FreeLibrary( rpcrt4_dll ); // no need anymore...
|
||||
|
||||
for( i = 2; i < 8; i++ ) // bytes 2 through 7 inclusive are MAC address
|
||||
mac[i-2] = uuid.Data4[i];
|
||||
|
||||
Q_snprintf( key, sizeof( key ), "%02X-%02X-%02X-%02X-%02X-%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
|
||||
|
||||
if( nLength ) *nLength = Q_strlen( key );
|
||||
return key;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_ShellExecute
|
||||
|
@ -542,9 +569,6 @@ void Sys_Print( const char *pMsg )
|
|||
char *c = logbuf;
|
||||
int i = 0;
|
||||
|
||||
if( pMsg[0] == '0' && pMsg[1] == '\n' && pMsg[2] == '\0' )
|
||||
return; // hlrally spam
|
||||
|
||||
if( host.type == HOST_NORMAL )
|
||||
Con_Print( pMsg );
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ void Sys_SetClipboardData( const byte *buffer, size_t size );
|
|||
#define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out ))
|
||||
qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size );
|
||||
void Sys_ShellExecute( const char *path, const char *parms, qboolean exit );
|
||||
const char *Sys_GetMachineKey( int *nLength );
|
||||
void Sys_SendKeyEvents( void );
|
||||
void Sys_Print( const char *pMsg );
|
||||
void Sys_PrintLog( const char *pMsg );
|
||||
|
|
|
@ -143,6 +143,10 @@ SOURCE=.\common\build.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\cfgscript.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_cmds.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -85,8 +85,8 @@ typedef enum
|
|||
typedef struct
|
||||
{
|
||||
int count;
|
||||
string_t classnames[64];
|
||||
entity_state_t baselines[64];
|
||||
string_t classnames[MAX_CUSTOM_BASELINES];
|
||||
entity_state_t baselines[MAX_CUSTOM_BASELINES];
|
||||
} sv_baselines_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -96,6 +96,14 @@ typedef struct
|
|||
vec3_t mins, maxs;
|
||||
} sv_consistency_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qboolean active;
|
||||
qboolean net_log;
|
||||
netadr_t net_address;
|
||||
file_t *file;
|
||||
} server_log_t;
|
||||
|
||||
// like as entity_state_t in Quake
|
||||
typedef struct
|
||||
{
|
||||
|
@ -213,6 +221,8 @@ typedef struct sv_client_s
|
|||
double timebase; // client timebase
|
||||
double lastservertime; // check if server time was not changed so no resaon to send update
|
||||
|
||||
char hashedcdkey[34]; // MD5 hash is 32 hex #'s, plus trailing 0
|
||||
|
||||
customization_t customdata; // player customization linked list
|
||||
resource_t resourcesonhand;
|
||||
resource_t resourcesneeded; // <mapname.res> from client (server downloading)
|
||||
|
@ -362,6 +372,8 @@ typedef struct
|
|||
int groupmask;
|
||||
int groupop;
|
||||
|
||||
server_log_t log;
|
||||
|
||||
char serverinfo[MAX_SERVERINFO_STRING];
|
||||
char localinfo[MAX_LOCALINFO_STRING];
|
||||
|
||||
|
@ -389,6 +401,8 @@ extern areanode_t sv_areanodes[]; // AABB dynamic tree
|
|||
|
||||
extern convar_t sv_lan;
|
||||
extern convar_t sv_lan_rate;
|
||||
extern convar_t mp_logecho;
|
||||
extern convar_t mp_logfile;
|
||||
extern convar_t sv_unlag;
|
||||
extern convar_t sv_maxunlag;
|
||||
extern convar_t sv_unlagpush;
|
||||
|
@ -421,6 +435,7 @@ extern convar_t sv_skyangle;
|
|||
extern convar_t sv_consistency;
|
||||
extern convar_t sv_spawntime;
|
||||
extern convar_t sv_changetime;
|
||||
extern convar_t sv_password;
|
||||
extern convar_t deathmatch;
|
||||
extern convar_t skill;
|
||||
extern convar_t coop;
|
||||
|
@ -606,6 +621,14 @@ _inline edict_t *SV_EDICT_NUM( int n, const char * file, const int line )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// sv_log.c
|
||||
//
|
||||
void Log_Close( void );
|
||||
void Log_Open( void );
|
||||
void Log_PrintServerVars( void );
|
||||
void SV_ServerLog_f( void );
|
||||
|
||||
//
|
||||
// sv_save.c
|
||||
//
|
||||
|
|
|
@ -107,6 +107,84 @@ int SV_GetFragmentSize( sv_client_t *cl )
|
|||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_RejectConnection
|
||||
|
||||
Rejects connection request and sends back a message
|
||||
================
|
||||
*/
|
||||
void SV_RejectConnection( netadr_t from, char *fmt, ... )
|
||||
{
|
||||
char text[1024];
|
||||
va_list argptr;
|
||||
|
||||
va_start( argptr, fmt );
|
||||
Q_vsnprintf( text, sizeof( text ), fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
MsgDev( D_REPORT, "%s connection refused. Reason: %s\n", NET_AdrToString( from ), text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "print\n^1Server was reject the connection:^7 %s", text );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_CheckChallenge
|
||||
|
||||
Make sure connecting client is not spoofing
|
||||
================
|
||||
*/
|
||||
int SV_CheckChallenge( netadr_t from, int challenge )
|
||||
{
|
||||
int i;
|
||||
|
||||
// see if the challenge is valid
|
||||
// don't care if it is a local address.
|
||||
if( NET_IsLocalAddress( from ))
|
||||
return 1;
|
||||
|
||||
for( i = 0; i < MAX_CHALLENGES; i++ )
|
||||
{
|
||||
if( NET_CompareAdr( from, svs.challenges[i].adr ))
|
||||
{
|
||||
if( challenge == svs.challenges[i].challenge )
|
||||
break; // valid challenge
|
||||
#if 0
|
||||
// g-cont. this breaks multiple connections from single machine
|
||||
SV_RejectConnection( from, "bad challenge %i\n", challenge );
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if( i == MAX_CHALLENGES )
|
||||
{
|
||||
SV_RejectConnection( from, "no challenge for your address\n" );
|
||||
return 0;
|
||||
}
|
||||
svs.challenges[i].connected = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_CheckIPRestrictions
|
||||
|
||||
Determine if client is outside appropriate address range
|
||||
================
|
||||
*/
|
||||
int SV_CheckIPRestrictions( netadr_t from )
|
||||
{
|
||||
if( !sv_lan.value )
|
||||
{
|
||||
if( !NET_CompareClassBAdr( from, net_local ) && !NET_IsReservedAdr( from ))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_DirectConnect
|
||||
|
@ -118,26 +196,71 @@ void SV_DirectConnect( netadr_t from )
|
|||
{
|
||||
char userinfo[MAX_INFO_STRING];
|
||||
char physinfo[MAX_PHYSINFO_STRING];
|
||||
char protinfo[MAX_INFO_STRING];
|
||||
sv_client_t temp, *cl, *newcl;
|
||||
int qport, version;
|
||||
int i, edictnum;
|
||||
int count = 0;
|
||||
int challenge;
|
||||
edict_t *ent;
|
||||
char *s;
|
||||
|
||||
if( Cmd_Argc() < 5 )
|
||||
{
|
||||
SV_RejectConnection( from, "insufficient connection info\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
version = Q_atoi( Cmd_Argv( 1 ));
|
||||
|
||||
if( version != PROTOCOL_VERSION )
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i.\n", PROTOCOL_VERSION );
|
||||
MsgDev( D_ERROR, "SV_DirectConnect: rejected connect from version %i\n", version );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
SV_RejectConnection( from, "unsupported protocol (%i should be %i)\n", version, PROTOCOL_VERSION );
|
||||
return;
|
||||
}
|
||||
|
||||
qport = Q_atoi( Cmd_Argv( 2 ));
|
||||
challenge = Q_atoi( Cmd_Argv( 3 ));
|
||||
Q_strncpy( userinfo, Cmd_Argv( 4 ), sizeof( userinfo ));
|
||||
challenge = Q_atoi( Cmd_Argv( 2 )); // get challenge
|
||||
|
||||
// see if the challenge is valid (local clients don't need to challenge)
|
||||
if( !SV_CheckChallenge( from, challenge ))
|
||||
return;
|
||||
|
||||
s = Cmd_Argv( 3 ); // protocol info
|
||||
|
||||
if( !Info_IsValid( s ))
|
||||
{
|
||||
SV_RejectConnection( from, "invalid protinfo in connect command\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( protinfo, s, sizeof( protinfo ));
|
||||
|
||||
// extract qport from protocol info
|
||||
qport = Q_atoi( Info_ValueForKey( protinfo, "qport" ));
|
||||
|
||||
s = Info_ValueForKey( protinfo, "uuid" );
|
||||
if( Q_strlen( s ) != 32 )
|
||||
{
|
||||
SV_RejectConnection( from, "invalid authentication certificate length\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// LAN servers restrict to class b IP addresses
|
||||
if( !SV_CheckIPRestrictions( from ))
|
||||
{
|
||||
SV_RejectConnection( from, "LAN servers are restricted to local clients (class C)\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
s = Cmd_Argv( 4 ); // user info
|
||||
|
||||
if( Q_strlen( s ) > MAX_INFO_STRING || !Info_IsValid( s ))
|
||||
{
|
||||
SV_RejectConnection( from, "invalid userinfo in connect command\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( userinfo, s, sizeof( userinfo ));
|
||||
|
||||
// quick reject
|
||||
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
|
||||
|
@ -149,35 +272,18 @@ void SV_DirectConnect( netadr_t from )
|
|||
{
|
||||
if( !NET_IsLocalAddress( from ) && ( host.realtime - cl->connection_started ) < sv_reconnect_limit->value )
|
||||
{
|
||||
MsgDev( D_INFO, "%s:reconnect rejected : too soon\n", NET_AdrToString( from ));
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
SV_RejectConnection( from, "too soon\n" );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// see if the challenge is valid (LAN clients don't need to challenge)
|
||||
if( !NET_IsLocalAddress( from ))
|
||||
|
||||
// check connection password (don't verify local client)
|
||||
if( !NET_IsLocalAddress( from ) && sv_password.string[0] && Q_stricmp( sv_password.string, Info_ValueForKey( userinfo, "password" )))
|
||||
{
|
||||
for( i = 0; i < MAX_CHALLENGES; i++ )
|
||||
{
|
||||
if( NET_CompareAdr( from, svs.challenges[i].adr ))
|
||||
{
|
||||
if( challenge == svs.challenges[i].challenge )
|
||||
break; // valid challenge
|
||||
}
|
||||
}
|
||||
|
||||
if( i == MAX_CHALLENGES )
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for address.\n" );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "Client %i connecting with challenge %p\n", i, challenge );
|
||||
svs.challenges[i].connected = true;
|
||||
SV_RejectConnection( from, "invalid password\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// force the IP key/value pair so the game can filter based on ip
|
||||
|
@ -214,9 +320,7 @@ void SV_DirectConnect( netadr_t from )
|
|||
|
||||
if( !newcl )
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "print\nServer is full.\n" );
|
||||
MsgDev( D_INFO, "SV_DirectConnect: rejected a connection.\n" );
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
SV_RejectConnection( from, "server is full\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,15 +356,14 @@ gotnewcl:
|
|||
if( !( SV_ClientConnect( ent, userinfo )))
|
||||
{
|
||||
if( *Info_ValueForKey( userinfo, "rejmsg" ))
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "print\n%s\nConnection refused.\n", Info_ValueForKey( userinfo, "rejmsg" ));
|
||||
else Netchan_OutOfBandPrint( NS_SERVER, from, "print\nConnection refused.\n" );
|
||||
|
||||
MsgDev( D_ERROR, "SV_DirectConnect: game rejected a connection.\n");
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "disconnect\n" );
|
||||
SV_RejectConnection( from, "%s\n", Info_ValueForKey( userinfo, "rejmsg" ));
|
||||
else SV_RejectConnection( from, "game rejected a connection\n" );
|
||||
SV_DropClient( newcl );
|
||||
return;
|
||||
}
|
||||
|
||||
// after this point connection is accepted
|
||||
|
||||
// send the connect packet to the client
|
||||
Netchan_OutOfBandPrint( NS_SERVER, from, "client_connect" );
|
||||
|
||||
|
@ -270,6 +373,9 @@ gotnewcl:
|
|||
newcl->cl_updaterate = 0.05; // 20 fps as default
|
||||
newcl->delta_sequence = -1;
|
||||
|
||||
Q_strncpy( newcl->hashedcdkey, Info_ValueForKey( protinfo, "uuid" ), 32 );
|
||||
newcl->hashedcdkey[32] = '\0';
|
||||
|
||||
// parse some info from the info strings (this can override cl_updaterate)
|
||||
Q_strncpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ));
|
||||
SV_UserinfoChanged( newcl, newcl->userinfo );
|
||||
|
@ -282,6 +388,8 @@ gotnewcl:
|
|||
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
|
||||
if( cl->state >= cs_connected ) count++;
|
||||
|
||||
Log_Printf( "\"%s<%i><%i><>\" connected, address \"%s\"\n", newcl->name, newcl->userid, i, NET_AdrToString( newcl->netchan.remote_address ));
|
||||
|
||||
if( count == 1 || count == svs.maxclients )
|
||||
svs.last_heartbeat = MAX_HEARTBEAT;
|
||||
}
|
||||
|
@ -769,6 +877,7 @@ void SV_RemoteCommand( netadr_t from, sizebuf_t *msg )
|
|||
int i;
|
||||
|
||||
MsgDev( D_INFO, "Rcon from %s:\n%s\n", NET_AdrToString( from ), MSG_GetData( msg ) + 4 );
|
||||
Log_Printf( "Rcon: \"%s\" from \"%s\"\n", MSG_GetData( msg ) + 4, NET_AdrToString( from ));
|
||||
SV_BeginRedirect( from, RD_PACKET, outputbuf, sizeof( outputbuf ) - 16, SV_FlushRedirect );
|
||||
|
||||
if( Rcon_Validate( ))
|
||||
|
@ -931,8 +1040,10 @@ Writes all update values to a bitbuf
|
|||
*/
|
||||
void SV_FullClientUpdate( sv_client_t *cl, sizebuf_t *msg )
|
||||
{
|
||||
char info[MAX_INFO_STRING];
|
||||
int i;
|
||||
char info[MAX_INFO_STRING];
|
||||
char digest[16];
|
||||
MD5Context_t ctx;
|
||||
int i;
|
||||
|
||||
// process userinfo before updating
|
||||
SV_UserinfoChanged( cl, cl->userinfo );
|
||||
|
@ -952,6 +1063,12 @@ void SV_FullClientUpdate( sv_client_t *cl, sizebuf_t *msg )
|
|||
// remove server passwords, etc.
|
||||
Info_RemovePrefixedKeys( info, '_' );
|
||||
MSG_WriteString( msg, info );
|
||||
|
||||
MD5Init( &ctx );
|
||||
MD5Update( &ctx, cl->hashedcdkey, sizeof( cl->hashedcdkey ));
|
||||
MD5Final( digest, &ctx );
|
||||
|
||||
MSG_WriteBytes( msg, digest, sizeof( digest ));
|
||||
}
|
||||
else MSG_WriteOneBit( msg, 0 );
|
||||
}
|
||||
|
@ -1109,6 +1226,28 @@ void SV_PutClientInServer( sv_client_t *cl )
|
|||
ent->v.fixangle = 0;
|
||||
}
|
||||
|
||||
if( svgame.dllFuncs.pfnParmsChangeLevel )
|
||||
{
|
||||
SAVERESTOREDATA levelData;
|
||||
string name;
|
||||
int i;
|
||||
|
||||
memset( &levelData, 0, sizeof( levelData ));
|
||||
svgame.globals->pSaveData = &levelData;
|
||||
svgame.dllFuncs.pfnParmsChangeLevel();
|
||||
|
||||
MSG_WriteByte( &cl->netchan.message, svc_restore );
|
||||
Q_snprintf( name, sizeof( name ), "save/%s.HL2", sv.name );
|
||||
COM_FixSlashes( name );
|
||||
MSG_WriteString( &cl->netchan.message, name );
|
||||
MSG_WriteByte( &cl->netchan.message, levelData.connectionCount );
|
||||
|
||||
for( i = 0; i < levelData.connectionCount; i++ )
|
||||
MSG_WriteString( &cl->netchan.message, levelData.levelList[i].mapName );
|
||||
|
||||
svgame.globals->pSaveData = NULL;
|
||||
}
|
||||
|
||||
// reset weaponanim
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_weaponanim );
|
||||
MSG_WriteByte( &cl->netchan.message, 0 );
|
||||
|
@ -2479,7 +2618,7 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
|
|||
SV_ParseCvarValue2( cl, msg );
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "SV_ReadClientMessage: clc_bad\n" );
|
||||
MsgDev( D_ERROR, "clc_bad\n" );
|
||||
SV_DropClient( cl );
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -344,28 +344,6 @@ void SV_HazardCourse_f( void )
|
|||
else Host_NewGame( GI->trainmap, false );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SV_EndGame_f
|
||||
|
||||
==============
|
||||
*/
|
||||
void SV_EndGame_f( void )
|
||||
{
|
||||
Host_EndGame( Cmd_Argv( 1 ));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SV_KillGame_f
|
||||
|
||||
==============
|
||||
*/
|
||||
void SV_KillGame_f( void )
|
||||
{
|
||||
Host_EndGame( "The End" );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SV_Load_f
|
||||
|
@ -630,6 +608,7 @@ void SV_Kick_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
Log_Printf( "Kick: \"%s<%i>\" was kicked\n", svs.currentPlayer->name, svs.currentPlayer->userid );
|
||||
SV_BroadcastPrintf( svs.currentPlayer, PRINT_HIGH, "%s was kicked\n", svs.currentPlayer->name );
|
||||
SV_ClientPrintf( svs.currentPlayer, PRINT_HIGH, "You were kicked from the game\n" );
|
||||
SV_DropClient( svs.currentPlayer );
|
||||
|
@ -753,7 +732,7 @@ void SV_ConSay_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( text, "console: ", MAX_SYSPATH );
|
||||
Q_snprintf( text, sizeof( text ), "%s: ", Cvar_VariableString( "hostname" ));
|
||||
p = Cmd_Args();
|
||||
|
||||
if( *p == '"' )
|
||||
|
@ -771,6 +750,7 @@ void SV_ConSay_f( void )
|
|||
|
||||
SV_ClientPrintf( client, PRINT_CHAT, "%s\n", text );
|
||||
}
|
||||
Log_Printf( "Server say: \"%s\"\n", p );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1023,11 +1003,10 @@ void SV_InitOperatorCommands( void )
|
|||
Cmd_AddCommand( "entpatch", SV_EntPatch_f, "write entity patch to allow external editing" );
|
||||
Cmd_AddCommand( "edict_usage", SV_EdictUsage_f, "show info about edicts usage" );
|
||||
Cmd_AddCommand( "entity_info", SV_EntityInfo_f, "show more info about edicts" );
|
||||
Cmd_AddCommand( "log", SV_ServerLog_f, "logging server events" );
|
||||
|
||||
if( host.type == HOST_NORMAL )
|
||||
{
|
||||
Cmd_AddCommand( "endgame", SV_EndGame_f, "end current game" );
|
||||
Cmd_AddCommand( "killgame", SV_KillGame_f, "end current game" );
|
||||
Cmd_AddCommand( "save", SV_Save_f, "save the game to a file" );
|
||||
Cmd_AddCommand( "savequick", SV_QuickSave_f, "save the game to the quicksave" );
|
||||
Cmd_AddCommand( "autosave", SV_AutoSave_f, "save the game to 'autosave' file" );
|
||||
|
@ -1046,6 +1025,9 @@ SV_KillOperatorCommands
|
|||
*/
|
||||
void SV_KillOperatorCommands( void )
|
||||
{
|
||||
Cvar_Reset( "public" );
|
||||
Cvar_Reset( "sv_lan" );
|
||||
|
||||
Cmd_RemoveCommand( "heartbeat" );
|
||||
Cmd_RemoveCommand( "kick" );
|
||||
Cmd_RemoveCommand( "kill" );
|
||||
|
@ -1059,11 +1041,10 @@ void SV_KillOperatorCommands( void )
|
|||
Cmd_RemoveCommand( "entpatch" );
|
||||
Cmd_RemoveCommand( "edict_usage" );
|
||||
Cmd_RemoveCommand( "entity_info" );
|
||||
Cmd_RemoveCommand( "log" );
|
||||
|
||||
if( host.type == HOST_NORMAL )
|
||||
{
|
||||
Cmd_RemoveCommand( "endgame" );
|
||||
Cmd_RemoveCommand( "killgame" );
|
||||
Cmd_RemoveCommand( "save" );
|
||||
Cmd_RemoveCommand( "savequick" );
|
||||
Cmd_RemoveCommand( "killsave" );
|
||||
|
|
|
@ -75,6 +75,8 @@ TYPEDESCRIPTION *SV_GetEntvarsDescirption( int number )
|
|||
|
||||
void SV_SysError( const char *error_string )
|
||||
{
|
||||
Log_Printf( "FATAL ERROR (shutting down): %s\n", error_string );
|
||||
|
||||
if( svgame.hInstance != NULL )
|
||||
svgame.dllFuncs.pfnSys_Error( error_string );
|
||||
}
|
||||
|
@ -1102,7 +1104,8 @@ void pfnSetModel( edict_t *e, const char *m )
|
|||
|
||||
if( e == svgame.edicts )
|
||||
{
|
||||
MsgDev( D_ERROR, "SV_SetModel: world model can't be changed\n" );
|
||||
if( sv.state == ss_active )
|
||||
MsgDev( D_ERROR, "SV_SetModel: world model can't be changed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2036,7 +2039,7 @@ void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *sample, float vo
|
|||
// not sending (because this is out of range)
|
||||
flags &= ~SND_SPAWNING;
|
||||
|
||||
MSG_BeginServerCmd( &sv.multicast, svc_ambientsound );
|
||||
MSG_BeginServerCmd( &sv.multicast, svc_sound );
|
||||
MSG_WriteUBitLong( &sv.multicast, flags, MAX_SND_FLAGS_BITS );
|
||||
MSG_WriteUBitLong( &sv.multicast, sound_idx, MAX_SOUND_BITS );
|
||||
MSG_WriteUBitLong( &sv.multicast, CHAN_STATIC, MAX_SND_CHAN_BITS );
|
||||
|
@ -2838,6 +2841,10 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... )
|
|||
if( host.developer < D_ERROR )
|
||||
return;
|
||||
break;
|
||||
case at_logged:
|
||||
if( svs.maxclients <= 1 )
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
va_start( args, szFmt );
|
||||
|
@ -2848,10 +2855,14 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... )
|
|||
{
|
||||
Sys_Print( va( "^3Warning:^7 %s", buffer ));
|
||||
}
|
||||
else if( level == at_error )
|
||||
else if( level == at_error )
|
||||
{
|
||||
Sys_Print( va( "^1Error:^7 %s", buffer ));
|
||||
}
|
||||
else if( level == at_logged )
|
||||
{
|
||||
Log_Printf( "%s", buffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Print( buffer );
|
||||
|
@ -3254,21 +3265,18 @@ void pfnClientPrintf( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg )
|
|||
return;
|
||||
}
|
||||
|
||||
if( FBitSet( client->flags, FCL_FAKECLIENT ))
|
||||
return;
|
||||
|
||||
switch( ptype )
|
||||
{
|
||||
case print_console:
|
||||
if( FBitSet( client->flags, FCL_FAKECLIENT ))
|
||||
MsgDev( D_INFO, "%s", szMsg );
|
||||
else SV_ClientPrintf( client, PRINT_HIGH, "%s", szMsg );
|
||||
SV_ClientPrintf( client, PRINT_HIGH, "%s", szMsg );
|
||||
break;
|
||||
case print_chat:
|
||||
if( FBitSet( client->flags, FCL_FAKECLIENT ))
|
||||
return;
|
||||
SV_ClientPrintf( client, PRINT_CHAT, "%s", szMsg );
|
||||
break;
|
||||
case print_center:
|
||||
if( FBitSet( client->flags, FCL_FAKECLIENT ))
|
||||
return;
|
||||
MSG_BeginServerCmd( &client->netchan.message, svc_centerprint );
|
||||
MSG_WriteString( &client->netchan.message, szMsg );
|
||||
break;
|
||||
|
@ -4125,19 +4133,15 @@ pfnCreateInstancedBaseline
|
|||
*/
|
||||
int pfnCreateInstancedBaseline( int classname, struct entity_state_s *baseline )
|
||||
{
|
||||
int i;
|
||||
if( !baseline || sv.instanced.count >= MAX_CUSTOM_BASELINES )
|
||||
return 0;
|
||||
|
||||
if( !baseline ) return -1;
|
||||
|
||||
i = sv.instanced.count;
|
||||
if( i > 64 ) return 0;
|
||||
|
||||
Msg( "Added instanced baseline: %s [%i]\n", STRING( classname ), i );
|
||||
sv.instanced.classnames[i] = classname;
|
||||
sv.instanced.baselines[i] = *baseline;
|
||||
Msg( "Added instanced baseline: %s [%i]\n", STRING( classname ), sv.instanced.count );
|
||||
sv.instanced.classnames[sv.instanced.count] = classname;
|
||||
sv.instanced.baselines[sv.instanced.count] = *baseline;
|
||||
sv.instanced.count++;
|
||||
|
||||
return i+1;
|
||||
return sv.instanced.count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -363,6 +363,8 @@ void SV_ActivateServer( void )
|
|||
MsgDev( D_INFO, "Game started\n" );
|
||||
}
|
||||
|
||||
Log_Printf( "Started map \"%s\" (CRC \"%i\")\n", sv.name, world.checksum );
|
||||
|
||||
// dedicated server purge unused resources here
|
||||
if( host.type == HOST_DEDICATED )
|
||||
Mod_FreeUnused ();
|
||||
|
@ -503,6 +505,10 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot )
|
|||
if( !svs.initialized )
|
||||
return false;
|
||||
|
||||
Log_Open();
|
||||
Log_Printf( "Loading map \"%s\"\n", mapname );
|
||||
Log_PrintServerVars();
|
||||
|
||||
svgame.globals->changelevel = false; // will be restored later if needed
|
||||
svs.timestart = Sys_DoubleTime();
|
||||
svs.spawncount++; // any partially connected client will be restarted
|
||||
|
|
|
@ -16,6 +16,77 @@ GNU General Public License for more details.
|
|||
#include "common.h"
|
||||
#include "server.h"
|
||||
|
||||
void Log_Open( void )
|
||||
{
|
||||
time_t ltime;
|
||||
struct tm *today;
|
||||
char szFileBase[ MAX_OSPATH ];
|
||||
char szTestFile[ MAX_OSPATH ];
|
||||
file_t *fp = NULL;
|
||||
char *temp;
|
||||
int i;
|
||||
|
||||
if( !svs.log.active )
|
||||
return;
|
||||
|
||||
if( !mp_logfile.value )
|
||||
{
|
||||
Msg( "Server logging data to console.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Log_Close();
|
||||
|
||||
// Find a new log file slot
|
||||
time( <ime );
|
||||
today = localtime( <ime );
|
||||
temp = Cvar_VariableString( "logsdir" );
|
||||
|
||||
if( temp && Q_strlen( temp ) > 0 && !Q_strstr( temp, ":" ) && !Q_strstr( temp, ".." ))
|
||||
Q_snprintf( szFileBase, sizeof( szFileBase ), "%s/L%02i%02i", temp, today->tm_mon + 1, today->tm_mday );
|
||||
else Q_snprintf( szFileBase, sizeof( szFileBase ), "logs/L%02i%02i", today->tm_mon + 1, today->tm_mday );
|
||||
|
||||
for ( i = 0; i < 1000; i++ )
|
||||
{
|
||||
Q_snprintf( szTestFile, sizeof( szTestFile ), "%s%03i.log", szFileBase, i );
|
||||
|
||||
if( FS_FileExists( szTestFile, false ))
|
||||
continue;
|
||||
|
||||
fp = FS_Open( szTestFile, "w", true );
|
||||
if( fp )
|
||||
{
|
||||
Msg( "Server logging data to file %s\n", szTestFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 1000;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == 1000 )
|
||||
{
|
||||
Msg( "Unable to open logfiles under %s\nLogging disabled\n", szFileBase );
|
||||
svs.log.active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if( fp ) svs.log.file = fp;
|
||||
Log_Printf( "Log file started (file \"%s\") (game \"%s\") (version \"%i/%.2f/%d\")\n",
|
||||
szTestFile, Info_ValueForKey( SV_Serverinfo(), "*gamedir" ), PROTOCOL_VERSION, XASH_VERSION, Q_buildnum() );
|
||||
}
|
||||
|
||||
void Log_Close( void )
|
||||
{
|
||||
if( svs.log.file )
|
||||
{
|
||||
Log_Printf( "Log file closed\n" );
|
||||
FS_Close( svs.log.file );
|
||||
}
|
||||
svs.log.file = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Log_Printf
|
||||
|
@ -25,5 +96,93 @@ Prints a frag log message to the server's frag log file, console, and possible a
|
|||
*/
|
||||
void Log_Printf( const char *fmt, ... )
|
||||
{
|
||||
// TODO: implement
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
char *p;
|
||||
time_t ltime;
|
||||
struct tm *today;
|
||||
|
||||
if( !svs.log.active )
|
||||
return;
|
||||
|
||||
time( <ime );
|
||||
today = localtime( <ime );
|
||||
|
||||
Q_snprintf( string, sizeof( string ), "%02i/%02i/%04i - %02i:%02i:%02i: ",
|
||||
today->tm_mon+1, today->tm_mday, 1900 + today->tm_year, today->tm_hour, today->tm_min, today->tm_sec );
|
||||
|
||||
p = string + Q_strlen( string );
|
||||
|
||||
va_start( argptr, fmt );
|
||||
Q_vsnprintf( p, sizeof( string ) - Q_strlen( string ), fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
if( svs.log.net_log )
|
||||
Netchan_OutOfBandPrint( NS_SERVER, svs.log.net_address, "log %s", string );
|
||||
|
||||
if( svs.log.active && svs.maxclients > 1 )
|
||||
{
|
||||
// echo to server console
|
||||
if( mp_logecho.value )
|
||||
Msg( "%s", string );
|
||||
|
||||
// echo to log file
|
||||
if( svs.log.file && mp_logfile.value )
|
||||
FS_Printf( svs.log.file, "%s", string );
|
||||
}
|
||||
}
|
||||
|
||||
static void Log_PrintServerCvar( const char *var_name, const char *var_value, const char *unused2, void *unused3 )
|
||||
{
|
||||
Log_Printf( "Server cvar \"%s\" = \"%s\"\n", var_name, var_value );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Log_PrintServerVars
|
||||
|
||||
==================
|
||||
*/
|
||||
void Log_PrintServerVars( void )
|
||||
{
|
||||
if( !svs.log.active )
|
||||
return;
|
||||
|
||||
Log_Printf( "Server cvars start\n" );
|
||||
Cvar_LookupVars( FCVAR_SERVER, NULL, NULL, Log_PrintServerCvar );
|
||||
Log_Printf( "Server cvars end\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
SV_ServerLog_f
|
||||
|
||||
====================
|
||||
*/
|
||||
void SV_ServerLog_f( void )
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "usage: log < on|off >\n" );
|
||||
|
||||
if( svs.log.active )
|
||||
Msg( "currently logging\n" );
|
||||
else Msg( "not currently logging\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( Cmd_Argv( 1 ), "off" ))
|
||||
{
|
||||
if( svs.log.active )
|
||||
Log_Close();
|
||||
}
|
||||
else if( !Q_stricmp( Cmd_Argv( 1 ), "on" ))
|
||||
{
|
||||
svs.log.active = true;
|
||||
Log_Open();
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "log: unknown parameter %s\n", Cmd_Argv( 1 ));
|
||||
}
|
||||
}
|
|
@ -50,6 +50,8 @@ CVAR_DEFINE_AUTO( sv_allow_upload, "1", FCVAR_SERVER, "allow uploading custom re
|
|||
CVAR_DEFINE_AUTO( sv_allow_download, "1", FCVAR_SERVER, "allow downloading custom resources to the client" );
|
||||
CVAR_DEFINE_AUTO( sv_downloadurl, "", FCVAR_PROTECTED, "location from which clients can download missing files" );
|
||||
CVAR_DEFINE( sv_consistency, "mp_consistency", "1", FCVAR_SERVER, "enbale consistency check in multiplayer" );
|
||||
CVAR_DEFINE_AUTO( mp_logecho, "1", 0, "log multiplayer frags to server logfile" );
|
||||
CVAR_DEFINE_AUTO( mp_logfile, "1", 0, "log multiplayer frags to console" );
|
||||
|
||||
// game-related cvars
|
||||
CVAR_DEFINE_AUTO( mapcyclefile, "mapcycle.txt", 0, "name of multiplayer map cycle configuration file" );
|
||||
|
@ -707,13 +709,14 @@ void SV_Init( void )
|
|||
Cvar_Get ("protocol", va( "%i", PROTOCOL_VERSION ), FCVAR_READ_ONLY, "displays server protocol version" );
|
||||
Cvar_Get ("suitvolume", "0.25", FCVAR_ARCHIVE, "HEV suit volume" );
|
||||
Cvar_Get ("sv_background", "0", FCVAR_READ_ONLY, "indicate what background map is running" );
|
||||
Cvar_Get( "gamedir", GI->gamefolder, FCVAR_SERVER|FCVAR_READ_ONLY, "game folder" );
|
||||
Cvar_Get( "gamedir", GI->gamefolder, FCVAR_SERVER, "game folder" );
|
||||
Cvar_Get( "sv_alltalk", "1", 0, "allow to talking for all players (legacy, unused)" );
|
||||
Cvar_Get( "sv_allow_PhysX", "1", FCVAR_ARCHIVE, "allow XashXT to usage PhysX engine" ); // XashXT cvar
|
||||
Cvar_Get( "sv_precache_meshes", "1", FCVAR_ARCHIVE, "cache SOLID_CUSTOM meshes before level loading" ); // Paranoia 2 cvar
|
||||
Cvar_Get ("mapcyclefile", "mapcycle.txt", 0, "name of config file for map changing rules" );
|
||||
Cvar_Get ("servercfgfile","server.cfg", 0, "name of dedicated server configuration file" );
|
||||
Cvar_Get ("lservercfgfile","listenserver.cfg", 0, "name of listen server configuration file" );
|
||||
Cvar_Get ("logsdir","logs", 0, "default folder to write server logs" );
|
||||
|
||||
Cvar_RegisterVariable (&sv_zmax);
|
||||
Cvar_RegisterVariable (&sv_wateramp);
|
||||
|
@ -781,10 +784,12 @@ void SV_Init( void )
|
|||
Cvar_RegisterVariable (&sv_send_logos);
|
||||
Cvar_RegisterVariable (&sv_send_resources);
|
||||
Cvar_RegisterVariable (&sv_version);
|
||||
sv_sendvelocity = Cvar_Get( "sv_sendvelocity", "1", FCVAR_ARCHIVE, "force to send velocity for event_t structure across network" );
|
||||
sv_sendvelocity = Cvar_Get( "sv_sendvelocity", "0", FCVAR_ARCHIVE, "force to send velocity for event_t structure across network" );
|
||||
Cvar_RegisterVariable (&sv_consistency);
|
||||
sv_novis = Cvar_Get( "sv_novis", "0", 0, "force to ignore server visibility" );
|
||||
sv_hostmap = Cvar_Get( "hostmap", GI->startmap, 0, "keep name of last entered map" );
|
||||
Cvar_RegisterVariable (&sv_password);
|
||||
Cvar_RegisterVariable (&sv_lan);
|
||||
|
||||
Cvar_RegisterVariable (&sv_spawntime);
|
||||
Cvar_RegisterVariable (&sv_changetime);
|
||||
|
@ -793,6 +798,8 @@ void SV_Init( void )
|
|||
Cvar_RegisterVariable (&violence_hblood);
|
||||
Cvar_RegisterVariable (&violence_agibs);
|
||||
Cvar_RegisterVariable (&violence_hgibs);
|
||||
Cvar_RegisterVariable (&mp_logecho);
|
||||
Cvar_RegisterVariable (&mp_logfile);
|
||||
|
||||
// when we in developer-mode automatically turn cheats on
|
||||
if( host.developer > 1 ) Cvar_SetValue( "sv_cheats", 1.0f );
|
||||
|
@ -882,6 +889,9 @@ void SV_Shutdown( qboolean reconnect )
|
|||
memset( &sv, 0, sizeof( sv ));
|
||||
Host_SetServerState( sv.state );
|
||||
|
||||
Log_Printf( "Server shutdown\n" );
|
||||
Log_Close();
|
||||
|
||||
// free server static data
|
||||
if( svs.clients )
|
||||
{
|
||||
|
|
|
@ -374,19 +374,19 @@ SV_RecursiveWaterLevel
|
|||
recursively recalculating the middle
|
||||
=============
|
||||
*/
|
||||
float SV_RecursiveWaterLevel( vec3_t origin, float mins, float maxs, int depth )
|
||||
float SV_RecursiveWaterLevel( vec3_t origin, float out, float in, int count )
|
||||
{
|
||||
vec3_t point;
|
||||
float waterlevel;
|
||||
float offset;
|
||||
|
||||
waterlevel = ((mins - maxs) * 0.5f) + maxs;
|
||||
if( ++depth > 5 ) return waterlevel;
|
||||
offset = ((out - in) * 0.5) + in;
|
||||
if( ++count > 5 ) return offset;
|
||||
|
||||
VectorSet( point, origin[0], origin[1], origin[2] + waterlevel );
|
||||
VectorSet( point, origin[0], origin[1], origin[2] + offset );
|
||||
|
||||
if( SV_PointContents( point ) == CONTENTS_WATER )
|
||||
return SV_RecursiveWaterLevel( origin, mins, waterlevel, depth );
|
||||
return SV_RecursiveWaterLevel( origin, waterlevel, maxs, depth );
|
||||
return SV_RecursiveWaterLevel( origin, out, offset, count );
|
||||
return SV_RecursiveWaterLevel( origin, offset, in, count );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,31 +398,29 @@ determine how deep the entity is
|
|||
*/
|
||||
float SV_Submerged( edict_t *ent )
|
||||
{
|
||||
float start, bottom;
|
||||
vec3_t point;
|
||||
vec3_t halfmax;
|
||||
float waterlevel;
|
||||
vec3_t center;
|
||||
|
||||
VectorAverage( ent->v.absmin, ent->v.absmax, halfmax );
|
||||
waterlevel = ent->v.absmin[2] - halfmax[2];
|
||||
VectorAverage( ent->v.absmin, ent->v.absmax, center );
|
||||
start = ent->v.absmin[2] - center[2];
|
||||
|
||||
switch( ent->v.waterlevel )
|
||||
{
|
||||
case 1:
|
||||
return SV_RecursiveWaterLevel( halfmax, 0.0f, waterlevel, 0 ) - waterlevel;
|
||||
bottom = SV_RecursiveWaterLevel( center, 0.0f, start, 0 );
|
||||
return bottom - start;
|
||||
case 3:
|
||||
VectorSet( point, halfmax[0], halfmax[1], ent->v.absmax[2] );
|
||||
VectorSet( point, center[0], center[1], ent->v.absmax[2] );
|
||||
svs.groupmask = ent->v.groupinfo;
|
||||
|
||||
if( SV_PointContents( point ) == CONTENTS_WATER )
|
||||
{
|
||||
return (ent->v.maxs[2] - ent->v.mins[2]);
|
||||
}
|
||||
// intentionally fallthrough
|
||||
case 2:
|
||||
return SV_RecursiveWaterLevel( halfmax, ent->v.absmax[2] - halfmax[2], 0.0f, 0 ) - waterlevel;
|
||||
default:
|
||||
return 0.0f;
|
||||
case 2: // intentionally fallthrough
|
||||
bottom = SV_RecursiveWaterLevel( center, ent->v.absmax[2] - center[2], 0.0f, 0 );
|
||||
return bottom - start;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -452,7 +452,7 @@ void ReapplyDecal( SAVERESTOREDATA *pSaveData, decallist_t *entry, qboolean adja
|
|||
// NOTE: at this point all decal indexes is valid
|
||||
decalIndex = pfnDecalIndex( entry->name );
|
||||
|
||||
if( flags & FDECAL_STUDIO )
|
||||
if( FBitSet( flags, FDECAL_STUDIO ))
|
||||
{
|
||||
// NOTE: studio decal trace start saved into impactPlaneNormal
|
||||
SV_CreateStudioDecal( &sv.signon, entry->position, entry->impactPlaneNormal, decalIndex, entityIndex, modelIndex, flags, &entry->studio_state );
|
||||
|
@ -748,6 +748,8 @@ void SV_SaveFinish( SAVERESTOREDATA *pSaveData )
|
|||
char **pTokens;
|
||||
ENTITYTABLE *pEntityTable;
|
||||
|
||||
if( !pSaveData ) return;
|
||||
|
||||
pTokens = SaveRestore_DetachSymbolTable( pSaveData );
|
||||
if( pTokens ) Mem_Free( pTokens );
|
||||
|
||||
|
@ -1448,6 +1450,9 @@ SAVERESTOREDATA *SV_SaveGameState( void )
|
|||
int i, numents;
|
||||
int id, version;
|
||||
|
||||
if( !svgame.dllFuncs.pfnParmsChangeLevel )
|
||||
return NULL;
|
||||
|
||||
pSaveData = SV_SaveInit( 0 );
|
||||
|
||||
// Save the data
|
||||
|
|
|
@ -1255,6 +1255,7 @@ void UI_AddServerToList( netadr_t adr, const char *info )
|
|||
if( uiStatic.numServers == UI_MAX_SERVERS )
|
||||
return; // full
|
||||
|
||||
// ignore games from difference game folder
|
||||
if( stricmp( gMenu.m_gameinfo.gamefolder, Info_ValueForKey( info, "gamedir" )))
|
||||
return;
|
||||
|
||||
|
|
|
@ -35,14 +35,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define ID_MAXFPSMESSAGE 5
|
||||
#define ID_HAND 6
|
||||
#define ID_ALLOWDOWNLOAD 7
|
||||
#define ID_ALWAYSRUN 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float maxFPS;
|
||||
int hand;
|
||||
int allowDownload;
|
||||
int alwaysRun;
|
||||
} uiGameValues_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -59,7 +57,6 @@ typedef struct
|
|||
menuAction_s maxFPSmessage;
|
||||
menuCheckBox_s hand;
|
||||
menuCheckBox_s allowDownload;
|
||||
menuCheckBox_s alwaysRun;
|
||||
} uiGameOptions_t;
|
||||
|
||||
static uiGameOptions_t uiGameOptions;
|
||||
|
@ -77,10 +74,9 @@ static void UI_GameOptions_UpdateConfig( void )
|
|||
sprintf( fpsText, "%.f", uiGameOptions.maxFPS.curValue );
|
||||
uiGameOptions.maxFPS.generic.name = fpsText;
|
||||
|
||||
CVAR_SET_FLOAT( "hand", uiGameOptions.hand.enabled );
|
||||
CVAR_SET_FLOAT( "cl_righthand", uiGameOptions.hand.enabled );
|
||||
CVAR_SET_FLOAT( "sv_allow_download", uiGameOptions.allowDownload.enabled );
|
||||
CVAR_SET_FLOAT( "fps_max", uiGameOptions.maxFPS.curValue );
|
||||
CVAR_SET_FLOAT( "cl_run", uiGameOptions.alwaysRun.enabled );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -90,10 +86,9 @@ UI_GameOptions_DiscardChanges
|
|||
*/
|
||||
static void UI_GameOptions_DiscardChanges( void )
|
||||
{
|
||||
CVAR_SET_FLOAT( "hand", uiGameInitial.hand );
|
||||
CVAR_SET_FLOAT( "cl_righthand", uiGameInitial.hand );
|
||||
CVAR_SET_FLOAT( "sv_allow_download", uiGameInitial.allowDownload );
|
||||
CVAR_SET_FLOAT( "fps_max", uiGameInitial.maxFPS );
|
||||
CVAR_SET_FLOAT( "cl_run", uiGameInitial.alwaysRun );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -117,12 +112,9 @@ static void UI_GameOptions_GetConfig( void )
|
|||
{
|
||||
uiGameInitial.maxFPS = uiGameOptions.maxFPS.curValue = CVAR_GET_FLOAT( "fps_max" );
|
||||
|
||||
if( CVAR_GET_FLOAT( "hand" ))
|
||||
if( CVAR_GET_FLOAT( "cl_righthand" ))
|
||||
uiGameInitial.hand = uiGameOptions.hand.enabled = 1;
|
||||
|
||||
if( CVAR_GET_FLOAT( "cl_run" ))
|
||||
uiGameInitial.alwaysRun = uiGameOptions.alwaysRun.enabled = 1;
|
||||
|
||||
if( CVAR_GET_FLOAT( "sv_allow_download" ))
|
||||
uiGameInitial.allowDownload = uiGameOptions.allowDownload.enabled = 1;
|
||||
|
||||
|
@ -142,7 +134,6 @@ static void UI_GameOptions_Callback( void *self, int event )
|
|||
{
|
||||
case ID_HAND:
|
||||
case ID_ALLOWDOWNLOAD:
|
||||
case ID_ALWAYSRUN:
|
||||
if( event == QM_PRESSED )
|
||||
((menuCheckBox_s *)self)->focusPic = UI_CHECKBOX_PRESSED;
|
||||
else ((menuCheckBox_s *)self)->focusPic = UI_CHECKBOX_FOCUS;
|
||||
|
@ -262,15 +253,6 @@ static void UI_GameOptions_Init( void )
|
|||
uiGameOptions.allowDownload.generic.callback = UI_GameOptions_Callback;
|
||||
uiGameOptions.allowDownload.generic.statusText = "Allow download of files from servers";
|
||||
|
||||
uiGameOptions.alwaysRun.generic.id = ID_ALWAYSRUN;
|
||||
uiGameOptions.alwaysRun.generic.type = QMTYPE_CHECKBOX;
|
||||
uiGameOptions.alwaysRun.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_ACT_ONRELEASE|QMF_MOUSEONLY|QMF_DROPSHADOW;
|
||||
uiGameOptions.alwaysRun.generic.x = 280;
|
||||
uiGameOptions.alwaysRun.generic.y = 450;
|
||||
uiGameOptions.alwaysRun.generic.name = "Always run";
|
||||
uiGameOptions.alwaysRun.generic.callback = UI_GameOptions_Callback;
|
||||
uiGameOptions.alwaysRun.generic.statusText = "Switch between run/step models when pressed 'run' button";
|
||||
|
||||
UI_GameOptions_GetConfig();
|
||||
|
||||
UI_AddItem( &uiGameOptions.menu, (void *)&uiGameOptions.background );
|
||||
|
@ -280,7 +262,6 @@ static void UI_GameOptions_Init( void )
|
|||
UI_AddItem( &uiGameOptions.menu, (void *)&uiGameOptions.maxFPS );
|
||||
UI_AddItem( &uiGameOptions.menu, (void *)&uiGameOptions.maxFPSmessage );
|
||||
UI_AddItem( &uiGameOptions.menu, (void *)&uiGameOptions.hand );
|
||||
UI_AddItem( &uiGameOptions.menu, (void *)&uiGameOptions.alwaysRun );
|
||||
UI_AddItem( &uiGameOptions.menu, (void *)&uiGameOptions.allowDownload );
|
||||
}
|
||||
|
||||
|
|
|
@ -242,6 +242,7 @@ static void UI_InternetGames_Callback( void *self, int event )
|
|||
break;
|
||||
case ID_CREATEGAME:
|
||||
CVAR_SET_FLOAT( "public", 1.0f );
|
||||
CVAR_SET_FLOAT( "sv_lan", 0.0f );
|
||||
UI_CreateGame_Menu();
|
||||
break;
|
||||
case ID_GAMEINFO:
|
||||
|
|
|
@ -242,6 +242,7 @@ static void UI_LanGame_Callback( void *self, int event )
|
|||
break;
|
||||
case ID_CREATEGAME:
|
||||
CVAR_SET_FLOAT( "public", 0.0f );
|
||||
CVAR_SET_FLOAT( "sv_lan", 1.0f );
|
||||
UI_CreateGame_Menu();
|
||||
break;
|
||||
case ID_GAMEINFO:
|
||||
|
|
Reference in New Issue