Esempio n. 1
0
static void main_AttemptConnection( )
{
	char	szBuffer[128];

	// Update the GUI.
	time( &g_tLastSentCommand );
	main_SetState( STATE_CONNECTING );
	sprintf( szBuffer, "Connecting to %s...", NETWORK_AddressToString( g_ServerAddress ));
	main_UpdateStatusbar( szBuffer );
	main_UpdateTrayTooltip( szBuffer );
	GetDlgItemText( g_hDlg, IDC_SERVERIP, szBuffer, 128 );

	// Save this server to our config file.
	g_Config.SetSection( "Settings", true );
	g_Config.SetValueForKey( "LastServer", szBuffer );
	g_Config.WriteConfigFile( );

	// Start listening for packets.
	if ( g_hThread == NULL )
	{
		g_hThread = CreateThread( NULL, 0, main_Loop, 0, 0, 0 );
		NETWORK_InitBuffer( &g_MessageBuffer, 8192, BUFFERTYPE_WRITE );
	}

	NETWORK_ClearBuffer( &g_MessageBuffer );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, CLRC_BEGINCONNECTION );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, PROTOCOL_VERSION );
	NETWORK_LaunchPacket( &g_MessageBuffer, g_ServerAddress );	
}
Esempio n. 2
0
static void server_WriteUpdateInfo( BYTESTREAM_s *pByteStream, int iUpdateType )
{
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, iUpdateType );

	switch ( iUpdateType )
	{
	// Update the player data.
	case SVRCU_PLAYERDATA:

		NETWORK_WriteByte( pByteStream, SERVER_CountPlayers( true ));
		for ( unsigned int i = 0; i < MAXPLAYERS; i++ )
		{
			if ( playeringame[i] )
			{
				FString		fsName;

				fsName.Format( "%s", players[i].userinfo.netname );
				V_RemoveColorCodes( fsName );
				NETWORK_WriteString( pByteStream, fsName );
			}
		}
		break;
	// Update the current map.
	case SVRCU_MAP:

		NETWORK_WriteString( pByteStream, level.mapname );
		break;
	// Update the number of other admins.
	case SVRCU_ADMINCOUNT:

		NETWORK_WriteByte( pByteStream, g_AuthedClients.Size() - 1 );
		break;
	}
}
Esempio n. 3
0
	void startPacket ( ) {
		NETWORK_ClearBuffer( &_netBuffer );
		NETWORK_WriteByte( &_netBuffer.ByteStream, MASTER_SERVER_BANLISTPART );
		NETWORK_WriteString( &_netBuffer.ByteStream, _destServer.MasterBanlistVerificationString.c_str() );
		NETWORK_WriteByte( &_netBuffer.ByteStream, _ulPacketNum );
		_ulSizeOfPacket = 2 + _destServer.MasterBanlistVerificationString.length();
		++_ulPacketNum;
	}
