void HumanClientApp::Autosave() { // autosave only on appropriate turn numbers, and when enabled for current // game type (single vs. multiplayer) int autosave_turns = GetOptionsDB().Get<int>("autosave.turns"); if (autosave_turns < 1) return; // avoid divide by zero if (CurrentTurn() % autosave_turns != 0 && CurrentTurn() != 1) return; // turns divisible by autosave_turns, and first turn, have autosaves done if (m_single_player_game && !GetOptionsDB().Get<bool>("autosave.single-player")) return; if (!m_single_player_game && !GetOptionsDB().Get<bool>("autosave.multiplayer")) return; const char* legal_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-"; // get empire name, filtered for filename acceptability int client_empire_id = EmpireID(); const Empire* empire = GetEmpire(client_empire_id); std::string empire_name; if (empire) empire_name = empire->Name(); else empire_name = UserString("OBSERVER"); std::string::size_type first_good_empire_char = empire_name.find_first_of(legal_chars); if (first_good_empire_char == std::string::npos) { empire_name.clear(); } else { std::string::size_type first_bad_empire_char = empire_name.find_first_not_of(legal_chars, first_good_empire_char); empire_name = empire_name.substr(first_good_empire_char, first_bad_empire_char - first_good_empire_char); } // get player name, also filtered std::string player_name; if (empire) player_name = empire->PlayerName(); std::string::size_type first_good_player_char = player_name.find_first_of(legal_chars); if (first_good_player_char == std::string::npos) { player_name.clear(); } else { std::string::size_type first_bad_player_char = player_name.find_first_not_of(legal_chars, first_good_player_char); player_name = player_name.substr(first_good_player_char, first_bad_player_char - first_good_player_char); } // select filename extension std::string extension; if (m_single_player_game) extension = SP_SAVE_FILE_EXTENSION; else extension = MP_SAVE_FILE_EXTENSION; // Add timestamp to autosave generated files std::string datetime_str = FilenameTimestamp(); boost::filesystem::path autosave_dir_path(GetSaveDir() / "auto"); std::string save_filename = boost::io::str(boost::format("FreeOrion_%s_%s_%04d_%s%s") % player_name % empire_name % CurrentTurn() % datetime_str % extension); boost::filesystem::path save_path(autosave_dir_path / save_filename); std::string path_string = PathString(save_path); try { // ensure autosave directory exists if (!exists(autosave_dir_path)) boost::filesystem::create_directories(autosave_dir_path); } catch (const std::exception& e) { ErrorLogger() << "Autosave unable to check / create autosave directory: " << e.what(); std::cerr << "Autosave unable to check / create autosave directory: " << e.what() << std::endl; } // check for and remove excess oldest autosaves int max_autosaves = GetOptionsDB().Get<int>("autosave.limit"); RemoveOldestFiles(max_autosaves, autosave_dir_path); // create new save DebugLogger() << "Autosaving to: " << path_string; try { SaveGame(path_string); } catch (const std::exception& e) { ErrorLogger() << "Autosave failed: " << e.what(); std::cerr << "Autosave failed: " << e.what() << std::endl; } }
SaveFileDialog::SaveFileDialog (const std::string& extension, bool load ) : CUIWnd ( UserString ( "GAME_MENU_SAVE_FILES" ), ( GG::GUI::GetGUI()->AppWidth() - SAVE_FILE_DIALOG_WIDTH ) / 2, ( GG::GUI::GetGUI()->AppHeight() - SAVE_FILE_DIALOG_HEIGHT ) / 2, SAVE_FILE_DIALOG_WIDTH, SAVE_FILE_DIALOG_HEIGHT, GG::INTERACTIVE | GG::DRAGABLE | GG::MODAL | GG::RESIZABLE ) { m_extension = extension; m_load_only = load; boost::shared_ptr<GG::Font> font = ClientUI::GetFont(); SetMinSize ( GG::Pt ( 2*SAVE_FILE_DIALOG_MIN_WIDTH, 2*SAVE_FILE_DIALOG_MIN_HEIGHT ) ); m_layout = new GG::Layout ( GG::X0, GG::Y0, SAVE_FILE_DIALOG_WIDTH - LeftBorder() - RightBorder(), SAVE_FILE_DIALOG_HEIGHT - TopBorder() - BottomBorder(), 3, 4 ); m_layout->SetCellMargin ( SAVE_FILE_CELL_MARGIN ); m_layout->SetBorderMargin ( SAVE_FILE_CELL_MARGIN*2 ); m_file_list = new SaveFileListBox(); m_file_list->SetStyle ( GG::LIST_SINGLESEL | GG::LIST_SORTDESCENDING ); m_file_list->SetColHeaders ( new SaveFileRow() ); m_confirm_btn = new CUIButton ( UserString ( "OK" ) ); CUIButton* cancel_btn = new CUIButton ( UserString ( "CANCEL" ) ); m_name_edit = new CUIEdit ( GG::X0, GG::Y0, GG::X1, "", font ); GG::TextControl* filename_label = new GG::TextControl ( GG::X0, GG::Y0, UserString ( "SAVE_FILENAME" ), font, ClientUI::TextColor() ); GG::TextControl* directory_label = new GG::TextControl ( GG::X0, GG::Y0, UserString ( "SAVE_DIRECTORY" ), font, ClientUI::TextColor() ); m_current_dir_edit = new CUIEdit ( GG::X0, GG::Y0, GG::X1, PathString ( GetSaveDir() ), font ); m_browse_dir_btn = new CUIButton ( "..." ); m_layout->Add ( m_file_list, 0, 0, 1, 4 ); m_layout->Add ( filename_label, 1, 0, 1, 1 ); m_layout->Add ( m_name_edit, 1, 1, 1, 2 ); m_layout->Add ( m_confirm_btn, 1, 3 ); m_layout->Add ( directory_label,2, 0 ); m_layout->Add ( m_current_dir_edit, 2, 1 ); m_layout->Add ( m_browse_dir_btn, 2, 2 ); m_layout->Add ( cancel_btn, 2, 3 ); m_layout->SetRowStretch ( 0, 1.0 ); m_layout->SetMinimumRowHeight ( 1, font->TextExtent ( m_confirm_btn->Text() ).y ); m_layout->SetMinimumRowHeight ( 2, font->TextExtent ( cancel_btn->Text() ).y ); m_layout->SetMinimumColumnWidth ( 0, std::max ( font->TextExtent ( filename_label->Text() ).x, font->TextExtent ( directory_label->Text() ).x ) ); m_layout->SetColumnStretch ( 1, 1.0 ); m_layout->SetMinimumColumnWidth ( 2, m_browse_dir_btn->MinUsableSize().x + SAVE_FILE_BUTTON_MARGIN*2 ); m_layout->SetMinimumColumnWidth ( 3, std::max ( m_confirm_btn->MinUsableSize().x, cancel_btn->MinUsableSize().x ) + SAVE_FILE_BUTTON_MARGIN ); SetLayout ( m_layout ); GG::Connect ( m_confirm_btn->LeftClickedSignal, &SaveFileDialog::Confirm, this ); GG::Connect ( cancel_btn->LeftClickedSignal, &SaveFileDialog::Cancel, this ); GG::Connect ( m_file_list->SelChangedSignal, &SaveFileDialog::SelectionChanged, this ); GG::Connect ( m_file_list->DoubleClickedSignal, &SaveFileDialog::DoubleClickRow, this ); GG::Connect ( m_browse_dir_btn->LeftClickedSignal, &SaveFileDialog::BrowseDirectories, this ); GG::Connect ( m_name_edit->EditedSignal, &SaveFileDialog::FileNameEdited, this ); UpdatePreviewList(); if(!m_load_only){ m_name_edit->SetText(std::string("save-") + FilenameTimestamp()); m_name_edit->SelectAll(); } }