static void row_cs( sqlInfo_t * db, tableInfo_t * table, cellInfo_t * row, const char * cs ) { columnInfo_t * c; char key [ MAX_INFO_KEY ]; char value [ MAX_INFO_VALUE ]; for ( ; ; ) { Info_NextPair( &cs, key, value ); if ( key[ 0 ] == '\0' ) break; c = find_column( table, key ); if ( c ) { if ( c->format == INTEGER ) { int v = atoi( value ); if ( row[ c->num ].integer != v ) { table->modified |= (1<<c->num); row[ c->num ].integer = v; } } else { const char * s = sql_alloc_string( db, value ); if ( Q_stricmp( row[ c->num ].string, s ) ) { table->modified |= (1<<c->num); row[ c->num ].string = s; } } } } }
/* ================= ServerInfo_MenuDraw ================= */ static void ServerInfo_MenuDraw( void ) { const char *s; char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; int y, i=0; int keylen, vallen, infonum=-1; UI_DrawIngameBG(); UI_DrawProportionalString( 320, 110, "SERVER INFO",UI_CENTER|UI_SMALLFONT,color_black); y = 140;//95; s = s_serverinfo.info; s_serverinfo.numdrawn = 0; while ( s && i < s_serverinfo.numlines ) { i++; Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } infonum++; if(s_serverinfo.firstline>infonum) continue; if(y>260) break; Com_sprintf(key,MAX_INFO_KEY,"%s: ",key); keylen=Q_PrintStrlen(key); vallen=Q_PrintStrlen(value); if(keylen+vallen<20) { UI_DrawString(230,y,key,UI_LEFT|UI_SMALLFONT,color_black); UI_DrawString(230+keylen*8,y,value,UI_LEFT|UI_SMALLFONT,color_blue); s_serverinfo.numdrawn++; } else { int i; // TODO: Also add linebreaks for long keys? UI_DrawString(230,y,key,UI_LEFT|UI_SMALLFONT,color_black); for(i=0;i<vallen;i+=20) { y += SMALLCHAR_HEIGHT; if(y>260) break; UI_DrawString(230,y,va("%20.20s",&value[i]),UI_LEFT|UI_SMALLFONT,color_blue); s_serverinfo.numdrawn++; } } y += SMALLCHAR_HEIGHT; } Menu_Draw( &s_serverinfo.menu ); }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s; char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); s = Info_ValueForKey( systemInfo, "helpUsObi" ); if ( atoi(s) == 0 ) { Cvar_SetCheatState(); } // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } Cvar_Set( key, value ); } extern cvar_t *s_language; if ( ( Q_stricmp( "DEUTSCH", s_language->string ) == 0 )//voice language is German || (sp_language->integer == SP_LANGUAGE_GERMAN )//text language is German || Cvar_VariableIntegerValue("ui_iscensored") == 1 ) { Cvar_Set( "g_dismemberment", "0"); } }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s; char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); s = Info_ValueForKey( systemInfo, "helpUsObi" ); cl_connectedToCheatServer = atoi( s ); if ( !cl_connectedToCheatServer ) { Cvar_SetCheatState(); } // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } Cvar_Set( key, value ); } //if ( Cvar_VariableIntegerValue("ui_iscensored") == 1 ) //{ // Cvar_Set( "g_dismemberment", "0"); //} }
/* ================= ServerInfo_MenuDraw ================= */ static void ServerInfo_MenuDraw( void ) { const char *s; char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; int i = 0, y; y = SCREEN_HEIGHT/2 - s_serverinfo.numlines*(SMALLCHAR_HEIGHT)/2 - 20; s = s_serverinfo.info; while ( s && i < s_serverinfo.numlines ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } Q_strcat( key, MAX_INFO_KEY, ":" ); UI_DrawString(SCREEN_WIDTH*0.50 - 8,y,key,UI_RIGHT|UI_SMALLFONT,color_red); UI_DrawString(SCREEN_WIDTH*0.50 + 8,y,value,UI_LEFT|UI_SMALLFONT,text_color_normal); y += SMALLCHAR_HEIGHT; i++; } Menu_Draw( &s_serverinfo.menu ); }
static void Svcmd_DumpUser_f( void ) { char name[ MAX_STRING_CHARS ], userinfo[ MAX_INFO_STRING ]; char key[ BIG_INFO_KEY ], value[ BIG_INFO_VALUE ]; const char *info; gclient_t *cl; if( trap_Argc( ) != 2 ) { G_Printf( "usage: dumpuser <player>\n" ); return; } trap_Argv( 1, name, sizeof( name ) ); cl = ClientForString( name ); if( !cl ) return; trap_GetUserinfo( cl-level.clients, userinfo, sizeof( userinfo ) ); info = &userinfo[ 0 ]; G_Printf( "userinfo\n--------\n" ); //Info_Print( userinfo ); while( 1 ) { Info_NextPair( &info, key, value ); if( !*info ) return; G_Printf( "%-20s%s\n", key, value ); } }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s, *t; char key[BIG_INFO_KEY]; char value[BIG_INFO_VALUE]; qboolean gameSet; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; // NOTE TTimo: // when the serverId changes, any further messages we send to the server will use this new serverId // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } s = Info_ValueForKey( systemInfo, "sv_cheats" ); if ( atoi(s) == 0 ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); gameSet = qfalse; // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } // ehw! if ( !Q_stricmp( key, "fs_game" ) ) { gameSet = qtrue; } Cvar_Set( key, value ); } // if game folder should not be set and it is set at the client side if ( !gameSet && *Cvar_VariableString("fs_game") ) { Cvar_Set( "fs_game", "" ); } cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged() { const char *systemInfo; const char *s; char key[ BIG_INFO_KEY ]; char value[ BIG_INFO_VALUE ]; systemInfo = cl.gameState[ CS_SYSTEMINFO ].c_str(); // NOTE TTimo: // when the serverId changes, any further messages we send to the server will use this new serverId // show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); // load paks sent by the server, but not if we are running a local server if (!com_sv_running->integer) { FS::PakPath::ClearPaks(); if (!FS_LoadServerPaks(Info_ValueForKey(systemInfo, "sv_paks"), clc.demoplaying)) { if (!cl_allowDownload->integer) { Com_Error(ERR_DROP, "Client is missing paks but downloads are disabled"); } else if (clc.demoplaying) { Com_Error(ERR_DROP, "Client is missing paks needed by the demo"); } } } // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } #ifdef USE_VOIP s = Info_ValueForKey( systemInfo, "sv_voip" ); clc.voipEnabled = atoi( s ); #endif // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[ 0 ] ) { break; } Cvar_Set( key, value ); } }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s, *t; char key[BIG_INFO_KEY]; char value[BIG_INFO_VALUE]; qboolean gameSet; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } s = Info_ValueForKey( systemInfo, "sv_cheats" ); if ( atoi(s) == 0 ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); gameSet = qfalse; // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } // ehw! if ( !Q_stricmp( key, "fs_game" ) ) { gameSet = qtrue; } Cvar_Set( key, value ); } // if game folder should not be set and it is set at the client side if ( !gameSet && *Cvar_VariableString("fs_game") ) { Cvar_Set( "fs_game", "" ); } cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s, *t; char key[BIG_INFO_KEY]; char value[BIG_INFO_VALUE]; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; // NOTE TTimo: // when the serverId changes, any further messages we send to the server will use this new serverId // show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); memset( &entLastVisible, 0, sizeof( entLastVisible ) ); // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } s = Info_ValueForKey( systemInfo, "sv_cheats" ); if ( atoi( s ) == 0 ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } Cvar_Set( key, value ); } cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); }
/* ================== Info_Print ================== */ void Info_Print( const char *infostring ) { char key[MAX_INFO_STRING]; char value[MAX_INFO_STRING]; while( infostring ) { Info_NextPair( &infostring, key, value ); if( !key[0] ) { break; } if( value[0] ) { Com_Printf( "%-20s %s\n", key, value ); } else { Com_Printf( "%-20s <MISSING VALUE>\n", key ); } } }
void JPLua_PushInfostring( lua_State *L, const char *info ) { const char *s; char key[BIG_INFO_KEY], value[BIG_INFO_VALUE]; int top = 0; lua_newtable( L ); top = lua_gettop( L ); //RAZTODO: cache userinfo somehow :/ s = info; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) break; lua_pushstring( L, key ); lua_pushstring( L, value ); lua_settable( L, top ); } }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s, *t; char key[BIG_INFO_KEY]; char value[BIG_INFO_VALUE]; qboolean gameSet; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; // NOTE TTimo: // when the serverId changes, any further messages we send to the server will use this new serverId // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); #ifdef USE_VOIP s = Info_ValueForKey( systemInfo, "sv_voipProtocol" ); clc.voipEnabled = !Q_stricmp(s, "opus"); #endif // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } s = Info_ValueForKey( systemInfo, "sv_cheats" ); cl_connectedToCheatServer = atoi( s ); if ( !cl_connectedToCheatServer ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); gameSet = qfalse; // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } // ehw! if (!Q_stricmp(key, "fs_game")) { char filename[MAX_QPATH]; char *title; if ( gameSet ) continue; if(FS_CheckDirTraversal(value)) { Com_Printf(S_COLOR_YELLOW "WARNING: Server sent invalid fs_game value %s\n", value); continue; } // create game title file if does not exist title = Info_ValueForKey( systemInfo, "sv_gameTitle" ); Com_sprintf( filename, sizeof ( filename ), "%s/description.txt", value ); if ( ( cl_allowDownload->integer & DLF_ENABLE ) && *title && !FS_SV_RW_FileExists( filename ) ) { fileHandle_t f = FS_SV_FOpenFileWrite( filename ); FS_Write( s, strlen( title ), f ); FS_FCloseFile( f ); } gameSet = qtrue; } Cvar_Server_Set(key, value); } // game folder must be set if ( !gameSet ) { Com_Error( ERR_DROP, "fs_game not set on server" ); } }
/* ================= UI_ServerInfoMenu ================= */ void UI_ServerInfoMenu( void ) { const char *s; char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; // zero set all our globals memset( &s_serverinfo, 0 ,sizeof(serverinfo_t) ); ServerInfo_Cache(); s_serverinfo.menu.draw = ServerInfo_MenuDraw; s_serverinfo.menu.key = ServerInfo_MenuKey; s_serverinfo.menu.wrapAround = qtrue; s_serverinfo.menu.fullscreen = qtrue; s_serverinfo.banner.generic.type = MTYPE_BTEXT; s_serverinfo.banner.generic.x = 320; s_serverinfo.banner.generic.y = 16; s_serverinfo.banner.string = "SERVER INFO"; s_serverinfo.banner.color = color_white; s_serverinfo.banner.style = UI_CENTER; s_serverinfo.framel.generic.type = MTYPE_BITMAP; s_serverinfo.framel.generic.name = SERVERINFO_FRAMEL; s_serverinfo.framel.generic.flags = QMF_INACTIVE; s_serverinfo.framel.generic.x = 0; s_serverinfo.framel.generic.y = 78; s_serverinfo.framel.width = 256; s_serverinfo.framel.height = 329; s_serverinfo.framer.generic.type = MTYPE_BITMAP; s_serverinfo.framer.generic.name = SERVERINFO_FRAMER; s_serverinfo.framer.generic.flags = QMF_INACTIVE; s_serverinfo.framer.generic.x = 376; s_serverinfo.framer.generic.y = 76; s_serverinfo.framer.width = 256; s_serverinfo.framer.height = 334; s_serverinfo.add.generic.type = MTYPE_PTEXT; s_serverinfo.add.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; s_serverinfo.add.generic.callback = ServerInfo_Event; s_serverinfo.add.generic.id = ID_ADD; s_serverinfo.add.generic.x = 320; s_serverinfo.add.generic.y = 371; s_serverinfo.add.string = "ADD TO FAVORITES"; s_serverinfo.add.style = UI_CENTER|UI_SMALLFONT; s_serverinfo.add.color = color_red; if( trap_Cvar_VariableValue( "sv_running" ) ) { s_serverinfo.add.generic.flags |= QMF_GRAYED; } s_serverinfo.back.generic.type = MTYPE_BITMAP; s_serverinfo.back.generic.name = SERVERINFO_BACK0; s_serverinfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; s_serverinfo.back.generic.callback = ServerInfo_Event; s_serverinfo.back.generic.id = ID_BACK; s_serverinfo.back.generic.x = 0; s_serverinfo.back.generic.y = 480-64; s_serverinfo.back.width = 128; s_serverinfo.back.height = 64; s_serverinfo.back.focuspic = SERVERINFO_BACK1; trap_GetConfigString( CS_SERVERINFO, s_serverinfo.info, MAX_INFO_STRING ); s_serverinfo.numlines = 0; s = s_serverinfo.info; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } s_serverinfo.numlines++; } if (s_serverinfo.numlines > 16) s_serverinfo.numlines = 16; Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.banner ); Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.framel ); Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.framer ); Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.add ); Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.back ); UI_PushMenu( &s_serverinfo.menu ); }
void CL_SystemInfoChanged() { const char *s, *t; // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } const char* systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; // when the serverId changes, any further messages we send to the server will use this new serverId // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this new serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); s = Info_ValueForKey( systemInfo, "sv_cheats" ); if ( atoi(s) == 0 ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); qbool gameSet = qfalse; // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { char key[BIG_INFO_KEY], value[BIG_INFO_VALUE]; Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } // ehw! if (!Q_stricmp(key, "fs_game")) { if (FS_CheckDirTraversal(value)) { Com_Printf("WARNING: Server sent invalid fs_game value %s\n", value); continue; } gameSet = qtrue; } // servers are only allowed to modify specific sets of cvars int flags = Cvar_Flags(key); if (flags == CVAR_NONEXISTENT) { Cvar_Get( key, value, CVAR_SERVER_CREATED | CVAR_ROM ); } else if (flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED)) { Cvar_Set( key, value ); } } // if game folder should not be set and it is set at the client side if ( !gameSet && *Cvar_VariableString("fs_game") ) { Cvar_Set( "fs_game", "" ); } cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); }
static void JoinServer_InfoDraw( void ) { char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; const char *info; int x = s_joinserver_server_list.width + 40; int y = 80; int index; serverStatus_t *server; playerStatus_t *player; int i; // Never draw on low resolutions if( viddef.width < 512 ) return; index = s_joinserver_server_list.curvalue; if( index < 0 || index >= MAX_MENU_SERVERS ) return; server = &localServers[sortedSList[index]]; DrawAltString( x, y, "Name Score Ping"); y += 8; DrawAltString( x, y, "--------------- ----- ----"); y += 10; if( !server->numPlayers ) { DrawAltString( x, y, "No players"); y += 8; } else { for( i=0, player=server->players ; i<server->numPlayers ; i++, player++ ) { DrawString( x, y, va( "%-15s %5i %4i\n", player->name, player->score, player->ping )); y += 8; } } y+=8; DrawAltString( x, y, "Server info"); y += 8; DrawAltString( x, y, "--------------------------"); y += 10; info = (const char *)server->infostring; while( *info ) { Info_NextPair( &info, key, value ); if(!key[0] || !value[0]) break; if( strlen( key ) > 15 ) { strcpy( key + 12, "..." ); } DrawString( x, y, va( "%-8s", key )); DrawString( x + 16 * 8, y, va( "%-16s", value )); y += 8; } }
void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s, *t; char key[ BIG_INFO_KEY ]; char value[ BIG_INFO_VALUE ]; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; // NOTE TTimo: // when the serverId changes, any further messages we send to the server will use this new serverId // show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } #ifdef USE_VOIP s = Info_ValueForKey( systemInfo, "sv_voip" ); clc.voipEnabled = atoi( s ); #endif s = Info_ValueForKey( systemInfo, "sv_cheats" ); sv_cheats = atoi( s ); //bani if ( atoi( s ) == 0 ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[ 0 ] ) { break; } Cvar_Set( key, value ); } // Arnout: big hack to clear the image cache on a pure change //cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); if ( Cvar_VariableValue( "sv_pure" ) ) { if ( !cl_connectedToPureServer && cls.state <= CA_CONNECTED ) { CL_PurgeCache(); } cl_connectedToPureServer = qtrue; } else { if ( cl_connectedToPureServer && cls.state <= CA_CONNECTED ) { CL_PurgeCache(); } cl_connectedToPureServer = qfalse; } }
/* ================= UI_StatusEvent A server status response has been received, validated and parsed. ================= */ void UI_StatusEvent(const serverStatus_t *status) { serverslot_t *slot; char *hostname, *host, *mod, *map, *maxclients; unsigned timestamp, ping; const char *info = status->infostring; char key[MAX_INFO_STRING]; char value[MAX_INFO_STRING]; int i; // ignore unless menu is up if (!m_servers.args) { return; } // see if already added slot = FindSlot(&net_from, &i); if (!slot) { // reply to broadcast, create new slot if (m_servers.list.numItems >= MAX_STATUS_SERVERS) { return; } m_servers.list.numItems++; hostname = UI_CopyString(NET_AdrToString(&net_from)); timestamp = m_servers.timestamp; } else { // free previous data hostname = slot->hostname; timestamp = slot->timestamp; FreeSlot(slot); } host = Info_ValueForKey(info, "hostname"); if (COM_IsWhite(host)) { host = hostname; } mod = Info_ValueForKey(info, "game"); if (COM_IsWhite(mod)) { mod = "baseq2"; } map = Info_ValueForKey(info, "mapname"); if (COM_IsWhite(map)) { map = "???"; } maxclients = Info_ValueForKey(info, "maxclients"); if (!COM_IsUint(maxclients)) { maxclients = "?"; } if (timestamp > com_eventTime) timestamp = com_eventTime; ping = com_eventTime - timestamp; if (ping > 999) ping = 999; slot = UI_FormatColumns(SLOT_EXTRASIZE, host, mod, map, va("%d/%s", status->numPlayers, maxclients), va("%u", ping), NULL); slot->status = SLOT_VALID; slot->address = net_from; slot->hostname = hostname; slot->color = ColorForStatus(status, ping); m_servers.list.items[i] = slot; slot->numRules = 0; while (slot->numRules < MAX_STATUS_RULES) { Info_NextPair(&info, key, value); if (!info) break; if (!key[0]) strcpy(key, "<MISSING KEY>"); if (!value[0]) strcpy(value, "<MISSING VALUE>"); slot->rules[slot->numRules++] = UI_FormatColumns(0, key, value, NULL); } slot->numPlayers = status->numPlayers; for (i = 0; i < status->numPlayers; i++) { slot->players[i] = UI_FormatColumns(0, va("%d", status->players[i].score), va("%d", status->players[i].ping), status->players[i].name, NULL); } slot->timestamp = timestamp; // don't sort when manually refreshing if (m_servers.pingstage) m_servers.list.sort(&m_servers.list); UpdateStatus(); UpdateSelection(); }
/* ================== CL_SystemInfoChanged The systeminfo configstring has been changed, so parse new information out of it. This will happen at every gamestate, and possibly during gameplay. ================== */ void CL_SystemInfoChanged( void ) { char *systemInfo; const char *s, *t; char key[BIG_INFO_KEY]; char value[BIG_INFO_VALUE]; qboolean gameSet; systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SYSTEMINFO ]; // NOTE TTimo: // when the serverId changes, any further messages we send to the server will use this new serverId // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=475 // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); #ifdef USE_VOIP s = Info_ValueForKey( systemInfo, "sv_voipProtocol" ); clc.voipEnabled = !Q_stricmp(s, "opus"); #endif // don't set any vars when playing a demo if ( clc.demoplaying ) { return; } s = Info_ValueForKey( systemInfo, "sv_cheats" ); cl_connectedToCheatServer = atoi( s ); if ( !cl_connectedToCheatServer ) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey( systemInfo, "sv_paks" ); t = Info_ValueForKey( systemInfo, "sv_pakNames" ); FS_PureServerSetLoadedPaks( s, t ); s = Info_ValueForKey( systemInfo, "sv_referencedPaks" ); t = Info_ValueForKey( systemInfo, "sv_referencedPakNames" ); FS_PureServerSetReferencedPaks( s, t ); gameSet = qfalse; // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while ( s ) { int cvar_flags; Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } // ehw! if (!Q_stricmp(key, "fs_game")) { if(FS_CheckDirTraversal(value)) { Com_Printf(S_COLOR_YELLOW "WARNING: Server sent invalid fs_game value %s\n", value); continue; } gameSet = qtrue; } if((cvar_flags = Cvar_Flags(key)) == CVAR_NONEXISTENT) Cvar_Get(key, value, CVAR_SERVER_CREATED | CVAR_ROM); else { // If this cvar may not be modified by a server discard the value. if(!(cvar_flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED | CVAR_USER_CREATED))) { #ifndef STANDALONE if(Q_stricmp(key, "g_synchronousClients") && Q_stricmp(key, "pmove_fixed") && Q_stricmp(key, "pmove_msec")) #endif { Com_Printf(S_COLOR_YELLOW "WARNING: server is not allowed to set %s=%s\n", key, value); continue; } } Cvar_SetSafe(key, value); } } // if game folder should not be set and it is set at the client side if ( !gameSet && *Cvar_VariableString("fs_game") ) { Cvar_Set( "fs_game", "" ); } cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); }
/* ================= UI_ServerInfoMenu ================= */ void UI_ServerInfoMenu( void ) { const char *s; char key[MAX_INFO_KEY]; char value[MAX_INFO_VALUE]; // zero set all our globals memset( &s_serverinfo, 0 ,sizeof(serverinfo_t) ); ServerInfo_Cache(); s_serverinfo.menu.draw = ServerInfo_MenuDraw; s_serverinfo.menu.key = ServerInfo_MenuKey; s_serverinfo.arrowup.generic.type = MTYPE_BITMAP1024S; s_serverinfo.arrowup.x = 630; s_serverinfo.arrowup.y = 226; s_serverinfo.arrowup.w = 29; s_serverinfo.arrowup.h = 74; s_serverinfo.arrowup.shader = trap_R_RegisterShaderNoMip(ARROWUP0); s_serverinfo.arrowup.mouseovershader = trap_R_RegisterShaderNoMip(ARROWUP1); s_serverinfo.arrowup.generic.callback = ServerInfo_Event; s_serverinfo.arrowup.generic.id = ID_SCROLL_UP; Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.arrowup ); s_serverinfo.arrowdown.generic.type = MTYPE_BITMAP1024S; s_serverinfo.arrowdown.x = 630; s_serverinfo.arrowdown.y = 436-74; s_serverinfo.arrowdown.w = 29;//38 s_serverinfo.arrowdown.h = 74;//98 s_serverinfo.arrowdown.shader = trap_R_RegisterShaderNoMip(ARROWDOWN0); s_serverinfo.arrowdown.mouseovershader = trap_R_RegisterShaderNoMip(ARROWDOWN1); s_serverinfo.arrowdown.generic.callback = ServerInfo_Event; s_serverinfo.arrowdown.generic.id = ID_SCROLL_DOWN; Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.arrowdown ); s_serverinfo.add.generic.type = MTYPE_TEXTS; s_serverinfo.add.fontHeight = 18.0f; s_serverinfo.add.generic.flags = QMF_CENTER_JUSTIFY;//|QMF_PULSEIFFOCUS; s_serverinfo.add.generic.callback = ServerInfo_Event; s_serverinfo.add.generic.id = ID_ADD; s_serverinfo.add.generic.x = 320; s_serverinfo.add.generic.y = 290; s_serverinfo.add.string = "ADD TO FAVORiTES"; s_serverinfo.add.style = UI_CENTER|UI_SMALLFONT; s_serverinfo.add.color = colorDkBlue; s_serverinfo.add.focuscolor = colorBlue; if( trap_Cvar_VariableValue( "sv_running" ) ) { s_serverinfo.add.generic.flags |= QMF_GRAYED; } s_serverinfo.back.generic.type = MTYPE_TEXTS; s_serverinfo.back.fontHeight = 16.0f; // s_serverinfo.back.generic.flags = QMF_PULSEIFFOCUS; s_serverinfo.back.generic.callback = ServerInfo_Event; s_serverinfo.back.generic.id = ID_BACK; s_serverinfo.back.generic.x = 245; s_serverinfo.back.generic.y = 315; s_serverinfo.back.string = "BACK"; s_serverinfo.back.style = UI_SMALLFONT; s_serverinfo.back.color = color_black; s_serverinfo.back.focuscolor = color_orange; trap_GetConfigString( CS_SERVERINFO, s_serverinfo.info, MAX_INFO_STRING ); s_serverinfo.numlines = 0; s = s_serverinfo.info; while ( s ) { Info_NextPair( &s, key, value ); if ( !key[0] ) { break; } s_serverinfo.numlines++; } Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.add ); Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.back ); UI_PushMenu( &s_serverinfo.menu ); }
void CL_SystemInfoChanged(void) { char *systemInfo = cl.gameState.stringData + cl.gameState.stringOffsets[CS_SYSTEMINFO]; const char *s, *t; char key[BIG_INFO_KEY]; char value[BIG_INFO_VALUE]; qboolean gameSet; // NOTE: when the serverId changes, any further messages we send to the server will use this new serverId // in some cases, outdated cp commands might get sent with this news serverId cl.serverId = atoi(Info_ValueForKey(systemInfo, "sv_serverid")); memset(&entLastVisible, 0, sizeof(entLastVisible)); // don't set any vars when playing a demo if (clc.demoplaying) { return; } s = Info_ValueForKey(systemInfo, "sv_cheats"); cl_connectedToCheatServer = atoi(s); //bani if (!cl_connectedToCheatServer) { Cvar_SetCheatState(); } // check pure server string s = Info_ValueForKey(systemInfo, "sv_paks"); t = Info_ValueForKey(systemInfo, "sv_pakNames"); FS_PureServerSetLoadedPaks(s, t); s = Info_ValueForKey(systemInfo, "sv_referencedPaks"); t = Info_ValueForKey(systemInfo, "sv_referencedPakNames"); FS_PureServerSetReferencedPaks(s, t); gameSet = qfalse; // scan through all the variables in the systeminfo and locally set cvars to match s = systemInfo; while (s) { int cvar_flags; Info_NextPair(&s, key, value); if (!key[0]) { break; } // ehw! if (!Q_stricmp(key, "fs_game")) { if (FS_CheckDirTraversal(value)) { Com_Printf(S_COLOR_YELLOW "WARNING: Server sent invalid fs_game value %s\n", value); continue; } gameSet = qtrue; } if ((cvar_flags = Cvar_Flags(key)) == CVAR_NONEXISTENT) { Cvar_Get(key, value, CVAR_SERVER_CREATED | CVAR_ROM); } else { // If this cvar may not be modified by a server discard the value. if (!(cvar_flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED | CVAR_USER_CREATED))) { if (Q_stricmp(key, "g_synchronousClients") && Q_stricmp(key, "pmove_fixed") && Q_stricmp(key, "pmove_msec")) { Com_DPrintf(S_COLOR_YELLOW "WARNING: server is not allowed to set %s=%s\n", key, value); continue; } } Cvar_SetSafe(key, value); } } // if game folder should not be set and it is set at the client side if (!gameSet && *Cvar_VariableString("fs_game")) { Cvar_Set("fs_game", ""); } // big hack to clear the image cache on a pure change //cl_connectedToPureServer = Cvar_VariableValue( "sv_pure" ); if (Cvar_VariableValue("sv_pure")) { if (!cl_connectedToPureServer && cls.state <= CA_CONNECTED) { CL_PurgeCache(); } cl_connectedToPureServer = qtrue; } else { if (cl_connectedToPureServer && cls.state <= CA_CONNECTED) { CL_PurgeCache(); } cl_connectedToPureServer = qfalse; } }