Reorganise code.

This is a big one. Namespacing, general formatting updates, and
renaming, among others.
This commit is contained in:
Guillaume Jacquemin 2023-11-29 12:33:26 +01:00
parent 9e7547a1cd
commit 819e144410
Signed by: williamjcm
SSH Key Fingerprint: SHA256:AYLOg+iTV0ElElnlu4vqM4edFazVdRiuQB0Y5LoKc4A
135 changed files with 2727 additions and 2094 deletions

View File

@ -14,8 +14,6 @@
// 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 "SaveTool.h"
#include <Corrade/Containers/ScopeGuard.h>
#include <Corrade/Utility/Unicode.h>
@ -37,6 +35,8 @@
#include "../Configuration/Configuration.h"
#include "../Logger/Logger.h"
#include "Application.h"
using namespace Containers::Literals;
extern const ImVec2 center_pivot = {0.5f, 0.5f};
@ -45,7 +45,9 @@ extern const ImVec2 center_pivot = {0.5f, 0.5f};
Utility::Tweakable tweak;
#endif
SaveTool::SaveTool(const Arguments& arguments):
namespace mbst {
Application::Application(const Arguments& arguments):
Platform::Sdl2Application{arguments,
Configuration{}.setTitle("M.A.S.S. Builder Save Tool " SAVETOOL_VERSION_STRING " (\"" SAVETOOL_CODENAME "\")")
.setSize({960, 720})}
@ -82,7 +84,7 @@ SaveTool::SaveTool(const Arguments& arguments):
LOG_INFO("Registering custom events.");
if((_initEventId = SDL_RegisterEvents(3)) == std::uint32_t(-1)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error",
"SDL_RegisterEvents() failed in SaveTool::SaveTool(). Exiting...", window());
"SDL_RegisterEvents() failed in Application::SaveTool(). Exiting...", window());
exit(EXIT_FAILURE);
return;
}
@ -118,7 +120,7 @@ SaveTool::SaveTool(const Arguments& arguments):
checkGameState();
_gameCheckTimerId = SDL_AddTimer(2000,
[](std::uint32_t interval, void* param)->std::uint32_t{
static_cast<SaveTool*>(param)->checkGameState();
static_cast<Application*>(param)->checkGameState();
return interval;
}, this);
if(_gameCheckTimerId == 0) {
@ -149,7 +151,7 @@ SaveTool::SaveTool(const Arguments& arguments):
_timeline.start();
}
SaveTool::~SaveTool() {
Application::~Application() {
LOG_INFO("Cleaning up.");
SDL_RemoveTimer(_gameCheckTimerId);
@ -162,7 +164,7 @@ SaveTool::~SaveTool() {
}
void
SaveTool::drawEvent() {
Application::drawEvent() {
#ifdef SAVETOOL_DEBUG_BUILD
tweak.update();
#endif
@ -183,7 +185,7 @@ SaveTool::drawEvent() {
}
void
SaveTool::viewportEvent(ViewportEvent& event) {
Application::viewportEvent(ViewportEvent& event) {
GL::defaultFramebuffer.setViewport({{}, event.framebufferSize()});
const Vector2 size = Vector2{windowSize()}/dpiScaling();
@ -191,32 +193,32 @@ SaveTool::viewportEvent(ViewportEvent& event) {
}
void
SaveTool::keyPressEvent(KeyEvent& event) {
Application::keyPressEvent(KeyEvent& event) {
if(_imgui.handleKeyPressEvent(event)) return;
}
void
SaveTool::keyReleaseEvent(KeyEvent& event) {
Application::keyReleaseEvent(KeyEvent& event) {
if(_imgui.handleKeyReleaseEvent(event)) return;
}
void
SaveTool::mousePressEvent(MouseEvent& event) {
Application::mousePressEvent(MouseEvent& event) {
if(_imgui.handleMousePressEvent(event)) return;
}
void
SaveTool::mouseReleaseEvent(MouseEvent& event) {
Application::mouseReleaseEvent(MouseEvent& event) {
if(_imgui.handleMouseReleaseEvent(event)) return;
}
void
SaveTool::mouseMoveEvent(MouseMoveEvent& event) {
Application::mouseMoveEvent(MouseMoveEvent& event) {
if(_imgui.handleMouseMoveEvent(event)) return;
}
void
SaveTool::mouseScrollEvent(MouseScrollEvent& event) {
Application::mouseScrollEvent(MouseScrollEvent& event) {
if(_imgui.handleMouseScrollEvent(event)) {
event.setAccepted();
return;
@ -224,12 +226,12 @@ SaveTool::mouseScrollEvent(MouseScrollEvent& event) {
}
void
SaveTool::textInputEvent(TextInputEvent& event) {
Application::textInputEvent(TextInputEvent& event) {
if(_imgui.handleTextInputEvent(event)) return;
}
void
SaveTool::anyEvent(SDL_Event& event) {
Application::anyEvent(SDL_Event& event) {
if(event.type == _initEventId) {
initEvent(event);
}
@ -242,7 +244,7 @@ SaveTool::anyEvent(SDL_Event& event) {
}
void
SaveTool::drawImGui() {
Application::drawImGui() {
_imgui.newFrame();
if(ImGui::GetIO().WantTextInput && !isTextInputActive()) {
@ -260,7 +262,7 @@ SaveTool::drawImGui() {
}
void
SaveTool::drawGui() {
Application::drawGui() {
drawMainMenu();
switch(_uiState) {
@ -303,7 +305,7 @@ SaveTool::drawGui() {
}
void
SaveTool::drawDisclaimer() {
Application::drawDisclaimer() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot);
if(ImGui::Begin("Disclaimer##DisclaimerWindow", nullptr,
@ -371,7 +373,7 @@ SaveTool::drawDisclaimer() {
}
void
SaveTool::drawInitialisation() {
Application::drawInitialisation() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot);
if(ImGui::BeginPopupModal("##InitPopup", nullptr,
@ -385,7 +387,7 @@ SaveTool::drawInitialisation() {
}
void
SaveTool::drawGameState() {
Application::drawGameState() {
ImGui::TextUnformatted("Game state:");
ImGui::SameLine();
{
@ -407,13 +409,13 @@ SaveTool::drawGameState() {
}
void
SaveTool::drawHelpMarker(Containers::StringView text, float wrap_pos) {
Application::drawHelpMarker(Containers::StringView text, float wrap_pos) {
ImGui::TextUnformatted(ICON_FA_QUESTION_CIRCLE);
drawTooltip(text, wrap_pos);
}
void
SaveTool::drawTooltip(Containers::StringView text, float wrap_pos) {
Application::drawTooltip(Containers::StringView text, float wrap_pos) {
if(ImGui::IsItemHovered()){
ImGui::BeginTooltip();
if(wrap_pos > 0.0f) {
@ -428,12 +430,12 @@ SaveTool::drawTooltip(Containers::StringView text, float wrap_pos) {
}
bool
SaveTool::drawCheckbox(Containers::StringView label, bool value) {
Application::drawCheckbox(Containers::StringView label, bool value) {
return ImGui::Checkbox(label.data(), &value);
}
void
SaveTool::openUri(Containers::StringView uri) {
Application::openUri(Containers::StringView uri) {
if(!conf().isRunningInWine()) {
ShellExecuteA(nullptr, nullptr, uri.data(), nullptr, nullptr, SW_SHOWDEFAULT);
}
@ -443,7 +445,7 @@ SaveTool::openUri(Containers::StringView uri) {
}
void
SaveTool::checkGameState() {
Application::checkGameState() {
WTS_PROCESS_INFOW* process_infos = nullptr;
unsigned long process_count = 0;
@ -464,3 +466,5 @@ SaveTool::checkGameState() {
_gameState = GameState::Unknown;
}
}
}

View File

@ -51,11 +51,13 @@ using namespace Corrade;
using namespace Containers::Literals;
using namespace Magnum;
class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener {
public:
explicit SaveTool(const Arguments& arguments);
namespace mbst {
~SaveTool() override;
class Application: public Platform::Sdl2Application, public efsw::FileWatchListener {
public:
explicit Application(const Arguments& arguments);
~Application() override;
void handleFileAction(efsw::WatchID watch_id,
const std::string& dir,
@ -113,20 +115,20 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void drawInitialisation();
void drawProfileManager();
ImGuiID drawBackupListPopup();
ImGuiID drawBackupProfilePopup(std::size_t profile_index);
ImGuiID drawDeleteProfilePopup(std::size_t profile_index);
auto drawBackupListPopup() -> ImGuiID;
auto drawBackupProfilePopup(std::size_t profile_index) -> ImGuiID;
auto drawDeleteProfilePopup(std::size_t profile_index) -> ImGuiID;
void drawManager();
bool drawIntEditPopup(int* value_to_edit, int max);
bool drawRenamePopup(Containers::ArrayView<char> name_view);
void drawGeneralInfo();
void drawResearchInventory();
void drawMaterialRow(Containers::StringView name, std::int32_t tier, MaterialID id);
void drawMaterialRow(Containers::StringView name, std::int32_t tier, GameData::MaterialID id);
void drawUnavailableMaterialRow(Containers::StringView name, std::int32_t tier);
void drawMassManager();
ImGuiID drawDeleteMassPopup(int mass_index);
ImGuiID drawDeleteStagedMassPopup(Containers::StringView filename);
auto drawDeleteMassPopup(int mass_index) -> ImGuiID;
auto drawDeleteStagedMassPopup(Containers::StringView filename) -> ImGuiID;
void drawMassViewer();
void drawFrameInfo();
@ -137,21 +139,24 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void drawArmour();
void drawCustomArmourStyles();
void drawWeapons();
void drawWeaponCategory(Containers::StringView name, Containers::ArrayView<Weapon> weapons_view, bool& dirty,
Containers::StringView payload_type, Containers::StringView payload_tooltip);
void drawWeaponEditor(Weapon& weapon);
void drawWeaponCategory(Containers::StringView name, Containers::ArrayView<GameObjects::Weapon> weapons_view,
bool& dirty, Containers::StringView payload_type,
Containers::StringView payload_tooltip);
void drawWeaponEditor(GameObjects::Weapon& weapon);
void drawGlobalStyles();
void drawTuning();
void drawDecalEditor(Decal& decal);
void drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<CustomStyle> style_view);
Containers::StringView getStyleName(std::int32_t id, Containers::ArrayView<CustomStyle> view);
void drawDecalEditor(GameObjects::Decal& decal);
void drawAccessoryEditor(GameObjects::Accessory& accessory,
Containers::ArrayView<GameObjects::CustomStyle> style_view);
auto getStyleName(std::int32_t id, Containers::ArrayView<GameObjects::CustomStyle> view)
-> Containers::StringView;
enum DCSResult {
DCS_Fail,
DCS_ResetStyle,
DCS_Save
};
DCSResult drawCustomStyle(CustomStyle& style);
auto drawCustomStyle(GameObjects::CustomStyle& style) -> DCSResult;
void drawAbout();
void drawGameState();
@ -206,11 +211,11 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
MassViewer
} _uiState{UiState::Disclaimer};
bool _aboutPopup{false};
bool _aboutPopup = false;
#ifdef SAVETOOL_DEBUG_BUILD
bool _demoWindow{false};
bool _styleEditor{false};
bool _metricsWindow{false};
bool _demoWindow = false;
bool _styleEditor = false;
bool _metricsWindow = false;
#endif
ToastQueue _queue;
@ -243,12 +248,12 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
SDL_TimerID _gameCheckTimerId = 0;
Containers::Pointer<ProfileManager> _profileManager;
Profile* _currentProfile{nullptr};
GameObjects::Profile* _currentProfile = nullptr;
Containers::Pointer<MassManager> _massManager;
Mass* _currentMass{nullptr};
GameObjects::Mass* _currentMass = nullptr;
Weapon* _currentWeapon = nullptr;
GameObjects::Weapon* _currentWeapon = nullptr;
Containers::Pointer<efsw::FileWatcher> _fileWatcher;
enum watchID {
@ -258,24 +263,27 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
Containers::StaticArray<2, efsw::WatchID> _watchIDs;
Containers::Optional<UpdateChecker> _checker{Containers::NullOpt};
std::mutex _checkerMutex;
std::mutex _checkerMutex;
bool _modifiedBySaveTool = false;
bool _jointsDirty = false;
bool _stylesDirty = false;
bool _eyeFlareDirty = false;
bool _meleeDirty = false;
bool _shieldsDirty = false;
bool _bShootersDirty = false;
bool _eShootersDirty = false;
bool _bLaunchersDirty = false;
bool _eLaunchersDirty = false;
bool _modifiedBySaveTool{false};
bool _jointsDirty{false};
bool _stylesDirty{false};
bool _eyeFlareDirty{false};
Containers::StaticArray<38, std::int32_t> _selectedArmourDecals{ValueInit};
Containers::StaticArray<38, std::int32_t> _selectedArmourAccessories{ValueInit};
std::int32_t _selectedBLPlacement{0};
std::int32_t _selectedWeaponPart{0};
std::int32_t _selectedWeaponDecal{0};
std::int32_t _selectedWeaponAccessory{0};
bool _meleeDirty{false};
bool _shieldsDirty{false};
bool _bShootersDirty{false};
bool _eShootersDirty{false};
bool _bLaunchersDirty{false};
bool _eLaunchersDirty{false};
std::int32_t _selectedBLPlacement = 0;
std::int32_t _selectedWeaponPart = 0;
std::int32_t _selectedWeaponDecal = 0;
std::int32_t _selectedWeaponAccessory = 0;
Timeline _timeline;
};
}

View File

@ -24,10 +24,12 @@
#include <fileapi.h>
#include <handleapi.h>
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::handleFileAction(efsw::WatchID watch_id,
Application::handleFileAction(efsw::WatchID watch_id,
const std::string&,
const std::string& filename,
efsw::Action action,
@ -64,7 +66,7 @@ SaveTool::handleFileAction(efsw::WatchID watch_id,
}
void
SaveTool::fileUpdateEvent(SDL_Event& event) {
Application::fileUpdateEvent(SDL_Event& event) {
Containers::String filename{static_cast<char*>(event.user.data1),
std::strlen(static_cast<char*>(event.user.data1)), nullptr};
@ -153,3 +155,5 @@ SaveTool::fileUpdateEvent(SDL_Event& event) {
_queue.addToast(Toast::Type::Warning, "Unknown file action type"_s);
}
}
}

View File

@ -14,7 +14,6 @@
// 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/Pair.h>
#include <Corrade/Containers/ScopeGuard.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/Unicode.h>
@ -29,10 +28,12 @@
#include "../FontAwesome/IconsFontAwesome5Brands.h"
#include "../Logger/Logger.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::initEvent(SDL_Event& event) {
Application::initEvent(SDL_Event& event) {
_initThread.join();
switch(event.user.code) {
@ -51,7 +52,7 @@ SaveTool::initEvent(SDL_Event& event) {
}
void
SaveTool::initialiseConfiguration() {
Application::initialiseConfiguration() {
LOG_INFO("Reading configuration file.");
setSwapInterval(conf().swapInterval());
@ -59,7 +60,7 @@ SaveTool::initialiseConfiguration() {
}
void
SaveTool::initialiseGui() {
Application::initialiseGui() {
LOG_INFO("Initialising Dear ImGui.");
auto ctx = ImGui::CreateContext();
@ -107,7 +108,7 @@ SaveTool::initialiseGui() {
}
void
SaveTool::initialiseManager() {
Application::initialiseManager() {
LOG_INFO("Initialising the profile manager.");
SDL_Event event;
@ -126,7 +127,7 @@ SaveTool::initialiseManager() {
}
auto
SaveTool::initialiseToolDirectories() -> bool {
Application::initialiseToolDirectories() -> bool {
LOG_INFO("Initialising Save Tool directories.");
_backupsDir = Utility::Path::join(Utility::Path::split(*Utility::Path::executableLocation()).first(), "backups");
@ -188,7 +189,7 @@ SaveTool::initialiseToolDirectories() -> bool {
}
auto
SaveTool::findGameDataDirectory() -> bool {
Application::findGameDataDirectory() -> bool {
LOG_INFO("Searching for the game's save directory.");
wchar_t* localappdata_path = nullptr;
@ -223,16 +224,18 @@ SaveTool::findGameDataDirectory() -> bool {
}
void
SaveTool::initialiseMassManager() {
Application::initialiseMassManager() {
LOG_INFO("Initialising the M.A.S.S. manager.");
_massManager.emplace(_saveDir, _currentProfile->account(), _currentProfile->isDemo(), _stagingDir);
}
void
SaveTool::initialiseFileWatcher() {
Application::initialiseFileWatcher() {
LOG_INFO("Initialising the file watcher.");
_fileWatcher.emplace();
_watchIDs[SaveDir] = _fileWatcher->addWatch(_saveDir, this, false);
_watchIDs[StagingDir] = _fileWatcher->addWatch(_stagingDir, this, false);
_fileWatcher->watch();
}
}

View File

@ -28,10 +28,12 @@
#include "../Maps/LastMissionId.h"
#include "../Maps/StoryProgress.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::drawManager() {
Application::drawManager() {
ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2{Vector2{float(windowSize().x()), float(windowSize().y()) - ImGui::GetItemRectSize().y} / dpiScaling()},
ImGuiCond_Always);
@ -99,7 +101,7 @@ SaveTool::drawManager() {
}
bool
SaveTool::drawIntEditPopup(int* value_to_edit, int max) {
Application::drawIntEditPopup(int* value_to_edit, int max) {
bool apply = false;
if(ImGui::BeginPopup("int_edit")) {
ImGui::Text("Please enter a value between 0 and %i:", max);
@ -123,7 +125,7 @@ SaveTool::drawIntEditPopup(int* value_to_edit, int max) {
}
bool
SaveTool::drawRenamePopup(Containers::ArrayView<char> name_view) {
Application::drawRenamePopup(Containers::ArrayView<char> name_view) {
bool apply = false;
if(ImGui::BeginPopup("name_edit")) {
ImGui::TextUnformatted("Please enter a new name. Conditions:");
@ -178,16 +180,16 @@ SaveTool::drawRenamePopup(Containers::ArrayView<char> name_view) {
}
void
SaveTool::drawGeneralInfo() {
Application::drawGeneralInfo() {
if(!_currentProfile) {
return;
}
ImGui::Text("Credits: %i", _currentProfile->credits());
auto it = std::find_if(story_progress.begin(), story_progress.end(),
[this](const StoryProgressPoint& p){ return p.id == _currentProfile->storyProgress(); });
if(it != story_progress.end())
auto it = std::find_if(GameData::story_progress.begin(), GameData::story_progress.end(),
[this](const GameData::StoryProgressPoint& p){ return p.id == _currentProfile->storyProgress(); });
if(it != GameData::story_progress.end())
{
ImGui::TextUnformatted("Story progress:");
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.x / 4.0f);
@ -202,8 +204,8 @@ SaveTool::drawGeneralInfo() {
ImGui::Text("Story progress: 0x%x", _currentProfile->storyProgress());
}
if(mission_id_map.find(_currentProfile->lastMissionId()) != mission_id_map.cend()) {
ImGui::Text("Last mission: %s", mission_id_map.at(_currentProfile->lastMissionId()).data());
if(GameData::mission_id_map.find(_currentProfile->lastMissionId()) != GameData::mission_id_map.cend()) {
ImGui::Text("Last mission: %s", GameData::mission_id_map.at(_currentProfile->lastMissionId()).data());
}
else if(_currentProfile->lastMissionId() == -1) {
ImGui::TextUnformatted("Last mission: none");
@ -260,7 +262,7 @@ SaveTool::drawGeneralInfo() {
if(_gameState != GameState::NotRunning) {
ImGui::CloseCurrentPopup();
}
for(const auto& sp : story_progress) {
for(const auto& sp : GameData::story_progress) {
if(ImGui::BeginMenu(sp.chapter.data())) {
if(!sp.after) {
if(ImGui::MenuItem(sp.point.data())) {
@ -287,7 +289,7 @@ SaveTool::drawGeneralInfo() {
}
void
SaveTool::drawResearchInventory() {
Application::drawResearchInventory() {
if(!_currentProfile) {
return;
}
@ -304,48 +306,48 @@ SaveTool::drawResearchInventory() {
ImGui::TableSetColumnIndex(1);
ImGui::TextUnformatted("Engine materials");
drawMaterialRow("Verse steel", 1, VerseSteel);
drawMaterialRow("Undinium", 2, Undinium);
drawMaterialRow("Necrium alloy", 3, NecriumAlloy);
drawMaterialRow("Lunarite", 4, Lunarite);
drawMaterialRow("Asterite", 5, Asterite);
drawMaterialRow("Hallite fragma", 6, HalliteFragma);
drawMaterialRow("Verse steel", 1, GameData::MaterialID::VerseSteel);
drawMaterialRow("Undinium", 2, GameData::MaterialID::Undinium);
drawMaterialRow("Necrium alloy", 3, GameData::MaterialID::NecriumAlloy);
drawMaterialRow("Lunarite", 4, GameData::MaterialID::Lunarite);
drawMaterialRow("Asterite", 5, GameData::MaterialID::Asterite);
drawMaterialRow("Hallite fragma", 6, GameData::MaterialID::HalliteFragma);
drawUnavailableMaterialRow("Unnoctinium", 7);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1);
ImGui::TextUnformatted("OS materials");
drawMaterialRow("Ednil", 1, Ednil);
drawMaterialRow("Nuflalt", 2, Nuflalt);
drawMaterialRow("Aurelene", 3, Aurelene);
drawMaterialRow("Soldus", 4, Soldus);
drawMaterialRow("Synthesized N", 5, SynthesisedN);
drawMaterialRow("Nanoc", 6, Nanoc);
drawMaterialRow("Ednil", 1, GameData::MaterialID::Ednil);
drawMaterialRow("Nuflalt", 2, GameData::MaterialID::Nuflalt);
drawMaterialRow("Aurelene", 3, GameData::MaterialID::Aurelene);
drawMaterialRow("Soldus", 4, GameData::MaterialID::Soldus);
drawMaterialRow("Synthesized N", 5, GameData::MaterialID::SynthesisedN);
drawMaterialRow("Nanoc", 6, GameData::MaterialID::Nanoc);
drawUnavailableMaterialRow("Abyssillite", 7);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1);
ImGui::TextUnformatted("Architect materials");
drawMaterialRow("Alcarbonite", 1, Alcarbonite);
drawMaterialRow("Keriphene", 2, Keriphene);
drawMaterialRow("Nitinol-CM", 3, NitinolCM);
drawMaterialRow("Quarkium", 4, Quarkium);
drawMaterialRow("Alterene", 5, Alterene);
drawMaterialRow("Cosmium", 6, Cosmium);
drawMaterialRow("Alcarbonite", 1, GameData::MaterialID::Alcarbonite);
drawMaterialRow("Keriphene", 2, GameData::MaterialID::Keriphene);
drawMaterialRow("Nitinol-CM", 3, GameData::MaterialID::NitinolCM);
drawMaterialRow("Quarkium", 4, GameData::MaterialID::Quarkium);
drawMaterialRow("Alterene", 5, GameData::MaterialID::Alterene);
drawMaterialRow("Cosmium", 6, GameData::MaterialID::Cosmium);
drawUnavailableMaterialRow("Purified quarkium", 7);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1);
ImGui::TextUnformatted("Quark data");
drawMaterialRow("Mixed composition", 1, MixedComposition);
drawMaterialRow("Void residue", 2, VoidResidue);
drawMaterialRow("Muscular construction", 3, MuscularConstruction);
drawMaterialRow("Mineral exoskeletology", 4, MineralExoskeletology);
drawMaterialRow("Carbonized skin", 5, CarbonisedSkin);
drawMaterialRow("Isolated void particle", 6, IsolatedVoidParticle);
drawMaterialRow("Mixed composition", 1, GameData::MaterialID::MixedComposition);
drawMaterialRow("Void residue", 2, GameData::MaterialID::VoidResidue);
drawMaterialRow("Muscular construction", 3, GameData::MaterialID::MuscularConstruction);
drawMaterialRow("Mineral exoskeletology", 4, GameData::MaterialID::MineralExoskeletology);
drawMaterialRow("Carbonized skin", 5, GameData::MaterialID::CarbonisedSkin);
drawMaterialRow("Isolated void particle", 6, GameData::MaterialID::IsolatedVoidParticle);
drawUnavailableMaterialRow("Weaponised physiology", 7);
ImGui::EndTable();
@ -353,7 +355,7 @@ SaveTool::drawResearchInventory() {
}
void
SaveTool::drawMaterialRow(Containers::StringView name, std::int32_t tier, MaterialID id) {
Application::drawMaterialRow(Containers::StringView name, std::int32_t tier, GameData::MaterialID id) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("T%i", tier);
@ -380,7 +382,7 @@ SaveTool::drawMaterialRow(Containers::StringView name, std::int32_t tier, Materi
}
void
SaveTool::drawUnavailableMaterialRow(Containers::StringView name, std::int32_t tier) {
Application::drawUnavailableMaterialRow(Containers::StringView name, std::int32_t tier) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Text("T%i", tier);
@ -391,7 +393,7 @@ SaveTool::drawUnavailableMaterialRow(Containers::StringView name, std::int32_t t
}
void
SaveTool::drawMassManager() {
Application::drawMassManager() {
if(!_massManager) {
return;
}
@ -426,7 +428,7 @@ SaveTool::drawMassManager() {
ImGui::TableSetColumnIndex(0);
ImGui::Selectable(Utility::format("{:.2d}", i + 1).data(),
false, ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_AllowItemOverlap);
if(_massManager->hangar(i).state() == Mass::State::Valid &&
if(_massManager->hangar(i).state() == GameObjects::Mass::State::Valid &&
ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
{
drag_drop_index = i;
@ -440,7 +442,7 @@ SaveTool::drawMassManager() {
if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("StagedMass")) {
if(payload->DataSize != sizeof(Containers::String)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error",
"payload->DataSize != sizeof(Containers::String) in SaveTool::drawMassManager()",
"payload->DataSize != sizeof(Containers::String) in Application::drawMassManager()",
window());
exit(EXIT_FAILURE);
}
@ -454,7 +456,7 @@ SaveTool::drawMassManager() {
else if((payload = ImGui::AcceptDragDropPayload("Mass"))) {
if(payload->DataSize != sizeof(int)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error",
"payload->DataSize != sizeof(int) in SaveTool::drawMassManager()",
"payload->DataSize != sizeof(int) in Application::drawMassManager()",
window());
exit(EXIT_FAILURE);
}
@ -471,13 +473,13 @@ SaveTool::drawMassManager() {
ImGui::TableSetColumnIndex(1);
switch(_massManager->hangar(i).state()) {
case Mass::State::Empty:
case GameObjects::Mass::State::Empty:
ImGui::TextDisabled("<empty>");
break;
case Mass::State::Invalid:
case GameObjects::Mass::State::Invalid:
ImGui::TextDisabled("<invalid>");
break;
case Mass::State::Valid:
case GameObjects::Mass::State::Valid:
ImGui::TextUnformatted(_massManager->hangar(i).name().data());
break;
}
@ -488,10 +490,10 @@ SaveTool::drawMassManager() {
drawTooltip("This is the currently active frame slot.");
}
if(_massManager->hangar(i).state() != Mass::State::Empty) {
if(_massManager->hangar(i).state() != GameObjects::Mass::State::Empty) {
ImGui::TableSetColumnIndex(3);
ImGui::PushID(i);
if(_massManager->hangar(i).state() == Mass::State::Valid) {
if(_massManager->hangar(i).state() == GameObjects::Mass::State::Valid) {
if(ImGui::SmallButton(ICON_FA_SEARCH)) {
_currentMass = &_massManager->hangar(i);
_uiState = UiState::MassViewer;
@ -570,7 +572,7 @@ SaveTool::drawMassManager() {
if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("Mass")) {
if(payload->DataSize != sizeof(int)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal error",
"payload->DataSize != sizeof(int) in SaveTool::drawMassManager()",
"payload->DataSize != sizeof(int) in Application::drawMassManager()",
window());
exit(EXIT_FAILURE);
}
@ -589,14 +591,14 @@ SaveTool::drawMassManager() {
}
ImGuiID
SaveTool::drawDeleteMassPopup(int mass_index) {
Application::drawDeleteMassPopup(int mass_index) {
if(!ImGui::BeginPopupModal("Confirmation##DeleteMassConfirmation", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{
return ImGui::GetID("Confirmation##DeleteMassConfirmation");
}
if(_massManager->hangar(mass_index).state() == Mass::State::Empty) {
if(_massManager->hangar(mass_index).state() == GameObjects::Mass::State::Empty) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
return 0;
@ -609,7 +611,7 @@ SaveTool::drawDeleteMassPopup(int mass_index) {
}
ImGui::PushTextWrapPos(float(windowSize().x()) * 0.40f);
if(_massManager->hangar(mass_index).state() == Mass::State::Invalid) {
if(_massManager->hangar(mass_index).state() == GameObjects::Mass::State::Invalid) {
ImGui::Text("Are you sure you want to delete the invalid M.A.S.S. data in hangar %.2i ? This operation is irreversible.",
mass_index + 1);
}
@ -646,7 +648,7 @@ SaveTool::drawDeleteMassPopup(int mass_index) {
}
ImGuiID
SaveTool::drawDeleteStagedMassPopup(Containers::StringView filename) {
Application::drawDeleteStagedMassPopup(Containers::StringView filename) {
if(!ImGui::BeginPopupModal("Confirmation##DeleteStagedMassConfirmation", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{
@ -683,3 +685,5 @@ SaveTool::drawDeleteStagedMassPopup(Containers::StringView filename) {
return 0;
}
}

View File

@ -25,11 +25,13 @@
#define STYLENAMES_DEFINITION
#include "../Maps/StyleNames.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::drawMassViewer() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawMassViewer() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
_currentMass = nullptr;
_currentWeapon = nullptr;
_uiState = UiState::MainManager;
@ -156,8 +158,8 @@ SaveTool::drawMassViewer() {
}
void
SaveTool::drawGlobalStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawGlobalStyles() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -193,8 +195,8 @@ SaveTool::drawGlobalStyles() {
}
void
SaveTool::drawTuning() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawTuning() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -289,9 +291,9 @@ SaveTool::drawTuning() {
ImGui::EndTable();
}
SaveTool::DCSResult
SaveTool::drawCustomStyle(CustomStyle& style) {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::DCSResult
Application::drawCustomStyle(GameObjects::CustomStyle& style) {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return DCS_Fail;
}
@ -396,7 +398,7 @@ SaveTool::drawCustomStyle(CustomStyle& style) {
}
void
SaveTool::drawDecalEditor(Decal& decal) {
Application::drawDecalEditor(GameObjects::Decal& decal) {
ImGui::Text("ID: %i", decal.id);
if(ImGui::BeginTable("##DecalTable", conf().advancedMode() ? 2 : 1, ImGuiTableFlags_BordersInnerV)) {
@ -501,12 +503,12 @@ SaveTool::drawDecalEditor(Decal& decal) {
}
void
SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<CustomStyle> style_view) {
Application::drawAccessoryEditor(GameObjects::Accessory& accessory, Containers::ArrayView<GameObjects::CustomStyle> style_view) {
if(accessory.id < 1) {
ImGui::TextUnformatted("Accessory: <none>");
}
else if(accessories.find(accessory.id) != accessories.cend()) {
ImGui::Text("Accessory #%.4i - %s", accessory.id, accessories.at(accessory.id).name.data());
else if(GameData::accessories.find(accessory.id) != GameData::accessories.cend()) {
ImGui::Text("Accessory #%.4i - %s", accessory.id, GameData::accessories.at(accessory.id).name.data());
}
else {
ImGui::Text("Accessory #%i", accessory.id);
@ -516,7 +518,7 @@ SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<Custom
ImGui::SameLine();
static std::int32_t tab = 0;
static Containers::Optional<AccessorySize> size = Containers::NullOpt;
static Containers::Optional<GameData::Accessory::Size> size = Containers::NullOpt;
if(ImGui::SmallButton("Change")) {
ImGui::OpenPopup("##AccessoryPopup");
if(accessory.id >= 3000) {
@ -574,45 +576,45 @@ SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<Custom
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
if(ImGui::Selectable("S", size && *size == AccessorySize::S, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(ImGui::Selectable("S", size && *size == GameData::Accessory::Size::S, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(!size) {
size.emplace();
}
*size = AccessorySize::S;
*size = GameData::Accessory::Size::S;
}
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
if(ImGui::Selectable("M", size && *size == AccessorySize::M, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(ImGui::Selectable("M", size && *size == GameData::Accessory::Size::M, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(!size) {
size.emplace();
}
*size = AccessorySize::M;
*size = GameData::Accessory::Size::M;
}
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
if(ImGui::Selectable("L", size && *size == AccessorySize::L, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(ImGui::Selectable("L", size && *size == GameData::Accessory::Size::L, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(!size) {
size.emplace();
}
*size = AccessorySize::L;
*size = GameData::Accessory::Size::L;
}
ImGui::SameLine();
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
ImGui::SameLine();
if(ImGui::Selectable("XL", size && *size == AccessorySize::XL, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(ImGui::Selectable("XL", size && *size == GameData::Accessory::Size::XL, ImGuiSelectableFlags_DontClosePopups, {70.0f, 0.0f})) {
if(!size) {
size.emplace();
}
*size = AccessorySize::XL;
*size = GameData::Accessory::Size::XL;
}
ImGui::PopStyleVar();
ImGui::Separator();
if(ImGui::BeginListBox("##AccessoryListbox", {-1.0f, 0.0f})) {
for(const auto& acc : accessories) {
for(const auto& acc : GameData::accessories) {
if(acc.first >= tab * 1000 && acc.first < ((tab + 1) * 1000) && (!size || *size == acc.second.size)) {
if(ImGui::Selectable(Utility::format("#{:.4d} - {} ({})", acc.first, acc.second.name, size_labels[acc.second.size]).data(),
acc.first == accessory.id))
@ -658,7 +660,7 @@ SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<Custom
ImGui::BeginGroup();
ImGui::PushMultiItemsWidths(2, ImGui::CalcItemWidth());
if(ImGui::BeginCombo("##Style1", getStyleName(accessory.styles[0], style_view).data())) {
for(const auto& style : style_names) {
for(const auto& style : GameData::style_names) {
if(ImGui::Selectable(getStyleName(style.first, style_view).data(), accessory.styles[0] == style.first)) {
accessory.styles[0] = style.first;
}
@ -669,7 +671,7 @@ SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<Custom
ImGui::PopItemWidth();
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
if(ImGui::BeginCombo("##Style2", getStyleName(accessory.styles[1], style_view).data())) {
for(const auto& style : style_names) {
for(const auto& style : GameData::style_names) {
if(ImGui::Selectable(getStyleName(style.first, style_view).data(), accessory.styles[1] == style.first)) {
accessory.styles[1] = style.first;
}
@ -740,7 +742,7 @@ SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<Custom
}
Containers::StringView
SaveTool::getStyleName(std::int32_t id, Containers::ArrayView<CustomStyle> view) {
Application::getStyleName(std::int32_t id, Containers::ArrayView<GameObjects::CustomStyle> view) {
if(id >= 0 && id <= 15) {
return view[id].name;
}
@ -748,6 +750,8 @@ SaveTool::getStyleName(std::int32_t id, Containers::ArrayView<CustomStyle> view)
return _currentMass->globalStyles()[id - 50].name;
}
else {
return style_names.at(id);
return GameData::style_names.at(id);
}
}
}

View File

@ -19,11 +19,13 @@
#include "../Maps/ArmourSets.h"
#include "../Maps/StyleNames.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::drawArmour() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawArmour() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -52,11 +54,17 @@ SaveTool::drawArmour() {
std::memset(header, '\0', 129);
if(armour_sets.find(part.id) != armour_sets.cend()) {
std::snprintf(header, 128, "%s: %s###%u", slot_labels[std::uint32_t(part.slot)].data(), armour_sets.at(part.id).name.data(), std::uint32_t(part.slot));
if(GameData::armour_sets.find(part.id) != GameData::armour_sets.cend()) {
std::snprintf(header, 128, "%s: %s###%u",
slot_labels[std::uint32_t(part.slot)].data(),
GameData::armour_sets.at(part.id).name.data(),
std::uint32_t(part.slot));
}
else {
std::snprintf(header, 128, "%s: %i###%u", slot_labels[std::uint32_t(part.slot)].data(), part.id, std::uint32_t(part.slot));
std::snprintf(header, 128, "%s: %i###%u",
slot_labels[std::uint32_t(part.slot)].data(),
part.id,
std::uint32_t(part.slot));
}
if(ImGui::CollapsingHeader(header)) {
@ -65,14 +73,14 @@ SaveTool::drawArmour() {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.491f);
if(ImGui::BeginListBox("##ChangePart")) {
if(std::strncmp("Neck", slot_labels[std::uint32_t(part.slot)].data(), 4) != 0) {
for(auto& set : armour_sets) {
for(auto& set : GameData::armour_sets) {
if(ImGui::Selectable(set.second.name.data(), set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
part.id = set.first;
}
}
}
else {
for(auto& set : armour_sets) {
for(auto& set : GameData::armour_sets) {
if(!set.second.neck_compatible) {
continue;
}
@ -106,7 +114,7 @@ SaveTool::drawArmour() {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 2.0f);
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[j], _currentMass->armourCustomStyles()).data())) {
for(const auto& style : style_names) {
for(const auto& style : GameData::style_names) {
if(ImGui::Selectable(getStyleName(style.first, _currentMass->armourCustomStyles()).data(), part.styles[j] == style.first)) {
part.styles[j] = style.first;
}
@ -164,19 +172,19 @@ SaveTool::drawArmour() {
ImGui::PopID();
}
if(_currentMass->bulletLauncherAttachmentStyle() != BulletLauncherAttachmentStyle::NotFound &&
if(_currentMass->bulletLauncherAttachmentStyle() != GameObjects::BulletLauncherAttachmentStyle::NotFound &&
ImGui::CollapsingHeader("Bullet launcher placement"))
{
drawAlignedText("Attachment style:"_s);
ImGui::SameLine();
ImGui::RadioButton("Active one",
_currentMass->bulletLauncherAttachmentStyle() == BulletLauncherAttachmentStyle::ActiveOne);
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::ActiveOne);
ImGui::SameLine();
ImGui::RadioButton("Active one per slot",
_currentMass->bulletLauncherAttachmentStyle() == BulletLauncherAttachmentStyle::ActiveOnePerSlot);
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::ActiveOnePerSlot);
ImGui::SameLine();
ImGui::RadioButton("All equipped",
_currentMass->bulletLauncherAttachmentStyle() == BulletLauncherAttachmentStyle::AllEquipped);
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::AllEquipped);
ImGui::Separator();
@ -203,13 +211,13 @@ SaveTool::drawArmour() {
if(ImGui::BeginCombo("##Socket", socket_labels[std::uint32_t(placement.socket)].data())) {
for(std::uint32_t i = 0; i < (sizeof(socket_labels) / sizeof(socket_labels[0])); i++) {
if(ImGui::Selectable(socket_labels[i].data(), i == std::uint32_t(placement.socket), ImGuiSelectableFlags_SpanAvailWidth)) {
placement.socket = static_cast<BulletLauncherSocket>(i);
placement.socket = static_cast<GameObjects::BulletLauncherAttachment::Socket>(i);
}
}
ImGui::EndCombo();
}
if(placement.socket != BulletLauncherSocket::Auto) {
if(placement.socket != GameObjects::BulletLauncherAttachment::Socket::Auto) {
ImGui::BeginGroup();
drawAlignedText("Relative position:");
drawAlignedText("Offset position:");
@ -290,8 +298,8 @@ SaveTool::drawArmour() {
}
void
SaveTool::drawCustomArmourStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawCustomArmourStyles() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -325,3 +333,5 @@ SaveTool::drawCustomArmourStyles() {
ImGui::EndChild();
}
}

View File

@ -17,11 +17,13 @@
#include "../FontAwesome/IconsFontAwesome5.h"
#include "../Maps/StyleNames.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::drawFrameInfo() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawFrameInfo() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -81,8 +83,8 @@ SaveTool::drawFrameInfo() {
}
void
SaveTool::drawJointSliders() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawJointSliders() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -204,8 +206,8 @@ SaveTool::drawJointSliders() {
}
void
SaveTool::drawFrameStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawFrameStyles() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -217,7 +219,7 @@ SaveTool::drawFrameStyles() {
ImGui::PushID(i);
if(ImGui::BeginCombo("##Style", getStyleName(_currentMass->frameStyles()[i], _currentMass->frameCustomStyles()).data())) {
for(const auto& style : style_names) {
for(const auto& style : GameData::style_names) {
if(ImGui::Selectable(getStyleName(style.first, _currentMass->frameCustomStyles()).data(), _currentMass->frameStyles()[i] == style.first)) {
_currentMass->frameStyles()[i] = style.first;
_stylesDirty = true;
@ -255,8 +257,8 @@ SaveTool::drawFrameStyles() {
}
void
SaveTool::drawEyeColourPicker() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawEyeColourPicker() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -289,8 +291,8 @@ SaveTool::drawEyeColourPicker() {
}
void
SaveTool::drawCustomFrameStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawCustomFrameStyles() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
return;
}
@ -324,3 +326,5 @@ SaveTool::drawCustomFrameStyles() {
ImGui::EndChild();
}
}

View File

@ -19,11 +19,13 @@
#include "../Maps/StyleNames.h"
#include "../Maps/WeaponParts.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::drawWeapons() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
Application::drawWeapons() {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
_currentWeapon = nullptr;
return;
}
@ -179,37 +181,37 @@ SaveTool::drawWeapons() {
if(drawUnsafeWidget([](){ return ImGui::Button(ICON_FA_SAVE " Save changes to weapon category"); })) {
_modifiedBySaveTool = true;
switch(_currentWeapon->type) {
case WeaponType::Melee:
case GameObjects::Weapon::Type::Melee:
if(!_currentMass->writeMeleeWeapons()) {
_modifiedBySaveTool = false;
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
}
break;
case WeaponType::Shield:
case GameObjects::Weapon::Type::Shield:
if(!_currentMass->writeShields()) {
_modifiedBySaveTool = false;
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
}
break;
case WeaponType::BulletShooter:
case GameObjects::Weapon::Type::BulletShooter:
if(!_currentMass->writeBulletShooters()) {
_modifiedBySaveTool = false;
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
}
break;
case WeaponType::EnergyShooter:
case GameObjects::Weapon::Type::EnergyShooter:
if(!_currentMass->writeEnergyShooters()) {
_modifiedBySaveTool = false;
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
}
break;
case WeaponType::BulletLauncher:
case GameObjects::Weapon::Type::BulletLauncher:
if(!_currentMass->writeBulletLaunchers()) {
_modifiedBySaveTool = false;
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
}
break;
case WeaponType::EnergyLauncher:
case GameObjects::Weapon::Type::EnergyLauncher:
if(!_currentMass->writeEnergyLaunchers()) {
_modifiedBySaveTool = false;
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
@ -225,22 +227,22 @@ SaveTool::drawWeapons() {
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset weapon category")) {
switch(_currentWeapon->type) {
case WeaponType::Melee:
case GameObjects::Weapon::Type::Melee:
_currentMass->getMeleeWeapons();
break;
case WeaponType::Shield:
case GameObjects::Weapon::Type::Shield:
_currentMass->getShields();
break;
case WeaponType::BulletShooter:
case GameObjects::Weapon::Type::BulletShooter:
_currentMass->getBulletShooters();
break;
case WeaponType::EnergyShooter:
case GameObjects::Weapon::Type::EnergyShooter:
_currentMass->getEnergyShooters();
break;
case WeaponType::BulletLauncher:
case GameObjects::Weapon::Type::BulletLauncher:
_currentMass->getBulletLaunchers();
break;
case WeaponType::EnergyLauncher:
case GameObjects::Weapon::Type::EnergyLauncher:
_currentMass->getEnergyLaunchers();
break;
default:
@ -252,7 +254,7 @@ SaveTool::drawWeapons() {
}
void
SaveTool::drawWeaponCategory(Containers::StringView name, Containers::ArrayView<Weapon> weapons_view, bool& dirty,
Application::drawWeaponCategory(Containers::StringView name, Containers::ArrayView<GameObjects::Weapon> weapons_view, bool& dirty,
Containers::StringView payload_type, Containers::StringView payload_tooltip)
{
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
@ -316,8 +318,8 @@ SaveTool::drawWeaponCategory(Containers::StringView name, Containers::ArrayView<
}
void
SaveTool::drawWeaponEditor(Weapon& weapon) {
if(!_currentMass || _currentMass->state() != Mass::State::Valid || !_currentWeapon) {
Application::drawWeaponEditor(GameObjects::Weapon& weapon) {
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid || !_currentWeapon) {
return;
}
@ -346,11 +348,11 @@ SaveTool::drawWeaponEditor(Weapon& weapon) {
ImGui::BeginGroup();
drawAlignedText("Equipped:");
if(weapon.type != WeaponType::Shield) {
if(weapon.type != GameObjects::Weapon::Type::Shield) {
drawAlignedText("Damage type:");
}
if(weapon.type == WeaponType::Melee) {
if(weapon.type == GameObjects::Weapon::Type::Melee) {
drawAlignedText("Dual-wield:");
drawAlignedText("Custom effect mode:");
@ -364,48 +366,48 @@ SaveTool::drawWeaponEditor(Weapon& weapon) {
ImGui::BeginGroup();
ImGui::Checkbox("##EquippedCheckbox", &weapon.attached);
if(weapon.type != WeaponType::Shield) {
if(weapon.type == WeaponType::Melee &&
ImGui::RadioButton("Physical##NoElement", weapon.damageType == DamageType::Physical))
if(weapon.type != GameObjects::Weapon::Type::Shield) {
if(weapon.type == GameObjects::Weapon::Type::Melee &&
ImGui::RadioButton("Physical##NoElement", weapon.damageType == GameObjects::Weapon::DamageType::Physical))
{
weapon.damageType = DamageType::Physical;
weapon.damageType = GameObjects::Weapon::DamageType::Physical;
}
else if((weapon.type == WeaponType::BulletShooter || weapon.type == WeaponType::BulletLauncher) &&
ImGui::RadioButton("Piercing##NoElement", weapon.damageType == DamageType::Piercing))
else if((weapon.type == GameObjects::Weapon::Type::BulletShooter || weapon.type == GameObjects::Weapon::Type::BulletLauncher) &&
ImGui::RadioButton("Piercing##NoElement", weapon.damageType == GameObjects::Weapon::DamageType::Piercing))
{
weapon.damageType = DamageType::Piercing;
weapon.damageType = GameObjects::Weapon::DamageType::Piercing;
}
else if((weapon.type == WeaponType::EnergyShooter || weapon.type == WeaponType::EnergyLauncher) &&
ImGui::RadioButton("Plasma##NoElement", weapon.damageType == DamageType::Plasma))
else if((weapon.type == GameObjects::Weapon::Type::EnergyShooter || weapon.type == GameObjects::Weapon::Type::EnergyLauncher) &&
ImGui::RadioButton("Plasma##NoElement", weapon.damageType == GameObjects::Weapon::DamageType::Plasma))
{
weapon.damageType = DamageType::Plasma;
weapon.damageType = GameObjects::Weapon::DamageType::Plasma;
}
ImGui::SameLine();
if(ImGui::RadioButton("Heat##Heat", weapon.damageType == DamageType::Heat)) {
weapon.damageType = DamageType::Heat;
if(ImGui::RadioButton("Heat##Heat", weapon.damageType == GameObjects::Weapon::DamageType::Heat)) {
weapon.damageType = GameObjects::Weapon::DamageType::Heat;
}
ImGui::SameLine();
if(ImGui::RadioButton("Freeze##Freeze", weapon.damageType == DamageType::Freeze)) {
weapon.damageType = DamageType::Freeze;
if(ImGui::RadioButton("Freeze##Freeze", weapon.damageType == GameObjects::Weapon::DamageType::Freeze)) {
weapon.damageType = GameObjects::Weapon::DamageType::Freeze;
}
ImGui::SameLine();
if(ImGui::RadioButton("Shock##Shock", weapon.damageType == DamageType::Shock)) {
weapon.damageType = DamageType::Shock;
if(ImGui::RadioButton("Shock##Shock", weapon.damageType == GameObjects::Weapon::DamageType::Shock)) {
weapon.damageType = GameObjects::Weapon::DamageType::Shock;
}
}
if(weapon.type == WeaponType::Melee) {
if(weapon.type == GameObjects::Weapon::Type::Melee) {
ImGui::Checkbox("##DualWield", &weapon.dualWield);
if(ImGui::RadioButton("Default##Default", weapon.effectColourMode == EffectColourMode::Default)) {
weapon.effectColourMode = EffectColourMode::Default;
if(ImGui::RadioButton("Default##Default", weapon.effectColourMode == GameObjects::Weapon::EffectColourMode::Default)) {
weapon.effectColourMode = GameObjects::Weapon::EffectColourMode::Default;
}
ImGui::SameLine();
if(ImGui::RadioButton("Custom##Custom", weapon.effectColourMode == EffectColourMode::Custom)) {
weapon.effectColourMode = EffectColourMode::Custom;
if(ImGui::RadioButton("Custom##Custom", weapon.effectColourMode == GameObjects::Weapon::EffectColourMode::Custom)) {
weapon.effectColourMode = GameObjects::Weapon::EffectColourMode::Custom;
}
bool custom_effect = (weapon.effectColourMode == EffectColourMode::Custom);
bool custom_effect = (weapon.effectColourMode == GameObjects::Weapon::EffectColourMode::Custom);
if(!custom_effect) {
ImGui::BeginDisabled();
}
@ -436,18 +438,18 @@ SaveTool::drawWeaponEditor(Weapon& weapon) {
const auto* map = [this, &weapon]()-> const std::map<std::int32_t, Containers::StringView>* {
switch(weapon.type) {
case WeaponType::Melee:
return _selectedWeaponPart == 0 ? &melee_grips : &melee_assaulters;
case WeaponType::Shield:
return _selectedWeaponPart == 0 ? &shield_handles : &shield_shells;
case WeaponType::BulletShooter:
return _selectedWeaponPart == 0 ? &bshooter_triggers : &bshooter_barrels;
case WeaponType::EnergyShooter:
return _selectedWeaponPart == 0 ? &eshooter_triggers : &eshooter_busters;
case WeaponType::BulletLauncher:
return _selectedWeaponPart == 0 ? &blauncher_pods : &blauncher_projectiles;
case WeaponType::EnergyLauncher:
return _selectedWeaponPart == 0 ? &elauncher_generators : &elauncher_pods;
case GameObjects::Weapon::Type::Melee:
return _selectedWeaponPart == 0 ? &GameData::melee_grips : &GameData::melee_assaulters;
case GameObjects::Weapon::Type::Shield:
return _selectedWeaponPart == 0 ? &GameData::shield_handles : &GameData::shield_shells;
case GameObjects::Weapon::Type::BulletShooter:
return _selectedWeaponPart == 0 ? &GameData::bshooter_triggers : &GameData::bshooter_barrels;
case GameObjects::Weapon::Type::EnergyShooter:
return _selectedWeaponPart == 0 ? &GameData::eshooter_triggers : &GameData::eshooter_busters;
case GameObjects::Weapon::Type::BulletLauncher:
return _selectedWeaponPart == 0 ? &GameData::blauncher_pods : &GameData::blauncher_projectiles;
case GameObjects::Weapon::Type::EnergyLauncher:
return _selectedWeaponPart == 0 ? &GameData::elauncher_generators : &GameData::elauncher_pods;
}
return nullptr;
@ -489,14 +491,14 @@ SaveTool::drawWeaponEditor(Weapon& weapon) {
}
}
if(weapon.type == WeaponType::Shield ||
(weapon.type == WeaponType::BulletLauncher && _selectedWeaponPart != 0))
if(weapon.type == GameObjects::Weapon::Type::Shield ||
(weapon.type == GameObjects::Weapon::Type::BulletLauncher && _selectedWeaponPart != 0))
{
ImGui::SameLine();
if(ImGui::SmallButton("Unequip")) {
part.id = -1;
}
if(weapon.type == WeaponType::Shield && _selectedWeaponPart == 0) {
if(weapon.type == GameObjects::Weapon::Type::Shield && _selectedWeaponPart == 0) {
drawTooltip("This will make the whole shield and its accessories invisible.");
}
else {
@ -515,7 +517,7 @@ SaveTool::drawWeaponEditor(Weapon& weapon) {
ImGui::PushID(i);
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[i], weapon.customStyles).data())) {
for(const auto& style: style_names) {
for(const auto& style: GameData::style_names) {
if(ImGui::Selectable(getStyleName(style.first, weapon.customStyles).data(),
part.styles[i] == style.first)) {
part.styles[i] = style.first;
@ -562,3 +564,5 @@ SaveTool::drawWeaponEditor(Weapon& weapon) {
ImGui::EndChild();
}
}
}

View File

@ -20,12 +20,14 @@
#include "../FontAwesome/IconsFontAwesome5.h"
#include "SaveTool.h"
#include "Application.h"
extern const ImVec2 center_pivot;
namespace mbst {
void
SaveTool::drawProfileManager() {
Application::drawProfileManager() {
static std::size_t profile_index = 0;
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot);
@ -81,7 +83,7 @@ SaveTool::drawProfileManager() {
ImGui::TextUnformatted("Actions");
for(std::size_t i = 0; i < _profileManager->profiles().size(); ++i) {
Profile& profile = _profileManager->profiles()[i];
GameObjects::Profile& profile = _profileManager->profiles()[i];
ImGui::TableNextRow();
@ -127,7 +129,7 @@ SaveTool::drawProfileManager() {
}
ImGuiID
SaveTool::drawBackupListPopup() {
Application::drawBackupListPopup() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot);
if(!ImGui::BeginPopupModal("Backups##BackupsModal", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
@ -283,7 +285,7 @@ SaveTool::drawBackupListPopup() {
backup.timestamp.second);
ImGui::TableSetColumnIndex(2);
ImGui::TextUnformatted(backup.type == ProfileType::Demo ? "Demo" : "Full");
ImGui::TextUnformatted(backup.demo ? "Demo" : "Full");
ImGui::TableSetColumnIndex(3);
ImGui::PushID(int(i));
@ -327,7 +329,7 @@ SaveTool::drawBackupListPopup() {
}
ImGuiID
SaveTool::drawBackupProfilePopup(std::size_t profile_index) {
Application::drawBackupProfilePopup(std::size_t profile_index) {
if(!ImGui::BeginPopupModal("Include builds ?##IncludeBuildsDialog", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{
@ -372,7 +374,7 @@ SaveTool::drawBackupProfilePopup(std::size_t profile_index) {
}
ImGuiID
SaveTool::drawDeleteProfilePopup(std::size_t profile_index) {
Application::drawDeleteProfilePopup(std::size_t profile_index) {
if(!ImGui::BeginPopupModal("Confirmation##DeleteProfileConfirmation", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{
@ -417,3 +419,5 @@ SaveTool::drawDeleteProfilePopup(std::size_t profile_index) {
return 0;
}
}

View File

@ -20,10 +20,12 @@
#include "../Logger/Logger.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::updateCheckEvent(SDL_Event& event) {
Application::updateCheckEvent(SDL_Event& event) {
_updateThread.join();
switch(static_cast<UpdateChecker::Result>(event.user.code)) {
@ -72,7 +74,7 @@ SaveTool::updateCheckEvent(SDL_Event& event) {
}
void
SaveTool::checkForUpdates() {
Application::checkForUpdates() {
SDL_Event event;
SDL_zero(event);
event.type = _updateEventId;
@ -89,3 +91,5 @@ SaveTool::checkForUpdates() {
SDL_PushEvent(&event);
}
}

View File

@ -14,8 +14,6 @@
// 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 "SaveTool.h"
#include <Corrade/version.h>
#include <Magnum/version.h>
@ -29,10 +27,14 @@
#include "../FontAwesome/IconsFontAwesome5.h"
#include "../FontAwesome/IconsFontAwesome5Brands.h"
#include "Application.h"
extern const ImVec2 center_pivot;
namespace mbst {
void
SaveTool::drawAbout() {
Application::drawAbout() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
ImGui::SetNextWindowSize({float(windowSize().x()) * 0.8f, float(windowSize().y()) * 0.75f}, ImGuiCond_Always);
@ -60,7 +62,7 @@ SaveTool::drawAbout() {
ImGui::TextWrapped("This application, made for the M.A.S.S. Builder community by Guillaume Jacquemin (aka William JCM), "
"is a rewrite of the wxWidgets-powered M.A.S.S. Builder Save Tool (formerly known as wxMASSManager).");
auto website = "https://williamjcm.ovh/coding/mbst";
auto website = "https://williamjcm.ovh/mbst";
drawAlignedText(ICON_FA_GLOBE " %s", website);
ImGui::SameLine();
if(ImGui::Button("Copy to clipboard")) {
@ -267,3 +269,5 @@ SaveTool::drawAbout() {
ImGui::EndPopup();
}
}

View File

@ -20,10 +20,12 @@
#include "../FontAwesome/IconsFontAwesome5.h"
#include "../FontAwesome/IconsFontAwesome5Brands.h"
#include "SaveTool.h"
#include "Application.h"
namespace mbst {
void
SaveTool::drawMainMenu() {
Application::drawMainMenu() {
if(!ImGui::BeginMainMenuBar()) {
return;
}
@ -239,3 +241,5 @@ SaveTool::drawMainMenu() {
ImGui::EndMainMenuBar();
}
}

View File

@ -37,7 +37,7 @@ set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)
corrade_add_resource(Assets assets.conf)
add_subdirectory(Logger EXCLUDE_FROM_ALL)
add_subdirectory(UESaveFile EXCLUDE_FROM_ALL)
add_subdirectory(Gvas EXCLUDE_FROM_ALL)
if(CORRADE_TARGET_WINDOWS)
set(SAVETOOL_RC_FILE resource.rc)
@ -45,19 +45,19 @@ endif()
add_executable(MassBuilderSaveTool
main.cpp
SaveTool/SaveTool.h
SaveTool/SaveTool.cpp
SaveTool/SaveTool_drawAbout.cpp
SaveTool/SaveTool_drawMainMenu.cpp
SaveTool/SaveTool_FileWatcher.cpp
SaveTool/SaveTool_Initialisation.cpp
SaveTool/SaveTool_MainManager.cpp
SaveTool/SaveTool_MassViewer.cpp
SaveTool/SaveTool_MassViewer_Frame.cpp
SaveTool/SaveTool_MassViewer_Armour.cpp
SaveTool/SaveTool_MassViewer_Weapons.cpp
SaveTool/SaveTool_ProfileManager.cpp
SaveTool/SaveTool_UpdateChecker.cpp
Application/Application.h
Application/Application.cpp
Application/Application_drawAbout.cpp
Application/Application_drawMainMenu.cpp
Application/Application_FileWatcher.cpp
Application/Application_Initialisation.cpp
Application/Application_MainManager.cpp
Application/Application_MassViewer.cpp
Application/Application_MassViewer_Frame.cpp
Application/Application_MassViewer_Armour.cpp
Application/Application_MassViewer_Weapons.cpp
Application/Application_ProfileManager.cpp
Application/Application_UpdateChecker.cpp
Configuration/Configuration.h
Configuration/Configuration.cpp
ProfileManager/ProfileManager.h
@ -102,7 +102,9 @@ add_executable(MassBuilderSaveTool
UpdateChecker/UpdateChecker.h
UpdateChecker/UpdateChecker.cpp
Utilities/Crc32.h
Utilities/Crc32.cpp
Version/Version.h
Version/Version.cpp
FontAwesome/IconsFontAwesome5.h
FontAwesome/IconsFontAwesome5Brands.h
${SAVETOOL_RC_FILE}
@ -145,7 +147,7 @@ target_link_libraries(MassBuilderSaveTool PRIVATE
Magnum::Sdl2Application
MagnumIntegration::ImGui
Logger
UESaveFile
Gvas
CURL::libcurl_static
)

View File

@ -20,6 +20,8 @@
#include "Configuration.h"
namespace mbst {
Configuration::Configuration() {
Containers::String exe_path = Utility::Path::split(*Utility::Path::executableLocation()).first();
_conf = Utility::Configuration{Utility::Path::join(exe_path, "MassBuilderSaveTool.ini")};
@ -174,3 +176,5 @@ Configuration&
conf() {
return Configuration::instance();
}
}

View File

@ -20,18 +20,20 @@
using namespace Corrade;
namespace mbst {
class Configuration {
public:
static Configuration& instance();
static auto instance() -> Configuration&;
~Configuration();
void save();
int swapInterval() const;
auto swapInterval() const -> int;
void setSwapInterval(int interval);
float fpsCap() const;
auto fpsCap() const -> float;
void setFpsCap(float cap);
bool cheatMode() const;
@ -54,14 +56,16 @@ class Configuration {
Utility::Configuration _conf;
int _swapInterval = 1;
int _swapInterval = 1;
float _fpsCap = 60.0f;
bool _cheatMode = false;
bool _advancedMode = false;
bool _checkUpdatesOnStartup = true;
bool _skipDisclaimer = false;
bool _cheatMode = false;
bool _advancedMode = false;
bool _checkUpdatesOnStartup = true;
bool _skipDisclaimer = false;
bool _isRunningInWine = false;
};
Configuration& conf();
}

View File

@ -23,6 +23,8 @@
#include "BinaryReader.h"
namespace Gvas {
BinaryReader::BinaryReader(Containers::StringView filename) {
_file = std::fopen(filename.data(), "rb");
@ -144,3 +146,5 @@ BinaryReader::peekChar() {
std::ungetc(c, _file);
return c;
}
}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
namespace Gvas {
class BinaryReader {
public:
explicit BinaryReader(Containers::StringView filename);
@ -32,7 +34,7 @@ class BinaryReader {
bool open();
bool eof();
std::int64_t position();
auto position() -> std::int64_t;
bool seek(std::int64_t position);
@ -63,8 +65,10 @@ class BinaryReader {
bool readUEString(Containers::String& str);
std::int32_t peekChar();
auto peekChar() -> std::int32_t;
private:
std::FILE* _file = nullptr;
};
}

View File

@ -22,6 +22,8 @@
using namespace Containers::Literals;
namespace Gvas {
BinaryWriter::BinaryWriter(Containers::StringView filename) {
_file = std::fopen(filename.data(), "wb");
if(!_file) {
@ -157,3 +159,5 @@ BinaryWriter::writeUEStringToArray(Containers::StringView value) {
writeDataToArray(Containers::ArrayView<const char>{value}) +
writeValueToArray<char>('\0');
}
}

View File

@ -26,6 +26,8 @@
using namespace Corrade;
namespace Gvas {
class BinaryWriter {
public:
explicit BinaryWriter(Containers::StringView filename);
@ -41,10 +43,10 @@ class BinaryWriter {
void closeFile();
std::int64_t position();
auto position() -> std::int64_t;
Containers::ArrayView<const char> array() const;
std::size_t arrayPosition() const;
auto array() const -> Containers::ArrayView<const char>;
auto arrayPosition() const -> std::size_t;
bool flushToFile();
bool writeChar(char value);
@ -72,12 +74,12 @@ class BinaryWriter {
bool writeUEString(Containers::StringView str);
template<typename T, typename U = std::conditional_t<std::is_trivially_copyable<T>::value, T, T&>>
std::size_t writeValueToArray(U value) {
auto writeValueToArray(U value) -> std::size_t {
Containers::ArrayView<T> view{&value, 1};
return writeDataToArray(view);
}
std::size_t writeUEStringToArray(Containers::StringView value);
auto writeUEStringToArray(Containers::StringView value) -> std::size_t;
template<typename T>
void writeValueToArrayAt(T& value, std::size_t position) {
@ -86,7 +88,7 @@ class BinaryWriter {
}
template<typename T>
std::size_t writeDataToArray(Containers::ArrayView<T> view) {
auto writeDataToArray(Containers::ArrayView<T> view) -> std::size_t {
arrayAppend(_data, Containers::arrayCast<const char>(view));
_index += sizeof(T) * view.size();
return sizeof(T) * view.size();
@ -106,3 +108,5 @@ class BinaryWriter {
Containers::Array<char> _data;
std::size_t _index = 0;
};
}

102
src/Gvas/CMakeLists.txt Normal file
View File

@ -0,0 +1,102 @@
# MassBuilderSaveTool
# Copyright (C) 2021-2023 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/>.
add_library(Gvas STATIC EXCLUDE_FROM_ALL
Serialisers/Serialisers.h
Serialisers/AbstractUnrealCollectionProperty.h
Serialisers/AbstractUnrealProperty.h
Serialisers/AbstractUnrealStruct.h
Serialisers/ArrayProperty.h
Serialisers/ArrayProperty.cpp
Serialisers/BoolProperty.h
Serialisers/BoolProperty.cpp
Serialisers/ByteProperty.h
Serialisers/ByteProperty.cpp
Serialisers/ColourProperty.h
Serialisers/ColourProperty.cpp
Serialisers/DateTimeProperty.h
Serialisers/DateTimeProperty.cpp
Serialisers/EnumProperty.h
Serialisers/EnumProperty.cpp
Serialisers/FloatProperty.h
Serialisers/FloatProperty.cpp
Serialisers/GuidProperty.h
Serialisers/GuidProperty.cpp
Serialisers/IntProperty.h
Serialisers/IntProperty.cpp
Serialisers/MapProperty.h
Serialisers/MapProperty.cpp
Serialisers/ResourceProperty.h
Serialisers/ResourceProperty.cpp
Serialisers/RotatorProperty.h
Serialisers/RotatorProperty.cpp
Serialisers/StringProperty.h
Serialisers/StringProperty.cpp
Serialisers/SetProperty.h
Serialisers/SetProperty.cpp
Serialisers/Struct.h
Serialisers/Struct.cpp
Serialisers/TextProperty.h
Serialisers/TextProperty.cpp
Serialisers/UnrealProperty.h
Serialisers/VectorProperty.h
Serialisers/VectorProperty.cpp
Serialisers/Vector2DProperty.h
Serialisers/Vector2DProperty.cpp
Types/Types.h
Types/ArrayProperty.h
Types/BoolProperty.h
Types/ByteProperty.h
Types/ColourStructProperty.h
Types/DateTimeStructProperty.h
Types/EnumProperty.h
Types/FloatProperty.h
Types/GenericStructProperty.h
Types/GuidStructProperty.h
Types/IntProperty.h
Types/MapProperty.h
Types/NoneProperty.h
Types/RotatorStructProperty.h
Types/SetProperty.h
Types/StringProperty.h
Types/StructProperty.h
Types/ResourceItemValue.h
Types/TextProperty.h
Types/UnrealProperty.h
Types/UnrealPropertyBase.h
Types/Vector2DStructProperty.h
Types/VectorStructProperty.h
Gvas.h
Debug.h
Debug.cpp
File.h
File.cpp
BinaryReader.h
BinaryReader.cpp
BinaryWriter.h
BinaryWriter.cpp
PropertySerialiser.h
PropertySerialiser.cpp
)
target_link_libraries(Gvas PRIVATE
Corrade::Containers
Corrade::Utility
Magnum::Magnum
Logger
)

View File

@ -23,19 +23,19 @@
#include "Debug.h"
Utility::Debug&
operator<<(Utility::Debug& debug, const ArrayProperty* prop) {
operator<<(Utility::Debug& debug, const Gvas::Types::ArrayProperty* prop) {
return debug << (*prop->name) << Utility::Debug::nospace << ":" <<
prop->propertyType << "of" << prop->items.size() << prop->itemType;
}
Utility::Debug&
operator<<(Utility::Debug& debug, const SetProperty* prop) {
operator<<(Utility::Debug& debug, const Gvas::Types::SetProperty* prop) {
return debug << (*prop->name) << Utility::Debug::nospace << ":" <<
prop->propertyType << "of" << prop->items.size() << prop->itemType;
}
Utility::Debug&
operator<<(Utility::Debug& debug, const GenericStructProperty* prop) {
operator<<(Utility::Debug& debug, const Gvas::Types::GenericStructProperty* prop) {
debug << (*prop->name) << Utility::Debug::nospace << ":" <<
prop->structType << "(" << Utility::Debug::nospace << prop->propertyType << Utility::Debug::nospace <<
") Contents:";
@ -46,8 +46,8 @@ operator<<(Utility::Debug& debug, const GenericStructProperty* prop) {
}
Utility::Debug&
operator<<(Utility::Debug& debug, const StructProperty* prop) {
auto cast = dynamic_cast<const GenericStructProperty*>(prop);
operator<<(Utility::Debug& debug, const Gvas::Types::StructProperty* prop) {
auto cast = dynamic_cast<const Gvas::Types::GenericStructProperty*>(prop);
if(cast) {
return debug << cast;
}
@ -57,21 +57,21 @@ operator<<(Utility::Debug& debug, const StructProperty* prop) {
}
Utility::Debug&
operator<<(Utility::Debug& debug, const UnrealPropertyBase* prop) {
operator<<(Utility::Debug& debug, const Gvas::Types::UnrealPropertyBase* prop) {
if(prop->propertyType == "ArrayProperty") {
auto array_prop = dynamic_cast<const ArrayProperty*>(prop);
auto array_prop = dynamic_cast<const Gvas::Types::ArrayProperty*>(prop);
if(array_prop) {
return debug << array_prop;
}
}
else if(prop->propertyType == "SetProperty") {
auto set_prop = dynamic_cast<const SetProperty*>(prop);
auto set_prop = dynamic_cast<const Gvas::Types::SetProperty*>(prop);
if(set_prop) {
return debug << set_prop;
}
}
else if(prop->propertyType == "StructProperty") {
auto struct_prop = dynamic_cast<const StructProperty*>(prop);
auto struct_prop = dynamic_cast<const Gvas::Types::StructProperty*>(prop);
if(struct_prop) {
return debug << struct_prop;
}

29
src/Gvas/Debug.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2023 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/Utility/Debug.h>
#include "Types/Types.h"
using namespace Corrade;
Utility::Debug& operator<<(Utility::Debug& debug, const Gvas::Types::ArrayProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const Gvas::Types::SetProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const Gvas::Types::GenericStructProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const Gvas::Types::StructProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const Gvas::Types::UnrealPropertyBase* prop);

View File

@ -17,15 +17,18 @@
#include <Corrade/Containers/Optional.h>
#include <Corrade/Utility/Path.h>
#include "BinaryReader.h"
#include "BinaryWriter.h"
#include "../Logger/Logger.h"
#include "UESaveFile.h"
#include "BinaryReader.h"
#include "BinaryWriter.h"
#include "File.h"
using namespace Containers::Literals;
UESaveFile::UESaveFile(Containers::String filepath):
namespace Gvas {
File::File(Containers::String filepath):
_propSerialiser{PropertySerialiser::instance()}
{
_filepath = std::move(filepath);
@ -34,46 +37,46 @@ UESaveFile::UESaveFile(Containers::String filepath):
}
bool
UESaveFile::valid() const {
File::valid() const {
return _valid;
}
Containers::StringView
UESaveFile::lastError() const {
File::lastError() const {
return _lastError;
}
bool
UESaveFile::reloadData() {
File::reloadData() {
if(_noReloadAfterSave) {
_noReloadAfterSave = false;
return valid();
}
_properties = Containers::Array<UnrealPropertyBase::ptr>{};
_properties = Containers::Array<Types::UnrealPropertyBase::ptr>{};
loadData();
return valid();
}
Containers::StringView
UESaveFile::saveType() {
File::saveType() {
return _saveType;
}
void
UESaveFile::appendProperty(UnrealPropertyBase::ptr prop) {
File::appendProperty(Types::UnrealPropertyBase::ptr prop) {
auto none_prop = std::move(_properties.back());
_properties.back() = std::move(prop);
arrayAppend(_properties, std::move(none_prop));
}
Containers::ArrayView<UnrealPropertyBase::ptr>
UESaveFile::props() {
Containers::ArrayView<Types::UnrealPropertyBase::ptr>
File::props() {
return _properties;
}
bool
UESaveFile::saveToFile() {
File::saveToFile() {
LOG_INFO_FORMAT("Writing to {}.", _filepath);
bool temp_file = _filepath.hasSuffix(".tmp");
@ -161,7 +164,7 @@ UESaveFile::saveToFile() {
}
void
UESaveFile::loadData() {
File::loadData() {
LOG_INFO_FORMAT("Reading data from {}.", _filepath);
_valid = false;
@ -244,7 +247,7 @@ UESaveFile::loadData() {
return;
}
UnrealPropertyBase::ptr prop;
Types::UnrealPropertyBase::ptr prop;
while((prop = _propSerialiser->read(reader)) != nullptr) {
arrayAppend(_properties, std::move(prop));
}
@ -265,3 +268,5 @@ UESaveFile::loadData() {
_valid = true;
}
}

View File

@ -29,19 +29,21 @@
using namespace Corrade;
class UESaveFile {
namespace Gvas {
class File {
public:
explicit UESaveFile(Containers::String filepath);
explicit File(Containers::String filepath);
bool valid() const;
Containers::StringView lastError() const;
auto lastError() const -> Containers::StringView;
bool reloadData();
Containers::StringView saveType();
auto saveType() -> Containers::StringView;
template<typename T>
std::enable_if_t<std::is_base_of<UnrealPropertyBase, T>::value, T*>
std::enable_if_t<std::is_base_of<Types::UnrealPropertyBase, T>::value, T*>
at(Containers::StringView name) {
for(auto& prop : _properties) {
if(prop->name == name) {
@ -51,9 +53,9 @@ class UESaveFile {
return nullptr;
}
void appendProperty(UnrealPropertyBase::ptr prop);
void appendProperty(Types::UnrealPropertyBase::ptr prop);
Containers::ArrayView<UnrealPropertyBase::ptr> props();
auto props() -> Containers::ArrayView<Types::UnrealPropertyBase::ptr>;
bool saveToFile();
@ -88,7 +90,9 @@ class UESaveFile {
Containers::String _saveType;
Containers::Array<UnrealPropertyBase::ptr> _properties;
Containers::Array<Types::UnrealPropertyBase::ptr> _properties;
Containers::Reference<PropertySerialiser> _propSerialiser;
};
}

26
src/Gvas/Gvas.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2023 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/>.
namespace Gvas {
class BinaryReader;
class BinaryWriter;
class File;
class PropertySerialiser;
}

View File

@ -16,55 +16,57 @@
#include <algorithm>
#include "Serialisers/ArrayPropertySerialiser.h"
#include "Serialisers/BoolPropertySerialiser.h"
#include "Serialisers/BytePropertySerialiser.h"
#include "Serialisers/ColourPropertySerialiser.h"
#include "Serialisers/DateTimePropertySerialiser.h"
#include "Serialisers/EnumPropertySerialiser.h"
#include "Serialisers/FloatPropertySerialiser.h"
#include "Serialisers/GuidPropertySerialiser.h"
#include "Serialisers/IntPropertySerialiser.h"
#include "Serialisers/MapPropertySerialiser.h"
#include "Serialisers/ResourcePropertySerialiser.h"
#include "Serialisers/RotatorPropertySerialiser.h"
#include "Serialisers/StringPropertySerialiser.h"
#include "Serialisers/SetPropertySerialiser.h"
#include "Serialisers/StructSerialiser.h"
#include "Serialisers/TextPropertySerialiser.h"
#include "Serialisers/VectorPropertySerialiser.h"
#include "Serialisers/Vector2DPropertySerialiser.h"
#include "../Logger/Logger.h"
#include "Serialisers/ArrayProperty.h"
#include "Serialisers/BoolProperty.h"
#include "Serialisers/ByteProperty.h"
#include "Serialisers/ColourProperty.h"
#include "Serialisers/DateTimeProperty.h"
#include "Serialisers/EnumProperty.h"
#include "Serialisers/FloatProperty.h"
#include "Serialisers/GuidProperty.h"
#include "Serialisers/IntProperty.h"
#include "Serialisers/MapProperty.h"
#include "Serialisers/ResourceProperty.h"
#include "Serialisers/RotatorProperty.h"
#include "Serialisers/StringProperty.h"
#include "Serialisers/SetProperty.h"
#include "Serialisers/Struct.h"
#include "Serialisers/TextProperty.h"
#include "Serialisers/VectorProperty.h"
#include "Serialisers/Vector2DProperty.h"
#include "Types/NoneProperty.h"
#include "BinaryReader.h"
#include "BinaryWriter.h"
#include "../Logger/Logger.h"
#include "PropertySerialiser.h"
PropertySerialiser::PropertySerialiser() {
arrayAppend(_serialisers, Containers::pointer<ArrayPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<BoolPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<BytePropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<ColourPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<DateTimePropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<EnumPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<FloatPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<GuidPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<IntPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<MapPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<ResourcePropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<RotatorPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<StringPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<SetPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<TextPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<VectorPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<Vector2DPropertySerialiser>());
arrayAppend(_serialisers, Containers::pointer<StructSerialiser>());
namespace Gvas {
arrayAppend(_collectionSerialisers, Containers::pointer<StructSerialiser>());
PropertySerialiser::PropertySerialiser() {
arrayAppend(_serialisers, Containers::pointer<Serialisers::ArrayProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::BoolProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::ByteProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::ColourProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::DateTimeProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::EnumProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::FloatProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::GuidProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::IntProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::MapProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::ResourceProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::RotatorProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::StringProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::SetProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::TextProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::VectorProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::Vector2DProperty>());
arrayAppend(_serialisers, Containers::pointer<Serialisers::Struct>());
arrayAppend(_collectionSerialisers, Containers::pointer<Serialisers::Struct>());
}
PropertySerialiser&
@ -73,7 +75,7 @@ PropertySerialiser::instance() {
return serialiser;
}
UnrealPropertyBase::ptr
Types::UnrealPropertyBase::ptr
PropertySerialiser::read(BinaryReader& reader) {
if(reader.peekChar() < 0 || reader.eof()) {
return nullptr;
@ -85,7 +87,7 @@ PropertySerialiser::read(BinaryReader& reader) {
}
if(name == "None") {
return Containers::pointer<NoneProperty>();
return Containers::pointer<Types::NoneProperty>();
}
Containers::String type;
@ -101,7 +103,7 @@ PropertySerialiser::read(BinaryReader& reader) {
return deserialise(std::move(name), std::move(type), value_length, reader);
}
UnrealPropertyBase::ptr
Types::UnrealPropertyBase::ptr
PropertySerialiser::readItem(BinaryReader& reader, Containers::String type, std::size_t value_length,
Containers::String name)
{
@ -112,7 +114,7 @@ PropertySerialiser::readItem(BinaryReader& reader, Containers::String type, std:
return deserialise(std::move(name), std::move(type), value_length, reader);
}
Containers::Array<UnrealPropertyBase::ptr>
Containers::Array<Types::UnrealPropertyBase::ptr>
PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView item_type, std::uint32_t count) {
if(reader.peekChar() < 0 || reader.eof()) {
return nullptr;
@ -120,7 +122,7 @@ PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView item_ty
auto serialiser = getCollectionSerialiser(item_type);
Containers::Array<UnrealPropertyBase::ptr> array;
Containers::Array<Types::UnrealPropertyBase::ptr> array;
if(serialiser) {
Containers::String name;
@ -156,11 +158,11 @@ PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView item_ty
return array;
}
UnrealPropertyBase::ptr
Types::UnrealPropertyBase::ptr
PropertySerialiser::deserialise(Containers::String name, Containers::String type, std::size_t value_length,
BinaryReader& reader)
{
UnrealPropertyBase::ptr prop;
Types::UnrealPropertyBase::ptr prop;
auto serialiser = getSerialiser(type);
if(serialiser == nullptr) {
@ -180,7 +182,7 @@ PropertySerialiser::deserialise(Containers::String name, Containers::String type
return prop;
}
bool PropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
bool PropertySerialiser::serialise(Types::UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer)
{
auto serialiser = getSerialiser(item_type);
@ -191,8 +193,8 @@ bool PropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, Containers::St
}
bool
PropertySerialiser::write(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer) {
if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast<NoneProperty*>(prop.get())) {
PropertySerialiser::write(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer) {
if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast<Types::NoneProperty*>(prop.get())) {
bytes_written += writer.writeUEStringToArray(*prop->name);
return true;
}
@ -215,10 +217,10 @@ PropertySerialiser::write(UnrealPropertyBase::ptr& prop, std::size_t& bytes_writ
}
bool
PropertySerialiser::writeItem(UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
PropertySerialiser::writeItem(Types::UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer)
{
if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast<NoneProperty*>(prop.get())) {
if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast<Types::NoneProperty*>(prop.get())) {
bytes_written += writer.writeUEStringToArray(*prop->name);
return true;
}
@ -226,7 +228,7 @@ PropertySerialiser::writeItem(UnrealPropertyBase::ptr& prop, Containers::StringV
return serialise(prop, item_type, bytes_written, writer);
}
bool PropertySerialiser::writeSet(Containers::ArrayView<UnrealPropertyBase::ptr> props,
bool PropertySerialiser::writeSet(Containers::ArrayView<Types::UnrealPropertyBase::ptr> props,
Containers::StringView item_type, std::size_t& bytes_written, BinaryWriter& writer)
{
auto serialiser = getCollectionSerialiser(item_type);
@ -244,7 +246,7 @@ bool PropertySerialiser::writeSet(Containers::ArrayView<UnrealPropertyBase::ptr>
}
}
AbstractUnrealPropertySerialiser*
Serialisers::AbstractUnrealProperty*
PropertySerialiser::getSerialiser(Containers::StringView item_type) {
for(auto& item : _serialisers) {
for(auto serialiser_type : item->types()) {
@ -257,7 +259,7 @@ PropertySerialiser::getSerialiser(Containers::StringView item_type) {
return nullptr;
}
AbstractUnrealCollectionPropertySerialiser*
Serialisers::AbstractUnrealCollectionProperty*
PropertySerialiser::getCollectionSerialiser(Containers::StringView item_type) {
for(auto& item : _collectionSerialisers) {
for(Containers::StringView serialiser_type : item->types()) {
@ -269,3 +271,5 @@ PropertySerialiser::getCollectionSerialiser(Containers::StringView item_type) {
return nullptr;
}
}

View File

@ -0,0 +1,64 @@
#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2023 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/GrowableArray.h>
#include <Corrade/Containers/String.h>
#include <Corrade/Containers/StringView.h>
#include "Serialisers/AbstractUnrealProperty.h"
#include "Serialisers/AbstractUnrealCollectionProperty.h"
#include "Types/UnrealPropertyBase.h"
#include "Gvas.h"
using namespace Corrade;
namespace Gvas {
class PropertySerialiser {
public:
static auto instance() -> PropertySerialiser&;
auto read(BinaryReader& reader) -> Types::UnrealPropertyBase::ptr;
auto readItem(BinaryReader& reader, Containers::String type, std::size_t value_length, Containers::String name)
-> Types::UnrealPropertyBase::ptr;
auto readSet(BinaryReader& reader, Containers::StringView item_type, std::uint32_t count)
-> Containers::Array<Types::UnrealPropertyBase::ptr>;
auto deserialise(Containers::String name, Containers::String type, std::size_t value_length,
BinaryReader& reader) -> Types::UnrealPropertyBase::ptr;
bool serialise(Types::UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer);
bool write(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer);
bool writeItem(Types::UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer);
bool writeSet(Containers::ArrayView<Types::UnrealPropertyBase::ptr> props, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer);
private:
PropertySerialiser();
auto getSerialiser(Containers::StringView item_type) -> Serialisers::AbstractUnrealProperty*;
auto getCollectionSerialiser(Containers::StringView item_type) -> Serialisers::AbstractUnrealCollectionProperty*;
Containers::Array<Serialisers::AbstractUnrealProperty::ptr> _serialisers;
Containers::Array<Serialisers::AbstractUnrealCollectionProperty::ptr> _collectionSerialisers;
};
}

View File

@ -21,29 +21,31 @@
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h>
#include "../Gvas.h"
#include "../Types/UnrealPropertyBase.h"
using namespace Corrade;
class BinaryReader;
class BinaryWriter;
class PropertySerialiser;
namespace Gvas { namespace Serialisers {
using PropertyArray = Containers::Array<UnrealPropertyBase::ptr>;
using PropertyArrayView = Containers::ArrayView<UnrealPropertyBase::ptr>;
using PropertyArray = Containers::Array<Types::UnrealPropertyBase::ptr>;
using PropertyArrayView = Containers::ArrayView<Types::UnrealPropertyBase::ptr>;
using StringArrayView = Containers::ArrayView<const Containers::String>;
class AbstractUnrealCollectionPropertySerialiser {
class AbstractUnrealCollectionProperty {
public:
using ptr = Containers::Pointer<AbstractUnrealCollectionPropertySerialiser>;
using ptr = Containers::Pointer<AbstractUnrealCollectionProperty>;
virtual ~AbstractUnrealCollectionPropertySerialiser() = default;
virtual ~AbstractUnrealCollectionProperty() = default;
virtual StringArrayView types() = 0;
virtual auto types() -> StringArrayView = 0;
virtual PropertyArray deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, std::uint32_t count, BinaryReader& reader,
PropertySerialiser& serialiser) = 0;
virtual auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
std::uint32_t count, BinaryReader& reader, PropertySerialiser& serialiser)
-> PropertyArray = 0;
virtual bool serialise(Containers::ArrayView<UnrealPropertyBase::ptr> props, Containers::StringView item_type,
virtual bool serialise(PropertyArrayView props, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) = 0;
};
}}

View File

@ -20,28 +20,30 @@
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h>
#include "../Gvas.h"
#include "../Types/UnrealPropertyBase.h"
using namespace Corrade;
class BinaryReader;
class BinaryWriter;
class PropertySerialiser;
namespace Gvas { namespace Serialisers {
using StringArrayView = Containers::ArrayView<const Containers::String>;
class AbstractUnrealPropertySerialiser {
class AbstractUnrealProperty {
public:
using ptr = Containers::Pointer<AbstractUnrealPropertySerialiser>;
using ptr = Containers::Pointer<AbstractUnrealProperty>;
virtual ~AbstractUnrealPropertySerialiser() = default;
virtual ~AbstractUnrealProperty() = default;
virtual StringArrayView types() = 0;
virtual auto types() -> StringArrayView = 0;
virtual UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) = 0;
virtual auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr = 0;
virtual bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
virtual bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) = 0;
};
}}

View File

@ -21,22 +21,25 @@
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h>
#include "../Gvas.h"
#include "../Types/UnrealPropertyBase.h"
using namespace Corrade;
class BinaryReader;
class BinaryWriter;
namespace Gvas { namespace Serialisers {
class AbstractUnrealStructSerialiser {
class AbstractUnrealStruct {
public:
using ptr = Containers::Pointer<AbstractUnrealStructSerialiser>;
using ptr = Containers::Pointer<AbstractUnrealStruct>;
virtual ~AbstractUnrealStructSerialiser() = default;
virtual ~AbstractUnrealStruct() = default;
virtual bool supportsType(Containers::StringView type) = 0;
virtual UnrealPropertyBase::ptr deserialise(BinaryReader& reader) = 0;
virtual auto deserialise(BinaryReader& reader) -> Types::UnrealPropertyBase::ptr = 0;
virtual bool serialise(UnrealPropertyBase::ptr& structProp, BinaryWriter& writer, std::size_t& bytes_written) = 0;
virtual bool serialise(Types::UnrealPropertyBase::ptr& structProp, BinaryWriter& writer,
std::size_t& bytes_written) = 0;
};
}}

View File

@ -21,12 +21,13 @@
#include "../PropertySerialiser.h"
#include "../../Logger/Logger.h"
#include "ArrayPropertySerialiser.h"
#include "ArrayProperty.h"
UnrealPropertyBase::ptr
ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
ArrayProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
Containers::String item_type;
if(!reader.readUEString(item_type)) {
@ -46,7 +47,7 @@ ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, Contai
return nullptr;
}
auto prop = Containers::pointer<ArrayProperty>();
auto prop = Containers::pointer<Types::ArrayProperty>();
prop->itemType = std::move(item_type);
prop->items = serialiser.readSet(reader, prop->itemType, item_count);
@ -54,10 +55,10 @@ ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, Contai
}
bool
ArrayPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
ArrayProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto array_prop = dynamic_cast<ArrayProperty*>(prop.get());
auto array_prop = dynamic_cast<Types::ArrayProperty*>(prop.get());
if(!array_prop) {
LOG_ERROR("The property is not a valid array property.");
return false;
@ -74,3 +75,5 @@ ArrayPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::s
return ret;
}
}}

View File

@ -18,20 +18,24 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "../Gvas.h"
#include "UnrealProperty.h"
#include "../Types/ArrayProperty.h"
using namespace Corrade;
class ArrayPropertySerialiser : public UnrealPropertySerialiser<ArrayProperty> {
namespace Gvas { namespace Serialisers {
class ArrayProperty : public UnrealProperty<Types::ArrayProperty> {
public:
using ptr = Containers::Pointer<ArrayPropertySerialiser>;
using ptr = Containers::Pointer<ArrayProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,18 +18,20 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "BoolPropertySerialiser.h"
#include "BoolProperty.h"
namespace Gvas { namespace Serialisers {
StringArrayView
BoolPropertySerialiser::types() {
BoolProperty::types() {
using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"BoolProperty"_s}};
return types;
}
UnrealPropertyBase::ptr
BoolPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
Types::UnrealPropertyBase::ptr
BoolProperty::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
if(value_length != 0) {
LOG_ERROR_FORMAT("Invalid value length for bool property {}. Expected 0, got {} instead.", name, value_length);
@ -47,17 +49,17 @@ BoolPropertySerialiser::deserialise(Containers::StringView name, Containers::Str
return nullptr;
}
auto prop = Containers::pointer<BoolProperty>();
auto prop = Containers::pointer<Types::BoolProperty>();
prop->value = value;
return prop;
}
bool
BoolPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
BoolProperty::serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto bool_prop = dynamic_cast<BoolProperty*>(prop.get());
auto bool_prop = dynamic_cast<Types::BoolProperty*>(prop.get());
if(!bool_prop) {
LOG_ERROR("The property is not a valid bool property.");
return false;
@ -67,3 +69,5 @@ BoolPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& by
return true;
}
}}

View File

@ -19,22 +19,26 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealPropertySerialiser.h"
#include "AbstractUnrealProperty.h"
#include "../Types/BoolProperty.h"
using namespace Corrade;
class BoolPropertySerialiser : public AbstractUnrealPropertySerialiser {
namespace Gvas { namespace Serialisers {
class BoolProperty : public AbstractUnrealProperty {
public:
using ptr = Containers::Pointer<BoolPropertySerialiser>;
using ptr = Containers::Pointer<BoolProperty>;
StringArrayView types() override;
auto types() -> StringArrayView override;
UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,20 +18,22 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "BytePropertySerialiser.h"
#include "ByteProperty.h"
namespace Gvas { namespace Serialisers {
StringArrayView
BytePropertySerialiser::types() {
ByteProperty::types() {
using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"ByteProperty"_s}};
return types;
}
UnrealPropertyBase::ptr
BytePropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
Types::UnrealPropertyBase::ptr
ByteProperty::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<ByteProperty>();
auto prop = Containers::pointer<Types::ByteProperty>();
if(value_length != std::size_t(-1)) {
if(!reader.readUEString(prop->enumType)) {
@ -66,10 +68,10 @@ BytePropertySerialiser::deserialise(Containers::StringView name, Containers::Str
}
bool
BytePropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
ByteProperty::serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto byte_prop = dynamic_cast<ByteProperty*>(prop.get());
auto byte_prop = dynamic_cast<Types::ByteProperty*>(prop.get());
if(!byte_prop) {
LOG_ERROR("The property is not a valid byte property.");
return false;
@ -88,3 +90,5 @@ BytePropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& by
return true;
}
}}

View File

@ -19,20 +19,24 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealPropertySerialiser.h"
#include "AbstractUnrealProperty.h"
#include "../Types/ByteProperty.h"
class BytePropertySerialiser : public AbstractUnrealPropertySerialiser {
namespace Gvas { namespace Serialisers {
class ByteProperty : public AbstractUnrealProperty {
public:
using ptr = Containers::Pointer<BytePropertySerialiser>;
using ptr = Containers::Pointer<ByteProperty>;
StringArrayView types() override;
auto types() -> StringArrayView override;
UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,14 +18,15 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "ColourPropertySerialiser.h"
#include "ColourProperty.h"
UnrealPropertyBase::ptr
ColourPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
ColourProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<ColourStructProperty>();
auto prop = Containers::pointer<Types::ColourStructProperty>();
if(!reader.readFloat(prop->r) || !reader.readFloat(prop->g) ||
!reader.readFloat(prop->b) || !reader.readFloat(prop->a))
@ -38,10 +39,10 @@ ColourPropertySerialiser::deserialiseProperty(Containers::StringView name, Conta
}
bool
ColourPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
ColourProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
auto colour_prop = dynamic_cast<ColourStructProperty*>(prop.get());
auto colour_prop = dynamic_cast<Types::ColourStructProperty*>(prop.get());
if(!colour_prop) {
LOG_ERROR("The property is not a valid colour property.");
return false;
@ -54,3 +55,5 @@ ColourPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::
return true;
}
}}

View File

@ -18,20 +18,24 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/ColourStructProperty.h"
using namespace Corrade;
class ColourPropertySerialiser : public UnrealPropertySerialiser<ColourStructProperty> {
namespace Gvas { namespace Serialisers {
class ColourProperty : public UnrealProperty<Types::ColourStructProperty> {
public:
using ptr = Containers::Pointer<ColourPropertySerialiser>;
using ptr = Containers::Pointer<ColourProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,14 +18,15 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "DateTimePropertySerialiser.h"
#include "DateTimeProperty.h"
UnrealPropertyBase::ptr
DateTimePropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
DateTimeProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<DateTimeStructProperty>();
auto prop = Containers::pointer<Types::DateTimeStructProperty>();
if(!reader.readInt64(prop->timestamp)) {
LOG_ERROR_FORMAT("Couldn't read date/time property {}'s value.", name);
@ -36,10 +37,10 @@ DateTimePropertySerialiser::deserialiseProperty(Containers::StringView name, Con
}
bool
DateTimePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
DateTimeProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
auto dt_prop = dynamic_cast<DateTimeStructProperty*>(prop.get());
auto dt_prop = dynamic_cast<Types::DateTimeStructProperty*>(prop.get());
if(!dt_prop) {
LOG_ERROR("The property is not a valid date/time property.");
return false;
@ -49,3 +50,5 @@ DateTimePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/DateTimeStructProperty.h"
class DateTimePropertySerialiser : public UnrealPropertySerialiser<DateTimeStructProperty> {
namespace Gvas { namespace Serialisers {
class DateTimeProperty : public UnrealProperty<Types::DateTimeStructProperty> {
public:
using ptr = Containers::Pointer<DateTimePropertySerialiser>;
using ptr = Containers::Pointer<DateTimeProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,20 +18,22 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "EnumPropertySerialiser.h"
#include "EnumProperty.h"
namespace Gvas { namespace Serialisers {
StringArrayView
EnumPropertySerialiser::types() {
EnumProperty::types() {
using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"EnumProperty"_s}};
return types;
}
UnrealPropertyBase::ptr
EnumPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
Types::UnrealPropertyBase::ptr
EnumProperty::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<EnumProperty>();
auto prop = Containers::pointer<Types::EnumProperty>();
if(!reader.readUEString(prop->enumType)) {
LOG_ERROR_FORMAT("Couldn't read enum property {}'s enum type.", name);
@ -53,10 +55,10 @@ EnumPropertySerialiser::deserialise(Containers::StringView name, Containers::Str
}
bool
EnumPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
EnumProperty::serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto enum_prop = dynamic_cast<EnumProperty*>(prop.get());
auto enum_prop = dynamic_cast<Types::EnumProperty*>(prop.get());
if(!enum_prop) {
LOG_ERROR("The property is not a valid enum property.");
return false;
@ -68,3 +70,5 @@ EnumPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& by
return true;
}
}}

View File

@ -19,20 +19,24 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealPropertySerialiser.h"
#include "AbstractUnrealProperty.h"
#include "../Types/EnumProperty.h"
class EnumPropertySerialiser : public AbstractUnrealPropertySerialiser {
namespace Gvas { namespace Serialisers {
class EnumProperty : public AbstractUnrealProperty {
public:
using ptr = Containers::Pointer<EnumPropertySerialiser>;
using ptr = Containers::Pointer<EnumProperty>;
StringArrayView types() override;
auto types() -> StringArrayView override;
UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,20 +18,22 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "FloatPropertySerialiser.h"
#include "FloatProperty.h"
namespace Gvas { namespace Serialisers {
StringArrayView
FloatPropertySerialiser::types() {
FloatProperty::types() {
using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"FloatProperty"_s}};
return types;
}
UnrealPropertyBase::ptr
FloatPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
Types::UnrealPropertyBase::ptr
FloatProperty::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<FloatProperty>();
auto prop = Containers::pointer<Types::FloatProperty>();
char terminator;
if(!reader.readChar(terminator) || terminator != '\0') {
@ -48,10 +50,10 @@ FloatPropertySerialiser::deserialise(Containers::StringView name, Containers::St
}
bool
FloatPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
FloatProperty::serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto float_prop = dynamic_cast<FloatProperty*>(prop.get());
auto float_prop = dynamic_cast<Types::FloatProperty*>(prop.get());
if(!float_prop) {
LOG_ERROR("The property is not a valid float property.");
return false;
@ -62,3 +64,5 @@ FloatPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& b
return true;
}
}}

View File

@ -19,20 +19,24 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealPropertySerialiser.h"
#include "AbstractUnrealProperty.h"
#include "../Types/FloatProperty.h"
class FloatPropertySerialiser : public AbstractUnrealPropertySerialiser {
namespace Gvas { namespace Serialisers {
class FloatProperty : public AbstractUnrealProperty {
public:
using ptr = Containers::Pointer<FloatPropertySerialiser>;
using ptr = Containers::Pointer<FloatProperty>;
StringArrayView types() override;
auto types() -> StringArrayView override;
UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,16 +18,17 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "GuidPropertySerialiser.h"
#include "GuidProperty.h"
using namespace Containers::Literals;
UnrealPropertyBase::ptr
GuidPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
GuidProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<GuidStructProperty>();
auto prop = Containers::pointer<Types::GuidStructProperty>();
if(!reader.readStaticArray(prop->guid)) {
LOG_ERROR_FORMAT("Couldn't read GUID property {}'s value.", name);
@ -38,12 +39,12 @@ GuidPropertySerialiser::deserialiseProperty(Containers::StringView name, Contain
}
bool
GuidPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
GuidProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto guid_prop = dynamic_cast<GuidStructProperty*>(prop.get());
auto guid_prop = dynamic_cast<Types::GuidStructProperty*>(prop.get());
if(!guid_prop) {
LOG_ERROR("The property is not a valid byte property.");
LOG_ERROR("The property is not a valid GUID property.");
return false;
}
@ -51,3 +52,5 @@ GuidPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::si
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/GuidStructProperty.h"
class GuidPropertySerialiser : public UnrealPropertySerialiser<GuidStructProperty> {
namespace Gvas { namespace Serialisers {
class GuidProperty : public UnrealProperty<Types::GuidStructProperty> {
public:
using ptr = Containers::Pointer<GuidPropertySerialiser>;
using ptr = Containers::Pointer<GuidProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,14 +18,15 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "IntPropertySerialiser.h"
#include "IntProperty.h"
UnrealPropertyBase::ptr
IntPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
IntProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<IntProperty>();
auto prop = Containers::pointer<Types::IntProperty>();
if(value_length == std::size_t(-1)) {
if(!reader.readInt32(prop->value)) {
@ -54,10 +55,10 @@ IntPropertySerialiser::deserialiseProperty(Containers::StringView name, Containe
}
bool
IntPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
IntProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto int_prop = dynamic_cast<IntProperty*>(prop.get());
auto int_prop = dynamic_cast<Types::IntProperty*>(prop.get());
if(!int_prop) {
LOG_ERROR("The property is not a valid int property.");
return false;
@ -71,3 +72,5 @@ IntPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::siz
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/IntProperty.h"
class IntPropertySerialiser : public UnrealPropertySerialiser<IntProperty> {
namespace Gvas { namespace Serialisers {
class IntProperty : public UnrealProperty<Types::IntProperty> {
public:
using ptr = Containers::Pointer<IntPropertySerialiser>;
using ptr = Containers::Pointer<IntProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -20,16 +20,17 @@
#include "../Types/NoneProperty.h"
#include "../../Logger/Logger.h"
#include "MapPropertySerialiser.h"
#include "MapProperty.h"
using namespace Containers::Literals;
UnrealPropertyBase::ptr
MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
MapProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<MapProperty>();
auto prop = Containers::pointer<Types::MapProperty>();
if(!reader.readUEString(prop->keyType)) {
LOG_ERROR_FORMAT("Couldn't read map property {}'s key type.", name);
@ -65,7 +66,7 @@ MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Containe
arrayReserve(prop->map, count);
for(std::uint32_t i = 0; i < count; i++) {
MapProperty::KeyValuePair pair;
Types::MapProperty::KeyValuePair pair;
if(prop->keyType == "IntProperty"_s || prop->keyType == "StrProperty"_s) {
pair.key = serialiser.readItem(reader, prop->keyType, -1, name);
@ -79,14 +80,14 @@ MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Containe
return nullptr;
}
UnrealPropertyBase::ptr value_item;
Types::UnrealPropertyBase::ptr value_item;
if(prop->valueType == "StructProperty"_s) {
while((value_item = serialiser.read(reader)) != nullptr) {
arrayAppend(pair.values, std::move(value_item));
if(pair.values.back()->name == "None"_s &&
pair.values.back()->propertyType == "NoneProperty"_s &&
dynamic_cast<NoneProperty*>(pair.values.back().get()) != nullptr)
dynamic_cast<Types::NoneProperty*>(pair.values.back().get()) != nullptr)
{
break;
}
@ -109,10 +110,10 @@ MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Containe
}
bool
MapPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
MapProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto map_prop = dynamic_cast<MapProperty*>(prop.get());
auto map_prop = dynamic_cast<Types::MapProperty*>(prop.get());
if(!map_prop) {
LOG_ERROR("The property is not a valid map property.");
return false;
@ -154,3 +155,5 @@ MapPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::siz
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/MapProperty.h"
class MapPropertySerialiser : public UnrealPropertySerialiser<MapProperty> {
namespace Gvas { namespace Serialisers {
class MapProperty : public UnrealProperty<Types::MapProperty> {
public:
using ptr = Containers::Pointer<MapPropertySerialiser>;
using ptr = Containers::Pointer<MapProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -21,16 +21,17 @@
#include "../Types/NoneProperty.h"
#include "../../Logger/Logger.h"
#include "ResourcePropertySerialiser.h"
#include "ResourceProperty.h"
using namespace Containers::Literals;
UnrealPropertyBase::ptr
ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
ResourceProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<ResourceItemValue>();
auto prop = Containers::pointer<Types::ResourceItemValue>();
auto id_prop = serialiser.read(reader);
if(!id_prop) {
@ -40,13 +41,13 @@ ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name, Con
if((*id_prop->name) != "ID_4_AAE08F17428E229EC7A2209F51081A21"_s ||
id_prop->propertyType != "IntProperty"_s ||
dynamic_cast<IntProperty*>(id_prop.get()) == nullptr)
dynamic_cast<Types::IntProperty*>(id_prop.get()) == nullptr)
{
LOG_ERROR("The ID property is invalid."_s);
return nullptr;
}
prop->id = dynamic_cast<IntProperty*>(id_prop.get())->value;
prop->id = dynamic_cast<Types::IntProperty*>(id_prop.get())->value;
auto value_prop = serialiser.read(reader);
if(!value_prop) {
@ -56,20 +57,20 @@ ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name, Con
if((*value_prop->name) != "Quantity_3_560F09B5485C365D3041888910019CE3"_s ||
value_prop->propertyType != "IntProperty"_s ||
dynamic_cast<IntProperty*>(value_prop.get()) == nullptr)
dynamic_cast<Types::IntProperty*>(value_prop.get()) == nullptr)
{
LOG_ERROR("The value property is invalid."_s);
return nullptr;
}
prop->quantity = dynamic_cast<IntProperty*>(value_prop.get())->value;
prop->quantity = dynamic_cast<Types::IntProperty*>(value_prop.get())->value;
auto none_prop = serialiser.read(reader);
if(!none_prop ||
(*none_prop->name) != "None"_s ||
none_prop->propertyType != "NoneProperty"_s ||
!dynamic_cast<NoneProperty*>(none_prop.get()))
!dynamic_cast<Types::NoneProperty*>(none_prop.get()))
{
LOG_ERROR("Couldn't find a terminating NoneProperty."_s);
return nullptr;
@ -79,10 +80,10 @@ ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name, Con
}
bool
ResourcePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
ResourceProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
auto res_prop = dynamic_cast<ResourceItemValue*>(prop.get());
auto res_prop = dynamic_cast<Types::ResourceItemValue*>(prop.get());
if(!res_prop) {
LOG_ERROR("The property is not a valid ResourceItemValue property.");
return false;
@ -104,3 +105,5 @@ ResourcePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/ResourceItemValue.h"
class ResourcePropertySerialiser : public UnrealPropertySerialiser<ResourceItemValue> {
namespace Gvas { namespace Serialisers {
class ResourceProperty : public UnrealProperty<Types::ResourceItemValue> {
public:
using ptr = Containers::Pointer<ResourcePropertySerialiser>;
using ptr = Containers::Pointer<ResourceProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,14 +18,15 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "RotatorPropertySerialiser.h"
#include "RotatorProperty.h"
UnrealPropertyBase::ptr
RotatorPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
RotatorProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<RotatorStructProperty>();
auto prop = Containers::pointer<Types::RotatorStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) {
LOG_ERROR_FORMAT("Couldn't read rotator property {}'s value.", name);
@ -36,10 +37,10 @@ RotatorPropertySerialiser::deserialiseProperty(Containers::StringView name, Cont
}
bool
RotatorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
RotatorProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
auto rotator = dynamic_cast<RotatorStructProperty*>(prop.get());
auto rotator = dynamic_cast<Types::RotatorStructProperty*>(prop.get());
if(!rotator) {
LOG_ERROR("The property is not a valid rotator property.");
return false;
@ -50,3 +51,5 @@ RotatorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std:
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/RotatorStructProperty.h"
class RotatorPropertySerialiser : public UnrealPropertySerialiser<RotatorStructProperty> {
namespace Gvas { namespace Serialisers {
class RotatorProperty : public UnrealProperty<Types::RotatorStructProperty> {
public:
using ptr = Containers::Pointer<RotatorPropertySerialiser>;
using ptr = Containers::Pointer<RotatorProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -0,0 +1,44 @@
#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2023 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/>.
namespace Gvas { namespace Serialisers {
class AbstractUnrealCollectionProperty;
class AbstractUnrealProperty;
class AbstractUnrealStruct;
class ArrayProperty;
class BoolProperty;
class ByteProperty;
class ColourProperty;
class DateTimeProperty;
class EnumProperty;
class FloatProperty;
class GuidProperty;
class IntProperty;
class MapProperty;
class ResourceProperty;
class RotatorProperty;
class SetProperty;
class StringProperty;
class Struct;
class TextProperty;
class UnrealProperty;
class Vector2DProperty;
class VectorProperty;
}}

View File

@ -19,12 +19,13 @@
#include "../PropertySerialiser.h"
#include "../../Logger/Logger.h"
#include "SetPropertySerialiser.h"
#include "SetProperty.h"
UnrealPropertyBase::ptr
SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
SetProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
Containers::String item_type;
if(!reader.readUEString(item_type)) {
@ -50,7 +51,7 @@ SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Containe
return nullptr;
}
auto prop = Containers::pointer<SetProperty>();
auto prop = Containers::pointer<Types::SetProperty>();
prop->itemType = std::move(item_type);
prop->items = serialiser.readSet(reader, prop->itemType, item_count);
@ -58,10 +59,10 @@ SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Containe
}
bool
SetPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
SetProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto set_prop = dynamic_cast<SetProperty*>(prop.get());
auto set_prop = dynamic_cast<Types::SetProperty*>(prop.get());
if(!set_prop) {
LOG_ERROR("The property is not a valid set property.");
return false;
@ -80,3 +81,5 @@ SetPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::siz
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/SetProperty.h"
class SetPropertySerialiser : public UnrealPropertySerialiser<SetProperty> {
namespace Gvas { namespace Serialisers {
class SetProperty : public UnrealProperty<Types::SetProperty> {
public:
using ptr = Containers::Pointer<SetPropertySerialiser>;
using ptr = Containers::Pointer<SetProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -18,10 +18,12 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "StringPropertySerialiser.h"
#include "StringProperty.h"
namespace Gvas { namespace Serialisers {
StringArrayView
StringPropertySerialiser::types() {
StringProperty::types() {
using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {
"NameProperty"_s, "StrProperty"_s, "SoftObjectProperty"_s, "ObjectProperty"_s
@ -29,11 +31,11 @@ StringPropertySerialiser::types() {
return types;
}
UnrealPropertyBase::ptr
StringPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
Types::UnrealPropertyBase::ptr
StringProperty::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<StringProperty>(type);
auto prop = Containers::pointer<Types::StringProperty>(type);
if(value_length != std::size_t(-1)) {
char terminator;
@ -54,10 +56,10 @@ StringPropertySerialiser::deserialise(Containers::StringView name, Containers::S
}
bool
StringPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
StringProperty::serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto str_prop = dynamic_cast<StringProperty*>(prop.get());
auto str_prop = dynamic_cast<Types::StringProperty*>(prop.get());
if(!str_prop) {
LOG_ERROR("The property is not a valid string property.");
return false;
@ -71,3 +73,5 @@ StringPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t&
return true;
}
}}

View File

@ -19,20 +19,24 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealPropertySerialiser.h"
#include "AbstractUnrealProperty.h"
#include "../Types/StringProperty.h"
class StringPropertySerialiser : public AbstractUnrealPropertySerialiser {
namespace Gvas { namespace Serialisers {
class StringProperty : public AbstractUnrealProperty {
public:
using ptr = Containers::Pointer<StringPropertySerialiser>;
using ptr = Containers::Pointer<StringProperty>;
StringArrayView types() override;
auto types() -> StringArrayView override;
UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -23,18 +23,20 @@
#include "../Types/NoneProperty.h"
#include "../../Logger/Logger.h"
#include "StructSerialiser.h"
#include "Struct.h"
namespace Gvas { namespace Serialisers {
StringArrayView
StructSerialiser::types() {
Struct::types() {
using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"StructProperty"_s}};
return types;
}
Containers::Array<UnrealPropertyBase::ptr>
StructSerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
std::uint32_t count, BinaryReader& reader, PropertySerialiser& serialiser)
PropertyArray
Struct::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
std::uint32_t count, BinaryReader& reader, PropertySerialiser& serialiser)
{
Containers::String item_type;
if(!reader.readUEString(item_type)) {
@ -54,16 +56,16 @@ StructSerialiser::deserialise(Containers::StringView name, Containers::StringVie
return nullptr;
}
Containers::Array<UnrealPropertyBase::ptr> array;
Containers::Array<Types::UnrealPropertyBase::ptr> array;
if(count == 0) {
auto prop = Containers::pointer<GenericStructProperty>();
auto prop = Containers::pointer<Types::GenericStructProperty>();
prop->structType = std::move(item_type);
prop->structGuid = std::move(guid);
}
else {
for(std::uint32_t i = 0; i < count; i++) {
auto prop = Containers::pointer<UnrealPropertyBase>();
auto prop = Containers::pointer<Types::UnrealPropertyBase>();
prop = serialiser.readItem(reader, item_type, std::size_t(-1), name);
@ -76,7 +78,7 @@ StructSerialiser::deserialise(Containers::StringView name, Containers::StringVie
return nullptr;
}
dynamic_cast<StructProperty*>(prop.get())->structGuid = guid;
dynamic_cast<Types::StructProperty*>(prop.get())->structGuid = guid;
arrayAppend(array, std::move(prop));
}
@ -85,9 +87,9 @@ StructSerialiser::deserialise(Containers::StringView name, Containers::StringVie
return array;
}
UnrealPropertyBase::ptr
StructSerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
Types::UnrealPropertyBase::ptr
Struct::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
Containers::String item_type;
if(!reader.readUEString(item_type)) {
@ -96,7 +98,7 @@ StructSerialiser::deserialise(Containers::StringView name, Containers::StringVie
}
if(item_type == "None") {
return NoneProperty::ptr{};
return Containers::pointer<Types::NoneProperty>();
}
Containers::StaticArray<16, char> guid{ValueInit};
@ -111,12 +113,12 @@ StructSerialiser::deserialise(Containers::StringView name, Containers::StringVie
return nullptr;
}
UnrealPropertyBase::ptr prop = serialiser.readItem(reader, item_type, value_length, name);
auto prop = serialiser.readItem(reader, item_type, value_length, name);
if(!prop) {
prop = readStructValue(name, item_type, value_length, reader, serialiser);
if(prop) {
dynamic_cast<GenericStructProperty*>(prop.get())->structGuid = std::move(guid);
dynamic_cast<Types::GenericStructProperty*>(prop.get())->structGuid = std::move(guid);
}
}
@ -124,15 +126,15 @@ StructSerialiser::deserialise(Containers::StringView name, Containers::StringVie
}
bool
StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr> props, Containers::StringView item_type,
std::size_t& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser)
Struct::serialise(PropertyArrayView props, Containers::StringView item_type, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
bytes_written += writer.writeUEStringToArray(*(props.front()->name));
bytes_written += writer.writeUEStringToArray(item_type);
std::size_t vl_pos = writer.arrayPosition();
bytes_written += writer.writeValueToArray<std::size_t>(0ull);
auto struct_prop = dynamic_cast<StructProperty*>(props.front().get());
auto struct_prop = dynamic_cast<Types::StructProperty*>(props.front().get());
if(!struct_prop) {
LOG_ERROR("The property is not a valid struct property.");
return false;
@ -146,7 +148,7 @@ StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr> props
std::size_t bytes_written_here = 0;
for(auto& prop : props) {
struct_prop = dynamic_cast<StructProperty*>(prop.get());
struct_prop = dynamic_cast<Types::StructProperty*>(prop.get());
if(!struct_prop) {
LOG_ERROR("The property is not a valid struct property.");
return false;
@ -168,10 +170,10 @@ StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr> props
}
bool
StructSerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
Struct::serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto struct_prop = dynamic_cast<StructProperty*>(prop.get());
auto struct_prop = dynamic_cast<Types::StructProperty*>(prop.get());
if(!struct_prop) {
LOG_ERROR("The property is not a valid struct property.");
return false;
@ -194,22 +196,22 @@ StructSerialiser::serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_wr
return true;
}
StructProperty::ptr
StructSerialiser::readStructValue(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
Types::StructProperty::ptr
Struct::readStructValue(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
static_cast<void>(value_length);
auto st_prop = Containers::pointer<GenericStructProperty>();
auto st_prop = Containers::pointer<Types::GenericStructProperty>();
st_prop->structType = type;
UnrealPropertyBase::ptr prop;
Types::UnrealPropertyBase::ptr prop;
while((prop = serialiser.read(reader)) != nullptr) {
arrayAppend(st_prop->properties, std::move(prop));
if(st_prop->properties.back()->name == "None" &&
st_prop->properties.back()->propertyType == "NoneProperty" &&
dynamic_cast<NoneProperty*>(st_prop->properties.back().get()) != nullptr)
dynamic_cast<Types::NoneProperty*>(st_prop->properties.back().get()) != nullptr)
{
break;
}
@ -221,10 +223,10 @@ StructSerialiser::readStructValue(Containers::StringView name, Containers::Strin
}
bool
StructSerialiser::writeStructValue(StructProperty* prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
Struct::writeStructValue(Types::StructProperty* prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto struct_prop = dynamic_cast<GenericStructProperty*>(prop);
auto struct_prop = dynamic_cast<Types::GenericStructProperty*>(prop);
if(!struct_prop) {
LOG_ERROR("The property is not a valid struct property.");
return false;
@ -239,3 +241,5 @@ StructSerialiser::writeStructValue(StructProperty* prop, std::size_t& bytes_writ
return true;
}
}}

View File

@ -0,0 +1,55 @@
#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2023 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/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealCollectionProperty.h"
#include "AbstractUnrealProperty.h"
#include "AbstractUnrealStruct.h"
#include "../Types/StructProperty.h"
namespace Gvas { namespace Serialisers {
class Struct : public AbstractUnrealProperty, public AbstractUnrealCollectionProperty {
public:
using ptr = Containers::Pointer<Struct>;
auto types() -> StringArrayView override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
std::uint32_t count, BinaryReader& reader, PropertySerialiser& serialiser)
-> PropertyArray override;
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialise(PropertyArrayView props, Containers::StringView item_type, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser) override;
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
private:
auto readStructValue(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser) -> Types::StructProperty::ptr;
bool writeStructValue(Types::StructProperty* prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser);
};
}}

View File

@ -16,17 +16,20 @@
#include <Corrade/Containers/String.h>
#include "../../Logger/Logger.h"
#include "../BinaryReader.h"
#include "../BinaryWriter.h"
#include "TextPropertySerialiser.h"
#include "TextProperty.h"
UnrealPropertyBase::ptr
TextPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
TextProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<TextProperty>();
auto prop = Containers::pointer<Types::TextProperty>();
auto start_position = reader.position();
@ -70,12 +73,12 @@ TextPropertySerialiser::deserialiseProperty(Containers::StringView name, Contain
}
bool
TextPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
TextProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{
auto text_prop = dynamic_cast<TextProperty*>(prop.get());
auto text_prop = dynamic_cast<Types::TextProperty*>(prop.get());
if(!text_prop) {
LOG_ERROR("The property is not a valid text property.");
return false;
}
@ -87,3 +90,5 @@ TextPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::si
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/TextProperty.h"
class TextPropertySerialiser : public UnrealPropertySerialiser<TextProperty> {
namespace Gvas { namespace Serialisers {
class TextProperty : public UnrealProperty<Types::TextProperty> {
public:
using ptr = Containers::Pointer<TextPropertySerialiser>;
using ptr = Containers::Pointer<TextProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -22,23 +22,25 @@
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/StringView.h>
#include "AbstractUnrealPropertySerialiser.h"
#include "AbstractUnrealProperty.h"
#include "../Types/StructProperty.h"
namespace Gvas { namespace Serialisers {
template<typename T>
class UnrealPropertySerialiser : public AbstractUnrealPropertySerialiser {
static_assert(std::is_base_of<UnrealPropertyBase, T>::value, "T must be derived from UnrealPropertyBase.");
class UnrealProperty : public AbstractUnrealProperty {
static_assert(std::is_base_of<Types::UnrealPropertyBase, T>::value, "T must be derived from UnrealPropertyBase.");
public:
using ptr = Containers::Pointer<UnrealPropertySerialiser<T>>;
using ptr = Containers::Pointer<UnrealProperty<T>>;
StringArrayView types() override {
auto types() -> StringArrayView override {
static const Containers::Array<Containers::String> types = []{
Containers::Array<Containers::String> array;
Containers::Pointer<T> p(new T);
if(std::is_base_of<StructProperty, T>::value) {
if(std::is_base_of<Types::StructProperty, T>::value) {
array = Containers::Array<Containers::String>{InPlaceInit, {
dynamic_cast<StructProperty*>(p.get())->structType
dynamic_cast<Types::StructProperty*>(p.get())->structType
}};
}
else {
@ -49,24 +51,26 @@ class UnrealPropertySerialiser : public AbstractUnrealPropertySerialiser {
return types;
}
UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override
auto deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override
{
return deserialiseProperty(name, type, value_length, reader, serialiser);
}
bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
bool serialise(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override
{
return serialiseProperty(prop, bytes_written, writer, serialiser);
}
private:
virtual UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) = 0;
virtual auto deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr = 0;
virtual bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) = 0;
virtual bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser) = 0;
};
}}

View File

@ -18,14 +18,15 @@
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "Vector2DPropertySerialiser.h"
#include "Vector2DProperty.h"
UnrealPropertyBase::ptr
Vector2DPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
Vector2DProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<Vector2DStructProperty>();
auto prop = Containers::pointer<Types::Vector2DStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y)) {
LOG_ERROR_FORMAT("Couldn't read 2D vector property {}'s value.", name);
@ -36,10 +37,10 @@ Vector2DPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
}
bool
Vector2DPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
Vector2DProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
auto vector = dynamic_cast<Vector2DStructProperty*>(prop.get());
auto vector = dynamic_cast<Types::Vector2DStructProperty*>(prop.get());
if(!vector) {
LOG_ERROR("The property is not a valid 2D vector property.");
return false;
@ -49,3 +50,5 @@ Vector2DPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/Vector2DStructProperty.h"
class Vector2DPropertySerialiser : public UnrealPropertySerialiser<Vector2DStructProperty> {
namespace Gvas { namespace Serialisers {
class Vector2DProperty : public UnrealProperty<Types::Vector2DStructProperty> {
public:
using ptr = Containers::Pointer<Vector2DPropertySerialiser>;
using ptr = Containers::Pointer<Vector2DProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -14,18 +14,20 @@
// 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 "../BinaryReader.h"
#include "../BinaryWriter.h"
#include "../../Logger/Logger.h"
#include "VectorPropertySerialiser.h"
#include "../BinaryReader.h"
#include "../BinaryWriter.h"
UnrealPropertyBase::ptr
VectorPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
#include "VectorProperty.h"
namespace Gvas { namespace Serialisers {
Types::UnrealPropertyBase::ptr
VectorProperty::deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{
auto prop = Containers::pointer<VectorStructProperty>();
auto prop = Containers::pointer<Types::VectorStructProperty>();
if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) {
LOG_ERROR_FORMAT("Couldn't read vector property {}'s value.", name);
@ -36,10 +38,10 @@ VectorPropertySerialiser::deserialiseProperty(Containers::StringView name, Conta
}
bool
VectorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
VectorProperty::serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{
auto vector = dynamic_cast<VectorStructProperty*>(prop.get());
auto vector = dynamic_cast<Types::VectorStructProperty*>(prop.get());
if(!vector) {
LOG_ERROR("The property is not a valid vector property.");
return false;
@ -50,3 +52,5 @@ VectorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::
return true;
}
}}

View File

@ -18,18 +18,22 @@
#include <Corrade/Containers/StringView.h>
#include "UnrealPropertySerialiser.h"
#include "UnrealProperty.h"
#include "../Types/VectorStructProperty.h"
class VectorPropertySerialiser : public UnrealPropertySerialiser<VectorStructProperty> {
namespace Gvas { namespace Serialisers {
class VectorProperty : public UnrealProperty<Types::VectorStructProperty> {
public:
using ptr = Containers::Pointer<VectorPropertySerialiser>;
using ptr = Containers::Pointer<VectorProperty>;
private:
UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
-> Types::UnrealPropertyBase::ptr override;
bool serialiseProperty(Types::UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
};
}}

View File

@ -23,6 +23,8 @@
#include "UnrealPropertyBase.h"
namespace Gvas { namespace Types {
struct ArrayProperty : public UnrealPropertyBase {
using ptr = Containers::Pointer<ArrayProperty>;
@ -44,3 +46,5 @@ struct ArrayProperty : public UnrealPropertyBase {
Containers::String itemType;
Containers::Array<UnrealPropertyBase::ptr> items;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct BoolProperty : public UnrealProperty<bool> {
using ptr = Containers::Pointer<BoolProperty>;
@ -31,3 +33,5 @@ struct BoolProperty : public UnrealProperty<bool> {
propertyType = "BoolProperty"_s;
}
};
}}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct ByteProperty : public UnrealProperty<Containers::Array<char>> {
using ptr = Containers::Pointer<ByteProperty>;
@ -33,7 +35,10 @@ struct ByteProperty : public UnrealProperty<Containers::Array<char>> {
propertyType = "ByteProperty"_s;
}
// For some reason, M.A.S.S. Builder stores EnumProperties as ByteProperties. Ugh...
// M.A.S.S. Builder stores EnumProperties as ByteProperties.
// I wonder if it's a general UE thing and agc93/unsave was just wrong.
Containers::String enumType;
Containers::String enumValue;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct ColourStructProperty : public StructProperty {
using ptr = Containers::Pointer<ColourStructProperty>;
ColourStructProperty() {
@ -31,3 +33,5 @@ struct ColourStructProperty : public StructProperty {
}
float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct DateTimeStructProperty : public StructProperty {
using ptr = Containers::Pointer<DateTimeStructProperty>;
@ -33,3 +35,5 @@ struct DateTimeStructProperty : public StructProperty {
std::int64_t timestamp = 0;
};
}}

View File

@ -24,6 +24,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct EnumProperty : public UnrealProperty<Containers::String> {
using ptr = Containers::Pointer<EnumProperty>;
@ -34,3 +36,5 @@ struct EnumProperty : public UnrealProperty<Containers::String> {
Containers::String enumType;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct FloatProperty : public UnrealProperty<float> {
using ptr = Containers::Pointer<FloatProperty>;
@ -31,3 +33,5 @@ struct FloatProperty : public UnrealProperty<float> {
propertyType = "FloatProperty"_s;
}
};
}}

View File

@ -26,6 +26,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct GenericStructProperty : public StructProperty {
using ptr = Containers::Pointer<GenericStructProperty>;
@ -53,3 +55,5 @@ struct GenericStructProperty : public StructProperty {
Containers::Array<UnrealPropertyBase::ptr> properties;
};
}}

View File

@ -24,6 +24,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct GuidStructProperty : public StructProperty {
using ptr = Containers::Pointer<GuidStructProperty>;
@ -34,3 +36,5 @@ struct GuidStructProperty : public StructProperty {
Containers::StaticArray<16, char> guid{ValueInit};
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct IntProperty : public UnrealProperty<std::int32_t> {
using ptr = Containers::Pointer<IntProperty>;
@ -31,3 +33,5 @@ struct IntProperty : public UnrealProperty<std::int32_t> {
propertyType = "IntProperty"_s;
}
};
}}

View File

@ -16,6 +16,7 @@
// 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/Pointer.h>
#include <Corrade/Containers/String.h>
#include <Corrade/Containers/StringView.h>
@ -24,6 +25,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct MapProperty : public UnrealPropertyBase {
using ptr = Containers::Pointer<MapProperty>;
@ -42,3 +45,5 @@ struct MapProperty : public UnrealPropertyBase {
Containers::Array<KeyValuePair> map;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct NoneProperty : UnrealPropertyBase {
using ptr = Containers::Pointer<NoneProperty>;
@ -32,3 +34,5 @@ struct NoneProperty : UnrealPropertyBase {
propertyType = "NoneProperty"_s;
}
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct ResourceItemValue : public StructProperty {
using ptr = Containers::Pointer<ResourceItemValue>;
@ -38,3 +40,5 @@ struct ResourceItemValue : public StructProperty {
std::int32_t id = 0;
std::int32_t quantity = 0;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct RotatorStructProperty : public StructProperty {
using ptr = Containers::Pointer<RotatorStructProperty>;
@ -33,3 +35,5 @@ struct RotatorStructProperty : public StructProperty {
float x = 0.0f, y = 0.0f, z = 0.0f;
};
}}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct SetProperty : public UnrealPropertyBase {
using ptr = Containers::Pointer<SetProperty>;
@ -44,3 +46,5 @@ struct SetProperty : public UnrealPropertyBase {
Containers::String itemType;
Containers::Array<UnrealPropertyBase::ptr> items;
};
}}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
using namespace Containers::Literals;
namespace Gvas { namespace Types {
struct StringProperty : public UnrealProperty<Containers::String> {
using ptr = Containers::Pointer<StringProperty>;
@ -32,3 +34,5 @@ struct StringProperty : public UnrealProperty<Containers::String> {
propertyType = type;
}
};
}}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct StructProperty : public UnrealPropertyBase {
using ptr = Containers::Pointer<StructProperty>;
@ -36,3 +38,5 @@ struct StructProperty : public UnrealPropertyBase {
Containers::StaticArray<16, char> structGuid{ValueInit};
Containers::String structType;
};
}}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct TextProperty : public UnrealProperty<Containers::String> {
using ptr = Containers::Pointer<TextProperty>;
@ -37,3 +39,5 @@ struct TextProperty : public UnrealProperty<Containers::String> {
char id = 0;
Containers::Array<Containers::String> data;
};
}}

View File

@ -16,18 +16,30 @@
// 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/Utility/Debug.h>
namespace Gvas { namespace Types {
struct ArrayProperty;
struct SetProperty;
struct GenericStructProperty;
struct StructProperty;
struct UnrealPropertyBase;
template<typename T>
struct UnrealProperty;
struct ArrayProperty;
struct BoolProperty;
struct ByteProperty;
struct ColourStructProperty;
struct DateTimeStructProperty;
struct EnumProperty;
struct FloatProperty;
struct GenericStructProperty;
struct GuidStructProperty;
struct IntProperty;
struct MapProperty;
struct NoneProperty;
struct ResourceItemValue;
struct RotatorStructProperty;
struct SetProperty;
struct StringProperty;
struct StructProperty;
struct TextProperty;
struct Vector2DStructProperty;
struct VectorStructProperty;
using namespace Corrade;
Utility::Debug& operator<<(Utility::Debug& debug, const ArrayProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const SetProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const GenericStructProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const StructProperty* prop);
Utility::Debug& operator<<(Utility::Debug& debug, const UnrealPropertyBase* prop);
}}

View File

@ -22,9 +22,13 @@
using namespace Corrade;
namespace Gvas { namespace Types {
template<typename T>
struct UnrealProperty : public UnrealPropertyBase {
using ptr = Containers::Pointer<UnrealProperty<T>>;
T value;
};
}}

View File

@ -24,6 +24,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct UnrealPropertyBase {
using ptr = Containers::Pointer<UnrealPropertyBase>;
@ -33,3 +35,5 @@ struct UnrealPropertyBase {
Containers::String propertyType;
std::size_t valueLength = 0;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct Vector2DStructProperty : public StructProperty {
using ptr = Containers::Pointer<Vector2DStructProperty>;
@ -33,3 +35,5 @@ struct Vector2DStructProperty : public StructProperty {
float x = 0.0f, y = 0.0f;
};
}}

View File

@ -23,6 +23,8 @@
using namespace Corrade;
namespace Gvas { namespace Types {
struct VectorStructProperty : public StructProperty {
using ptr = Containers::Pointer<VectorStructProperty>;
@ -33,3 +35,5 @@ struct VectorStructProperty : public StructProperty {
float x = 0.0f, y = 0.0f, z = 0.0f;
};
}}

View File

@ -45,7 +45,7 @@ class Logger {
Logger(Logger&&) = delete;
Logger& operator=(Logger&&) = delete;
static Logger& instance();
static auto instance() -> Logger&;
void initialise();
@ -69,7 +69,7 @@ class Logger {
std::mutex _logMutex{};
};
Logger& logger();
auto logger() -> Logger&;
#define LOG(entry_type, message) logger().lockMutex(); \
logger().log(EntryType::entry_type, \

View File

@ -28,7 +28,7 @@ class MagnumLogBuffer : public std::stringbuf {
~MagnumLogBuffer() override;
private:
int sync() override;
auto sync() -> int override;
EntryType _type;
};

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,8 @@
using namespace Corrade;
using namespace Containers::Literals;
namespace mbst { namespace GameData {
struct ArmourSet {
Containers::StringView name;
bool neck_compatible;
@ -55,3 +57,5 @@ static const std::map<std::int32_t, ArmourSet> armour_sets {
{26, {"Axial Core S-Type"_s, false}},
{27, {"Axial Core X-Type"_s, false}},
};
}}

View File

@ -23,36 +23,40 @@
using namespace Corrade;
using namespace Containers::Literals;
namespace mbst { namespace GameData {
static const std::map<std::int32_t, Containers::StringView> mission_id_map {{
// Story missions
{0x0064, "Mission 1 - Training"_s},
{0x0065, "Mission 2 - Patrol Operation"_s},
{0x0066, "Mission 3 - Fusion Cells in the Snow"_s},
{0x0067, "Mission 4 - Earning Changes"_s},
{0x0068, "Mission 5 - Unexpected Coordination"_s},
{0x0069, "Mission 6 - Empowering Void"_s},
{0x006A, "Mission 7 - Logisitics Obstacles"_s},
{0x006B, "Mission 8 - Wrath of the Wastelands"_s},
{0x006C, "Mission 9 - Suspicious Originator"_s},
{0x006D, "Mission 10 - Researchers Data Recovery"_s},
{0x006E, "Mission 11 - Tempestuous Sector"_s},
{0x006F, "Mission 12 - Clashes of Metal"_s},
{0x0070, "Mission 13 - The Sandstorm Glutton"_s},
{0x0071, "Mission 14 - An Icy Investigation"_s},
{0x0072, "Mission 15 - Outposts Line of Defense"_s},
{0x0073, "Mission 16 - Hidden in the Pass"_s},
{0x0074, "Mission 17 - Homebase Security"_s},
{100, "Mission 1 - Training"_s},
{101, "Mission 2 - Patrol Operation"_s},
{102, "Mission 3 - Fusion Cells in the Snow"_s},
{103, "Mission 4 - Earning Changes"_s},
{104, "Mission 5 - Unexpected Coordination"_s},
{105, "Mission 6 - Empowering Void"_s},
{106, "Mission 7 - Logisitics Obstacles"_s},
{107, "Mission 8 - Wrath of the Wastelands"_s},
{108, "Mission 9 - Suspicious Originator"_s},
{109, "Mission 10 - Researchers Data Recovery"_s},
{110, "Mission 11 - Tempestuous Sector"_s},
{111, "Mission 12 - Clashes of Metal"_s},
{112, "Mission 13 - The Sandstorm Glutton"_s},
{113, "Mission 14 - An Icy Investigation"_s},
{114, "Mission 15 - Outposts Line of Defense"_s},
{115, "Mission 16 - Hidden in the Pass"_s},
{116, "Mission 17 - Homebase Security"_s},
// Hunting grounds
{0x00C8, "Hunt 1 - Desert Pathway Safety"_s},
{0x00C9, "Hunt 2 - Snowfield Custodian"_s},
{0x00CA, "Hunt 3 - Abandoned Valley Raid"_s},
{0x00CB, "Hunt 4 - Depths of the Machineries"_s},
{0x00CC, "Hunt 5 - Crater Crashers"_s},
{0x00CD, "Hunt 6 - Prototype Performance Tests"_s},
{200, "Hunt 1 - Desert Pathway Safety"_s},
{201, "Hunt 2 - Snowfield Custodian"_s},
{202, "Hunt 3 - Abandoned Valley Raid"_s},
{203, "Hunt 4 - Depths of the Machineries"_s},
{204, "Hunt 5 - Crater Crashers"_s},
{205, "Hunt 6 - Prototype Performance Tests"_s},
// Challenges
{0x012C, "Challenge 1 - Redline Battlefront"_s},
{0x0140, "Challenge 2 - Void Convergence"_s},
{0x0190, "Challenge 3 - Gates of Ascension"_s}
{300, "Challenge 1 - Redline Battlefront"_s},
{320, "Challenge 2 - Void Convergence"_s},
{400, "Challenge 3 - Gates of Ascension"_s}
}};
}}

View File

@ -22,6 +22,8 @@
using namespace Corrade;
using namespace Containers::Literals;
namespace mbst { namespace GameData {
struct StoryProgressPoint {
std::int32_t id{};
Containers::StringView chapter = nullptr;
@ -109,3 +111,5 @@ static const Corrade::Containers::Array<StoryProgressPoint> story_progress
{0x070A, "Chapter 3"_s, "Got hunt 6 briefing"_s, "After mission 17"_s},
}
};
}}

View File

@ -25,6 +25,8 @@
using namespace Corrade;
using namespace Containers::Literals;
namespace mbst { namespace GameData {
extern const std::map<std::int32_t, Containers::StringView> style_names
#ifdef STYLENAMES_DEFINITION
{
@ -193,3 +195,5 @@ extern const std::map<std::int32_t, Containers::StringView> style_names
}
#endif
;
}}

View File

@ -25,6 +25,8 @@ using namespace Corrade;
using namespace Containers::Literals;
namespace mbst { namespace GameData {
// region Melee
static const std::map<std::int32_t, Containers::StringView> melee_grips {
{0, "Combat Grip (1H)"_s},
@ -430,3 +432,5 @@ static const std::map<std::int32_t, Containers::StringView> elauncher_pods {
{399, "P Base EPod (Photon)"_s},
};
// endregion
}}

Some files were not shown because too many files have changed in this diff Show More