void NetworkServerStart() { /* Return if the networking isnt active */ if( !_network_available ) return; /* return if already hosting. */ if( _is_network_server || _network_dedicated ) return; /* Close current game */ NetworkDisconnect(); my_Server = new NetworkServerGameSocketHandler(); if( !my_Server->Listen() ) return; _is_network_server = true; /* Reset counts for client back to 0. */ game_settings.network_settings.server_settings.LastClients = CLIENT_ID_SERVER; /* Advise master server that server has started and can advertise. */ if( my_Master ) my_Master->HostGame(); /* Remove the client. */ my_Client->Close(); delete my_Client; my_Client = NULL; /* Start dedicated server. */ if( _network_dedicated ) { CLog::Get().Write( LOG_SERVER, true, "[UDP] Starting dedicated server." ); return; } /* Add the local player. */ _network_own_client_id = CLIENT_ID_SERVER; NetworkClients *nc = new NetworkClients( CLIENT_ID_SERVER ); strecpy( nc->client_name, game_settings.network_settings.client_settings.clientName, lastof( game_settings.network_settings.client_settings.clientName ) ); nc->client_status = STATUS_AUTHORISED; nc->client_session = 1000000000; // Any number but not 0. CLog::Get().Write( LOG_SERVER, true, "[UDP] Server started." ); my_Server->SendChat( NETWORK_ACTION_JOIN, TYPE_BROADCAST, 0, game_settings.network_settings.server_settings.HostName ); my_Server->SendChat( NETWORK_ACTION_JOIN, TYPE_BROADCAST, 0, Connect_String( "Client(%i): %s has joined.", nc->client_id, nc->client_name ) ); }
/** * Load the specified savegame but on error do different things. * If loading fails due to corrupt savegame, bad version, etc. go back to * a previous correct state. In the menu for example load the intro game again. * @param mode mode of loading, either SL_LOAD or SL_OLD_LOAD * @param newgm switch to this mode of loading fails due to some unknown error * @param filename file to be loaded * @param subdir default directory to look for filename, set to 0 if not needed * @param lf Load filter to use, if NULL: use filename + subdir. */ bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL) { assert(fop == SLO_LOAD); assert(dft == DFT_GAME_FILE || (lf == NULL && dft == DFT_OLD_GAME_FILE)); GameMode ogm = _game_mode; _game_mode = newgm; switch (lf == NULL ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) { case SL_OK: return true; case SL_REINIT: #ifdef ENABLE_NETWORK if (_network_dedicated) { /* * We need to reinit a network map... * We can't simply load the intro game here as that game has many * special cases which make clients desync immediately. So we fall * back to just generating a new game with the current settings. */ DEBUG(net, 0, "Loading game failed, so a new (random) game will be started!"); MakeNewGame(false, true); return false; } if (_network_server) { /* We can't load the intro game as server, so disconnect first. */ NetworkDisconnect(); } #endif /* ENABLE_NETWORK */ switch (ogm) { default: case GM_MENU: LoadIntroGame(); break; case GM_EDITOR: MakeNewEditorWorld(); break; } return false; default: _game_mode = ogm; return false; } }
/* Connection, disconnection and reboot */ void NetworkJoinGame( Network_Address address, unsigned char team_id, const char *join_server_password, const char *join_team_password ) { if( !_network_available ) return; if( _network_dedicated ) return; if( _is_network_server ) return; if( my_Client->isConnected() ) return; /* Check to ensure client pointer exists */ if( my_Client ) { my_Client = new NetworkClientGameSocketHandler(); } NetworkDisconnect(); _network_own_client_id = CLIENT_ID_CLIENT; Packet p( PACKET_CLIENT_JOIN ); p.Send_UChar( NETWORK_GAME_ID ); ///< Unique ID. p.Send_UInt( GAME_REVISION ); ///< Revision ID. p.Send_UInt( my_Client->NetworkSessionID() ); ///< Session id, send 0 if not known. p.Send_String( game_settings.network_settings.client_settings.clientName ); ///< Clients name if( join_server_password == "" ) { p.Send_Bool( false ); }else { p.Send_Bool( true ); p.Send_String( join_server_password ); } if( join_team_password == "" ) { p.Send_Bool( false ); }else { p.Send_Bool( true ); p.Send_UChar( team_id );p.Send_String( join_team_password ); } my_Client->SendPacket( &p, &address, PACKET_TYPE_NETWORK_CORE ); CLog::Get().Write( LOG_CLIENT, true, Connect_String( "[UDP] Connecting to server %i.%i.%i.%i:%i...", address.GetA(), address.GetB(), address.GetC(), address.GetD(), address.GetPort() ) ); }
void SwitchToMode(SwitchMode new_mode) { #ifdef ENABLE_NETWORK /* If we are saving something, the network stays in his current state */ if (new_mode != SM_SAVE_GAME) { /* If the network is active, make it not-active */ if (_networking) { if (_network_server && (new_mode == SM_LOAD_GAME || new_mode == SM_NEWGAME || new_mode == SM_RESTARTGAME)) { NetworkReboot(); } else { NetworkDisconnect(); } } /* If we are a server, we restart the server */ if (_is_network_server) { /* But not if we are going to the menu */ if (new_mode != SM_MENU) { /* check if we should reload the config */ if (_settings_client.network.reload_cfg) { LoadFromConfig(); MakeNewgameSettingsLive(); ResetGRFConfig(false); } NetworkServerStart(); } else { /* This client no longer wants to be a network-server */ _is_network_server = false; } } } #endif /* ENABLE_NETWORK */ /* Make sure all AI controllers are gone at quitting game */ if (new_mode != SM_SAVE_GAME) AI::KillAll(); switch (new_mode) { case SM_EDITOR: // Switch to scenario editor MakeNewEditorWorld(); break; case SM_RESTARTGAME: // Restart --> 'Random game' with current settings case SM_NEWGAME: // New Game --> 'Random game' #ifdef ENABLE_NETWORK if (_network_server) { seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "Random Map"); } #endif /* ENABLE_NETWORK */ MakeNewGame(false, new_mode == SM_NEWGAME); break; case SM_LOAD_GAME: { // Load game, Play Scenario ResetGRFConfig(true); ResetWindowSystem(); if (!SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_NORMAL, NO_DIRECTORY)) { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); } else { if (_file_to_saveload.abstract_ftype == FT_SCENARIO) { /* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */ EngineOverrideManager::ResetToCurrentNewGRFConfig(); } /* Update the local company for a loaded game. It is either always * company #1 (eg 0) or in the case of a dedicated server a spectator */ SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST); /* Execute the game-start script */ IConsoleCmdExec("exec scripts/game_start.scr 0"); /* Decrease pause counter (was increased from opening load dialog) */ DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); #ifdef ENABLE_NETWORK if (_network_server) { seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title); } #endif /* ENABLE_NETWORK */ } break; } case SM_START_HEIGHTMAP: // Load a heightmap and start a new game from it #ifdef ENABLE_NETWORK if (_network_server) { seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "%s (Heightmap)", _file_to_saveload.title); } #endif /* ENABLE_NETWORK */ MakeNewGame(true, true); break; case SM_LOAD_HEIGHTMAP: // Load heightmap from scenario editor SetLocalCompany(OWNER_NONE); GenerateWorld(GWM_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y); MarkWholeScreenDirty(); break; case SM_LOAD_SCENARIO: { // Load scenario from scenario editor if (SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_EDITOR, NO_DIRECTORY)) { SetLocalCompany(OWNER_NONE); _settings_newgame.game_creation.starting_year = _cur_year; /* Cancel the saveload pausing */ DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); } else { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); } break; } case SM_MENU: // Switch to game intro menu LoadIntroGame(); if (BaseSounds::ini_set == NULL && BaseSounds::GetUsedSet()->fallback) { ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL); BaseSounds::ini_set = stredup(BaseSounds::GetUsedSet()->name); } break; case SM_SAVE_GAME: // Save game. /* Make network saved games on pause compatible to singleplayer */ if (SaveOrLoad(_file_to_saveload.name, SLO_SAVE, DFT_GAME_FILE, NO_DIRECTORY) != SL_OK) { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); } else { DeleteWindowById(WC_SAVELOAD, 0); } break; case SM_SAVE_HEIGHTMAP: // Save heightmap. MakeHeightmapScreenshot(_file_to_saveload.name); DeleteWindowById(WC_SAVELOAD, 0); break; case SM_GENRANDLAND: // Generate random land within scenario editor SetLocalCompany(OWNER_NONE); GenerateWorld(GWM_RANDOM, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y); /* XXX: set date */ MarkWholeScreenDirty(); break; default: NOT_REACHED(); } }