/* ================== SV_BanNum_f Ban a user from being able to play on this server through the auth server ================== */ static void SV_BanNum_f( void ) { client_t *cl; // make sure server is running if ( !com_sv_running->integer ) { Com_Printf( "Server is not running.\n" ); return; } if ( Cmd_Argc() != 2 ) { Com_Printf ("Usage: banClient <client number>\n"); return; } cl = SV_GetPlayerByNum(); if ( !cl ) { return; } if( cl->netchan.remoteAddress.type == NA_LOOPBACK ) { Com_Printf("Cannot kick host player\n"); return; } // look up the authorize server's IP if ( !svs.authorizeAddress.ip[0] && svs.authorizeAddress.type != NA_BAD ) { Com_Printf( "Resolving %s\n", AUTHORIZE_SERVER_NAME ); if ( !NET_StringToAdr( AUTHORIZE_SERVER_NAME, &svs.authorizeAddress, NA_IP ) ) { Com_Printf( "Couldn't resolve address\n" ); return; } svs.authorizeAddress.port = BigShort( PORT_AUTHORIZE ); Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", AUTHORIZE_SERVER_NAME, svs.authorizeAddress.ip[0], svs.authorizeAddress.ip[1], svs.authorizeAddress.ip[2], svs.authorizeAddress.ip[3], BigShort( svs.authorizeAddress.port ) ); } // otherwise send their ip to the authorize server if ( svs.authorizeAddress.type != NA_BAD ) { NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress, "banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1], cl->netchan.remoteAddress.ip[2], cl->netchan.remoteAddress.ip[3] ); Com_Printf("%s was banned from coming back\n", cl->name); } }
const char *NET_AdrToString (netadr_t a) { static char s[64]; if (a.type == NA_LOOPBACK) { Com_sprintf (s, sizeof(s), "loopback"); } else if (a.type == NA_BOT) { Com_sprintf (s, sizeof(s), "bot"); } else if (a.type == NA_IP) { Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%hu", a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port)); } else { Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x.%02x%02x%02x%02x%02x%02x:%hu", a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9], BigShort(a.port)); } return s; }
qbool NET_SendTCPPacket_SV (netsrc_t netsrc, int length, void *data, netadr_t to) { svtcpstream_t *st; if (netsrc != NS_SERVER) return false; for (st = svs.tcpstreams; st; st = st->next) { if (st->socketnum == INVALID_SOCKET) continue; if (NET_CompareAdr(to, st->remoteaddr)) { int sent; unsigned short slen = BigShort((unsigned short)length); if (st->outlen + length + sizeof(slen) >= sizeof(st->outbuffer)) { // not enough space, we overflowed break; // well, quake should resist to some packet lost.. so we just drop that packet. } // put data in buffer memmove(st->outbuffer + st->outlen, (char*)&slen, sizeof(slen)); st->outlen += sizeof(slen); memmove(st->outbuffer + st->outlen, data, length); st->outlen += length; sent = send(st->socketnum, st->outbuffer, st->outlen, 0); if (sent == 0) { // think it's OK } else if (sent > 0) //we put some data through { //move up the buffer st->outlen -= sent; memmove(st->outbuffer, st->outbuffer + sent, st->outlen); } else { //error of some kind. would block or something if (qerrno != EWOULDBLOCK && qerrno != EAGAIN) { st->drop = true; // something cricial, drop than } } break; } } // 'st' will be not zero, if we found 'to' in 'svs.tcpstreams'. // That does not mean we actualy send packet, since there case of overflow, but who cares, // all is matter that we found such 'to' and tried to send packet. return !!st; }
/* ================= SV_MasterGameCompleteStatus NERVE - SMF - Sends gameCompleteStatus messages to all master servers ================= */ void SV_MasterGameCompleteStatus() { static netadr_t adr[MAX_MASTER_SERVERS]; int i; // "dedicated 1" is for lan play, "dedicated 2" is for inet public play if ( !com_dedicated || com_dedicated->integer != 2 ) { return; // only dedicated servers send master game status } // send to group masters for ( i = 0 ; i < MAX_MASTER_SERVERS ; i++ ) { if ( !sv_master[i]->string[0] ) { continue; } // see if we haven't already resolved the name // resolving usually causes hitches on win95, so only // do it when needed if ( sv_master[i]->modified ) { sv_master[i]->modified = qfalse; Com_Printf( "Resolving %s\n", sv_master[i]->string ); if ( !NET_StringToAdr( sv_master[i]->string, &adr[i] ) ) { // if the address failed to resolve, clear it // so we don't take repeated dns hits Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string ); Cvar_Set( sv_master[i]->name, "" ); sv_master[i]->modified = qfalse; continue; } if ( !strstr( ":", sv_master[i]->string ) ) { adr[i].port = BigShort( PORT_MASTER ); } Com_Printf( "%s resolved to %i.%i.%i.%i:%i\n", sv_master[i]->string, adr[i].ip[0], adr[i].ip[1], adr[i].ip[2], adr[i].ip[3], BigShort( adr[i].port ) ); } Com_Printf( "Sending gameCompleteStatus to %s\n", sv_master[i]->string ); // this command should be changed if the server info / status format // ever incompatably changes SVC_GameCompleteStatus( adr[i] ); } }
/* * NET_CompareAddress * * Compares with the port */ qboolean NET_CompareAddress( const netadr_t *a, const netadr_t *b ) { if( a->type != b->type ) return qfalse; switch( a->type ) { case NA_LOOPBACK: return qtrue; case NA_IP: { const netadr_ipv4_t *addr1 = &a->address.ipv4; const netadr_ipv4_t *addr2 = &b->address.ipv4; if( addr1->ip[0] == addr2->ip[0] && addr1->ip[1] == addr2->ip[1] && addr1->ip[2] == addr2->ip[2] && addr1->ip[3] == addr2->ip[3] && BigShort( addr1->port ) == BigShort( addr2->port ) ) { return qtrue; } return qfalse; } case NA_IP6: { const netadr_ipv6_t *addr1 = &a->address.ipv6; const netadr_ipv6_t *addr2 = &b->address.ipv6; if( memcmp( addr1->ip, addr2->ip, sizeof( addr1->ip ) ) == 0 && addr1->scope_id == addr2->scope_id && BigShort( addr1->port ) == BigShort( addr2->port ) ) { return qtrue; } return qfalse; } default: assert( qfalse ); return qfalse; } }
//----------------------------------------------------------------------------- // Returns information about the PSD file //----------------------------------------------------------------------------- bool PSDGetInfo( CUtlBuffer &buf, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma ) { int nGet = buf.TellGet(); PSDHeader_t header; buf.Get( &header, sizeof(header) ); buf.SeekGet( CUtlBuffer::SEEK_HEAD, nGet ); if ( BigLong( header.m_nSignature ) != PSD_SIGNATURE ) return false; if ( BigShort( header.m_nVersion ) != 1 ) return false; if ( BigShort( header.m_nDepth ) != 8 ) return false; *pWidth = BigLong( header.m_nColumns ); *pHeight = BigLong( header.m_nRows ); *pImageFormat = BigShort( header.m_nChannels ) == 3 ? IMAGE_FORMAT_RGB888 : IMAGE_FORMAT_RGBA8888; *pSourceGamma = ARTWORK_GAMMA; return true; }
static char *FChecks_FServerResponse_Text(void) { netadr_t adr; if (!NET_StringToAdr (cls.servername, &adr)) return NULL; if (adr.port == 0) adr.port = BigShort (PORT_SERVER); return NET_AdrToString(adr); }
PSDImageResources::ResElement PSDImageResources::FindElement( Resource eType ) const { ResElement res; memset( &res, 0, sizeof( res ) ); unsigned char const *pvBuffer = m_pvBuffer, * const pvBufferEnd = m_pvBuffer + m_numBytes; while ( pvBuffer < pvBufferEnd ) { // 4 : signature // 2 : type // 4 : reserved // 2 : length // bytes[ length ] unsigned long uSignature = BigLong( *( unsigned long * )( pvBuffer ) ); pvBuffer += 4; if ( uSignature != PSD_IMGRES_SIGNATURE ) break; unsigned short uType = BigShort( *( unsigned short * )( pvBuffer ) ); pvBuffer += 6; unsigned short uLength = BigShort( *( unsigned short * )( pvBuffer ) ); pvBuffer += 2; if ( uType == eType ) { res.m_eType = eType; res.m_numBytes = uLength; res.m_pvData = pvBuffer; break; } else { pvBuffer += ( ( uLength + 1 ) &~1 ); } } return res; }
/* ============= NET_StringToAdr Traps "localhost" for loopback, passes everything else to system ============= */ qboolean NET_StringToAdr( const char *s, netadr_t *a ) { qboolean r; char base[MAX_STRING_CHARS]; char *port; if (!strcmp (s, "localhost")) { Com_Memset (a, 0, sizeof(*a)); a->type = NA_LOOPBACK; return qtrue; } // look for a port number Q_strncpyz( base, s, sizeof( base ) ); port = strstr( base, ":" ); if ( port ) { *port = 0; port++; } r = Sys_StringToAdr( base, a ); if ( !r ) { a->type = NA_BAD; return qfalse; } // inet_addr returns this if out of range if ( a->ip[0] == 255 && a->ip[1] == 255 && a->ip[2] == 255 && a->ip[3] == 255 ) { a->type = NA_BAD; return qfalse; } if ( port ) { a->port = BigShort( (short)atoi( port ) ); } else { a->port = BigShort( PORT_SERVER ); } return qtrue; }
/* * Send the rest of the command line over as * an unconnected command. */ void CL_Rcon_f(void) { char message[1024]; int i; netadr_t to; if (!rcon_client_password->string) { Com_Printf("You must set 'rcon_password' before\n" "issuing an rcon command.\n"); return; } memset(&to, 0, sizeof(to)); message[0] = (char) 255; message[1] = (char) 255; message[2] = (char) 255; message[3] = (char) 255; message[4] = 0; NET_Config(true); /* allow remote */ strcat(message, "rcon "); strcat(message, rcon_client_password->string); strcat(message, " "); for (i = 1; i < Cmd_Argc(); i++) { strcat(message, Cmd_Argv(i)); strcat(message, " "); } if (cls.state >= ca_connected) { to = cls.netchan.remote_address; } else { if (!strlen(rcon_address->string)) { Com_Printf("You must either be connected,\n" "or set the 'rcon_address' cvar\n" "to issue rcon commands\n"); return; } NET_StringToAdr(rcon_address->string, &to); if (to.port == 0) { to.port = BigShort(PORT_SERVER); } } NET_SendPacket(NS_CLIENT, strlen(message) + 1, message, to); }
/* * Specify a list of master servers */ void SV_SetMaster_f(void) { int i, slot; /* only dedicated servers send heartbeats */ if (!dedicated->value) { Com_Printf("Only dedicated servers use masters.\n"); return; } /* make sure the server is listed public */ Cvar_Set("public", "1"); for (i = 1; i < MAX_MASTERS; i++) { memset(&master_adr[i], 0, sizeof(master_adr[i])); } slot = 1; /* slot 0 will always contain the id master */ for (i = 1; i < Cmd_Argc(); i++) { if (slot == MAX_MASTERS) { break; } if (!NET_StringToAdr(Cmd_Argv(i), &master_adr[i])) { Com_Printf("Bad address: %s\n", Cmd_Argv(i)); continue; } if (master_adr[slot].port == 0) { master_adr[slot].port = BigShort(PORT_MASTER); } Com_Printf("Master server at %s\n", NET_AdrToString(master_adr[slot])); Com_Printf("Sending a ping.\n"); Netchan_OutOfBandPrint(NS_SERVER, master_adr[slot], "ping"); slot++; } svs.last_heartbeat = -9999999; }
PSDResFileInfo::ResFileInfoElement PSDResFileInfo::FindElement( ResFileInfo eType ) const { ResFileInfoElement res; memset( &res, 0, sizeof( res ) ); unsigned char const *pvBuffer = m_res.m_pvData, * const pvBufferEnd = pvBuffer + m_res.m_numBytes; while ( pvBuffer < pvBufferEnd ) { // 2 : = 0x1C02 // 1 : type // 2 : length // bytes[ length ] unsigned short uResLabel = BigShort( *( unsigned short * )( pvBuffer ) ); pvBuffer += 2; unsigned char uType = *pvBuffer; pvBuffer += 1; unsigned short uLength = BigShort( *( unsigned short * )( pvBuffer ) ); pvBuffer += 2; if ( uType == eType && uResLabel == 0x1C02 ) { res.m_eType = eType; res.m_numBytes = uLength; res.m_pvData = pvBuffer; break; } else { pvBuffer += uLength; } } return res; }
/* CL_SendConnectPacket called by CL_Connect_f and CL_CheckResend */ void CL_SendConnectPacket (void) { netadr_t adr; char data[2048]; double t1, t2; // JACK: Fixed bug where DNS lookups would cause two connects real fast // Now, adds lookup time to the connect time. // Should I add it to realtime instead?!?! if (cls.state != ca_disconnected) return; t1 = Sys_DoubleTime (); if (!NET_StringToAdr (cls.servername, &adr)) { Con_Printf ("Bad server address\n"); connect_time = -1; return; } if (!NET_IsClientLegal (&adr)) { Con_Printf ("Illegal server address\n"); connect_time = -1; return; } if (adr.port == 0) adr.port = BigShort (27500); t2 = Sys_DoubleTime (); connect_time = realtime + t2 - t1; // for retransmit requests cls.qport = Cvar_VariableValue ("qport"); // Arrgh, this was not in the old binary only release, and eats up // far too much of the 196 chars in the userinfo space, leaving nothing // for player use, thus, its commented out for the moment.. // // Info_SetValueForStarKey (cls.userinfo, "*ip", NET_AdrToString(adr), // MAX_INFO_STRING); // Con_Printf ("Connecting to %s...\n", cls.servername); snprintf (data, sizeof (data), "%c%c%c%cconnect %i %i %i \"%s\"\n", 255, 255, 255, 255, PROTOCOL_VERSION, cls.qport, cls.challenge, cls.userinfo); NET_SendPacket (strlen (data), data, adr); }
static void ping_broadcast (void) { netadr_t adr; char buff[256]; cvar_t *noudp; cvar_t *noipx; NET_Config(true); // allow remote Com_DPrintf("Pinging broadcast...\n"); noudp = Cvar_Get("noudp", "0", CVAR_NOSET); noipx = Cvar_Get("noipx", "1", CVAR_NOSET); m_serverPingSartTime = Sys_Milliseconds(); if (!noudp->value) { int i; // Scan the LAN for multiple IP's for (i = PORT_SERVER; i <= PORT_SERVER_MAX; i++) // jitLAN { adr.type = NA_BROADCAST; adr.port = BigShort(i); sprintf(buff, "info %i", PROTOCOL_VERSION); Netchan_OutOfBandPrint(NS_CLIENT, adr, buff); } } if (!noipx->value) { adr.type = NA_BROADCAST_IPX; adr.port = BigShort(PORT_SERVER); sprintf(buff, "info %i", PROTOCOL_VERSION); Netchan_OutOfBandPrint(NS_CLIENT, adr, buff); } }
// Reads the next chunk in the block. Returns true if successful and // returns false if it ran out of input data. bool UncompressBlock() { if(Stream.CFlags & 1) { // Check to see if we have enough input if(Stream.AvailIn < 2) return false; Stream.AvailIn -= 2; WORD pos = BigShort(*(WORD*)Stream.In); BYTE len = (pos & 0xF)+1; pos >>= 4; Stream.In += 2; if(len == 1) { // We've reached the end of the stream. Stream.State = STREAM_FINAL; return true; } const BYTE* copyStart = Stream.InternalBuffer-pos-1; // Complete overlap: Single byte repeated if(pos == 0) memset(Stream.InternalBuffer, *copyStart, len); // No overlap: One copy else if(pos >= len) memcpy(Stream.InternalBuffer, copyStart, len); else { // Partial overlap: Copy in 2 or 3 chunks. do { unsigned int copy = MIN<unsigned int>(len, pos+1); memcpy(Stream.InternalBuffer, copyStart, copy); Stream.InternalBuffer += copy; Stream.InternalOut += copy; len -= copy; pos += copy; // Increase our position since we can copy twice as much the next round. } while(len); } Stream.InternalOut += len; Stream.InternalBuffer += len; } else {
/* * Cl_Servers_f */ void Cl_Servers_f(void) { net_addr_t addr; if (!Net_StringToNetaddr(IP_MASTER, &addr)) { Com_Print("Failed to resolve %s\n", IP_MASTER); return; } Com_Print("Refreshing servers.\n"); addr.type = NA_IP; addr.port = (unsigned short) BigShort(PORT_MASTER); Netchan_OutOfBandPrint(NS_CLIENT, addr, "getservers"); Cl_SendBroadcast(); }
/* * byteSwapRawSamples * Medar: untested */ static void byteSwapRawSamples( int samples, int width, int channels, const uint8_t *data ) { int i; if( LittleShort( 256 ) == 256 ) return; if( width != 2 ) return; if( channels == 2 ) samples <<= 1; for( i = 0; i < samples; i++ ) ( (short *)data )[i] = BigShort( ( (short *)data )[i] ); }
static void FTP_GetPassiveAddress(const char* line, netadr_t* adr) { int i, j, port; int numbers[24]; Com_Memset(adr, 0, sizeof(netadr_t)); i = 0; /* Find the start of address */ while(line[i] != '(' && line[i] != '\0') i++; if(line[i] != '(') return; i++; for(j = 0; j < sizeof(numbers); j++) { numbers[j] = atoi(&line[i]); while(line[i] != ',' && line[i] != ')' && line[i] != '\0') i++; if(line[i] == ',') { /* A number delimiter */ i++; }else if(line[i] == ')' && j >= 5){ /* End of address */ adr->type = NA_IP; adr->ip[0] = numbers[0]; adr->ip[1] = numbers[1]; adr->ip[2] = numbers[2]; adr->ip[3] = numbers[3]; port = 256 * numbers[4] + numbers[5]; adr->port = BigShort(port); return; }else{ /* Something is invalid */ return; } } }
void SV_MasterHeartbeat( void ) { static netadr_t adr[MAX_MASTER_SERVERS]; int i; // "dedicated 1" is for lan play, "dedicated 2" is for inet public play if ( !com_dedicated || com_dedicated->integer != 2 ) { return; // only dedicated servers send heartbeats } // if not time yet, don't send anything if ( svs.time < svs.nextHeartbeatTime ) { return; } svs.nextHeartbeatTime = svs.time + HEARTBEAT_MSEC; // send to group masters for ( i = 0 ; i < MAX_MASTER_SERVERS ; i++ ) { if ( !sv_master[i]->string[0] ) { continue; } // see if we haven't already resolved the name // resolving usually causes hitches on win95, so only // do it when needed if ( sv_master[i]->modified ) { sv_master[i]->modified = qfalse; Com_Printf( "Resolving %s\n", sv_master[i]->string ); if ( !NET_StringToAdr( sv_master[i]->string, &adr[i], NA_UNSPEC ) ) { Com_Printf( "Couldn't resolve address: %s\n", sv_master[i]->string ); continue; } if ( !strchr( sv_master[i]->string, ':' ) ) { adr[i].port = BigShort( PORT_MASTER ); } Com_Printf( "%s resolved to %s\n", sv_master[i]->string, NET_AdrToStringwPort(adr[i])); } Com_Printf ("Sending heartbeat to %s\n", sv_master[i]->string ); // this command should be changed if the server info / status format // ever incompatably changes NET_OutOfBandPrint( NS_SERVER, adr[i], "heartbeat %s\n", HEARTBEAT_GAME ); } }
/* * ============ * PartialIPAddress * * this lets you type only as much of the net address as required, * using the local network components to fill in the rest * ============ */ int NET_PartialIPAddress(const char *in, const netadr_t *myaddr, netadr_t *addr) { char buff[256]; char *b; int ip; int num; int mask; int run; int port; buff[0] = '.'; b = buff; strcpy(buff + 1, in); if (buff[1] == '.') b++; ip = 0; mask = -1; while (*b == '.') { b++; num = 0; run = 0; while (!(*b < '0' || *b > '9')) { num = num * 10 + *b++ - '0'; if (++run > 3) return -1; } if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) return -1; if (num < 0 || num > 255) return -1; mask <<= 8; ip = (ip << 8) + num; } if (*b++ == ':') port = Q_atoi(b); else port = net_hostport; addr->port = BigShort(port); addr->ip.l = (myaddr->ip.l & BigLong(mask)) | BigLong(ip); return 0; }
static void AddServer(const netadr_t *address, const char *hostname) { netadr_t tmp; serverslot_t *slot; if (m_servers.list.numItems >= MAX_STATUS_SERVERS) return; if (!address) { // either address or hostname can be NULL, but not both if (!hostname) return; if (!NET_StringToAdr(hostname, &tmp, PORT_SERVER)) { Com_Printf("Bad server address: %s\n", hostname); return; } address = &tmp; } // ignore if already listed if (FindSlot(address, NULL)) return; if (!hostname) hostname = NET_AdrToString(address); // privileged ports are not allowed if (BigShort(address->port) < 1024) { Com_Printf("Bad server port: %s\n", hostname); return; } slot = UI_FormatColumns(SLOT_EXTRASIZE, hostname, "???", "???", "?/?", "???", NULL); slot->status = SLOT_IDLE; slot->address = *address; slot->hostname = UI_CopyString(hostname); slot->color = U32_WHITE; slot->numRules = 0; slot->numPlayers = 0; slot->timestamp = com_eventTime; m_servers.list.items[m_servers.list.numItems++] = slot; }
qbool NET_SendTCPPacket_CL (netsrc_t netsrc, int length, void *data, netadr_t to) { unsigned short slen; if (netsrc != NS_CLIENT || cls.sockettcp == INVALID_SOCKET) return false; if (!NET_CompareAdr(to, cls.sockettcpdest)) return false; // this goes to the server so send it via TCP. slen = BigShort((unsigned short)length); // FIXME: CHECK send() result, we use NON BLOCKIN MODE, FFS! send(cls.sockettcp, (char*)&slen, sizeof(slen), 0); send(cls.sockettcp, data, length, 0); return true; }
/* ==================== SV_SetMaster_f Specify a list of master servers ==================== */ static void SV_SetMaster_f (void) { int i, slot; // only dedicated servers send heartbeats if (!dedicated->integer) { Com_Printf ("Only dedicated servers use masters.\n"); return; } // make sure the server is listed public Cvar_Set ("sv_public", "1"); memset (&master_adr, 0, sizeof(master_adr)); slot = 1; // slot 0 will always contain the id master for (i=1 ; i<Cmd_Argc() ; i++) { if (slot == MAX_MASTERS) break; if (!NET_StringToAdr (Cmd_Argv(i), &master_adr[i])) { Com_Printf ("Bad address: %s\n", Cmd_Argv(i)); continue; } if (master_adr[slot].port == 0) master_adr[slot].port = BigShort (PORT_MASTER); Com_Printf ("Master server at %s\n", NET_AdrToString (&master_adr[slot])); if (svs.initialized) { Com_Printf ("Sending a ping.\n"); Netchan_OutOfBandPrint (NS_SERVER, &master_adr[slot], "ping"); } slot++; } svs.last_heartbeat = -9999999; }
/* ================= CL_CheckForResend Resend a connect message if the last one has timed out ================= */ void CL_CheckForResend (void) { char data[2048]; double t1, t2; if (cls.state == ca_disconnected && com_serveractive) { // if the local server is running and we are not, then connect cls.nqprotocol = false; strlcpy (cls.servername, "local", sizeof(cls.servername)); NET_StringToAdr ("local", &cls.server_adr); CL_SendConnectPacket (); // we don't need a challenge on the local server // FIXME: cls.state = ca_connecting so that we don't send the packet twice? return; } if (cls.state != ca_disconnected || !connect_time) return; if (cls.realtime - connect_time < 5.0) return; t1 = Sys_DoubleTime (); if (!NET_StringToAdr (cls.servername, &cls.server_adr)) { Com_Printf ("Bad server address\n"); connect_time = 0; return; } t2 = Sys_DoubleTime (); connect_time = cls.realtime + t2 - t1; // for retransmit requests if (cls.server_adr.port == 0) cls.server_adr.port = BigShort (cls.nqprotocol ? 26000 : PORT_SERVER); Com_Printf ("Connecting to %s...\n", cls.servername); if (cls.nqprotocol) { memcpy (data, "\x80\x00\x00\x0C" "\x01" "QUAKE\x00" "\x03", 12); NET_SendPacket (NS_CLIENT, 12, data, cls.server_adr); } else { sprintf (data, "\xff\xff\xff\xff" "getchallenge\n"); NET_SendPacket (NS_CLIENT, strlen(data), data, cls.server_adr); } }
/* * Resend a connect message if the last one has timed out */ void CL_CheckForResend(void) { netadr_t adr; /* if the local server is running and we aren't just connect */ if ((cls.state == ca_disconnected) && Com_ServerState()) { cls.state = ca_connecting; Q_strlcpy(cls.servername, "localhost", sizeof(cls.servername)); /* we don't need a challenge on the localhost */ CL_SendConnectPacket(); return; } /* resend if we haven't gotten a reply yet */ if (cls.state != ca_connecting) { return; } if (cls.realtime - cls.connect_time < 3000) { return; } if (!NET_StringToAdr(cls.servername, &adr)) { Com_Printf("Bad server address\n"); cls.state = ca_disconnected; return; } if (adr.port == 0) { adr.port = BigShort(PORT_SERVER); } cls.connect_time = cls.realtime; Com_Printf("Connecting to %s...\n", cls.servername); Netchan_OutOfBandPrint(NS_CLIENT, adr, "getchallenge\n"); }
/* =============== SV_UpdateSharedConfig =============== */ void SV_UpdateSharedConfig( unsigned int port, const char *rconpass ) { char message[MAX_RCON_MESSAGE]; netadr_t to; message[0] = -1; message[1] = -1; message[2] = -1; message[3] = -1; message[4] = 0; Q_strcat (message, MAX_RCON_MESSAGE, "rcon "); Q_strcat (message, MAX_RCON_MESSAGE, rconpass); Q_strcat (message, MAX_RCON_MESSAGE, " !readconfig"); NET_StringToAdr ("127.0.0.1", &to, NA_UNSPEC); to.port = BigShort (port); NET_SendPacket (NS_SERVER, strlen(message)+1, message, to); }
/* ======================= CL_SendConnectPacket called by CL_Connect_f and CL_CheckResend ====================== */ void CL_SendConnectPacket (void) { netadr_t adr; char data[2048]; double t1, t2; // JACK: Fixed bug where DNS lookups would cause two connects real fast // Now, adds lookup time to the connect time. // Should I add it to realtime instead?!?! if (cls.state != ca_disconnected) return; t1 = Sys_DoubleTime (); if (!NET_StringToAdr (cls.servername, &adr)) { Con_Printf ("Bad server address\n"); connect_time = -1; return; } if (!NET_IsClientLegal(&adr)) { Con_Printf ("Illegal server address\n"); connect_time = -1; return; } if (adr.port == 0) adr.port = BigShort (27500); t2 = Sys_DoubleTime (); connect_time = realtime+t2-t1; // for retransmit requests cls.qport = Cvar_VariableValue("qport"); Info_SetValueForStarKey (cls.userinfo, "*ip", NET_AdrToString(adr), MAX_INFO_STRING); //Con_Printf ("Connecting to %s...\n", cls.servername); sprintf (data, "%c%c%c%cconnect %i %i %i \"%s\"\n", 255, 255, 255, 255, PROTOCOL_VERSION, cls.qport, cls.challenge, cls.userinfo); NET_SendPacket (strlen(data), data, adr); }
/* ===================== CL_Rcon_f Send the rest of the command line over as an unconnected command. ===================== */ void CL_Rcon_f (void) { char message[1024]; netadr_t to; extern cvar_t cl_rconAddress; extern cvar_t *cl_rconPassword; message[0] = 255; message[1] = 255; message[2] = 255; message[3] = 255; message[4] = 0; strcat (message, "rcon "); if (cl_rconPassword->string[0]) { strcat (message, cl_rconPassword->string); strcat (message, " "); } strlcat (message, Cmd_MakeArgs(1), sizeof(message)); if (cls.state >= ca_connected) to = cls.netchan.remote_address; else { if (!strlen(cl_rconAddress.string)) { Com_Printf ("You must either be connected,\n" "or set the 'rcon_address' cvar\n" "to issue rcon commands\n"); return; } NET_StringToAdr (cl_rconAddress.string, &to); if (to.port == 0) to.port = BigShort (PORT_SERVER); } NET_SendPacket (NS_CLIENT, strlen(message)+1, message , to); }
/* ================== CL_GlobalServers_f ================== */ void CL_GlobalServers_f( void ) { netadr_t to; int i; int count; char *buffptr; char command[1024]; if ( Cmd_Argc() < 3) { Com_Printf( "usage: globalservers <master# 0-1> <protocol> [keywords]\n"); return; } cls.masterNum = atoi( Cmd_Argv(1) ); Com_Printf( "Requesting servers from the master...\n"); // reset the list, waiting for response // -1 is used to distinguish a "no response" if( cls.masterNum == 1 ) { NET_StringToAdr( MASTER_SERVER_NAME, &to ); cls.nummplayerservers = -1; cls.pingUpdateSource = AS_MPLAYER; } else { NET_StringToAdr( MASTER_SERVER_NAME, &to ); cls.numglobalservers = -1; cls.pingUpdateSource = AS_GLOBAL; } to.type = NA_IP; to.port = BigShort(PORT_MASTER); sprintf( command, "getservers %s", Cmd_Argv(2) ); // tack on keywords buffptr = command + strlen( command ); count = Cmd_Argc(); for (i=3; i<count; i++) buffptr += sprintf( buffptr, " %s", Cmd_Argv(i) ); NET_OutOfBandPrint( NS_SERVER, to, command ); }
/* ======================= CL_SendConnectPacket We have gotten a challenge from the server, so try and connect. ====================== */ void CL_SendConnectPacket (void) { netadr_t adr; int port; if (!NET_StringToAdr (cls.servername, &adr)) { Com_Printf ("Bad server address\n"); cls.connect_time = 0; return; } if (adr.port == 0) adr.port = BigShort (PORT_SERVER); port = Cvar_VariableValue ("qport"); userinfo_modified = false; Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n", PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() ); }