#include "server.h"
Include dependency graph for sv_main.c:

Go to the source code of this file.
|
|
Definition at line 215 of file sv_main.c. Referenced by SV_MasterHeartbeat(). |
|
|
|
|
|
Referenced by SVC_RemoteCommand(). |
|
||||||||||||
|
Definition at line 128 of file sv_main.c. References client_t, Com_Printf(), i, MAX_RELIABLE_COMMANDS, Q_strncpyz(), client_s::reliableAcknowledge, client_s::reliableCommands, client_s::reliableSequence, and SV_DropClient(). Referenced by SV_MapRestart_f(), and SV_SendServerCommand(). 00128 {
00129 int index, i;
00130
00131 // this is very ugly but it's also a waste to for instance send multiple config string updates
00132 // for the same config string index in one snapshot
00133 // if ( SV_ReplacePendingServerCommands( client, cmd ) ) {
00134 // return;
00135 // }
00136
00137 client->reliableSequence++;
00138 // if we would be losing an old command that hasn't been acknowledged,
00139 // we must drop the connection
00140 // we check == instead of >= so a broadcast print added by SV_DropClient()
00141 // doesn't cause a recursive drop client
00142 if ( client->reliableSequence - client->reliableAcknowledge == MAX_RELIABLE_COMMANDS + 1 ) {
00143 Com_Printf( "===== pending server commands =====\n" );
00144 for ( i = client->reliableAcknowledge + 1 ; i <= client->reliableSequence ; i++ ) {
00145 Com_Printf( "cmd %5d: %s\n", i, client->reliableCommands[ i & (MAX_RELIABLE_COMMANDS-1) ] );
00146 }
00147 Com_Printf( "cmd %5d: %s\n", i, cmd );
00148 SV_DropClient( client, "Server command overflow" );
00149 return;
00150 }
00151 index = client->reliableSequence & ( MAX_RELIABLE_COMMANDS - 1 );
00152 Q_strncpyz( client->reliableCommands[ index ], cmd, sizeof( client->reliableCommands[ index ] ) );
00153 }
|
Here is the call graph for this function:

|
|
Definition at line 613 of file sv_main.c. References cl, client_t, serverStatic_t::clients, count, i, cvar_s::integer, j, playerState_s::ping, playerState_t, SV_GameClientNum(), sv_maxclients, and svs. Referenced by SV_Frame(). 00613 {
00614 int i, j;
00615 client_t *cl;
00616 int total, count;
00617 int delta;
00618 playerState_t *ps;
00619
00620 for (i=0 ; i < sv_maxclients->integer ; i++) {
00621 cl = &svs.clients[i];
00622 if ( cl->state != CS_ACTIVE ) {
00623 cl->ping = 999;
00624 continue;
00625 }
00626 if ( !cl->gentity ) {
00627 cl->ping = 999;
00628 continue;
00629 }
00630 if ( cl->gentity->r.svFlags & SVF_BOT ) {
00631 cl->ping = 0;
00632 continue;
00633 }
00634
00635 total = 0;
00636 count = 0;
00637 for ( j = 0 ; j < PACKET_BACKUP ; j++ ) {
00638 if ( cl->frames[j].messageAcked <= 0 ) {
00639 continue;
00640 }
00641 delta = cl->frames[j].messageAcked - cl->frames[j].messageSent;
00642 count++;
00643 total += delta;
00644 }
00645 if (!count) {
00646 cl->ping = 999;
00647 } else {
00648 cl->ping = total/count;
00649 if ( cl->ping > 999 ) {
00650 cl->ping = 999;
00651 }
00652 }
00653
00654 // let the game dll know about the ping
00655 ps = SV_GameClientNum( i );
00656 ps->ping = cl->ping;
00657 }
00658 }
|
Here is the call graph for this function:

