📄 common.c
字号:
if ( com_sv_running->integer ) {
Com_RunAndTimeServerPacket( &evFrom, &buf );
} else {
CL_PacketEvent( evFrom, &buf );
}
break;
}
// free any block data
if ( ev.evPtr ) {
Z_Free( ev.evPtr );
}
}
return 0; // never reached
}
/*
================
Com_Milliseconds
Can be used for profiling, but will be journaled accurately
================
*/
int Com_Milliseconds (void) {
sysEvent_t ev;
// get events and push them until we get a null event with the current time
do {
ev = Com_GetRealEvent();
if ( ev.evType != SE_NONE ) {
Com_PushEvent( &ev );
}
} while ( ev.evType != SE_NONE );
return ev.evTime;
}
//============================================================================
/*
=============
Com_Error_f
Just throw a fatal error to
test error shutdown procedures
=============
*/
static void Com_Error_f (void) {
if ( Cmd_Argc() > 1 ) {
Com_Error( ERR_DROP, "Testing drop error" );
} else {
Com_Error( ERR_FATAL, "Testing fatal error" );
}
}
/*
=============
Com_Freeze_f
Just freeze in place for a given number of seconds to test
error recovery
=============
*/
static void Com_Freeze_f (void) {
float s;
int start, now;
if ( Cmd_Argc() != 2 ) {
Com_Printf( "freeze <seconds>\n" );
return;
}
s = atof( Cmd_Argv(1) );
start = Com_Milliseconds();
while ( 1 ) {
now = Com_Milliseconds();
if ( ( now - start ) * 0.001 > s ) {
break;
}
}
}
/*
=================
Com_Crash_f
A way to force a bus error for development reasons
=================
*/
static void Com_Crash_f( void ) {
* ( int * ) 0 = 0x12345678;
}
// TTimo: centralizing the cl_cdkey stuff after I discovered a buffer overflow problem with the dedicated server version
// not sure it's necessary to have different defaults for regular and dedicated, but I don't want to risk it
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=470
#ifndef DEDICATED
char cl_cdkey[34] = " ";
#else
char cl_cdkey[34] = "123456789";
#endif
/*
=================
Com_ReadCDKey
=================
*/
qboolean CL_CDKeyValidate( const char *key, const char *checksum );
void Com_ReadCDKey( const char *filename ) {
fileHandle_t f;
char buffer[33];
char fbuffer[MAX_OSPATH];
sprintf(fbuffer, "%s/q3key", filename);
FS_SV_FOpenFileRead( fbuffer, &f );
if ( !f ) {
Q_strncpyz( cl_cdkey, " ", 17 );
return;
}
Com_Memset( buffer, 0, sizeof(buffer) );
FS_Read( buffer, 16, f );
FS_FCloseFile( f );
if (CL_CDKeyValidate(buffer, NULL)) {
Q_strncpyz( cl_cdkey, buffer, 17 );
} else {
Q_strncpyz( cl_cdkey, " ", 17 );
}
}
/*
=================
Com_AppendCDKey
=================
*/
void Com_AppendCDKey( const char *filename ) {
fileHandle_t f;
char buffer[33];
char fbuffer[MAX_OSPATH];
sprintf(fbuffer, "%s/q3key", filename);
FS_SV_FOpenFileRead( fbuffer, &f );
if (!f) {
Q_strncpyz( &cl_cdkey[16], " ", 17 );
return;
}
Com_Memset( buffer, 0, sizeof(buffer) );
FS_Read( buffer, 16, f );
FS_FCloseFile( f );
if (CL_CDKeyValidate(buffer, NULL)) {
strcat( &cl_cdkey[16], buffer );
} else {
Q_strncpyz( &cl_cdkey[16], " ", 17 );
}
}
#ifndef DEDICATED // bk001204
/*
=================
Com_WriteCDKey
=================
*/
static void Com_WriteCDKey( const char *filename, const char *ikey ) {
fileHandle_t f;
char fbuffer[MAX_OSPATH];
char key[17];
sprintf(fbuffer, "%s/q3key", filename);
Q_strncpyz( key, ikey, 17 );
if(!CL_CDKeyValidate(key, NULL) ) {
return;
}
f = FS_SV_FOpenFileWrite( fbuffer );
if ( !f ) {
Com_Printf ("Couldn't write %s.\n", filename );
return;
}
FS_Write( key, 16, f );
FS_Printf( f, "\n// generated by quake, do not modify\r\n" );
FS_Printf( f, "// Do not give this file to ANYONE.\r\n" );
FS_Printf( f, "// id Software and Activision will NOT ask you to send this file to them.\r\n");
FS_FCloseFile( f );
}
#endif
/*
=================
Com_Init
=================
*/
void Com_Init( char *commandLine )
{
char *s;
Com_Printf( "%s %s %s\n", Q3_VERSION, CPUSTRING, __DATE__ );
if ( setjmp (abortframe) ) {
Sys_Error ("Error during initialization");
}
// bk001129 - do this before anything else decides to push events
Com_InitPushEvent();
Com_InitSmallZoneMemory();
Cvar_Init ();
// prepare enough of the subsystems to handle
// cvar and command buffer management
Com_ParseCommandLine( commandLine );
// Swap_Init ();
Cbuf_Init ();
Com_InitZoneMemory();
Cmd_Init ();
// override anything from the config files with command line args
Com_StartupVariable( NULL );
// get the developer cvar set as early as possible
Com_StartupVariable( "developer" );
// done early so bind command exists
CL_InitKeyCommands();
FS_InitFilesystem ();
Com_InitJournaling();
Cbuf_AddText ("exec default.cfg\n");
// skip the q3config.cfg if "safe" is on the command line
if ( !Com_SafeMode() ) {
Cbuf_AddText ("exec q3config.cfg\n");
}
Cbuf_AddText ("exec autoexec.cfg\n");
Cbuf_Execute ();
// override anything from the config files with command line args
Com_StartupVariable( NULL );
// get dedicated here for proper hunk megs initialization
#ifdef DEDICATED
com_dedicated = Cvar_Get ("dedicated", "1", CVAR_ROM);
#else
com_dedicated = Cvar_Get ("dedicated", "0", CVAR_LATCH);
#endif
// allocate the stack based hunk allocator
Com_InitHunkMemory();
// if any archived cvars are modified after this, we will trigger a writing
// of the config file
cvar_modifiedFlags &= ~CVAR_ARCHIVE;
//
// init commands and vars
//
com_maxfps = Cvar_Get ("com_maxfps", "85", CVAR_ARCHIVE);
com_blood = Cvar_Get ("com_blood", "1", CVAR_ARCHIVE);
com_developer = Cvar_Get ("developer", "0", CVAR_TEMP );
com_logfile = Cvar_Get ("logfile", "0", CVAR_TEMP );
com_timescale = Cvar_Get ("timescale", "1", CVAR_CHEAT | CVAR_SYSTEMINFO );
com_fixedtime = Cvar_Get ("fixedtime", "0", CVAR_CHEAT);
com_showtrace = Cvar_Get ("com_showtrace", "0", CVAR_CHEAT);
com_dropsim = Cvar_Get ("com_dropsim", "0", CVAR_CHEAT);
com_viewlog = Cvar_Get( "viewlog", "0", CVAR_CHEAT );
com_speeds = Cvar_Get ("com_speeds", "0", 0);
com_timedemo = Cvar_Get ("timedemo", "0", CVAR_CHEAT);
com_cameraMode = Cvar_Get ("com_cameraMode", "0", CVAR_CHEAT);
cl_paused = Cvar_Get ("cl_paused", "0", CVAR_ROM);
sv_paused = Cvar_Get ("sv_paused", "0", CVAR_ROM);
com_sv_running = Cvar_Get ("sv_running", "0", CVAR_ROM);
com_cl_running = Cvar_Get ("cl_running", "0", CVAR_ROM);
com_buildScript = Cvar_Get( "com_buildScript", "0", 0 );
com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
#if defined(_WIN32) && defined(_DEBUG)
com_noErrorInterrupt = Cvar_Get( "com_noErrorInterrupt", "0", 0 );
#endif
if ( com_dedicated->integer ) {
if ( !com_viewlog->integer ) {
Cvar_Set( "viewlog", "1" );
}
}
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 );
s = va("%s %s %s", Q3_VERSION, CPUSTRING, __DATE__ );
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
Sys_Init();
Netchan_Init( Com_Milliseconds() & 0xffff ); // pick a port value that should be nice and random
VM_Init();
SV_Init();
com_dedicated->modified = qfalse;
if ( !com_dedicated->integer ) {
CL_Init();
Sys_ShowConsole( com_viewlog->integer, qfalse );
}
// set com_frameTime so that if a map is started on the
// command line it will still be able to count on com_frameTime
// being random enough for a serverid
com_frameTime = Com_Milliseconds();
// add + commands from command line
if ( !Com_AddStartupCommands() ) {
// if the user didn't give any commands, run default action
if ( !com_dedicated->integer ) {
Cbuf_AddText ("cinematic idlogo.RoQ\n");
if( !com_introPlayed->integer ) {
Cvar_Set( com_introPlayed->name, "1" );
Cvar_Set( "nextmap", "cinematic intro.RoQ" );
}
}
}
// start in full screen ui mode
Cvar_Set("r_uiFullScreen", "1");
CL_StartHunkUsers();
// make sure single player is off by default
Cvar_Set("ui_singlePlayerActive", "0");
com_fullyInitialized = qtrue;
Com_Printf ("--- Common Initialization Complete ---\n");
}
//==================================================================
void Com_WriteConfigToFile( const char *filename ) {
fileHandle_t f;
f = FS_FOpenFileWrite( filename );
if ( !f ) {
Com_Printf ("Couldn't write %s.\n", filename );
return;
}
FS_Printf (f, "// generated by quake, do not modify\n");
Key_WriteBindings (f);
Cvar_WriteVariables (f);
FS_FCloseFile( f );
}
/*
===============
Com_WriteConfiguration
Writes key bindings and archived cvars to config file if modified
===============
*/
void Com_WriteConfiguration( void ) {
#ifndef DEDICATED // bk001204
cvar_t *fs;
#endif
// if we are quiting without fully initializing, make sure
// we don't write out anything
if ( !com_fullyInitialized ) {
return;
}
if ( !(cvar_modifiedFlags & CVAR_ARCHIVE ) ) {
return;
}
cvar_modifiedFlags &= ~CVAR_ARCHIVE;
Com_WriteConfigToFile( "q3config.cfg" );
// bk001119 - tentative "not needed for dedicated"
#ifndef DEDICATED
fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) {
Com_WriteCDKey( fs->string, &cl_cdkey[16] );
} else {
Com_WriteCDKey( "baseq3", cl_cdkey );
}
#endif
}
/*
===============
Com_WriteConfig_f
Write the config file to a specific name
===============
*/
void Com_WriteConfig_f( void ) {
char filename[MAX_QPATH];
if ( Cmd_Argc() != 2 ) {
Com_Printf( "Usage: writeconfig <filename>\n" );
return;
}
Q_strncpyz( filename, Cmd_Argv(1), sizeof( filename ) );
COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
Com_Printf( "Writing %s.\n", filename );
Com_WriteConfigToFile( filename );
}
/*
================
Com_ModifyMsec
================
*/
int Com_ModifyMsec( int msec ) {
int clampTime;
//
// modify time for debugging values
//
if ( com_fixedtime->integer ) {
msec = com_fixedtime->integer;
} else if ( com_timescale->value ) {
msec *= com_timescale->value;
} else if (com_cameraMode->integer) {
msec *= com_timescale->value;
}
// don't let it scale below 1 msec
if ( msec < 1 && com_timescale->value) {
msec = 1;
}
if ( com_dedicated->integer ) {
// dedicated servers don't want to clamp for a much longer
// period, because it would mess up all the client's views
// of time.
if ( msec > 500 ) {
Com_Printf( "Hitch warning: %i msec frame time\n", msec );
}
clampTime = 5000;
} else
if ( !com_sv_running->integer ) {
// clients of remote servers do not want to clamp time, because
// it would skew their view of the server's time temporarily
clampTime = 5000;
} else {
// for local single player gaming
// we may want to clamp the time to prevent players from
// flying off edges when something hitches.
clampTime = 200;
}
if ( msec > clampTime ) {
msec = clampTime;
}
return msec;
}
/*
=================
Com_Frame
=================
*/
void Com_Frame( void ) {
int msec, minMsec;
static int lastTime;
int key;
int timeBeforeFirstEvents;
int timeBeforeServer;
int timeBeforeEvents;
int timeBeforeClient;
int timeAfter;
if ( setjmp (abortframe) ) {
return; // an ERR_DROP was thrown
}
// bk001204 - init to zero.
// also: might be clobbered by `longjmp' or `vfork'
timeBeforeFirstEvents =0;
timeBeforeServer =0;
timeBeforeEvents =0;
timeBeforeClient = 0;
timeAfter = 0;
// old net chan encryption key
key = 0x87243987;
// write config file if anything changed
Com_WriteConfiguration();
// if "viewlog" has be
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -