boost::statechart::result QuittingGame::react(const ShutdownServer& u) { TraceLogger(FSM) << "(HumanClientFSM) QuittingGame.ShutdownServer"; if (!m_server_process) { ErrorLogger(FSM) << "m_server_process is nullptr"; post_event(TerminateServer()); return discard_event(); } if (m_server_process->Empty()) { if (Client().Networking().IsTxConnected()) { WarnLogger(FSM) << "Disconnecting from server that is already killed."; Client().Networking().DisconnectFromServer(); } post_event(TerminateServer()); return discard_event(); } if (Client().Networking().IsTxConnected()) { DebugLogger(FSM) << "Sending server shutdown message."; Client().Networking().SendMessage(ShutdownServerMessage()); post_event(WaitForDisconnect()); } else { post_event(TerminateServer()); } return discard_event(); }
void HumanClientApp::EndGame(bool suppress_FSM_reset) { DebugLogger() << "HumanClientApp::EndGame"; m_game_started = false; if (m_networking.Connected()) { DebugLogger() << "HumanClientApp::EndGame Sending server shutdown message."; m_networking.SendMessage(ShutdownServerMessage(m_networking.PlayerID())); boost::this_thread::sleep(boost::posix_time::seconds(1)); m_networking.DisconnectFromServer(); if (!m_networking.Connected()) DebugLogger() << "HumanClientApp::EndGame Disconnected from server."; else ErrorLogger() << "HumanClientApp::EndGame Unexpectedly still connected to server...?"; } if (!m_server_process.Empty()) { DebugLogger() << "HumanClientApp::EndGame Terminated server process."; m_server_process.RequestTermination(); } m_networking.SetPlayerID(Networking::INVALID_PLAYER_ID); m_networking.SetHostPlayerID(Networking::INVALID_PLAYER_ID); SetEmpireID(ALL_EMPIRES); m_ui->GetMapWnd()->Sanitize(); m_universe.Clear(); m_empires.Clear(); m_orders.Reset(); GetCombatLogManager().Clear(); if (!suppress_FSM_reset) m_fsm->process_event(ResetToIntroMenu()); }
void HumanClientApp::NewSinglePlayerGame(bool quickstart) { if (!GetOptionsDB().Get<bool>("force-external-server")) { try { StartServer(); } catch (const std::runtime_error& err) { ErrorLogger() << "HumanClientApp::NewSinglePlayerGame : Couldn't start server. Got error message: " << err.what(); ClientUI::MessageBox(UserString("SERVER_WONT_START"), true); return; } } bool ended_with_ok = false; if (!quickstart) { GalaxySetupWnd galaxy_wnd; galaxy_wnd.Run(); ended_with_ok = galaxy_wnd.EndedWithOk(); } bool failed = false; unsigned int start_time = Ticks(); while (!m_networking.ConnectToLocalHostServer(boost::posix_time::seconds(2))) { if (SERVER_CONNECT_TIMEOUT < Ticks() - start_time) { ClientUI::MessageBox(UserString("ERR_CONNECT_TIMED_OUT"), true); failed = true; break; } } m_connected = !failed; if (!failed && (quickstart || ended_with_ok)) { DebugLogger() << "HumanClientApp::NewSinglePlayerGame : Connected to server"; SinglePlayerSetupData setup_data; setup_data.m_new_game = true; setup_data.m_filename.clear(); // not used for new game // get values stored in options from previous time game was run or // from just having run GalaxySetupWnd // GalaxySetupData setup_data.m_seed = GetOptionsDB().Get<std::string>("GameSetup.seed"); setup_data.m_size = GetOptionsDB().Get<int>("GameSetup.stars"); setup_data.m_shape = GetOptionsDB().Get<Shape>("GameSetup.galaxy-shape"); setup_data.m_age = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.galaxy-age"); setup_data.m_starlane_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.starlane-frequency"); setup_data.m_planet_density = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.planet-density"); setup_data.m_specials_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.specials-frequency"); setup_data.m_monster_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.monster-frequency"); setup_data.m_native_freq = GetOptionsDB().Get<GalaxySetupOption>("GameSetup.native-frequency"); setup_data.m_ai_aggr = GetOptionsDB().Get<Aggression>("GameSetup.ai-aggression"); // SinglePlayerSetupData contains a map of PlayerSetupData, for // the human and AI players. Need to compile this information // from the specified human options and number of requested AIs // Human player setup data first PlayerSetupData human_player_setup_data; human_player_setup_data.m_player_name = GetOptionsDB().Get<std::string>("GameSetup.player-name"); human_player_setup_data.m_empire_name = GetOptionsDB().Get<std::string>("GameSetup.empire-name"); // DB stores index into array of available colours, so need to get that array to look up value of index. // if stored value is invalid, use a default colour const std::vector<GG::Clr>& empire_colours = EmpireColors(); int colour_index = GetOptionsDB().Get<int>("GameSetup.empire-color"); if (colour_index >= 0 && colour_index < static_cast<int>(empire_colours.size())) human_player_setup_data.m_empire_color = empire_colours[colour_index]; else human_player_setup_data.m_empire_color = GG::CLR_GREEN; human_player_setup_data.m_starting_species_name = GetOptionsDB().Get<std::string>("GameSetup.starting-species"); if (human_player_setup_data.m_starting_species_name == "1") human_player_setup_data.m_starting_species_name = "SP_HUMAN"; // kludge / bug workaround for bug with options storage and retreival. Empty-string options are stored, but read in as "true" boolean, and converted to string equal to "1" if (!GetSpecies(human_player_setup_data.m_starting_species_name)) { const SpeciesManager& sm = GetSpeciesManager(); if (sm.NumPlayableSpecies() < 1) human_player_setup_data.m_starting_species_name.clear(); else human_player_setup_data.m_starting_species_name = sm.playable_begin()->first; } human_player_setup_data.m_save_game_empire_id = ALL_EMPIRES; // not used for new games human_player_setup_data.m_client_type = Networking::CLIENT_TYPE_HUMAN_PLAYER; // add to setup data players setup_data.m_players.push_back(human_player_setup_data); // AI player setup data. One entry for each requested AI int num_AIs = GetOptionsDB().Get<int>("GameSetup.ai-players"); for (int ai_i = 1; ai_i <= num_AIs; ++ai_i) { PlayerSetupData ai_setup_data; ai_setup_data.m_player_name = "AI_" + boost::lexical_cast<std::string>(ai_i); ai_setup_data.m_empire_name.clear(); // leave blank, to be set by server in Universe::GenerateEmpires ai_setup_data.m_empire_color = GG::CLR_ZERO; // to be set by server ai_setup_data.m_starting_species_name.clear(); // leave blank, to be set by server ai_setup_data.m_save_game_empire_id = ALL_EMPIRES; // not used for new games ai_setup_data.m_client_type = Networking::CLIENT_TYPE_AI_PLAYER; setup_data.m_players.push_back(ai_setup_data); } m_networking.SendMessage(HostSPGameMessage(setup_data)); m_fsm->process_event(HostSPGameRequested()); } else { DebugLogger() << "HumanClientApp::NewSinglePlayerGame killing server due to canceled game or server connection failure"; if (m_networking.Connected()) { DebugLogger() << "HumanClientApp::NewSinglePlayerGame Sending server shutdown message."; m_networking.SendMessage(ShutdownServerMessage(m_networking.PlayerID())); boost::this_thread::sleep(boost::posix_time::seconds(1)); m_networking.DisconnectFromServer(); if (!m_networking.Connected()) DebugLogger() << "HumanClientApp::NewSinglePlayerGame Disconnected from server."; else ErrorLogger() << "HumanClientApp::NewSinglePlayerGame Unexpectedly still connected to server...?"; } KillServer(); } }