// Main functions qbool SNDDMA_Init(void) { int retval; #ifdef __FreeBSD__ Com_Printf("sound: Initializing OSS...\n"); retval = SNDDMA_Init_OSS(); #else // Give user the option to force OSS... if (Cvar_Value("s_noalsa")) { // User wants us to use OSS... SNDDMA_ALSA = false; Com_Printf("sound: Using OSS at user's request...\n"); retval = SNDDMA_Init_OSS(); } else { // Try ALSA first... Com_Printf("sound: Attempting to initialise ALSA...\n"); retval = SNDDMA_Init_ALSA(); if (retval) { SNDDMA_ALSA = true; } else { // Fall back to OSS... SNDDMA_ALSA = false; Com_Printf("sound: Falling back to OSS...\n"); Cvar_Set(&s_device, "/dev/dsp"); retval = SNDDMA_Init_OSS(); } } #endif return retval; }
// returns true if we should draw this player, we don't if we are chase camming qbool Cam_DrawPlayer(int playernum) { if (cl.spectator && autocam && locked && cl_chasecam.value && #ifdef JSS_CAM !Cvar_Value("cam_thirdperson") && #endif spec_track == playernum) return false; return true; }
/** * Writes the tags of the server for filtering in the Steam server browser. * * @param tags string where to write the tags (at least MAX_STEAMQUERY_TAG_STRING bytes) */ static void SV_GetSteamTags( char *tags ) { // Currently there is no way to filter by tag in the game itself, // so this is mostly to make sure the tags aren't empty on old servers if they are added. Q_strncpyz( tags, Cvar_String( "g_gametype" ), MAX_STEAMQUERY_TAG_STRING ); if( Cvar_Value( "g_instagib" ) ) { if( tags[0] ) Q_strncatz( tags, ",", MAX_STEAMQUERY_TAG_STRING ); Q_strncatz( tags, "instagib", MAX_STEAMQUERY_TAG_STRING ); } // If sv_tags cvar is added, every comma-separated tag from the cvar must be added separately // (so the last tag exceeding MAX_STEAMQUERY_TAG_STRING isn't cut off) // and validated not to contain any characters disallowed in userinfo (CVAR_SERVERINFO). }
/* ======================= CL_SendConnectPacket called by CL_Connect_f and CL_CheckResend ====================== */ void CL_SendConnectPacket (void) { char data[2048]; char biguserinfo[MAX_INFO_STRING + 32]; if (cls.state != ca_disconnected) return; connect_time = cls.realtime; // for retransmit requests cls.qport = Cvar_Value("qport"); // let the server know what extensions we support strcpy (biguserinfo, cls.userinfo); Info_SetValueForStarKey (biguserinfo, "*z_ext", va("%i", CLIENT_EXTENSIONS), sizeof(biguserinfo)); sprintf (data, "\xff\xff\xff\xff" "connect %i %i %i \"%s\"\n", PROTOCOL_VERSION, cls.qport, cls.challenge, biguserinfo); NET_SendPacket (NS_CLIENT, strlen(data), data, cls.server_adr); }
void IN_Frame( void ) { qboolean m_active = qfalse; if( !input_inited ) return; HandleEvents(); if( focus ) { if( !Cvar_Value( "vid_fullscreen" ) && ( ( cls.key_dest == key_console ) && !in_grabinconsole->integer ) ) { m_active = qfalse; } else { m_active = qtrue; } } IN_Activate( m_active ); }
void IN_Frame( void ) { if( !input_inited ) return; if( !mapped || ( ( x11display.features.wmStateFullscreen || !Cvar_Value( "vid_fullscreen" ) ) && ( !focus || ( ( cls.key_dest == key_console ) && !in_grabinconsole->integer ) ) ) ) { if( input_active ) IN_Activate( qfalse ); } else { if( !input_active ) IN_Activate( qtrue ); } HandleEvents(); if( input_active && in_dgamouse->modified ) { uninstall_grabs(); install_grabs(); } }
/** * This function is called for every frame and gives us some time to poll * for events that occured at our input devices. */ void IN_Frame() { if( !input_inited ) return; if( !input_focus || ( !Cvar_Value( "vid_fullscreen" ) && cls.key_dest == key_console && !in_grabinconsole->integer ) ) { if( mouse_active ) { if( mouse_relative ) { mouse_relative = !(SDL_SetRelativeMouseMode( SDL_FALSE ) == 0); if( !mouse_relative ) { IN_SetMouseScalingEnabled( true ); } } SDL_ShowCursor( SDL_ENABLE ); } mouse_active = false; input_active = true; } else { if( !mouse_active ) { SDL_ShowCursor( SDL_DISABLE ); mouse_relative = SDL_SetRelativeMouseMode( SDL_TRUE ) == 0; if( mouse_relative ) { IN_SetMouseScalingEnabled( false ); } else { IN_WarpMouseToCenter( NULL, NULL ); } IN_SkipRelativeMouseMove(); } mouse_active = true; input_active = true; } IN_HandleEvents(); }
/* * CM_LoadMap * Loads in the map and all submodels * * for spawning a server with no map at all, call like this: * CM_LoadMap( "", qfalse, &checksum ); // no real map */ cmodel_t *CM_LoadMap( cmodel_state_t *cms, const char *name, qboolean clientload, unsigned *checksum ) { int length; unsigned *buf; char *header; const modelFormatDescr_t *descr; bspFormatDesc_t *bspFormat = NULL; assert( cms ); assert( name && strlen( name ) < MAX_CONFIGSTRING_CHARS ); assert( checksum ); cms->map_clientload = clientload; if( !strcmp( cms->map_name, name ) && ( clientload || !Cvar_Value( "flushmap" ) ) ) { *checksum = cms->checksum; if( !clientload ) { memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); CM_FloodAreaConnections( cms ); } return cms->map_cmodels; // still have the right version } CM_Clear( cms ); if( !name || !name[0] ) { cms->numleafs = 1; cms->numcmodels = 2; *checksum = 0; return cms->map_cmodels; // cinematic servers won't have anything at all } // // load the file // length = FS_LoadFile( name, ( void ** )&buf, NULL, 0 ); if( !buf ) Com_Error( ERR_DROP, "Couldn't load %s", name ); cms->checksum = Com_MD5Digest32( ( const qbyte * )buf, length ); *checksum = cms->checksum; // call the apropriate loader descr = Q_FindFormatDescriptor( cm_supportedformats, ( const qbyte * )buf, (const bspFormatDesc_t **)&bspFormat ); if( !descr ) Com_Error( ERR_DROP, "CM_LoadMap: unknown fileid for %s", name ); if( !bspFormat ) Com_Error( ERR_DROP, "CM_LoadMap: %s: unknown bsp format" ); // copy header into temp variable to be saveed in a cvar header = Mem_TempMalloc( descr->headerLen + 1 ); memcpy( header, buf, descr->headerLen ); header[descr->headerLen] = '\0'; // store map format description in cvars Cvar_ForceSet( "cm_mapHeader", header ); Cvar_ForceSet( "cm_mapVersion", va( "%i", LittleLong( *((int *)((qbyte *)buf + descr->headerLen)) ) ) ); Mem_TempFree( header ); descr->loader( cms, NULL, buf, bspFormat ); CM_InitBoxHull( cms ); CM_InitOctagonHull( cms ); if( cms->numareas ) { cms->map_areas = Mem_Alloc( cms->mempool, cms->numareas * sizeof( *cms->map_areas ) ); cms->map_areaportals = Mem_Alloc( cms->mempool, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); CM_FloodAreaConnections( cms ); } memset( cms->nullrow, 255, MAX_CM_LEAFS / 8 ); Q_strncpyz( cms->map_name, name, sizeof( cms->map_name ) ); return cms->map_cmodels; }
static char *SV_ShortInfoString( void ) { static char string[MAX_STRING_SVCINFOSTRING]; char hostname[64]; char entry[20]; size_t len; int i, count, bots; const char *password; bots = 0; count = 0; for( i = 0; i < sv_maxclients->integer; i++ ) { if( svs.clients[i].state >= CS_CONNECTED ) { if( svs.clients[i].edict->r.svflags & SVF_FAKECLIENT || svs.clients[i].tvclient ) bots++; count++; } } //format: //" \377\377\377\377info\\n\\server_name\\m\\map name\\u\\clients/maxclients\\g\\gametype\\s\\skill\\EOT " Q_strncpyz( hostname, sv_hostname->string, sizeof( hostname ) ); Q_snprintfz( string, sizeof( string ), "\\\\n\\\\%s\\\\m\\\\%8s\\\\u\\\\%2i/%2i\\\\", hostname, sv.mapname, count > 99 ? 99 : count, sv_maxclients->integer > 99 ? 99 : sv_maxclients->integer ); len = strlen( string ); Q_snprintfz( entry, sizeof( entry ), "g\\\\%6s\\\\", Cvar_String( "g_gametype" ) ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } if( Q_stricmp( FS_GameDirectory(), FS_BaseGameDirectory() ) ) { Q_snprintfz( entry, sizeof( entry ), "mo\\\\%8s\\\\", FS_GameDirectory() ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } } if( Cvar_Value( "g_instagib" ) ) { Q_snprintfz( entry, sizeof( entry ), "ig\\\\1\\\\" ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } } Q_snprintfz( entry, sizeof( entry ), "s\\\\%1d\\\\", sv_skilllevel->integer ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } password = Cvar_String( "password" ); if( password[0] != '\0' ) { Q_snprintfz( entry, sizeof( entry ), "p\\\\1\\\\" ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } } if( bots ) { Q_snprintfz( entry, sizeof( entry ), "b\\\\%2i\\\\", bots > 99 ? 99 : bots ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } } if( SV_MM_Initialized() ) { Q_snprintfz( entry, sizeof( entry ), "mm\\\\1\\\\" ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } } if( Cvar_Value( "g_race_gametype" ) ) { Q_snprintfz( entry, sizeof( entry ), "r\\\\1\\\\" ); if( MAX_SVCINFOSTRING_LEN - len > strlen( entry ) ) { Q_strncatz( string, entry, sizeof( string ) ); len = strlen( string ); } } // finish it Q_strncatz( string, "EOT", sizeof( string ) ); return string; }
// Take over the user controls and track a player. // We find a nice position to watch the player and move there void Cam_Track(usercmd_t *cmd) { player_state_t *player, *self; frame_t *frame; vec3_t vec; if (!cl.spectator) { return; } // hack: save +movedown command cmddown = cmd->upmove < 0; // cl_hightrack if (cl_hightrack.value && !locked) { Cam_CheckHighTarget(); } if (!autocam || cls.state != ca_active) { return; } if (locked && (!cl.players[spec_track].name[0] || cl.players[spec_track].spectator)) { locked = false; // cl_hightrack if (cl_hightrack.value) { Cam_CheckHighTarget(); } else { Cam_Unlock(); } return; } frame = &cl.frames[cl.validsequence & UPDATE_MASK]; if (autocam && cls.mvdplayback) { if (ideal_track != spec_track && cls.realtime - last_lock > 0.1 && frame->playerstate[ideal_track].messagenum == cl.parsecount) { Cam_Lock(ideal_track); } if (frame->playerstate[spec_track].messagenum != cl.parsecount) { int i; for (i = 0; i < MAX_CLIENTS; i++) { if (frame->playerstate[i].messagenum == cl.parsecount) break; } if (i < MAX_CLIENTS) { Cam_Lock(i); } } } player = frame->playerstate + spec_track; self = frame->playerstate + cl.playernum; if (!locked || !Cam_IsVisible(player, desired_position)) { if (!locked || cls.realtime - cam_lastviewtime > 0.1) { if (!InitFlyby(self, player, true)) InitFlyby(self, player, false); cam_lastviewtime = cls.realtime; } } else { cam_lastviewtime = cls.realtime; } // couldn't track for some reason if (!locked || !autocam) return; if (cl_chasecam.value) { cmd->forwardmove = cmd->sidemove = cmd->upmove = 0; #ifdef JSS_CAM if (!Cvar_Value ("cam_thirdperson")) #endif { VectorCopy(player->viewangles, cl.viewangles); } VectorCopy(player->origin, desired_position); if (memcmp(&desired_position, &self->origin, sizeof(desired_position)) != 0) { MSG_WriteByte (&cls.netchan.message, clc_tmove); MSG_WriteCoord (&cls.netchan.message, desired_position[0]); MSG_WriteCoord (&cls.netchan.message, desired_position[1]); MSG_WriteCoord (&cls.netchan.message, desired_position[2]); // move there locally immediately VectorCopy(desired_position, self->origin); } } else { // Ok, move to our desired position and set our angles to view // the player VectorSubtract(desired_position, self->origin, vec); cmd->forwardmove = cmd->sidemove = cmd->upmove = 0; if (VectorLength(vec) > 16) { // close enough? MSG_WriteByte (&cls.netchan.message, clc_tmove); MSG_WriteCoord (&cls.netchan.message, desired_position[0]); MSG_WriteCoord (&cls.netchan.message, desired_position[1]); MSG_WriteCoord (&cls.netchan.message, desired_position[2]); } // move there locally immediately VectorCopy(desired_position, self->origin); VectorSubtract(player->origin, desired_position, vec); vectoangles(vec, cl.viewangles); cl.viewangles[0] = -cl.viewangles[0]; } }
static qbool Cam_FirstPersonMode(void) { return cl_chasecam.value && !Cvar_Value("cam_thirdperson") && !Cvar_Value("cl_camera_tpp"); }
// Send the intended movement message to the server. void CL_BaseMove (usercmd_t *cmd) { CL_AdjustAngles (); memset (cmd, 0, sizeof(*cmd)); VectorCopy (cl.viewangles, cmd->angles); if (cl_iDrive.integer) { float s1, s2; if (in_strafe.state & 1) { s1 = CL_KeyState (&in_right, false); s2 = CL_KeyState (&in_left, false); if (s1 && s2) { if (in_right.downtime > in_left.downtime) s2 = 0; if (in_right.downtime < in_left.downtime) s1 = 0; } cmd->sidemove += cl_sidespeed.value * s1; cmd->sidemove -= cl_sidespeed.value * s2; } s1 = CL_KeyState (&in_moveright, false); s2 = CL_KeyState (&in_moveleft, false); if (s1 && s2) { if (in_moveright.downtime > in_moveleft.downtime) s2 = 0; if (in_moveright.downtime < in_moveleft.downtime) s1 = 0; } cmd->sidemove += cl_sidespeed.value * s1; cmd->sidemove -= cl_sidespeed.value * s2; s1 = CL_KeyState (&in_up, false); s2 = CL_KeyState (&in_down, false); if (s1 && s2) { if (in_up.downtime > in_down.downtime) s2 = 0; if (in_up.downtime < in_down.downtime) s1 = 0; } cmd->upmove += cl_upspeed.value * s1; cmd->upmove -= cl_upspeed.value * s2; if (!(in_klook.state & 1)) { s1 = CL_KeyState (&in_forward, false); s2 = CL_KeyState (&in_back, false); if (s1 && s2) { if (in_forward.downtime > in_back.downtime) s2 = 0; if (in_forward.downtime < in_back.downtime) s1 = 0; } cmd->forwardmove += cl_forwardspeed.value * s1; cmd->forwardmove -= cl_backspeed.value * s2; } } else { if (in_strafe.state & 1) { cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right, false); cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left, false); } cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright, false); cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft, false); cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up, false); cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down, false); if (!(in_klook.state & 1)) { cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward, false); cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back, false); } } // adjust for speed key if (in_speed.state & 1) { cmd->forwardmove *= cl_movespeedkey.value; cmd->sidemove *= cl_movespeedkey.value; cmd->upmove *= cl_movespeedkey.value; } #ifdef JSS_CAM { static float zoomspeed = 0; if ((cls.demoplayback || cl.spectator) && Cvar_Value("cam_thirdperson") && !Cvar_Value("cam_lockpos")) { zoomspeed -= CL_KeyState(&in_forward, false) * cls.trueframetime * cam_zoomaccel.value; zoomspeed += CL_KeyState(&in_back, false) * cls.trueframetime * cam_zoomaccel.value; if (!CL_KeyState(&in_forward, false) && !CL_KeyState(&in_back, false)) { if (zoomspeed > 0) { zoomspeed -= cls.trueframetime * cam_zoomaccel.value; if (zoomspeed < 0) zoomspeed = 0; } else if (zoomspeed < 0) { zoomspeed += cls.trueframetime * cam_zoomaccel.value; if (zoomspeed > 0) zoomspeed = 0; } } zoomspeed = bound (-cam_zoomspeed.value, zoomspeed, cam_zoomspeed.value); if (zoomspeed) { float dist = Cvar_Value("cam_dist"); dist += cls.trueframetime * zoomspeed; if (dist < 0) dist = 0; Cvar_SetValue (Cvar_Find("cam_dist"), dist); } } } #endif // JSS_CAM }
void PR_LoadProgs (void) { int i; char num[32]; char name[MAX_OSPATH]; int filesize; // flush the non-C variable lookup cache for (i = 0; i < GEFV_CACHESIZE; i++) gefvCache[i].field[0] = 0; // clear pr_newstrtbl PF_clear_strtbl(); snprintf(name, sizeof(name), "%s.dat", sv_progsname.string); progs = (dprograms_t *)FS_LoadHunkFile (name, &filesize); if (!progs) progs = (dprograms_t *)FS_LoadHunkFile ("qwprogs.dat", &filesize); if (!progs) progs = (dprograms_t *)FS_LoadHunkFile ("spprogs.dat", &filesize); #ifdef WITH_NQPROGS pr_nqprogs = false; if (!progs || Cvar_Value("sv_forcenqprogs")) { progs = (dprograms_t *)FS_LoadHunkFile ("progs.dat", &filesize); if (progs) pr_nqprogs = true; } #endif if (!progs) SV_Error ("PR_LoadProgs: couldn't load progs.dat"); Con_DPrintf ("Programs occupy %iK.\n", filesize/1024); // add prog crc to the serverinfo snprintf (num, sizeof(num), "%i", CRC_Block ((byte *)progs, filesize)); #ifdef USE_PR2 Info_SetStar( &_localinfo_, "*qvm", "DAT" ); // Info_SetValueForStarKey (svs.info, "*qvm", "DAT", MAX_SERVERINFO_STRING); #endif Info_SetValueForStarKey (svs.info, "*progs", num, MAX_SERVERINFO_STRING); // byte swap the header for (i = 0; i < (int) sizeof(*progs) / 4 ; i++) ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] ); if (progs->version != PROG_VERSION) SV_Error ("qwprogs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); if (progs->crc != (pr_nqprogs ? NQ_PROGHEADER_CRC : PROGHEADER_CRC)) SV_Error ("You must have the qwprogs.dat from QuakeWorld installed"); pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions); pr_strings = (char *)progs + progs->ofs_strings; pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs); pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs); pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements); num_prstr = 0; pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals); pr_globals = (float *)pr_global_struct; pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t); // byte swap the lumps for (i = 0; i < progs->numstatements; i++) { pr_statements[i].op = LittleShort(pr_statements[i].op); pr_statements[i].a = LittleShort(pr_statements[i].a); pr_statements[i].b = LittleShort(pr_statements[i].b); pr_statements[i].c = LittleShort(pr_statements[i].c); } for (i = 0; i < progs->numfunctions; i++) { pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement); pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); pr_functions[i].locals = LittleLong (pr_functions[i].locals); } for (i = 0; i < progs->numglobaldefs; i++) { pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type); pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs); pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name); } for (i = 0; i < progs->numfielddefs; i++) { pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type); if (pr_fielddefs[i].type & DEF_SAVEGLOBAL) SV_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); } for (i = 0; i < progs->numglobals; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); #ifdef WITH_NQPROGS PR_InitPatchTables(); #endif // find optional QC-exported functions SpectatorConnect = ED_FindFunctionOffset ("SpectatorConnect"); SpectatorThink = ED_FindFunctionOffset ("SpectatorThink"); SpectatorDisconnect = ED_FindFunctionOffset ("SpectatorDisconnect"); ChatMessage = ED_FindFunctionOffset ("ChatMessage"); UserInfo_Changed = ED_FindFunctionOffset ("UserInfo_Changed"); mod_ConsoleCmd = ED_FindFunctionOffset ("ConsoleCmd"); mod_UserCmd = ED_FindFunctionOffset ("UserCmd"); localinfoChanged = ED_FindFunctionOffset ("localinfoChanged"); GE_ClientCommand = ED_FindFunctionOffset ("GE_ClientCommand"); GE_PausedTic = ED_FindFunctionOffset ("GE_PausedTic"); GE_ShouldPause = ED_FindFunctionOffset ("GE_ShouldPause"); CheckKTPro (); }
/** * Responds to a Steam server query. * * @param s query string * @param socket response socket * @param address response address * @param inmsg message for arguments * @return whether the request was handled as a Steam query */ bool SV_SteamServerQuery( const char *s, const socket_t *socket, const netadr_t *address, msg_t *inmsg ) { #if APP_STEAMID if( sv.state < ss_loading || sv.state > ss_game ) return false; // server not running if( ( !sv_public->integer && !NET_IsLANAddress( address ) ) || ( sv_maxclients->integer == 1 ) ) return false; if( !strcmp( s, "i" ) ) { // ping const char pingResponse[] = "j00000000000000"; Netchan_OutOfBand( socket, address, sizeof( pingResponse ), ( const uint8_t * )pingResponse ); return true; } if( !strcmp( s, "W" ) || !strcmp( s, "U\xFF\xFF\xFF\xFF" ) ) { // challenge - security feature, but since we don't send multiple packets always return 0 const uint8_t challengeResponse[] = { 'A', 0, 0, 0, 0 }; Netchan_OutOfBand( socket, address, sizeof( challengeResponse ), ( const uint8_t * )challengeResponse ); return true; } if( !strcmp( s, "TSource Engine Query" ) ) { // server info char hostname[MAX_INFO_VALUE]; char gamedir[MAX_QPATH]; char gamename[128]; char version[32]; char tags[MAX_STEAMQUERY_TAG_STRING]; int i, players = 0, bots = 0, maxclients = 0; int flags = 0x80 | 0x01; // game port | game ID containing app ID client_t *cl; msg_t msg; uint8_t msgbuf[MAX_STEAMQUERY_PACKETLEN - sizeof( int32_t )]; if( sv_showInfoQueries->integer ) Com_Printf( "Steam Info Packet %s\n", NET_AddressToString( address ) ); Q_strncpyz( hostname, COM_RemoveColorTokens( sv_hostname->string ), sizeof( hostname ) ); if( !hostname[0] ) Q_strncpyz( hostname, sv_hostname->dvalue, sizeof( hostname ) ); Q_strncpyz( gamedir, FS_GameDirectory(), sizeof( gamedir ) ); Q_strncpyz( gamename, APPLICATION, sizeof( gamename ) ); if( Cvar_Value( "g_instagib" ) ) Q_strncatz( gamename, " IG", sizeof( gamename ) ); if( sv.configstrings[CS_GAMETYPETITLE][0] || sv.configstrings[CS_GAMETYPENAME][0] ) { Q_strncatz( gamename, " ", sizeof( gamename ) ); Q_strncatz( gamename, sv.configstrings[sv.configstrings[CS_GAMETYPETITLE][0] ? CS_GAMETYPETITLE : CS_GAMETYPENAME], sizeof( gamename ) ); } for( i = 0; i < sv_maxclients->integer; i++ ) { cl = &svs.clients[i]; if( cl->state >= CS_CONNECTED ) { if( cl->tvclient ) // exclude TV from the max players count continue; if( cl->edict->r.svflags & SVF_FAKECLIENT ) bots++; players++; } maxclients++; } Q_snprintfz( version, sizeof( version ), "%i.%i.0.0", APP_VERSION_MAJOR, APP_VERSION_MINOR ); SV_GetSteamTags( tags ); if( tags[0] ) flags |= 0x20; MSG_Init( &msg, msgbuf, sizeof( msgbuf ) ); MSG_WriteByte( &msg, 'I' ); MSG_WriteByte( &msg, APP_PROTOCOL_VERSION ); MSG_WriteString( &msg, hostname ); MSG_WriteString( &msg, sv.mapname ); MSG_WriteString( &msg, gamedir ); MSG_WriteString( &msg, gamename ); MSG_WriteShort( &msg, 0 ); // app ID specified later MSG_WriteByte( &msg, min( players, 99 ) ); MSG_WriteByte( &msg, min( maxclients, 99 ) ); MSG_WriteByte( &msg, min( bots, 99 ) ); MSG_WriteByte( &msg, ( dedicated && dedicated->integer ) ? 'd' : 'l' ); MSG_WriteByte( &msg, STEAMQUERY_OS ); MSG_WriteByte( &msg, Cvar_String( "password" )[0] ? 1 : 0 ); MSG_WriteByte( &msg, 0 ); // VAC insecure MSG_WriteString( &msg, version ); MSG_WriteByte( &msg, flags ); // port MSG_WriteShort( &msg, sv_port->integer ); // tags if( flags & 0x20 ) MSG_WriteString( &msg, tags ); // 64-bit game ID - needed to specify app ID MSG_WriteLong( &msg, APP_STEAMID & 0xffffff ); MSG_WriteLong( &msg, 0 ); Netchan_OutOfBand( socket, address, msg.cursize, msg.data ); return true; } if( s[0] == 'U' ) { // players msg_t msg; uint8_t msgbuf[MAX_STEAMQUERY_PACKETLEN - sizeof( int32_t )]; int i, players = 0; client_t *cl; char name[MAX_NAME_BYTES]; unsigned int time = Sys_Milliseconds(); if( sv_showInfoQueries->integer ) Com_Printf( "Steam Players Packet %s\n", NET_AddressToString( address ) ); MSG_Init( &msg, msgbuf, sizeof( msgbuf ) ); MSG_WriteByte( &msg, 'D' ); MSG_WriteByte( &msg, 0 ); for( i = 0; i < sv_maxclients->integer; i++ ) { cl = &svs.clients[i]; if( ( cl->state < CS_CONNECTED ) || cl->tvclient ) continue; Q_strncpyz( name, COM_RemoveColorTokens( cl->name ), sizeof( name ) ); if( ( msg.cursize + 10 + strlen( name ) ) > sizeof( msgbuf ) ) break; MSG_WriteByte( &msg, i ); MSG_WriteString( &msg, name ); MSG_WriteLong( &msg, cl->edict->r.client->r.frags ); MSG_WriteFloat( &msg, ( float )( time - cl->lastconnect ) * 0.001f ); players++; if( players == 99 ) break; } msgbuf[1] = players; Netchan_OutOfBand( socket, address, msg.cursize, msg.data ); return true; } if( !strcmp( s, "s" ) ) { // master server query, terminated by \n, followed by the challenge int i; bool fromMaster = false; int challenge; char gamedir[MAX_QPATH], basedir[MAX_QPATH], tags[MAX_STEAMQUERY_TAG_STRING]; int players = 0, bots = 0, maxclients = 0; client_t *cl; char msg[MAX_STEAMQUERY_PACKETLEN]; for( i = 0; i < MAX_MASTERS; i++ ) { if( sv_masters[i].steam && NET_CompareAddress( address, &sv_masters[i].address ) ) { fromMaster = true; break; } } if( !fromMaster ) return true; if( sv_showInfoQueries->integer ) Com_Printf( "Steam Master Server Info Packet %s\n", NET_AddressToString( address ) ); challenge = MSG_ReadLong( inmsg ); Q_strncpyz( gamedir, FS_GameDirectory(), sizeof( gamedir ) ); Q_strncpyz( basedir, FS_BaseGameDirectory(), sizeof( basedir ) ); SV_GetSteamTags( tags ); for( i = 0; i < sv_maxclients->integer; i++ ) { cl = &svs.clients[i]; if( cl->state >= CS_CONNECTED ) { if( cl->tvclient ) // exclude TV from the max players count continue; if( cl->edict->r.svflags & SVF_FAKECLIENT ) bots++; players++; } maxclients++; } Q_snprintfz( msg, sizeof( msg ), "0\n\\protocol\\7\\challenge\\%i" // protocol must be 7 to match Source "\\players\\%i\\max\\%i\\bots\\%i" "\\gamedir\\%s\\map\\%s" "\\password\\%i\\os\\%c" "\\lan\\%i\\region\\255" "%s%s" "\\type\\%c\\secure\\0" "\\version\\%i.%i.0.0" "\\product\\%s\n", challenge, min( players, 99 ), min( maxclients, 99 ), min( bots, 99 ), gamedir, sv.mapname, Cvar_String( "password" )[0] ? 1 : 0, STEAMQUERY_OS, sv_public->integer ? 0 : 1, tags[0] ? "\\gametype\\" /* legacy - "gametype", not "tags" */ : "", tags, ( dedicated && dedicated->integer ) ? 'd' : 'l', APP_VERSION_MAJOR, APP_VERSION_MINOR, basedir ); NET_SendPacket( socket, ( const uint8_t * )msg, strlen( msg ), address ); return true; } if( s[0] == 'O' ) { // out of date message static bool printed = false; if( !printed ) { int i; for( i = 0; i < MAX_MASTERS; i++ ) { if( sv_masters[i].steam && NET_CompareAddress( address, &sv_masters[i].address ) ) { Com_Printf( "Server is out of date and cannot be added to the Steam master servers.\n" ); printed = true; return true; } } } return true; } #endif return false; }
static void HandleEvents( void ) { XEvent event; qboolean dowarp = qfalse, was_focused = focus; int mwx = x11display.win_width / 2; int mwy = x11display.win_height / 2; char *p; int key = 0; int time = 0; assert( x11display.dpy && x11display.win ); #ifdef WSW_EVDEV if( mouse_active && m_evdev_num ) { evdev_read(); } else #endif if( mouse_active && !dgamouse ) { int root_x, root_y, win_x, win_y; unsigned int mask; Window root, child; if( XQueryPointer( x11display.dpy, x11display.win, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask ) ) { mx += ( (int)win_x - mwx ); my += ( (int)win_y - mwy ); mwx = win_x; mwy = win_y; if( mx || my ) dowarp = qtrue; if( ignore_one ) { mx = my = 0; ignore_one = qfalse; } } } while( XPending( x11display.dpy ) ) { XNextEvent( x11display.dpy, &event ); switch( event.type ) { case KeyPress: time = Sys_XTimeToSysTime(event.xkey.time); p = XLateKey( &event.xkey, &key ); if( key ) Key_Event( key, qtrue, time ); while ( p && *p ) { qwchar wc = Q_GrabWCharFromUtf8String( (const char **)&p ); Key_CharEvent( key, wc ); } break; case KeyRelease: if( repeated_press( &event ) ) break; // don't send release events when repeating time = Sys_XTimeToSysTime(event.xkey.time); XLateKey( &event.xkey, &key ); Key_Event( key, event.type == KeyPress, time ); break; case MotionNotify: #ifdef WSW_EVDEV if( mouse_active && dgamouse && !m_evdev_num ) #else if( mouse_active && dgamouse ) #endif { mx += event.xmotion.x_root; my += event.xmotion.y_root; if( ignore_one ) { mx = my = 0; ignore_one = qfalse; } } break; case ButtonPress: if( ( cls.key_dest == key_console ) && !in_grabinconsole->integer ) break; #ifdef WSW_EVDEV if( m_evdev_num ) break; #endif time = Sys_XTimeToSysTime(event.xkey.time); if( event.xbutton.button == 1 ) Key_MouseEvent( K_MOUSE1, 1, time ); else if( event.xbutton.button == 2 ) Key_MouseEvent( K_MOUSE3, 1, time ); else if( event.xbutton.button == 3 ) Key_MouseEvent( K_MOUSE2, 1, time ); else if( event.xbutton.button == 4 ) Key_Event( K_MWHEELUP, 1, time ); else if( event.xbutton.button == 5 ) Key_Event( K_MWHEELDOWN, 1, time ); else if( event.xbutton.button >= 6 && event.xbutton.button <= 10 ) Key_MouseEvent( K_MOUSE4+event.xbutton.button-6, 1, time ); break; case ButtonRelease: if( ( cls.key_dest == key_console ) && !in_grabinconsole->integer ) break; #ifdef WSW_EVDEV if( m_evdev_num ) break; #endif time = Sys_XTimeToSysTime(event.xkey.time); if( event.xbutton.button == 1 ) Key_MouseEvent( K_MOUSE1, 0, time ); else if( event.xbutton.button == 2 ) Key_MouseEvent( K_MOUSE3, 0, time ); else if( event.xbutton.button == 3 ) Key_MouseEvent( K_MOUSE2, 0, time ); else if( event.xbutton.button == 4 ) Key_Event( K_MWHEELUP, 0, time ); else if( event.xbutton.button == 5 ) Key_Event( K_MWHEELDOWN, 0, time ); else if( event.xbutton.button >= 6 && event.xbutton.button <= 10 ) Key_MouseEvent( K_MOUSE4+event.xbutton.button-6, 0, time ); break; case FocusIn: if( x11display.ic ) XSetICFocus(x11display.ic); if( !focus ) { focus = qtrue; } break; case FocusOut: if( x11display.ic ) XUnsetICFocus(x11display.ic); if( focus ) { Key_ClearStates(); focus = qfalse; } break; case ClientMessage: if( event.xclient.data.l[0] == x11display.wmDeleteWindow ) Cbuf_ExecuteText( EXEC_NOW, "quit" ); break; case MapNotify: mapped = qtrue; if( x11display.modeset ) { if ( x11display.dpy && x11display.win ) { XSetInputFocus( x11display.dpy, x11display.win, RevertToPointerRoot, CurrentTime ); x11display.modeset = qfalse; } } if( input_active ) { uninstall_grabs(); install_grabs(); } break; case ConfigureNotify: VID_AppActivate( qtrue, qfalse ); break; case PropertyNotify: if( event.xproperty.window == x11display.win ) { if ( event.xproperty.atom == x11display.wmState ) { qboolean was_minimized = minimized; _X11_CheckWMSTATE(); if( minimized != was_minimized ) { // FIXME: find a better place for this?.. CL_SoundModule_Activate( !minimized ); } } } break; } } if( dowarp ) { XWarpPointer( x11display.dpy, None, x11display.win, 0, 0, 0, 0, x11display.win_width/2, x11display.win_height/2 ); } // set fullscreen or windowed mode upon focus in/out events if: // a) lost focus in fullscreen -> windowed // b) received focus -> fullscreen if a) if( ( focus != was_focused ) ) { if( x11display.features.wmStateFullscreen ) { if( !focus && Cvar_Value( "vid_fullscreen" ) ) { go_fullscreen_on_focus = qtrue; Cbuf_ExecuteText( EXEC_APPEND, "vid_fullscreen 0\n" ); } else if( focus && go_fullscreen_on_focus ) { go_fullscreen_on_focus = qfalse; Cbuf_ExecuteText( EXEC_APPEND, "vid_fullscreen 1\n" ); } } } }
static void HandleEvents( void ) { XEvent event, response; XSelectionRequestEvent* request; assert( x11display.dpy && x11display.win ); while( XPending( x11display.dpy ) ) { XGenericEventCookie *cookie = &event.xcookie; XNextEvent( x11display.dpy, &event ); if( cookie->type == GenericEvent && cookie->extension == xi_opcode && XGetEventData( x11display.dpy, cookie ) ) { handle_cookie( cookie ); XFreeEventData( x11display.dpy, cookie ); continue; } switch( event.type ) { case FocusIn: if( event.xfocus.mode == NotifyGrab || event.xfocus.mode == NotifyUngrab ) { // Someone is handling a global hotkey, ignore it continue; } if( !focus ) { focus = qtrue; install_grabs_keyboard(); } break; case FocusOut: if( event.xfocus.mode == NotifyGrab || event.xfocus.mode == NotifyUngrab ) { // Someone is handling a global hotkey, ignore it continue; } if( focus ) { if( Cvar_Value( "vid_fullscreen" ) ) { Cbuf_ExecuteText( EXEC_APPEND, "set vid_fullscreen 0\n" ); } uninstall_grabs_keyboard(); Key_ClearStates(); focus = qfalse; shift_level = 0; } break; case ClientMessage: if( event.xclient.data.l[0] == x11display.wmDeleteWindow ) Cbuf_ExecuteText( EXEC_NOW, "quit" ); break; case ConfigureNotify: VID_AppActivate( qtrue, qfalse ); break; case PropertyNotify: if( event.xproperty.window == x11display.win ) { if ( event.xproperty.atom == x11display.wmState ) { qboolean was_minimized = minimized; _X11_CheckWMSTATE(); if( minimized != was_minimized ) { // FIXME: find a better place for this?.. CL_SoundModule_Activate( !minimized ); } } } break; case SelectionClear: // Another app took clipboard ownership away // There's not actually anything we need to do here break; case SelectionRequest: // Another app is requesting clipboard information request = &event.xselectionrequest; memset( &response, 0, sizeof( response ) ); response.xselection.type = SelectionNotify; response.xselection.display = request->display; response.xselection.requestor = request->requestor; response.xselection.selection = request->selection; response.xselection.target = request->target; response.xselection.time = request->time; response.xselection.property = Sys_ClipboardProperty( request ); // Send the response XSendEvent( x11display.dpy, request->requestor, 0, 0, &response ); break; } } }
static qboolean Cvar_CheatsAllowed() { return ( Com_ClientState() < CA_CONNECTED ) || // not connected Com_DemoPlaying() || // playing demo ( Com_ServerState() && Cvar_Value( "sv_cheats" ) ); // local server, sv_cheats }
/* =============== PR_LoadProgs =============== */ void PR_LoadProgs (void) { int i; char num[32]; static int lumpsize[6] = { sizeof(dstatement_t), sizeof(ddef_t), sizeof(ddef_t), sizeof(dfunction_t), 4, 4 }; int filesize = 0; const char *progsname; progs = NULL; // decide whether to load qwprogs.dat, progs.dat or spprogs.dat #ifdef WITH_NQPROGS if (Cvar_Value("sv_forcenqprogs")) goto use_progs; #endif if (!deathmatch.value) { if (Q_stricmp(com_gamedirfile, "qw") && strcmp(com_gamedirfile, "")) { // if we're using a custom mod, anything // in gamedir is preferred to stock *progs.dat qbool check; check = FS_FindFile ("spprogs.dat"); if (check && file_from_gamedir) goto use_spprogs; #ifdef WITH_NQPROGS check = FS_FindFile ("progs.dat"); if (check && file_from_gamedir) goto use_progs; #endif check = FS_FindFile ("qwprogs.dat"); if (check && file_from_gamedir) goto use_qwprogs; } use_spprogs: progs = (dprograms_t *) FS_LoadHunkFile ("spprogs.dat"); progsname = "spprogs.dat"; pr_nqprogs = false; if (!progs) { #ifdef WITH_NQPROGS use_progs: progs = (dprograms_t *)FS_LoadHunkFile ("progs.dat"); progsname = "progs.dat"; pr_nqprogs = true; } #endif if (!progs) { use_qwprogs: progs = (dprograms_t *)FS_LoadHunkFile ("qwprogs.dat"); progsname = "qwprogs.dat"; pr_nqprogs = false; } } else // deathmatch { if (Q_stricmp(com_gamedirfile, "qw") && strcmp(com_gamedirfile, "")) { qbool check; check = FS_FindFile ("qwprogs.dat"); if (check && file_from_gamedir) goto dm_use_qwprogs; #ifdef WITH_NQPROGS check = FS_FindFile ("progs.dat"); if (check && file_from_gamedir) goto dm_use_progs; #endif } dm_use_qwprogs: progs = (dprograms_t *) FS_LoadHunkFile ("qwprogs.dat"); progsname = "qwprogs.dat"; pr_nqprogs = false; if (!progs) { #ifdef WITH_NQPROGS dm_use_progs: progs = (dprograms_t *)FS_LoadHunkFile ("progs.dat"); progsname = "progs.dat"; pr_nqprogs = true; } #endif } if (!progs) Host_Error ("PR_LoadProgs: couldn't load progs.dat"); filesize = fs_filesize; if (filesize < (int)sizeof(*progs)) Host_Error("%s is corrupt", progsname); Com_DPrintf ("Using %s (%i bytes).\n", progsname, filesize); // add prog crc to the serverinfo sprintf (num, "%i", CRC_Block ((byte *)progs, filesize)); svs.info.set("*progs", num); // byte swap the header for (i = 0; i < sizeof(*progs)/4; i++) ((int *)progs)[i] = LittleLong ( ((int *)progs)[i] ); if (progs->version != PROG_VERSION) Host_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION); if (progs->crc != (pr_nqprogs ? NQ_PROGHEADER_CRC : PROGHEADER_CRC)) Host_Error ("You must have the qwprogs.dat from QuakeWorld installed"); // check lump offsets and sizes for (i = 0; i < 6; i ++) { if (((int *)progs)[i*2 + 2] < sizeof(*progs) || ((int *)progs)[i*2 + 2] + ((int *)progs)[i*2 + 3]*lumpsize[i] > filesize) Host_Error("progs.dat is corrupt"); } pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions); pr_strings = (char *)progs + progs->ofs_strings; pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs); pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs); pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements); pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals); pr_globals = (float *)pr_global_struct; PR_InitStrings (); pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t); // byte swap the lumps for (i=0 ; i<progs->numstatements ; i++) { pr_statements[i].op = LittleShort(pr_statements[i].op); pr_statements[i].a = LittleShort(pr_statements[i].a); pr_statements[i].b = LittleShort(pr_statements[i].b); pr_statements[i].c = LittleShort(pr_statements[i].c); } for (i=0 ; i<progs->numfunctions; i++) { pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement); pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); pr_functions[i].locals = LittleLong (pr_functions[i].locals); } for (i=0 ; i<progs->numglobaldefs ; i++) { pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type); pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs); pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name); } for (i=0 ; i<progs->numfielddefs ; i++) { pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type); if (pr_fielddefs[i].type & DEF_SAVEGLOBAL) Host_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); } for (i=0 ; i<progs->numglobals ; i++) ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); #ifdef WITH_NQPROGS if (pr_nqprogs) { memcpy (pr_globaloffsetpatch, pr_globaloffsetpatch_nq, sizeof(pr_globaloffsetpatch)); for (i = 0; i < 106; i++) { pr_fieldoffsetpatch[i] = (i < 8) ? i : (i < 25) ? i + 1 : (i < 28) ? i + (102 - 25) : (i < 73) ? i - 2 : (i < 74) ? i + (105 - 73) : (i < 105) ? i - 3 : /* (i == 105) */ 8; } for (i=0 ; i<progs->numfielddefs ; i++) pr_fielddefs[i].ofs = PR_FIELDOFS(pr_fielddefs[i].ofs); } else { memset (pr_globaloffsetpatch, 0, sizeof(pr_globaloffsetpatch)); for (i = 0; i < 106; i++) pr_fieldoffsetpatch[i] = i; } #endif // find optional QC-exported functions SpectatorConnect = ED_FindFunctionOffset ("SpectatorConnect"); SpectatorThink = ED_FindFunctionOffset ("SpectatorThink"); SpectatorDisconnect = ED_FindFunctionOffset ("SpectatorDisconnect"); GE_ClientCommand = ED_FindFunctionOffset ("GE_ClientCommand"); GE_ConsoleCommand = ED_FindFunctionOffset ("GE_ConsoleCommand"); GE_PausedTic = ED_FindFunctionOffset ("GE_PausedTic"); GE_ShouldPause = ED_FindFunctionOffset ("GE_ShouldPause"); // find optional QC-exported fields fofs_maxspeed = ED_FindFieldOffset ("maxspeed"); fofs_gravity = ED_FindFieldOffset ("gravity"); fofs_items2 = ED_FindFieldOffset ("items2"); fofs_movement = ED_FindFieldOffset ("movement"); fofs_vw_index = ED_FindFieldOffset ("vw_index"); for (i = 3; i < 8; i++) fofs_buttonX[i-3] = ED_FindFieldOffset(va("button%i", i)); // reset stuff like ZQ_CLIENTCOMMAND, progs must enable it explicitly memset (&pr_ext_enabled, sizeof(pr_ext_enabled), 0); PR_Exec_Init (); }