void Irc_Connect_f( void ) { const int argc = Cmd_Argc(); if( argc <= 3 ) { if( !irc_libhandle ) Irc_LoadLibrary(); // load IRC library if not already loaded if( irc_libhandle ) { // library loaded, check for connection status bool *c; if( !irc_server ) irc_server = Cvar_Get( "irc_server", "irc.quakenet.org", CVAR_ARCHIVE ); if( !irc_connected ) irc_connected = Dynvar_Lookup( "irc_connected" ); assert( irc_server ); assert( irc_connected ); Dynvar_GetValue( irc_connected, (void **) &c ); if( !*c ) { // not connected yet if( argc >= 2 ) Cvar_Set( "irc_server", Cmd_Argv( 1 ) ); if( argc >= 3 ) Cvar_Set( "irc_port", Cmd_Argv( 2 ) ); Dynvar_AddListener( irc_connected, Irc_ConnectedListener_f ); irc_export->Connect(); Dynvar_GetValue( irc_connected, (void **) &c ); if( *c ) { irc_wakelock = Sys_AcquireWakeLock(); } else { // connect failed Com_Printf( "Could not connect to %s (%s).\n", Cvar_GetStringValue( irc_server ), irc_export->ERROR_MSG ); Dynvar_RemoveListener( irc_connected, Irc_ConnectedListener_f ); } } else Com_Printf( "Already connected.\n" ); } } else Com_Printf( "usage: irc_connect [<server>] [<port>]" ); }
/* * SV_InitGame * A brand new game has been started */ void SV_InitGame( void ) { int i; edict_t *ent; netadr_t address, ipv6_address; bool socket_opened = false; // make sure the client is down CL_Disconnect( NULL ); SCR_BeginLoadingPlaque(); if( svs.initialized ) { // cause any connected clients to reconnect SV_ShutdownGame( "Server restarted", true ); // SV_ShutdownGame will also call Cvar_GetLatchedVars } else { // get any latched variable changes (sv_maxclients, etc) Cvar_GetLatchedVars( CVAR_LATCH ); } svs.initialized = true; if( sv_skilllevel->integer > 2 ) { Cvar_ForceSet( "sv_skilllevel", "2" ); } if( sv_skilllevel->integer < 0 ) { Cvar_ForceSet( "sv_skilllevel", "0" ); } // init clients if( sv_maxclients->integer < 1 ) { Cvar_FullSet( "sv_maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH, true ); } else if( sv_maxclients->integer > MAX_CLIENTS ) { Cvar_FullSet( "sv_maxclients", va( "%i", MAX_CLIENTS ), CVAR_SERVERINFO | CVAR_LATCH, true ); } svs.spawncount = rand(); svs.clients = Mem_Alloc( sv_mempool, sizeof( client_t ) * sv_maxclients->integer ); svs.client_entities.num_entities = sv_maxclients->integer * UPDATE_BACKUP * MAX_SNAP_ENTITIES; svs.client_entities.entities = Mem_Alloc( sv_mempool, sizeof( entity_state_t ) * svs.client_entities.num_entities ); // init network stuff address.type = NA_NOTRANSMIT; ipv6_address.type = NA_NOTRANSMIT; if( !dedicated->integer ) { NET_InitAddress( &address, NA_LOOPBACK ); if( !NET_OpenSocket( &svs.socket_loopback, SOCKET_LOOPBACK, &address, true ) ) { Com_Error( ERR_FATAL, "Couldn't open loopback socket: %s\n", NET_ErrorString() ); } } if( dedicated->integer || sv_maxclients->integer > 1 ) { // IPv4 NET_StringToAddress( sv_ip->string, &address ); NET_SetAddressPort( &address, sv_port->integer ); if( !NET_OpenSocket( &svs.socket_udp, SOCKET_UDP, &address, true ) ) { Com_Printf( "Error: Couldn't open UDP socket: %s\n", NET_ErrorString() ); } else { socket_opened = true; } // IPv6 NET_StringToAddress( sv_ip6->string, &ipv6_address ); if( ipv6_address.type == NA_IP6 ) { NET_SetAddressPort( &ipv6_address, sv_port6->integer ); if( !NET_OpenSocket( &svs.socket_udp6, SOCKET_UDP, &ipv6_address, true ) ) { Com_Printf( "Error: Couldn't open UDP6 socket: %s\n", NET_ErrorString() ); } else { socket_opened = true; } } else { Com_Printf( "Error: invalid IPv6 address: %s\n", sv_ip6->string ); } } #ifdef TCP_ALLOW_CONNECT if( sv_tcp->integer && ( dedicated->integer || sv_maxclients->integer > 1 ) ) { bool err = true; if( !NET_OpenSocket( &svs.socket_tcp, SOCKET_TCP, &address, true ) ) { Com_Printf( "Error: Couldn't open TCP socket: %s\n", NET_ErrorString() ); } else { NET_SetSocketNoDelay( &svs.socket_tcp, 1 ); if( !NET_Listen( &svs.socket_tcp ) ) { Com_Printf( "Error: Couldn't listen to TCP socket: %s\n", NET_ErrorString() ); NET_CloseSocket( &svs.socket_tcp ); } else { err = false; socket_opened = true; } } if( ipv6_address.type == NA_IP6 ) { if( !NET_OpenSocket( &svs.socket_tcp6, SOCKET_TCP, &ipv6_address, true ) ) { Com_Printf( "Error: Couldn't open TCP6 socket: %s\n", NET_ErrorString() ); } else { NET_SetSocketNoDelay( &svs.socket_tcp6, 1 ); if( !NET_Listen( &svs.socket_tcp6 ) ) { Com_Printf( "Error: Couldn't listen to TCP6 socket: %s\n", NET_ErrorString() ); NET_CloseSocket( &svs.socket_tcp6 ); } else { err = false; socket_opened = true; } } } if( err ) { Cvar_ForceSet( "sv_tcp", "0" ); } } #endif if( dedicated->integer && !socket_opened ) { Com_Error( ERR_FATAL, "Couldn't open any socket\n" ); } // init mm // SV_MM_Init(); // init game SV_InitGameProgs(); for( i = 0; i < sv_maxclients->integer; i++ ) { ent = EDICT_NUM( i + 1 ); ent->s.number = i + 1; svs.clients[i].edict = ent; } // load the map assert( !svs.cms ); svs.cms = CM_New( NULL ); CM_AddReference( svs.cms ); // keep CPU awake assert( !svs.wakelock ); svs.wakelock = Sys_AcquireWakeLock(); }
/* * CL_ParseServerData */ static void CL_ParseServerData( msg_t *msg ) { const char *str, *gamedir; int i, sv_bitflags, numpure; int http_portnum; Com_DPrintf( "Serverdata packet received.\n" ); // wipe the client_state_t struct CL_ClearState(); CL_SetClientState( CA_CONNECTED ); // parse protocol version number i = MSG_ReadLong( msg ); if( i != APP_PROTOCOL_VERSION && !(cls.demo.playing && i == APP_DEMO_PROTOCOL_VERSION) ) Com_Error( ERR_DROP, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION ); cl.servercount = MSG_ReadLong( msg ); cl.snapFrameTime = (unsigned int)MSG_ReadShort( msg ); cl.gamestart = true; // set extrapolation time to half snapshot time Cvar_ForceSet( "cl_extrapolationTime", va( "%i", (unsigned int)( cl.snapFrameTime * 0.5 ) ) ); cl_extrapolationTime->modified = false; // base game directory str = MSG_ReadString( msg ); if( !str || !str[0] ) Com_Error( ERR_DROP, "Server sent an empty base game directory" ); if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) ) Com_Error( ERR_DROP, "Server sent an invalid base game directory: %s", str ); if( strcmp( FS_BaseGameDirectory(), str ) ) { Com_Error( ERR_DROP, "Server has different base game directory (%s) than the client (%s)", str, FS_BaseGameDirectory() ); } // game directory str = MSG_ReadString( msg ); if( !str || !str[0] ) Com_Error( ERR_DROP, "Server sent an empty game directory" ); if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) ) Com_Error( ERR_DROP, "Server sent an invalid game directory: %s", str ); gamedir = FS_GameDirectory(); if( strcmp( str, gamedir ) ) { // shutdown the cgame module first in case it is running for whatever reason // (happens on wswtv in lobby), otherwise precaches that are going to follow // will probably f**k up (like models trying to load before the world model) CL_GameModule_Shutdown(); if( !FS_SetGameDirectory( str, true ) ) Com_Error( ERR_DROP, "Failed to load game directory set by server: %s", str ); ML_Restart( true ); } // parse player entity number cl.playernum = MSG_ReadShort( msg ); // get the full level name Q_strncpyz( cl.servermessage, MSG_ReadString( msg ), sizeof( cl.servermessage ) ); sv_bitflags = MSG_ReadByte( msg ); if( cls.demo.playing ) { cls.reliable = ( sv_bitflags & SV_BITFLAGS_RELIABLE ); } else { if( cls.reliable != ( ( sv_bitflags & SV_BITFLAGS_RELIABLE ) != 0 ) ) Com_Error( ERR_DROP, "Server and client disagree about connection reliability" ); } // builting HTTP server port if( cls.httpbaseurl ) { Mem_Free( cls.httpbaseurl ); cls.httpbaseurl = NULL; } if( ( sv_bitflags & SV_BITFLAGS_HTTP ) != 0 ) { if( ( sv_bitflags & SV_BITFLAGS_HTTP_BASEURL ) != 0 ) { // read base upstream url cls.httpbaseurl = ZoneCopyString( MSG_ReadString( msg ) ); } else { http_portnum = MSG_ReadShort( msg ) & 0xffff; cls.httpaddress = cls.serveraddress; if( cls.httpaddress.type == NA_IP6 ) { cls.httpaddress.address.ipv6.port = BigShort( http_portnum ); } else { cls.httpaddress.address.ipv4.port = BigShort( http_portnum ); } if( http_portnum ) { if( cls.httpaddress.type == NA_LOOPBACK ) { cls.httpbaseurl = ZoneCopyString( va( "http://localhost:%hu/", http_portnum ) ); } else { cls.httpbaseurl = ZoneCopyString( va( "http://%s/", NET_AddressToString( &cls.httpaddress ) ) ); } } } } // pure list // clean old, if necessary Com_FreePureList( &cls.purelist ); // add new numpure = MSG_ReadShort( msg ); while( numpure > 0 ) { const char *pakname = MSG_ReadString( msg ); const unsigned checksum = MSG_ReadLong( msg ); Com_AddPakToPureList( &cls.purelist, pakname, checksum, NULL ); numpure--; } //assert( numpure == 0 ); // get the configstrings request CL_AddReliableCommand( va( "configstrings %i 0", cl.servercount ) ); cls.sv_pure = ( sv_bitflags & SV_BITFLAGS_PURE ) != 0; cls.sv_tv = ( sv_bitflags & SV_BITFLAGS_TVSERVER ) != 0; #ifdef PURE_CHEAT cls.sv_pure = false; #endif cls.wakelock = Sys_AcquireWakeLock(); if( !cls.demo.playing && ( cls.serveraddress.type == NA_IP ) ) Steam_AdvertiseGame( cls.serveraddress.address.ipv4.ip, NET_GetAddressPort( &cls.serveraddress ) ); // separate the printfs so the server message can have a color Com_Printf( S_COLOR_WHITE "\n" "=====================================\n" ); Com_Printf( S_COLOR_WHITE "%s\n\n", cl.servermessage ); }