|
|
Definition at line 714 of file sv_main.c. References cl, cl_paused, client_t, serverStatic_t::clients, count, CS_CONNECTED, Cvar_Set(), i, cvar_s::integer, qboolean, sv_maxclients, sv_paused, and svs. Referenced by SV_Frame(). 00714 {
00715 int count;
00716 client_t *cl;
00717 int i;
00718
00719 if ( !cl_paused->integer ) {
00720 return qfalse;
00721 }
00722
00723 // only pause if there is just a single client connected
00724 count = 0;
00725 for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
00726 if ( cl->state >= CS_CONNECTED && cl->netchan.remoteAddress.type != NA_BOT ) {
00727 count++;
00728 }
00729 }
00730
00731 if ( count > 1 ) {
00732 // don't pause
00733 if (sv_paused->integer)
00734 Cvar_Set("sv_paused", "0");
00735 return qfalse;
00736 }
00737
00738 if (!sv_paused->integer)
00739 Cvar_Set("sv_paused", "1");
00740 return qtrue;
00741 }
|
Here is the call graph for this function:

|
|
Definition at line 673 of file sv_main.c. References cl, client_t, serverStatic_t::clients, Com_DPrintf(), CS_CONNECTED, CS_ZOMBIE, i, cvar_s::integer, SV_DropClient(), sv_maxclients, sv_timeout, sv_zombietime, svs, and serverStatic_t::time. Referenced by SV_Frame(). 00673 {
00674 int i;
00675 client_t *cl;
00676 int droppoint;
00677 int zombiepoint;
00678
00679 droppoint = svs.time - 1000 * sv_timeout->integer;
00680 zombiepoint = svs.time - 1000 * sv_zombietime->integer;
00681
00682 for (i=0,cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
00683 // message times may be wrong across a changelevel
00684 if (cl->lastPacketTime > svs.time) {
00685 cl->lastPacketTime = svs.time;
00686 }
00687
00688 if (cl->state == CS_ZOMBIE
00689 && cl->lastPacketTime < zombiepoint) {
00690 // using the client id cause the cl->name is empty at this point
00691 Com_DPrintf( "Going from CS_ZOMBIE to CS_FREE for client %d\n", i );
00692 cl->state = CS_FREE; // can now be reused
00693 continue;
00694 }
00695 if ( cl->state >= CS_CONNECTED && cl->lastPacketTime < droppoint) {
00696 // wait several frames so a debugger session doesn't
00697 // cause a timeout
00698 if ( ++cl->timeoutCount > 5 ) {
00699 SV_DropClient (cl, "timed out");
00700 cl->state = CS_FREE; // don't bother with zombie state
00701 }
00702 } else {
00703 cl->timeoutCount = 0;
00704 }
00705 }
00706 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 502 of file sv_main.c. References c, Cmd_Argv(), Cmd_TokenizeString(), Com_DPrintf(), msg_t::data, Huff_Decompress(), MSG_BeginReadingOOB(), MSG_ReadLong(), MSG_ReadStringLine(), NET_AdrToString(), Q_stricmp(), Q_strncmp(), s, SV_AuthorizeIpPacket(), SV_DirectConnect(), SV_GetChallenge(), SVC_Info(), SVC_RemoteCommand(), and SVC_Status(). Referenced by SV_PacketEvent(). 00502 {
00503 char *s;
00504 char *c;
00505
00506 MSG_BeginReadingOOB( msg );
00507 MSG_ReadLong( msg ); // skip the -1 marker
00508
00509 if (!Q_strncmp("connect", &msg->data[4], 7)) {
00510 Huff_Decompress(msg, 12);
00511 }
00512
00513 s = MSG_ReadStringLine( msg );
00514 Cmd_TokenizeString( s );
00515
00516 c = Cmd_Argv(0);
00517 Com_DPrintf ("SV packet %s : %s\n", NET_AdrToString(from), c);
00518
00519 if (!Q_stricmp(c, "getstatus")) {
00520 SVC_Status( from );
00521 } else if (!Q_stricmp(c, "getinfo")) {
00522 SVC_Info( from );
00523 } else if (!Q_stricmp(c, "getchallenge")) {
00524 SV_GetChallenge( from );
00525 } else if (!Q_stricmp(c, "connect")) {
00526 SV_DirectConnect( from );
00527 } else if (!Q_stricmp(c, "ipAuthorize")) {
00528 SV_AuthorizeIpPacket( from );
00529 } else if (!Q_stricmp(c, "rcon")) {
00530 SVC_RemoteCommand( from, msg );
00531 } else if (!Q_stricmp(c, "disconnect")) {
00532 // if a client starts up a local server, we may see some spurious
00533 // server disconnect messages when their new server sees our final
00534 // sequenced messages to the old client
00535 } else {
00536 Com_DPrintf ("bad connectionless packet from %s:\n%s\n"
00537 , NET_AdrToString (from), s);
00538 }
00539 }
|
Here is the call graph for this function:

|
|
Definition at line 71 of file sv_main.c. References in, l, and string(). Referenced by SV_SendServerCommand(). 00071 {
00072 static char string[1024];
00073 int l;
00074
00075 l = 0;
00076 while ( *in && l < sizeof(string) - 3 ) {
00077 if ( *in == '\n' ) {
00078 string[l++] = '\\';
00079 string[l++] = 'n';
00080 } else {
00081 string[l++] = *in;
00082 }
00083 in++;
00084 }
00085 string[l] = 0;
00086
00087 return string;
00088 }
|
Here is the call graph for this function:

|
|
Definition at line 419 of file sv_main.c. References NET_OutOfBandPrint(), NS_SERVER, serverStatic_t::redirectAddress, and svs. Referenced by SVC_RemoteCommand(). 00419 {
00420 NET_OutOfBandPrint( NS_SERVER, svs.redirectAddress, "print\n%s", outputbuf );
00421 }
|
Here is the call graph for this function:

|
|
Definition at line 751 of file sv_main.c. References Cbuf_AddText(), com_dedicated, com_speeds, com_sv_running, CS_SERVERINFO, CS_SYSTEMINFO, Cvar_InfoString(), Cvar_InfoString_Big(), cvar_modifiedFlags, CVAR_SERVERINFO, Cvar_Set(), CVAR_SYSTEMINFO, GAME_RUN_FRAME, gvm, cvar_s::integer, NET_Sleep(), serverStatic_t::nextSnapshotEntities, serverStatic_t::numSnapshotEntities, server_t::restartTime, startTime, sv, SV_BotFrame(), SV_CalcPings(), SV_CheckPaused(), SV_CheckTimeouts(), sv_fps, sv_killserver, SV_MasterHeartbeat(), SV_SendClientMessages(), SV_SetConfigstring(), SV_Shutdown(), svs, Sys_Milliseconds(), serverStatic_t::time, time_game, server_t::timeResidual, and VM_Call(). Referenced by CL_Connect_f(), and Com_Frame(). 00751 {
00752 int frameMsec;
00753 int startTime;
00754
00755 // the menu kills the server with this cvar
00756 if ( sv_killserver->integer ) {
00757 SV_Shutdown ("Server was killed.\n");
00758 Cvar_Set( "sv_killserver", "0" );
00759 return;
00760 }
00761
00762 if ( !com_sv_running->integer ) {
00763 return;
00764 }
00765
00766 // allow pause if only the local client is connected
00767 if ( SV_CheckPaused() ) {
00768 return;
00769 }
00770
00771 // if it isn't time for the next frame, do nothing
00772 if ( sv_fps->integer < 1 ) {
00773 Cvar_Set( "sv_fps", "10" );
00774 }
00775 frameMsec = 1000 / sv_fps->integer ;
00776
00777 sv.timeResidual += msec;
00778
00779 if (!com_dedicated->integer) SV_BotFrame( svs.time + sv.timeResidual );
00780
00781 if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
00782 // NET_Sleep will give the OS time slices until either get a packet
00783 // or time enough for a server frame has gone by
00784 NET_Sleep(frameMsec - sv.timeResidual);
00785 return;
00786 }
00787
00788 // if time is about to hit the 32nd bit, kick all clients
00789 // and clear sv.time, rather
00790 // than checking for negative time wraparound everywhere.
00791 // 2giga-milliseconds = 23 days, so it won't be too often
00792 if ( svs.time > 0x70000000 ) {
00793 SV_Shutdown( "Restarting server due to time wrapping" );
00794 Cbuf_AddText( "vstr nextmap\n" );
00795 return;
00796 }
00797 // this can happen considerably earlier when lots of clients play and the map doesn't change
00798 if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) {
00799 SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" );
00800 Cbuf_AddText( "vstr nextmap\n" );
00801 return;
00802 }
00803
00804 if( sv.restartTime && svs.time >= sv.restartTime ) {
00805 sv.restartTime = 0;
00806 Cbuf_AddText( "map_restart 0\n" );
00807 return;
00808 }
00809
00810 // update infostrings if anything has been changed
00811 if ( cvar_modifiedFlags & CVAR_SERVERINFO ) {
00812 SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
00813 cvar_modifiedFlags &= ~CVAR_SERVERINFO;
00814 }
00815 if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) {
00816 SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) );
00817 cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
00818 }
00819
00820 if ( com_speeds->integer ) {
00821 startTime = Sys_Milliseconds ();
00822 } else {
00823 startTime = 0; // quite a compiler warning
00824 }
00825
00826 // update ping based on the all received frames
00827 SV_CalcPings();
00828
00829 if (com_dedicated->integer) SV_BotFrame( svs.time );
00830
00831 // run the game simulation in chunks
00832 while ( sv.timeResidual >= frameMsec ) {
00833 sv.timeResidual -= frameMsec;
00834 svs.time += frameMsec;
00835
00836 // let everything in the world think and move
00837 VM_Call( gvm, GAME_RUN_FRAME, svs.time );
00838 }
00839
00840 if ( com_speeds->integer ) {
00841 time_game = Sys_Milliseconds () - startTime;
00842 }
00843
00844 // check timeouts
00845 SV_CheckTimeouts();
00846
00847 // send messages back to the clients
00848 SV_SendClientMessages();
00849
00850 // send a heartbeat to the master if needed
00851 SV_MasterHeartbeat();
00852 }
|
Here is the call graph for this function:

