Пример #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 );	
}
Пример #2
0
//*****************************************************************************
//
void SERVER_RCON_Construct( )
{
	NETWORK_InitBuffer( &g_MessageBuffer, MAX_UDP_PACKET, BUFFERTYPE_WRITE );
	NETWORK_ClearBuffer( &g_MessageBuffer );
	
	// Call SERVER_RCON_Destruct() when Skulltag closes.
	atterm( SERVER_RCON_Destruct );
}
Пример #3
0
	BanlistPacketSender ( const SERVER_s &DestServer )
		: _ulMaxPacketSize ( 1024 ),
			_ulPacketNum ( 0 ),
			_ulSizeOfPacket ( 0 ),
			_destServer ( DestServer )
	{
		NETWORK_InitBuffer( &_netBuffer, MAX_UDP_PACKET, BUFFERTYPE_WRITE );
		NETWORK_ClearBuffer( &_netBuffer );
	}
Пример #4
0
void NETWORK_AUTH_Construct( void )
{
	NETWORK_InitBuffer( &g_AuthServerBuffer, MAX_UDP_PACKET, BUFFERTYPE_WRITE );
	NETWORK_ClearBuffer( &g_AuthServerBuffer );

	g_AuthServerAddress = NETWORK_AUTH_GetServerAddress();

	atterm( NETWORK_AUTH_Destruct );
}
Пример #5
0
void ZANDRONUM_Construct( void )
{
	// Setup our message buffer.
	NETWORK_InitBuffer( &g_MessageBuffer, 8192, BUFFERTYPE_WRITE );
	NETWORK_ClearBuffer( &g_MessageBuffer );

	NETWORK_StringToAddress( "master.zandronum.com", &g_AddressMasterServer );
	g_AddressMasterServer.usPort = htons( DEFAULT_MASTER_PORT );

	// Call ZANDRONUM_Destruct when the program terminates.
	atexit( ZANDRONUM_Destruct );
}
Пример #6
0
void SERVER_MASTER_Construct( void )
{
	char	*pszPort;

	// Setup our message buffer.
	NETWORK_InitBuffer( &g_MasterServerBuffer, MAX_UDP_PACKET );
	NETWORK_ClearBuffer( &g_MasterServerBuffer );

	// Allow the user to specify which port the master server is on.
	pszPort = Args.CheckValue( "-masterport" );
    if ( pszPort )
    {
       g_lMasterPort = atoi( pszPort );
       Printf( PRINT_HIGH, "Alternate master server port: %d.\n", g_lMasterPort );
    }
	else
	   g_lMasterPort = DEFAULT_MASTER_PORT;

	g_lStoredQueryIPHead = 0;
	g_lStoredQueryIPTail = 0;
}
Пример #7
0
//*****************************************************************************
//
int main( int argc, char **argv )
{
	BYTESTREAM_s	*pByteStream;

	std::cerr << "=== Zandronum Master ===\n";
	std::cerr << "Revision: "SVN_REVISION_STRING"\n";

	std::cerr << "Port: " << DEFAULT_MASTER_PORT << std::endl << std::endl;

	// Initialize the network system.
	NETWORK_Construct( DEFAULT_MASTER_PORT, ( ( argc >= 4 ) && ( stricmp ( argv[2], "-useip" ) == 0 ) ) ? argv[3] : NULL );

	// Initialize the message buffer we send messages to the launcher in.
	NETWORK_InitBuffer( &g_MessageBuffer, MAX_UDP_PACKET, BUFFERTYPE_WRITE );
	NETWORK_ClearBuffer( &g_MessageBuffer );

	// Initialize the bans subsystem.
	std::cerr << "Initializing ban list...\n";
	MASTERSERVER_InitializeBans( );
	int lastParsingTime = I_GetTime( );
	int lastBanlistVerificationTimeout = lastParsingTime;

	// [BB] Do we want to hide servers that ignore our ban list?
	if ( ( argc >= 2 ) && ( stricmp ( argv[1], "-DontHideBanIgnoringServers" ) == 0 ) )
	{
		std::cerr << "Note: Servers that do not enforce our ban list are shown." << std::endl;
		g_bHideBanIgnoringServers = false;
	}
	else
	{
		std::cerr << "Note: Servers that do not enforce our ban list are hidden." << std::endl;
		g_bHideBanIgnoringServers = true;
	}

	// Done setting up!
	std::cerr << "\n=== Master server started! ===\n";

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

			// Now parse the packet.
			MASTERSERVER_ParseCommands( pByteStream );
		}

		// Update the ignore queues.
		g_queryIPQueue.adjustHead ( g_lCurrentTime );
		g_floodProtectionIPQueue.adjustHead ( g_lCurrentTime );
		g_ShortFloodQueue.adjustHead ( g_lCurrentTime );

		// See if any servers have timed out.
		MASTERSERVER_CheckTimeouts( );

		if ( g_lCurrentTime > lastBanlistVerificationTimeout + 10 )
		{
			for( std::set<SERVER_s, SERVERCompFunc>::iterator it = g_Servers.begin(); it != g_Servers.end(); ++it )
			{
				if ( ( it->bVerifiedLatestBanList == false ) && ( it->bNewFormatServer == true ) )
				{
					it->bHasLatestBanList = false;
					std::cerr << "No receipt received from " << NETWORK_AddressToString ( it->Address ) << ". Resending banlist.\n";
				}
			}
			lastBanlistVerificationTimeout = g_lCurrentTime;
		}

		// [BB] Reparse the ban list every 15 minutes.
		if ( g_lCurrentTime > lastParsingTime + 15*60 )
		{
			std::cerr << "~ Reparsing the ban lists...\n";
			MASTERSERVER_InitializeBans( );
			lastParsingTime = g_lCurrentTime;
		}
	}	
	
	return ( 0 );
}
Пример #8
0
void NETWORK_Construct( USHORT usPort, bool bAllocateLANSocket )
{
	char			szString[128];
	ULONG			ulArg;
	USHORT			usNewPort;
	bool			bSuccess;

	// Initialize the Huffman buffer.
	HUFFMAN_Construct( );

#ifdef __WIN32__
	// [BB] Linux doesn't know WSADATA, so this may not be moved outside the ifdef.
	WSADATA			WSAData;
	if ( WSAStartup( 0x0101, &WSAData ))
		network_Error( "Winsock initialization failed!\n" );

	Printf( "Winsock initialization succeeded!\n" );
#endif

	ULONG ulInAddr = INADDR_ANY;
	const char* pszIPAddress = Args->CheckValue( "-useip" );
	// [BB] An IP was specfied. Check if it's valid and if it is, try to bind our socket to it.
	if ( pszIPAddress )
	{
		ULONG requestedIP = inet_addr( pszIPAddress );
		if ( requestedIP == INADDR_NONE )
		{
			sprintf( szString, "NETWORK_Construct: %s is not a valid IP address\n", pszIPAddress );
			network_Error( szString );
		}
		else
			ulInAddr = requestedIP;
	}

	g_usLocalPort = usPort;

	// Allocate a socket, and attempt to bind it to the given port.
	g_NetworkSocket = network_AllocateSocket( );
	// [BB] If we can't allocate a socket, sending / receiving net packets won't work.
	if ( g_NetworkSocket == INVALID_SOCKET )
		network_Error( "NETWORK_Construct: Couldn't allocate socket. You will not be able to host or join servers.\n" );
	else if ( network_BindSocketToPort( g_NetworkSocket, ulInAddr, g_usLocalPort, false ) == false )
	{
		bSuccess = true;
		bool bSuccessIP = true;
		usNewPort = g_usLocalPort;
		while ( network_BindSocketToPort( g_NetworkSocket, ulInAddr, ++usNewPort, false ) == false )
		{
			// Didn't find an available port. Oh well...
			if ( usNewPort == g_usLocalPort )
			{
				// [BB] We couldn't use the specified IP, so just try any.
				if ( ulInAddr != INADDR_ANY )
				{
					ulInAddr = INADDR_ANY;
					bSuccessIP = false;
					continue;
				}
				bSuccess = false;
				break;
			}
		}

		if ( bSuccess == false )
		{
			sprintf( szString, "NETWORK_Construct: Couldn't bind socket to port: %d\n", g_usLocalPort );
			network_Error( szString );
		}
		else if ( bSuccessIP == false )
		{
			sprintf( szString, "NETWORK_Construct: Couldn't bind socket to IP %s, using the default IP instead:\n", pszIPAddress );
			network_Error( szString );
		}
		else
		{
			Printf( "NETWORK_Construct: Couldn't bind to %d. Binding to %d instead...\n", g_usLocalPort, usNewPort );
			g_usLocalPort = usNewPort;
		}
	}

	ulArg = true;
	if ( ioctlsocket( g_NetworkSocket, FIONBIO, &ulArg ) == -1 )
		printf( "network_AllocateSocket: ioctl FIONBIO: %s", strerror( errno ));

	// If we're not starting a server, setup a socket to listen for LAN servers.
	if ( bAllocateLANSocket )
	{
		g_LANSocket = network_AllocateSocket( );
		if ( network_BindSocketToPort( g_LANSocket, ulInAddr, DEFAULT_BROADCAST_PORT, true ) == false )
		{
			sprintf( szString, "network_BindSocketToPort: Couldn't bind LAN socket to port: %d. You will not be able to see LAN servers in the browser.", DEFAULT_BROADCAST_PORT );
			network_Error( szString );
			// [BB] The socket won't work in this case, make sure not to use it.
			g_bLANSocketInvalid = true;
		}

		if ( ioctlsocket( g_LANSocket, FIONBIO, &ulArg ) == -1 )
			printf( "network_AllocateSocket: ioctl FIONBIO: %s", strerror( errno ));
	}

	// Init our read buffer.
	// [BB] Vortex Cortex pointed us to the fact that the smallest huffman code is only 3 bits
	// and it turns into 8 bits when it's decompressed. Thus we need to allocate a buffer that
	// can hold the biggest possible size we may get after decompressing (aka Huffman decoding)
	// the incoming UDP packet.
	NETWORK_InitBuffer( &g_NetworkMessage, ((MAX_UDP_PACKET * 8) / 3 + 1), BUFFERTYPE_READ );
	NETWORK_ClearBuffer( &g_NetworkMessage );

	// [BB] Get and save our local IP.
	if ( ( ulInAddr == INADDR_ANY ) || ( pszIPAddress == NULL ) )
		g_LocalAddress = NETWORK_GetLocalAddress( );
	// [BB] We are using a specified IP, so we don't need to figure out what IP we have, but just use the specified one.
	else
	{
		NETWORK_StringToAddress ( pszIPAddress, &g_LocalAddress );
		g_LocalAddress.usPort = htons ( NETWORK_GetLocalPort() );
	}

	// Print out our local IP address.
	Printf( "IP address %s\n", NETWORK_AddressToString( g_LocalAddress ));

	// If hosting, update the server GUI.
	if( NETWORK_GetState() == NETSTATE_SERVER )
		SERVERCONSOLE_UpdateIP( g_LocalAddress );

	// [BB] Initialize the checksum of the non-map lumps that need to be authenticated when connecting a new player.
	std::vector<std::string>	lumpsToAuthenticate;
	std::vector<LumpAuthenticationMode>	lumpsToAuthenticateMode;

	lumpsToAuthenticate.push_back( "COLORMAP" );
	lumpsToAuthenticateMode.push_back( LAST_LUMP );
	lumpsToAuthenticate.push_back( "PLAYPAL" );
	lumpsToAuthenticateMode.push_back( LAST_LUMP );
	lumpsToAuthenticate.push_back( "HTICDEFS" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "HEXNDEFS" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "STRFDEFS" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "DOOMDEFS" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "GLDEFS" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "DECORATE" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "LOADACS" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "DEHACKED" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );
	lumpsToAuthenticate.push_back( "GAMEMODE" );
	lumpsToAuthenticateMode.push_back( ALL_LUMPS );

	FString checksum, longChecksum;
	bool noProtectedLumpsAutoloaded = true;

	// [BB] All precompiled ACS libraries need to be authenticated. The only way to find all of them
	// at this point is to parse all LOADACS lumps.
	{
		int lump, lastlump = 0;
		while ((lump = Wads.FindLump ("LOADACS", &lastlump)) != -1)
		{
			FScanner sc(lump);
			while (sc.GetString())
			{
				NETWORK_AddLumpForAuthentication ( Wads.CheckNumForName (sc.String, ns_acslibrary) );
			}
		}
	}

	// [BB] First check the lumps that were marked for authentication while initializing. This
	// includes for example those lumps included by DECORATE lumps. It's much easier to mark those
	// lumps while the engine parses the DECORATE code than trying to find all included lumps from
	// the DECORATE lumps directly.
	for ( unsigned int i = 0; i < g_LumpNumsToAuthenticate.Size(); ++i )
	{
		if ( !network_GenerateLumpMD5HashAndWarnIfNeeded( g_LumpNumsToAuthenticate[i], Wads.GetLumpFullName (g_LumpNumsToAuthenticate[i]), checksum ) )
			noProtectedLumpsAutoloaded = false;
		longChecksum += checksum;
	}

	for ( unsigned int i = 0; i < lumpsToAuthenticate.size(); i++ )
	{
		switch ( lumpsToAuthenticateMode[i] ){
			case LAST_LUMP:
				int lump;
				lump = Wads.CheckNumForName(lumpsToAuthenticate[i].c_str());
				// [BB] Possibly we find the COLORMAP lump only in the colormaps name space.
				if ( ( lump == -1 ) && ( lumpsToAuthenticate[i].compare ( "COLORMAP" ) == 0 ) )
					lump = Wads.CheckNumForName("COLORMAP", ns_colormaps);
				if ( lump == -1 )
				{
					Printf ( PRINT_BOLD, "Warning: Can't find lump %s for authentication!\n", lumpsToAuthenticate[i].c_str() );
					continue;
				}
				if ( !network_GenerateLumpMD5HashAndWarnIfNeeded( lump, lumpsToAuthenticate[i].c_str(), checksum ) )
					noProtectedLumpsAutoloaded = false;

				// [BB] To make Doom and Freedoom network compatible, substitue the Freedoom PLAYPAL/COLORMAP hash
				// by the corresponding Doom hash.
				// 4804c7f34b5285c334a7913dd98fae16 Doom PLAYPAL hash
				// 061a4c0f80aa8029f2c1bc12dc2e261e Doom COLORMAP hash
				// 2e01ae6258f2a0fdad32125537efe1af Freedoom PLAYPAL hash
				// bb535e66cae508e3833a5d2de974267b Freedoom COLORMAP hash
				if ( ( stricmp ( lumpsToAuthenticate[i].c_str(), "PLAYPAL" ) == 0 ) && ( stricmp ( checksum.GetChars(), "2e01ae6258f2a0fdad32125537efe1af" ) == 0 ) )
					checksum = "4804c7f34b5285c334a7913dd98fae16";
				else if ( ( stricmp ( lumpsToAuthenticate[i].c_str(), "COLORMAP" ) == 0 ) && ( stricmp ( checksum.GetChars(), "bb535e66cae508e3833a5d2de974267b" ) == 0 ) )
					checksum = "061a4c0f80aa8029f2c1bc12dc2e261e";

				longChecksum += checksum;
				break;

			case ALL_LUMPS:
				int workingLump, lastLump;

				lastLump = 0;
				while ((workingLump = Wads.FindLump(lumpsToAuthenticate[i].c_str(), &lastLump)) != -1)
				{
					if ( !network_GenerateLumpMD5HashAndWarnIfNeeded( workingLump, lumpsToAuthenticate[i].c_str(), checksum ) )
						noProtectedLumpsAutoloaded = false;
					longChecksum += checksum;
				}
				break;
		}
	}
	CMD5Checksum::GetMD5( reinterpret_cast<const BYTE *>(longChecksum.GetChars()), longChecksum.Len(), g_lumpsAuthenticationChecksum );

	// [BB] Warn the user about problematic auto-loaded files.
	if ( noProtectedLumpsAutoloaded == false )
	{
		Printf ( PRINT_BOLD, "Warning: Above auto-loaded files contain protected lumps.\n" );
		if ( Args->CheckParm( "-host" ) )
			Printf ( PRINT_BOLD, "Clients without these files can't connect to this server.\n" );
		else
			Printf ( PRINT_BOLD, "You can't connect to servers without these files.\n" );
	}

	// [BB] Initialize the actor network class indices.
	for ( unsigned int i = 0; i < PClass::m_Types.Size(); i++ )
	{
		PClass* cls = PClass::m_Types[i];
		if ( (cls->IsDescendantOf(RUNTIME_CLASS(AActor)))
		     // [BB] The server only binaries don't know DynamicLight and derived classes.
		     && !(cls->IsDescendantOf(PClass::FindClass("DynamicLight"))) )
			cls->ActorNetworkIndex = 1 + g_ActorNetworkIndexClassPointerMap.Push ( cls );
		else
			cls->ActorNetworkIndex = 0;
	}

	// [RC/BB] Init the list of PWADs.
	network_InitPWADList( );

	// Call NETWORK_Destruct() when Skulltag closes.
	atterm( NETWORK_Destruct );

	Printf( "UDP Initialized.\n" );
}