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 ); }
//***************************************************************************** // 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 ); }
BanlistPacketSender ( const SERVER_s &DestServer ) : _ulMaxPacketSize ( 1024 ), _ulPacketNum ( 0 ), _ulSizeOfPacket ( 0 ), _destServer ( DestServer ) { NETWORK_InitBuffer( &_netBuffer, MAX_UDP_PACKET, BUFFERTYPE_WRITE ); NETWORK_ClearBuffer( &_netBuffer ); }
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 ); }
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 ); }
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; }
//***************************************************************************** // 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 ); }
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" ); }