// MassBuilderSaveTool // Copyright (C) 2021 Guillaume Jacquemin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include "MassManager.h" static const std::string empty_string = ""; MassManager::MassManager(const std::string& save_path, const std::string& steam_id, bool demo): _stagingAreaDirectory{Utility::Directory::join(Utility::Directory::path(Utility::Directory::executableLocation()), "staging")} { _saveDirectory = save_path; _steamId = steam_id; _demo = demo; Containers::arrayReserve(_hangars, 32); std::string mass_filename = ""; for(int i = 0; i < 32; i++) { mass_filename = Utility::Directory::join(_saveDirectory, Utility::formatString("{}Unit{:.2d}{}.sav", demo ? "Demo" : "", i, _steamId)); Containers::arrayAppend(_hangars, Mass{mass_filename}); } if(!Utility::Directory::exists(_stagingAreaDirectory)) { Utility::Directory::mkpath(_stagingAreaDirectory); } refreshStagedMasses(); } auto MassManager::saveDirectory() -> std::string const& { return _saveDirectory; } auto MassManager::stagingAreaDirectory() -> std::string const& { return _stagingAreaDirectory; } auto MassManager::lastError() -> std::string const& { return _lastError; } auto MassManager::massName(int hangar) -> std::string const& { if(hangar < 0 || hangar >= 32) { return empty_string; } return _hangars[hangar].name(); } auto MassManager::massState(int hangar) -> MassState { if(hangar < 0 || hangar >= 32) { return MassState::Empty; } return _hangars[hangar].state(); } void MassManager::refreshHangar(int hangar) { if(hangar < 0 || hangar >= 32) { return; } std::string mass_filename = Utility::Directory::join(_saveDirectory, Utility::formatString("{}Unit{:.2d}{}.sav", _demo ? "Demo" : "", hangar, _steamId)); _hangars[hangar] = Mass{mass_filename}; } auto MassManager::importMass(const std::string& staged_fn, int hangar) -> bool { if(hangar < 0 || hangar >= 32) { _lastError = "Hangar out of range in MassManager::importMass()"; return false; } auto it = _stagedMasses.find(staged_fn); if(it == _stagedMasses.end()) { _lastError = "Couldn't find " + staged_fn + " in the staged M.A.S.S.es."; return false; } std::string source = Utility::Directory::join(_stagingAreaDirectory, staged_fn); Utility::Directory::copy(source, source + ".tmp"); if(!Mass{source + ".tmp"}.updateSteamId(_steamId)) { _lastError = "The M.A.S.S. file at " + source + " seems to be corrupt."; Utility::Directory::rm(source + ".tmp"); return false; } if(Utility::Directory::exists(_hangars[hangar].filename())) { Utility::Directory::rm(_hangars[hangar].filename()); } if(!Utility::Directory::move(source + ".tmp", _hangars[hangar].filename())) { _lastError = Utility::formatString("Couldn't move {} to hangar {:.2d}", staged_fn, hangar + 1); return false; } return true; } auto MassManager::exportMass(int hangar) -> bool { if(hangar < 0 || hangar >= 32) { _lastError = "Hangar out of range in MassManager::exportMass()"; return false; } if(_hangars[hangar].state() != MassState::Valid) { _lastError = Utility::formatString("There is no valid data to export in hangar {:.2d}", hangar + 1); return false; } std::string source = Utility::Directory::join(_saveDirectory, _hangars[hangar].filename()); std::string dest = Utility::Directory::join(_stagingAreaDirectory, Utility::formatString("{}_{}.sav", _hangars[hangar].name(), _steamId)); if(!Utility::Directory::copy(source, dest)) { _lastError = Utility::formatString("Couldn't export data from hangar {:.2d} to {}", hangar, dest); return false; } return true; } auto MassManager::moveMass(int source, int destination) -> bool { if(source < 0 || source >= 32) { _lastError = "Source hangar out of range."; return false; } if(destination < 0 || destination >= 32) { _lastError = "Destination hangar out of range."; return false; } std::string source_file = _hangars[source].filename(); std::string dest_file = _hangars[destination].filename(); MassState dest_state = _hangars[destination].state(); switch(dest_state) { case MassState::Empty: break; case MassState::Invalid: Utility::Directory::rm(dest_file); break; case MassState::Valid: Utility::Directory::move(dest_file, dest_file + ".tmp"); break; } Utility::Directory::move(source_file, dest_file); if(dest_state == MassState::Valid) { Utility::Directory::move(dest_file + ".tmp", source_file); } return true; } auto MassManager::deleteMass(int hangar) -> bool { if(hangar < 0 || hangar >= 32) { _lastError = "Hangar out of bounds"; return false; } if(!Utility::Directory::rm(_hangars[hangar].filename())) { _lastError = "Deletion failed. Maybe the file was already deleted, or it's locked by another application."; return false; } return true; } auto MassManager::stagedMasses() -> std::map const& { return _stagedMasses; } void MassManager::refreshStagedMasses() { _stagedMasses.clear(); using Utility::Directory::Flag; std::vector file_list = Utility::Directory::list(_stagingAreaDirectory, Flag::SkipSpecial|Flag::SkipDirectories|Flag::SkipDotAndDotDot); auto iter = std::remove_if(file_list.begin(), file_list.end(), [](std::string& file){ return !Utility::String::endsWith(file, ".sav"); }); file_list.erase(iter, file_list.end()); for(const std::string& file : file_list) { std::string name = Mass::getNameFromFile(Utility::Directory::join(_stagingAreaDirectory, file)); if(!name.empty()) { _stagedMasses[file] = name; } } } auto MassManager::deleteStagedMass(const std::string& filename) -> bool { if(_stagedMasses.find(filename) == _stagedMasses.cend()) { _lastError = "The file " + filename + " couldn't be found in the list of staged M.A.S.S.es."; return false; } if(!Utility::Directory::rm(Utility::Directory::join(_stagingAreaDirectory, filename))) { _lastError = "The file " + filename + " couldn't be deleted for unknown reasons."; return false; } return true; }