|
|
Definition at line 216 of file sv_main.c. References BigShort(), com_dedicated, Com_Printf(), Cvar_Set(), HEARTBEAT_GAME, i, cvar_s::integer, cvar_s::modified, name, NET_OutOfBandPrint(), NET_StringToAdr(), serverStatic_t::nextHeartbeatTime, NS_SERVER, netadr_t::port, PORT_MASTER, string(), cvar_s::string, strstr(), sv_master, svs, and serverStatic_t::time. Referenced by SV_Frame(), and SV_MasterShutdown(). 00216 {
00217 static netadr_t adr[MAX_MASTER_SERVERS];
00218 int i;
00219
00220 // "dedicated 1" is for lan play, "dedicated 2" is for inet public play
00221 if ( !com_dedicated || com_dedicated->integer != 2 ) {
00222 return; // only dedicated servers send heartbeats
00223 }
00224
00225 // if not time yet, don't send anything
00226 if ( svs.time < svs.nextHeartbeatTime ) {
00227 return;
00228 }
00229 svs.nextHeartbeatTime = svs.time + HEARTBEAT_MSEC;
00230
00231
00232 // send to group masters
00233 for ( i = 0 ; i < MAX_MASTER_SERVERS ; i++ ) {
00234 if ( !sv_master[i]->string[0] ) {
00235 continue;
00236 }
00237
00238 // see if we haven't already resolved the name
00239 // resolving usually causes hitches on win95, so only
00240 // do it when needed
00241 if ( sv_master[i]->modified ) {
00242 sv_master[i]->modified = qfalse;
00243
00244 Com_Printf( "Resolving %s\n", sv_master[i]->string );
00245 if ( !NET_StringToAdr( sv_master[i]->string, &adr[i] ) ) {
00246 // if the address failed to resolve, clear it
00247 // so we don't take repeated dns hits
00248 Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string );
00249 Cvar_Set( sv_master[i]->name, "" );
00250 sv_master[i]->modified = qfalse;
00251 continue;
00252 }
00253 if ( !strstr( ":", sv_master[i]->string ) ) {
00254 adr[i].port = BigShort( PORT_MASTER );
00255 }
00256 Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", sv_master[i]->string,
00257 adr[i].ip[0], adr[i].ip[1], adr[i].ip[2], adr[i].ip[3],
00258 BigShort( adr[i].port ) );
00259 }
00260
00261
00262 Com_Printf ("Sending heartbeat to %s\n", sv_master[i]->string );
00263 // this command should be changed if the server info / status format
00264 // ever incompatably changes
00265 NET_OutOfBandPrint( NS_SERVER, adr[i], "heartbeat %s\n", HEARTBEAT_GAME );
00266 }
00267 }
|
Here is the call graph for this function:

