//////////////////////////////////////////////////////////// // MPLobby //////////////////////////////////////////////////////////// MPLobby::MPLobby(my_context ctx) : Base(ctx) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby"; Client().Register(Client().GetClientUI().GetMultiPlayerLobbyWnd()); }
/** \brief Return a vector of absolute paths to files in the given path * * @param[in] path relative or absolute directory (searched recursively) * @return Any regular files in * @return if absolute directory: path * @return if relative directory: GetResourceDir() / path */ std::vector<fs::path> ListDir(const fs::path& path) { std::vector<fs::path> retval; bool is_rel = path.is_relative(); if (!is_rel && (fs::is_empty(path) || !fs::is_directory(path))) { DebugLogger() << "ListDir: File " << PathToString(path) << " was not included as it is empty or not a directoy"; } else { const fs::path& default_path = is_rel ? GetResourceDir() / path : path; for (fs::recursive_directory_iterator dir_it(default_path); dir_it != fs::recursive_directory_iterator(); ++dir_it) { if (fs::is_regular_file(dir_it->status())) { retval.push_back(dir_it->path()); } else if (!fs::is_directory(dir_it->status())) { TraceLogger() << "Parse: Unknown file not included: " << PathToString(dir_it->path()); } } } if (retval.empty()) { DebugLogger() << "ListDir: No files found for " << path.string(); } return retval; }
boost::statechart::result MPLobby::react(const LobbyUpdate& msg) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby.LobbyUpdate"; MultiplayerLobbyData lobby_data; ExtractLobbyUpdateMessageData(msg.m_message, lobby_data); Client().GetClientUI().GetMultiPlayerLobbyWnd()->LobbyUpdate(lobby_data); return discard_event(); }
void Species::Init() { for (auto& effect : m_effects) { effect->SetTopLevelContent(m_name); } if (!m_location) { // set up a Condition structure to match popcenters that have // (not uninhabitable) environment for this species std::vector<std::unique_ptr<ValueRef::ValueRefBase< ::PlanetEnvironment>>> environments_vec; environments_vec.push_back( boost::make_unique<ValueRef::Constant<PlanetEnvironment>>( ::PE_UNINHABITABLE)); auto this_species_name_ref = boost::make_unique<ValueRef::Constant<std::string>>(m_name); // m_name specifies this species auto enviro_cond = std::unique_ptr<Condition::ConditionBase>( boost::make_unique<Condition::Not>( std::unique_ptr<Condition::ConditionBase>( boost::make_unique<Condition::PlanetEnvironment>( std::move(environments_vec), std::move(this_species_name_ref))))); auto type_cond = std::unique_ptr<Condition::ConditionBase>(boost::make_unique<Condition::Type>( boost::make_unique<ValueRef::Constant<UniverseObjectType>>( ::OBJ_POP_CENTER))); std::vector<std::unique_ptr<Condition::ConditionBase>> operands; operands.push_back(std::move(enviro_cond)); operands.push_back(std::move(type_cond)); m_location = std::unique_ptr<Condition::ConditionBase>(boost::make_unique<Condition::And>(std::move(operands))); } m_location->SetTopLevelContent(m_name); if (m_combat_targets) m_combat_targets->SetTopLevelContent(m_name); TraceLogger() << "Species::Init: " << Dump(); }
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(); }
boost::statechart::result WaitingForMPJoinAck::react(const JoinGame& msg) { TraceLogger(FSM) << "(HumanClientFSM) WaitingForMPJoinAck.JoinGame"; try { int player_id; boost::uuids::uuid cookie; ExtractJoinAckMessageData(msg.m_message, player_id, cookie); if (!cookie.is_nil()) { try { std::string cookie_option = "network.server.cookie." + Client().Networking().Destination(); GetOptionsDB().Remove(cookie_option); GetOptionsDB().Add(cookie_option, "OPTIONS_DB_SERVER_COOKIE", boost::uuids::to_string(cookie)); GetOptionsDB().Commit(); } catch(const std::exception& err) { WarnLogger() << "Cann't save cookie for server " << Client().Networking().Destination() << ": " << err.what(); // ignore } } Client().Networking().SetPlayerID(player_id); return transit<MPLobby>(); } catch (const boost::bad_lexical_cast& ex) { ErrorLogger(FSM) << "WaitingForMPJoinAck::react(const JoinGame& msg) Host id " << msg.m_message.Text() << " is not a number: " << ex.what(); return transit<IntroMenu>(); } }
boost::statechart::result PlayingTurn::react(const SaveGameDataRequest& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingTurn.SaveGameDataRequest"; DebugLogger(FSM) << "Sending Save Game Data to Server"; Client().GetClientUI().GetMessageWnd()->HandleGameStatusUpdate(UserString("SERVER_SAVE_INITIATE_ACK") + "\n"); Client().HandleSaveGameDataRequest(); return discard_event(); }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.TurnUpdate"; int current_turn = INVALID_GAME_TURN; try { ExtractTurnUpdateMessageData(msg.m_message, Client().EmpireID(), current_turn, Empires(), GetUniverse(), GetSpeciesManager(), GetCombatLogManager(), GetSupplyManager(), Client().Players()); } catch (...) { Client().GetClientUI().GetMessageWnd()->HandleLogMessage(UserString("ERROR_PROCESSING_SERVER_MESSAGE") + "\n"); return discard_event(); } DebugLogger(FSM) << "Extracted TurnUpdate message for turn: " << current_turn; Client().SetCurrentTurn(current_turn); // if I am the host, do autosave if (Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); Client().HandleTurnUpdate(); return transit<PlayingTurn>(); }
std::locale GetLocale(const std::string& name) { static bool locale_init { false }; // Initialize backend and generator on first use, provide a log for current enivornment locale static auto locale_backend = boost::locale::localization_backend_manager::global(); if (!locale_init) locale_backend.select("std"); static boost::locale::generator locale_gen(locale_backend); if (!locale_init) { locale_gen.locale_cache_enabled(true); try { InfoLogger() << "Global locale: " << std::use_facet<boost::locale::info>(locale_gen("")).name(); } catch (const std::runtime_error&) { ErrorLogger() << "Global locale: set to invalid locale, setting to C locale"; std::locale::global(std::locale::classic()); } locale_init = true; } std::locale retval; try { retval = locale_gen(name); } catch(const std::runtime_error&) { ErrorLogger() << "Requested locale \"" << name << "\" is not a valid locale for this operating system"; return std::locale::classic(); } TraceLogger() << "Requested " << (name.empty() ? "(default)" : name) << " locale" << " returning " << std::use_facet<boost::locale::info>(retval).name(); return retval; }
boost::statechart::result PlayingGame::react(const StartQuittingGame& e) { TraceLogger(FSM) << "(HumanClientFSM) Quit or reset to main menu."; Client().GetClientUI().GetMessageWnd()->HandleGameStatusUpdate(UserString("RETURN_TO_INTRO") + "\n"); post_event(e); return transit<QuittingGame>(); }
boost::statechart::result WaitingForMPJoinAck::react(const CancelMPGameClicked& a) { TraceLogger(FSM) << "(HumanClientFSM) WaitingForMPJoinAck.CancelMPGameClicked"; // See reaction_transition_note. auto retval = discard_event(); Client().ResetToIntro(true); return retval; }
boost::statechart::result QuittingGame::react(const StartQuittingGame& u) { TraceLogger(FSM) << "(HumanClientFSM) QuittingGame"; m_server_process = &u.m_server; m_after_server_shutdown_action = u.m_after_server_shutdown_action; post_event(ShutdownServer()); return discard_event(); }
boost::statechart::result QuittingGame::react(const StartQuittingGame& u) { TraceLogger(FSM) << "(HumanClientFSM) QuittingGame reset to intro is " << u.m_reset_to_intro; m_reset_to_intro = u.m_reset_to_intro; m_server_process = &u.m_server; post_event(ShutdownServer()); return discard_event(); }
boost::statechart::result PlayingGame::react(const TurnPartialUpdate& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.TurnPartialUpdate"; ExtractTurnPartialUpdateMessageData(msg.m_message, Client().EmpireID(), GetUniverse()); Client().GetClientUI().GetMapWnd()->MidTurnUpdate(); return discard_event(); }
boost::statechart::result PlayingGame::react(const TurnProgress& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.TurnProgress"; Message::TurnProgressPhase phase_id; ExtractTurnProgressMessageData(msg.m_message, phase_id); Client().HandleTurnPhaseUpdate(phase_id); return discard_event(); }
//////////////////////////////////////////////////////////// // MPLobby //////////////////////////////////////////////////////////// MPLobby::MPLobby(my_context ctx) : Base(ctx) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby"; const auto& wnd = Client().GetClientUI().GetMultiPlayerLobbyWnd(); Client().Register(wnd); wnd->CleanupChat(); }
boost::statechart::result PlayingGame::react(const DiplomaticStatusUpdate& u) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.DiplomaticStatusUpdate"; DiplomaticStatusUpdateInfo diplo_update; ExtractDiplomaticStatusMessageData(u.m_message, diplo_update); Empires().SetDiplomaticStatus(diplo_update.empire1_id, diplo_update.empire2_id, diplo_update.diplo_status); return discard_event(); }
boost::statechart::result PlayingGame::react(const Disconnection& d) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.Disconnection"; // See reaction_transition_note. auto retval = discard_event(); Client().ResetToIntro(true); ClientUI::MessageBox(UserString("SERVER_LOST"), true); return retval; }
boost::statechart::result PlayingGame::react(const Diplomacy& d) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.Diplomacy"; DiplomaticMessage diplo_message; ExtractDiplomacyMessageData(d.m_message, diplo_message); Empires().SetDiplomaticMessage(diplo_message); return discard_event(); }
//////////////////////////////////////////////////////////// // PlayingGame //////////////////////////////////////////////////////////// PlayingGame::PlayingGame(my_context ctx) : Base(ctx) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame"; Client().Register(Client().GetClientUI().GetMapWnd()); Client().GetClientUI().GetMapWnd()->Show(); Client().GetClientUI().GetMessageWnd()->Clear(); }
boost::statechart::result MPLobby::react(const CancelMPGameClicked& a) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby.CancelMPGameClicked"; // See reaction_transition_note. auto retval = discard_event(); Client().ResetToIntro(); return retval; }
boost::statechart::result MPLobby::react(const CheckSum& e) { TraceLogger(FSM) << "(HumanClientFSM) CheckSum."; std::map<std::string, unsigned int> checksums; ExtractContentCheckSumMessageData(e.m_message, checksums); InfoLogger() << "Got checksum message from server:"; for (const auto& c : checksums) InfoLogger() << c.first << " : " << c.second; return discard_event(); }
boost::statechart::result MPLobby::react(const StartMPGameClicked& a) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby.StartMPGameClicked"; if (Client().Networking().PlayerIsHost(Client().Networking().PlayerID())) Client().Networking().SendMessage(StartMPGameMessage()); else ErrorLogger(FSM) << "MPLobby::react received start MP game event but this client is not the host. Ignoring"; return discard_event(); // wait for server response GameStart message to leave this state... }
boost::statechart::result PlayingGame::react(const PlayerChat& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.PlayerChat: " << msg.m_message.Text(); std::string text; int sending_player_id; ExtractPlayerChatMessageData(msg.m_message, sending_player_id, text); Client().GetClientUI().GetMessageWnd()->HandlePlayerChatMessage(text, sending_player_id, Client().PlayerID()); return discard_event(); }
/** The QuittingGame state expects to start with a StartQuittingGame message posted. */ QuittingGame::QuittingGame(my_context c) : my_base(c), m_start_time(Clock::now()) { // Quit the game by sending a shutdown message to the server and waiting for // the disconnection event. Free the server if it starts an orderly // shutdown, otherwise kill it. TraceLogger(FSM) << "(Host) QuittingGame"; }
//////////////////////////////////////////////////////////// // WaitingForGameStart //////////////////////////////////////////////////////////// WaitingForGameStart::WaitingForGameStart(my_context ctx) : Base(ctx) { TraceLogger(FSM) << "(HumanClientFSM) WaitingForGameStart"; Client().Register(Client().GetClientUI().GetMessageWnd()); Client().Register(Client().GetClientUI().GetPlayerListWnd()); Client().GetClientUI().GetMapWnd()->EnableOrderIssuing(false); }
boost::statechart::result MPLobby::react(const PlayerChat& msg) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby.PlayerChat"; int player_id; std::string data; ExtractServerPlayerChatMessageData(msg.m_message, player_id, data); Client().GetClientUI().GetMultiPlayerLobbyWnd()->ChatMessage(player_id, data); return discard_event(); }
boost::statechart::result PlayingTurn::react(const TurnUpdate& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingTurn.TurnUpdate"; Client().GetClientUI().GetMessageWnd()->HandleLogMessage(UserString("ERROR_EARLY_TURN_UPDATE") + "\n"); // need to re-post the game start message to be re-handled after // transitioning into WaitingForTurnData post_event(msg); return transit<WaitingForTurnData>(); }
boost::statechart::result MPLobby::react(const GameStart& msg) { TraceLogger(FSM) << "(HumanClientFSM) MPLobby.GameStart"; // need to re-post the game start message to be re-handled after // transitioning into WaitingForGameStart post_event(msg); Client().GetClientUI().GetMapWnd()->Sanitize(); Client().Remove(Client().GetClientUI().GetMultiPlayerLobbyWnd()); return transit<WaitingForGameStart>(); }
boost::statechart::result PlayingGame::react(const LobbyUpdate& msg) { TraceLogger(FSM) << "(HumanClientFSM) PlayingGame.LobbyUpdate"; // need to re-post the lobby update message to be re-handled after // transitioning into MPLobby post_event(msg); Client().ResetClientData(true); Client().GetClientUI().ShowMultiPlayerLobbyWnd(); return transit<MPLobby>(); }