Esempio n. 4
0
//*****************************************************************************
//
void MASTERSERVER_SendServerIPToLauncher( const NETADDRESS_s &Address, BYTESTREAM_s *pByteStream )
{
	// Tell the launcher the IP of this server on the list.
	NETWORK_WriteByte( pByteStream, MSC_SERVER );
	NETWORK_WriteByte( pByteStream, Address.abIP[0] );
	NETWORK_WriteByte( pByteStream, Address.abIP[1] );
	NETWORK_WriteByte( pByteStream, Address.abIP[2] );
	NETWORK_WriteByte( pByteStream, Address.abIP[3] );
	NETWORK_WriteShort( pByteStream, ntohs( Address.usPort ));
}
Esempio n. 5
0
//*****************************************************************************
//
void MASTERSERVER_SendServerIPBlockToLauncher( const NETADDRESS_s &Address, const std::vector<USHORT> &PortList, BYTESTREAM_s *pByteStream )
{
	if ( PortList.size() == 0 )
		return;

	// Tell the launcher the IP and all ports of the servers on that IP.
	NETWORK_WriteByte( pByteStream, PortList.size() );
	NETWORK_WriteByte( pByteStream, Address.abIP[0] );
	NETWORK_WriteByte( pByteStream, Address.abIP[1] );
	NETWORK_WriteByte( pByteStream, Address.abIP[2] );
	NETWORK_WriteByte( pByteStream, Address.abIP[3] );
	for ( unsigned int i = 0; i < PortList.size(); ++i )
		NETWORK_WriteShort( pByteStream, ntohs( PortList[i] ) );
}
Esempio n. 6
0
static void main_Disconnect( )
{
	NETWORK_ClearBuffer( &g_MessageBuffer );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, CLRC_DISCONNECT );
	NETWORK_LaunchPacket( &g_MessageBuffer, g_ServerAddress );
	main_SetState( STATE_WAITING );
}
Esempio n. 7
0
void SERVER_RCON_Print( const char *pszString )
{
	for ( unsigned int i = 0; i < g_AuthedClients.Size( ); i++ )
	{
		NETWORK_ClearBuffer( &g_MessageBuffer );
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_MESSAGE );
		NETWORK_WriteString( &g_MessageBuffer.ByteStream, pszString );
		NETWORK_LaunchPacket( &g_MessageBuffer, g_AuthedClients[i].Address );
	}

	//==========================================
	// Add this to the cache of recent messages.
	//==========================================

	if ( g_RecentConsoleLines.size() >= 32 )
		g_RecentConsoleLines.pop_front();

	FString			fsLogged = pszString;
	time_t			tNow = time(0);
	struct	tm		*pTimeInfo = localtime( &tNow );

	if ( pTimeInfo->tm_hour < 12 )
		fsLogged.Format( "[%02d:%02d:%02d am] %s ", ( pTimeInfo->tm_hour == 0 ) ? 12 : pTimeInfo->tm_hour, pTimeInfo->tm_min, pTimeInfo->tm_sec, pszString );
	else
		fsLogged.Format( "[%02d:%02d:%02d pm] %s", ( pTimeInfo->tm_hour == 12 ) ? 12 : pTimeInfo->tm_hour % 12, pTimeInfo->tm_min, pTimeInfo->tm_sec, pszString );

	g_RecentConsoleLines.push_back( fsLogged );
}
Esempio n. 8
0
//*****************************************************************************
//
void SERVER_MASTER_Tick( void )
{
	UCVarValue	Val;

	while (( g_lStoredQueryIPHead != g_lStoredQueryIPTail ) && ( gametic >= g_StoredQueryIPs[g_lStoredQueryIPHead].lNextAllowedGametic ))
	{
		g_lStoredQueryIPHead++;
		g_lStoredQueryIPHead = g_lStoredQueryIPHead % MAX_STORED_QUERY_IPS;
	}

	// Send an update to the master server every 30 seconds.
	if ( gametic % ( TICRATE * 30 ))
		return;

	// User doesn't wish to update the master server.
	if ( sv_updatemaster == false )
		return;

	NETWORK_ClearBuffer( &g_MasterServerBuffer );

	Val = sv_masterip.GetGenericRep( CVAR_String );
	NETWORK_StringToAddress( Val.String, &g_AddressMasterServer );
	I_SetPort( g_AddressMasterServer, g_lMasterPort );

	// Write to our packet a challenge to the master server.
	Val = sv_masteroverrideip.GetGenericRep( CVAR_String );
	if ( Val.String[0] == '\0' )
		NETWORK_WriteLong( &g_MasterServerBuffer, SERVER_MASTER_CHALLENGE );
	else
	{
		netadr_t	OverrideIP;

		NETWORK_WriteLong( &g_MasterServerBuffer, SERVER_MASTER_CHALLENGE_OVERRIDE );

		NETWORK_StringToAddress( Val.String, &OverrideIP );
		NETWORK_WriteByte( &g_MasterServerBuffer, OverrideIP.ip[0] );
		NETWORK_WriteByte( &g_MasterServerBuffer, OverrideIP.ip[1] );
		NETWORK_WriteByte( &g_MasterServerBuffer, OverrideIP.ip[2] );
		NETWORK_WriteByte( &g_MasterServerBuffer, OverrideIP.ip[3] );
		NETWORK_WriteShort( &g_MasterServerBuffer, NETWORK_GetLocalPort( ));
	}

	// Send the master server our packet.
//	NETWORK_LaunchPacket( &g_MasterServerBuffer, g_AddressMasterServer, true );
	NETWORK_LaunchPacket( &g_MasterServerBuffer, g_AddressMasterServer );
}
Esempio n. 9
0
//*****************************************************************************
//
void MASTERSERVER_RequestServerVerification( const SERVER_s &Server )
{
	NETWORK_ClearBuffer( &g_MessageBuffer );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MASTER_SERVER_VERIFICATION );
	NETWORK_WriteString( &g_MessageBuffer.ByteStream, Server.MasterBanlistVerificationString.c_str() );
	NETWORK_WriteLong( &g_MessageBuffer.ByteStream, Server.ServerVerificationInt );
	NETWORK_LaunchPacket( &g_MessageBuffer, Server.Address );
}
Esempio n. 10
0
// DEBUG FUNCTION!
void NETWORK_FillBufferWithShit( BYTESTREAM_s *pByteStream, ULONG ulSize )
{
	ULONG	ulIdx;

	for ( ulIdx = 0; ulIdx < ulSize; ulIdx++ )
		NETWORK_WriteByte( pByteStream, M_Random( ));

//	NETWORK_ClearBuffer( &g_NetworkMessage );
}
Esempio n. 11
0
//*****************************************************************************
//
void SERVER_AUTH_Negotiate ( const char *Username, const unsigned int ClientSessionID )
{
	NETWORK_ClearBuffer( &g_AuthServerBuffer );
	NETWORK_WriteLong( &g_AuthServerBuffer.ByteStream, SERVER_AUTH_NEGOTIATE );
	NETWORK_WriteByte( &g_AuthServerBuffer.ByteStream, AUTH_PROTOCOL_VERSION );
	NETWORK_WriteLong( &g_AuthServerBuffer.ByteStream, ClientSessionID);
	NETWORK_WriteString( &g_AuthServerBuffer.ByteStream, Username );
	NETWORK_LaunchPacket( &g_AuthServerBuffer, g_AuthServerAddress );
}
Esempio n. 12
0
static void server_rcon_HandleNewConnection( NETADDRESS_s Address,  int iProtocolVersion )
{
	// Banned client? Notify him, ignore him, and get out of here.
	if ( SERVERBAN_IsIPBanned( Address ))
	{
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_BANNED );
		NETWORK_LaunchPacket( &g_MessageBuffer, Address );
		g_BadRequestFloodQueue.addAddress( Address, gametic / 1000 );
		return;
	}

	// Old protocol version? Notify, ignore, and quit.
	if ( iProtocolVersion < MIN_PROTOCOL_VERSION )
	{
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_OLDPROTOCOL );
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, PROTOCOL_VERSION );
		NETWORK_WriteString( &g_MessageBuffer.ByteStream, DOTVERSIONSTR );
		NETWORK_LaunchPacket( &g_MessageBuffer, Address );
		g_BadRequestFloodQueue.addAddress( Address, gametic / 1000 );
		return;
	}

	// Check if there's already a user at this address. Remove him if so (must be reconnecting).
	// This ensures that each address never has more than one entry (since this is the only function that gives out new candidate slots).
	int iIndex = server_rcon_FindCandidate( Address );
	if ( iIndex != -1 )
		g_Candidates.Delete( iIndex );
	iIndex = server_rcon_FindClient( Address );
	if ( iIndex != -1 )
		g_AuthedClients.Delete( iIndex );

	// Create a slot for him, and request his password.
	RCONCANDIDATE_s		Candidate;
	Candidate.iLastMessageTic = gametic;
	Candidate.Address = Address;
	server_rcon_CreateSalt( Candidate.szSalt );
	g_Candidates.Push( Candidate );

	NETWORK_ClearBuffer( &g_MessageBuffer );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_SALT );
	NETWORK_WriteString( &g_MessageBuffer.ByteStream, Candidate.szSalt );
	NETWORK_LaunchPacket( &g_MessageBuffer, Address );
}
Esempio n. 13
0
//*****************************************************************************
//
void SERVER_AUTH_SRPMessage ( const int MagicNumber, const int SessionID, const TArray<unsigned char> &Bytes )
{
	NETWORK_ClearBuffer( &g_AuthServerBuffer );
	NETWORK_WriteLong( &g_AuthServerBuffer.ByteStream, MagicNumber );
	NETWORK_WriteLong( &g_AuthServerBuffer.ByteStream, SessionID );
	NETWORK_WriteShort( &g_AuthServerBuffer.ByteStream, Bytes.Size() );
	for ( unsigned int i = 0; i < Bytes.Size(); ++i )
		NETWORK_WriteByte( &g_AuthServerBuffer.ByteStream, Bytes[i] );
	NETWORK_LaunchPacket( &g_AuthServerBuffer, g_AuthServerAddress );
}
Esempio n. 14
0
void SERVER_RCON_UpdateInfo( int iUpdateType )
{
	int		iNumPlayers = (int) SERVER_CountPlayers( true );

	for ( unsigned int i = 0; i < g_AuthedClients.Size( ); i++ )
	{	
		NETWORK_ClearBuffer( &g_MessageBuffer );
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_UPDATE );		
		server_WriteUpdateInfo( &g_MessageBuffer.ByteStream, iUpdateType );
		NETWORK_LaunchPacket( &g_MessageBuffer, g_AuthedClients[i].Address );
	}
}
Esempio n. 15
0
	void writeBanEntry ( const char *BanEntry, const int EntryType )
	{
		const unsigned long ulCommandSize = 1 + strlen ( BanEntry );

		// [BB] If this command doesn't fit into the current packet, start a new one.
		if ( _ulSizeOfPacket + ulCommandSize > _ulMaxPacketSize - 1 )
			finishCurrentAndStartNewPacket();

		NETWORK_WriteByte( &_netBuffer.ByteStream, EntryType );
		NETWORK_WriteString( &_netBuffer.ByteStream, BanEntry );
		_ulSizeOfPacket += ulCommandSize;
	}