|
|
Definition at line 276 of file sv_main.c. References serverStatic_t::nextHeartbeatTime, SV_MasterHeartbeat(), and svs. Referenced by SV_Shutdown(). 00276 {
00277 // send a hearbeat right now
00278 svs.nextHeartbeatTime = -9999;
00279 SV_MasterHeartbeat();
00280
00281 // send it again to minimize chance of drops
00282 svs.nextHeartbeatTime = -9999;
00283 SV_MasterHeartbeat();
00284
00285 // when the master tries to poll the server, it won't respond, so
00286 // it will be removed from the list
00287 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 548 of file sv_main.c. References cl, client_t, serverStatic_t::clients, Com_Printf(), msg_t::cursize, msg_t::data, i, cvar_s::integer, MSG_BeginReadingOOB(), MSG_ReadLong(), MSG_ReadShort(), NET_CompareBaseAdr(), NET_OutOfBandPrint(), NS_SERVER, netadr_t::port, qport, SV_ConnectionlessPacket(), SV_ExecuteClientMessage(), sv_maxclients, SV_Netchan_Process(), svs, and serverStatic_t::time. Referenced by Com_RunAndTimeServerPacket(). 00548 {
00549 int i;
00550 client_t *cl;
00551 int qport;
00552
00553 // check for connectionless packet (0xffffffff) first
00554 if ( msg->cursize >= 4 && *(int *)msg->data == -1) {
00555 SV_ConnectionlessPacket( from, msg );
00556 return;
00557 }
00558
00559 // read the qport out of the message so we can fix up
00560 // stupid address translating routers
00561 MSG_BeginReadingOOB( msg );
00562 MSG_ReadLong( msg ); // sequence number
00563 qport = MSG_ReadShort( msg ) & 0xffff;
00564
00565 // find which client the message is from
00566 for (i=0, cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++) {
00567 if (cl->state == CS_FREE) {
00568 continue;
00569 }
00570 if ( !NET_CompareBaseAdr( from, cl->netchan.remoteAddress ) ) {
00571 continue;
00572 }
00573 // it is possible to have multiple clients from a single IP
00574 // address, so they are differentiated by the qport variable
00575 if (cl->netchan.qport != qport) {
00576 continue;
00577 }
00578
00579 // the IP port can't be used to differentiate them, because
00580 // some address translating routers periodically change UDP
00581 // port assignments
00582 if (cl->netchan.remoteAddress.port != from.port) {
00583 Com_Printf( "SV_PacketEvent: fixing up a translated port\n" );
00584 cl->netchan.remoteAddress.port = from.port;
00585 }
00586
00587 // make sure it is a valid, in sequence packet
00588 if (SV_Netchan_Process(cl, msg)) {
00589 // zombie clients still need to do the Netchan_Process
00590 // to make sure they don't need to retransmit the final
00591 // reliable message, but they don't do any other processing
00592 if (cl->state != CS_ZOMBIE) {
00593 cl->lastPacketTime = svs.time; // don't timeout
00594 SV_ExecuteClientMessage( cl, msg );
00595 }
00596 }
00597 return;
00598 }
00599
00600 // if we received a sequenced packet from an address we don't recognize,
00601 // send an out of band disconnect packet to it
00602 NET_OutOfBandPrint( NS_SERVER, from, "disconnect" );
00603 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 97 of file sv_main.c. References client_t, i, MAX_RELIABLE_COMMANDS, Q_strncmp(), Q_strncpyz(), client_s::reliableCommands, client_s::reliableSent, client_s::reliableSequence, sscanf(), and strlen(). 00097 {
00098 int i, index, csnum1, csnum2;
00099
00100 for ( i = client->reliableSent+1; i <= client->reliableSequence; i++ ) {
00101 index = i & ( MAX_RELIABLE_COMMANDS - 1 );
00102 //
00103 if ( !Q_strncmp(cmd, client->reliableCommands[ index ], strlen("cs")) ) {
00104 sscanf(cmd, "cs %i", &csnum1);
00105 sscanf(client->reliableCommands[ index ], "cs %i", &csnum2);
00106 if ( csnum1 == csnum2 ) {
00107 Q_strncpyz( client->reliableCommands[ index ], cmd, sizeof( client->reliableCommands[ index ] ) );
00108 /*
00109 if ( client->netchan.remoteAddress.type != NA_BOT ) {
00110 Com_Printf( "WARNING: client %i removed double pending config string %i: %s\n", client-svs.clients, csnum1, cmd );
00111 }
00112 */
00113 return qtrue;
00114 }
00115 }
00116 }
00117 return qfalse;
00118 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 165 of file sv_main.c. References byte, cl, client_t, serverStatic_t::clients, com_dedicated, Com_Printf(), cvar_s::integer, j, Q_vsnprintf, QDECL, client_s::state, strncmp(), SV_AddServerCommand(), SV_ExpandNewlines(), sv_maxclients, svs, va_end, va_list, and va_start. Referenced by SV_Ban_f(), SV_BanNum_f(), SV_ConSay_f(), SV_DropClient(), SV_FinalMessage(), SV_GameSendServerCommand(), SV_Kick_f(), SV_KickNum_f(), and SV_SetConfigstring(). 00165 {
00166 va_list argptr;
00167 byte message[MAX_MSGLEN];
00168 client_t *client;
00169 int j;
00170
00171 va_start (argptr,fmt);
00172 Q_vsnprintf ((char *)message, sizeof(message), fmt,argptr);
00173 va_end (argptr);
00174
00175 if ( cl != NULL ) {
00176 SV_AddServerCommand( cl, (char *)message );
00177 return;
00178 }
00179
00180 // hack to echo broadcast prints to console
00181 if ( com_dedicated->integer && !strncmp( (char *)message, "print", 5) ) {
00182 Com_Printf ("broadcast: %s\n", SV_ExpandNewlines((char *)message) );
00183 }
00184
00185 // send the data to all relevent clients
00186 for (j = 0, client = svs.clients; j < sv_maxclients->integer ; j++, client++) {
00187 if ( client->state < CS_PRIMED ) {
00188 continue;
00189 }
00190 SV_AddServerCommand( client, (char *)message );
00191 }
00192 }
|
Here is the call graph for this function:

|
|
Definition at line 366 of file sv_main.c. References serverStatic_t::clients, Cmd_Argv(), count, Cvar_VariableString(), Cvar_VariableValue(), gamedir, GT_SINGLE_PLAYER, i, Info_SetValueForKey(), cvar_s::integer, NET_OutOfBandPrint(), NS_SERVER, PROTOCOL_VERSION, client_s::state, cvar_s::string, sv_gametype, sv_hostname, sv_mapname, sv_maxclients, sv_maxPing, sv_minPing, sv_privateClients, sv_pure, svs, and va(). Referenced by SV_ConnectionlessPacket(). 00366 {
00367 int i, count;
00368 char *gamedir;
00369 char infostring[MAX_INFO_STRING];
00370
00371 // ignore if we are in single player
00372 if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
00373 return;
00374 }
00375
00376 // don't count privateclients
00377 count = 0;
00378 for ( i = sv_privateClients->integer ; i < sv_maxclients->integer ; i++ ) {
00379 if ( svs.clients[i].state >= CS_CONNECTED ) {
00380 count++;
00381 }
00382 }
00383
00384 infostring[0] = 0;
00385
00386 // echo back the parameter to status. so servers can use it as a challenge
00387 // to prevent timed spoofed reply packets that add ghost servers
00388 Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) );
00389
00390 Info_SetValueForKey( infostring, "protocol", va("%i", PROTOCOL_VERSION) );
00391 Info_SetValueForKey( infostring, "hostname", sv_hostname->string );
00392 Info_SetValueForKey( infostring, "mapname", sv_mapname->string );
00393 Info_SetValueForKey( infostring, "clients", va("%i", count) );
00394 Info_SetValueForKey( infostring, "sv_maxclients",
00395 va("%i", sv_maxclients->integer - sv_privateClients->integer ) );
00396 Info_SetValueForKey( infostring, "gametype", va("%i", sv_gametype->integer ) );
00397 Info_SetValueForKey( infostring, "pure", va("%i", sv_pure->integer ) );
00398
00399 if( sv_minPing->integer ) {
00400 Info_SetValueForKey( infostring, "minPing", va("%i", sv_minPing->integer) );
00401 }
00402 if( sv_maxPing->integer ) {
00403 Info_SetValueForKey( infostring, "maxPing", va("%i", sv_maxPing->integer) );
00404 }
00405 gamedir = Cvar_VariableString( "fs_game" );
00406 if( *gamedir ) {
00407 Info_SetValueForKey( infostring, "game", gamedir );
00408 }
00409
00410 NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
00411 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 432 of file sv_main.c. References Cmd_Argv(), Cmd_Cmd(), Cmd_ExecuteString(), Com_BeginRedirect(), Com_EndRedirect(), Com_Milliseconds(), Com_Printf(), NET_AdrToString(), Q_strcat(), qboolean, serverStatic_t::redirectAddress, strcmp(), cvar_s::string, strlen(), SV_FlushRedirect(), SV_OUTPUTBUF_LENGTH, sv_rconPassword, svs, and time(). Referenced by SV_ConnectionlessPacket(). 00432 {
00433 qboolean valid;
00434 unsigned int time;
00435 char remaining[1024];
00436 // TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
00437 // (OOB messages are the bottleneck here)
00438 #define SV_OUTPUTBUF_LENGTH (1024 - 16)
00439 char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
00440 static unsigned int lasttime = 0;
00441 char *cmd_aux;
00442
00443 // TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534
00444 time = Com_Milliseconds();
00445 if (time<(lasttime+500)) {
00446 return;
00447 }
00448 lasttime = time;
00449
00450 if ( !strlen( sv_rconPassword->string ) ||
00451 strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
00452 valid = qfalse;
00453 Com_Printf ("Bad rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
00454 } else {
00455 valid = qtrue;
00456 Com_Printf ("Rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
00457 }
00458
00459 // start redirecting all print outputs to the packet
00460 svs.redirectAddress = from;
00461 Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);
00462
00463 if ( !strlen( sv_rconPassword->string ) ) {
00464 Com_Printf ("No rconpassword set on the server.\n");
00465 } else if ( !valid ) {
00466 Com_Printf ("Bad rconpassword.\n");
00467 } else {
00468 remaining[0] = 0;
00469
00470 // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543
00471 // get the command directly, "rcon <pass> <command>" to avoid quoting issues
00472 // extract the command by walking
00473 // since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
00474 cmd_aux = Cmd_Cmd();
00475 cmd_aux+=4;
00476 while(cmd_aux[0]==' ')
00477 cmd_aux++;
00478 while(cmd_aux[0] && cmd_aux[0]!=' ') // password
00479 cmd_aux++;
00480 while(cmd_aux[0]==' ')
00481 cmd_aux++;
00482
00483 Q_strcat( remaining, sizeof(remaining), cmd_aux);
00484
00485 Cmd_ExecuteString (remaining);
00486
00487 }
00488
00489 Com_EndRedirect ();
00490 }
|
Here is the call graph for this function:

|
|
Definition at line 307 of file sv_main.c. References cl, client_t, serverStatic_t::clients, Cmd_Argv(), Com_sprintf(), Cvar_InfoString(), CVAR_SERVERINFO, Cvar_VariableValue(), i, Info_SetValueForKey(), Info_ValueForKey(), cvar_s::integer, NET_OutOfBandPrint(), NS_SERVER, PERS_SCORE, playerState_s::persistant, playerState_t, strcpy(), strlen(), SV_GameClientNum(), sv_maxclients, and svs. Referenced by SV_ConnectionlessPacket(). 00307 {
00308 char player[1024];
00309 char status[MAX_MSGLEN];
00310 int i;
00311 client_t *cl;
00312 playerState_t *ps;
00313 int statusLength;
00314 int playerLength;
00315 char infostring[MAX_INFO_STRING];
00316
00317 // ignore if we are in single player
00318 if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER ) {
00319 return;
00320 }
00321
00322 strcpy( infostring, Cvar_InfoString( CVAR_SERVERINFO ) );
00323
00324 // echo back the parameter to status. so master servers can use it as a challenge
00325 // to prevent timed spoofed reply packets that add ghost servers
00326 Info_SetValueForKey( infostring, "challenge", Cmd_Argv(1) );
00327
00328 // add "demo" to the sv_keywords if restricted
00329 if ( Cvar_VariableValue( "fs_restrict" ) ) {
00330 char keywords[MAX_INFO_STRING];
00331
00332 Com_sprintf( keywords, sizeof( keywords ), "demo %s",
00333 Info_ValueForKey( infostring, "sv_keywords" ) );
00334 Info_SetValueForKey( infostring, "sv_keywords", keywords );
00335 }
00336
00337 status[0] = 0;
00338 statusLength = 0;
00339
00340 for (i=0 ; i < sv_maxclients->integer ; i++) {
00341 cl = &svs. |