1.5: Fuckin' UE5... #38
4 changed files with 300 additions and 0 deletions
|
@ -199,6 +199,9 @@ add_executable(MassBuilderSaveTool
|
||||||
Managers/MassManager.cpp
|
Managers/MassManager.cpp
|
||||||
Managers/ProfileManager.h
|
Managers/ProfileManager.h
|
||||||
Managers/ProfileManager.cpp
|
Managers/ProfileManager.cpp
|
||||||
|
Managers/StagedMass.h
|
||||||
|
Managers/StagedMassManager.h
|
||||||
|
Managers/StagedMassManager.cpp
|
||||||
Managers/Vfs/Directory.h
|
Managers/Vfs/Directory.h
|
||||||
Maps/ArmourSlots.hpp
|
Maps/ArmourSlots.hpp
|
||||||
Maps/BulletLauncherAttachmentStyles.hpp
|
Maps/BulletLauncherAttachmentStyles.hpp
|
||||||
|
|
30
src/Managers/StagedMass.h
Normal file
30
src/Managers/StagedMass.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// MassBuilderSaveTool
|
||||||
|
// Copyright (C) 2021-2024 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <Corrade/Containers/String.h>
|
||||||
|
|
||||||
|
using namespace Corrade;
|
||||||
|
|
||||||
|
namespace mbst::Managers {
|
||||||
|
|
||||||
|
struct StagedMass {
|
||||||
|
Containers::String filename;
|
||||||
|
Containers::String name;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
215
src/Managers/StagedMassManager.cpp
Normal file
215
src/Managers/StagedMassManager.cpp
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
// MassBuilderSaveTool
|
||||||
|
// Copyright (C) 2021-2024 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <Corrade/Containers/Optional.h>
|
||||||
|
#include <Corrade/Utility/Path.h>
|
||||||
|
|
||||||
|
#include "../Configuration/Configuration.h"
|
||||||
|
#include "../GameObjects/Mass.h"
|
||||||
|
#include "../Logger/Logger.h"
|
||||||
|
#include "../Utilities/Temp.h"
|
||||||
|
|
||||||
|
#include "StagedMassManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace mbst::Managers {
|
||||||
|
|
||||||
|
StagedMassManager::StagedMassManager() {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Containers::StringView
|
||||||
|
StagedMassManager::lastError() {
|
||||||
|
return _lastError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Containers::ArrayView<const StagedMass>
|
||||||
|
StagedMassManager::stagedMasses() const {
|
||||||
|
return _stagedMasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StagedMass&
|
||||||
|
StagedMassManager::at(Containers::StringView filename) const {
|
||||||
|
for(const auto& mass : _stagedMasses) {
|
||||||
|
if(mass.filename == filename) {
|
||||||
|
return mass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CORRADE_ASSERT_UNREACHABLE("Invalid staged M.A.S.S.!", StagedMass{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StagedMassManager::refresh() {
|
||||||
|
_stagedMasses = Containers::Array<StagedMass>{};
|
||||||
|
|
||||||
|
LOG_INFO("Scanning for staged M.A.S.S.es...");
|
||||||
|
|
||||||
|
scanSubdir(""_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StagedMassManager::refreshMass(Containers::StringView filename) {
|
||||||
|
LOG_INFO_FORMAT("Refreshing staged unit with filename {}.", filename);
|
||||||
|
|
||||||
|
bool file_exists = Utility::Path::exists(Utility::Path::join(conf().directories().staging, filename));
|
||||||
|
auto index = _stagedMasses.size();
|
||||||
|
for(std::size_t i = 0; i < _stagedMasses.size(); ++i) {
|
||||||
|
if(_stagedMasses[i].filename == filename) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file_exists) {
|
||||||
|
if(auto name = GameObjects::Mass::getNameFromFile(Utility::Path::join(conf().directories().staging, filename))) {
|
||||||
|
arrayAppend(_stagedMasses, StagedMass{filename, *name});
|
||||||
|
std::sort(_stagedMasses.begin(), _stagedMasses.end(),
|
||||||
|
[](const StagedMass& a, const StagedMass& b)->bool{
|
||||||
|
if(a.filename.contains('/') && !b.filename.contains('/')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return a.filename < b.filename;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(index != _stagedMasses.size()) {
|
||||||
|
arrayRemove(_stagedMasses, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(index != _stagedMasses.size()) {
|
||||||
|
arrayRemove(_stagedMasses, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StagedMassManager::import(Containers::StringView filename, int index, Containers::StringView new_account, bool demo) {
|
||||||
|
if(index < 0 || index >= 32) {
|
||||||
|
LOG_ERROR(_lastError = "Hangar index out of range."_s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for(auto& mass : _stagedMasses) {
|
||||||
|
if(mass.filename == filename) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found) {
|
||||||
|
LOG_ERROR(_lastError = "Couldn't find "_s + filename + " in the staged M.A.S.S.es."_s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto source = Utility::Path::join(conf().directories().staging, filename);
|
||||||
|
auto temp_path = Utilities::getTempPath(Utility::Path::split(filename).second());
|
||||||
|
Utility::Path::copy(source, temp_path);
|
||||||
|
|
||||||
|
{
|
||||||
|
GameObjects::Mass mass{temp_path};
|
||||||
|
if(!mass.updateAccount(new_account)) {
|
||||||
|
LOG_ERROR(_lastError = mass.lastError());
|
||||||
|
Utility::Path::remove(temp_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dest = Utility::Path::join(conf().directories().gameSaves,
|
||||||
|
Utility::format("{}Unit{}{}.sav", demo ? "Demo" : "", index, new_account));
|
||||||
|
|
||||||
|
if(Utility::Path::exists(dest)) {
|
||||||
|
Utility::Path::remove(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Utility::Path::move(temp_path, dest)) {
|
||||||
|
_lastError = Utility::format("Couldn't move {} to hangar {:.2d}", filename, index + 1);
|
||||||
|
LOG_ERROR(_lastError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StagedMassManager::remove(Containers::StringView filename) {
|
||||||
|
bool found = false;
|
||||||
|
for(auto& mass : _stagedMasses) {
|
||||||
|
if(mass.filename == filename) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found || !Utility::Path::remove(Utility::Path::join(conf().directories().staging, filename))) {
|
||||||
|
LOG_ERROR(_lastError = Utility::format("{} couldn't be found.", filename));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StagedMassManager::scanSubdir(Containers::StringView subdir) {
|
||||||
|
static std::uint8_t depth = 0;
|
||||||
|
|
||||||
|
auto full_subdir = Utility::Path::join(conf().directories().staging, subdir);
|
||||||
|
|
||||||
|
using Flag = Utility::Path::ListFlag;
|
||||||
|
auto files = Utility::Path::list(full_subdir, Flag::SkipSpecial|Flag::SkipDirectories);
|
||||||
|
|
||||||
|
if(!files) {
|
||||||
|
LOG_ERROR_FORMAT("{} couldn't be opened.", full_subdir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iter = std::remove_if(files->begin(), files->end(), [](Containers::StringView file){
|
||||||
|
return !file.hasSuffix(".sav"_s);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto files_view = files->exceptSuffix(files->end() - iter);
|
||||||
|
|
||||||
|
for(Containers::StringView file : files_view) {
|
||||||
|
if(auto name = GameObjects::Mass::getNameFromFile(Utility::Path::join(full_subdir, file))) {
|
||||||
|
LOG_INFO_FORMAT("Found staged M.A.S.S.: {}", *name);
|
||||||
|
arrayAppend(_stagedMasses, InPlaceInit, file, *name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_WARNING_FORMAT("Skipped {}.", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(depth == 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto subdirs = Utility::Path::list(full_subdir, Flag::SkipFiles|Flag::SkipSpecial|Flag::SkipDotAndDotDot);
|
||||||
|
if(!subdirs) {
|
||||||
|
LOG_ERROR_FORMAT("Couldn't list contents of {}.", full_subdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
depth++;
|
||||||
|
|
||||||
|
for(auto& dir : *subdirs) {
|
||||||
|
scanSubdir(Utility::Path::join(subdir, dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
depth--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
src/Managers/StagedMassManager.h
Normal file
52
src/Managers/StagedMassManager.h
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// MassBuilderSaveTool
|
||||||
|
// Copyright (C) 2021-2024 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <Corrade/Containers/Array.h>
|
||||||
|
#include <Corrade/Containers/ArrayView.h>
|
||||||
|
#include <Corrade/Containers/String.h>
|
||||||
|
#include <Corrade/Containers/StringView.h>
|
||||||
|
|
||||||
|
#include "StagedMass.h"
|
||||||
|
|
||||||
|
using namespace Corrade;
|
||||||
|
|
||||||
|
namespace mbst::Managers {
|
||||||
|
|
||||||
|
class StagedMassManager {
|
||||||
|
public:
|
||||||
|
explicit StagedMassManager();
|
||||||
|
|
||||||
|
auto lastError() -> Containers::StringView;
|
||||||
|
|
||||||
|
auto stagedMasses() const -> Containers::ArrayView<const StagedMass>;
|
||||||
|
auto at(Containers::StringView filename) const -> const StagedMass&;
|
||||||
|
|
||||||
|
void refresh();
|
||||||
|
void refreshMass(Containers::StringView filename);
|
||||||
|
bool import(Containers::StringView filename, int index, Containers::StringView new_account, bool demo);
|
||||||
|
bool remove(Containers::StringView filename);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void scanSubdir(Containers::StringView subdir);
|
||||||
|
|
||||||
|
Containers::String _lastError;
|
||||||
|
|
||||||
|
Containers::Array<StagedMass> _stagedMasses;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue