Esempio n. 1
0
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();
}
Esempio n. 2
0
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());
}
Esempio n. 3
0
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();
    }
}