Esempio n. 16
0
//*****************************************************************************
//
void NETWORK_WriteString( BYTESTREAM_s *pByteStream, const char *pszString )
{
	if (( pszString ) && ( strlen( pszString ) > MAX_NETWORK_STRING ))
	{
		Printf( "NETWORK_WriteString: String exceeds %d characters!\n", MAX_NETWORK_STRING );
		return;
	}

#ifdef	WIN32
	if ( pszString == NULL )
		NETWORK_WriteBuffer( pByteStream, "", 1 );
	else
		NETWORK_WriteBuffer( pByteStream, pszString, (int)( strlen( pszString )) + 1 );
#else
	if ( pszString == NULL )
		NETWORK_WriteByte( pByteStream, 0 );
	else
	{
		NETWORK_WriteBuffer( pByteStream, pszString, strlen( pszString ));
		NETWORK_WriteByte( pByteStream, 0 );
	}
#endif
}
Esempio n. 17
0
static void main_SendPassword( const char *pszSalt )
{
	char	szString[512];

	main_UpdateStatusbar( "Authenticating..." );
	FString fsString, fsHash;
	fsString.Format( "%s%s", pszSalt, g_szPassword );
	CMD5Checksum::GetMD5( reinterpret_cast<const BYTE *>(fsString.GetChars()), fsString.Len(), fsHash );

	NETWORK_ClearBuffer( &g_MessageBuffer );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, CLRC_PASSWORD );
	NETWORK_WriteString( &g_MessageBuffer.ByteStream, fsHash.GetChars() );
	NETWORK_LaunchPacket( &g_MessageBuffer, g_ServerAddress );
	time( &g_tLastSentCommand );
}
Esempio n. 18
0
//*****************************************************************************
//
void MASTERSERVER_SendBanlistToServer( const SERVER_s &Server )
{
	// [BB] If the server supports it, potentially split the ban list over multiple packets.
	if ( Server.iServerRevision >= 2907 )
	{
		BanlistPacketSender sender ( Server );
		sender.start();

		// Write all the bans.
		for ( unsigned int i = 0; i < g_BannedIPs.size( ); ++i )
			sender.writeBanEntry ( g_BannedIPs.getEntryAsString( i, false, false, false ).c_str( ), MSB_BAN );

		// Write all the exceptions.
		for ( unsigned int i = 0; i < g_BannedIPExemptions.size( ); ++i )
			sender.writeBanEntry ( g_BannedIPExemptions.getEntryAsString( i, false, false, false ).c_str( ), MSB_BANEXEMPTION );

		sender.end();
	}
	else
	{
		NETWORK_ClearBuffer( &g_MessageBuffer );
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MASTER_SERVER_BANLIST );
		// [BB] If the server sent us a verification string, send it along with the ban list.
		// This allows the server to verify that the list actually was sent from our master
		// (and is not just a packet with forged source IP).
		if ( Server.MasterBanlistVerificationString.size() )
			NETWORK_WriteString( &g_MessageBuffer.ByteStream, Server.MasterBanlistVerificationString.c_str() );

		// Write all the bans.
		NETWORK_WriteLong( &g_MessageBuffer.ByteStream, g_BannedIPs.size( ));
		for ( ULONG i = 0; i < g_BannedIPs.size( ); i++ )
			NETWORK_WriteString( &g_MessageBuffer.ByteStream, g_BannedIPs.getEntryAsString( i, false, false, false ).c_str( ));

		// Write all the exceptions.
		NETWORK_WriteLong( &g_MessageBuffer.ByteStream, g_BannedIPExemptions.size( ));
		for ( ULONG i = 0; i < g_BannedIPExemptions.size( ); i++ )
			NETWORK_WriteString( &g_MessageBuffer.ByteStream, g_BannedIPExemptions.getEntryAsString( i, false, false, false ).c_str( ));

		NETWORK_LaunchPacket( &g_MessageBuffer, Server.Address );
	}
	Server.bHasLatestBanList = true;
	Server.bVerifiedLatestBanList = false;
	printf( "-> Banlist sent to %s.\n", NETWORK_AddressToString( Server.Address ));
}
Esempio n. 19
0
//*****************************************************************************
//
void SERVER_MASTER_SendServerInfo( netadr_t Address, ULONG ulFlags, ULONG ulTime )
{
	UCVarValue	Val;
	char		szAddress[4][4];
	ULONG		ulIdx;
	ULONG		ulBits;
	ULONG		ulNumPWADs;

	// Let's just use the master server buffer! It gets cleared again when we need it anyway!
	NETWORK_ClearBuffer( &g_MasterServerBuffer );

	// First, check to see if we've been queried by this address recently.
	if ( g_lStoredQueryIPHead != g_lStoredQueryIPTail )
	{
		ulIdx = g_lStoredQueryIPHead;
		while ( ulIdx != (ULONG)g_lStoredQueryIPTail )
		{
			// Check to see if this IP exists in our stored query IP list. If it does, then
			// ignore it, since it queried us less than 10 seconds ago.
			if ( NETWORK_CompareAddress( Address, g_StoredQueryIPs[ulIdx].Address, true ))
			{
				// Write our header.
				NETWORK_WriteLong( &g_MasterServerBuffer, SERVER_LAUNCHER_IGNORING );

				// Send the time the launcher sent to us.
				NETWORK_WriteLong( &g_MasterServerBuffer, ulTime );

				// Send the packet.
//				NETWORK_LaunchPacket( &g_MasterServerBuffer, Address, true );
				NETWORK_LaunchPacket( &g_MasterServerBuffer, Address );

				if ( sv_showlauncherqueries )
					Printf( "Ignored IP launcher challenge.\n" );

				// Nothing more to do here.
				return;
			}

			ulIdx++;
			ulIdx = ulIdx % MAX_STORED_QUERY_IPS;
		}
	}

	// Now, check to see if this IP has been banend from this server.
	itoa( Address.ip[0], szAddress[0], 10 );
	itoa( Address.ip[1], szAddress[1], 10 );
	itoa( Address.ip[2], szAddress[2], 10 );
	itoa( Address.ip[3], szAddress[3], 10 );
	if (( sv_enforcebans ) && ( SERVERBAN_IsIPBanned( szAddress[0], szAddress[1], szAddress[2], szAddress[3] )))
	{
		// Write our header.
		NETWORK_WriteLong( &g_MasterServerBuffer, SERVER_LAUNCHER_BANNED );

		// Send the time the launcher sent to us.
		NETWORK_WriteLong( &g_MasterServerBuffer, ulTime );

		// Send the packet.
		NETWORK_LaunchPacket( &g_MasterServerBuffer, Address );

		if ( sv_showlauncherqueries )
			Printf( "Denied BANNED IP launcher challenge.\n" );

		// Nothing more to do here.
		return;
	}

	// This IP didn't exist in the list. and it wasn't banned.
	// So, add it, and keep it there for 10 seconds.
	g_StoredQueryIPs[g_lStoredQueryIPTail].Address = Address;
	g_StoredQueryIPs[g_lStoredQueryIPTail].lNextAllowedGametic = gametic + ( TICRATE * ( sv_queryignoretime ));

	g_lStoredQueryIPTail++;
	g_lStoredQueryIPTail = g_lStoredQueryIPTail % MAX_STORED_QUERY_IPS;
	if ( g_lStoredQueryIPTail == g_lStoredQueryIPHead )
		Printf( "SERVER_MASTER_SendServerInfo: WARNING! g_lStoredQueryIPTail == g_lStoredQueryIPHead\n" );

	// Write our header.
	NETWORK_WriteLong( &g_MasterServerBuffer, SERVER_LAUNCHER_CHALLENGE );

	// Send the time the launcher sent to us.
	NETWORK_WriteLong( &g_MasterServerBuffer, ulTime );

	// Send our version.
	NETWORK_WriteString( &g_MasterServerBuffer, DOTVERSIONSTR );

	// Send the information about the data that will be sent.
	ulBits = ulFlags;

	// If the launcher desires to know the team damage, but we're not in a game mode where
	// team damage applies, then don't send back team damage information.
	if (( teamplay || teamgame || teamlms || teampossession || teamcoop || (( deathmatch == false ) && ( teamgame == false ))) == false )
	{
		if ( ulBits & SQF_TEAMDAMAGE )
			ulBits &= ~SQF_TEAMDAMAGE;
	}

	// If the launcher desires to know the team score, but we're not in a game mode where
	// teams have scores, then don't send back team score information.
	if (( teamplay || teamgame || teamlms || teampossession || teamcoop ) == false )
	{
		if ( ulBits & SQF_TEAMSCORES )
			ulBits &= ~SQF_TEAMSCORES;
	}

	// If the launcher wants to know player data, then we have to tell them how many players
	// are in the server.
	if ( ulBits & SQF_PLAYERDATA )
		ulBits |= SQF_NUMPLAYERS;

	NETWORK_WriteLong( &g_MasterServerBuffer, ulBits );

	// Send the server name.
	if ( ulBits & SQF_NAME )
	{
		Val = sv_hostname.GetGenericRep( CVAR_String );
		NETWORK_WriteString( &g_MasterServerBuffer, Val.String );
	}

	// Send the website URL.
	if ( ulBits & SQF_URL )
	{
		Val = sv_website.GetGenericRep( CVAR_String );
		NETWORK_WriteString( &g_MasterServerBuffer, Val.String );
	}

	// Send the host's e-mail address.
	if ( ulBits & SQF_EMAIL )
	{
		Val = sv_hostemail.GetGenericRep( CVAR_String );
		NETWORK_WriteString( &g_MasterServerBuffer, Val.String );
	}

	if ( ulBits & SQF_MAPNAME )
		NETWORK_WriteString( &g_MasterServerBuffer, level.mapname );

	if ( ulBits & SQF_MAXCLIENTS )
		NETWORK_WriteByte( &g_MasterServerBuffer, sv_maxclients );

	if ( ulBits & SQF_MAXPLAYERS )
		NETWORK_WriteByte( &g_MasterServerBuffer, sv_maxplayers );

	// Send out the PWAD information.
	if ( ulBits & SQF_PWADS )
	{
		ulNumPWADs = 0;
		for ( ulIdx = 0; Wads.GetWadName( ulIdx ) != NULL; ulIdx++ )
		{
			// Skip the IWAD file index, skulltag.wad/pk3, and files that were automatically
			// loaded from subdirectories (such as skin files).
			if (( ulIdx == FWadCollection::IWAD_FILENUM ) ||
				( stricmp( Wads.GetWadName( ulIdx ), "scoredoomst.wad" ) == 0 ) ||
				( stricmp( Wads.GetWadName( ulIdx ), "scoredoomst.pk3" ) == 0 ) ||
				( Wads.GetLoadedAutomatically( ulIdx )))
			{
				continue;
			}

			ulNumPWADs++;
		}

		NETWORK_WriteByte( &g_MasterServerBuffer, ulNumPWADs );
		for ( ulIdx = 0; Wads.GetWadName( ulIdx ) != NULL; ulIdx++ )
		{
			// Skip the IWAD file index, skulltag.wad/pk3, and files that were automatically
			// loaded from subdirectories (such as skin files).
			if (( ulIdx == FWadCollection::IWAD_FILENUM ) ||
				( stricmp( Wads.GetWadName( ulIdx ), "scoredoomst.wad" ) == 0 ) ||
				( stricmp( Wads.GetWadName( ulIdx ), "scoredoomst.pk3" ) == 0 ) ||
				( Wads.GetLoadedAutomatically( ulIdx )))
			{
				continue;
			}

			NETWORK_WriteString( &g_MasterServerBuffer, (char *)Wads.GetWadName( ulIdx ));
		}
	}

	if ( ulBits & SQF_GAMETYPE )
	{
		NETWORK_WriteByte( &g_MasterServerBuffer, GAME_GetGameType( ));
		NETWORK_WriteByte( &g_MasterServerBuffer, instagib );
		NETWORK_WriteByte( &g_MasterServerBuffer, buckshot );
	}

	if ( ulBits & SQF_GAMENAME )
		NETWORK_WriteString( &g_MasterServerBuffer, SERVER_MASTER_GetGameName( ));

	if ( ulBits & SQF_IWAD )
		NETWORK_WriteString( &g_MasterServerBuffer, (char *)Wads.GetWadName( FWadCollection::IWAD_FILENUM ));

	if ( ulBits & SQF_FORCEPASSWORD )
		NETWORK_WriteByte( &g_MasterServerBuffer, sv_forcepassword );

	if ( ulBits & SQF_FORCEJOINPASSWORD )
		NETWORK_WriteByte( &g_MasterServerBuffer, sv_forcejoinpassword );

	if ( ulBits & SQF_GAMESKILL )
		NETWORK_WriteByte( &g_MasterServerBuffer, gameskill );

	if ( ulBits & SQF_BOTSKILL )
		NETWORK_WriteByte( &g_MasterServerBuffer, botskill );

	if ( ulBits & SQF_DMFLAGS )
	{
		NETWORK_WriteLong( &g_MasterServerBuffer, dmflags );
		NETWORK_WriteLong( &g_MasterServerBuffer, dmflags2 );
		NETWORK_WriteLong( &g_MasterServerBuffer, compatflags );
	}

	if ( ulBits & SQF_LIMITS )
	{
		NETWORK_WriteShort( &g_MasterServerBuffer, fraglimit );
		NETWORK_WriteShort( &g_MasterServerBuffer, (SHORT)timelimit );
		if ( timelimit )
		{
			LONG	lTimeLeft;

			lTimeLeft = (LONG)( timelimit - ( level.totaltime / ( TICRATE * 60 ))); //ghk
			if ( lTimeLeft < 0 )
				lTimeLeft = 0;
			NETWORK_WriteShort( &g_MasterServerBuffer, lTimeLeft );
		}
		NETWORK_WriteShort( &g_MasterServerBuffer, duellimit );
		NETWORK_WriteLong( &g_MasterServerBuffer, pointlimit ); //ghk writelong
		NETWORK_WriteShort( &g_MasterServerBuffer, winlimit );
	}

	// Send the team damage scale.
	if ( teamplay || teamgame || teamlms || teampossession || teamcoop || (( deathmatch == false ) && ( teamgame == false )))
	{
		if ( ulBits & SQF_TEAMDAMAGE )
			NETWORK_WriteFloat( &g_MasterServerBuffer, teamdamage );
	}

	// Send the team scores.
	if ( teamplay || teamgame || teamlms || teampossession || teamcoop )
	{
		if ( ulBits & SQF_TEAMSCORES )
		{
			for ( ulIdx = 0; ulIdx < NUM_TEAMS; ulIdx++ )
			{
				if ( teamplay )
					NETWORK_WriteShort( &g_MasterServerBuffer, TEAM_GetFragCount( ulIdx ));
				else if ( teamlms )
					NETWORK_WriteShort( &g_MasterServerBuffer, TEAM_GetWinCount( ulIdx ));
				else
					NETWORK_WriteShort( &g_MasterServerBuffer, TEAM_GetScore( ulIdx )); //ghk writelong?
			}
		}
	}

	if ( ulBits & SQF_NUMPLAYERS )
		NETWORK_WriteByte( &g_MasterServerBuffer, SERVER_CalcNumPlayers( ));

	if ( ulBits & SQF_PLAYERDATA )
	{
		for ( ulIdx = 0; ulIdx < MAXPLAYERS; ulIdx++ )
		{
			if ( playeringame[ulIdx] == false )
				continue;

			NETWORK_WriteString( &g_MasterServerBuffer, players[ulIdx].userinfo.netname );
			if ( teamgame || possession || teampossession || cooperative || teamcoop )
				NETWORK_WriteLong( &g_MasterServerBuffer, players[ulIdx].lPointCount );//ghk writelong
			else if ( deathmatch )
				NETWORK_WriteLong( &g_MasterServerBuffer, players[ulIdx].fragcount ); //ghk writelong
			else
				NETWORK_WriteLong( &g_MasterServerBuffer, players[ulIdx].killcount ); //ghk writelong

			NETWORK_WriteShort( &g_MasterServerBuffer, players[ulIdx].ulPing );
			NETWORK_WriteByte( &g_MasterServerBuffer, PLAYER_IsTrueSpectator( &players[ulIdx] ));
			NETWORK_WriteByte( &g_MasterServerBuffer, players[ulIdx].bIsBot );

			if ( teamplay || teamgame || teamlms || teampossession || teamcoop )
			{
				if ( players[ulIdx].bOnTeam == false )
					NETWORK_WriteByte( &g_MasterServerBuffer, 255 );
				else
					NETWORK_WriteByte( &g_MasterServerBuffer, players[ulIdx].ulTeam );
			}

			NETWORK_WriteByte( &g_MasterServerBuffer, players[ulIdx].ulTime / ( TICRATE * 60 ));
		}
	}

//	NETWORK_LaunchPacket( &g_MasterServerBuffer, Address, true );
	NETWORK_LaunchPacket( &g_MasterServerBuffer, Address );
}
Esempio n. 20
0
//*****************************************************************************
//
void MASTERSERVER_ParseCommands( BYTESTREAM_s *pByteStream )
{
	long			lCommand;
	NETADDRESS_s	AddressFrom;

	AddressFrom = NETWORK_GetFromAddress( );

	// [RC] If this IP is in our flood queue, ignore it completely.
	if ( g_floodProtectionIPQueue.addressInQueue( AddressFrom ) || g_ShortFloodQueue.addressInQueue( AddressFrom ))
	{
		while ( NETWORK_ReadByte( pByteStream ) != -1 ) // [RC] Is this really necessary?
			;
		return;
	}

	// Is this IP banned? Send the user an explanation, and ignore the IP for 30 seconds.
	if ( !g_BannedIPExemptions.isIPInList( AddressFrom ) && g_BannedIPs.isIPInList( AddressFrom ))
	{
		NETWORK_ClearBuffer( &g_MessageBuffer );
		NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_IPISBANNED );
		NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );

		printf( "* Received challenge from banned IP (%s). Ignoring for 10 seconds.\n", NETWORK_AddressToString( AddressFrom ));
		g_queryIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
		return;
	}

	lCommand = NETWORK_ReadLong( pByteStream );
	switch ( lCommand )
	{

	// Server is telling master server of its existence.
	case SERVER_MASTER_CHALLENGE:
		{
			// Certain IPs can be blocked from just hosting.
			if ( !g_BannedIPExemptions.isIPInList( AddressFrom ) && g_BlockedIPs.isIPInList( AddressFrom ))
			{
				NETWORK_ClearBuffer( &g_MessageBuffer );
				NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_IPISBANNED );
				NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );

				printf( "* Received server challenge from blocked IP (%s). Ignoring for 10 seconds.\n", NETWORK_AddressToString( AddressFrom ));
				g_queryIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
				return;
			}
			SERVER_s newServer;
			newServer.Address = AddressFrom;
			// [BB] If no verification string was send, NETWORK_ReadString just returns an empty string.
			// Thus, this is still compatible with older servers that don't send the string.
			newServer.MasterBanlistVerificationString = NETWORK_ReadString( pByteStream );
			// [BB] If no value was send, NETWORK_ReadByte just returns -1.
			// Thus, this is still compatible with older servers that don't tell us whether they enforce our bans
			// and gives them the benefit of the doubt, i.e. it assumes that they enforce our bans.
			const int temp = NETWORK_ReadByte( pByteStream );
			newServer.bEnforcesBanList = ( temp != 0 );
			newServer.bNewFormatServer = ( temp != -1 );
			newServer.iServerRevision = ( ( pByteStream->pbStreamEnd - pByteStream->pbStream ) >= 4 ) ? NETWORK_ReadLong( pByteStream ) : NETWORK_ReadShort( pByteStream );

			std::set<SERVER_s, SERVERCompFunc>::iterator currentServer = g_Servers.find ( newServer );

			// This is a new server; add it to the list.
			if ( currentServer == g_Servers.end() )
			{
				unsigned int iNumOtherServers = 0;

				// First count the number of servers from this IP.
				for( std::set<SERVER_s, SERVERCompFunc>::const_iterator it = g_Servers.begin(); it != g_Servers.end(); ++it )
				{
					if ( NETWORK_CompareAddress( it->Address, AddressFrom, true ))
						iNumOtherServers++;
				}

				if ( iNumOtherServers >= 10 && !g_MultiServerExceptions.isIPInList( AddressFrom ))
					printf( "* More than 10 servers received from %s. Ignoring request...\n", NETWORK_AddressToString( AddressFrom ));
				else
				{
					// [BB] 3021 is 98d, don't put those servers on the list.
					if ( ( newServer.bNewFormatServer ) && ( newServer.iServerRevision != 3021 ) )
					{
						std::set<SERVER_s, SERVERCompFunc>::iterator currentUnverifiedServer = g_UnverifiedServers.find ( newServer );
						// [BB] This is a new server, but we still need to verify it.
						if ( currentUnverifiedServer == g_UnverifiedServers.end() )
						{
							srand ( time(NULL) );
							newServer.ServerVerificationInt = rand() + rand() * rand() + rand() * rand() * rand();
							// [BB] We don't send the ban list to unverified servers, so just pretent the server already has the list.
							newServer.bHasLatestBanList = true;

							MASTERSERVER_RequestServerVerification ( newServer );
							MASTERSERVER_AddServer( newServer, g_UnverifiedServers );
						}
					}
					else
					{
						printf( "* Received server challenge from old server (%s). Ignoring IP for 10 seconds.\n", NETWORK_AddressToString( newServer.Address ));
						g_queryIPQueue.addAddress( newServer.Address, g_lCurrentTime, &std::cerr );
					}
				}
			}

			// Command is from a server already on the list. It's just sending us a heartbeat.
			else
			{
				// [BB] Only if the verification string matches.
				if ( stricmp ( currentServer->MasterBanlistVerificationString.c_str(), newServer.MasterBanlistVerificationString.c_str() ) == 0 )
				{
					currentServer->lLastReceived = g_lCurrentTime;
					// [BB] The server possibly changed the ban setting, so update it.
					currentServer->bEnforcesBanList = newServer.bEnforcesBanList;
				}
			}

			// Ignore IP for 10 seconds.
		//	if ( !g_MultiServerExceptions.isIPInList( Address ) )
		//		g_floodProtectionIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
			return;
		}
	case SERVER_MASTER_VERIFICATION:
		{
			SERVER_s newServer;
			newServer.Address = AddressFrom;
			newServer.MasterBanlistVerificationString = NETWORK_ReadString( pByteStream );
			newServer.ServerVerificationInt = NETWORK_ReadLong( pByteStream );

			std::set<SERVER_s, SERVERCompFunc>::iterator currentServer = g_UnverifiedServers.find ( newServer );

			// [BB] Apparently, we didn't request any verification from this server, so ignore it.
			if ( currentServer == g_UnverifiedServers.end() )
				return;

			if ( ( stricmp ( newServer.MasterBanlistVerificationString.c_str(), currentServer->MasterBanlistVerificationString.c_str() ) == 0 )
				&& ( newServer.ServerVerificationInt == currentServer->ServerVerificationInt ) )
			{
				MASTERSERVER_AddServer( *currentServer, g_Servers );
				g_UnverifiedServers.erase ( currentServer );
			}
			return;
		}
	case SERVER_MASTER_BANLIST_RECEIPT:
		{
			SERVER_s server;
			server.Address = AddressFrom;
			server.MasterBanlistVerificationString = NETWORK_ReadString( pByteStream );

			std::set<SERVER_s, SERVERCompFunc>::iterator currentServer = g_Servers.find ( server );

			// [BB] We don't know the server. Just ignore it.
			if ( currentServer == g_Servers.end() )
				return;

			if ( stricmp ( server.MasterBanlistVerificationString.c_str(), currentServer->MasterBanlistVerificationString.c_str() ) == 0 )
			{
				currentServer->bVerifiedLatestBanList = true;
				std::cerr << NETWORK_AddressToString ( AddressFrom ) << " acknowledged receipt of the banlist.\n";
			}
		}
		return;
	// Launcher is asking master server for server list.
	case LAUNCHER_SERVER_CHALLENGE:
	case LAUNCHER_MASTER_CHALLENGE:
		{
			NETWORK_ClearBuffer( &g_MessageBuffer );

			// Did this IP query us recently? If so, send it an explanation, and ignore it completely for 3 seconds.
			if ( g_queryIPQueue.addressInQueue( AddressFrom ))
			{
				NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_REQUESTIGNORED );
				NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );

				printf( "* Extra launcher challenge from %s. Ignoring for 3 seconds.\n", NETWORK_AddressToString( AddressFrom ));
				g_ShortFloodQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
				return;
			}

			// [BB] The launcher only sends the protocol version with LAUNCHER_MASTER_CHALLENGE.
			if ( lCommand == LAUNCHER_MASTER_CHALLENGE )
			{
				// [BB] Check if the requested version of the protocol matches ours.
				const unsigned short usVersion = NETWORK_ReadShort( pByteStream );

				if ( usVersion != MASTER_SERVER_VERSION )
				{
					NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_WRONGVERSION );
					NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );
					return;
				}
			}

			printf( "-> Sending server list to %s.\n", NETWORK_AddressToString( AddressFrom ));

			// Wait 10 seconds before sending this IP the server list again.
			g_queryIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );

			switch ( lCommand )
			{
			case LAUNCHER_SERVER_CHALLENGE:
				// Send the list of servers.
				NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_BEGINSERVERLIST );
				for( std::set<SERVER_s, SERVERCompFunc>::const_iterator it = g_Servers.begin(); it != g_Servers.end(); ++it )
				{
					// [BB] Possibly omit servers that don't enforce our ban list.
					if ( ( it->bEnforcesBanList == true ) || ( g_bHideBanIgnoringServers == false ) )
						MASTERSERVER_SendServerIPToLauncher ( it->Address, &g_MessageBuffer.ByteStream );
				}

				// Tell the launcher that we're done sending servers.
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MSC_ENDSERVERLIST );

				// Send the launcher our packet.
				NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );
				return;

			case LAUNCHER_MASTER_CHALLENGE:

				const unsigned long ulMaxPacketSize = 1024;
				unsigned long ulPacketNum = 0;

				std::set<SERVER_s, SERVERCompFunc>::const_iterator it = g_Servers.begin();

				NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_BEGINSERVERLISTPART );
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, ulPacketNum );
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MSC_SERVERBLOCK );
				unsigned long ulSizeOfPacket = 6; // 4 (MSC_BEGINSERVERLISTPART) + 1 (0) + 1 (MSC_SERVERBLOCK)

				while ( it != g_Servers.end() )
				{
					NETADDRESS_s serverAddress = it->Address;
					std::vector<USHORT> serverPortList;

					do {
						// [BB] Possibly omit servers that don't enforce our ban list.
						if ( ( it->bEnforcesBanList == true ) || ( g_bHideBanIgnoringServers == false ) )
							serverPortList.push_back ( it->Address.usPort );
						++it;
					} while ( ( it != g_Servers.end() ) && NETWORK_CompareAddress( it->Address, serverAddress, true ) );

					// [BB] All servers on this IP ignore the list, nothing to send.
					if ( serverPortList.size() == 0 )
						continue;

					const unsigned long ulServerBlockNetSize = MASTERSERVER_CalcServerIPBlockNetSize( serverAddress, serverPortList );

					// [BB] If sending this block would cause the current packet to exceed ulMaxPacketSize ...
					if ( ulSizeOfPacket + ulServerBlockNetSize > ulMaxPacketSize - 1 )
					{
						// [BB] ... close the current packet and start a new one.
						NETWORK_WriteByte( &g_MessageBuffer.ByteStream, 0 ); // [BB] Terminate MSC_SERVERBLOCK by sending 0 ports.
						NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MSC_ENDSERVERLISTPART );
						NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );

						NETWORK_ClearBuffer( &g_MessageBuffer );
						++ulPacketNum;
						ulSizeOfPacket = 5;
						NETWORK_WriteLong( &g_MessageBuffer.ByteStream, MSC_BEGINSERVERLISTPART );
						NETWORK_WriteByte( &g_MessageBuffer.ByteStream, ulPacketNum );
						NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MSC_SERVERBLOCK );
					}
					ulSizeOfPacket += ulServerBlockNetSize;
					MASTERSERVER_SendServerIPBlockToLauncher ( serverAddress, serverPortList, &g_MessageBuffer.ByteStream );
				}
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, 0 ); // [BB] Terminate MSC_SERVERBLOCK by sending 0 ports.
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, MSC_ENDSERVERLIST );
				NETWORK_LaunchPacket( &g_MessageBuffer, AddressFrom );
				return;
			}
		}
	}

	printf( "* Received unknown challenge (%ld) from %s. Ignoring for 10 seconds...\n", lCommand, NETWORK_AddressToString( AddressFrom ));
	g_floodProtectionIPQueue.addAddress( AddressFrom, g_lCurrentTime, &std::cerr );
}
Esempio n. 21
0
BOOL CALLBACK main_RCONDialogCallback( HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam )
{
	char	szBuffer[128];

	switch ( Message )
	{
	case WM_CTLCOLORSTATIC:

		switch ( GetDlgCtrlID( (HWND) lParam ))
		{
		// Paint these two labels (and the disconnct button's background) white.
		case IDCANCEL:
		case IDC_STATUS:
		case IDC_SERVERSUBINFO:

			return (LRESULT) g_hWhiteBrush;
		// Ignore everything else.
		default:

			return NULL;
		}
		break;
	case WM_PAINT:
		{
			// Paint the top of the form white.
			PAINTSTRUCT Ps;
			RECT r;
			r.left = 0;
			r.top = 0;
			r.bottom = 48;
			r.right = 800;
			main_PaintRectangle( BeginPaint(hDlg, &Ps), &r, RGB(255, 255, 255));
		}
		break;
	case WM_INITDIALOG:
		
		// Hide the old dialog, and take its place.
		ShowWindow( g_hDlg, SW_HIDE );
		g_hDlg = hDlg;		

		SendDlgItemMessage( hDlg, IDC_CONSOLEBOX, EM_SETLIMITTEXT, 4096, 0 );
		SendDlgItemMessage( hDlg, IDC_INPUTBOX, EM_SETLIMITTEXT, 256, 0 );
		SetWindowText( hDlg, g_szHostname );
		main_SetState( STATE_CONNECTED );
		Printf( "\nMap: %s\n", g_szMapname );

		// Fill the console with the received history.
		sprintf( szBuffer, "Connected to \"%s\".", g_szHostname );
		SetDlgItemText( hDlg, IDC_CONSOLEBOX, szBuffer );
		SetDlgItemText( hDlg, IDC_STATUS, szBuffer );
		main_UpdateTrayTooltip( szBuffer );
		Printf_NoTimestamp( "\n" );
		for( std::list<FString>::iterator i = g_RecentConsoleHistory.begin(); i != g_RecentConsoleHistory.end(); ++i )
			Printf_NoTimestamp( "%s", *i );
		g_RecentConsoleHistory.clear();

		// Set up the top, white section.
		SendMessage( GetDlgItem( g_hDlg, IDC_STATUS ), WM_SETFONT, (WPARAM) CreateFont( 13, 0, 0, 0, 600, 0, 0, 0, 0, 0, 0, 0, 0, "Tahoma" ), (LPARAM) 1 );
		LOGBRUSH LogBrush;
		LogBrush.lbStyle = BS_SOLID;
		LogBrush.lbColor = RGB( 255, 255, 255 );
		g_hWhiteBrush = CreateBrushIndirect( &LogBrush );
		main_UpdateServerStatus( );

		// Set up the player list
		LVCOLUMN	ColumnData;
		ColumnData.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH;
		ColumnData.fmt = LVCFMT_LEFT;
		ColumnData.cx = 192;
		ColumnData.pszText = "Name";
		ColumnData.cchTextMax = 64;
		ColumnData.iSubItem = 0;
		SendDlgItemMessage( hDlg, IDC_PLAYERLIST, LVM_INSERTCOLUMN, COLUMN_NAME, (LPARAM)&ColumnData );

		// Add the cached list of players.
		LVITEM		Item;
		Item.mask = LVIF_TEXT;
		Item.iSubItem = COLUMN_NAME;
		Item.iItem = MAXPLAYERS;
		while ( g_InitialPlayers.size( ) )
		{
			Item.pszText = (LPSTR) g_InitialPlayers.front( ).GetChars( );
			g_InitialPlayers.pop_front( );
			SendDlgItemMessage( g_hDlg, IDC_PLAYERLIST, LVM_INSERTITEM, 0, (LPARAM)&Item ) ;
		}

		// Load the icon.
		SendMessage( hDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM) (HICON) LoadImage( g_hInst,	MAKEINTRESOURCE( AAA_MAIN_ICON ), IMAGE_ICON, 16, 16, LR_SHARED ));
		SendMessage( hDlg, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)LoadIcon( g_hInst, MAKEINTRESOURCE( AAA_MAIN_ICON )));

		// Set up the status bar.
		g_hDlgStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE, (LPCTSTR)NULL, hDlg, IDC_STATIC);

		g_bRCONDialogVisible = true;
		break;
	case WM_COMMAND:

			switch ( LOWORD( wParam ))
			{

			// This also occurs when esc is pressed.
			case IDCANCEL:

				main_Quit( );
				break;

			// "Send" button.
			case IDC_SEND:
			
				char	szCommand[256];

				GetDlgItemText( hDlg, IDC_INPUTBOX, szCommand, sizeof( szCommand ));
				NETWORK_ClearBuffer( &g_MessageBuffer );
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, CLRC_COMMAND );

				if ( szCommand[0] == ':' ) // If the text in the send buffer begins with a :, the admin is just talking.
				{
					char	szBuffer2[256 + 4];

					sprintf( szBuffer2, "say %s", szCommand + 1 );
					NETWORK_WriteString( &g_MessageBuffer.ByteStream, szBuffer2 );
					break;
				}
				else if ( szCommand[0] == '/' ) // If the text in the send buffer begins with a slash, error out -- Skulltag used to require you to do this to send commands.
				{
					Printf( "You longer have to prefix commands with a / to send them.\n" );
					SetDlgItemText( hDlg, IDC_INPUTBOX, szCommand + 1 );
					SendMessage( GetDlgItem( hDlg, IDC_INPUTBOX ), EM_SETSEL, strlen( szCommand ) - 1, strlen( szCommand ) - 1 );
					break;
				}
				else
					NETWORK_WriteString( &g_MessageBuffer.ByteStream, szCommand );				
				
				NETWORK_LaunchPacket( &g_MessageBuffer, g_ServerAddress );
				time( &g_tLastSentCommand );
				SetDlgItemText( hDlg, IDC_INPUTBOX, "" );
				break;
			}
			break;
	case WM_SYSCOMMAND:

		// Hide the window when minimized.
		if ( wParam == SC_MINIMIZE )
			ShowWindow( hDlg, SW_HIDE );
		else
			DefWindowProc( hDlg, Message, wParam, lParam );
		break;
	case WM_CLOSE:

		main_Quit( );
		break;
	case WM_DESTROY:

		Shell_NotifyIcon( NIM_DELETE, &g_NotifyIconData );
		PostQuitMessage( 0 );
		break;
	case UWM_TRAY_TRAYID:

		return main_TrayIconClicked( hDlg, lParam );	
	default:

		return FALSE;
	}

	return TRUE; // If this is false, minimizing the window won't hide it.
}
Esempio n. 22
0
DWORD WINAPI main_Loop( LPVOID )
{
	char	szBuffer[128];

	while ( 1 )
	{		
		while ( NETWORK_GetPackets( ))
		{
			// Set up our byte stream.
			BYTESTREAM_s *pByteStream = &NETWORK_GetNetworkMessageBuffer( )->ByteStream;
			pByteStream->pbStream = NETWORK_GetNetworkMessageBuffer( )->pbData;
			pByteStream->pbStreamEnd = pByteStream->pbStream + NETWORK_GetNetworkMessageBuffer( )->ulCurrentSize;

			// Parse the packet, but only if it came from the server we're trying to reach. Ignore everything else.
			 if ( g_State > STATE_WAITING && NETWORK_CompareAddress( NETWORK_GetFromAddress( ), g_ServerAddress, false ))
				main_ParseCommands( pByteStream );
		}
		
		time_t tNow = time( 0 );
		
		// Refresh the "connect" button.
		if ( g_tLastIncorrectLogin > 0 && ( timeGetTime( ) - g_lLastCountdownTime > 250 ))
		{
			g_lLastCountdownTime = timeGetTime( );
			if ( tNow - g_tLastIncorrectLogin < BAD_QUERY_IGNORE_TIME )
				sprintf( szBuffer, "Connect [%d]", BAD_QUERY_IGNORE_TIME - ( tNow - g_tLastIncorrectLogin ));
			else
				strcpy( szBuffer, "Connect" );

			SetDlgItemText( g_hDlg, IDOK, szBuffer );
			EnableWindow( GetDlgItem( g_hDlg, IDOK ), ( tNow - g_tLastIncorrectLogin >= BAD_QUERY_IGNORE_TIME ) && ( g_State == STATE_WAITING ));
		}

		// If we've been waiting for a while without response, try again, then error out.
		if ( g_State == STATE_CONNECTING && ( tNow - g_tLastSentCommand ) > 2 )
		{
			if ( g_iRetries < 3 )
			{
				main_AttemptConnection();
				g_iRetries++;
				sprintf( szBuffer, "Retrying (%d) to reach %s...", g_iRetries, NETWORK_AddressToString( g_ServerAddress ));
				main_UpdateStatusbar( szBuffer );
				main_UpdateTrayTooltip( szBuffer );
			}
			else
			{
				main_ShowMessage( "That address doesn't seem valid; there was no response.", MB_ICONEXCLAMATION );
				main_SetState( STATE_WAITING );
				main_EnableConnectionButtons( TRUE );
				g_iRetries = 0;
			}
		}

		// If we haven't sent a message recently, let the server know we're still here.
		if ( g_State == STATE_CONNECTED && ( tNow - g_tLastSentCommand ) > RCON_CLIENT_TIMEOUT_TIME / 4 )
		{
			NETWORK_ClearBuffer( &g_MessageBuffer );
			NETWORK_WriteByte( &g_MessageBuffer.ByteStream, CLRC_PONG );
			NETWORK_LaunchPacket( &g_MessageBuffer, g_ServerAddress );
			time( &g_tLastSentCommand );
		}

		Sleep( 200 );
	}

}
Esempio n. 23
0
void SERVER_RCON_ParseMessage( NETADDRESS_s Address, LONG lMessage, BYTESTREAM_s *pByteStream )
{
	int iIndex = -1;

	switch ( lMessage )
	{
	case CLRC_BEGINCONNECTION:

		server_rcon_HandleNewConnection( Address, NETWORK_ReadByte( pByteStream ));
		break;
	case CLRC_PASSWORD:

		server_rcon_HandleLogin( server_rcon_FindCandidate( Address ), NETWORK_ReadString( pByteStream ));
		break;	
	case CLRC_PONG:

		iIndex = server_rcon_FindClient( Address );
		if ( iIndex != -1 )	
			g_AuthedClients[iIndex].iLastMessageTic = gametic;
		break;
	case CLRC_COMMAND:

		// Execute the command (if this came from an admin).
		iIndex = server_rcon_FindClient( Address );
		if ( iIndex != -1 )
		{
			const char *szCommand = NETWORK_ReadString( pByteStream );
			// [BB] Log the command before adding it. If we don't have a server GUI, the command
			// is executed immediately and may cause Skulltag to exit before the command is logged.
			Printf( "-> %s (RCON by %s)\n", szCommand, NETWORK_AddressToString( Address ) );
			SERVER_AddCommand( szCommand );
			g_AuthedClients[iIndex].iLastMessageTic = gametic;
		}
		break;
	case CLRC_DISCONNECT:
		
		iIndex = server_rcon_FindClient( Address );
		if ( iIndex != -1 )	
		{
			g_AuthedClients.Delete( iIndex );
			SERVER_RCON_UpdateInfo( SVRCU_ADMINCOUNT );
			Printf( "RCON client at %s disconnected.\n", NETWORK_AddressToString( Address ));
		}
		break;
	case CLRC_TABCOMPLETE:

		// [TP] RCON client wishes to tab-complete
		iIndex = server_rcon_FindClient( Address );
		if ( iIndex != -1 )
		{
			const char* part = NETWORK_ReadString( pByteStream );
			TArray<FString> list = C_GetTabCompletes( part );
			NETWORK_ClearBuffer( &g_MessageBuffer );

			// [TP] Let's not send too many of these though
			if ( list.Size() < 50 )
			{
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_TABCOMPLETE );
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, list.Size() );

				for ( unsigned i = 0; i < list.Size(); ++i )
					NETWORK_WriteString( &g_MessageBuffer.ByteStream, list[i] );
			}
			else
			{
				NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_TOOMANYTABCOMPLETES );
				NETWORK_WriteShort( &g_MessageBuffer.ByteStream, list.Size() );
			}

			NETWORK_LaunchPacket( &g_MessageBuffer, g_AuthedClients[iIndex].Address );
		}
		break;
	}
}
Esempio n. 24
0
	void finishAndLaunchPacket ( const bool bIsFinal ) {
		NETWORK_WriteByte( &_netBuffer.ByteStream, bIsFinal ? MSB_ENDBANLIST : MSB_ENDBANLISTPART );
		NETWORK_LaunchPacket( &_netBuffer, _destServer.Address );
	}
