boost::statechart::result MPLobby::react(const LobbyUpdate& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) MPLobby.LobbyUpdate"; MultiplayerLobbyData lobby_data; ExtractMessageData(msg.m_message, lobby_data); Client().GetClientUI()->GetMultiPlayerLobbyWnd()->LobbyUpdate(lobby_data); return discard_event(); }
void HumanClientApp::RequestSavePreviews(const std::string& directory, PreviewInformation& previews){ std::string generic_directory = fs::path(directory).generic_string(); if(!m_networking.Connected()){ DebugLogger() << "HumanClientApp::RequestSavePreviews: No game running. Start a server for savegame queries."; StartServer(); DebugLogger() << "HumanClientApp::RequestSavePreviews Connecting to server"; unsigned int start_time = Ticks(); while (!m_networking.ConnectToLocalHostServer()) { if (SERVER_CONNECT_TIMEOUT < Ticks() - start_time) { ErrorLogger() << "HumanClientApp::LoadSinglePlayerGame() server connecting timed out"; ClientUI::MessageBox(UserString("ERR_CONNECT_TIMED_OUT"), true); KillServer(); return; } } m_connected = true; } DebugLogger() << "HumanClientApp::RequestSavePreviews Requesting previews for " << generic_directory; Message response; m_networking.SendSynchronousMessage(RequestSavePreviewsMessage(PlayerID(), generic_directory), response); if (response.Type() == Message::DISPATCH_SAVE_PREVIEWS){ ExtractMessageData(response, previews); DebugLogger() << "HumanClientApp::RequestSavePreviews Got " << previews.previews.size() << " previews."; }else{ ErrorLogger() << "HumanClientApp::RequestSavePreviews: Wrong response type from server: " << EnumToString(response.Type()); } }
boost::statechart::result PlayingGame::react(const EndGame& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.EndGame"; Message::EndGameReason reason; std::string reason_player_name; ExtractMessageData(msg.m_message, reason, reason_player_name); std::string reason_message; bool error = false; switch (reason) { case Message::LOCAL_CLIENT_DISCONNECT: Client().EndGame(true); reason_message = UserString("SERVER_LOST"); break; case Message::PLAYER_DISCONNECT: Client().EndGame(true); reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name); error = true; break; } //Note: Any transit<> transition must occur before the MessageBox(). // MessageBox blocks and can allow other events to transit<> to a new state // which makes this transit fatal. boost::statechart::result retval = transit<IntroMenu>(); ClientUI::MessageBox(reason_message, error); return retval; }
boost::statechart::result PlayingGame::react(const EndGame& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) PlayingGame.EndGame"; Message::EndGameReason reason; std::string reason_player_name; ExtractMessageData(msg.m_message, reason, reason_player_name); std::string reason_message; bool error = false; switch (reason) { case Message::LOCAL_CLIENT_DISCONNECT: Client().EndGame(true); reason_message = UserString("SERVER_LOST"); break; case Message::PLAYER_DISCONNECT: Client().EndGame(true); reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name); error = true; break; case Message::YOU_ARE_ELIMINATED: Client().EndGame(true); reason_message = UserString("PLAYER_DEFEATED"); break; } ClientUI::MessageBox(reason_message, error); return transit<IntroMenu>(); }
boost::statechart::result PlayingGame::react(const EndGame& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.EndGame"; Message::EndGameReason reason; std::string reason_player_name; ExtractMessageData(msg.m_message, reason, reason_player_name); std::string reason_message; bool error = false; switch (reason) { case Message::LOCAL_CLIENT_DISCONNECT: Client().EndGame(true); reason_message = UserString("SERVER_LOST"); break; case Message::PLAYER_DISCONNECT: Client().EndGame(true); reason_message = boost::io::str(FlexibleFormat(UserString("PLAYER_DISCONNECTED")) % reason_player_name); error = true; break; case Message::YOU_ARE_ELIMINATED: Client().EndGame(true); reason_message = UserString("PLAYER_DEFEATED"); break; } ClientUI::MessageBox(reason_message, error); Client().Remove(Client().GetClientUI()->GetMapWnd()); Client().GetClientUI()->GetMapWnd()->RemoveWindows(); Client().Networking().SetHostPlayerID(Networking::INVALID_PLAYER_ID); Client().Networking().SetPlayerID(Networking::INVALID_PLAYER_ID); return transit<IntroMenu>(); }
boost::statechart::result WaitingForTurnData::react(const GameStart& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.GameStart"; bool loaded_game_data; bool ui_data_available; SaveGameUIData ui_data; bool save_state_string_available; std::string save_state_string; // ignored - used by AI but not by human client OrderSet orders; ExtractMessageData(msg.m_message, Client().m_single_player_game, Client().EmpireIDRef(), Client().CurrentTurnRef(), Empires(), GetUniverse(), GetSpeciesManager(), Client().m_player_info, orders, loaded_game_data, ui_data_available, ui_data, save_state_string_available, save_state_string); Client().StartGame(); std::swap(Client().Orders(), orders); // bring back orders planned in the current turn, they will be applied later, after some basic turn initialization if (loaded_game_data && ui_data_available) Client().m_ui->RestoreFromSaveData(ui_data); // if I am the host on the first turn, do an autosave. on later turns, will // have just loaded save, so don't need to autosave. might also have just // loaded a turn 1 autosave, but not sure how to check for that here... if (Client().CurrentTurn() == 1 && Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result PlayingGame::react(const DiplomaticStatusUpdate& u) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.DiplomaticStatusUpdate"; DiplomaticStatusUpdateInfo diplo_update; ExtractMessageData(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 TurnProgress& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.TurnProgress"; Message::TurnProgressPhase phase_id; ExtractMessageData(msg.m_message, phase_id); Client().GetClientUI()->GetMessageWnd()->HandleTurnPhaseUpdate(phase_id); return discard_event(); }
boost::statechart::result PlayingGame::react(const Diplomacy& d) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.Diplomacy"; DiplomaticMessage diplo_message; ExtractMessageData(d.m_message, diplo_message); Empires().SetDiplomaticMessage(diplo_message); return discard_event(); }
boost::statechart::result WaitingForTurnData::react(const TurnPartialUpdate& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.TurnPartialUpdate"; ExtractMessageData(msg.m_message, Client().EmpireID(), GetUniverse()); Client().m_ui->GetMapWnd()->MidTurnUpdate(); return discard_event(); }
boost::statechart::result WaitingForTurnData::react(const TurnProgress& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.TurnProgress"; Message::TurnProgressPhase phase_id; ExtractMessageData(msg.m_message, phase_id); Client().m_ui->GetMessageWnd()->HandleTurnPhaseUpdate(phase_id); return discard_event(); }
boost::statechart::result PlayingGame::react(const TurnPartialUpdate& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.TurnPartialUpdate"; ExtractMessageData(msg.m_message, Client().EmpireID(), GetUniverse()); Client().GetClientUI()->GetMapWnd()->MidTurnUpdate(); return discard_event(); }
boost::statechart::result PlayingGame::react(const PlayerEliminated& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.PlayerEliminated"; int empire_id; std::string empire_name; ExtractMessageData(msg.m_message, empire_id, empire_name); Client().EmpireEliminatedSignal(empire_id); // TODO: replace this with something better //ClientUI::MessageBox(boost::io::str(FlexibleFormat(UserString("EMPIRE_DEFEATED")) % empire_name)); return discard_event(); }
boost::statechart::result ResolvingCombat::react(const CombatStart& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) ResolvingCombat.CombatStart"; std::vector<CombatSetupGroup> setup_groups; Universe::ShipDesignMap foreign_designs; ExtractMessageData(msg.m_message, *m_combat_data, setup_groups, foreign_designs); for (Universe::ShipDesignMap::const_iterator it = foreign_designs.begin(); it != foreign_designs.end(); ++it) { GetUniverse().InsertShipDesignID(it->second, it->first); } m_combat_wnd->InitCombat(*m_combat_data, setup_groups); return discard_event(); }
boost::statechart::result ResolvingCombat::react(const CombatRoundUpdate& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) ResolvingCombat.CombatRoundUpdate"; if (m_previous_combat_data.get()) { FreeCombatData(m_previous_combat_data.get()); m_previous_combat_data.release(); } m_previous_combat_data = m_combat_data; m_combat_data.reset(new CombatData); ExtractMessageData(msg.m_message, *m_combat_data); m_combat_wnd->CombatTurnUpdate(*m_combat_data); return discard_event(); }
boost::statechart::result PlayingGame::react(const PlayerStatus& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) PlayingGame.PlayerStatus"; int about_player_id; Message::PlayerStatus status; ExtractMessageData(msg.m_message, about_player_id, status); Client().m_ui->GetMessageWnd()->HandlePlayerStatusUpdate(status, about_player_id); Client().m_ui->GetPlayerListWnd()->HandlePlayerStatusUpdate(status, about_player_id); // TODO: tell the map wnd or something else as well? return discard_event(); }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.TurnUpdate"; ExtractMessageData(msg.m_message, Client().EmpireID(), Client().CurrentTurnRef(), Empires(), GetUniverse(), GetSpeciesManager(), Client().m_player_info); // if I am the host, do autosave if (Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) WaitingForTurnData.TurnUpdate"; ExtractMessageData(msg.m_message, Client().EmpireID(), Client().CurrentTurnRef(), Empires(), GetUniverse(), GetSpeciesManager(), Client().m_player_info); // if I am the host, do autosave for (std::map<int, PlayerInfo>::const_iterator it = Client().m_player_info.begin(); it != Client().m_player_info.end(); ++it) if (it->second.host && it->first == Client().PlayerID()) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result PlayingTurn::react(const SaveGameComplete& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingTurn.SaveGameComplete"; std::string save_filename; int bytes_written; ExtractMessageData(msg.m_message, save_filename, bytes_written); Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate( boost::io::str(FlexibleFormat(UserString("SERVER_SAVE_COMPLETE")) % save_filename % bytes_written) + "\n"); DebugLogger() << "Save Complete on Server"; return discard_event(); }
boost::statechart::result PlayingGame::react(const VictoryDefeat& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.VictoryDefeat"; Message::VictoryOrDefeat victory_or_defeat; std::string reason_string; int empire_id; ExtractMessageData(msg.m_message, victory_or_defeat, reason_string, empire_id); const Empire* empire = GetEmpire(empire_id); std::string empire_name = UserString("UNKNOWN_EMPIRE"); if (empire) empire_name = empire->Name(); //ClientUI::MessageBox(boost::io::str(FlexibleFormat(UserString(reason_string)) % empire_name)); return discard_event(); }
boost::statechart::result PlayingGame::react(const Error& msg) { if (TRACE_EXECUTION) Logger().debugStream() << "(HumanClientFSM) PlayingGame.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); Logger().errorStream() << "PlayingGame::react(const Error& msg) error: " << problem; ClientUI::MessageBox(UserString(problem), true); if (fatal) { Client().m_ui->GetMessageWnd()->HandleGameStatusUpdate(UserString("RETURN_TO_INTRO") + "\n"); return transit<IntroMenu>(); } else { return discard_event(); } }
boost::statechart::result WaitingForMPJoinAck::react(const Error& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) WaitingForMPJoinAck.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); ErrorLogger() << "WaitingForMPJoinAck::react(const Error& msg) error: " << problem; ClientUI::MessageBox(UserString(problem), true); if (fatal) { Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate(UserString("RETURN_TO_INTRO") + "\n"); return transit<IntroMenu>(); } else { return discard_event(); } }
boost::statechart::result MPLobby::react(const Error& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) MPLobby.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); ErrorLogger() << "MPLobby::react(const Error& msg) error: " << problem; ClientUI::MessageBox(UserString(problem), true); if (fatal) { Client().Remove(Client().GetClientUI()->GetMultiPlayerLobbyWnd()); return transit<IntroMenu>(); } else { return discard_event(); } }
boost::statechart::result MPLobby::react(const Error& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) MPLobby.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); ErrorLogger() << "MPLobby::react(const Error& msg) error: " << problem; //Note: Any transit<> transition must occur before the MessageBox(). // MessageBox blocks and can allow other events to transit<> to a new state // which makes this transit fatal. boost::statechart::result retval = fatal ? transit<IntroMenu>() : discard_event(); if (fatal) ClientUI::MessageBox(UserString(problem), true); return retval; }
boost::statechart::result PlayingTurn::react(const PlayerStatus& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingTurn.PlayerStatus"; int about_player_id; Message::PlayerStatus status; ExtractMessageData(msg.m_message, about_player_id, status); Client().SetPlayerStatus(about_player_id, status); Client().GetClientUI()->GetMessageWnd()->HandlePlayerStatusUpdate(status, about_player_id); Client().GetClientUI()->GetPlayerListWnd()->HandlePlayerStatusUpdate(status, about_player_id); if (Client().GetApp()->GetClientType() == Networking::CLIENT_TYPE_HUMAN_MODERATOR && Client().GetClientUI()->GetMapWnd()->AutoEndTurnEnabled()) { // check status of all non-mod non-obs players: are they all done their turns? bool all_participants_waiting = true; const std::map<int, Message::PlayerStatus>& player_status = Client().PlayerStatus(); const std::map<int, PlayerInfo>& players = Client().Players(); for (std::map<int, PlayerInfo>::const_iterator it = players.begin(); it != players.end(); ++it) { int player_id = it->first; if (it->second.client_type != Networking::CLIENT_TYPE_AI_PLAYER && it->second.client_type != Networking::CLIENT_TYPE_HUMAN_PLAYER) { continue; } // only active participants matter... std::map<int, Message::PlayerStatus>::const_iterator status_it = player_status.find(player_id); if (status_it == player_status.end()) { all_participants_waiting = false; break; } if (status_it->second != Message::WAITING) { all_participants_waiting = false; break; } } // if all participants waiting, can end turn immediately if (all_participants_waiting) post_event(AdvanceTurn()); } return discard_event(); }
boost::statechart::result PlayingGame::react(const Error& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); ErrorLogger() << "PlayingGame::react(const Error& msg) error: " << problem; ClientUI::MessageBox(UserString(problem), true); if (fatal) { Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate(UserString("RETURN_TO_INTRO") + "\n"); Client().Remove(Client().GetClientUI()->GetMapWnd()); Client().Networking().SetHostPlayerID(Networking::INVALID_PLAYER_ID); Client().Networking().SetPlayerID(Networking::INVALID_PLAYER_ID); return transit<IntroMenu>(); } else { return discard_event(); } }
boost::statechart::result WaitingForMPJoinAck::react(const Error& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) WaitingForMPJoinAck.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); ErrorLogger() << "WaitingForMPJoinAck::react(const Error& msg) error: " << problem; //Note: Any transit<> transition must occur before the MessageBox(). // MessageBox blocks and can allow other events to transit<> to a new state // which makes this transit fatal. boost::statechart::result retval = fatal ? transit<IntroMenu>() : discard_event(); if (fatal) { ClientUI::MessageBox(UserString(problem), true); Client().GetClientUI()->GetMessageWnd()->HandleGameStatusUpdate(UserString("RETURN_TO_INTRO") + "\n"); } return retval; }
boost::statechart::result PlayingGame::react(const Error& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.Error"; std::string problem; bool fatal; ExtractMessageData(msg.m_message, problem, fatal); ErrorLogger() << "PlayingGame::react(const Error& msg) error: " << problem << "\nProblem is" <<(fatal ? "":"non-")<<" fatal"; //Note: Any transit<> transition must occur before the MessageBox(). // MessageBox blocks and can allow other events to transit<> to a new state // which makes this transit fatal. boost::statechart::result retval = fatal ? transit<IntroMenu>() : discard_event(); ClientUI::MessageBox(UserString(problem), false); if (fatal) { ClientUI::MessageBox(UserString(problem), true); Client().EndGame(true); } return retval; }
boost::statechart::result WaitingForGameStart::react(const GameStart& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) WaitingForGameStart.GameStart"; bool loaded_game_data; bool ui_data_available; SaveGameUIData ui_data; bool save_state_string_available; std::string save_state_string; // ignored - used by AI but not by human client OrderSet orders; bool single_player_game = false; int empire_id = ALL_EMPIRES; int current_turn = INVALID_GAME_TURN; Client().PlayerStatus().clear(); ExtractMessageData(msg.m_message, single_player_game, empire_id, current_turn, Empires(), GetUniverse(), GetSpeciesManager(), GetCombatLogManager(), Client().Players(), orders, loaded_game_data, ui_data_available, ui_data, save_state_string_available, save_state_string, Client().GetGalaxySetupData()); DebugLogger() << "Extracted GameStart message for turn: " << current_turn << " with empire: " << empire_id; Client().SetSinglePlayerGame(single_player_game); Client().SetEmpireID(empire_id); Client().SetCurrentTurn(current_turn); Client().StartGame(); std::swap(Client().Orders(), orders); // bring back orders planned in the current turn, they will be applied later, after some basic turn initialization if (loaded_game_data && ui_data_available) Client().GetClientUI()->RestoreFromSaveData(ui_data); // if I am the host on the first turn, do an autosave. on later turns, will // have just loaded save, so don't need to autosave. might also have just // loaded a turn 1 autosave, but not sure how to check for that here... if (Client().CurrentTurn() == 1 && Client().Networking().PlayerIsHost(Client().PlayerID())) Client().Autosave(); return transit<PlayingTurn>(); }
boost::statechart::result WaitingForTurnData::react(const TurnUpdate& msg) { if (TRACE_EXECUTION) DebugLogger() << "(HumanClientFSM) PlayingGame.TurnUpdate"; int current_turn = INVALID_GAME_TURN; try { ExtractMessageData(msg.m_message, Client().EmpireID(), current_turn, Empires(), GetUniverse(), GetSpeciesManager(), GetCombatLogManager(), Client().Players()); } catch (...) { Client().GetClientUI()->GetMessageWnd()->HandleLogMessage(UserString("ERROR_PROCESSING_SERVER_MESSAGE") + "\n"); return discard_event(); } DebugLogger() << "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(); return transit<PlayingTurn>(); }