Esempio n. 25
0
//*****************************************************************************
//
void NETWORK_WriteHeader( BYTESTREAM_s *pByteStream, int Byte )
{
	NETWORK_WriteByte( pByteStream, Byte );
}
Esempio n. 26
0
static void server_rcon_HandleLogin( int iCandidateIndex, const char *pszHash )
{
	// If there's no slot, the candidate must have timed out, or is hacking. Bye!
	if ( iCandidateIndex == -1 )
		return;

	// Combine the salt and password, and hash it.
	FString fsString, fsCorrectHash;
	fsString.Format( "%s%s", g_Candidates[iCandidateIndex].szSalt, sv_rconpassword.GetGenericRep(CVAR_String).String );	
	CMD5Checksum::GetMD5( reinterpret_cast<const BYTE *>(fsString.GetChars()), fsString.Len(), fsCorrectHash );

	// Compare that to what he sent us.
	// Printf("Mine: %s\nTheirs: %s\n", fsCorrectHash, pszHash );
	NETWORK_ClearBuffer( &g_MessageBuffer );
	// [BB] Do not allow the server to let anybody use RCON in case sv_rconpassword is empty.
	if ( fsCorrectHash.Compare( pszHash ) || ( strlen( sv_rconpassword.GetGenericRep(CVAR_String).String ) == 0 ) )
	{
		// Wrong password.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_INVALIDPASSWORD );
		NETWORK_LaunchPacket( &g_MessageBuffer, g_Candidates[iCandidateIndex].Address ); // [RC] Note: Be sure to finish any packets before calling Printf(). Otherwise SERVER_RCON_Print will clear your buffer.

		// To prevent mass password flooding, ignore the IP for a few seconds.
		g_BadRequestFloodQueue.addAddress( g_Candidates[iCandidateIndex].Address, gametic / 1000 );

		Printf( "Failed RCON login from %s. Ignoring IP for 10 seconds...\n", NETWORK_AddressToString( g_Candidates[iCandidateIndex].Address ));
	}
	else
	{		
		// [BB] Since we log when RCON clients disconnect, we should also log when they connect.
		// Do this before we do anything else so that this message is sent to the new RCON client
		// with the console history.
		Printf( "RCON client at %s connected.\n", NETWORK_AddressToString( g_Candidates[iCandidateIndex].Address ));

		// Correct password. Promote him to an authed client.
		RCONCLIENT_s Client;
		Client.Address = g_Candidates[iCandidateIndex].Address;
		Client.iLastMessageTic = gametic;
		g_AuthedClients.Push( Client );

		NETWORK_ClearBuffer( &g_MessageBuffer );
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, SVRC_LOGGEDIN );

		// Tell him some info about the server.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, PROTOCOL_VERSION );
		NETWORK_WriteString( &g_MessageBuffer.ByteStream, sv_hostname.GetGenericRep( CVAR_String ).String );
		
		// Send updates.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, NUM_RCON_UPDATES );
		for ( int i = 0; i < NUM_RCON_UPDATES; i++ )
			server_WriteUpdateInfo( &g_MessageBuffer.ByteStream, i );

		// Send the console history.
		NETWORK_WriteByte( &g_MessageBuffer.ByteStream, g_RecentConsoleLines.size() );
		for( std::list<FString>::iterator i = g_RecentConsoleLines.begin(); i != g_RecentConsoleLines.end(); ++i )
			NETWORK_WriteString( &g_MessageBuffer.ByteStream, *i );

		NETWORK_LaunchPacket( &g_MessageBuffer, g_Candidates[iCandidateIndex].Address );
		SERVER_RCON_UpdateInfo( SVRCU_ADMINCOUNT );
	}

	// Remove his temporary slot.	
	g_Candidates.Delete( iCandidateIndex );
}