Compare commits

...

10 commits

Author SHA1 Message Date
ba60d29253 CMakeLists: reorganise the sub-libs. 2022-12-13 22:23:47 +01:00
2ec415f2b5 CMakeLists: we're working on 1.5 now. 2022-12-13 21:15:06 +01:00
274d8ce014 CMakeLists: change how defines are handled. 2022-12-13 21:11:54 +01:00
267226a386 Profile,SaveTool: change how materials are handled. 2022-12-13 21:11:54 +01:00
d21e2cbabb SaveTool: update a TextUnformatted() call. 2022-12-13 21:11:54 +01:00
457bb5e89f Update coding style.
Magnum's type names are fine, but I'd rather limit what depends on
Magnum as much as possible. Vector types are still allowed, though. No
way I'll write my own.
2022-12-13 21:11:54 +01:00
5144121812 Match the new coding style I use. 2022-12-13 21:11:53 +01:00
cf69d3396f Configuration: add missing licence text. 2022-12-13 21:11:53 +01:00
3403feb668 SaveTool: move the configuration to its own class. 2022-12-13 21:11:53 +01:00
6450572f97 SaveTool: add a wrapper over ImGui::Checkbox().
This way, I can make it work like radio buttons or selectables.
2022-12-13 21:11:53 +01:00
111 changed files with 2029 additions and 1892 deletions

View file

@ -18,7 +18,7 @@ set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(SAVETOOL_PROJECT_VERSION 1.4.2) set(SAVETOOL_PROJECT_VERSION 1.5.0-pre)
find_package(Corrade REQUIRED Main Containers Utility) find_package(Corrade REQUIRED Main Containers Utility)
find_package(Magnum REQUIRED GL Sdl2Application) find_package(Magnum REQUIRED GL Sdl2Application)
@ -28,101 +28,8 @@ set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)
corrade_add_resource(Assets assets.conf) corrade_add_resource(Assets assets.conf)
add_library(Logger STATIC EXCLUDE_FROM_ALL add_subdirectory(Logger EXCLUDE_FROM_ALL)
Logger/Logger.h add_subdirectory(UESaveFile EXCLUDE_FROM_ALL)
Logger/Logger.cpp
Logger/EntryType.h
Logger/MagnumLogBuffer.h
Logger/MagnumLogBuffer.cpp
)
target_link_libraries(Logger PRIVATE
Corrade::Utility
Magnum::Magnum
)
add_library(UESaveFile STATIC EXCLUDE_FROM_ALL
UESaveFile/Serialisers/AbstractUnrealCollectionPropertySerialiser.h
UESaveFile/Serialisers/AbstractUnrealPropertySerialiser.h
UESaveFile/Serialisers/AbstractUnrealStructSerialiser.h
UESaveFile/Serialisers/ArrayPropertySerialiser.h
UESaveFile/Serialisers/ArrayPropertySerialiser.cpp
UESaveFile/Serialisers/BoolPropertySerialiser.h
UESaveFile/Serialisers/BoolPropertySerialiser.cpp
UESaveFile/Serialisers/BytePropertySerialiser.h
UESaveFile/Serialisers/BytePropertySerialiser.cpp
UESaveFile/Serialisers/ColourPropertySerialiser.h
UESaveFile/Serialisers/ColourPropertySerialiser.cpp
UESaveFile/Serialisers/DateTimePropertySerialiser.h
UESaveFile/Serialisers/DateTimePropertySerialiser.cpp
UESaveFile/Serialisers/EnumPropertySerialiser.h
UESaveFile/Serialisers/EnumPropertySerialiser.cpp
UESaveFile/Serialisers/FloatPropertySerialiser.h
UESaveFile/Serialisers/FloatPropertySerialiser.cpp
UESaveFile/Serialisers/GuidPropertySerialiser.h
UESaveFile/Serialisers/GuidPropertySerialiser.cpp
UESaveFile/Serialisers/IntPropertySerialiser.h
UESaveFile/Serialisers/IntPropertySerialiser.cpp
UESaveFile/Serialisers/MapPropertySerialiser.h
UESaveFile/Serialisers/MapPropertySerialiser.cpp
UESaveFile/Serialisers/ResourcePropertySerialiser.h
UESaveFile/Serialisers/ResourcePropertySerialiser.cpp
UESaveFile/Serialisers/RotatorPropertySerialiser.h
UESaveFile/Serialisers/RotatorPropertySerialiser.cpp
UESaveFile/Serialisers/StringPropertySerialiser.h
UESaveFile/Serialisers/StringPropertySerialiser.cpp
UESaveFile/Serialisers/SetPropertySerialiser.h
UESaveFile/Serialisers/SetPropertySerialiser.cpp
UESaveFile/Serialisers/StructSerialiser.h
UESaveFile/Serialisers/StructSerialiser.cpp
UESaveFile/Serialisers/TextPropertySerialiser.h
UESaveFile/Serialisers/TextPropertySerialiser.cpp
UESaveFile/Serialisers/UnrealPropertySerialiser.h
UESaveFile/Serialisers/VectorPropertySerialiser.h
UESaveFile/Serialisers/VectorPropertySerialiser.cpp
UESaveFile/Serialisers/Vector2DPropertySerialiser.h
UESaveFile/Serialisers/Vector2DPropertySerialiser.cpp
UESaveFile/Types/ArrayProperty.h
UESaveFile/Types/BoolProperty.h
UESaveFile/Types/ByteProperty.h
UESaveFile/Types/ColourStructProperty.h
UESaveFile/Types/DateTimeStructProperty.h
UESaveFile/Types/EnumProperty.h
UESaveFile/Types/FloatProperty.h
UESaveFile/Types/GenericStructProperty.h
UESaveFile/Types/GuidStructProperty.h
UESaveFile/Types/IntProperty.h
UESaveFile/Types/MapProperty.h
UESaveFile/Types/NoneProperty.h
UESaveFile/Types/RotatorStructProperty.h
UESaveFile/Types/SetProperty.h
UESaveFile/Types/StringProperty.h
UESaveFile/Types/StructProperty.h
UESaveFile/Types/ResourceItemValue.h
UESaveFile/Types/TextProperty.h
UESaveFile/Types/UnrealProperty.h
UESaveFile/Types/UnrealPropertyBase.h
UESaveFile/Types/VectorStructProperty.h
UESaveFile/Debug.h
UESaveFile/Debug.cpp
UESaveFile/UESaveFile.h
UESaveFile/UESaveFile.cpp
UESaveFile/BinaryReader.h
UESaveFile/BinaryReader.cpp
UESaveFile/BinaryWriter.h
UESaveFile/BinaryWriter.cpp
UESaveFile/PropertySerialiser.h
UESaveFile/PropertySerialiser.cpp
)
target_link_libraries(UESaveFile PRIVATE
Corrade::Containers
Corrade::Utility
Magnum::Magnum
Logger
)
add_executable(MassBuilderSaveTool WIN32 add_executable(MassBuilderSaveTool WIN32
main.cpp main.cpp
@ -139,6 +46,8 @@ add_executable(MassBuilderSaveTool WIN32
SaveTool/SaveTool_MassViewer_Weapons.cpp SaveTool/SaveTool_MassViewer_Weapons.cpp
SaveTool/SaveTool_ProfileManager.cpp SaveTool/SaveTool_ProfileManager.cpp
SaveTool/SaveTool_UpdateChecker.cpp SaveTool/SaveTool_UpdateChecker.cpp
Configuration/Configuration.h
Configuration/Configuration.cpp
ProfileManager/ProfileManager.h ProfileManager/ProfileManager.h
ProfileManager/ProfileManager.cpp ProfileManager/ProfileManager.cpp
Profile/Profile.h Profile/Profile.h
@ -186,11 +95,12 @@ add_executable(MassBuilderSaveTool WIN32
) )
if(CMAKE_BUILD_TYPE STREQUAL Debug) if(CMAKE_BUILD_TYPE STREQUAL Debug)
add_compile_definitions(SAVETOOL_DEBUG_BUILD) target_compile_definitions(Logger PRIVATE SAVETOOL_DEBUG_BUILD)
target_compile_definitions(MassBuilderSaveTool PRIVATE SAVETOOL_DEBUG_BUILD)
endif() endif()
add_compile_definitions( target_compile_definitions(MassBuilderSaveTool PRIVATE
SAVETOOL_VERSION="${SAVETOOL_PROJECT_VERSION}" SAVETOOL_VERSION="${SAVETOOL_PROJECT_VERSION}"
SAVETOOL_CODENAME="Enigmatic Ellenier" SAVETOOL_CODENAME="Friendly Valkyrie"
SUPPORTED_GAME_VERSION="0.9.x" SUPPORTED_GAME_VERSION="0.9.x"
) )

View file

@ -0,0 +1,168 @@
// MassBuilderSaveTool
// Copyright (C) 2021-2022 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/Optional.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Utility/Path.h>
#include "Configuration.h"
Configuration::Configuration() {
Containers::String exe_path = Utility::Path::split(*Utility::Path::executableLocation()).first();
_conf = Utility::Configuration{Utility::Path::join(exe_path, "MassBuilderSaveTool.ini")};
if(_conf.hasValue("swap_interval")) {
_swapInterval = _conf.value<int>("swap_interval");
}
else {
_conf.setValue("swap_interval", 1);
}
if(_conf.hasValue("frame_limit")) {
std::string frame_limit = _conf.value("frame_limit");
if(frame_limit == "half_vsync") {
_swapInterval = 2;
}
_conf.removeValue("frame_limit");
}
if(_conf.hasValue("fps_cap")) {
_fpsCap = _conf.value<float>("fps_cap");
}
else {
_conf.setValue("fps_cap", 60.0f);
}
if(_conf.hasValue("cheat_mode")) {
_cheatMode = _conf.value<bool>("cheat_mode");
}
else {
_conf.setValue("cheat_mode", _cheatMode);
}
if(_conf.hasValue("advanced_mode")) {
_advancedMode = _conf.value<bool>("advanced_mode");
}
else {
_conf.setValue("advanced_mode", _advancedMode);
}
if(_conf.hasValue("startup_update_check")) {
_checkUpdatesOnStartup = _conf.value<bool>("startup_update_check");
}
else {
_conf.setValue("startup_update_check", _checkUpdatesOnStartup);
}
if(_conf.hasValue("skip_disclaimer")) {
_skipDisclaimer = _conf.value<bool>("skip_disclaimer");
}
else {
_conf.setValue("skip_disclaimer", _skipDisclaimer);
}
}
Configuration::~Configuration() {
save();
}
void
Configuration::save() {
_conf.save();
}
int
Configuration::swapInterval() const {
return _swapInterval;
}
void
Configuration::setSwapInterval(int interval) {
_swapInterval = interval;
_conf.setValue("swap_interval", _swapInterval);
_conf.save();
}
float
Configuration::fpsCap() const {
return _fpsCap;
}
void
Configuration::setFpsCap(float cap) {
_fpsCap = cap;
_conf.setValue("fps_cap", _fpsCap);
_conf.save();
}
bool
Configuration::cheatMode() const {
return _cheatMode;
}
void
Configuration::setCheatMode(bool enabled) {
_cheatMode = enabled;
_conf.setValue("cheat_mode", _cheatMode);
_conf.save();
}
bool
Configuration::advancedMode() const {
return _advancedMode;
}
void
Configuration::setAdvancedMode(bool enabled) {
_advancedMode = enabled;
_conf.setValue("advanced_mode", _advancedMode);
_conf.save();
}
bool
Configuration::checkUpdatesOnStartup() const {
return _checkUpdatesOnStartup;
}
void
Configuration::setCheckUpdatesOnStartup(bool mode) {
_checkUpdatesOnStartup = mode;
_conf.setValue("startup_update_check", _checkUpdatesOnStartup);
_conf.save();
}
bool
Configuration::skipDisclaimer() const {
return _skipDisclaimer;
}
void
Configuration::setSkipDisclaimer(bool mode) {
_skipDisclaimer = mode;
_conf.setValue("skip_disclaimer", _skipDisclaimer);
_conf.save();
}
Configuration&
Configuration::instance() {
static Configuration conf{};
return conf;
}
Configuration&
conf() {
return Configuration::instance();
}

View file

@ -0,0 +1,62 @@
#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2022 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/Configuration.h>
using namespace Corrade;
class Configuration {
public:
static Configuration& instance();
~Configuration();
void save();
int swapInterval() const;
void setSwapInterval(int interval);
float fpsCap() const;
void setFpsCap(float cap);
bool cheatMode() const;
void setCheatMode(bool enabled);
bool advancedMode() const;
void setAdvancedMode(bool enabled);
bool checkUpdatesOnStartup() const;
void setCheckUpdatesOnStartup(bool mode);
bool skipDisclaimer() const;
void setSkipDisclaimer(bool mode);
private:
explicit Configuration();
Utility::Configuration _conf;
int _swapInterval = 1;
float _fpsCap = 60.0f;
bool _cheatMode = false;
bool _advancedMode = false;
bool _checkUpdatesOnStartup = true;
bool _skipDisclaimer = false;
};
Configuration& conf();

28
src/Logger/CMakeLists.txt Normal file
View file

@ -0,0 +1,28 @@
# MassBuilderSaveTool
# Copyright (C) 2021-2022 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(Logger STATIC EXCLUDE_FROM_ALL
Logger.h
Logger.cpp
EntryType.h
MagnumLogBuffer.h
MagnumLogBuffer.cpp
)
target_link_libraries(Logger PRIVATE
Corrade::Utility
Magnum::Magnum
)

View file

@ -25,8 +25,6 @@ using Utility::Debug;
using Utility::Warning; using Utility::Warning;
using Utility::Error; using Utility::Error;
using namespace Magnum;
Logger& Logger&
Logger::instance() { Logger::instance() {
static Logger logger; static Logger logger;
@ -89,7 +87,7 @@ Logger::log(EntryType type, StringView location, StringView message) {
d << "["_s << Debug::nospace << location << Debug::nospace << "]"; d << "["_s << Debug::nospace << location << Debug::nospace << "]";
for(UnsignedInt i = 0; i < _indentLevel; i++) { for(auto i = 0u; i < _indentLevel; i++) {
d << Debug::nospace << " "_s << Debug::nospace; d << Debug::nospace << " "_s << Debug::nospace;
} }

View file

@ -27,8 +27,6 @@
#include <Corrade/Containers/ArrayView.h> #include <Corrade/Containers/ArrayView.h>
#include <Corrade/Utility/Format.h> #include <Corrade/Utility/Format.h>
#include <Magnum/Types.h>
#include "EntryType.h" #include "EntryType.h"
using namespace Corrade; using namespace Corrade;
@ -37,8 +35,6 @@ using Containers::ArrayView;
using Containers::String; using Containers::String;
using Containers::StringView; using Containers::StringView;
using namespace Magnum;
using namespace Containers::Literals; using namespace Containers::Literals;
class Logger { class Logger {
@ -49,7 +45,7 @@ class Logger {
Logger(Logger&&) = delete; Logger(Logger&&) = delete;
Logger& operator=(Logger&&) = delete; Logger& operator=(Logger&&) = delete;
static auto instance() -> Logger&; static Logger& instance();
void initialise(); void initialise();
@ -68,12 +64,12 @@ class Logger {
std::ofstream _logFile; std::ofstream _logFile;
#endif #endif
UnsignedInt _indentLevel = 0; std::uint32_t _indentLevel = 0;
std::mutex _logMutex{}; std::mutex _logMutex{};
}; };
auto logger() -> Logger&; Logger& logger();
#define LOG(entry_type, message) logger().lockMutex(); \ #define LOG(entry_type, message) logger().lockMutex(); \
logger().log(EntryType::entry_type, \ logger().log(EntryType::entry_type, \

View file

@ -16,7 +16,12 @@
#include "MagnumLogBuffer.h" #include "MagnumLogBuffer.h"
MagnumLogBuffer::MagnumLogBuffer(EntryType type): std::stringbuf(std::ios_base::out), _type{type} {} MagnumLogBuffer::MagnumLogBuffer(EntryType type):
std::stringbuf(std::ios_base::out),
_type{type}
{
//ctor
}
MagnumLogBuffer::~MagnumLogBuffer() = default; MagnumLogBuffer::~MagnumLogBuffer() = default;

View file

@ -16,15 +16,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <map> #include <map>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Containers::Literals; using namespace Containers::Literals;
using namespace Magnum;
enum AccessorySize { enum AccessorySize {
S, S,
@ -38,7 +37,7 @@ struct AccessoryData{
AccessorySize size = AccessorySize::S; AccessorySize size = AccessorySize::S;
}; };
static const std::map<Int, AccessoryData> accessories { static const std::map<std::int32_t, AccessoryData> accessories {
// region Primitives // region Primitives
{1, {"Cube"_s, AccessorySize::S}}, {1, {"Cube"_s, AccessorySize::S}},
{2, {"Pentagon"_s, AccessorySize::S}}, {2, {"Pentagon"_s, AccessorySize::S}},

View file

@ -16,22 +16,21 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <map> #include <map>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Containers::Literals; using namespace Containers::Literals;
using namespace Magnum;
struct ArmourSet { struct ArmourSet {
Containers::StringView name; Containers::StringView name;
bool neck_compatible; bool neck_compatible;
}; };
static const std::map<Int, ArmourSet> armour_sets { static const std::map<std::int32_t, ArmourSet> armour_sets {
{-1, {"<unequipped>"_s, true}}, {-1, {"<unequipped>"_s, true}},
{0, {"Vanguard"_s, true}}, {0, {"Vanguard"_s, true}},
{1, {"Assault Mk.I"_s, true}}, {1, {"Assault Mk.I"_s, true}},

View file

@ -20,13 +20,10 @@
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Containers::Literals; using namespace Containers::Literals;
using namespace Magnum;
static const std::map<Int, Containers::StringView> mission_id_map {{ static const std::map<std::int32_t, Containers::StringView> mission_id_map {{
// Story missions // Story missions
{0x0064, "Mission 1 - Training"_s}, {0x0064, "Mission 1 - Training"_s},
{0x0065, "Mission 2 - Patrol Operation"_s}, {0x0065, "Mission 2 - Patrol Operation"_s},

View file

@ -19,14 +19,11 @@
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Containers::Literals; using namespace Containers::Literals;
using namespace Magnum;
struct StoryProgressPoint { struct StoryProgressPoint {
Int id; std::int32_t id;
Containers::StringView chapter; Containers::StringView chapter;
Containers::StringView point; Containers::StringView point;
Containers::StringView after = nullptr; Containers::StringView after = nullptr;

View file

@ -16,17 +16,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <map> #include <map>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Magnum.h>
using namespace Corrade; using namespace Corrade;
using namespace Containers::Literals; using namespace Containers::Literals;
using namespace Magnum;
extern const std::map<Int, Containers::StringView> style_names extern const std::map<std::int32_t, Containers::StringView> style_names
#ifdef STYLENAMES_DEFINITION #ifdef STYLENAMES_DEFINITION
{ {
{0, "Custom Style 1"_s}, {0, "Custom Style 1"_s},

View file

@ -15,19 +15,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <map> #include <map>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
using namespace Containers::Literals; using namespace Containers::Literals;
// region Melee // region Melee
static const std::map<Int, Containers::StringView> melee_grips { static const std::map<std::int32_t, Containers::StringView> melee_grips {
{0, "Combat Grip (1H)"_s}, {0, "Combat Grip (1H)"_s},
{1, "Knuckle Guard Grip (1H)"_s}, {1, "Knuckle Guard Grip (1H)"_s},
{2, "Dual Guard Grip (1H)"_s}, {2, "Dual Guard Grip (1H)"_s},
@ -78,7 +77,7 @@ static const std::map<Int, Containers::StringView> melee_grips {
{2404, "Arched Twin Blade (2H)"_s}, {2404, "Arched Twin Blade (2H)"_s},
}; };
static const std::map<Int, Containers::StringView> melee_assaulters { static const std::map<std::int32_t, Containers::StringView> melee_assaulters {
{0, "Long Metal Blade"_s}, {0, "Long Metal Blade"_s},
{1, "Long Assault Blade"_s}, {1, "Long Assault Blade"_s},
{2, "Long Fin Blade"_s}, {2, "Long Fin Blade"_s},
@ -172,7 +171,7 @@ static const std::map<Int, Containers::StringView> melee_assaulters {
// endregion // endregion
// region Shields // region Shields
static const std::map<Int, Containers::StringView> shield_handles { static const std::map<std::int32_t, Containers::StringView> shield_handles {
{0, "Balanced Handle"_s}, {0, "Balanced Handle"_s},
{1, "Expanded Handle"_s}, {1, "Expanded Handle"_s},
{2, "Lowguard Handle"_s}, {2, "Lowguard Handle"_s},
@ -191,7 +190,7 @@ static const std::map<Int, Containers::StringView> shield_handles {
{101, "Star Handle"_s}, {101, "Star Handle"_s},
}; };
static const std::map<Int, Containers::StringView> shield_shells { static const std::map<std::int32_t, Containers::StringView> shield_shells {
{0, "Balanced Shell"_s}, {0, "Balanced Shell"_s},
{1, "Compass Shell"_s}, {1, "Compass Shell"_s},
{2, "Uppoint Shell"_s}, {2, "Uppoint Shell"_s},
@ -212,7 +211,7 @@ static const std::map<Int, Containers::StringView> shield_shells {
// endregion // endregion
// region Bullet Shooters // region Bullet Shooters
static const std::map<Int, Containers::StringView> bshooter_triggers { static const std::map<std::int32_t, Containers::StringView> bshooter_triggers {
{0, "BL-Combat Trigger (1H)"_s}, {0, "BL-Combat Trigger (1H)"_s},
{1, "Light Machine Trigger (1H)"_s}, {1, "Light Machine Trigger (1H)"_s},
{2, "Tactical Trigger (1H)"_s}, {2, "Tactical Trigger (1H)"_s},
@ -230,7 +229,7 @@ static const std::map<Int, Containers::StringView> bshooter_triggers {
{199, "2H Base Trigger (2H)"_s}, {199, "2H Base Trigger (2H)"_s},
}; };
static const std::map<Int, Containers::StringView> bshooter_barrels { static const std::map<std::int32_t, Containers::StringView> bshooter_barrels {
{0, "BL-Combat Barrel (1 shot)"_s}, {0, "BL-Combat Barrel (1 shot)"_s},
{1, "Shock Absorb Barrel (1 shot) (Motion)"_s}, {1, "Shock Absorb Barrel (1 shot) (Motion)"_s},
{2, "Muzzlemod Barrel (1 shot)"_s}, {2, "Muzzlemod Barrel (1 shot)"_s},
@ -267,7 +266,7 @@ static const std::map<Int, Containers::StringView> bshooter_barrels {
// endregion // endregion
//region Energy Shooters //region Energy Shooters
static const std::map<Int, Containers::StringView> eshooter_triggers { static const std::map<std::int32_t, Containers::StringView> eshooter_triggers {
{0, "EN-Rifle Trigger (1H)"_s}, {0, "EN-Rifle Trigger (1H)"_s},
{1, "Underarm Trigger (1H)"_s}, {1, "Underarm Trigger (1H)"_s},
{2, "EN-Inverted Trigger (1H)"_s}, {2, "EN-Inverted Trigger (1H)"_s},
@ -285,7 +284,7 @@ static const std::map<Int, Containers::StringView> eshooter_triggers {
{199, "2H Base EnTrigger (2H)"_s}, {199, "2H Base EnTrigger (2H)"_s},
}; };
static const std::map<Int, Containers::StringView> eshooter_busters { static const std::map<std::int32_t, Containers::StringView> eshooter_busters {
{0, "EN-Combat Buster (1 shot)"_s}, {0, "EN-Combat Buster (1 shot)"_s},
{1, "Delta Cycler (1 shot) (Motion)"_s}, {1, "Delta Cycler (1 shot) (Motion)"_s},
{2, "EN-Longbarrel Buster (1 shot)"_s}, {2, "EN-Longbarrel Buster (1 shot)"_s},
@ -321,7 +320,7 @@ static const std::map<Int, Containers::StringView> eshooter_busters {
// endregion // endregion
// region Bullet Launchers // region Bullet Launchers
static const std::map<Int, Containers::StringView> blauncher_pods { static const std::map<std::int32_t, Containers::StringView> blauncher_pods {
{0, "BL-Delta Pack Launcher (Missile x12)"_s}, {0, "BL-Delta Pack Launcher (Missile x12)"_s},
{1, "BL-Twin Pack Launcher (Missile x12)"_s}, {1, "BL-Twin Pack Launcher (Missile x12)"_s},
{2, "Detector Launcher (Missile x12)"_s}, {2, "Detector Launcher (Missile x12)"_s},
@ -351,7 +350,7 @@ static const std::map<Int, Containers::StringView> blauncher_pods {
{399, "C Base Pod (Cluster x40)"_s}, {399, "C Base Pod (Cluster x40)"_s},
}; };
static const std::map<Int, Containers::StringView> blauncher_projectiles { static const std::map<std::int32_t, Containers::StringView> blauncher_projectiles {
{0, "Flathead Missile"_s}, {0, "Flathead Missile"_s},
{1, "Warhead Missile"_s}, {1, "Warhead Missile"_s},
{2, "Pointhead Missile"_s}, {2, "Pointhead Missile"_s},
@ -361,7 +360,7 @@ static const std::map<Int, Containers::StringView> blauncher_projectiles {
// endregion // endregion
// region Energy Launchers // region Energy Launchers
static const std::map<Int, Containers::StringView> elauncher_generators { static const std::map<std::int32_t, Containers::StringView> elauncher_generators {
{0, "Fly Unit"_s}, {0, "Fly Unit"_s},
{1, "Assault Unit (Motion)"_s}, {1, "Assault Unit (Motion)"_s},
{2, "Falcon Unit"_s}, {2, "Falcon Unit"_s},
@ -393,7 +392,7 @@ static const std::map<Int, Containers::StringView> elauncher_generators {
{99, "Base Generator"}, {99, "Base Generator"},
}; };
static const std::map<Int, Containers::StringView> elauncher_pods { static const std::map<std::int32_t, Containers::StringView> elauncher_pods {
{0, "EN-Dual Claw Launcher (Echo) (Motion)"_s}, {0, "EN-Dual Claw Launcher (Echo) (Motion)"_s},
{1, "EN-Assault Launcher (Echo)"_s}, {1, "EN-Assault Launcher (Echo)"_s},
{2, "EN-Tactical Launcher (Echo)"_s}, {2, "EN-Tactical Launcher (Echo)"_s},

View file

@ -25,9 +25,9 @@ using namespace Corrade;
using namespace Magnum; using namespace Magnum;
struct Accessory { struct Accessory {
Int attachIndex = -1; std::int32_t attachIndex = -1;
Int id = -1; std::int32_t id = -1;
Containers::StaticArray<2, Int> styles{ValueInit}; Containers::StaticArray<2, std::int32_t> styles{ValueInit};
Vector3 relativePosition{0.0f}; Vector3 relativePosition{0.0f};
Vector3 relativePositionOffset{0.0f}; Vector3 relativePositionOffset{0.0f};
Vector3 relativeRotation{0.0f}; Vector3 relativeRotation{0.0f};

View file

@ -19,13 +19,10 @@
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Magnum/Types.h>
#include "Decal.h" #include "Decal.h"
#include "Accessory.h" #include "Accessory.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
enum class ArmourSlot { enum class ArmourSlot {
#define c(enumerator, enumstr, name) enumerator, #define c(enumerator, enumstr, name) enumerator,
@ -35,8 +32,8 @@ enum class ArmourSlot {
struct ArmourPart { struct ArmourPart {
ArmourSlot slot = ArmourSlot::Face; ArmourSlot slot = ArmourSlot::Face;
Int id = 0; std::int32_t id = 0;
Containers::StaticArray<4, Int> styles{ValueInit}; Containers::StaticArray<4, std::int32_t> styles{ValueInit};
Containers::Array<Decal> decals; Containers::Array<Decal> decals;
Containers::Array<Accessory> accessories; Containers::Array<Accessory> accessories;
}; };

View file

@ -28,13 +28,13 @@ using namespace Magnum;
struct CustomStyle { struct CustomStyle {
Containers::String name; Containers::String name;
Color4 colour{0.0f}; Color4 colour{0.0f};
Float metallic = 0.5f; float metallic = 0.5f;
Float gloss = 0.5f; float gloss = 0.5f;
bool glow = false; bool glow = false;
Int patternId = 0; std::int32_t patternId = 0;
Float opacity = 0.5f; float opacity = 0.5f;
Vector2 offset{0.5f}; Vector2 offset{0.5f};
Float rotation = 0.0f; float rotation = 0.0f;
Float scale = 0.5f; float scale = 0.5f;
}; };

View file

@ -19,18 +19,19 @@
#include <Magnum/Magnum.h> #include <Magnum/Magnum.h>
#include <Magnum/Math/Color.h> #include <Magnum/Math/Color.h>
#include <Magnum/Math/Vector2.h> #include <Magnum/Math/Vector2.h>
#include <Magnum/Math/Vector3.h>
using namespace Magnum; using namespace Magnum;
struct Decal { struct Decal {
Int id = -1; std::int32_t id = -1;
Color4 colour{0.0f}; Color4 colour{0.0f};
Vector3 position{0.0f}; Vector3 position{0.0f};
Vector3 uAxis{0.0f}; Vector3 uAxis{0.0f};
Vector3 vAxis{0.0f}; Vector3 vAxis{0.0f};
Vector2 offset{0.5f}; Vector2 offset{0.5f};
Float scale = 0.5f; float scale = 0.5f;
Float rotation = 0.0f; float rotation = 0.0f;
bool flip = false; bool flip = false;
bool wrap = false; bool wrap = false;
}; };

View file

@ -16,17 +16,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <Magnum/Types.h>
using namespace Magnum;
struct Joints { struct Joints {
Float neck = 0.0f; float neck = 0.0f;
Float body = 0.0f; float body = 0.0f;
Float shoulders = 0.0f; float shoulders = 0.0f;
Float hips = 0.0f; float hips = 0.0f;
Float upperArms = 0.0f; float upperArms = 0.0f;
Float lowerArms = 0.0f; float lowerArms = 0.0f;
Float upperLegs = 0.0f; float upperLegs = 0.0f;
Float lowerLegs = 0.0f; float lowerLegs = 0.0f;
}; };

View file

@ -42,11 +42,13 @@ Mass::Mass(Containers::StringView path) {
refreshValues(); refreshValues();
} }
auto Mass::lastError() -> Containers::StringView { Containers::StringView
Mass::lastError() {
return _lastError; return _lastError;
} }
auto Mass::getNameFromFile(Containers::StringView path) -> Containers::Optional<Containers::String> { Containers::Optional<Containers::String>
Mass::getNameFromFile(Containers::StringView path) {
if(!Utility::Path::exists(path)) { if(!Utility::Path::exists(path)) {
LOG_ERROR_FORMAT("{} couldn't be found.", path); LOG_ERROR_FORMAT("{} couldn't be found.", path);
return Containers::NullOpt; return Containers::NullOpt;
@ -76,7 +78,8 @@ auto Mass::getNameFromFile(Containers::StringView path) -> Containers::Optional<
return {name_prop->value}; return {name_prop->value};
} }
void Mass::refreshValues() { void
Mass::refreshValues() {
LOG_INFO_FORMAT("Refreshing values for {}.", _filename); LOG_INFO_FORMAT("Refreshing values for {}.", _filename);
logger().lockMutex(); logger().lockMutex();
@ -229,16 +232,19 @@ void Mass::refreshValues() {
_state = State::Valid; _state = State::Valid;
} }
auto Mass::filename() -> Containers::StringView { Containers::StringView
Mass::filename() {
return _filename; return _filename;
} }
auto Mass::name() -> Containers::StringView { Containers::StringView
Mass::name() {
CORRADE_INTERNAL_ASSERT(_name); CORRADE_INTERNAL_ASSERT(_name);
return *_name; return *_name;
} }
auto Mass::setName(Containers::StringView new_name) -> bool { bool
Mass::setName(Containers::StringView new_name) {
_name = {new_name}; _name = {new_name};
auto unit_data = _mass->at<GenericStructProperty>("UnitData"_s); auto unit_data = _mass->at<GenericStructProperty>("UnitData"_s);
@ -267,19 +273,22 @@ auto Mass::setName(Containers::StringView new_name) -> bool {
return true; return true;
} }
auto Mass::state() -> State { Mass::State
Mass::state() {
return _state; return _state;
} }
auto Mass::dirty() const -> bool { bool Mass::dirty() const {
return _dirty; return _dirty;
} }
void Mass::setDirty(bool dirty) { void
Mass::setDirty(bool dirty) {
_dirty = dirty; _dirty = dirty;
} }
void Mass::getTuning() { void
Mass::getTuning() {
getTuningCategory(MASS_ENGINE, _tuning.engineId, getTuningCategory(MASS_ENGINE, _tuning.engineId,
MASS_GEARS, _tuning.gearIds); MASS_GEARS, _tuning.gearIds);
if(_state == State::Invalid) { if(_state == State::Invalid) {
@ -299,35 +308,43 @@ void Mass::getTuning() {
} }
} }
auto Mass::engine() -> Int& { std::int32_t&
Mass::engine() {
return _tuning.engineId; return _tuning.engineId;
} }
auto Mass::gears() -> Containers::ArrayView<Int> { Containers::ArrayView<std::int32_t>
Mass::gears() {
return _tuning.gearIds; return _tuning.gearIds;
} }
auto Mass::os() -> Int& { std::int32_t&
Mass::os() {
return _tuning.osId; return _tuning.osId;
} }
auto Mass::modules() -> Containers::ArrayView<Int> { Containers::ArrayView<std::int32_t>
Mass::modules() {
return _tuning.moduleIds; return _tuning.moduleIds;
} }
auto Mass::architecture() -> Int& { std::int32_t&
Mass::architecture() {
return _tuning.archId; return _tuning.archId;
} }
auto Mass::techs() -> Containers::ArrayView<Int> { Containers::ArrayView<std::int32_t>
Mass::techs() {
return _tuning.techIds; return _tuning.techIds;
} }
auto Mass::account() -> Containers::StringView { Containers::StringView
Mass::account() {
return _account; return _account;
} }
auto Mass::updateAccount(Containers::StringView new_account) -> bool { bool
Mass::updateAccount(Containers::StringView new_account) {
_account = new_account; _account = new_account;
auto account = _mass->at<StringProperty>(MASS_ACCOUNT); auto account = _mass->at<StringProperty>(MASS_ACCOUNT);
@ -347,8 +364,10 @@ auto Mass::updateAccount(Containers::StringView new_account) -> bool {
return true; return true;
} }
void Mass::getTuningCategory(Containers::StringView big_node_prop_name, Int& big_node_id, void
Containers::StringView small_nodes_prop_name, Containers::ArrayView<Int> small_nodes_ids) Mass::getTuningCategory(Containers::StringView big_node_prop_name, std::int32_t& big_node_id,
Containers::StringView small_nodes_prop_name,
Containers::ArrayView<std::int32_t> small_nodes_ids)
{ {
LOG_INFO_FORMAT("Getting tuning data ({}, {}).", big_node_prop_name, small_nodes_prop_name); LOG_INFO_FORMAT("Getting tuning data ({}, {}).", big_node_prop_name, small_nodes_prop_name);
@ -374,7 +393,7 @@ void Mass::getTuningCategory(Containers::StringView big_node_prop_name, Int& big
return; return;
} }
for(UnsignedInt i = 0; i < small_nodes_ids.size(); i++) { for(std::uint32_t i = 0; i < small_nodes_ids.size(); i++) {
auto small_node_id = node_ids->at<IntProperty>(i); auto small_node_id = node_ids->at<IntProperty>(i);
CORRADE_INTERNAL_ASSERT(small_node_id); CORRADE_INTERNAL_ASSERT(small_node_id);
small_nodes_ids[i] = small_node_id->value; small_nodes_ids[i] = small_node_id->value;

View file

@ -45,10 +45,6 @@ struct ArrayProperty;
class Mass { class Mass {
public: public:
enum class State : UnsignedByte {
Empty, Invalid, Valid
};
explicit Mass(Containers::StringView path); explicit Mass(Containers::StringView path);
Mass(const Mass&) = delete; Mass(const Mass&) = delete;
@ -57,96 +53,100 @@ class Mass {
Mass(Mass&&) = default; Mass(Mass&&) = default;
Mass& operator=(Mass&&) = default; Mass& operator=(Mass&&) = default;
auto lastError() -> Containers::StringView; Containers::StringView lastError();
static auto getNameFromFile(Containers::StringView path) -> Containers::Optional<Containers::String>; static Containers::Optional<Containers::String> getNameFromFile(Containers::StringView path);
void refreshValues(); void refreshValues();
auto filename() -> Containers::StringView; Containers::StringView filename();
auto name() -> Containers::StringView; Containers::StringView name();
auto setName(Containers::StringView new_name) -> bool; bool setName(Containers::StringView new_name);
auto state() -> State; enum class State: std::uint8_t {
Empty, Invalid, Valid
};
auto dirty() const -> bool; State state();
bool dirty() const;
void setDirty(bool dirty = true); void setDirty(bool dirty = true);
auto jointSliders() -> Joints&; Joints& jointSliders();
void getJointSliders(); void getJointSliders();
auto writeJointSliders() -> bool; bool writeJointSliders();
auto frameStyles() -> Containers::ArrayView<Int>; Containers::ArrayView<std::int32_t> frameStyles();
void getFrameStyles(); void getFrameStyles();
auto writeFrameStyles() -> bool; bool writeFrameStyles();
auto eyeFlareColour() -> Color4&; Color4& eyeFlareColour();
void getEyeFlareColour(); void getEyeFlareColour();
auto writeEyeFlareColour() -> bool; bool writeEyeFlareColour();
auto frameCustomStyles() -> Containers::ArrayView<CustomStyle>; Containers::ArrayView<CustomStyle> frameCustomStyles();
void getFrameCustomStyles(); void getFrameCustomStyles();
auto writeFrameCustomStyle(UnsignedLong index) -> bool; bool writeFrameCustomStyle(std::size_t index);
auto armourParts() -> Containers::ArrayView<ArmourPart>; Containers::ArrayView<ArmourPart> armourParts();
void getArmourParts(); void getArmourParts();
auto writeArmourPart(ArmourSlot slot) -> bool; bool writeArmourPart(ArmourSlot slot);
auto bulletLauncherAttachmentStyle() -> BulletLauncherAttachmentStyle&; BulletLauncherAttachmentStyle& bulletLauncherAttachmentStyle();
auto bulletLauncherAttachments() -> Containers::ArrayView<BulletLauncherAttachment>; Containers::ArrayView<BulletLauncherAttachment> bulletLauncherAttachments();
void getBulletLauncherAttachments(); void getBulletLauncherAttachments();
auto writeBulletLauncherAttachments() -> bool; bool writeBulletLauncherAttachments();
auto armourCustomStyles() -> Containers::ArrayView<CustomStyle>; Containers::ArrayView<CustomStyle> armourCustomStyles();
void getArmourCustomStyles(); void getArmourCustomStyles();
auto writeArmourCustomStyle(UnsignedLong index) -> bool; bool writeArmourCustomStyle(std::size_t index);
auto meleeWeapons() -> Containers::ArrayView<Weapon>; Containers::ArrayView<Weapon> meleeWeapons();
void getMeleeWeapons(); void getMeleeWeapons();
auto writeMeleeWeapons() -> bool; bool writeMeleeWeapons();
auto shields() -> Containers::ArrayView<Weapon>; Containers::ArrayView<Weapon> shields();
void getShields(); void getShields();
auto writeShields() -> bool; bool writeShields();
auto bulletShooters() -> Containers::ArrayView<Weapon>; Containers::ArrayView<Weapon> bulletShooters();
void getBulletShooters(); void getBulletShooters();
auto writeBulletShooters() -> bool; bool writeBulletShooters();
auto energyShooters() -> Containers::ArrayView<Weapon>; Containers::ArrayView<Weapon> energyShooters();
void getEnergyShooters(); void getEnergyShooters();
auto writeEnergyShooters() -> bool; bool writeEnergyShooters();
auto bulletLaunchers() -> Containers::ArrayView<Weapon>; Containers::ArrayView<Weapon> bulletLaunchers();
void getBulletLaunchers(); void getBulletLaunchers();
auto writeBulletLaunchers() -> bool; bool writeBulletLaunchers();
auto energyLaunchers() -> Containers::ArrayView<Weapon>; Containers::ArrayView<Weapon> energyLaunchers();
void getEnergyLaunchers(); void getEnergyLaunchers();
auto writeEnergyLaunchers() -> bool; bool writeEnergyLaunchers();
auto globalStyles() -> Containers::ArrayView<CustomStyle>; Containers::ArrayView<CustomStyle> globalStyles();
void getGlobalStyles(); void getGlobalStyles();
auto writeGlobalStyle(UnsignedLong index) -> bool; bool writeGlobalStyle(std::size_t index);
void getTuning(); void getTuning();
auto engine() -> Int&; std::int32_t& engine();
auto gears() -> Containers::ArrayView<Int>; Containers::ArrayView<std::int32_t> gears();
auto os() -> Int&; std::int32_t& os();
auto modules() -> Containers::ArrayView<Int>; Containers::ArrayView<std::int32_t> modules();
auto architecture() -> Int&; std::int32_t& architecture();
auto techs() -> Containers::ArrayView<Int>; Containers::ArrayView<std::int32_t> techs();
auto account() -> Containers::StringView; Containers::StringView account();
auto updateAccount(Containers::StringView new_account) -> bool; bool updateAccount(Containers::StringView new_account);
private: private:
void getCustomStyles(Containers::ArrayView<CustomStyle> styles, ArrayProperty* style_array); void getCustomStyles(Containers::ArrayView<CustomStyle> styles, ArrayProperty* style_array);
auto writeCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayProperty* style_array) -> bool; bool writeCustomStyle(const CustomStyle& style, std::size_t index, ArrayProperty* style_array);
void getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array); void getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array);
void writeDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array); void writeDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array);
@ -155,10 +155,11 @@ class Mass {
void writeAccessories(Containers::ArrayView<Accessory> accessories, ArrayProperty* accs_array); void writeAccessories(Containers::ArrayView<Accessory> accessories, ArrayProperty* accs_array);
void getWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array); void getWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array);
auto writeWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array) -> bool; bool writeWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array);
void getTuningCategory(Containers::StringView big_node_prop_name, Int& big_node_id, void getTuningCategory(Containers::StringView big_node_prop_name, std::int32_t& big_node_id,
Containers::StringView small_nodes_prop_name, Containers::ArrayView<Int> small_nodes_ids); Containers::StringView small_nodes_prop_name,
Containers::ArrayView<std::int32_t> small_nodes_ids);
Containers::Optional<UESaveFile> _mass; Containers::Optional<UESaveFile> _mass;
@ -174,7 +175,7 @@ class Mass {
struct { struct {
Joints joints{}; Joints joints{};
Containers::StaticArray<4, Int> styles{ValueInit}; Containers::StaticArray<4, std::int32_t> styles{ValueInit};
Color4 eyeFlare{0.0f}; Color4 eyeFlare{0.0f};
Containers::StaticArray<16, CustomStyle> customStyles; Containers::StaticArray<16, CustomStyle> customStyles;
} _frame; } _frame;
@ -198,14 +199,14 @@ class Mass {
Containers::Array<CustomStyle> _globalStyles; Containers::Array<CustomStyle> _globalStyles;
struct { struct {
Int engineId; std::int32_t engineId;
Containers::StaticArray<7, Int> gearIds; Containers::StaticArray<7, std::int32_t> gearIds;
Int osId; std::int32_t osId;
Containers::StaticArray<7, Int> moduleIds; Containers::StaticArray<7, std::int32_t> moduleIds;
Int archId; std::int32_t archId;
Containers::StaticArray<7, Int> techIds; Containers::StaticArray<7, std::int32_t> techIds;
} _tuning; } _tuning;
Containers::String _account; Containers::String _account;

View file

@ -29,11 +29,13 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto Mass::armourParts() -> Containers::ArrayView<ArmourPart> { Containers::ArrayView<ArmourPart>
Mass::armourParts() {
return _armour.parts; return _armour.parts;
} }
void Mass::getArmourParts() { void
Mass::getArmourParts() {
LOG_INFO("Getting armour parts."); LOG_INFO("Getting armour parts.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -57,7 +59,7 @@ void Mass::getArmourParts() {
return; return;
} }
for(UnsignedInt i = 0; i < armour_array->items.size(); i++) { for(std::uint32_t i = 0; i < armour_array->items.size(); i++) {
auto part_prop = armour_array->at<GenericStructProperty>(i); auto part_prop = armour_array->at<GenericStructProperty>(i);
auto& part = _armour.parts[i]; auto& part = _armour.parts[i];
@ -87,7 +89,7 @@ void Mass::getArmourParts() {
return; return;
} }
for(UnsignedInt j = 0; j < part_styles->items.size(); j++) { for(std::uint32_t j = 0; j < part_styles->items.size(); j++) {
part.styles[j] = part_styles->at<IntProperty>(j)->value; part.styles[j] = part_styles->at<IntProperty>(j)->value;
} }
@ -117,7 +119,8 @@ void Mass::getArmourParts() {
} }
} }
auto Mass::writeArmourPart(ArmourSlot slot) -> bool { bool
Mass::writeArmourPart(ArmourSlot slot) {
LOG_INFO_FORMAT("Writing armour part in slot {}.", static_cast<int>(slot)); LOG_INFO_FORMAT("Writing armour part in slot {}.", static_cast<int>(slot));
auto& part = *std::find_if(_armour.parts.begin(), _armour.parts.end(), [&slot](const ArmourPart& part){ return slot == part.slot; }); auto& part = *std::find_if(_armour.parts.begin(), _armour.parts.end(), [&slot](const ArmourPart& part){ return slot == part.slot; });
@ -149,7 +152,7 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool {
GenericStructProperty* part_prop = nullptr; GenericStructProperty* part_prop = nullptr;
for(UnsignedInt i = 0; i < armour_array->items.size(); i++) { for(std::uint32_t i = 0; i < armour_array->items.size(); i++) {
part_prop = armour_array->at<GenericStructProperty>(i); part_prop = armour_array->at<GenericStructProperty>(i);
if(slot_str == part_prop->at<ByteProperty>(MASS_ARMOUR_SLOT)->enumValue) { if(slot_str == part_prop->at<ByteProperty>(MASS_ARMOUR_SLOT)->enumValue) {
break; break;
@ -175,7 +178,7 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool {
part_prop->at<IntProperty>(MASS_ARMOUR_ID)->value = part.id; part_prop->at<IntProperty>(MASS_ARMOUR_ID)->value = part.id;
auto part_styles = part_prop->at<ArrayProperty>(MASS_ARMOUR_STYLES); auto part_styles = part_prop->at<ArrayProperty>(MASS_ARMOUR_STYLES);
for(UnsignedInt i = 0; i < part.styles.size(); i++) { for(std::uint32_t i = 0; i < part.styles.size(); i++) {
part_styles->at<IntProperty>(i)->value = part.styles[i]; part_styles->at<IntProperty>(i)->value = part.styles[i];
} }
@ -195,15 +198,18 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool {
return true; return true;
} }
auto Mass::bulletLauncherAttachmentStyle() -> BulletLauncherAttachmentStyle& { BulletLauncherAttachmentStyle&
Mass::bulletLauncherAttachmentStyle() {
return _armour.blAttachmentStyle; return _armour.blAttachmentStyle;
} }
auto Mass::bulletLauncherAttachments() -> Containers::ArrayView<BulletLauncherAttachment> { Containers::ArrayView<BulletLauncherAttachment>
Mass::bulletLauncherAttachments() {
return _armour.blAttachment; return _armour.blAttachment;
} }
void Mass::getBulletLauncherAttachments() { void
Mass::getBulletLauncherAttachments() {
LOG_INFO("Getting the bullet launcher attachment data."); LOG_INFO("Getting the bullet launcher attachment data.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -232,7 +238,7 @@ void Mass::getBulletLauncherAttachments() {
if(attach_array->items.size() == _weapons.bulletLaunchers.size() && if(attach_array->items.size() == _weapons.bulletLaunchers.size() &&
attach_array->items.size() == _armour.blAttachment.size()) attach_array->items.size() == _armour.blAttachment.size())
{ {
for(UnsignedInt i = 0; i < attach_array->items.size(); i++) { for(std::uint32_t i = 0; i < attach_array->items.size(); i++) {
auto attachment_prop = attach_array->at<GenericStructProperty>(i); auto attachment_prop = attach_array->at<GenericStructProperty>(i);
auto& attachment = _armour.blAttachment[i]; auto& attachment = _armour.blAttachment[i];
@ -274,7 +280,8 @@ void Mass::getBulletLauncherAttachments() {
} }
} }
auto Mass::writeBulletLauncherAttachments() -> bool { bool
Mass::writeBulletLauncherAttachments() {
LOG_INFO("Writing bullet launcher attachments."); LOG_INFO("Writing bullet launcher attachments.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -306,7 +313,7 @@ auto Mass::writeBulletLauncherAttachments() -> bool {
if(attach_array->items.size() == _weapons.bulletLaunchers.size() && if(attach_array->items.size() == _weapons.bulletLaunchers.size() &&
attach_array->items.size() == _armour.blAttachment.size()) attach_array->items.size() == _armour.blAttachment.size())
{ {
for(UnsignedInt i = 0; i < attach_array->items.size(); i++) { for(std::uint32_t i = 0; i < attach_array->items.size(); i++) {
auto attachment_prop = attach_array->at<GenericStructProperty>(i); auto attachment_prop = attach_array->at<GenericStructProperty>(i);
auto& attachment = _armour.blAttachment[i]; auto& attachment = _armour.blAttachment[i];
@ -373,11 +380,13 @@ auto Mass::writeBulletLauncherAttachments() -> bool {
return true; return true;
} }
auto Mass::armourCustomStyles() -> Containers::ArrayView<CustomStyle> { Containers::ArrayView<CustomStyle>
Mass::armourCustomStyles() {
return _armour.customStyles; return _armour.customStyles;
} }
void Mass::getArmourCustomStyles() { void
Mass::getArmourCustomStyles() {
LOG_INFO("Getting the custom armour styles."); LOG_INFO("Getting the custom armour styles.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -404,7 +413,8 @@ void Mass::getArmourCustomStyles() {
getCustomStyles(_armour.customStyles, armour_styles); getCustomStyles(_armour.customStyles, armour_styles);
} }
auto Mass::writeArmourCustomStyle(UnsignedLong index) -> bool { bool
Mass::writeArmourCustomStyle(std::size_t index) {
LOG_INFO_FORMAT("Writing custom armour style {}.", index); LOG_INFO_FORMAT("Writing custom armour style {}.", index);
if(index > _armour.customStyles.size()) { if(index > _armour.customStyles.size()) {

View file

@ -29,8 +29,9 @@
using namespace Containers::Literals; using namespace Containers::Literals;
void Mass::getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array) { void
for(UnsignedInt i = 0; i < decal_array->items.size(); i++) { Mass::getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array) {
for(std::uint32_t i = 0; i < decal_array->items.size(); i++) {
auto decal_prop = decal_array->at<GenericStructProperty>(i); auto decal_prop = decal_array->at<GenericStructProperty>(i);
CORRADE_INTERNAL_ASSERT(decal_prop); CORRADE_INTERNAL_ASSERT(decal_prop);
auto& decal = decals[i]; auto& decal = decals[i];
@ -53,8 +54,9 @@ void Mass::getDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_a
} }
} }
void Mass::writeDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array) { void
for(UnsignedInt i = 0; i < decal_array->items.size(); i++) { Mass::writeDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal_array) {
for(std::uint32_t i = 0; i < decal_array->items.size(); i++) {
auto decal_prop = decal_array->at<GenericStructProperty>(i); auto decal_prop = decal_array->at<GenericStructProperty>(i);
CORRADE_INTERNAL_ASSERT(decal_prop); CORRADE_INTERNAL_ASSERT(decal_prop);
auto& decal = decals[i]; auto& decal = decals[i];
@ -87,8 +89,9 @@ void Mass::writeDecals(Containers::ArrayView<Decal> decals, ArrayProperty* decal
} }
} }
void Mass::getAccessories(Containers::ArrayView<Accessory> accessories, ArrayProperty* accessory_array) { void
for(UnsignedInt i = 0; i < accessory_array->items.size(); i++) { Mass::getAccessories(Containers::ArrayView<Accessory> accessories, ArrayProperty* accessory_array) {
for(std::uint32_t i = 0; i < accessory_array->items.size(); i++) {
auto acc_prop = accessory_array->at<GenericStructProperty>(i); auto acc_prop = accessory_array->at<GenericStructProperty>(i);
CORRADE_INTERNAL_ASSERT(acc_prop); CORRADE_INTERNAL_ASSERT(acc_prop);
auto& accessory = accessories[i]; auto& accessory = accessories[i];
@ -96,7 +99,7 @@ void Mass::getAccessories(Containers::ArrayView<Accessory> accessories, ArrayPro
accessory.attachIndex = acc_prop->at<IntProperty>(MASS_ACCESSORY_ATTACH_INDEX)->value; accessory.attachIndex = acc_prop->at<IntProperty>(MASS_ACCESSORY_ATTACH_INDEX)->value;
accessory.id = acc_prop->at<IntProperty>(MASS_ACCESSORY_ID)->value; accessory.id = acc_prop->at<IntProperty>(MASS_ACCESSORY_ID)->value;
auto acc_styles = acc_prop->at<ArrayProperty>(MASS_ACCESSORY_STYLES); auto acc_styles = acc_prop->at<ArrayProperty>(MASS_ACCESSORY_STYLES);
for(UnsignedInt j = 0; j < acc_styles->items.size(); j++) { for(std::uint32_t j = 0; j < acc_styles->items.size(); j++) {
accessory.styles[j] = acc_styles->at<IntProperty>(j)->value; accessory.styles[j] = acc_styles->at<IntProperty>(j)->value;
} }
auto rel_pos_prop = acc_prop->at<VectorStructProperty>(MASS_ACCESSORY_RELPOS); auto rel_pos_prop = acc_prop->at<VectorStructProperty>(MASS_ACCESSORY_RELPOS);
@ -112,8 +115,9 @@ void Mass::getAccessories(Containers::ArrayView<Accessory> accessories, ArrayPro
} }
} }
void Mass::writeAccessories(Containers::ArrayView<Accessory> accessories, ArrayProperty* accs_array) { void
for(UnsignedInt i = 0; i < accs_array->items.size(); i++) { Mass::writeAccessories(Containers::ArrayView<Accessory> accessories, ArrayProperty* accs_array) {
for(std::uint32_t i = 0; i < accs_array->items.size(); i++) {
auto acc_prop = accs_array->at<GenericStructProperty>(i); auto acc_prop = accs_array->at<GenericStructProperty>(i);
CORRADE_INTERNAL_ASSERT(acc_prop); CORRADE_INTERNAL_ASSERT(acc_prop);
auto& accessory = accessories[i]; auto& accessory = accessories[i];
@ -121,7 +125,7 @@ void Mass::writeAccessories(Containers::ArrayView<Accessory> accessories, ArrayP
acc_prop->at<IntProperty>(MASS_ACCESSORY_ATTACH_INDEX)->value = accessory.attachIndex; acc_prop->at<IntProperty>(MASS_ACCESSORY_ATTACH_INDEX)->value = accessory.attachIndex;
acc_prop->at<IntProperty>(MASS_ACCESSORY_ID)->value = accessory.id; acc_prop->at<IntProperty>(MASS_ACCESSORY_ID)->value = accessory.id;
auto acc_styles = acc_prop->at<ArrayProperty>(MASS_ACCESSORY_STYLES); auto acc_styles = acc_prop->at<ArrayProperty>(MASS_ACCESSORY_STYLES);
for(UnsignedInt j = 0; j < acc_styles->items.size(); j++) { for(std::uint32_t j = 0; j < acc_styles->items.size(); j++) {
acc_styles->at<IntProperty>(j)->value = accessory.styles[j]; acc_styles->at<IntProperty>(j)->value = accessory.styles[j];
} }
auto rel_pos_prop = acc_prop->at<VectorStructProperty>(MASS_ACCESSORY_RELPOS); auto rel_pos_prop = acc_prop->at<VectorStructProperty>(MASS_ACCESSORY_RELPOS);

View file

@ -26,11 +26,13 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto Mass::jointSliders() -> Joints& { Joints&
Mass::jointSliders() {
return _frame.joints; return _frame.joints;
} }
void Mass::getJointSliders() { void
Mass::getJointSliders() {
LOG_INFO("Getting joint sliders."); LOG_INFO("Getting joint sliders.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -65,7 +67,8 @@ void Mass::getJointSliders() {
_frame.joints.lowerLegs = (length ? length->value : 0.0f); _frame.joints.lowerLegs = (length ? length->value : 0.0f);
} }
auto Mass::writeJointSliders() -> bool { bool
Mass::writeJointSliders() {
LOG_INFO("Writing joint sliders"); LOG_INFO("Writing joint sliders");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -181,11 +184,13 @@ auto Mass::writeJointSliders() -> bool {
return true; return true;
} }
auto Mass::frameStyles() -> Containers::ArrayView<Int> { Containers::ArrayView<std::int32_t>
Mass::frameStyles() {
return _frame.styles; return _frame.styles;
} }
void Mass::getFrameStyles() { void
Mass::getFrameStyles() {
LOG_INFO("Getting frame styles."); LOG_INFO("Getting frame styles.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -216,12 +221,13 @@ void Mass::getFrameStyles() {
return; return;
} }
for(UnsignedInt i = 0; i < frame_styles->items.size(); i++) { for(std::uint32_t i = 0; i < frame_styles->items.size(); i++) {
_frame.styles[i] = frame_styles->at<IntProperty>(i)->value; _frame.styles[i] = frame_styles->at<IntProperty>(i)->value;
} }
} }
auto Mass::writeFrameStyles() -> bool { bool
Mass::writeFrameStyles() {
LOG_INFO("Writing frame styles."); LOG_INFO("Writing frame styles.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -248,7 +254,7 @@ auto Mass::writeFrameStyles() -> bool {
return false; return false;
} }
for(UnsignedInt i = 0; i < frame_styles->items.size(); i++) { for(std::uint32_t i = 0; i < frame_styles->items.size(); i++) {
frame_styles->at<IntProperty>(i)->value = _frame.styles[i]; frame_styles->at<IntProperty>(i)->value = _frame.styles[i];
} }
@ -260,11 +266,13 @@ auto Mass::writeFrameStyles() -> bool {
return true; return true;
} }
auto Mass::eyeFlareColour() -> Color4& { Color4&
Mass::eyeFlareColour() {
return _frame.eyeFlare; return _frame.eyeFlare;
} }
void Mass::getEyeFlareColour() { void
Mass::getEyeFlareColour() {
LOG_INFO("Getting the eye flare colour."); LOG_INFO("Getting the eye flare colour.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -291,7 +299,8 @@ void Mass::getEyeFlareColour() {
_frame.eyeFlare = Color4{eye_flare_prop->r, eye_flare_prop->g, eye_flare_prop->b, eye_flare_prop->a}; _frame.eyeFlare = Color4{eye_flare_prop->r, eye_flare_prop->g, eye_flare_prop->b, eye_flare_prop->a};
} }
auto Mass::writeEyeFlareColour() -> bool { bool
Mass::writeEyeFlareColour() {
LOG_INFO("Writing the eye flare colour."); LOG_INFO("Writing the eye flare colour.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -331,11 +340,13 @@ auto Mass::writeEyeFlareColour() -> bool {
return true; return true;
} }
auto Mass::frameCustomStyles() -> Containers::ArrayView<CustomStyle> { Containers::ArrayView<CustomStyle>
Mass::frameCustomStyles() {
return _frame.customStyles; return _frame.customStyles;
} }
void Mass::getFrameCustomStyles() { void
Mass::getFrameCustomStyles() {
LOG_INFO("Getting the frame's custom styles."); LOG_INFO("Getting the frame's custom styles.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -362,7 +373,8 @@ void Mass::getFrameCustomStyles() {
getCustomStyles(_frame.customStyles, frame_styles); getCustomStyles(_frame.customStyles, frame_styles);
} }
auto Mass::writeFrameCustomStyle(UnsignedLong index) -> bool { bool
Mass::writeFrameCustomStyle(std::size_t index) {
LOG_INFO_FORMAT("Writing frame custom style number {}.", index); LOG_INFO_FORMAT("Writing frame custom style number {}.", index);
if(index > _frame.customStyles.size()) { if(index > _frame.customStyles.size()) {

View file

@ -27,11 +27,13 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto Mass::globalStyles() -> Containers::ArrayView<CustomStyle> { Containers::ArrayView<CustomStyle>
Mass::globalStyles() {
return _globalStyles; return _globalStyles;
} }
void Mass::getGlobalStyles() { void
Mass::getGlobalStyles() {
LOG_INFO("Getting global styles."); LOG_INFO("Getting global styles.");
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
@ -55,7 +57,8 @@ void Mass::getGlobalStyles() {
getCustomStyles(_globalStyles, global_styles); getCustomStyles(_globalStyles, global_styles);
} }
auto Mass::writeGlobalStyle(UnsignedLong index) -> bool { bool
Mass::writeGlobalStyle(std::size_t index) {
LOG_INFO_FORMAT("Writing global style number {}.", index); LOG_INFO_FORMAT("Writing global style number {}.", index);
if(index > _globalStyles.size()) { if(index > _globalStyles.size()) {
@ -83,8 +86,9 @@ auto Mass::writeGlobalStyle(UnsignedLong index) -> bool {
return writeCustomStyle(_globalStyles[index], index, global_styles); return writeCustomStyle(_globalStyles[index], index, global_styles);
} }
void Mass::getCustomStyles(Containers::ArrayView<CustomStyle> styles, ArrayProperty* style_array) { void
for(UnsignedInt i = 0; i < style_array->items.size(); i++) { Mass::getCustomStyles(Containers::ArrayView<CustomStyle> styles, ArrayProperty* style_array) {
for(std::uint32_t i = 0; i < style_array->items.size(); i++) {
auto style_prop = style_array->at<GenericStructProperty>(i); auto style_prop = style_array->at<GenericStructProperty>(i);
auto& style = styles[i]; auto& style = styles[i];
@ -106,7 +110,8 @@ void Mass::getCustomStyles(Containers::ArrayView<CustomStyle> styles, ArrayPrope
} }
} }
auto Mass::writeCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayProperty* style_array) -> bool { bool
Mass::writeCustomStyle(const CustomStyle& style, std::size_t index, ArrayProperty* style_array) {
if(!style_array) { if(!style_array) {
_lastError = "style_array is null."_s; _lastError = "style_array is null."_s;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);

View file

@ -28,91 +28,110 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto Mass::meleeWeapons() -> Containers::ArrayView<Weapon> { Containers::ArrayView<Weapon>
Mass::meleeWeapons() {
return _weapons.melee; return _weapons.melee;
} }
void Mass::getMeleeWeapons() { void
Mass::getMeleeWeapons() {
LOG_INFO("Getting melee weapons."); LOG_INFO("Getting melee weapons.");
getWeaponType(MASS_WEAPONS_MELEE, _weapons.melee); getWeaponType(MASS_WEAPONS_MELEE, _weapons.melee);
} }
auto Mass::writeMeleeWeapons() -> bool { bool
Mass::writeMeleeWeapons() {
LOG_INFO("Writing melee weapons."); LOG_INFO("Writing melee weapons.");
return writeWeaponType(MASS_WEAPONS_MELEE, _weapons.melee); return writeWeaponType(MASS_WEAPONS_MELEE, _weapons.melee);
} }
auto Mass::shields() -> Containers::ArrayView<Weapon> { Containers::ArrayView<Weapon>
Mass::shields() {
return _weapons.shields; return _weapons.shields;
} }
void Mass::getShields() { void
Mass::getShields() {
LOG_INFO("Getting shields."); LOG_INFO("Getting shields.");
getWeaponType(MASS_WEAPONS_SHIELD, _weapons.shields); getWeaponType(MASS_WEAPONS_SHIELD, _weapons.shields);
} }
auto Mass::writeShields() -> bool { bool
Mass::writeShields() {
LOG_INFO("Writing shields."); LOG_INFO("Writing shields.");
return writeWeaponType(MASS_WEAPONS_SHIELD, _weapons.shields); return writeWeaponType(MASS_WEAPONS_SHIELD, _weapons.shields);
} }
auto Mass::bulletShooters() -> Containers::ArrayView<Weapon> { Containers::ArrayView<Weapon>
Mass::bulletShooters() {
return _weapons.bulletShooters; return _weapons.bulletShooters;
} }
void Mass::getBulletShooters() { void
Mass::getBulletShooters() {
LOG_INFO("Getting bullet shooters."); LOG_INFO("Getting bullet shooters.");
getWeaponType(MASS_WEAPONS_BSHOOTER, _weapons.bulletShooters); getWeaponType(MASS_WEAPONS_BSHOOTER, _weapons.bulletShooters);
} }
auto Mass::writeBulletShooters() -> bool { bool
Mass::writeBulletShooters() {
LOG_INFO("Writing bullet shooters."); LOG_INFO("Writing bullet shooters.");
return writeWeaponType(MASS_WEAPONS_BSHOOTER, _weapons.bulletShooters); return writeWeaponType(MASS_WEAPONS_BSHOOTER, _weapons.bulletShooters);
} }
auto Mass::energyShooters() -> Containers::ArrayView<Weapon> { Containers::ArrayView<Weapon>
Mass::energyShooters() {
return _weapons.energyShooters; return _weapons.energyShooters;
} }
void Mass::getEnergyShooters() { void
Mass::getEnergyShooters() {
LOG_INFO("Getting energy shooters."); LOG_INFO("Getting energy shooters.");
getWeaponType(MASS_WEAPONS_ESHOOTER, _weapons.energyShooters); getWeaponType(MASS_WEAPONS_ESHOOTER, _weapons.energyShooters);
} }
auto Mass::writeEnergyShooters() -> bool { bool
Mass::writeEnergyShooters() {
LOG_INFO("Writing energy shooters."); LOG_INFO("Writing energy shooters.");
return writeWeaponType(MASS_WEAPONS_ESHOOTER, _weapons.energyShooters); return writeWeaponType(MASS_WEAPONS_ESHOOTER, _weapons.energyShooters);
} }
auto Mass::bulletLaunchers() -> Containers::ArrayView<Weapon> { Containers::ArrayView<Weapon>
Mass::bulletLaunchers() {
return _weapons.bulletLaunchers; return _weapons.bulletLaunchers;
} }
void Mass::getBulletLaunchers() { void
Mass::getBulletLaunchers() {
LOG_INFO("Getting bullet launchers."); LOG_INFO("Getting bullet launchers.");
getWeaponType(MASS_WEAPONS_BLAUNCHER, _weapons.bulletLaunchers); getWeaponType(MASS_WEAPONS_BLAUNCHER, _weapons.bulletLaunchers);
} }
auto Mass::writeBulletLaunchers() -> bool { bool
Mass::writeBulletLaunchers() {
LOG_INFO("Writing bullet launchers."); LOG_INFO("Writing bullet launchers.");
return writeWeaponType(MASS_WEAPONS_BLAUNCHER, _weapons.bulletLaunchers); return writeWeaponType(MASS_WEAPONS_BLAUNCHER, _weapons.bulletLaunchers);
} }
auto Mass::energyLaunchers() -> Containers::ArrayView<Weapon> { Containers::ArrayView<Weapon>
Mass::energyLaunchers() {
return _weapons.energyLaunchers; return _weapons.energyLaunchers;
} }
void Mass::getEnergyLaunchers() { void
Mass::getEnergyLaunchers() {
LOG_INFO("Getting energy launchers."); LOG_INFO("Getting energy launchers.");
getWeaponType(MASS_WEAPONS_ELAUNCHER, _weapons.energyLaunchers); getWeaponType(MASS_WEAPONS_ELAUNCHER, _weapons.energyLaunchers);
} }
auto Mass::writeEnergyLaunchers() -> bool { bool
Mass::writeEnergyLaunchers() {
LOG_INFO("Writing energy launchers."); LOG_INFO("Writing energy launchers.");
return writeWeaponType(MASS_WEAPONS_ELAUNCHER, _weapons.energyLaunchers); return writeWeaponType(MASS_WEAPONS_ELAUNCHER, _weapons.energyLaunchers);
} }
void Mass::getWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array) { void
Mass::getWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array) {
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
if(!unit_data) { if(!unit_data) {
LOG_ERROR_FORMAT("Couldn't find {} in {}.", MASS_UNIT_DATA, _filename); LOG_ERROR_FORMAT("Couldn't find {} in {}.", MASS_UNIT_DATA, _filename);
@ -134,7 +153,7 @@ void Mass::getWeaponType(Containers::StringView prop_name, Containers::ArrayView
return; return;
} }
for(UnsignedInt i = 0; i < weapon_array.size(); i++) { for(std::uint32_t i = 0; i < weapon_array.size(); i++) {
auto weapon_prop = prop->at<GenericStructProperty>(i); auto weapon_prop = prop->at<GenericStructProperty>(i);
auto& weapon = weapon_array[i]; auto& weapon = weapon_array[i];
@ -152,14 +171,14 @@ void Mass::getWeaponType(Containers::StringView prop_name, Containers::ArrayView
auto parts_prop = weapon_prop->at<ArrayProperty>(MASS_WEAPON_ELEMENT); auto parts_prop = weapon_prop->at<ArrayProperty>(MASS_WEAPON_ELEMENT);
weapon.parts = Containers::Array<WeaponPart>{ValueInit, parts_prop->items.size()}; weapon.parts = Containers::Array<WeaponPart>{ValueInit, parts_prop->items.size()};
for(UnsignedInt j = 0; j < parts_prop->items.size(); j++) { for(std::uint32_t j = 0; j < parts_prop->items.size(); j++) {
auto part_prop = parts_prop->at<GenericStructProperty>(j); auto part_prop = parts_prop->at<GenericStructProperty>(j);
auto& part = weapon.parts[j]; auto& part = weapon.parts[j];
part.id = part_prop->at<IntProperty>(MASS_WEAPON_PART_ID)->value; part.id = part_prop->at<IntProperty>(MASS_WEAPON_PART_ID)->value;
auto part_styles = part_prop->at<ArrayProperty>(MASS_WEAPON_PART_STYLES); auto part_styles = part_prop->at<ArrayProperty>(MASS_WEAPON_PART_STYLES);
for(UnsignedInt k = 0; k < part_styles->items.size(); k++) { for(std::uint32_t k = 0; k < part_styles->items.size(); k++) {
part.styles[k] = part_styles->at<IntProperty>(k)->value; part.styles[k] = part_styles->at<IntProperty>(k)->value;
} }
@ -223,7 +242,8 @@ void Mass::getWeaponType(Containers::StringView prop_name, Containers::ArrayView
} }
} }
auto Mass::writeWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array) -> bool { bool
Mass::writeWeaponType(Containers::StringView prop_name, Containers::ArrayView<Weapon> weapon_array) {
auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA); auto unit_data = _mass->at<GenericStructProperty>(MASS_UNIT_DATA);
if(!unit_data) { if(!unit_data) {
_lastError = "No unit data in "_s + _filename; _lastError = "No unit data in "_s + _filename;
@ -248,7 +268,7 @@ auto Mass::writeWeaponType(Containers::StringView prop_name, Containers::ArrayVi
return false; return false;
} }
for(UnsignedInt i = 0; i < weapon_array.size(); i++) { for(std::uint32_t i = 0; i < weapon_array.size(); i++) {
auto weapon_prop = prop->at<GenericStructProperty>(i); auto weapon_prop = prop->at<GenericStructProperty>(i);
auto& weapon = weapon_array[i]; auto& weapon = weapon_array[i];
@ -272,14 +292,14 @@ auto Mass::writeWeaponType(Containers::StringView prop_name, Containers::ArrayVi
return false; return false;
} }
for(UnsignedInt j = 0; j < parts_prop->items.size(); j++) { for(std::uint32_t j = 0; j < parts_prop->items.size(); j++) {
auto part_prop = parts_prop->at<GenericStructProperty>(j); auto part_prop = parts_prop->at<GenericStructProperty>(j);
auto& part = weapon.parts[j]; auto& part = weapon.parts[j];
part_prop->at<IntProperty>(MASS_WEAPON_PART_ID)->value = part.id; part_prop->at<IntProperty>(MASS_WEAPON_PART_ID)->value = part.id;
auto part_styles = part_prop->at<ArrayProperty>(MASS_WEAPON_PART_STYLES); auto part_styles = part_prop->at<ArrayProperty>(MASS_WEAPON_PART_STYLES);
for(UnsignedInt k = 0; k < part_styles->items.size(); k++) { for(std::uint32_t k = 0; k < part_styles->items.size(); k++) {
part_styles->at<IntProperty>(k)->value = part.styles[k]; part_styles->at<IntProperty>(k)->value = part.styles[k];
} }
@ -318,7 +338,7 @@ auto Mass::writeWeaponType(Containers::StringView prop_name, Containers::ArrayVi
return false; return false;
} }
for(UnsignedInt j = 0; j < weapon.customStyles.size(); j++) { for(std::uint32_t j = 0; j < weapon.customStyles.size(); j++) {
writeCustomStyle(weapon.customStyles[j], j, custom_styles); writeCustomStyle(weapon.customStyles[j], j, custom_styles);
} }

View file

@ -20,7 +20,7 @@ Weapon::Weapon(const Weapon& other) {
name = other.name; name = other.name;
type = other.type; type = other.type;
parts = Containers::Array<WeaponPart>{other.parts.size()}; parts = Containers::Array<WeaponPart>{other.parts.size()};
for(UnsignedInt i = 0; i < parts.size(); i++) { for(std::uint32_t i = 0; i < parts.size(); i++) {
parts[i] = other.parts[i]; parts[i] = other.parts[i];
} }
customStyles = other.customStyles; customStyles = other.customStyles;
@ -35,7 +35,7 @@ Weapon& Weapon::operator=(const Weapon& other) {
name = other.name; name = other.name;
type = other.type; type = other.type;
parts = Containers::Array<WeaponPart>{other.parts.size()}; parts = Containers::Array<WeaponPart>{other.parts.size()};
for(UnsignedInt i = 0; i < parts.size(); i++) { for(std::uint32_t i = 0; i < parts.size(); i++) {
parts[i] = other.parts[i]; parts[i] = other.parts[i];
} }
customStyles = other.customStyles; customStyles = other.customStyles;

View file

@ -19,13 +19,10 @@
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Magnum/Types.h>
#include "Decal.h" #include "Decal.h"
#include "Accessory.h" #include "Accessory.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
struct WeaponPart { struct WeaponPart {
WeaponPart() = default; WeaponPart() = default;
@ -34,11 +31,11 @@ struct WeaponPart {
id = other.id; id = other.id;
styles = other.styles; styles = other.styles;
decals = Containers::Array<Decal>{other.decals.size()}; decals = Containers::Array<Decal>{other.decals.size()};
for(UnsignedInt i = 0; i < decals.size(); i++) { for(auto i = 0u; i < decals.size(); i++) {
decals[i] = other.decals[i]; decals[i] = other.decals[i];
} }
accessories = Containers::Array<Accessory>{other.accessories.size()}; accessories = Containers::Array<Accessory>{other.accessories.size()};
for(UnsignedInt i = 0; i < accessories.size(); i++) { for(auto i = 0u; i < accessories.size(); i++) {
accessories[i] = other.accessories[i]; accessories[i] = other.accessories[i];
} }
} }
@ -46,11 +43,11 @@ struct WeaponPart {
id = other.id; id = other.id;
styles = other.styles; styles = other.styles;
decals = Containers::Array<Decal>{other.decals.size()}; decals = Containers::Array<Decal>{other.decals.size()};
for(UnsignedInt i = 0; i < decals.size(); i++) { for(auto i = 0u; i < decals.size(); i++) {
decals[i] = other.decals[i]; decals[i] = other.decals[i];
} }
accessories = Containers::Array<Accessory>{other.accessories.size()}; accessories = Containers::Array<Accessory>{other.accessories.size()};
for(UnsignedInt i = 0; i < accessories.size(); i++) { for(auto i = 0u; i < accessories.size(); i++) {
accessories[i] = other.accessories[i]; accessories[i] = other.accessories[i];
} }
return *this; return *this;
@ -59,8 +56,8 @@ struct WeaponPart {
WeaponPart(WeaponPart&& other) = default; WeaponPart(WeaponPart&& other) = default;
WeaponPart& operator=(WeaponPart&& other) = default; WeaponPart& operator=(WeaponPart&& other) = default;
Int id = 0; std::int32_t id = 0;
Containers::StaticArray<4, Int> styles{ValueInit}; Containers::StaticArray<4, std::int32_t> styles{ValueInit};
Containers::Array<Decal> decals{}; Containers::Array<Decal> decals{};
Containers::Array<Accessory> accessories{}; Containers::Array<Accessory> accessories{};
}; };

View file

@ -30,7 +30,7 @@ MassManager::MassManager(Containers::StringView save_path, Containers::StringVie
_saveDirectory{save_path}, _account{account}, _demo{demo}, _stagingAreaDirectory{staging_dir} _saveDirectory{save_path}, _account{account}, _demo{demo}, _stagingAreaDirectory{staging_dir}
{ {
Containers::String mass_filename = ""; Containers::String mass_filename = "";
for(UnsignedInt i = 0; i < _hangars.size(); i++) { for(std::uint32_t i = 0; i < _hangars.size(); i++) {
mass_filename = Utility::Path::join(_saveDirectory, mass_filename = Utility::Path::join(_saveDirectory,
Utility::format("{}Unit{:.2d}{}.sav", demo ? "Demo"_s : ""_s, i, _account)); Utility::format("{}Unit{:.2d}{}.sav", demo ? "Demo"_s : ""_s, i, _account));
new(&_hangars[i]) Mass{mass_filename}; new(&_hangars[i]) Mass{mass_filename};
@ -39,15 +39,18 @@ MassManager::MassManager(Containers::StringView save_path, Containers::StringVie
refreshStagedMasses(); refreshStagedMasses();
} }
auto MassManager::lastError() -> Containers::StringView { Containers::StringView
MassManager::lastError() {
return _lastError; return _lastError;
} }
auto MassManager::hangar(Int hangar) -> Mass& { Mass&
MassManager::hangar(std::int32_t hangar) {
return _hangars[hangar]; return _hangars[hangar];
} }
void MassManager::refreshHangar(Int hangar) { void
MassManager::refreshHangar(std::int32_t hangar) {
if(hangar < 0 || hangar >= 32) { if(hangar < 0 || hangar >= 32) {
_lastError = "Hangar index out of range."; _lastError = "Hangar index out of range.";
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
@ -60,7 +63,8 @@ void MassManager::refreshHangar(Int hangar) {
_hangars[hangar] = Mass{mass_filename}; _hangars[hangar] = Mass{mass_filename};
} }
auto MassManager::importMass(Containers::StringView staged_fn, Int hangar) -> bool { bool
MassManager::importMass(Containers::StringView staged_fn, std::int32_t hangar) {
if(hangar < 0 || hangar >= 32) { if(hangar < 0 || hangar >= 32) {
_lastError = "Hangar index out of range."; _lastError = "Hangar index out of range.";
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
@ -102,7 +106,8 @@ auto MassManager::importMass(Containers::StringView staged_fn, Int hangar) -> bo
return true; return true;
} }
auto MassManager::exportMass(Int hangar) -> bool { bool
MassManager::exportMass(std::int32_t hangar) {
if(hangar < 0 || hangar >= 32) { if(hangar < 0 || hangar >= 32) {
_lastError = "Hangar index out of range."_s; _lastError = "Hangar index out of range."_s;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
@ -128,7 +133,8 @@ auto MassManager::exportMass(Int hangar) -> bool {
return true; return true;
} }
auto MassManager::moveMass(Int source, Int destination) -> bool { bool
MassManager::moveMass(std::int32_t source, std::int32_t destination) {
if(source < 0 || source >= 32) { if(source < 0 || source >= 32) {
_lastError = "Source hangar index out of range."_s; _lastError = "Source hangar index out of range."_s;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
@ -165,7 +171,8 @@ auto MassManager::moveMass(Int source, Int destination) -> bool {
return true; return true;
} }
auto MassManager::deleteMass(Int hangar) -> bool { bool
MassManager::deleteMass(std::int32_t hangar) {
if(hangar < 0 || hangar >= 32) { if(hangar < 0 || hangar >= 32) {
_lastError = "Hangar index out of range."_s; _lastError = "Hangar index out of range."_s;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
@ -181,11 +188,13 @@ auto MassManager::deleteMass(Int hangar) -> bool {
return true; return true;
} }
auto MassManager::stagedMasses() -> std::map<Containers::String, Containers::String> const& { const std::map<Containers::String, Containers::String>&
MassManager::stagedMasses() {
return _stagedMasses; return _stagedMasses;
} }
void MassManager::refreshStagedMasses() { void
MassManager::refreshStagedMasses() {
_stagedMasses.clear(); _stagedMasses.clear();
using Utility::Path::ListFlag; using Utility::Path::ListFlag;
@ -217,7 +226,8 @@ void MassManager::refreshStagedMasses() {
} }
} }
void MassManager::refreshStagedMass(Containers::StringView filename) { void
MassManager::refreshStagedMass(Containers::StringView filename) {
LOG_INFO_FORMAT("Refreshing staged unit with filename {}.", filename); LOG_INFO_FORMAT("Refreshing staged unit with filename {}.", filename);
bool file_exists = Utility::Path::exists(Utility::Path::join(_stagingAreaDirectory, filename)); bool file_exists = Utility::Path::exists(Utility::Path::join(_stagingAreaDirectory, filename));
@ -237,7 +247,8 @@ void MassManager::refreshStagedMass(Containers::StringView filename) {
} }
} }
auto MassManager::deleteStagedMass(Containers::StringView filename) -> bool { bool
MassManager::deleteStagedMass(Containers::StringView filename) {
if(_stagedMasses.find(filename) == _stagedMasses.cend()) { if(_stagedMasses.find(filename) == _stagedMasses.cend()) {
_lastError = "The file "_s + filename + " couldn't be found in the list of staged M.A.S.S.es."_s; _lastError = "The file "_s + filename + " couldn't be found in the list of staged M.A.S.S.es."_s;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);

View file

@ -30,22 +30,22 @@ class MassManager {
public: public:
MassManager(Containers::StringView save_path, Containers::StringView account, bool demo, Containers::StringView staging_dir); MassManager(Containers::StringView save_path, Containers::StringView account, bool demo, Containers::StringView staging_dir);
auto lastError() -> Containers::StringView; Containers::StringView lastError();
auto hangar(int hangar) -> Mass&; Mass& hangar(int hangar);
void refreshHangar(int hangar); void refreshHangar(int hangar);
auto importMass(Containers::StringView staged_fn, int hangar) -> bool; bool importMass(Containers::StringView staged_fn, int hangar);
auto exportMass(int hangar) -> bool; bool exportMass(int hangar);
auto moveMass(int source, int destination) -> bool; bool moveMass(int source, int destination);
auto deleteMass(int hangar) -> bool; bool deleteMass(int hangar);
auto stagedMasses() -> std::map<Containers::String, Containers::String> const&; std::map<Containers::String, Containers::String> const& stagedMasses();
void refreshStagedMasses(); void refreshStagedMasses();
void refreshStagedMass(Containers::StringView filename); void refreshStagedMass(Containers::StringView filename);
auto deleteStagedMass(Containers::StringView filename) -> bool; bool deleteStagedMass(Containers::StringView filename);
private: private:
Containers::StringView _saveDirectory; Containers::StringView _saveDirectory;

View file

@ -62,31 +62,38 @@ Profile::Profile(Containers::StringView path):
refreshValues(); refreshValues();
} }
auto Profile::valid() const -> bool { bool
Profile::valid() const {
return _valid; return _valid;
} }
auto Profile::lastError() const -> Containers::StringView { Containers::StringView
Profile::lastError() const {
return _lastError; return _lastError;
} }
auto Profile::filename() const -> Containers::StringView { Containers::StringView
Profile::filename() const {
return _filename; return _filename;
} }
auto Profile::type() const -> ProfileType { ProfileType
Profile::type() const {
return _type; return _type;
} }
auto Profile::isDemo() const -> bool { bool
Profile::isDemo() const {
return _type == ProfileType::Demo; return _type == ProfileType::Demo;
} }
auto Profile::account() const -> Containers::StringView { Containers::StringView
Profile::account() const {
return _account; return _account;
} }
void Profile::refreshValues() { void
Profile::refreshValues() {
if(!_profile.reloadData()) { if(!_profile.reloadData()) {
LOG_ERROR(_profile.lastError()); LOG_ERROR(_profile.lastError());
_valid = false; _valid = false;
@ -126,42 +133,44 @@ void Profile::refreshValues() {
_lastMissionId = prop ? prop->value : 0; _lastMissionId = prop ? prop->value : 0;
LOG_INFO("Getting the materials."); LOG_INFO("Getting the materials.");
_verseSteel = getResource(PROFILE_MATERIAL, VerseSteel); _materials[VerseSteel] = getResource(PROFILE_MATERIAL, VerseSteel);
_undinium = getResource(PROFILE_MATERIAL, Undinium); _materials[Undinium] = getResource(PROFILE_MATERIAL, Undinium);
_necriumAlloy = getResource(PROFILE_MATERIAL, NecriumAlloy); _materials[NecriumAlloy] = getResource(PROFILE_MATERIAL, NecriumAlloy);
_lunarite = getResource(PROFILE_MATERIAL, Lunarite); _materials[Lunarite] = getResource(PROFILE_MATERIAL, Lunarite);
_asterite = getResource(PROFILE_MATERIAL, Asterite); _materials[Asterite] = getResource(PROFILE_MATERIAL, Asterite);
_halliteFragma = getResource(PROFILE_MATERIAL, HalliteFragma); _materials[HalliteFragma] = getResource(PROFILE_MATERIAL, HalliteFragma);
_ednil = getResource(PROFILE_MATERIAL, Ednil); _materials[Ednil] = getResource(PROFILE_MATERIAL, Ednil);
_nuflalt = getResource(PROFILE_MATERIAL, Nuflalt); _materials[Nuflalt] = getResource(PROFILE_MATERIAL, Nuflalt);
_aurelene = getResource(PROFILE_MATERIAL, Aurelene); _materials[Aurelene] = getResource(PROFILE_MATERIAL, Aurelene);
_soldus = getResource(PROFILE_MATERIAL, Soldus); _materials[Soldus] = getResource(PROFILE_MATERIAL, Soldus);
_synthesisedN = getResource(PROFILE_MATERIAL, SynthesisedN); _materials[SynthesisedN] = getResource(PROFILE_MATERIAL, SynthesisedN);
_nanoc = getResource(PROFILE_MATERIAL, Nanoc); _materials[Nanoc] = getResource(PROFILE_MATERIAL, Nanoc);
_alcarbonite = getResource(PROFILE_MATERIAL, Alcarbonite); _materials[Alcarbonite] = getResource(PROFILE_MATERIAL, Alcarbonite);
_keriphene = getResource(PROFILE_MATERIAL, Keriphene); _materials[Keriphene] = getResource(PROFILE_MATERIAL, Keriphene);
_nitinolCM = getResource(PROFILE_MATERIAL, NitinolCM); _materials[NitinolCM] = getResource(PROFILE_MATERIAL, NitinolCM);
_quarkium = getResource(PROFILE_MATERIAL, Quarkium); _materials[Quarkium] = getResource(PROFILE_MATERIAL, Quarkium);
_alterene = getResource(PROFILE_MATERIAL, Alterene); _materials[Alterene] = getResource(PROFILE_MATERIAL, Alterene);
_cosmium = getResource(PROFILE_MATERIAL, Cosmium); _materials[Cosmium] = getResource(PROFILE_MATERIAL, Cosmium);
_mixedComposition = getResource(PROFILE_QUARK_DATA, MixedComposition); _materials[MixedComposition] = getResource(PROFILE_QUARK_DATA, MixedComposition);
_voidResidue = getResource(PROFILE_QUARK_DATA, VoidResidue); _materials[VoidResidue] = getResource(PROFILE_QUARK_DATA, VoidResidue);
_muscularConstruction = getResource(PROFILE_QUARK_DATA, MuscularConstruction); _materials[MuscularConstruction] = getResource(PROFILE_QUARK_DATA, MuscularConstruction);
_mineralExoskeletology = getResource(PROFILE_QUARK_DATA, MineralExoskeletology); _materials[MineralExoskeletology] = getResource(PROFILE_QUARK_DATA, MineralExoskeletology);
_carbonisedSkin = getResource(PROFILE_QUARK_DATA, CarbonisedSkin); _materials[CarbonisedSkin] = getResource(PROFILE_QUARK_DATA, CarbonisedSkin);
_isolatedVoidParticle = getResource(PROFILE_QUARK_DATA, IsolatedVoidParticle); _materials[IsolatedVoidParticle] = getResource(PROFILE_QUARK_DATA, IsolatedVoidParticle);
_valid = true; _valid = true;
} }
auto Profile::companyName() const -> Containers::StringView { Containers::StringView
Profile::companyName() const {
return _name; return _name;
} }
auto Profile::renameCompany(Containers::StringView new_name) -> bool { bool
Profile::renameCompany(Containers::StringView new_name) {
auto name_prop = _profile.at<StringProperty>(PROFILE_NAME); auto name_prop = _profile.at<StringProperty>(PROFILE_NAME);
if(!name_prop) { if(!name_prop) {
_lastError = "No company name in "_s + _filename; _lastError = "No company name in "_s + _filename;
@ -180,21 +189,24 @@ auto Profile::renameCompany(Containers::StringView new_name) -> bool {
return true; return true;
} }
auto Profile::activeFrameSlot() const -> Int { std::int32_t
Profile::activeFrameSlot() const {
return _activeFrameSlot; return _activeFrameSlot;
} }
auto Profile::credits() const -> Int { std::int32_t
Profile::credits() const {
return _credits; return _credits;
} }
auto Profile::setCredits(Int amount) -> bool { bool
Profile::setCredits(std::int32_t amount) {
auto credits_prop = _profile.at<IntProperty>(PROFILE_CREDITS); auto credits_prop = _profile.at<IntProperty>(PROFILE_CREDITS);
if(!credits_prop) { if(!credits_prop) {
credits_prop = new IntProperty; credits_prop = new IntProperty;
credits_prop->name.emplace("Credit"_s); credits_prop->name.emplace("Credit"_s);
credits_prop->valueLength = sizeof(Int); credits_prop->valueLength = sizeof(std::int32_t);
_profile.appendProperty(IntProperty::ptr{credits_prop}); _profile.appendProperty(IntProperty::ptr{credits_prop});
} }
@ -208,17 +220,19 @@ auto Profile::setCredits(Int amount) -> bool {
return true; return true;
} }
auto Profile::storyProgress() const -> Int { std::int32_t
Profile::storyProgress() const {
return _storyProgress; return _storyProgress;
} }
auto Profile::setStoryProgress(Int progress) -> bool { bool
Profile::setStoryProgress(std::int32_t progress) {
auto story_progress_prop = _profile.at<IntProperty>("StoryProgress"_s); auto story_progress_prop = _profile.at<IntProperty>("StoryProgress"_s);
if(!story_progress_prop) { if(!story_progress_prop) {
story_progress_prop = new IntProperty; story_progress_prop = new IntProperty;
story_progress_prop->name.emplace("StoryProgress"_s); story_progress_prop->name.emplace("StoryProgress"_s);
story_progress_prop->valueLength = sizeof(Int); story_progress_prop->valueLength = sizeof(std::int32_t);
_profile.appendProperty(IntProperty::ptr{story_progress_prop}); _profile.appendProperty(IntProperty::ptr{story_progress_prop});
} }
@ -232,227 +246,19 @@ auto Profile::setStoryProgress(Int progress) -> bool {
return true; return true;
} }
auto Profile::lastMissionId() const -> Int { std::int32_t
Profile::lastMissionId() const {
return _lastMissionId; return _lastMissionId;
} }
auto Profile::verseSteel() const -> Int { std::int32_t
return _verseSteel; Profile::material(MaterialID id) const {
} return _materials.at(id);
auto Profile::setVerseSteel(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, VerseSteel, amount);
}
auto Profile::undinium() const -> Int {
return _undinium;
}
auto Profile::setUndinium(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Undinium, amount);
}
auto Profile::necriumAlloy() const -> Int {
return _necriumAlloy;
}
auto Profile::setNecriumAlloy(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, NecriumAlloy, amount);
}
auto Profile::lunarite() const -> Int {
return _lunarite;
}
auto Profile::setLunarite(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Lunarite, amount);
}
auto Profile::asterite() const -> Int {
return _asterite;
}
auto Profile::setAsterite(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Asterite, amount);
}
Int
Profile::halliteFragma() const {
return _halliteFragma;
} }
bool bool
Profile::setHalliteFragma(Int amount) { Profile::setMaterial(MaterialID id, std::int32_t amount) {
return setResource(PROFILE_MATERIAL, HalliteFragma, amount); Containers::StringView container = id > MixedComposition ? PROFILE_QUARK_DATA : PROFILE_MATERIAL;
}
auto Profile::ednil() const -> Int {
return _ednil;
}
auto Profile::setEdnil(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Ednil, amount);
}
auto Profile::nuflalt() const -> Int {
return _nuflalt;
}
auto Profile::setNuflalt(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Nuflalt, amount);
}
auto Profile::aurelene() const -> Int {
return _aurelene;
}
auto Profile::setAurelene(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Aurelene, amount);
}
auto Profile::soldus() const -> Int {
return _soldus;
}
auto Profile::setSoldus(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Soldus, amount);
}
auto Profile::synthesisedN() const -> Int {
return _synthesisedN;
}
auto Profile::setSynthesisedN(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, SynthesisedN, amount);
}
Int
Profile::nanoc() const {
return _nanoc;
}
bool
Profile::setNanoc(Int amount) {
return setResource(PROFILE_MATERIAL, Nanoc, amount);
}
auto Profile::alcarbonite() const -> Int {
return _alcarbonite;
}
auto Profile::setAlcarbonite(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Alcarbonite, amount);
}
auto Profile::keriphene() const -> Int {
return _keriphene;
}
auto Profile::setKeriphene(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Keriphene, amount);
}
auto Profile::nitinolCM() const -> Int {
return _nitinolCM;
}
auto Profile::setNitinolCM(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, NitinolCM, amount);
}
auto Profile::quarkium() const -> Int {
return _quarkium;
}
auto Profile::setQuarkium(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Quarkium, amount);
}
auto Profile::alterene() const -> Int {
return _alterene;
}
auto Profile::setAlterene(Int amount) -> bool {
return setResource(PROFILE_MATERIAL, Alterene, amount);
}
Int
Profile::cosmium() const {
return _cosmium;
}
bool
Profile::setCosmium(Int amount) {
return setResource(PROFILE_MATERIAL, Cosmium, amount);
}
auto Profile::mixedComposition() const -> Int {
return _mixedComposition;
}
auto Profile::setMixedComposition(Int amount) -> bool {
return setResource(PROFILE_QUARK_DATA, MixedComposition, amount);
}
auto Profile::voidResidue() const -> Int {
return _voidResidue;
}
auto Profile::setVoidResidue(Int amount) -> bool {
return setResource(PROFILE_QUARK_DATA, VoidResidue, amount);
}
auto Profile::muscularConstruction() const -> Int {
return _muscularConstruction;
}
auto Profile::setMuscularConstruction(Int amount) -> bool {
return setResource(PROFILE_QUARK_DATA, MuscularConstruction, amount);
}
auto Profile::mineralExoskeletology() const -> Int {
return _mineralExoskeletology;
}
auto Profile::setMineralExoskeletology(Int amount) -> bool {
return setResource(PROFILE_QUARK_DATA, MineralExoskeletology, amount);
}
auto Profile::carbonisedSkin() const -> Int {
return _carbonisedSkin;
}
auto Profile::setCarbonisedSkin(Int amount) -> bool {
return setResource(PROFILE_QUARK_DATA, CarbonisedSkin, amount);
}
Int
Profile::isolatedVoidParticle() const {
return _isolatedVoidParticle;
}
bool
Profile::setIsolatedVoidParticle(Int amount) {
return setResource(PROFILE_QUARK_DATA, IsolatedVoidParticle, amount);
}
auto Profile::getResource(Containers::StringView container, MaterialID id) -> Int {
auto mats_prop = _profile.at<ArrayProperty>(container);
if(!mats_prop) {
return 0;
}
auto predicate = [&id](UnrealPropertyBase::ptr& prop){
auto res_prop = static_cast<ResourceItemValue*>(prop.get());
return res_prop->id == id;
};
auto it = std::find_if(mats_prop->items.begin(), mats_prop->items.end(), predicate);
return it != mats_prop->items.end() ? static_cast<ResourceItemValue*>(it->get())->quantity : 0;
}
auto Profile::setResource(Containers::StringView container, MaterialID id, Int amount) -> bool {
auto mats_prop = _profile.at<ArrayProperty>(container); auto mats_prop = _profile.at<ArrayProperty>(container);
if(!mats_prop) { if(!mats_prop) {
@ -492,3 +298,20 @@ auto Profile::setResource(Containers::StringView container, MaterialID id, Int a
return true; return true;
} }
std::int32_t
Profile::getResource(Containers::StringView container, MaterialID id) {
auto mats_prop = _profile.at<ArrayProperty>(container);
if(!mats_prop) {
return 0;
}
auto predicate = [&id](UnrealPropertyBase::ptr& prop){
auto res_prop = static_cast<ResourceItemValue*>(prop.get());
return res_prop->id == id;
};
auto it = std::find_if(mats_prop->items.begin(), mats_prop->items.end(), predicate);
return it != mats_prop->items.end() ? static_cast<ResourceItemValue*>(it->get())->quantity : 0;
}

View file

@ -16,19 +16,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <map>
#include <Corrade/Containers/String.h> #include <Corrade/Containers/String.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Magnum.h>
#include "../UESaveFile/UESaveFile.h" #include "../UESaveFile/UESaveFile.h"
#include "ResourceIDs.h" #include "ResourceIDs.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
enum class ProfileType : UnsignedByte { enum class ProfileType: std::uint8_t {
Demo, Demo,
FullGame FullGame
}; };
@ -37,107 +36,37 @@ class Profile {
public: public:
explicit Profile(Containers::StringView path); explicit Profile(Containers::StringView path);
auto valid() const -> bool; bool valid() const;
auto lastError() const -> Containers::StringView; auto lastError() const -> Containers::StringView;
auto filename() const -> Containers::StringView; auto filename() const -> Containers::StringView;
auto type() const -> ProfileType; ProfileType type() const;
auto isDemo() const -> bool; bool isDemo() const;
auto account() const -> Containers::StringView; auto account() const -> Containers::StringView;
void refreshValues(); void refreshValues();
auto companyName() const -> Containers::StringView; auto companyName() const -> Containers::StringView;
auto renameCompany(Containers::StringView new_name) -> bool; bool renameCompany(Containers::StringView new_name);
auto activeFrameSlot() const -> Int; std::int32_t activeFrameSlot() const;
auto credits() const -> Int; std::int32_t credits() const;
auto setCredits(Int credits) -> bool; bool setCredits(std::int32_t credits);
auto storyProgress() const -> Int; std::int32_t storyProgress() const;
auto setStoryProgress(Int progress) -> bool; bool setStoryProgress(std::int32_t progress);
auto lastMissionId() const -> Int; std::int32_t lastMissionId() const;
auto verseSteel() const -> Int; std::int32_t material(MaterialID id) const;
auto setVerseSteel(Int amount) -> bool; bool setMaterial(MaterialID id, std::int32_t amount);
auto undinium() const -> Int;
auto setUndinium(Int amount) -> bool;
auto necriumAlloy() const -> Int;
auto setNecriumAlloy(Int amount) -> bool;
auto lunarite() const -> Int;
auto setLunarite(Int amount) -> bool;
auto asterite() const -> Int;
auto setAsterite(Int amount) -> bool;
Int halliteFragma() const;
bool setHalliteFragma(Int amount);
auto ednil() const -> Int;
auto setEdnil(Int amount) -> bool;
auto nuflalt() const -> Int;
auto setNuflalt(Int amount) -> bool;
auto aurelene() const -> Int;
auto setAurelene(Int amount) -> bool;
auto soldus() const -> Int;
auto setSoldus(Int amount) -> bool;
auto synthesisedN() const -> Int;
auto setSynthesisedN(Int amount) -> bool;
Int nanoc() const;
bool setNanoc(Int amount);
auto alcarbonite() const -> Int;
auto setAlcarbonite(Int amount) -> bool;
auto keriphene() const -> Int;
auto setKeriphene(Int amount) -> bool;
auto nitinolCM() const -> Int;
auto setNitinolCM(Int amount) -> bool;
auto quarkium() const -> Int;
auto setQuarkium(Int amount) -> bool;
auto alterene() const -> Int;
auto setAlterene(Int amount) -> bool;
Int cosmium() const;
bool setCosmium(Int amount);
auto mixedComposition() const -> Int;
auto setMixedComposition(Int amount) -> bool;
auto voidResidue() const -> Int;
auto setVoidResidue(Int amount) -> bool;
auto muscularConstruction() const -> Int;
auto setMuscularConstruction(Int amount) -> bool;
auto mineralExoskeletology() const -> Int;
auto setMineralExoskeletology(Int amount) -> bool;
auto carbonisedSkin() const -> Int;
auto setCarbonisedSkin(Int amount) -> bool;
Int isolatedVoidParticle() const;
bool setIsolatedVoidParticle(Int amount);
private: private:
auto getResource(Containers::StringView container, MaterialID id) -> Int; std::int32_t getResource(Containers::StringView container, MaterialID id);
auto setResource(Containers::StringView container, MaterialID id, Int amount) -> bool;
Containers::String _filename; Containers::String _filename;
@ -146,38 +75,12 @@ class Profile {
UESaveFile _profile; UESaveFile _profile;
Containers::String _name; Containers::String _name;
Int _activeFrameSlot = 0; std::int32_t _activeFrameSlot = 0;
Int _credits = 0; std::int32_t _credits = 0;
Int _storyProgress = 0; std::int32_t _storyProgress = 0;
Int _lastMissionId = 0; std::int32_t _lastMissionId = 0;
Int _verseSteel = 0; std::map<MaterialID, std::int32_t> _materials;
Int _undinium = 0;
Int _necriumAlloy = 0;
Int _lunarite = 0;
Int _asterite = 0;
Int _halliteFragma = 0;
Int _ednil = 0;
Int _nuflalt = 0;
Int _aurelene = 0;
Int _soldus = 0;
Int _synthesisedN = 0;
Int _nanoc = 0;
Int _alcarbonite = 0;
Int _keriphene = 0;
Int _nitinolCM = 0;
Int _quarkium = 0;
Int _alterene = 0;
Int _cosmium = 0;
Int _mixedComposition = 0;
Int _voidResidue = 0;
Int _muscularConstruction = 0;
Int _mineralExoskeletology = 0;
Int _carbonisedSkin = 0;
Int _isolatedVoidParticle = 0;
Containers::String _account; Containers::String _account;

View file

@ -16,11 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <Magnum/Types.h> enum MaterialID : std::int32_t {
using namespace Magnum;
enum MaterialID : Int {
VerseSteel = 0xC3500, VerseSteel = 0xC3500,
Undinium = 0xC3501, Undinium = 0xC3501,
NecriumAlloy = 0xC3502, NecriumAlloy = 0xC3502,

View file

@ -40,19 +40,23 @@ ProfileManager::ProfileManager(Containers::StringView save_dir, Containers::Stri
_ready = refreshProfiles(); _ready = refreshProfiles();
} }
auto ProfileManager::ready() const -> bool { bool
ProfileManager::ready() const {
return _ready; return _ready;
} }
auto ProfileManager::lastError() -> Containers::StringView { Containers::StringView
ProfileManager::lastError() {
return _lastError; return _lastError;
} }
auto ProfileManager::profiles() -> Containers::ArrayView<Profile> { Containers::ArrayView<Profile>
ProfileManager::profiles() {
return _profiles; return _profiles;
} }
auto ProfileManager::refreshProfiles() -> bool { bool
ProfileManager::refreshProfiles() {
LOG_INFO("Refreshing profiles."); LOG_INFO("Refreshing profiles.");
_profiles = Containers::Array<Profile>{}; _profiles = Containers::Array<Profile>{};
@ -93,11 +97,13 @@ auto ProfileManager::refreshProfiles() -> bool {
return true; return true;
} }
auto ProfileManager::getProfile(std::size_t index) -> Profile* { Profile*
ProfileManager::getProfile(std::size_t index) {
return index <= _profiles.size() ? &(_profiles[index]) : nullptr; return index <= _profiles.size() ? &(_profiles[index]) : nullptr;
} }
auto ProfileManager::deleteProfile(std::size_t index, bool delete_builds) -> bool { bool
ProfileManager::deleteProfile(std::size_t index, bool delete_builds) {
if(!Utility::Path::remove(Utility::Path::join(_saveDirectory, _profiles[index].filename()))) { if(!Utility::Path::remove(Utility::Path::join(_saveDirectory, _profiles[index].filename()))) {
_lastError = Utility::format("Couldn't delete {} (filename: {}).", _lastError = Utility::format("Couldn't delete {} (filename: {}).",
_profiles[index].companyName(), _profiles[index].companyName(),
@ -108,7 +114,7 @@ auto ProfileManager::deleteProfile(std::size_t index, bool delete_builds) -> boo
} }
if(delete_builds) { if(delete_builds) {
for(UnsignedByte i = 0; i < 32; ++i) { for(std::uint8_t i = 0; i < 32; ++i) {
auto filename = Utility::format("{}Unit{:.2d}{}.sav", auto filename = Utility::format("{}Unit{:.2d}{}.sav",
_profiles[index].type() == ProfileType::Demo ? "Demo": "", _profiles[index].type() == ProfileType::Demo ? "Demo": "",
i, _profiles[index].account()); i, _profiles[index].account());
@ -126,7 +132,8 @@ auto ProfileManager::deleteProfile(std::size_t index, bool delete_builds) -> boo
return true; return true;
} }
auto ProfileManager::backupProfile(std::size_t index, bool backup_builds) -> bool { bool
ProfileManager::backupProfile(std::size_t index, bool backup_builds) {
std::time_t timestamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::time_t timestamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::tm* time = std::localtime(&timestamp); std::tm* time = std::localtime(&timestamp);
auto& profile = _profiles[index]; auto& profile = _profiles[index];
@ -169,7 +176,7 @@ auto ProfileManager::backupProfile(std::size_t index, bool backup_builds) -> boo
zip_set_archive_comment(zip, comment.data(), comment.size()); zip_set_archive_comment(zip, comment.data(), comment.size());
if(backup_builds) { if(backup_builds) {
for(UnsignedByte i = 0; i < 32; ++i) { for(std::uint8_t i = 0; i < 32; ++i) {
auto build_filename = Utility::format("{}Unit{:.2d}{}.sav", auto build_filename = Utility::format("{}Unit{:.2d}{}.sav",
profile.isDemo() ? "Demo"_s : ""_s, i, profile.isDemo() ? "Demo"_s : ""_s, i,
profile.account()); profile.account());
@ -202,11 +209,13 @@ auto ProfileManager::backupProfile(std::size_t index, bool backup_builds) -> boo
return true; return true;
} }
auto ProfileManager::backups() -> Containers::ArrayView<Backup> { Containers::ArrayView<Backup>
ProfileManager::backups() {
return _backups; return _backups;
} }
void ProfileManager::refreshBackups() { void
ProfileManager::refreshBackups() {
_backups = Containers::Array<Backup>{}; _backups = Containers::Array<Backup>{};
using Utility::Path::ListFlag; using Utility::Path::ListFlag;
@ -238,7 +247,7 @@ void ProfileManager::refreshBackups() {
Containers::ScopeGuard guard{zip, zip_close}; Containers::ScopeGuard guard{zip, zip_close};
Long num_entries = zip_get_num_entries(zip, ZIP_FL_UNCHANGED); auto num_entries = zip_get_num_entries(zip, ZIP_FL_UNCHANGED);
if(num_entries == 0) { if(num_entries == 0) {
continue; continue;
@ -282,7 +291,7 @@ void ProfileManager::refreshBackups() {
arrayReserve(backup.includedFiles, num_entries); arrayReserve(backup.includedFiles, num_entries);
for(Long i = 0; i < num_entries; i++) { for(auto i = 0; i < num_entries; i++) {
arrayAppend(backup.includedFiles, InPlaceInit, zip_get_name(zip, i, ZIP_FL_UNCHANGED)); arrayAppend(backup.includedFiles, InPlaceInit, zip_get_name(zip, i, ZIP_FL_UNCHANGED));
} }
@ -290,7 +299,8 @@ void ProfileManager::refreshBackups() {
} }
} }
auto ProfileManager::deleteBackup(std::size_t index) -> bool { bool
ProfileManager::deleteBackup(std::size_t index) {
if(!Utility::Path::remove(Utility::Path::join(_backupsDirectory, _backups[index].filename))) { if(!Utility::Path::remove(Utility::Path::join(_backupsDirectory, _backups[index].filename))) {
_lastError = "Couldn't delete " + _backups[index].filename; _lastError = "Couldn't delete " + _backups[index].filename;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
@ -307,7 +317,8 @@ auto ProfileManager::deleteBackup(std::size_t index) -> bool {
return true; return true;
} }
auto ProfileManager::restoreBackup(std::size_t index) -> bool { bool
ProfileManager::restoreBackup(std::size_t index) {
const Backup& backup = _backups[index]; const Backup& backup = _backups[index];
auto error_format = "Extraction of file {} failed: {}"_s; auto error_format = "Extraction of file {} failed: {}"_s;
@ -347,7 +358,7 @@ auto ProfileManager::restoreBackup(std::size_t index) -> bool {
Containers::StaticArray<8192, char> buf{ValueInit}; Containers::StaticArray<8192, char> buf{ValueInit};
Long bytes_read = 0; auto bytes_read = 0l;
while((bytes_read = zip_fread(zf, buf.data(), buf.size())) > 0) { while((bytes_read = zip_fread(zf, buf.data(), buf.size())) > 0) {
if(std::fwrite(buf.data(), sizeof(char), bytes_read, out) < static_cast<std::size_t>(bytes_read)) { if(std::fwrite(buf.data(), sizeof(char), bytes_read, out) < static_cast<std::size_t>(bytes_read)) {
_lastError = Utility::format(error_format.data(), file, "not enough bytes written."); _lastError = Utility::format(error_format.data(), file, "not enough bytes written.");

View file

@ -16,6 +16,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <string> #include <string>
#include <Corrade/Containers/Array.h> #include <Corrade/Containers/Array.h>
@ -30,12 +32,12 @@ struct Backup {
Containers::String company; Containers::String company;
ProfileType type; ProfileType type;
struct { struct {
int year; std::int32_t year;
int month; std::int32_t month;
int day; std::int32_t day;
int hour; std::int32_t hour;
int minute; std::int32_t minute;
int second; std::int32_t second;
} timestamp; } timestamp;
Containers::Array<Containers::String> includedFiles; Containers::Array<Containers::String> includedFiles;
}; };
@ -45,20 +47,20 @@ class ProfileManager {
explicit ProfileManager(Containers::StringView save_dir, Containers::StringView backup_dir); explicit ProfileManager(Containers::StringView save_dir, Containers::StringView backup_dir);
auto ready() const -> bool; auto ready() const -> bool;
auto lastError() -> Containers::StringView; Containers::StringView lastError();
auto profiles() -> Containers::ArrayView<Profile>; Containers::ArrayView<Profile> profiles();
auto refreshProfiles() -> bool; bool refreshProfiles();
auto getProfile(std::size_t index) -> Profile*; Profile* getProfile(std::size_t index);
auto deleteProfile(std::size_t index, bool delete_builds) -> bool; bool deleteProfile(std::size_t index, bool delete_builds);
auto backupProfile(std::size_t index, bool backup_builds) -> bool; bool backupProfile(std::size_t index, bool backup_builds);
auto backups() -> Containers::ArrayView<Backup>; Containers::ArrayView<Backup> backups();
void refreshBackups(); void refreshBackups();
auto deleteBackup(std::size_t index) -> bool; bool deleteBackup(std::size_t index);
auto restoreBackup(std::size_t index) -> bool; bool restoreBackup(std::size_t index);
private: private:
bool _ready = false; bool _ready = false;

View file

@ -35,6 +35,7 @@
#include <wtsapi32.h> #include <wtsapi32.h>
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../Configuration/Configuration.h"
#include "../Logger/Logger.h" #include "../Logger/Logger.h"
using namespace Containers::Literals; using namespace Containers::Literals;
@ -57,8 +58,6 @@ SaveTool::SaveTool(const Arguments& arguments):
LOG_INFO("Configuring OpenGL renderer."); LOG_INFO("Configuring OpenGL renderer.");
GL::Renderer::enable(GL::Renderer::Feature::Blending); GL::Renderer::enable(GL::Renderer::Feature::Blending);
GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); GL::Renderer::enable(GL::Renderer::Feature::ScissorTest);
GL::Renderer::disable(GL::Renderer::Feature::FaceCulling);
GL::Renderer::disable(GL::Renderer::Feature::DepthTest);
GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha, GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha,
GL::Renderer::BlendFunction::OneMinusSourceAlpha); GL::Renderer::BlendFunction::OneMinusSourceAlpha);
GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add, GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add,
@ -78,7 +77,7 @@ SaveTool::SaveTool(const Arguments& arguments):
#endif #endif
LOG_INFO("Registering custom events."); LOG_INFO("Registering custom events.");
if((_initEventId = SDL_RegisterEvents(3)) == UnsignedInt(-1)) { if((_initEventId = SDL_RegisterEvents(3)) == std::uint32_t(-1)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error",
"SDL_RegisterEvents() failed in SaveTool::SaveTool(). Exiting...", window()); "SDL_RegisterEvents() failed in SaveTool::SaveTool(). Exiting...", window());
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -115,7 +114,7 @@ SaveTool::SaveTool(const Arguments& arguments):
checkGameState(); checkGameState();
_gameCheckTimerId = SDL_AddTimer(2000, _gameCheckTimerId = SDL_AddTimer(2000,
[](UnsignedInt interval, void* param)->UnsignedInt{ [](std::uint32_t interval, void* param)->std::uint32_t{
static_cast<SaveTool*>(param)->checkGameState(); static_cast<SaveTool*>(param)->checkGameState();
return interval; return interval;
}, this); }, this);
@ -130,7 +129,7 @@ SaveTool::SaveTool(const Arguments& arguments):
LOG_INFO("Initialising update checker."); LOG_INFO("Initialising update checker.");
curl_global_init(CURL_GLOBAL_DEFAULT); curl_global_init(CURL_GLOBAL_DEFAULT);
if(_checkUpdatesOnStartup) { if(conf().checkUpdatesOnStartup()) {
_queue.addToast(Toast::Type::Default, "Checking for updates..."_s); _queue.addToast(Toast::Type::Default, "Checking for updates..."_s);
_updateThread = std::thread{[this]{ checkForUpdates(); }}; _updateThread = std::thread{[this]{ checkForUpdates(); }};
} }
@ -141,7 +140,7 @@ SaveTool::SaveTool(const Arguments& arguments):
GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, false); GL::DebugOutput::setEnabled(GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, false);
} }
if(_skipDisclaimer) { if(conf().skipDisclaimer()) {
_uiState = UiState::Initialising; _uiState = UiState::Initialising;
_initThread = std::thread{[this]{ initialiseManager(); }}; _initThread = std::thread{[this]{ initialiseManager(); }};
} }
@ -159,19 +158,13 @@ SaveTool::~SaveTool() {
LOG_INFO("Saving the configuration."); LOG_INFO("Saving the configuration.");
_conf.setValue("cheat_mode"_s, _cheatMode); conf().save();
_conf.setValue("advanced_mode"_s, _advancedMode);
_conf.setValue("startup_update_check"_s, _checkUpdatesOnStartup);
_conf.setValue("skip_disclaimer"_s, _skipDisclaimer);
_conf.setValue("swap_interval"_s, _swapInterval);
_conf.setValue("fps_cap"_s, _fpsCap);
_conf.save();
LOG_INFO("Exiting."); LOG_INFO("Exiting.");
} }
void SaveTool::drawEvent() { void
SaveTool::drawEvent() {
#ifdef SAVETOOL_DEBUG_BUILD #ifdef SAVETOOL_DEBUG_BUILD
tweak.update(); tweak.update();
#endif #endif
@ -182,8 +175,8 @@ void SaveTool::drawEvent() {
swapBuffers(); swapBuffers();
if(_swapInterval == 0 && _fpsCap < 301.0f) { if(conf().swapInterval() == 0 && conf().fpsCap() < 301.0f) {
while(_timeline.currentFrameDuration() < (1.0f / _fpsCap)); while(_timeline.currentFrameDuration() < (1.0f / conf().fpsCap()));
} }
redraw(); redraw();
@ -191,45 +184,54 @@ void SaveTool::drawEvent() {
_timeline.nextFrame(); _timeline.nextFrame();
} }
void SaveTool::viewportEvent(ViewportEvent& event) { void
SaveTool::viewportEvent(ViewportEvent& event) {
GL::defaultFramebuffer.setViewport({{}, event.framebufferSize()}); GL::defaultFramebuffer.setViewport({{}, event.framebufferSize()});
const Vector2 size = Vector2{windowSize()}/dpiScaling(); const Vector2 size = Vector2{windowSize()}/dpiScaling();
_imgui.relayout(size, windowSize(), framebufferSize()); _imgui.relayout(size, windowSize(), framebufferSize());
} }
void SaveTool::keyPressEvent(KeyEvent& event) { void
SaveTool::keyPressEvent(KeyEvent& event) {
if(_imgui.handleKeyPressEvent(event)) return; if(_imgui.handleKeyPressEvent(event)) return;
} }
void SaveTool::keyReleaseEvent(KeyEvent& event) { void
SaveTool::keyReleaseEvent(KeyEvent& event) {
if(_imgui.handleKeyReleaseEvent(event)) return; if(_imgui.handleKeyReleaseEvent(event)) return;
} }
void SaveTool::mousePressEvent(MouseEvent& event) { void
SaveTool::mousePressEvent(MouseEvent& event) {
if(_imgui.handleMousePressEvent(event)) return; if(_imgui.handleMousePressEvent(event)) return;
} }
void SaveTool::mouseReleaseEvent(MouseEvent& event) { void
SaveTool::mouseReleaseEvent(MouseEvent& event) {
if(_imgui.handleMouseReleaseEvent(event)) return; if(_imgui.handleMouseReleaseEvent(event)) return;
} }
void SaveTool::mouseMoveEvent(MouseMoveEvent& event) { void
SaveTool::mouseMoveEvent(MouseMoveEvent& event) {
if(_imgui.handleMouseMoveEvent(event)) return; if(_imgui.handleMouseMoveEvent(event)) return;
} }
void SaveTool::mouseScrollEvent(MouseScrollEvent& event) { void
SaveTool::mouseScrollEvent(MouseScrollEvent& event) {
if(_imgui.handleMouseScrollEvent(event)) { if(_imgui.handleMouseScrollEvent(event)) {
event.setAccepted(); event.setAccepted();
return; return;
} }
} }
void SaveTool::textInputEvent(TextInputEvent& event) { void
SaveTool::textInputEvent(TextInputEvent& event) {
if(_imgui.handleTextInputEvent(event)) return; if(_imgui.handleTextInputEvent(event)) return;
} }
void SaveTool::anyEvent(SDL_Event& event) { void
SaveTool::anyEvent(SDL_Event& event) {
if(event.type == _initEventId) { if(event.type == _initEventId) {
initEvent(event); initEvent(event);
} }
@ -241,7 +243,8 @@ void SaveTool::anyEvent(SDL_Event& event) {
} }
} }
void SaveTool::drawImGui() { void
SaveTool::drawImGui() {
_imgui.newFrame(); _imgui.newFrame();
if(ImGui::GetIO().WantTextInput && !isTextInputActive()) { if(ImGui::GetIO().WantTextInput && !isTextInputActive()) {
@ -258,7 +261,8 @@ void SaveTool::drawImGui() {
_imgui.drawFrame(); _imgui.drawFrame();
} }
void SaveTool::drawGui() { void
SaveTool::drawGui() {
drawMainMenu(); drawMainMenu();
switch(_uiState) { switch(_uiState) {
@ -300,7 +304,8 @@ void SaveTool::drawGui() {
_queue.draw(windowSize()); _queue.draw(windowSize());
} }
void SaveTool::drawDisclaimer() { void
SaveTool::drawDisclaimer() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot); ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
if(ImGui::Begin("Disclaimer##DisclaimerWindow", nullptr, if(ImGui::Begin("Disclaimer##DisclaimerWindow", nullptr,
@ -344,7 +349,9 @@ void SaveTool::drawDisclaimer() {
ImGui::Dummy({0.0f, 5.0f}); ImGui::Dummy({0.0f, 5.0f});
ImGui::Dummy({4.0f, 0.0f}); ImGui::Dummy({4.0f, 0.0f});
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox("Don't show next time", &_skipDisclaimer); if(drawCheckbox("Don't show next time", conf().skipDisclaimer())) {
conf().setSkipDisclaimer(!conf().skipDisclaimer());
}
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {24.0f, 12.0f}); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {24.0f, 12.0f});
if(ImGui::Button("I understand the risks")) { if(ImGui::Button("I understand the risks")) {
@ -359,7 +366,8 @@ void SaveTool::drawDisclaimer() {
ImGui::End(); ImGui::End();
} }
void SaveTool::drawInitialisation() { void
SaveTool::drawInitialisation() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot); ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
if(ImGui::BeginPopupModal("##InitPopup", nullptr, if(ImGui::BeginPopupModal("##InitPopup", nullptr,
@ -372,7 +380,8 @@ void SaveTool::drawInitialisation() {
ImGui::OpenPopup("##InitPopup"); ImGui::OpenPopup("##InitPopup");
} }
void SaveTool::drawGameState() { void
SaveTool::drawGameState() {
ImGui::TextUnformatted("Game state:"); ImGui::TextUnformatted("Game state:");
ImGui::SameLine(); ImGui::SameLine();
{ {
@ -393,12 +402,14 @@ void SaveTool::drawGameState() {
} }
} }
void SaveTool::drawHelpMarker(Containers::StringView text, Float wrap_pos) { void
SaveTool::drawHelpMarker(Containers::StringView text, float wrap_pos) {
ImGui::TextUnformatted(ICON_FA_QUESTION_CIRCLE); ImGui::TextUnformatted(ICON_FA_QUESTION_CIRCLE);
drawTooltip(text, wrap_pos); drawTooltip(text, wrap_pos);
} }
void SaveTool::drawTooltip(Containers::StringView text, Float wrap_pos) { void
SaveTool::drawTooltip(Containers::StringView text, float wrap_pos) {
if(ImGui::IsItemHovered()){ if(ImGui::IsItemHovered()){
ImGui::BeginTooltip(); ImGui::BeginTooltip();
if(wrap_pos > 0.0f) { if(wrap_pos > 0.0f) {
@ -412,11 +423,18 @@ void SaveTool::drawTooltip(Containers::StringView text, Float wrap_pos) {
} }
} }
void SaveTool::openUri(Containers::StringView uri) { bool
SaveTool::drawCheckbox(Containers::StringView label, bool value) {
return ImGui::Checkbox(label.data(), &value);
}
void
SaveTool::openUri(Containers::StringView uri) {
ShellExecuteW(nullptr, nullptr, Utility::Unicode::widen(uri.data()), nullptr, nullptr, SW_SHOWDEFAULT); ShellExecuteW(nullptr, nullptr, Utility::Unicode::widen(uri.data()), nullptr, nullptr, SW_SHOWDEFAULT);
} }
void SaveTool::checkGameState() { void
SaveTool::checkGameState() {
WTS_PROCESS_INFOW* process_infos = nullptr; WTS_PROCESS_INFOW* process_infos = nullptr;
unsigned long process_count = 0; unsigned long process_count = 0;

View file

@ -21,7 +21,6 @@
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/String.h> #include <Corrade/Containers/String.h>
#include <Corrade/Utility/Configuration.h>
#include <Corrade/Utility/Resource.h> #include <Corrade/Utility/Resource.h>
#ifdef SAVETOOL_DEBUG_BUILD #ifdef SAVETOOL_DEBUG_BUILD
#include <Corrade/Utility/Tweakable.h> #include <Corrade/Utility/Tweakable.h>
@ -78,20 +77,20 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void anyEvent(SDL_Event& event) override; void anyEvent(SDL_Event& event) override;
enum InitStatus: Int { enum InitStatus: std::int32_t {
InitSuccess, InitSuccess,
ProfileManagerFailure ProfileManagerFailure
}; };
void initEvent(SDL_Event& event); void initEvent(SDL_Event& event);
enum UpdateCheckStatus : Int { enum UpdateCheckStatus : std::int32_t {
CurlInitFailed = 0, CurlInitFailed = 0,
CurlError = 1, CurlError = 1,
CurlTimeout = 2, CurlTimeout = 2,
}; };
void updateCheckEvent(SDL_Event& event); void updateCheckEvent(SDL_Event& event);
enum FileEventType: Int { enum FileEventType: std::int32_t {
FileAdded = efsw::Action::Add, FileAdded = efsw::Action::Add,
FileDeleted = efsw::Action::Delete, FileDeleted = efsw::Action::Delete,
FileModified = efsw::Action::Modified, FileModified = efsw::Action::Modified,
@ -104,8 +103,8 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void initialiseConfiguration(); void initialiseConfiguration();
void initialiseGui(); void initialiseGui();
void initialiseManager(); void initialiseManager();
auto initialiseToolDirectories() -> bool; bool initialiseToolDirectories();
auto findGameDataDirectory() -> bool; bool findGameDataDirectory();
void initialiseMassManager(); void initialiseMassManager();
void initialiseFileWatcher(); void initialiseFileWatcher();
@ -117,21 +116,20 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void drawInitialisation(); void drawInitialisation();
void drawProfileManager(); void drawProfileManager();
auto drawBackupListPopup() -> ImGuiID; ImGuiID drawBackupListPopup();
auto drawBackupProfilePopup(std::size_t profile_index) -> ImGuiID; ImGuiID drawBackupProfilePopup(std::size_t profile_index);
auto drawDeleteProfilePopup(std::size_t profile_index) -> ImGuiID; ImGuiID drawDeleteProfilePopup(std::size_t profile_index);
void drawManager(); void drawManager();
auto drawIntEditPopup(int* value_to_edit, int max) -> bool; bool drawIntEditPopup(int* value_to_edit, int max);
auto drawRenamePopup(Containers::ArrayView<char> name_view) -> bool; bool drawRenamePopup(Containers::ArrayView<char> name_view);
void drawGeneralInfo(); void drawGeneralInfo();
void drawResearchInventory(); void drawResearchInventory();
template<typename Getter, typename Setter> void drawMaterialRow(Containers::StringView name, std::int32_t tier, MaterialID id);
void drawMaterialRow(Containers::StringView name, Int tier, Getter getter, Setter setter); void drawUnavailableMaterialRow(Containers::StringView name, std::int32_t tier);
void drawUnavailableMaterialRow(Containers::StringView name, Int tier);
void drawMassManager(); void drawMassManager();
auto drawDeleteMassPopup(int mass_index) -> ImGuiID; ImGuiID drawDeleteMassPopup(int mass_index);
auto drawDeleteStagedMassPopup(Containers::StringView filename) -> ImGuiID; ImGuiID drawDeleteStagedMassPopup(Containers::StringView filename);
void drawMassViewer(); void drawMassViewer();
void drawFrameInfo(); void drawFrameInfo();
@ -149,24 +147,25 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void drawTuning(); void drawTuning();
void drawDecalEditor(Decal& decal); void drawDecalEditor(Decal& decal);
void drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<CustomStyle> style_view); void drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<CustomStyle> style_view);
auto getStyleName(Int id, Containers::ArrayView<CustomStyle> view) -> Containers::StringView; Containers::StringView getStyleName(std::int32_t id, Containers::ArrayView<CustomStyle> view);
enum DCSResult { enum DCSResult {
DCS_Fail, DCS_Fail,
DCS_ResetStyle, DCS_ResetStyle,
DCS_Save DCS_Save
}; };
auto drawCustomStyle(CustomStyle& style) -> DCSResult; DCSResult drawCustomStyle(CustomStyle& style);
void drawAbout(); void drawAbout();
void drawGameState(); void drawGameState();
// Convenience wrappers over ImGui stuff // Convenience wrappers over ImGui stuff
void drawHelpMarker(Containers::StringView text, Float wrap_pos = 0.0f); void drawHelpMarker(Containers::StringView text, float wrap_pos = 0.0f);
void drawTooltip(Containers::StringView text, Float wrap_pos = 0.0f); void drawTooltip(Containers::StringView text, float wrap_pos = 0.0f);
bool drawCheckbox(Containers::StringView label, bool value);
template<typename Functor, typename... Args> template<typename Functor, typename... Args>
auto drawUnsafeWidget(Functor func, Args... args) -> bool { bool drawUnsafeWidget(Functor func, Args... args) {
GameState game_state = _gameState; // Copying the value to reduce the risk of a data race. GameState game_state = _gameState; // Copying the value to reduce the risk of a data race.
ImGui::BeginDisabled(game_state != GameState::NotRunning); ImGui::BeginDisabled(game_state != GameState::NotRunning);
bool result = func(std::forward<Args>(args)...); bool result = func(std::forward<Args>(args)...);
@ -197,7 +196,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
void checkForUpdates(); void checkForUpdates();
Utility::Configuration _conf{"MassBuilderSaveTool.ini"_s};
Utility::Resource _rs{"assets"_s}; Utility::Resource _rs{"assets"_s};
// GUI-related members // GUI-related members
@ -223,9 +221,9 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
std::thread _initThread; std::thread _initThread;
std::thread _updateThread; std::thread _updateThread;
UnsignedInt _initEventId; std::uint32_t _initEventId;
UnsignedInt _updateEventId; std::uint32_t _updateEventId;
UnsignedInt _fileEventId; std::uint32_t _fileEventId;
Containers::String _lastError; Containers::String _lastError;
@ -241,7 +239,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
//Containers::String _weaponsDir; //Containers::String _weaponsDir;
//Containers::String _stylesDir; //Containers::String _stylesDir;
enum class GameState : UnsignedByte { enum class GameState : std::uint8_t {
Unknown, NotRunning, Running Unknown, NotRunning, Running
} _gameState{GameState::Unknown}; } _gameState{GameState::Unknown};
@ -262,12 +260,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
}; };
Containers::StaticArray<2, efsw::WatchID> _watchIDs; Containers::StaticArray<2, efsw::WatchID> _watchIDs;
int _swapInterval = 1;
float _fpsCap = 60.0f;
bool _skipDisclaimer{false};
bool _checkUpdatesOnStartup{true};
bool _updateAvailable{false}; bool _updateAvailable{false};
Containers::String _latestVersion; Containers::String _latestVersion;
Containers::String _releaseLink; Containers::String _releaseLink;
@ -277,12 +269,12 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
bool _jointsDirty{false}; bool _jointsDirty{false};
bool _stylesDirty{false}; bool _stylesDirty{false};
bool _eyeFlareDirty{false}; bool _eyeFlareDirty{false};
Containers::StaticArray<38, Int> _selectedArmourDecals{ValueInit}; Containers::StaticArray<38, std::int32_t> _selectedArmourDecals{ValueInit};
Containers::StaticArray<38, Int> _selectedArmourAccessories{ValueInit}; Containers::StaticArray<38, std::int32_t> _selectedArmourAccessories{ValueInit};
Int _selectedBLPlacement{0}; std::int32_t _selectedBLPlacement{0};
Int _selectedWeaponPart{0}; std::int32_t _selectedWeaponPart{0};
Int _selectedWeaponDecal{0}; std::int32_t _selectedWeaponDecal{0};
Int _selectedWeaponAccessory{0}; std::int32_t _selectedWeaponAccessory{0};
bool _meleeDirty{false}; bool _meleeDirty{false};
bool _shieldsDirty{false}; bool _shieldsDirty{false};
bool _bShootersDirty{false}; bool _bShootersDirty{false};
@ -290,8 +282,5 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
bool _bLaunchersDirty{false}; bool _bLaunchersDirty{false};
bool _eLaunchersDirty{false}; bool _eLaunchersDirty{false};
bool _cheatMode{false};
bool _advancedMode{false};
Timeline _timeline; Timeline _timeline;
}; };

View file

@ -26,7 +26,8 @@
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::handleFileAction(efsw::WatchID watch_id, void
SaveTool::handleFileAction(efsw::WatchID watch_id,
const std::string&, const std::string&,
const std::string& filename, const std::string& filename,
efsw::Action action, efsw::Action action,
@ -60,7 +61,8 @@ void SaveTool::handleFileAction(efsw::WatchID watch_id,
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
void SaveTool::fileUpdateEvent(SDL_Event& event) { void
SaveTool::fileUpdateEvent(SDL_Event& event) {
Containers::String filename{static_cast<char*>(event.user.data1), Containers::String filename{static_cast<char*>(event.user.data1),
std::strlen(static_cast<char*>(event.user.data1)), nullptr}; std::strlen(static_cast<char*>(event.user.data1)), nullptr};
@ -71,8 +73,8 @@ void SaveTool::fileUpdateEvent(SDL_Event& event) {
Containers::String old_filename; Containers::String old_filename;
Int index = 0; std::int32_t index = 0;
Int old_index = 0; std::int32_t old_index = 0;
bool is_current_profile = filename == _currentProfile->filename(); bool is_current_profile = filename == _currentProfile->filename();
bool is_unit = filename.hasPrefix(_currentProfile->isDemo() ? "DemoUnit"_s : "Unit"_s); bool is_unit = filename.hasPrefix(_currentProfile->isDemo() ? "DemoUnit"_s : "Unit"_s);
if(is_unit) { if(is_unit) {

View file

@ -24,13 +24,15 @@
#include <shlobj.h> #include <shlobj.h>
#include "../Configuration/Configuration.h"
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../FontAwesome/IconsFontAwesome5Brands.h" #include "../FontAwesome/IconsFontAwesome5Brands.h"
#include "../Logger/Logger.h" #include "../Logger/Logger.h"
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::initEvent(SDL_Event& event) { void
SaveTool::initEvent(SDL_Event& event) {
_initThread.join(); _initThread.join();
switch(event.user.code) { switch(event.user.code) {
@ -48,68 +50,16 @@ void SaveTool::initEvent(SDL_Event& event) {
} }
} }
void SaveTool::initialiseConfiguration() { void
SaveTool::initialiseConfiguration() {
LOG_INFO("Reading configuration file."); LOG_INFO("Reading configuration file.");
if(_conf.hasValue("cheat_mode"_s)) { setSwapInterval(conf().swapInterval());
_cheatMode = _conf.value<bool>("cheat_mode"_s);
}
else {
_conf.setValue("cheat_mode"_s, _cheatMode);
}
if(_conf.hasValue("advanced_mode"_s)) {
_advancedMode = _conf.value<bool>("advanced_mode"_s);
}
else {
_conf.setValue("advanced_mode"_s, _advancedMode);
}
if(_conf.hasValue("startup_update_check"_s)) {
_checkUpdatesOnStartup = _conf.value<bool>("startup_update_check"_s);
}
else {
_conf.setValue("startup_update_check"_s, _checkUpdatesOnStartup);
}
if(_conf.hasValue("skip_disclaimer"_s)) {
_skipDisclaimer = _conf.value<bool>("skip_disclaimer"_s);
}
else {
_conf.setValue("skip_disclaimer"_s, _skipDisclaimer);
}
if(_conf.hasValue("swap_interval"_s)) {
_swapInterval = _conf.value<int>("swap_interval"_s);
}
else {
_conf.setValue("swap_interval"_s, 1);
}
if(_conf.hasValue("fps_cap"_s)) {
_fpsCap = _conf.value<float>("fps_cap");
}
else {
_conf.setValue("fps_cap", 60.0f);
}
if(_conf.hasValue("frame_limit"_s)) {
std::string frame_limit = _conf.value("frame_limit"_s);
if(frame_limit == "half_vsync"_s) {
_swapInterval = 2;
}
_conf.removeValue("frame_limit"_s);
}
setSwapInterval(_swapInterval);
if(_swapInterval == 0) {
setMinimalLoopPeriod(0); setMinimalLoopPeriod(0);
} }
_conf.save(); void
} SaveTool::initialiseGui() {
void SaveTool::initialiseGui() {
LOG_INFO("Initialising Dear ImGui."); LOG_INFO("Initialising Dear ImGui.");
ImGui::CreateContext(); ImGui::CreateContext();
@ -123,7 +73,7 @@ void SaveTool::initialiseGui() {
font_config.FontDataOwnedByAtlas = false; font_config.FontDataOwnedByAtlas = false;
std::strcpy(font_config.Name, "Source Sans Pro"); std::strcpy(font_config.Name, "Source Sans Pro");
io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(reg_font.data()), int(reg_font.size()), io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(reg_font.data()), int(reg_font.size()),
20.0f * Float(framebufferSize().x()) / size.x(), &font_config); 20.0f * float(framebufferSize().x()) / size.x(), &font_config);
auto icon_font = _rs.getRaw(FONT_ICON_FILE_NAME_FAS); auto icon_font = _rs.getRaw(FONT_ICON_FILE_NAME_FAS);
static const ImWchar icon_range[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; static const ImWchar icon_range[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
@ -134,12 +84,12 @@ void SaveTool::initialiseGui() {
icon_config.OversampleH = icon_config.OversampleV = 1; icon_config.OversampleH = icon_config.OversampleV = 1;
icon_config.GlyphMinAdvanceX = 18.0f; icon_config.GlyphMinAdvanceX = 18.0f;
io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(icon_font.data()), int(icon_font.size()), io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(icon_font.data()), int(icon_font.size()),
16.0f * Float(framebufferSize().x()) / size.x(), &icon_config, icon_range); 16.0f * float(framebufferSize().x()) / size.x(), &icon_config, icon_range);
auto brand_font = _rs.getRaw(FONT_ICON_FILE_NAME_FAB); auto brand_font = _rs.getRaw(FONT_ICON_FILE_NAME_FAB);
static const ImWchar brand_range[] = { ICON_MIN_FAB, ICON_MAX_FAB, 0 }; static const ImWchar brand_range[] = { ICON_MIN_FAB, ICON_MAX_FAB, 0 };
io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(brand_font.data()), int(brand_font.size()), io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(brand_font.data()), int(brand_font.size()),
16.0f * Float(framebufferSize().x()) / size.x(), &icon_config, brand_range); 16.0f * float(framebufferSize().x()) / size.x(), &icon_config, brand_range);
auto mono_font = _rs.getRaw("SourceCodePro-Regular.ttf"_s); auto mono_font = _rs.getRaw("SourceCodePro-Regular.ttf"_s);
ImVector<ImWchar> range; ImVector<ImWchar> range;
@ -148,7 +98,7 @@ void SaveTool::initialiseGui() {
builder.AddChar(u'š'); // This allows displaying Vladimír Vondruš' name in Corrade's and Magnum's licences. builder.AddChar(u'š'); // This allows displaying Vladimír Vondruš' name in Corrade's and Magnum's licences.
builder.BuildRanges(&range); builder.BuildRanges(&range);
io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(mono_font.data()), int(mono_font.size()), io.Fonts->AddFontFromMemoryTTF(const_cast<char*>(mono_font.data()), int(mono_font.size()),
18.0f * Float(framebufferSize().x()) / size.x(), &font_config, range.Data); 18.0f * float(framebufferSize().x()) / size.x(), &font_config, range.Data);
_imgui = ImGuiIntegration::Context(*ImGui::GetCurrentContext(), windowSize()); _imgui = ImGuiIntegration::Context(*ImGui::GetCurrentContext(), windowSize());
@ -161,7 +111,8 @@ void SaveTool::initialiseGui() {
style.Colors[ImGuiCol_WindowBg] = ImColor(0xff1f1f1f); style.Colors[ImGuiCol_WindowBg] = ImColor(0xff1f1f1f);
} }
void SaveTool::initialiseManager() { void
SaveTool::initialiseManager() {
LOG_INFO("Initialising the profile manager."); LOG_INFO("Initialising the profile manager.");
SDL_Event event; SDL_Event event;
@ -179,7 +130,8 @@ void SaveTool::initialiseManager() {
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
auto SaveTool::initialiseToolDirectories() -> bool { auto
SaveTool::initialiseToolDirectories() -> bool {
LOG_INFO("Initialising Save Tool directories."); LOG_INFO("Initialising Save Tool directories.");
_backupsDir = Utility::Path::join(Utility::Path::split(*Utility::Path::executableLocation()).first(), "backups"); _backupsDir = Utility::Path::join(Utility::Path::split(*Utility::Path::executableLocation()).first(), "backups");
@ -240,7 +192,8 @@ auto SaveTool::initialiseToolDirectories() -> bool {
return true; return true;
} }
auto SaveTool::findGameDataDirectory() -> bool { auto
SaveTool::findGameDataDirectory() -> bool {
LOG_INFO("Searching for the game's save directory."); LOG_INFO("Searching for the game's save directory.");
wchar_t* localappdata_path = nullptr; wchar_t* localappdata_path = nullptr;
@ -266,12 +219,14 @@ auto SaveTool::findGameDataDirectory() -> bool {
return true; return true;
} }
void SaveTool::initialiseMassManager() { void
SaveTool::initialiseMassManager() {
LOG_INFO("Initialising the M.A.S.S. manager."); LOG_INFO("Initialising the M.A.S.S. manager.");
_massManager.emplace(_saveDir, _currentProfile->account(), _currentProfile->isDemo(), _stagingDir); _massManager.emplace(_saveDir, _currentProfile->account(), _currentProfile->isDemo(), _stagingDir);
} }
void SaveTool::initialiseFileWatcher() { void
SaveTool::initialiseFileWatcher() {
LOG_INFO("Initialising the file watcher."); LOG_INFO("Initialising the file watcher.");
_fileWatcher.emplace(); _fileWatcher.emplace();
_watchIDs[SaveDir] = _fileWatcher->addWatch(_saveDir, this, false); _watchIDs[SaveDir] = _fileWatcher->addWatch(_saveDir, this, false);

View file

@ -21,15 +21,17 @@
#include <SDL_messagebox.h> #include <SDL_messagebox.h>
#include "../Configuration/Configuration.h"
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../Maps/LastMissionId.h" #include "../Maps/LastMissionId.h"
#include "../Maps/StoryProgress.h" #include "../Maps/StoryProgress.h"
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::drawManager() { void
SaveTool::drawManager() {
ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always); ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always);
ImGui::SetNextWindowSize({Float(windowSize().x()), Float(windowSize().y()) - ImGui::GetItemRectSize().y}, ImGui::SetNextWindowSize({float(windowSize().x()), float(windowSize().y()) - ImGui::GetItemRectSize().y},
ImGuiCond_Always); ImGuiCond_Always);
if(!ImGui::Begin("##MainWindow", nullptr, if(!ImGui::Begin("##MainWindow", nullptr,
ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoMove| ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoMove|
@ -94,7 +96,8 @@ void SaveTool::drawManager() {
ImGui::End(); ImGui::End();
} }
auto SaveTool::drawIntEditPopup(int* value_to_edit, int max) -> bool { bool
SaveTool::drawIntEditPopup(int* value_to_edit, int max) {
bool apply = false; bool apply = false;
if(ImGui::BeginPopup("int_edit")) { if(ImGui::BeginPopup("int_edit")) {
ImGui::Text("Please enter a value between 0 and %i:", max); ImGui::Text("Please enter a value between 0 and %i:", max);
@ -103,7 +106,7 @@ auto SaveTool::drawIntEditPopup(int* value_to_edit, int max) -> bool {
drawHelpMarker("You can either drag the widget left or right to change the value,\n" drawHelpMarker("You can either drag the widget left or right to change the value,\n"
"or click on it while holding Ctrl to edit the value directly."); "or click on it while holding Ctrl to edit the value directly.");
ImGui::SameLine(); ImGui::SameLine();
drawUnsafeWidget([](auto... args){ return ImGui::SliderInt("", args...); }, drawUnsafeWidget([](auto... args){ return ImGui::SliderInt("##IntSlider", args...); },
value_to_edit, 0, max, "%d", ImGuiSliderFlags_AlwaysClamp); value_to_edit, 0, max, "%d", ImGuiSliderFlags_AlwaysClamp);
ImGui::SameLine(); ImGui::SameLine();
if(drawUnsafeWidget([]{ return ImGui::Button("Apply"); })) { if(drawUnsafeWidget([]{ return ImGui::Button("Apply"); })) {
@ -117,7 +120,8 @@ auto SaveTool::drawIntEditPopup(int* value_to_edit, int max) -> bool {
return apply; return apply;
} }
auto SaveTool::drawRenamePopup(Containers::ArrayView<char> name_view) -> bool { bool
SaveTool::drawRenamePopup(Containers::ArrayView<char> name_view) {
bool apply = false; bool apply = false;
if(ImGui::BeginPopup("name_edit")) { if(ImGui::BeginPopup("name_edit")) {
ImGui::TextUnformatted("Please enter a new name. Conditions:"); ImGui::TextUnformatted("Please enter a new name. Conditions:");
@ -133,13 +137,15 @@ auto SaveTool::drawRenamePopup(Containers::ArrayView<char> name_view) -> bool {
(name_view[0] != ' ' && name_view[len - 1] != ' ') ? ICON_FA_CHECK : ICON_FA_TIMES); (name_view[0] != ' ' && name_view[len - 1] != ' ') ? ICON_FA_CHECK : ICON_FA_TIMES);
static auto callback = [](ImGuiInputTextCallbackData* data)->int { static auto callback = [](ImGuiInputTextCallbackData* data)->int {
if(data->EventChar < 256 && std::strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789- ", char(data->EventChar))) { if(data->EventChar < 256 &&
std::strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789- ", char(data->EventChar)))
{
return 0; return 0;
} }
return 1; return 1;
}; };
drawUnsafeWidget([](auto... args){ return ImGui::InputText("", args...); }, drawUnsafeWidget([](auto... args){ return ImGui::InputText("##NameField", args...); },
name_view.data(), name_view.size(), name_view.data(), name_view.size(),
ImGuiInputTextFlags_CallbackCharFilter, ImGuiInputTextFlags_CallbackCharFilter,
callback, nullptr); callback, nullptr);
@ -169,7 +175,8 @@ auto SaveTool::drawRenamePopup(Containers::ArrayView<char> name_view) -> bool {
return apply; return apply;
} }
void SaveTool::drawGeneralInfo() { void
SaveTool::drawGeneralInfo() {
if(!_currentProfile) { if(!_currentProfile) {
return; return;
} }
@ -205,7 +212,7 @@ void SaveTool::drawGeneralInfo() {
drawTooltip("This is the last mission selected in the mission selection screen, not the last mission played.", drawTooltip("This is the last mission selected in the mission selection screen, not the last mission played.",
float(windowSize().x()) * 0.35f); float(windowSize().x()) * 0.35f);
const Float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::Dummy({ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y - footer_height_to_reserve}); ImGui::Dummy({ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y - footer_height_to_reserve});
ImGui::Separator(); ImGui::Separator();
@ -224,13 +231,13 @@ void SaveTool::drawGeneralInfo() {
} }
} }
if(!_cheatMode) { if(!conf().cheatMode()) {
return; return;
} }
ImGui::SameLine(); ImGui::SameLine();
static Int credits; static std::int32_t credits;
if(drawUnsafeWidget([]{ return ImGui::Button("Edit credits"); })) { if(drawUnsafeWidget([]{ return ImGui::Button("Edit credits"); })) {
credits = _currentProfile->credits(); credits = _currentProfile->credits();
ImGui::OpenPopup("int_edit"); ImGui::OpenPopup("int_edit");
@ -277,7 +284,8 @@ void SaveTool::drawGeneralInfo() {
} }
} }
void SaveTool::drawResearchInventory() { void
SaveTool::drawResearchInventory() {
if(!_currentProfile) { if(!_currentProfile) {
return; return;
} }
@ -292,150 +300,96 @@ void SaveTool::drawResearchInventory() {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::Text("Engine materials"); ImGui::TextUnformatted("Engine materials");
drawMaterialRow("Verse steel", 1, drawMaterialRow("Verse steel", 1, VerseSteel);
[this]{ return _currentProfile->verseSteel(); }, drawMaterialRow("Undinium", 2, Undinium);
[this](Int amount){ return _currentProfile->setVerseSteel(amount); }); drawMaterialRow("Necrium alloy", 3, NecriumAlloy);
drawMaterialRow("Undinium", 2, drawMaterialRow("Lunarite", 4, Lunarite);
[this]{ return _currentProfile->undinium(); }, drawMaterialRow("Asterite", 5, Asterite);
[this](Int amount){ return _currentProfile->setUndinium(amount); }); drawMaterialRow("Hallite fragma", 6, HalliteFragma);
drawMaterialRow("Necrium alloy", 3,
[this]{ return _currentProfile->necriumAlloy(); },
[this](Int amount){ return _currentProfile->setNecriumAlloy(amount); });
drawMaterialRow("Lunarite", 4,
[this]{ return _currentProfile->lunarite(); },
[this](Int amount){ return _currentProfile->setLunarite(amount); });
drawMaterialRow("Asterite", 5,
[this]{ return _currentProfile->asterite(); },
[this](Int amount){ return _currentProfile->setAsterite(amount); });
drawMaterialRow("Hallite fragma", 6,
[this]{ return _currentProfile->halliteFragma(); },
[this](Int amount){ return _currentProfile->setHalliteFragma(amount); });
drawUnavailableMaterialRow("Unnoctinium", 7); drawUnavailableMaterialRow("Unnoctinium", 7);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::Text("OS materials"); ImGui::TextUnformatted("OS materials");
drawMaterialRow("Ednil", 1, drawMaterialRow("Ednil", 1, Ednil);
[this]{ return _currentProfile->ednil(); }, drawMaterialRow("Nuflalt", 2, Nuflalt);
[this](Int amount){ return _currentProfile->setEdnil(amount); }); drawMaterialRow("Aurelene", 3, Aurelene);
drawMaterialRow("Nuflalt", 2, drawMaterialRow("Soldus", 4, Soldus);
[this]{ return _currentProfile->nuflalt(); }, drawMaterialRow("Synthesized N", 5, SynthesisedN);
[this](Int amount){ return _currentProfile->setNuflalt(amount); }); drawMaterialRow("Nanoc", 6, Nanoc);
drawMaterialRow("Aurelene", 3,
[this]{ return _currentProfile->aurelene(); },
[this](Int amount){ return _currentProfile->setAurelene(amount); });
drawMaterialRow("Soldus", 4,
[this]{ return _currentProfile->soldus(); },
[this](Int amount){ return _currentProfile->setSoldus(amount); });
drawMaterialRow("Synthesized N", 5,
[this]{ return _currentProfile->synthesisedN(); },
[this](Int amount){ return _currentProfile->setSynthesisedN(amount); });
drawMaterialRow("Nanoc", 6,
[this]{ return _currentProfile->nanoc(); },
[this](Int amount){ return _currentProfile->setNanoc(amount); });
drawUnavailableMaterialRow("Abyssillite", 7); drawUnavailableMaterialRow("Abyssillite", 7);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::Text("Architect materials"); ImGui::TextUnformatted("Architect materials");
drawMaterialRow("Alcarbonite", 1, drawMaterialRow("Alcarbonite", 1, Alcarbonite);
[this]{ return _currentProfile->alcarbonite(); }, drawMaterialRow("Keriphene", 2, Keriphene);
[this](Int amount){ return _currentProfile->setAlcarbonite(amount); }); drawMaterialRow("Nitinol-CM", 3, NitinolCM);
drawMaterialRow("Keripehene", 2, drawMaterialRow("Quarkium", 4, Quarkium);
[this]{ return _currentProfile->keriphene(); }, drawMaterialRow("Alterene", 5, Alterene);
[this](Int amount){ return _currentProfile->setKeriphene(amount); }); drawMaterialRow("Cosmium", 6, Cosmium);
drawMaterialRow("Nitinol-CM", 3,
[this]{ return _currentProfile->nitinolCM(); },
[this](Int amount){ return _currentProfile->setNitinolCM(amount); });
drawMaterialRow("Quarkium", 4,
[this]{ return _currentProfile->quarkium(); },
[this](Int amount){ return _currentProfile->setQuarkium(amount); });
drawMaterialRow("Alterene", 5,
[this]{ return _currentProfile->alterene(); },
[this](Int amount){ return _currentProfile->setAlterene(amount); });
drawMaterialRow("Cosmium", 6,
[this]{ return _currentProfile->cosmium(); },
[this](Int amount){ return _currentProfile->setCosmium(amount); });
drawUnavailableMaterialRow("Purified quarkium", 7); drawUnavailableMaterialRow("Purified quarkium", 7);
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::Text("Quark data"); ImGui::TextUnformatted("Quark data");
drawMaterialRow("Mixed composition", 1, drawMaterialRow("Mixed composition", 1, MixedComposition);
[this]{ return _currentProfile->mixedComposition(); }, drawMaterialRow("Void residue", 2, VoidResidue);
[this](Int amount){ return _currentProfile->setMixedComposition(amount); }); drawMaterialRow("Muscular construction", 3, MuscularConstruction);
drawMaterialRow("Void residue", 2, drawMaterialRow("Mineral exoskeletology", 4, MineralExoskeletology);
[this]{ return _currentProfile->voidResidue(); }, drawMaterialRow("Carbonized skin", 5, CarbonisedSkin);
[this](Int amount){ return _currentProfile->setVoidResidue(amount); }); drawMaterialRow("Isolated void particle", 6, IsolatedVoidParticle);
drawMaterialRow("Muscular construction", 3,
[this]{ return _currentProfile->muscularConstruction(); },
[this](Int amount){ return _currentProfile->setMuscularConstruction(amount); });
drawMaterialRow("Mineral exoskeletology", 4,
[this]{ return _currentProfile->mineralExoskeletology(); },
[this](Int amount){ return _currentProfile->setMineralExoskeletology(amount); });
drawMaterialRow("Carbonized skin", 5,
[this]{ return _currentProfile->carbonisedSkin(); },
[this](Int amount){ return _currentProfile->setCarbonisedSkin(amount); });
drawMaterialRow("Isolated void particle", 6,
[this]{ return _currentProfile->isolatedVoidParticle(); },
[this](Int amount){ return _currentProfile->setIsolatedVoidParticle(amount); });
drawUnavailableMaterialRow("Weaponised physiology", 7); drawUnavailableMaterialRow("Weaponised physiology", 7);
ImGui::EndTable(); ImGui::EndTable();
} }
} }
template<typename Getter, typename Setter> void
void SaveTool::drawMaterialRow(Containers::StringView name, Int tier, Getter getter, Setter setter) { SaveTool::drawMaterialRow(Containers::StringView name, std::int32_t tier, MaterialID id) {
static_assert(std::is_same<decltype(getter()), Int>::value, "getter doesn't return an Int, and/or doesn't take zero arguments.");
static_assert(std::is_same<decltype(setter(0)), bool>::value, "setter doesn't return a bool, and/or doesn't take a single Int as an argument.");
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
ImGui::Text("T%i", tier); ImGui::Text("T%i", tier);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::TextUnformatted(name.data()); ImGui::TextUnformatted(name.data());
ImGui::TableSetColumnIndex(2); ImGui::TableSetColumnIndex(2);
if(getter() != -1) { ImGui::Text("%i", _currentProfile->material(id));
ImGui::Text("%i", getter()); if(conf().cheatMode()) {
if(_cheatMode) {
ImGui::TableSetColumnIndex(3); ImGui::TableSetColumnIndex(3);
ImGui::PushID(name.data()); ImGui::PushID(name.data());
static Int var = 0; static std::int32_t var = 0;
if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_EDIT)) { if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_EDIT)) {
(var) = getter(); var = _currentProfile->material(id);
ImGui::OpenPopup("int_edit"); ImGui::OpenPopup("int_edit");
} }
drawTooltip("Edit"); drawTooltip("Edit");
if(drawIntEditPopup(&(var), 9999)) { if(drawIntEditPopup(&var, 9999)) {
if(!setter(var)) { if(!_currentProfile->setMaterial(id, var)) {
_queue.addToast(Toast::Type::Error, _currentProfile->lastError()); _queue.addToast(Toast::Type::Error, _currentProfile->lastError());
} }
} }
ImGui::PopID(); ImGui::PopID();
} }
} }
else {
ImGui::TextDisabled("Not found in the save file");
}
}
void SaveTool::drawUnavailableMaterialRow(Containers::StringView name, Int tier) { void
SaveTool::drawUnavailableMaterialRow(Containers::StringView name, std::int32_t tier) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
ImGui::Text("T%i", tier); ImGui::Text("T%i", tier);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
ImGui::TextUnformatted(name.data()); ImGui::TextUnformatted(name.begin(), name.end());
ImGui::TableSetColumnIndex(2); ImGui::TableSetColumnIndex(2);
ImGui::TextDisabled("Unavailable as of game version " SUPPORTED_GAME_VERSION); ImGui::TextDisabled("Unavailable as of game version " SUPPORTED_GAME_VERSION);
} }
void SaveTool::drawMassManager() { void
SaveTool::drawMassManager() {
if(!_massManager) { if(!_massManager) {
return; return;
} }
@ -632,7 +586,8 @@ void SaveTool::drawMassManager() {
drawDeleteStagedMassPopup(staged_mass_to_delete); drawDeleteStagedMassPopup(staged_mass_to_delete);
} }
auto SaveTool::drawDeleteMassPopup(int mass_index) -> ImGuiID { ImGuiID
SaveTool::drawDeleteMassPopup(int mass_index) {
if(!ImGui::BeginPopupModal("Confirmation##DeleteMassConfirmation", nullptr, if(!ImGui::BeginPopupModal("Confirmation##DeleteMassConfirmation", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{ {
@ -688,7 +643,8 @@ auto SaveTool::drawDeleteMassPopup(int mass_index) -> ImGuiID {
return 0; return 0;
} }
auto SaveTool::drawDeleteStagedMassPopup(Containers::StringView filename) -> ImGuiID { ImGuiID
SaveTool::drawDeleteStagedMassPopup(Containers::StringView filename) {
if(!ImGui::BeginPopupModal("Confirmation##DeleteStagedMassConfirmation", nullptr, if(!ImGui::BeginPopupModal("Confirmation##DeleteStagedMassConfirmation", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{ {

View file

@ -19,6 +19,7 @@
#include <Magnum/ImGuiIntegration/Integration.h> #include <Magnum/ImGuiIntegration/Integration.h>
#include "../Configuration/Configuration.h"
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../Maps/Accessories.h" #include "../Maps/Accessories.h"
#define STYLENAMES_DEFINITION #define STYLENAMES_DEFINITION
@ -26,7 +27,8 @@
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::drawMassViewer() { void
SaveTool::drawMassViewer() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
_currentMass = nullptr; _currentMass = nullptr;
_currentWeapon = nullptr; _currentWeapon = nullptr;
@ -36,7 +38,7 @@ void SaveTool::drawMassViewer() {
} }
ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always); ImGui::SetNextWindowPos({0.0f, ImGui::GetItemRectSize().y}, ImGuiCond_Always);
ImGui::SetNextWindowSize({Float(windowSize().x()), Float(windowSize().y()) - ImGui::GetItemRectSize().y}, ImGui::SetNextWindowSize({float(windowSize().x()), float(windowSize().y()) - ImGui::GetItemRectSize().y},
ImGuiCond_Always); ImGuiCond_Always);
if(!ImGui::Begin("##MassViewer", nullptr, if(!ImGui::Begin("##MassViewer", nullptr,
ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoMove| ImGuiWindowFlags_NoDecoration|ImGuiWindowFlags_NoMove|
@ -84,8 +86,8 @@ void SaveTool::drawMassViewer() {
_jointsDirty = false; _jointsDirty = false;
_stylesDirty = false; _stylesDirty = false;
_eyeFlareDirty = false; _eyeFlareDirty = false;
_selectedArmourDecals = Containers::StaticArray<38, Int>{ValueInit}; _selectedArmourDecals = Containers::StaticArray<38, std::int32_t>{ValueInit};
_selectedArmourAccessories = Containers::StaticArray<38, Int>{ValueInit}; _selectedArmourAccessories = Containers::StaticArray<38, std::int32_t>{ValueInit};
_selectedBLPlacement = 0; _selectedBLPlacement = 0;
_selectedWeaponPart = 0; _selectedWeaponPart = 0;
_selectedWeaponDecal = 0; _selectedWeaponDecal = 0;
@ -153,7 +155,8 @@ void SaveTool::drawMassViewer() {
ImGui::End(); ImGui::End();
} }
void SaveTool::drawGlobalStyles() { void
SaveTool::drawGlobalStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -165,7 +168,7 @@ void SaveTool::drawGlobalStyles() {
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game."); ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
for(UnsignedInt i = 0; i < _currentMass->globalStyles().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->globalStyles().size(); i++) {
ImGui::PushID(int(i)); ImGui::PushID(int(i));
DCSResult result; DCSResult result;
result = drawCustomStyle(_currentMass->globalStyles()[i]); result = drawCustomStyle(_currentMass->globalStyles()[i]);
@ -189,7 +192,8 @@ void SaveTool::drawGlobalStyles() {
ImGui::EndChild(); ImGui::EndChild();
} }
void SaveTool::drawTuning() { void
SaveTool::drawTuning() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -221,7 +225,7 @@ void SaveTool::drawTuning() {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted("Gears"); ImGui::TextUnformatted("Gears");
for(UnsignedInt i = 0; i < _currentMass->gears().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->gears().size(); i++) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%i", _currentMass->gears()[i]); ImGui::Text("%i", _currentMass->gears()[i]);
@ -247,7 +251,7 @@ void SaveTool::drawTuning() {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted("Modules"); ImGui::TextUnformatted("Modules");
for(UnsignedInt i = 0; i < _currentMass->modules().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->modules().size(); i++) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%i", _currentMass->modules()[i]); ImGui::Text("%i", _currentMass->modules()[i]);
@ -273,7 +277,7 @@ void SaveTool::drawTuning() {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted("Techs"); ImGui::TextUnformatted("Techs");
for(UnsignedInt i = 0; i < _currentMass->techs().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->techs().size(); i++) {
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("%i", _currentMass->techs()[i]); ImGui::Text("%i", _currentMass->techs()[i]);
@ -285,7 +289,8 @@ void SaveTool::drawTuning() {
ImGui::EndTable(); ImGui::EndTable();
} }
auto SaveTool::drawCustomStyle(CustomStyle& style) -> DCSResult { SaveTool::DCSResult
SaveTool::drawCustomStyle(CustomStyle& style) {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return DCS_Fail; return DCS_Fail;
} }
@ -390,13 +395,14 @@ auto SaveTool::drawCustomStyle(CustomStyle& style) -> DCSResult {
return return_value; return return_value;
} }
void SaveTool::drawDecalEditor(Decal& decal) { void
SaveTool::drawDecalEditor(Decal& decal) {
ImGui::Text("ID: %i", decal.id); ImGui::Text("ID: %i", decal.id);
if(ImGui::BeginTable("##DecalTable", _advancedMode ? 2 : 1, ImGuiTableFlags_BordersInnerV)) { if(ImGui::BeginTable("##DecalTable", conf().advancedMode() ? 2 : 1, ImGuiTableFlags_BordersInnerV)) {
ImGui::TableSetupColumn("##Normal", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Normal", ImGuiTableColumnFlags_WidthStretch);
if(_advancedMode) { if(conf().advancedMode()) {
ImGui::TableSetupColumn("##Advanced", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Advanced", ImGuiTableColumnFlags_WidthStretch);
} }
@ -442,7 +448,7 @@ void SaveTool::drawDecalEditor(Decal& decal) {
ImGui::Checkbox("##Wrap", &decal.wrap); ImGui::Checkbox("##Wrap", &decal.wrap);
ImGui::EndGroup(); ImGui::EndGroup();
if(_advancedMode) { if(conf().advancedMode()) {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextColored(ImColor(255, 255, 0), ICON_FA_EXCLAMATION_TRIANGLE); ImGui::TextColored(ImColor(255, 255, 0), ICON_FA_EXCLAMATION_TRIANGLE);
@ -494,7 +500,8 @@ void SaveTool::drawDecalEditor(Decal& decal) {
} }
} }
void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<CustomStyle> style_view) { void
SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<CustomStyle> style_view) {
if(accessory.id < 1) { if(accessory.id < 1) {
ImGui::TextUnformatted("Accessory: <none>"); ImGui::TextUnformatted("Accessory: <none>");
} }
@ -508,7 +515,7 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
ImGui::SameLine(); ImGui::SameLine();
static Int tab = 0; static std::int32_t tab = 0;
static Containers::Optional<AccessorySize> size = Containers::NullOpt; static Containers::Optional<AccessorySize> size = Containers::NullOpt;
if(ImGui::SmallButton("Change")) { if(ImGui::SmallButton("Change")) {
ImGui::OpenPopup("##AccessoryPopup"); ImGui::OpenPopup("##AccessoryPopup");
@ -532,7 +539,7 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
"L", "L",
"XL" "XL"
}; };
static const Float selectable_width = 90.0f; static const float selectable_width = 90.0f;
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, {0.5f, 0.0f}); ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, {0.5f, 0.0f});
if(ImGui::Selectable("Primitives", tab == 0, ImGuiSelectableFlags_DontClosePopups, {selectable_width, 0.0f})) { if(ImGui::Selectable("Primitives", tab == 0, ImGuiSelectableFlags_DontClosePopups, {selectable_width, 0.0f})) {
@ -635,11 +642,11 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
ImGui::BeginGroup(); ImGui::BeginGroup();
drawAlignedText("Styles:"); drawAlignedText("Styles:");
if(_advancedMode) { if(conf().advancedMode()) {
drawAlignedText("Base position:"); drawAlignedText("Base position:");
} }
drawAlignedText("Position offset:"); drawAlignedText("Position offset:");
if(_advancedMode) { if(conf().advancedMode()) {
drawAlignedText("Base rotation:"); drawAlignedText("Base rotation:");
} }
drawAlignedText("Rotation offset:"); drawAlignedText("Rotation offset:");
@ -672,7 +679,7 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
} }
ImGui::PopItemWidth(); ImGui::PopItemWidth();
if(_advancedMode) { if(conf().advancedMode()) {
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
ImGui::DragFloat("##PosX", &accessory.relativePosition.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f"); ImGui::DragFloat("##PosX", &accessory.relativePosition.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f");
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -696,7 +703,7 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
ImGui::SameLine(); ImGui::SameLine();
drawHelpMarker("+/-500.0 = +/-250 in-game"); drawHelpMarker("+/-500.0 = +/-250 in-game");
if(_advancedMode) { if(conf().advancedMode()) {
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth()); ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
ImGui::DragFloat("##RotX", &accessory.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f"); ImGui::DragFloat("##RotX", &accessory.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f");
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -732,7 +739,8 @@ void SaveTool::drawAccessoryEditor(Accessory& accessory, Containers::ArrayView<C
ImGui::EndGroup(); ImGui::EndGroup();
} }
auto SaveTool::getStyleName(Int id, Containers::ArrayView<CustomStyle> view) -> Containers::StringView { Containers::StringView
SaveTool::getStyleName(std::int32_t id, Containers::ArrayView<CustomStyle> view) {
if(id >= 0 && id <= 15) { if(id >= 0 && id <= 15) {
return view[id].name; return view[id].name;
} }

View file

@ -21,7 +21,8 @@
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::drawArmour() { void
SaveTool::drawArmour() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -42,7 +43,7 @@ void SaveTool::drawArmour() {
#undef c #undef c
}; };
for(UnsignedInt i = 0; i < _currentMass->armourParts().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->armourParts().size(); i++) {
ImGui::PushID(int(i)); ImGui::PushID(int(i));
auto& part = _currentMass->armourParts()[i]; auto& part = _currentMass->armourParts()[i];
@ -52,10 +53,10 @@ void SaveTool::drawArmour() {
std::memset(header, '\0', 129); std::memset(header, '\0', 129);
if(armour_sets.find(part.id) != armour_sets.cend()) { if(armour_sets.find(part.id) != armour_sets.cend()) {
std::snprintf(header, 128, "%s: %s###%u", slot_labels[UnsignedInt(part.slot)].data(), armour_sets.at(part.id).name.data(), UnsignedInt(part.slot)); 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));
} }
else { else {
std::snprintf(header, 128, "%s: %i###%u", slot_labels[UnsignedInt(part.slot)].data(), part.id, UnsignedInt(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)) { if(ImGui::CollapsingHeader(header)) {
@ -63,7 +64,7 @@ void SaveTool::drawArmour() {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.491f); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.491f);
if(ImGui::BeginListBox("##ChangePart")) { if(ImGui::BeginListBox("##ChangePart")) {
if(std::strncmp("Neck", slot_labels[UnsignedInt(part.slot)].data(), 4) != 0) { if(std::strncmp("Neck", slot_labels[std::uint32_t(part.slot)].data(), 4) != 0) {
for(auto& set : armour_sets) { for(auto& set : armour_sets) {
if(ImGui::Selectable(set.second.name.data(), set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) { if(ImGui::Selectable(set.second.name.data(), set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
part.id = set.first; part.id = set.first;
@ -96,7 +97,7 @@ void SaveTool::drawArmour() {
ImGui::TextUnformatted("Styles:"); ImGui::TextUnformatted("Styles:");
for(Int j = 0; j < 4; j++) { for(std::int32_t j = 0; j < 4; j++) {
drawAlignedText("Slot %d:", j + 1); drawAlignedText("Slot %d:", j + 1);
ImGui::SameLine(); ImGui::SameLine();
@ -124,7 +125,7 @@ void SaveTool::drawArmour() {
ImGui::PushID("Decal"); ImGui::PushID("Decal");
drawAlignedText("Showing/editing decal"); drawAlignedText("Showing/editing decal");
for(UnsignedInt j = 0; j < part.decals.size(); j++) { for(std::uint32_t j = 0; j < part.decals.size(); j++) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], int(j)); ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], int(j));
} }
@ -139,7 +140,7 @@ void SaveTool::drawArmour() {
ImGui::PushID("Accessory"); ImGui::PushID("Accessory");
drawAlignedText("Showing/editing accessory"); drawAlignedText("Showing/editing accessory");
for(UnsignedInt j = 0; j < part.accessories.size(); j++) { for(std::uint32_t j = 0; j < part.accessories.size(); j++) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], int(j)); ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], int(j));
} }
@ -199,9 +200,9 @@ void SaveTool::drawArmour() {
drawAlignedText("Socket:"); drawAlignedText("Socket:");
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::BeginCombo("##Socket", socket_labels[UnsignedInt(placement.socket)].data())) { if(ImGui::BeginCombo("##Socket", socket_labels[std::uint32_t(placement.socket)].data())) {
for(UnsignedInt i = 0; i < (sizeof(socket_labels) / sizeof(socket_labels[0])); i++) { for(std::uint32_t i = 0; i < (sizeof(socket_labels) / sizeof(socket_labels[0])); i++) {
if(ImGui::Selectable(socket_labels[i].data(), i == UnsignedInt(placement.socket), ImGuiSelectableFlags_SpanAvailWidth)) { 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<BulletLauncherSocket>(i);
} }
} }
@ -288,7 +289,8 @@ void SaveTool::drawArmour() {
ImGui::EndChild(); ImGui::EndChild();
} }
void SaveTool::drawCustomArmourStyles() { void
SaveTool::drawCustomArmourStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -300,7 +302,7 @@ void SaveTool::drawCustomArmourStyles() {
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game."); ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
for(UnsignedInt i = 0; i < _currentMass->armourCustomStyles().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->armourCustomStyles().size(); i++) {
ImGui::PushID(int(i)); ImGui::PushID(int(i));
DCSResult result; DCSResult result;
result = drawCustomStyle(_currentMass->armourCustomStyles()[i]); result = drawCustomStyle(_currentMass->armourCustomStyles()[i]);

View file

@ -15,12 +15,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../Maps/StyleNames.h" #include "../Maps/StyleNames.h"
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::drawFrameInfo() { void
SaveTool::drawFrameInfo() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -73,7 +73,8 @@ void SaveTool::drawFrameInfo() {
ImGui::EndChild(); ImGui::EndChild();
} }
void SaveTool::drawJointSliders() { void
SaveTool::drawJointSliders() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -195,12 +196,13 @@ void SaveTool::drawJointSliders() {
} }
} }
void SaveTool::drawFrameStyles() { void
SaveTool::drawFrameStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
for(Int i = 0; i < 4; i++) { for(std::int32_t i = 0; i < 4; i++) {
drawAlignedText("Slot %d:", i + 1); drawAlignedText("Slot %d:", i + 1);
ImGui::SameLine(); ImGui::SameLine();
@ -245,7 +247,8 @@ void SaveTool::drawFrameStyles() {
} }
} }
void SaveTool::drawEyeColourPicker() { void
SaveTool::drawEyeColourPicker() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -278,7 +281,8 @@ void SaveTool::drawEyeColourPicker() {
} }
} }
void SaveTool::drawCustomFrameStyles() { void
SaveTool::drawCustomFrameStyles() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
return; return;
} }
@ -290,7 +294,7 @@ void SaveTool::drawCustomFrameStyles() {
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game."); ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
for(UnsignedInt i = 0; i < _currentMass->frameCustomStyles().size(); i++) { for(std::uint32_t i = 0; i < _currentMass->frameCustomStyles().size(); i++) {
ImGui::PushID(int(i)); ImGui::PushID(int(i));
DCSResult result; DCSResult result;
result = drawCustomStyle(_currentMass->frameCustomStyles()[i]); result = drawCustomStyle(_currentMass->frameCustomStyles()[i]);

View file

@ -21,13 +21,14 @@
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::drawWeapons() { void
SaveTool::drawWeapons() {
if(!_currentMass || _currentMass->state() != Mass::State::Valid) { if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
_currentWeapon = nullptr; _currentWeapon = nullptr;
return; return;
} }
const Float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
ImGui::BeginGroup(); ImGui::BeginGroup();
@ -254,7 +255,8 @@ void SaveTool::drawWeapons() {
ImGui::EndGroup(); ImGui::EndGroup();
} }
void SaveTool::drawWeaponCategory(Containers::StringView name, Containers::ArrayView<Weapon> weapons_view, bool& dirty, void
SaveTool::drawWeaponCategory(Containers::StringView name, Containers::ArrayView<Weapon> weapons_view, bool& dirty,
Containers::StringView payload_type, Containers::StringView payload_tooltip) Containers::StringView payload_type, Containers::StringView payload_tooltip)
{ {
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
@ -263,7 +265,7 @@ void SaveTool::drawWeaponCategory(Containers::StringView name, Containers::Array
ImGui::PushID(payload_type.data()); ImGui::PushID(payload_type.data());
for(UnsignedInt i = 0; i < weapons_view.size(); i++) { for(std::uint32_t i = 0; i < weapons_view.size(); i++) {
auto& weapon = weapons_view[i]; auto& weapon = weapons_view[i];
ImGui::TableNextRow(); ImGui::TableNextRow();
@ -275,7 +277,7 @@ void SaveTool::drawWeaponCategory(Containers::StringView name, Containers::Array
_currentWeapon = &weapon; _currentWeapon = &weapon;
} }
if(ImGui::BeginDragDropSource()) { if(ImGui::BeginDragDropSource()) {
ImGui::SetDragDropPayload(payload_type.data(), &i, sizeof(UnsignedInt)); ImGui::SetDragDropPayload(payload_type.data(), &i, sizeof(std::uint32_t));
if(ImGui::GetIO().KeyCtrl) { if(ImGui::GetIO().KeyCtrl) {
ImGui::Text("%s %i - %s (copy)", payload_tooltip.data(), i + 1, weapon.name.data()); ImGui::Text("%s %i - %s (copy)", payload_tooltip.data(), i + 1, weapon.name.data());
} }
@ -317,7 +319,8 @@ void SaveTool::drawWeaponCategory(Containers::StringView name, Containers::Array
ImGui::PopID(); ImGui::PopID();
} }
void SaveTool::drawWeaponEditor(Weapon& weapon) { void
SaveTool::drawWeaponEditor(Weapon& weapon) {
if(!_currentMass || _currentMass->state() != Mass::State::Valid || !_currentWeapon) { if(!_currentMass || _currentMass->state() != Mass::State::Valid || !_currentWeapon) {
return; return;
} }
@ -328,7 +331,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
#undef c #undef c
}; };
drawAlignedText("%s: %s", labels[UnsignedInt(weapon.type)].data(), weapon.name.data()); drawAlignedText("%s: %s", labels[std::uint32_t(weapon.type)].data(), weapon.name.data());
ImGui::SameLine(); ImGui::SameLine();
@ -425,8 +428,8 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
if(ImGui::CollapsingHeader("Weapon parts")) { if(ImGui::CollapsingHeader("Weapon parts")) {
drawAlignedText("Viewing/editing part:"); drawAlignedText("Viewing/editing part:");
for(Int i = 0; UnsignedLong(i) < weapon.parts.size(); i++) { for(std::int32_t i = 0; std::size_t(i) < weapon.parts.size(); i++) {
if(UnsignedLong(_selectedWeaponPart) >= weapon.parts.size()) { if(std::size_t(_selectedWeaponPart) >= weapon.parts.size()) {
_selectedWeaponPart = 0; _selectedWeaponPart = 0;
} }
ImGui::SameLine(); ImGui::SameLine();
@ -435,7 +438,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
auto& part = weapon.parts[_selectedWeaponPart]; auto& part = weapon.parts[_selectedWeaponPart];
const auto* map = [this, &weapon]()-> const std::map<Int, Containers::StringView>* { const auto* map = [this, &weapon]()-> const std::map<std::int32_t, Containers::StringView>* {
switch(weapon.type) { switch(weapon.type) {
case WeaponType::Melee: case WeaponType::Melee:
return _selectedWeaponPart == 0 ? &melee_grips : &melee_assaulters; return _selectedWeaponPart == 0 ? &melee_grips : &melee_assaulters;
@ -508,7 +511,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
if(ImGui::BeginChild("##PartDetails", {0.0f, 0.0f}, true)) { if(ImGui::BeginChild("##PartDetails", {0.0f, 0.0f}, true)) {
ImGui::TextUnformatted("Styles:"); ImGui::TextUnformatted("Styles:");
for(Int i = 0; i < 4; i++) { for(std::int32_t i = 0; i < 4; i++) {
drawAlignedText("Slot %d:", i + 1); drawAlignedText("Slot %d:", i + 1);
ImGui::SameLine(); ImGui::SameLine();
@ -534,7 +537,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
ImGui::PushID("Decal"); ImGui::PushID("Decal");
drawAlignedText("Showing/editing decal"); drawAlignedText("Showing/editing decal");
for(UnsignedLong i = 0; i < part.decals.size(); i++) { for(std::size_t i = 0; i < part.decals.size(); i++) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponDecal, int(i)); ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponDecal, int(i));
} }
@ -549,7 +552,7 @@ void SaveTool::drawWeaponEditor(Weapon& weapon) {
ImGui::PushID("Accessory"); ImGui::PushID("Accessory");
drawAlignedText("Showing/editing accessory"); drawAlignedText("Showing/editing accessory");
for(UnsignedLong i = 0; i < part.accessories.size(); i++) { for(std::size_t i = 0; i < part.accessories.size(); i++) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::RadioButton(std::string{char(65 + i)}.c_str(), &_selectedWeaponAccessory, int(i)); ImGui::RadioButton(std::string{char(65 + i)}.c_str(), &_selectedWeaponAccessory, int(i));
} }

View file

@ -24,7 +24,8 @@
extern const ImVec2 center_pivot; extern const ImVec2 center_pivot;
void SaveTool::drawProfileManager() { void
SaveTool::drawProfileManager() {
static std::size_t profile_index = 0; static std::size_t profile_index = 0;
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot); ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
@ -125,7 +126,8 @@ void SaveTool::drawProfileManager() {
ImGui::End(); ImGui::End();
} }
auto SaveTool::drawBackupListPopup() -> ImGuiID { ImGuiID
SaveTool::drawBackupListPopup() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot); ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot);
if(!ImGui::BeginPopupModal("Backups##BackupsModal", nullptr, if(!ImGui::BeginPopupModal("Backups##BackupsModal", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
@ -324,7 +326,8 @@ auto SaveTool::drawBackupListPopup() -> ImGuiID {
return 0; return 0;
} }
auto SaveTool::drawBackupProfilePopup(std::size_t profile_index) -> ImGuiID { ImGuiID
SaveTool::drawBackupProfilePopup(std::size_t profile_index) {
if(!ImGui::BeginPopupModal("Include builds ?##IncludeBuildsDialog", nullptr, if(!ImGui::BeginPopupModal("Include builds ?##IncludeBuildsDialog", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{ {
@ -368,7 +371,8 @@ auto SaveTool::drawBackupProfilePopup(std::size_t profile_index) -> ImGuiID {
return 0; return 0;
} }
auto SaveTool::drawDeleteProfilePopup(std::size_t profile_index) -> ImGuiID { ImGuiID
SaveTool::drawDeleteProfilePopup(std::size_t profile_index) {
if(!ImGui::BeginPopupModal("Confirmation##DeleteProfileConfirmation", nullptr, if(!ImGui::BeginPopupModal("Confirmation##DeleteProfileConfirmation", nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove))
{ {

View file

@ -24,7 +24,8 @@
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::updateCheckEvent(SDL_Event& event) { void
SaveTool::updateCheckEvent(SDL_Event& event) {
_updateThread.join(); _updateThread.join();
if(event.user.code == CurlInitFailed) { if(event.user.code == CurlInitFailed) {
@ -72,10 +73,10 @@ void SaveTool::updateCheckEvent(SDL_Event& event) {
prerelease = true; prerelease = true;
} }
} }
Int fullVersion; std::int32_t fullVersion;
Int major = 0; std::int32_t major = 0;
Int minor = 0; std::int32_t minor = 0;
Int patch = 0; std::int32_t patch = 0;
bool prerelease = false; bool prerelease = false;
bool operator==(const Version& other) const { bool operator==(const Version& other) const {
@ -123,13 +124,16 @@ void SaveTool::updateCheckEvent(SDL_Event& event) {
} }
} }
inline auto writeData(char* ptr, std::size_t size, std::size_t nmemb, Containers::String* buf)-> std::size_t { inline
std::size_t
writeData(char* ptr, std::size_t size, std::size_t nmemb, Containers::String* buf) {
if(!ptr || !buf) return 0; if(!ptr || !buf) return 0;
(*buf) = Utility::format("{}{}", *buf, Containers::StringView{ptr, size * nmemb}); (*buf) = Utility::format("{}{}", *buf, Containers::StringView{ptr, size * nmemb});
return size * nmemb; return size * nmemb;
} }
void SaveTool::checkForUpdates() { void
SaveTool::checkForUpdates() {
SDL_Event event; SDL_Event event;
SDL_zero(event); SDL_zero(event);
event.type = _updateEventId; event.type = _updateEventId;
@ -157,7 +161,7 @@ void SaveTool::checkForUpdates() {
if(code == CURLE_OK) { if(code == CURLE_OK) {
long status = 0; long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
event.user.code = Int(status); event.user.code = std::int32_t(status);
event.user.data1 = response_body.release(); event.user.data1 = response_body.release();
} }
else if(code == CURLE_OPERATION_TIMEDOUT) { else if(code == CURLE_OPERATION_TIMEDOUT) {

View file

@ -31,7 +31,8 @@
extern const ImVec2 center_pivot; extern const ImVec2 center_pivot;
void SaveTool::drawAbout() { void
SaveTool::drawAbout() {
ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f}}, ImGuiCond_Always, center_pivot); 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); ImGui::SetNextWindowSize({float(windowSize().x()) * 0.8f, float(windowSize().y()) * 0.75f}, ImGuiCond_Always);
@ -88,7 +89,7 @@ void SaveTool::drawAbout() {
if(ImGui::BeginChild("##GPL", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##GPL", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
static auto licence = _rs.getRaw("COPYING"); static auto licence = _rs.getRaw("COPYING");
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(licence.data(), licence.data() + licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(licence.begin(), licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -117,7 +118,7 @@ void SaveTool::drawAbout() {
static auto corrade_licence = _rs.getRaw("COPYING.Corrade"); static auto corrade_licence = _rs.getRaw("COPYING.Corrade");
if(ImGui::BeginChild("##CorradeLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##CorradeLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(corrade_licence.data(), corrade_licence.data() + corrade_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(corrade_licence.begin(), corrade_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -145,7 +146,7 @@ void SaveTool::drawAbout() {
static auto magnum_licence = _rs.getRaw("COPYING.Magnum"); static auto magnum_licence = _rs.getRaw("COPYING.Magnum");
if(ImGui::BeginChild("##MagnumLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##MagnumLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(magnum_licence.data(), magnum_licence.data() + magnum_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(magnum_licence.begin(), magnum_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -171,7 +172,7 @@ void SaveTool::drawAbout() {
static auto imgui_licence = _rs.getRaw("LICENSE.ImGui"); static auto imgui_licence = _rs.getRaw("LICENSE.ImGui");
if(ImGui::BeginChild("##ImGuiLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##ImGuiLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(imgui_licence.data(), imgui_licence.data() + imgui_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(imgui_licence.begin(), imgui_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -197,7 +198,7 @@ void SaveTool::drawAbout() {
static auto sdl_licence = _rs.getRaw("LICENSE.SDL"); static auto sdl_licence = _rs.getRaw("LICENSE.SDL");
if(ImGui::BeginChild("##SDLLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##SDLLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(sdl_licence.data(), sdl_licence.data() + sdl_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(sdl_licence.begin(), sdl_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -223,7 +224,7 @@ void SaveTool::drawAbout() {
static auto libzip_licence = _rs.getRaw("LICENSE.libzip"); static auto libzip_licence = _rs.getRaw("LICENSE.libzip");
if(ImGui::BeginChild("##libzipLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##libzipLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(libzip_licence.data(), libzip_licence.data() + libzip_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(libzip_licence.begin(), libzip_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -248,7 +249,7 @@ void SaveTool::drawAbout() {
static auto efsw_licence = _rs.getRaw("LICENSE.efsw"); static auto efsw_licence = _rs.getRaw("LICENSE.efsw");
if(ImGui::BeginChild("##efswLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##efswLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(efsw_licence.data(), efsw_licence.data() + efsw_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(efsw_licence.begin(), efsw_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -274,7 +275,7 @@ void SaveTool::drawAbout() {
static auto curl_licence = _rs.getRaw("LICENSE.curl"); static auto curl_licence = _rs.getRaw("LICENSE.curl");
if(ImGui::BeginChild("##libcurlLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) { if(ImGui::BeginChild("##libcurlLicence", {0.0f, float(windowSize().y()) * 0.3f}, true)) {
ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]); ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
ImGui::TextEx(curl_licence.data(), curl_licence.data() + curl_licence.size(), ImGuiTextFlags_None); ImGui::TextUnformatted(curl_licence.begin(), curl_licence.end());
ImGui::PopFont(); ImGui::PopFont();
} }
ImGui::EndChild(); ImGui::EndChild();

View file

@ -16,13 +16,18 @@
#include <Corrade/Utility/Path.h> #include <Corrade/Utility/Path.h>
#include "../Configuration/Configuration.h"
#include "../FontAwesome/IconsFontAwesome5.h" #include "../FontAwesome/IconsFontAwesome5.h"
#include "../FontAwesome/IconsFontAwesome5Brands.h" #include "../FontAwesome/IconsFontAwesome5Brands.h"
#include "SaveTool.h" #include "SaveTool.h"
void SaveTool::drawMainMenu() { void
if(ImGui::BeginMainMenuBar()) { SaveTool::drawMainMenu() {
if(!ImGui::BeginMainMenuBar()) {
return;
}
if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) { if(ImGui::BeginMenu("Save Tool##SaveToolMenu")) {
if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Path::exists(_gameDataDir))) { if(ImGui::BeginMenu(ICON_FA_FOLDER_OPEN " Open game data directory", Utility::Path::exists(_gameDataDir))) {
if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Path::exists(_configDir))) { if(ImGui::MenuItem(ICON_FA_COG " Configuration", nullptr, false, Utility::Path::exists(_configDir))) {
@ -57,7 +62,7 @@ void SaveTool::drawMainMenu() {
if(ImGui::BeginMenu(ICON_FA_COG " Settings")) { if(ImGui::BeginMenu(ICON_FA_COG " Settings")) {
ImGui::BeginGroup(); ImGui::BeginGroup();
drawAlignedText("Vertical sync:"); drawAlignedText("Vertical sync:");
if(_swapInterval == 0) { if(conf().swapInterval() == 0) {
drawAlignedText("FPS cap:"); drawAlignedText("FPS cap:");
} }
ImGui::EndGroup(); ImGui::EndGroup();
@ -75,10 +80,10 @@ void SaveTool::drawMainMenu() {
ImGui::PushItemWidth(300.0f); ImGui::PushItemWidth(300.0f);
if(ImGui::BeginCombo("##FrameLimit", framelimit_labels[_swapInterval])) { if(ImGui::BeginCombo("##FrameLimit", framelimit_labels[conf().swapInterval()])) {
for(int i = 0; i <= 3; i++) { for(int i = 0; i <= 3; i++) {
if(ImGui::Selectable(framelimit_labels[i], _swapInterval == i)) { if(ImGui::Selectable(framelimit_labels[i], conf().swapInterval() == i)) {
_swapInterval = i; conf().setSwapInterval(i);
setSwapInterval(i); setSwapInterval(i);
if(i == 0) { if(i == 0) {
setMinimalLoopPeriod(0); setMinimalLoopPeriod(0);
@ -89,28 +94,38 @@ void SaveTool::drawMainMenu() {
ImGui::EndCombo(); ImGui::EndCombo();
} }
if(_swapInterval == 0) { if(conf().swapInterval() == 0) {
ImGui::SliderFloat("##FpsCapSlider", &_fpsCap, 15.0f, 301.0f, static float fps_cap = conf().fpsCap();
_fpsCap != 301.0f ? "%.0f" : "Uncapped", ImGuiSliderFlags_AlwaysClamp); if(ImGui::SliderFloat("##FpsCapSlider", &fps_cap, 15.0f, 301.0f,
conf().fpsCap() != 301.0f ? "%.0f" : "Uncapped", ImGuiSliderFlags_AlwaysClamp))
{
conf().setFpsCap(fps_cap);
}
} }
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::EndGroup(); ImGui::EndGroup();
ImGui::Checkbox("Cheat mode", &_cheatMode); if(drawCheckbox("Cheat mode", conf().cheatMode())) {
conf().setCheatMode(!conf().cheatMode());
}
ImGui::SameLine(); ImGui::SameLine();
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
drawHelpMarker("This gives access to save edition features that can be considered cheats.", drawHelpMarker("This gives access to save edition features that can be considered cheats.",
Float(windowSize().x()) * 0.4f); float(windowSize().x()) * 0.4f);
ImGui::Checkbox("Advanced mode", &_advancedMode); if(drawCheckbox("Advanced mode", conf().advancedMode())) {
conf().setAdvancedMode(!conf().advancedMode());
}
ImGui::SameLine(); ImGui::SameLine();
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
drawHelpMarker("This gives access to editing values that have unknown purposes or are undocumented.", drawHelpMarker("This gives access to editing values that have unknown purposes or are undocumented.",
Float(windowSize().x()) * 0.4f); float(windowSize().x()) * 0.4f);
ImGui::Checkbox("Check for updates on startup", &_checkUpdatesOnStartup); if(drawCheckbox("Check for updates on startup", conf().checkUpdatesOnStartup())) {
conf().setCheckUpdatesOnStartup(!conf().checkUpdatesOnStartup());
}
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button(ICON_FA_SYNC_ALT " Check now")) { if(ImGui::Button(ICON_FA_SYNC_ALT " Check now")) {
_queue.addToast(Toast::Type::Default, "Checking for updates..."); _queue.addToast(Toast::Type::Default, "Checking for updates...");
@ -128,7 +143,9 @@ void SaveTool::drawMainMenu() {
} }
} }
ImGui::Checkbox("Skip disclaimer", &_skipDisclaimer); if(drawCheckbox("Skip disclaimer", conf().skipDisclaimer())) {
conf().setSkipDisclaimer(!conf().skipDisclaimer());
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -214,4 +231,3 @@ void SaveTool::drawMainMenu() {
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
} }
}

View file

@ -26,20 +26,23 @@
using namespace Containers::Literals; using namespace Containers::Literals;
constexpr UnsignedInt success_colour = 0xff67d23bu; constexpr std::uint32_t success_colour = 0xff67d23bu;
constexpr UnsignedInt info_colour = 0xffcc832fu; constexpr std::uint32_t info_colour = 0xffcc832fu;
constexpr UnsignedInt warning_colour = 0xff2fcfc7u; constexpr std::uint32_t warning_colour = 0xff2fcfc7u;
constexpr UnsignedInt error_colour = 0xff3134cdu; constexpr std::uint32_t error_colour = 0xff3134cdu;
constexpr UnsignedInt fade_time = 150; constexpr std::uint32_t fade_time = 150;
constexpr Float base_opacity = 1.0f; constexpr float base_opacity = 1.0f;
constexpr Vector2 padding{20.0f, 20.0f}; constexpr Vector2 padding{20.0f, 20.0f};
constexpr Float toast_spacing = 10.0f; constexpr float toast_spacing = 10.0f;
Toast::Toast(Type type, Containers::StringView message, std::chrono::milliseconds timeout): Toast::Toast(Type type, Containers::StringView message, std::chrono::milliseconds timeout):
_type{type}, _message{message}, _timeout{timeout}, _creationTime{std::chrono::steady_clock::now()} _type{type},
_message{message},
_timeout{timeout},
_creationTime{std::chrono::steady_clock::now()}
{ {
_phaseTrack = Animation::Track<UnsignedInt, Phase>{{ _phaseTrack = Animation::Track<std::uint32_t, Phase>{{
{0, Phase::FadeIn}, {0, Phase::FadeIn},
{fade_time, Phase::Wait}, {fade_time, Phase::Wait},
{fade_time + timeout.count(), Phase::FadeOut}, {fade_time + timeout.count(), Phase::FadeOut},
@ -47,56 +50,66 @@ Toast::Toast(Type type, Containers::StringView message, std::chrono::millisecond
}, Math::select, Animation::Extrapolation::Constant}; }, Math::select, Animation::Extrapolation::Constant};
} }
auto Toast::type() -> Type { Toast::Type
Toast::type() {
return _type; return _type;
} }
auto Toast::message() -> Containers::StringView { Containers::StringView
Toast::message() {
return _message; return _message;
} }
auto Toast::timeout() -> std::chrono::milliseconds { std::chrono::milliseconds
Toast::timeout() {
return _timeout; return _timeout;
} }
auto Toast::creationTime() -> std::chrono::steady_clock::time_point { std::chrono::steady_clock::time_point
Toast::creationTime() {
return _creationTime; return _creationTime;
} }
auto Toast::elapsedTime() -> std::chrono::milliseconds { std::chrono::milliseconds
Toast::elapsedTime() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - _creationTime); return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - _creationTime);
} }
auto Toast::phase() -> Phase { Toast::Phase
Toast::phase() {
return _phaseTrack.at(elapsedTime().count()); return _phaseTrack.at(elapsedTime().count());
} }
auto Toast::opacity() -> Float { float
Toast::opacity() {
Phase phase = this->phase(); Phase phase = this->phase();
Long elapsed_time = elapsedTime().count(); std::int64_t elapsed_time = elapsedTime().count();
if(phase == Phase::FadeIn) { if(phase == Phase::FadeIn) {
return Float(elapsed_time) / Float(fade_time); return float(elapsed_time) / float(fade_time);
} }
else if(phase == Phase::FadeOut) { else if(phase == Phase::FadeOut) {
return 1.0f - ((Float(elapsed_time) - Float(fade_time) - Float(_timeout.count())) / Float(fade_time)); return 1.0f - ((float(elapsed_time) - float(fade_time) - float(_timeout.count())) / float(fade_time));
} }
return 1.0f; return 1.0f;
} }
void ToastQueue::addToast(Toast&& toast) { void
ToastQueue::addToast(Toast&& toast) {
_toasts.push_back(std::move(toast)); _toasts.push_back(std::move(toast));
} }
void ToastQueue::addToast(Toast::Type type, Containers::StringView message, std::chrono::milliseconds timeout) { void
ToastQueue::addToast(Toast::Type type, Containers::StringView message, std::chrono::milliseconds timeout) {
_toasts.emplace_back(type, message, timeout); _toasts.emplace_back(type, message, timeout);
} }
void ToastQueue::draw(Vector2i viewport_size) { void
Float height = 0.0f; ToastQueue::draw(Vector2i viewport_size) {
float height = 0.0f;
for(UnsignedInt i = 0; i < _toasts.size(); i++) { for(std::uint32_t i = 0; i < _toasts.size(); i++) {
Toast* current = &_toasts[i]; Toast* current = &_toasts[i];
if(current->phase() == Toast::Phase::TimedOut) { if(current->phase() == Toast::Phase::TimedOut) {
@ -106,11 +119,12 @@ void ToastQueue::draw(Vector2i viewport_size) {
Containers::String win_id = Utility::format("##Toast{}", i); Containers::String win_id = Utility::format("##Toast{}", i);
Float opacity = base_opacity * current->opacity(); float opacity = base_opacity * current->opacity();
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, opacity); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, opacity);
ImGui::SetNextWindowPos({viewport_size.x() - padding.x(), viewport_size.y() - padding.y() - height}, ImGuiCond_Always, {1.0f, 1.0f}); ImGui::SetNextWindowPos({float(viewport_size.x()) - padding.x(), float(viewport_size.y()) - padding.y() - height},
ImGuiCond_Always, {1.0f, 1.0f});
if(ImGui::Begin(win_id.data(), nullptr, if(ImGui::Begin(win_id.data(), nullptr,
ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoDecoration| ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoDecoration|
ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoNav|ImGuiWindowFlags_NoFocusOnAppearing)) ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoNav|ImGuiWindowFlags_NoFocusOnAppearing))
@ -154,6 +168,7 @@ void ToastQueue::draw(Vector2i viewport_size) {
} }
} }
void ToastQueue::removeToast(Long index) { void
ToastQueue::removeToast(std::int64_t index) {
_toasts.erase(_toasts.begin() + index); _toasts.erase(_toasts.begin() + index);
} }

View file

@ -29,11 +29,11 @@ using namespace Magnum;
class Toast { class Toast {
public: public:
enum class Type : UnsignedByte { enum class Type: std::uint8_t {
Default, Success, Info, Warning, Error Default, Success, Info, Warning, Error
}; };
enum class Phase : UnsignedByte { enum class Phase: std::uint8_t {
FadeIn, Wait, FadeOut, TimedOut FadeIn, Wait, FadeOut, TimedOut
}; };
@ -46,26 +46,26 @@ class Toast {
Toast(Toast&& other) = default; Toast(Toast&& other) = default;
Toast& operator=(Toast&& other) = default; Toast& operator=(Toast&& other) = default;
auto type() -> Type; Type type();
auto message() -> Containers::StringView; Containers::StringView message();
auto timeout() -> std::chrono::milliseconds; std::chrono::milliseconds timeout();
auto creationTime() -> std::chrono::steady_clock::time_point; std::chrono::steady_clock::time_point creationTime();
auto elapsedTime() -> std::chrono::milliseconds; std::chrono::milliseconds elapsedTime();
auto phase() -> Phase; Phase phase();
auto opacity() -> Float; float opacity();
private: private:
Type _type{Type::Default}; Type _type{Type::Default};
Containers::String _message; Containers::String _message;
std::chrono::milliseconds _timeout; std::chrono::milliseconds _timeout;
std::chrono::steady_clock::time_point _creationTime; std::chrono::steady_clock::time_point _creationTime;
Animation::Track<UnsignedInt, Phase> _phaseTrack; Animation::Track<std::uint32_t, Phase> _phaseTrack;
}; };
class ToastQueue { class ToastQueue {
@ -78,7 +78,7 @@ class ToastQueue {
void draw(Vector2i viewport_size); void draw(Vector2i viewport_size);
private: private:
void removeToast(Long index); void removeToast(std::int64_t index);
std::vector<Toast> _toasts; std::vector<Toast> _toasts;
}; };

View file

@ -35,72 +35,89 @@ BinaryReader::~BinaryReader() {
closeFile(); closeFile();
} }
auto BinaryReader::open() -> bool { bool
BinaryReader::open() {
return _file; return _file;
} }
auto BinaryReader::eof() -> bool { bool
BinaryReader::eof() {
return std::feof(_file) != 0; return std::feof(_file) != 0;
} }
auto BinaryReader::position() -> Long { std::int64_t
BinaryReader::position() {
return _ftelli64(_file); return _ftelli64(_file);
} }
auto BinaryReader::seek(Long position) -> bool { bool
BinaryReader::seek(std::int64_t position) {
return _fseeki64(_file, position, SEEK_SET) == 0; return _fseeki64(_file, position, SEEK_SET) == 0;
} }
void BinaryReader::closeFile() { void
BinaryReader::closeFile() {
std::fclose(_file); std::fclose(_file);
_file = nullptr; _file = nullptr;
} }
auto BinaryReader::readChar(char& value) -> bool { bool
BinaryReader::readChar(char& value) {
return std::fread(&value, sizeof(char), 1, _file) == 1; return std::fread(&value, sizeof(char), 1, _file) == 1;
} }
auto BinaryReader::readByte(Byte& value) -> bool { bool
return std::fread(&value, sizeof(Byte), 1, _file) == 1; BinaryReader::readInt8(std::int8_t& value) {
return std::fread(&value, sizeof(std::int8_t), 1, _file) == 1;
} }
auto BinaryReader::readUnsignedByte(UnsignedByte& value) -> bool { bool
return std::fread(&value, sizeof(UnsignedByte), 1, _file) == 1; BinaryReader::readUint8(std::uint8_t& value) {
return std::fread(&value, sizeof(std::uint8_t), 1, _file) == 1;
} }
auto BinaryReader::readShort(Short& value) -> bool { bool
return std::fread(&value, sizeof(Short), 1, _file) == 1; BinaryReader::readInt16(std::int16_t& value) {
return std::fread(&value, sizeof(std::int16_t), 1, _file) == 1;
} }
auto BinaryReader::readUnsignedShort(UnsignedShort& value) -> bool { bool
return std::fread(&value, sizeof(UnsignedShort), 1, _file) == 1; BinaryReader::readUint16(std::uint16_t& value) {
return std::fread(&value, sizeof(std::uint16_t), 1, _file) == 1;
} }
auto BinaryReader::readInt(Int& value) -> bool { bool
return std::fread(&value, sizeof(Int), 1, _file) == 1; BinaryReader::readInt32(std::int32_t& value) {
return std::fread(&value, sizeof(std::int32_t), 1, _file) == 1;
} }
auto BinaryReader::readUnsignedInt(UnsignedInt& value) -> bool { bool
return std::fread(&value, sizeof(UnsignedInt), 1, _file) == 1; BinaryReader::readUint32(std::uint32_t& value) {
return std::fread(&value, sizeof(std::uint32_t), 1, _file) == 1;
} }
auto BinaryReader::readLong(Long& value) -> bool { bool
return std::fread(&value, sizeof(Long), 1, _file) == 1; BinaryReader::readInt64(std::int64_t& value) {
return std::fread(&value, sizeof(std::int64_t), 1, _file) == 1;
} }
auto BinaryReader::readUnsignedLong(UnsignedLong& value) -> bool { bool
return std::fread(&value, sizeof(UnsignedLong), 1, _file) == 1; BinaryReader::readUint64(std::uint64_t& value) {
return std::fread(&value, sizeof(std::uint64_t), 1, _file) == 1;
} }
auto BinaryReader::readFloat(Float& value) -> bool { bool
return std::fread(&value, sizeof(Float), 1, _file) == 1; BinaryReader::readFloat(float& value) {
return std::fread(&value, sizeof(float), 1, _file) == 1;
} }
auto BinaryReader::readDouble(Double& value) -> bool { bool
return std::fread(&value, sizeof(Double), 1, _file) == 1; BinaryReader::readDouble(double& value) {
return std::fread(&value, sizeof(double), 1, _file) == 1;
} }
auto BinaryReader::readArray(Containers::Array<char>& array, std::size_t count) -> bool { bool
BinaryReader::readArray(Containers::Array<char>& array, std::size_t count) {
if(array.size() < count) { if(array.size() < count) {
array = Containers::Array<char>{ValueInit, count}; array = Containers::Array<char>{ValueInit, count};
} }
@ -108,9 +125,10 @@ auto BinaryReader::readArray(Containers::Array<char>& array, std::size_t count)
return std::fread(array.data(), sizeof(char), count, _file) == count; return std::fread(array.data(), sizeof(char), count, _file) == count;
} }
auto BinaryReader::readUEString(Containers::String& str) -> bool { bool
UnsignedInt length = 0; BinaryReader::readUEString(Containers::String& str) {
if(!readUnsignedInt(length) || length == 0) { std::uint32_t length = 0;
if(!readUint32(length) || length == 0) {
return false; return false;
} }
@ -119,8 +137,9 @@ auto BinaryReader::readUEString(Containers::String& str) -> bool {
return std::fread(str.data(), sizeof(char), length, _file) == length; return std::fread(str.data(), sizeof(char), length, _file) == length;
} }
auto BinaryReader::peekChar() -> Int { std::int32_t
Int c; BinaryReader::peekChar() {
std::int32_t c;
c = std::fgetc(_file); c = std::fgetc(_file);
std::ungetc(c, _file); std::ungetc(c, _file);
return c; return c;

View file

@ -16,56 +16,54 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <cstdio> #include <cstdio>
#include <Corrade/Containers/Containers.h> #include <Corrade/Containers/Containers.h>
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
class BinaryReader { class BinaryReader {
public: public:
explicit BinaryReader(Containers::StringView filename); explicit BinaryReader(Containers::StringView filename);
~BinaryReader(); ~BinaryReader();
auto open() -> bool; bool open();
auto eof() -> bool; bool eof();
auto position() -> Long; std::int64_t position();
auto seek(Long position) -> bool; bool seek(std::int64_t position);
void closeFile(); void closeFile();
auto readChar(char& value) -> bool; bool readChar(char& value);
auto readByte(Byte& value) -> bool; bool readInt8(std::int8_t& value);
auto readUnsignedByte(UnsignedByte& value) -> bool; bool readUint8(std::uint8_t& value);
auto readShort(Short& value) -> bool; bool readInt16(std::int16_t& value);
auto readUnsignedShort(UnsignedShort& value) -> bool; bool readUint16(std::uint16_t& value);
auto readInt(Int& value) -> bool; bool readInt32(std::int32_t& value);
auto readUnsignedInt(UnsignedInt& value) -> bool; bool readUint32(std::uint32_t& value);
auto readLong(Long& value) -> bool; bool readInt64(std::int64_t& value);
auto readUnsignedLong(UnsignedLong& value) -> bool; bool readUint64(std::uint64_t& value);
auto readFloat(Float& value) -> bool; bool readFloat(float& value);
auto readDouble(Double& value) -> bool; bool readDouble(double& value);
auto readArray(Containers::Array<char>& array, std::size_t count) -> bool; bool readArray(Containers::Array<char>& array, std::size_t count);
template<typename T> template<typename T>
auto readValue(T& value) -> bool { bool readValue(T& value) {
return fread(&value, sizeof(T), 1, _file) == sizeof(T); return fread(&value, sizeof(T), 1, _file) == sizeof(T);
} }
template<std::size_t S> template<std::size_t S>
auto readStaticArray(Containers::StaticArray<S, char>& array) -> bool { bool readStaticArray(Containers::StaticArray<S, char>& array) {
return std::fread(array.data(), sizeof(char), S, _file) == S; return std::fread(array.data(), sizeof(char), S, _file) == S;
} }
auto readUEString(Containers::String& str) -> bool; bool readUEString(Containers::String& str);
auto peekChar() -> Int; std::int32_t peekChar();
private: private:
std::FILE* _file = nullptr; std::FILE* _file = nullptr;

View file

@ -33,29 +33,35 @@ BinaryWriter::~BinaryWriter() {
closeFile(); closeFile();
} }
auto BinaryWriter::open() -> bool { bool
BinaryWriter::open() {
return _file; return _file;
} }
void BinaryWriter::closeFile() { void
BinaryWriter::closeFile() {
std::fflush(_file); std::fflush(_file);
std::fclose(_file); std::fclose(_file);
_file = nullptr; _file = nullptr;
} }
auto BinaryWriter::position() -> Long { std::int64_t
BinaryWriter::position() {
return _ftelli64(_file); return _ftelli64(_file);
} }
auto BinaryWriter::array() const -> Containers::ArrayView<const char> { Containers::ArrayView<const char>
BinaryWriter::array() const {
return _data; return _data;
} }
auto BinaryWriter::arrayPosition() const -> UnsignedLong { std::size_t
BinaryWriter::arrayPosition() const {
return _index; return _index;
} }
auto BinaryWriter::flushToFile() -> bool { bool
BinaryWriter::flushToFile() {
bool ret = writeArray(_data); bool ret = writeArray(_data);
std::fflush(_file); std::fflush(_file);
_data = Containers::Array<char>{}; _data = Containers::Array<char>{};
@ -63,51 +69,63 @@ auto BinaryWriter::flushToFile() -> bool {
return ret; return ret;
} }
auto BinaryWriter::writeChar(char value) -> bool { bool
BinaryWriter::writeChar(char value) {
return std::fwrite(&value, sizeof(char), 1, _file) == 1; return std::fwrite(&value, sizeof(char), 1, _file) == 1;
} }
auto BinaryWriter::writeByte(Byte value) -> bool { bool
return std::fwrite(&value, sizeof(Byte), 1, _file) == 1; BinaryWriter::writeInt8(std::int8_t value) {
return std::fwrite(&value, sizeof(std::int8_t), 1, _file) == 1;
} }
auto BinaryWriter::writeUnsignedByte(UnsignedByte value) -> bool { bool
return std::fwrite(&value, sizeof(UnsignedByte), 1, _file) == 1; BinaryWriter::writeUint8(std::uint8_t value) {
return std::fwrite(&value, sizeof(std::uint8_t), 1, _file) == 1;
} }
auto BinaryWriter::writeShort(Short value) -> bool { bool
return std::fwrite(&value, sizeof(Short), 1, _file) == 1; BinaryWriter::writeInt16(std::int16_t value) {
return std::fwrite(&value, sizeof(std::int16_t), 1, _file) == 1;
} }
auto BinaryWriter::writeUnsignedShort(UnsignedShort value) -> bool { bool
return std::fwrite(&value, sizeof(UnsignedShort), 1, _file) == 1; BinaryWriter::writeUint16(std::uint16_t value) {
return std::fwrite(&value, sizeof(std::uint16_t), 1, _file) == 1;
} }
auto BinaryWriter::writeInt(Int value) -> bool { bool
return std::fwrite(&value, sizeof(Int), 1, _file) == 1; BinaryWriter::writeInt32(std::int32_t value) {
return std::fwrite(&value, sizeof(std::int32_t), 1, _file) == 1;
} }
auto BinaryWriter::writeUnsignedInt(UnsignedInt value) -> bool { bool
return std::fwrite(&value, sizeof(UnsignedInt), 1, _file) == 1; BinaryWriter::writeUint32(std::uint32_t value) {
return std::fwrite(&value, sizeof(std::uint32_t), 1, _file) == 1;
} }
auto BinaryWriter::writeLong(Long value) -> bool { bool
return std::fwrite(&value, sizeof(Long), 1, _file) == 1; BinaryWriter::writeInt64(std::int64_t value) {
return std::fwrite(&value, sizeof(std::int64_t), 1, _file) == 1;
} }
auto BinaryWriter::writeUnsignedLong(UnsignedLong value) -> bool { bool
return std::fwrite(&value, sizeof(UnsignedLong), 1, _file) == 1; BinaryWriter::writeUint64(std::uint64_t value) {
return std::fwrite(&value, sizeof(std::uint64_t), 1, _file) == 1;
} }
auto BinaryWriter::writeFloat(Float value) -> bool { bool
return std::fwrite(&value, sizeof(Float), 1, _file) == 1; BinaryWriter::writeFloat(float value) {
return std::fwrite(&value, sizeof(float), 1, _file) == 1;
} }
auto BinaryWriter::writeDouble(Double value) -> bool { bool
return std::fwrite(&value, sizeof(Double), 1, _file) == 1; BinaryWriter::writeDouble(double value) {
return std::fwrite(&value, sizeof(double), 1, _file) == 1;
} }
auto BinaryWriter::writeArray(Containers::ArrayView<const char> array) -> bool { bool
BinaryWriter::writeArray(Containers::ArrayView<const char> array) {
if(array.size() == 0) { if(array.size() == 0) {
return false; return false;
} }
@ -115,13 +133,14 @@ auto BinaryWriter::writeArray(Containers::ArrayView<const char> array) -> bool {
return std::fwrite(array.data(), sizeof(char), array.size(), _file) == array.size(); return std::fwrite(array.data(), sizeof(char), array.size(), _file) == array.size();
} }
auto BinaryWriter::writeUEString(Containers::StringView str) -> bool { bool
BinaryWriter::writeUEString(Containers::StringView str) {
if(str.size() > UINT32_MAX) { if(str.size() > UINT32_MAX) {
LOG_ERROR_FORMAT("String is too big. Expected size() < UINT32_MAX, got {} instead.", str.size()); LOG_ERROR_FORMAT("String is too big. Expected size() < UINT32_MAX, got {} instead.", str.size());
return false; return false;
} }
writeUnsignedInt(static_cast<UnsignedInt>(str.size()) + 1); writeUint32(static_cast<std::uint32_t>(str.size()) + 1);
if(str.size() > 0) { if(str.size() > 0) {
std::size_t count = std::fwrite(str.data(), sizeof(char), str.size(), _file); std::size_t count = std::fwrite(str.data(), sizeof(char), str.size(), _file);
@ -132,8 +151,9 @@ auto BinaryWriter::writeUEString(Containers::StringView str) -> bool {
return writeChar('\0'); return writeChar('\0');
} }
auto BinaryWriter::writeUEStringToArray(Containers::StringView value) -> UnsignedLong { std::size_t
return writeValueToArray<UnsignedInt>(UnsignedInt(value.size()) + 1u) + BinaryWriter::writeUEStringToArray(Containers::StringView value) {
return writeValueToArray<std::uint32_t>(std::uint32_t(value.size()) + 1u) +
writeDataToArray(Containers::ArrayView<const char>{value}) + writeDataToArray(Containers::ArrayView<const char>{value}) +
writeValueToArray<char>('\0'); writeValueToArray<char>('\0');
} }

View file

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdint>
#include <cstdio> #include <cstdio>
#include <Corrade/Containers/ArrayView.h> #include <Corrade/Containers/ArrayView.h>
@ -23,10 +24,7 @@
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
class BinaryWriter { class BinaryWriter {
public: public:
@ -39,65 +37,65 @@ class BinaryWriter {
BinaryWriter(BinaryWriter&& other) = default; BinaryWriter(BinaryWriter&& other) = default;
BinaryWriter& operator=(BinaryWriter&& other) = default; BinaryWriter& operator=(BinaryWriter&& other) = default;
auto open() -> bool; bool open();
void closeFile(); void closeFile();
auto position() -> Long; std::int64_t position();
auto array() const -> Containers::ArrayView<const char>; Containers::ArrayView<const char> array() const;
auto arrayPosition() const -> UnsignedLong; std::size_t arrayPosition() const;
auto flushToFile() -> bool; bool flushToFile();
auto writeByte(Byte value) -> bool; bool writeChar(char value);
auto writeChar(char value) -> bool; bool writeInt8(std::int8_t value);
auto writeUnsignedByte(UnsignedByte value) -> bool; bool writeUint8(std::uint8_t value);
auto writeShort(Short value) -> bool; bool writeInt16(std::int16_t value);
auto writeUnsignedShort(UnsignedShort value) -> bool; bool writeUint16(std::uint16_t value);
auto writeInt(Int value) -> bool; bool writeInt32(std::int32_t value);
auto writeUnsignedInt(UnsignedInt value) -> bool; bool writeUint32(std::uint32_t value);
auto writeLong(Long value) -> bool; bool writeInt64(std::int64_t value);
auto writeUnsignedLong(UnsignedLong value) -> bool; bool writeUint64(std::uint64_t value);
auto writeFloat(Float value) -> bool; bool writeFloat(float value);
auto writeDouble(Double value) -> bool; bool writeDouble(double value);
auto writeArray(Containers::ArrayView<const char> array) -> bool; bool writeArray(Containers::ArrayView<const char> array);
template<std::size_t size> template<std::size_t size>
auto writeString(const char(&str)[size]) -> bool { bool writeString(const char(&str)[size]) {
return writeArray({str, size - 1}); return writeArray({str, size - 1});
} }
template<std::size_t S> template<std::size_t S>
auto writeStaticArray(Containers::StaticArrayView<S, const char> array) -> bool { bool writeStaticArray(Containers::StaticArrayView<S, const char> array) {
return std::fwrite(array.data(), sizeof(char), S, _file) == S; return std::fwrite(array.data(), sizeof(char), S, _file) == S;
} }
auto writeUEString(Containers::StringView str) -> bool; bool writeUEString(Containers::StringView str);
template<typename T, typename U = std::conditional_t<std::is_trivially_copyable<T>::value, T, T&>> template<typename T, typename U = std::conditional_t<std::is_trivially_copyable<T>::value, T, T&>>
auto writeValueToArray(U value) -> UnsignedLong { std::size_t writeValueToArray(U value) {
Containers::ArrayView<T> view{&value, 1}; Containers::ArrayView<T> view{&value, 1};
return writeDataToArray(view); return writeDataToArray(view);
} }
auto writeUEStringToArray(Containers::StringView value) -> UnsignedLong; std::size_t writeUEStringToArray(Containers::StringView value);
template<typename T> template<typename T>
void writeValueToArrayAt(T& value, UnsignedLong position) { void writeValueToArrayAt(T& value, std::size_t position) {
Containers::ArrayView<T> view{&value, 1}; Containers::ArrayView<T> view{&value, 1};
writeDataToArrayAt(view, position); writeDataToArrayAt(view, position);
} }
template<typename T> template<typename T>
auto writeDataToArray(Containers::ArrayView<T> view) -> UnsignedLong { std::size_t writeDataToArray(Containers::ArrayView<T> view) {
arrayAppend(_data, Containers::arrayCast<const char>(view)); arrayAppend(_data, Containers::arrayCast<const char>(view));
_index += sizeof(T) * view.size(); _index += sizeof(T) * view.size();
return sizeof(T) * view.size(); return sizeof(T) * view.size();
} }
template<typename T> template<typename T>
void writeDataToArrayAt(Containers::ArrayView<T> view, UnsignedLong position) { void writeDataToArrayAt(Containers::ArrayView<T> view, std::size_t position) {
auto casted_view = Containers::arrayCast<const char>(view); auto casted_view = Containers::arrayCast<const char>(view);
for(UnsignedLong i = 0; i < casted_view.size(); i++) { for(std::size_t i = 0; i < casted_view.size(); i++) {
_data[position + i] = casted_view[i]; _data[position + i] = casted_view[i];
} }
} }
@ -106,5 +104,5 @@ class BinaryWriter {
FILE* _file = nullptr; FILE* _file = nullptr;
Containers::Array<char> _data; Containers::Array<char> _data;
UnsignedLong _index = 0; std::size_t _index = 0;
}; };

View file

@ -0,0 +1,98 @@
# MassBuilderSaveTool
# Copyright (C) 2021-2022 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(UESaveFile STATIC EXCLUDE_FROM_ALL
Serialisers/AbstractUnrealCollectionPropertySerialiser.h
Serialisers/AbstractUnrealPropertySerialiser.h
Serialisers/AbstractUnrealStructSerialiser.h
Serialisers/ArrayPropertySerialiser.h
Serialisers/ArrayPropertySerialiser.cpp
Serialisers/BoolPropertySerialiser.h
Serialisers/BoolPropertySerialiser.cpp
Serialisers/BytePropertySerialiser.h
Serialisers/BytePropertySerialiser.cpp
Serialisers/ColourPropertySerialiser.h
Serialisers/ColourPropertySerialiser.cpp
Serialisers/DateTimePropertySerialiser.h
Serialisers/DateTimePropertySerialiser.cpp
Serialisers/EnumPropertySerialiser.h
Serialisers/EnumPropertySerialiser.cpp
Serialisers/FloatPropertySerialiser.h
Serialisers/FloatPropertySerialiser.cpp
Serialisers/GuidPropertySerialiser.h
Serialisers/GuidPropertySerialiser.cpp
Serialisers/IntPropertySerialiser.h
Serialisers/IntPropertySerialiser.cpp
Serialisers/MapPropertySerialiser.h
Serialisers/MapPropertySerialiser.cpp
Serialisers/ResourcePropertySerialiser.h
Serialisers/ResourcePropertySerialiser.cpp
Serialisers/RotatorPropertySerialiser.h
Serialisers/RotatorPropertySerialiser.cpp
Serialisers/StringPropertySerialiser.h
Serialisers/StringPropertySerialiser.cpp
Serialisers/SetPropertySerialiser.h
Serialisers/SetPropertySerialiser.cpp
Serialisers/StructSerialiser.h
Serialisers/StructSerialiser.cpp
Serialisers/TextPropertySerialiser.h
Serialisers/TextPropertySerialiser.cpp
Serialisers/UnrealPropertySerialiser.h
Serialisers/VectorPropertySerialiser.h
Serialisers/VectorPropertySerialiser.cpp
Serialisers/Vector2DPropertySerialiser.h
Serialisers/Vector2DPropertySerialiser.cpp
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/VectorStructProperty.h
Debug.h
Debug.cpp
UESaveFile.h
UESaveFile.cpp
BinaryReader.h
BinaryReader.cpp
BinaryWriter.h
BinaryWriter.cpp
PropertySerialiser.h
PropertySerialiser.cpp
)
target_link_libraries(UESaveFile PRIVATE
Corrade::Containers
Corrade::Utility
Magnum::Magnum
Logger
)

View file

@ -22,17 +22,20 @@
#include "Debug.h" #include "Debug.h"
Utility::Debug& operator<<(Utility::Debug& debug, const ArrayProperty* prop) { Utility::Debug&
operator<<(Utility::Debug& debug, const ArrayProperty* prop) {
return debug << (*prop->name) << Utility::Debug::nospace << ":" << return debug << (*prop->name) << Utility::Debug::nospace << ":" <<
prop->propertyType << "of" << prop->items.size() << prop->itemType; prop->propertyType << "of" << prop->items.size() << prop->itemType;
} }
Utility::Debug& operator<<(Utility::Debug& debug, const SetProperty* prop) { Utility::Debug&
operator<<(Utility::Debug& debug, const SetProperty* prop) {
return debug << (*prop->name) << Utility::Debug::nospace << ":" << return debug << (*prop->name) << Utility::Debug::nospace << ":" <<
prop->propertyType << "of" << prop->items.size() << prop->itemType; prop->propertyType << "of" << prop->items.size() << prop->itemType;
} }
Utility::Debug& operator<<(Utility::Debug& debug, const GenericStructProperty* prop) { Utility::Debug&
operator<<(Utility::Debug& debug, const GenericStructProperty* prop) {
debug << (*prop->name) << Utility::Debug::nospace << ":" << debug << (*prop->name) << Utility::Debug::nospace << ":" <<
prop->structType << "(" << Utility::Debug::nospace << prop->propertyType << Utility::Debug::nospace << prop->structType << "(" << Utility::Debug::nospace << prop->propertyType << Utility::Debug::nospace <<
") Contents:"; ") Contents:";
@ -42,7 +45,8 @@ Utility::Debug& operator<<(Utility::Debug& debug, const GenericStructProperty* p
return debug; return debug;
} }
Utility::Debug& operator<<(Utility::Debug& debug, const StructProperty* prop) { Utility::Debug&
operator<<(Utility::Debug& debug, const StructProperty* prop) {
auto cast = dynamic_cast<const GenericStructProperty*>(prop); auto cast = dynamic_cast<const GenericStructProperty*>(prop);
if(cast) { if(cast) {
return debug << cast; return debug << cast;
@ -52,7 +56,8 @@ Utility::Debug& operator<<(Utility::Debug& debug, const StructProperty* prop) {
prop->structType << "(" << Utility::Debug::nospace << prop->propertyType << Utility::Debug::nospace << ")"; prop->structType << "(" << Utility::Debug::nospace << prop->propertyType << Utility::Debug::nospace << ")";
} }
Utility::Debug& operator<<(Utility::Debug& debug, const UnrealPropertyBase* prop) { Utility::Debug&
operator<<(Utility::Debug& debug, const UnrealPropertyBase* prop) {
if(prop->propertyType == "ArrayProperty") { if(prop->propertyType == "ArrayProperty") {
auto array_prop = dynamic_cast<const ArrayProperty*>(prop); auto array_prop = dynamic_cast<const ArrayProperty*>(prop);
if(array_prop) { if(array_prop) {

View file

@ -67,12 +67,14 @@ PropertySerialiser::PropertySerialiser() {
arrayAppend(_collectionSerialisers, Containers::pointer<StructSerialiser>()); arrayAppend(_collectionSerialisers, Containers::pointer<StructSerialiser>());
} }
auto PropertySerialiser::instance() -> PropertySerialiser& { PropertySerialiser&
PropertySerialiser::instance() {
static PropertySerialiser serialiser; static PropertySerialiser serialiser;
return serialiser; return serialiser;
} }
auto PropertySerialiser::read(BinaryReader& reader) -> UnrealPropertyBase::ptr { UnrealPropertyBase::ptr
PropertySerialiser::read(BinaryReader& reader) {
if(reader.peekChar() < 0 || reader.eof()) { if(reader.peekChar() < 0 || reader.eof()) {
return nullptr; return nullptr;
} }
@ -91,16 +93,18 @@ auto PropertySerialiser::read(BinaryReader& reader) -> UnrealPropertyBase::ptr {
return nullptr; return nullptr;
} }
UnsignedLong value_length; std::size_t value_length;
if(!reader.readUnsignedLong(value_length)) { if(!reader.readUint64(value_length)) {
return nullptr; return nullptr;
} }
return deserialise(std::move(name), std::move(type), value_length, reader); return deserialise(std::move(name), std::move(type), value_length, reader);
} }
auto PropertySerialiser::readItem(BinaryReader& reader, Containers::String type, UnsignedLong value_length, UnrealPropertyBase::ptr
Containers::String name) -> UnrealPropertyBase::ptr { PropertySerialiser::readItem(BinaryReader& reader, Containers::String type, std::size_t value_length,
Containers::String name)
{
if(reader.peekChar() < 0 || reader.eof()) { if(reader.peekChar() < 0 || reader.eof()) {
return nullptr; return nullptr;
} }
@ -108,9 +112,8 @@ auto PropertySerialiser::readItem(BinaryReader& reader, Containers::String type,
return deserialise(std::move(name), std::move(type), value_length, reader); return deserialise(std::move(name), std::move(type), value_length, reader);
} }
auto PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView item_type, Containers::Array<UnrealPropertyBase::ptr>
UnsignedInt count) -> Containers::Array<UnrealPropertyBase::ptr> PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView item_type, std::uint32_t count) {
{
if(reader.peekChar() < 0 || reader.eof()) { if(reader.peekChar() < 0 || reader.eof()) {
return nullptr; return nullptr;
} }
@ -130,8 +133,8 @@ auto PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView it
return nullptr; return nullptr;
} }
UnsignedLong value_length; std::size_t value_length;
if(!reader.readUnsignedLong(value_length)) { if(!reader.readUint64(value_length)) {
return nullptr; return nullptr;
} }
@ -144,8 +147,8 @@ auto PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView it
} }
} }
else { else {
for(UnsignedInt i = 0; i < count; i++) { for(std::uint32_t i = 0; i < count; i++) {
auto item = readItem(reader, item_type, UnsignedLong(-1), ""); auto item = readItem(reader, item_type, std::size_t(-1), "");
arrayAppend(array, std::move(item)); arrayAppend(array, std::move(item));
} }
} }
@ -153,8 +156,9 @@ auto PropertySerialiser::readSet(BinaryReader& reader, Containers::StringView it
return array; return array;
} }
auto PropertySerialiser::deserialise(Containers::String name, Containers::String type, UnsignedLong value_length, UnrealPropertyBase::ptr
BinaryReader& reader) -> UnrealPropertyBase::ptr PropertySerialiser::deserialise(Containers::String name, Containers::String type, std::size_t value_length,
BinaryReader& reader)
{ {
UnrealPropertyBase::ptr prop; UnrealPropertyBase::ptr prop;
auto serialiser = getSerialiser(type); auto serialiser = getSerialiser(type);
@ -176,8 +180,8 @@ auto PropertySerialiser::deserialise(Containers::String name, Containers::String
return prop; return prop;
} }
auto PropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, Containers::StringView item_type, bool PropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, Containers::StringView item_type,
UnsignedLong& bytes_written, BinaryWriter& writer) -> bool std::size_t& bytes_written, BinaryWriter& writer)
{ {
auto serialiser = getSerialiser(item_type); auto serialiser = getSerialiser(item_type);
if(!serialiser) { if(!serialiser) {
@ -186,7 +190,8 @@ auto PropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, Containers::St
return serialiser->serialise(prop, bytes_written, writer, *this); return serialiser->serialise(prop, bytes_written, writer, *this);
} }
auto PropertySerialiser::write(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool { 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())) { if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast<NoneProperty*>(prop.get())) {
bytes_written += writer.writeUEStringToArray(*prop->name); bytes_written += writer.writeUEStringToArray(*prop->name);
return true; return true;
@ -195,10 +200,10 @@ auto PropertySerialiser::write(UnrealPropertyBase::ptr& prop, UnsignedLong& byte
bytes_written += writer.writeUEStringToArray(*prop->name); bytes_written += writer.writeUEStringToArray(*prop->name);
bytes_written += writer.writeUEStringToArray(prop->propertyType); bytes_written += writer.writeUEStringToArray(prop->propertyType);
UnsignedLong value_length = 0; std::size_t value_length = 0;
UnsignedLong vl_position = writer.arrayPosition(); std::size_t vl_position = writer.arrayPosition();
bytes_written += writer.writeValueToArray<UnsignedLong>(value_length); bytes_written += writer.writeValueToArray<std::size_t>(value_length);
bool ret = serialise(prop, prop->propertyType, value_length, writer); bool ret = serialise(prop, prop->propertyType, value_length, writer);
@ -209,8 +214,9 @@ auto PropertySerialiser::write(UnrealPropertyBase::ptr& prop, UnsignedLong& byte
return ret; return ret;
} }
auto PropertySerialiser::writeItem(UnrealPropertyBase::ptr& prop, Containers::StringView item_type, bool
UnsignedLong& bytes_written, BinaryWriter& writer) -> bool PropertySerialiser::writeItem(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<NoneProperty*>(prop.get())) {
bytes_written += writer.writeUEStringToArray(*prop->name); bytes_written += writer.writeUEStringToArray(*prop->name);
@ -220,9 +226,8 @@ auto PropertySerialiser::writeItem(UnrealPropertyBase::ptr& prop, Containers::St
return serialise(prop, item_type, bytes_written, writer); return serialise(prop, item_type, bytes_written, writer);
} }
auto PropertySerialiser::writeSet(Containers::ArrayView<UnrealPropertyBase::ptr> props, bool PropertySerialiser::writeSet(Containers::ArrayView<UnrealPropertyBase::ptr> props,
Containers::StringView item_type, UnsignedLong& bytes_written, Containers::StringView item_type, std::size_t& bytes_written, BinaryWriter& writer)
BinaryWriter& writer) -> bool
{ {
auto serialiser = getCollectionSerialiser(item_type); auto serialiser = getCollectionSerialiser(item_type);
if(serialiser) { if(serialiser) {
@ -239,7 +244,8 @@ auto PropertySerialiser::writeSet(Containers::ArrayView<UnrealPropertyBase::ptr>
} }
} }
auto PropertySerialiser::getSerialiser(Containers::StringView item_type) -> AbstractUnrealPropertySerialiser* { AbstractUnrealPropertySerialiser*
PropertySerialiser::getSerialiser(Containers::StringView item_type) {
for(auto& item : _serialisers) { for(auto& item : _serialisers) {
for(auto serialiser_type : item->types()) { for(auto serialiser_type : item->types()) {
if(item_type == serialiser_type) { if(item_type == serialiser_type) {
@ -251,7 +257,8 @@ auto PropertySerialiser::getSerialiser(Containers::StringView item_type) -> Abst
return nullptr; return nullptr;
} }
auto PropertySerialiser::getCollectionSerialiser(Containers::StringView item_type) -> AbstractUnrealCollectionPropertySerialiser* { AbstractUnrealCollectionPropertySerialiser*
PropertySerialiser::getCollectionSerialiser(Containers::StringView item_type) {
for(auto& item : _collectionSerialisers) { for(auto& item : _collectionSerialisers) {
for(Containers::StringView serialiser_type : item->types()) { for(Containers::StringView serialiser_type : item->types()) {
if(item_type == serialiser_type) { if(item_type == serialiser_type) {

View file

@ -32,28 +32,29 @@ class BinaryWriter;
class PropertySerialiser { class PropertySerialiser {
public: public:
static auto instance() -> PropertySerialiser&; static PropertySerialiser& instance();
auto read(BinaryReader& reader) -> UnrealPropertyBase::ptr; UnrealPropertyBase::ptr read(BinaryReader& reader);
auto readItem(BinaryReader& reader, Containers::String type, UnsignedLong value_length, UnrealPropertyBase::ptr readItem(BinaryReader& reader, Containers::String type, std::size_t value_length,
Containers::String name) -> UnrealPropertyBase::ptr; Containers::String name);
auto readSet(BinaryReader& reader, Containers::StringView item_type, UnsignedInt count) -> Containers::Array<UnrealPropertyBase::ptr>; Containers::Array<UnrealPropertyBase::ptr> readSet(BinaryReader& reader, Containers::StringView item_type,
auto deserialise(Containers::String name, Containers::String type, UnsignedLong value_length, std::uint32_t count);
BinaryReader& reader) -> UnrealPropertyBase::ptr; UnrealPropertyBase::ptr deserialise(Containers::String name, Containers::String type, std::size_t value_length,
BinaryReader& reader);
auto serialise(UnrealPropertyBase::ptr& prop, Containers::StringView item_type, UnsignedLong& bytes_written, bool serialise(UnrealPropertyBase::ptr& prop, Containers::StringView item_type, std::size_t& bytes_written,
BinaryWriter& writer) -> bool; BinaryWriter& writer);
auto write(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool; bool write(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer);
auto writeItem(UnrealPropertyBase::ptr& prop, Containers::StringView item_type, UnsignedLong& bytes_written, bool writeItem(UnrealPropertyBase::ptr& prop, Containers::StringView item_type, std::size_t& bytes_written,
BinaryWriter& writer) -> bool; BinaryWriter& writer);
auto writeSet(Containers::ArrayView<UnrealPropertyBase::ptr> props, Containers::StringView item_type, bool writeSet(Containers::ArrayView<UnrealPropertyBase::ptr> props, Containers::StringView item_type,
UnsignedLong& bytes_written, BinaryWriter& writer) -> bool; std::size_t& bytes_written, BinaryWriter& writer);
private: private:
PropertySerialiser(); PropertySerialiser();
auto getSerialiser(Containers::StringView item_type) -> AbstractUnrealPropertySerialiser*; AbstractUnrealPropertySerialiser* getSerialiser(Containers::StringView item_type);
auto getCollectionSerialiser(Containers::StringView item_type) -> AbstractUnrealCollectionPropertySerialiser*; AbstractUnrealCollectionPropertySerialiser* getCollectionSerialiser(Containers::StringView item_type);
Containers::Array<AbstractUnrealPropertySerialiser::ptr> _serialisers; Containers::Array<AbstractUnrealPropertySerialiser::ptr> _serialisers;
Containers::Array<AbstractUnrealCollectionPropertySerialiser::ptr> _collectionSerialisers; Containers::Array<AbstractUnrealCollectionPropertySerialiser::ptr> _collectionSerialisers;

View file

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

View file

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

View file

@ -21,12 +21,9 @@
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
#include "../Types/UnrealPropertyBase.h" #include "../Types/UnrealPropertyBase.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
class BinaryReader; class BinaryReader;
class BinaryWriter; class BinaryWriter;
@ -37,10 +34,9 @@ class AbstractUnrealStructSerialiser {
virtual ~AbstractUnrealStructSerialiser() = default; virtual ~AbstractUnrealStructSerialiser() = default;
virtual auto supportsType(Containers::StringView type) -> bool = 0; virtual bool supportsType(Containers::StringView type) = 0;
virtual auto deserialise(BinaryReader& reader) -> UnrealPropertyBase::ptr = 0; virtual UnrealPropertyBase::ptr deserialise(BinaryReader& reader) = 0;
virtual auto serialise(UnrealPropertyBase::ptr& structProp, BinaryWriter& writer, virtual bool serialise(UnrealPropertyBase::ptr& structProp, BinaryWriter& writer, std::size_t& bytes_written) = 0;
UnsignedLong& bytes_written) -> bool = 0;
}; };

View file

@ -23,9 +23,10 @@
#include "ArrayPropertySerialiser.h" #include "ArrayPropertySerialiser.h"
auto ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
Containers::String item_type; Containers::String item_type;
if(!reader.readUEString(item_type)) { if(!reader.readUEString(item_type)) {
@ -39,8 +40,8 @@ auto ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, C
return nullptr; return nullptr;
} }
UnsignedInt item_count; std::uint32_t item_count;
if(!reader.readUnsignedInt(item_count)) { if(!reader.readUint32(item_count)) {
LOG_ERROR_FORMAT("Couldn't read array property {}'s item count.", name); LOG_ERROR_FORMAT("Couldn't read array property {}'s item count.", name);
return nullptr; return nullptr;
} }
@ -52,8 +53,9 @@ auto ArrayPropertySerialiser::deserialiseProperty(Containers::StringView name, C
return prop; return prop;
} }
auto ArrayPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool ArrayPropertySerialiser::serialiseProperty(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<ArrayProperty*>(prop.get());
if(!array_prop) { if(!array_prop) {
@ -63,10 +65,10 @@ auto ArrayPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, U
writer.writeUEStringToArray(array_prop->itemType); writer.writeUEStringToArray(array_prop->itemType);
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
bytes_written += writer.writeValueToArray<UnsignedInt>(UnsignedInt(array_prop->items.size())); bytes_written += writer.writeValueToArray<std::uint32_t>(std::uint32_t(array_prop->items.size()));
UnsignedLong start_pos = writer.arrayPosition(); std::size_t start_pos = writer.arrayPosition();
UnsignedLong dummy_bytes_written = 0; std::size_t dummy_bytes_written = 0;
bool ret = serialiser.writeSet(array_prop->items, array_prop->itemType, dummy_bytes_written, writer); bool ret = serialiser.writeSet(array_prop->items, array_prop->itemType, dummy_bytes_written, writer);
bytes_written += writer.arrayPosition() - start_pos; bytes_written += writer.arrayPosition() - start_pos;

View file

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

View file

@ -20,23 +20,24 @@
#include "BoolPropertySerialiser.h" #include "BoolPropertySerialiser.h"
auto BoolPropertySerialiser::types() -> Containers::ArrayView<const Containers::String> { StringArrayView
BoolPropertySerialiser::types() {
using namespace Containers::Literals; using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"BoolProperty"_s}}; static const Containers::Array<Containers::String> types{InPlaceInit, {"BoolProperty"_s}};
return types; return types;
} }
auto BoolPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, BoolPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr BinaryReader& reader, PropertySerialiser& serialiser)
{ {
if(value_length != 0) { if(value_length != 0) {
LOG_ERROR_FORMAT("Invalid value length for bool property {}. Expected 0, got {} instead.", name, value_length); LOG_ERROR_FORMAT("Invalid value length for bool property {}. Expected 0, got {} instead.", name, value_length);
return nullptr; return nullptr;
} }
Short value; std::int16_t value;
if(!reader.readShort(value)) { if(!reader.readInt16(value)) {
LOG_ERROR_FORMAT("Couldn't read bool property {}'s value.", name); LOG_ERROR_FORMAT("Couldn't read bool property {}'s value.", name);
return nullptr; return nullptr;
} }
@ -52,8 +53,9 @@ auto BoolPropertySerialiser::deserialise(Containers::StringView name, Containers
return prop; return prop;
} }
auto BoolPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool BoolPropertySerialiser::serialise(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<BoolProperty*>(prop.get());
if(!bool_prop) { if(!bool_prop) {
@ -61,7 +63,7 @@ auto BoolPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLo
return false; return false;
} }
writer.writeValueToArray<Short>(Short(bool_prop->value)); writer.writeValueToArray<std::int16_t>(std::int16_t(bool_prop->value));
return true; return true;
} }

View file

@ -29,11 +29,12 @@ class BoolPropertySerialiser : public AbstractUnrealPropertySerialiser {
public: public:
using ptr = Containers::Pointer<BoolPropertySerialiser>; using ptr = Containers::Pointer<BoolPropertySerialiser>;
auto types() -> Containers::ArrayView<const Containers::String> override; StringArrayView types() override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) -> bool override; PropertySerialiser& serialiser) override;
}; };

View file

@ -20,19 +20,20 @@
#include "BytePropertySerialiser.h" #include "BytePropertySerialiser.h"
auto BytePropertySerialiser::types() -> Containers::ArrayView<const Containers::String> { StringArrayView
BytePropertySerialiser::types() {
using namespace Containers::Literals; using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"ByteProperty"_s}}; static const Containers::Array<Containers::String> types{InPlaceInit, {"ByteProperty"_s}};
return types; return types;
} }
auto BytePropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, BytePropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr BinaryReader& reader, PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<ByteProperty>(); auto prop = Containers::pointer<ByteProperty>();
if(value_length != UnsignedLong(-1)) { if(value_length != std::size_t(-1)) {
if(!reader.readUEString(prop->enumType)) { if(!reader.readUEString(prop->enumType)) {
LOG_ERROR_FORMAT("Couldn't read byte property {}'s enum type.", name); LOG_ERROR_FORMAT("Couldn't read byte property {}'s enum type.", name);
return nullptr; return nullptr;
@ -52,8 +53,8 @@ auto BytePropertySerialiser::deserialise(Containers::StringView name, Containers
prop->valueLength = value_length; prop->valueLength = value_length;
//UnsignedInt count = 0; //std::uint32_t count = 0;
//if(!reader.readUnsignedInt(count)) { //if(!reader.readstd::uint32_t(count)) {
// return nullptr; // return nullptr;
//} //}
@ -64,8 +65,9 @@ auto BytePropertySerialiser::deserialise(Containers::StringView name, Containers
return prop; return prop;
} }
auto BytePropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool BytePropertySerialiser::serialise(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<ByteProperty*>(prop.get());
if(!byte_prop) { if(!byte_prop) {
@ -74,10 +76,10 @@ auto BytePropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLo
} }
//writer.writeValueToArray<char>('\0'); //writer.writeValueToArray<char>('\0');
//bytes_written += writer.writeValueToArray<UnsignedInt>(byte_prop->value.size()); //bytes_written += writer.writeValueToArray<std::uint32_t>(byte_prop->value.size());
//bytes_written += writer.writeDataToArray<char>(byte_prop->value); //bytes_written += writer.writeDataToArray<char>(byte_prop->value);
if(byte_prop->valueLength != UnsignedLong(-1)) { if(byte_prop->valueLength != std::size_t(-1)) {
writer.writeUEStringToArray(byte_prop->enumType); writer.writeUEStringToArray(byte_prop->enumType);
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
} }

View file

@ -27,11 +27,12 @@ class BytePropertySerialiser : public AbstractUnrealPropertySerialiser {
public: public:
using ptr = Containers::Pointer<BytePropertySerialiser>; using ptr = Containers::Pointer<BytePropertySerialiser>;
auto types() -> Containers::ArrayView<const Containers::String> override; StringArrayView types() override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) -> bool override; PropertySerialiser& serialiser) override;
}; };

View file

@ -20,9 +20,10 @@
#include "ColourPropertySerialiser.h" #include "ColourPropertySerialiser.h"
auto ColourPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, ColourPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<ColourStructProperty>(); auto prop = Containers::pointer<ColourStructProperty>();
@ -36,8 +37,9 @@ auto ColourPropertySerialiser::deserialiseProperty(Containers::StringView name,
return prop; return prop;
} }
auto ColourPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool ColourPropertySerialiser::serialiseProperty(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<ColourStructProperty*>(prop.get());
if(!colour_prop) { if(!colour_prop) {
@ -45,8 +47,10 @@ auto ColourPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop,
return false; return false;
} }
bytes_written += writer.writeValueToArray<Float>(colour_prop->r) + writer.writeValueToArray<Float>(colour_prop->g) + bytes_written += writer.writeValueToArray<float>(colour_prop->r) +
writer.writeValueToArray<Float>(colour_prop->b) + writer.writeValueToArray<Float>(colour_prop->a); writer.writeValueToArray<float>(colour_prop->g) +
writer.writeValueToArray<float>(colour_prop->b) +
writer.writeValueToArray<float>(colour_prop->a);
return true; return true;
} }

View file

@ -29,8 +29,9 @@ class ColourPropertySerialiser : public UnrealPropertySerialiser<ColourStructPro
using ptr = Containers::Pointer<ColourPropertySerialiser>; using ptr = Containers::Pointer<ColourPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -20,13 +20,14 @@
#include "DateTimePropertySerialiser.h" #include "DateTimePropertySerialiser.h"
auto DateTimePropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, DateTimePropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<DateTimeStructProperty>(); auto prop = Containers::pointer<DateTimeStructProperty>();
if(!reader.readUnsignedLong(prop->timestamp)) { if(!reader.readInt64(prop->timestamp)) {
LOG_ERROR_FORMAT("Couldn't read date/time property {}'s value.", name); LOG_ERROR_FORMAT("Couldn't read date/time property {}'s value.", name);
return nullptr; return nullptr;
} }
@ -34,8 +35,9 @@ auto DateTimePropertySerialiser::deserialiseProperty(Containers::StringView name
return prop; return prop;
} }
auto DateTimePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool DateTimePropertySerialiser::serialiseProperty(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<DateTimeStructProperty*>(prop.get());
if(!dt_prop) { if(!dt_prop) {
@ -43,7 +45,7 @@ auto DateTimePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop
return false; return false;
} }
bytes_written += writer.writeValueToArray<UnsignedLong>(dt_prop->timestamp); bytes_written += writer.writeValueToArray<std::int64_t>(dt_prop->timestamp);
return true; return true;
} }

View file

@ -27,8 +27,9 @@ class DateTimePropertySerialiser : public UnrealPropertySerialiser<DateTimeStruc
using ptr = Containers::Pointer<DateTimePropertySerialiser>; using ptr = Containers::Pointer<DateTimePropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -20,15 +20,16 @@
#include "EnumPropertySerialiser.h" #include "EnumPropertySerialiser.h"
auto EnumPropertySerialiser::types() -> Containers::ArrayView<const Containers::String> { StringArrayView
EnumPropertySerialiser::types() {
using namespace Containers::Literals; using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"EnumProperty"_s}}; static const Containers::Array<Containers::String> types{InPlaceInit, {"EnumProperty"_s}};
return types; return types;
} }
auto EnumPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, EnumPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr BinaryReader& reader, PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<EnumProperty>(); auto prop = Containers::pointer<EnumProperty>();
@ -51,8 +52,9 @@ auto EnumPropertySerialiser::deserialise(Containers::StringView name, Containers
return prop; return prop;
} }
auto EnumPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool EnumPropertySerialiser::serialise(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<EnumProperty*>(prop.get());
if(!enum_prop) { if(!enum_prop) {

View file

@ -27,11 +27,12 @@ class EnumPropertySerialiser : public AbstractUnrealPropertySerialiser {
public: public:
using ptr = Containers::Pointer<EnumPropertySerialiser>; using ptr = Containers::Pointer<EnumPropertySerialiser>;
auto types() -> Containers::ArrayView<const Containers::String> override; StringArrayView types() override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) -> bool override; PropertySerialiser& serialiser) override;
}; };

View file

@ -20,15 +20,16 @@
#include "FloatPropertySerialiser.h" #include "FloatPropertySerialiser.h"
auto FloatPropertySerialiser::types() -> Containers::ArrayView<const Containers::String> { StringArrayView
FloatPropertySerialiser::types() {
using namespace Containers::Literals; using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"FloatProperty"_s}}; static const Containers::Array<Containers::String> types{InPlaceInit, {"FloatProperty"_s}};
return types; return types;
} }
auto FloatPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, FloatPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<FloatProperty>(); auto prop = Containers::pointer<FloatProperty>();
@ -46,8 +47,9 @@ auto FloatPropertySerialiser::deserialise(Containers::StringView name, Container
return prop; return prop;
} }
auto FloatPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool FloatPropertySerialiser::serialise(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<FloatProperty*>(prop.get());
if(!float_prop) { if(!float_prop) {
@ -56,7 +58,7 @@ auto FloatPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedL
} }
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
bytes_written += writer.writeValueToArray<Float>(float_prop->value); bytes_written += writer.writeValueToArray<float>(float_prop->value);
return true; return true;
} }

View file

@ -27,11 +27,12 @@ class FloatPropertySerialiser : public AbstractUnrealPropertySerialiser {
public: public:
using ptr = Containers::Pointer<FloatPropertySerialiser>; using ptr = Containers::Pointer<FloatPropertySerialiser>;
auto types() -> Containers::ArrayView<const Containers::String> override; StringArrayView types() override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) -> bool override; PropertySerialiser& serialiser) override;
}; };

View file

@ -22,9 +22,10 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto GuidPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, GuidPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<GuidStructProperty>(); auto prop = Containers::pointer<GuidStructProperty>();
@ -36,8 +37,9 @@ auto GuidPropertySerialiser::deserialiseProperty(Containers::StringView name, Co
return prop; return prop;
} }
auto GuidPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool GuidPropertySerialiser::serialiseProperty(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<GuidStructProperty*>(prop.get());
if(!guid_prop) { if(!guid_prop) {

View file

@ -27,8 +27,9 @@ class GuidPropertySerialiser : public UnrealPropertySerialiser<GuidStructPropert
using ptr = Containers::Pointer<GuidPropertySerialiser>; using ptr = Containers::Pointer<GuidPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -20,19 +20,20 @@
#include "IntPropertySerialiser.h" #include "IntPropertySerialiser.h"
auto IntPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, IntPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<IntProperty>(); auto prop = Containers::pointer<IntProperty>();
if(value_length == UnsignedLong(-1)) { if(value_length == std::size_t(-1)) {
if(!reader.readInt(prop->value)) { if(!reader.readInt32(prop->value)) {
LOG_ERROR("Couldn't read int property's value."); LOG_ERROR("Couldn't read int property's value.");
return nullptr; return nullptr;
} }
prop->valueLength = UnsignedLong(-1); prop->valueLength = std::size_t(-1);
return prop; return prop;
} }
@ -42,7 +43,7 @@ auto IntPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
return nullptr; return nullptr;
} }
if(!reader.readInt(prop->value)) { if(!reader.readInt32(prop->value)) {
LOG_ERROR_FORMAT("Couldn't read int property {}'s value.", name); LOG_ERROR_FORMAT("Couldn't read int property {}'s value.", name);
return nullptr; return nullptr;
} }
@ -52,8 +53,9 @@ auto IntPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
return prop; return prop;
} }
auto IntPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool IntPropertySerialiser::serialiseProperty(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<IntProperty*>(prop.get());
if(!int_prop) { if(!int_prop) {
@ -61,11 +63,11 @@ auto IntPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, Uns
return false; return false;
} }
if(prop->valueLength != UnsignedLong(-1)) { if(prop->valueLength != std::size_t(-1)) {
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
} }
bytes_written += writer.writeValueToArray<Int>(int_prop->value); bytes_written += writer.writeValueToArray<std::int32_t>(int_prop->value);
return true; return true;
} }

View file

@ -27,8 +27,9 @@ class IntPropertySerialiser : public UnrealPropertySerialiser<IntProperty> {
using ptr = Containers::Pointer<IntPropertySerialiser>; using ptr = Containers::Pointer<IntPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -24,9 +24,10 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<MapProperty>(); auto prop = Containers::pointer<MapProperty>();
@ -46,14 +47,14 @@ auto MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
return nullptr; return nullptr;
} }
UnsignedInt null; std::uint32_t null;
if(!reader.readUnsignedInt(null) || null != 0u) { if(!reader.readUint32(null) || null != 0u) {
LOG_ERROR_FORMAT("Couldn't read a null int in map property {}.", name); LOG_ERROR_FORMAT("Couldn't read a null int in map property {}.", name);
return nullptr; return nullptr;
} }
UnsignedInt count; std::uint32_t count;
if(!reader.readUnsignedInt(count)) { if(!reader.readUint32(count)) {
LOG_ERROR_FORMAT("Couldn't read map property {}'s item count.", name); LOG_ERROR_FORMAT("Couldn't read map property {}'s item count.", name);
return nullptr; return nullptr;
} }
@ -63,7 +64,7 @@ auto MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
arrayReserve(prop->map, count); arrayReserve(prop->map, count);
for(UnsignedInt i = 0; i < count; i++) { for(std::uint32_t i = 0; i < count; i++) {
MapProperty::KeyValuePair pair; MapProperty::KeyValuePair pair;
if(prop->keyType == "IntProperty"_s || prop->keyType == "StrProperty"_s) { if(prop->keyType == "IntProperty"_s || prop->keyType == "StrProperty"_s) {
@ -107,8 +108,9 @@ auto MapPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
return prop; return prop;
} }
auto MapPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool MapPropertySerialiser::serialiseProperty(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<MapProperty*>(prop.get());
if(!map_prop) { if(!map_prop) {
@ -120,12 +122,12 @@ auto MapPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, Uns
writer.writeUEStringToArray(map_prop->valueType); writer.writeUEStringToArray(map_prop->valueType);
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
UnsignedLong value_start = writer.arrayPosition(); std::size_t value_start = writer.arrayPosition();
writer.writeValueToArray<UnsignedInt>(0u); writer.writeValueToArray<std::uint32_t>(0u);
writer.writeValueToArray<UnsignedInt>(UnsignedInt(map_prop->map.size())); writer.writeValueToArray<std::uint32_t>(std::uint32_t(map_prop->map.size()));
UnsignedLong dummy_bytes_written = 0; std::size_t dummy_bytes_written = 0;
for(auto& pair : map_prop->map) { for(auto& pair : map_prop->map) {
if(!serialiser.writeItem(pair.key, map_prop->keyType, dummy_bytes_written, writer)) { if(!serialiser.writeItem(pair.key, map_prop->keyType, dummy_bytes_written, writer)) {
LOG_ERROR("Couldn't write a key."); LOG_ERROR("Couldn't write a key.");

View file

@ -27,8 +27,9 @@ class MapPropertySerialiser : public UnrealPropertySerialiser<MapProperty> {
using ptr = Containers::Pointer<MapPropertySerialiser>; using ptr = Containers::Pointer<MapPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -25,9 +25,10 @@
using namespace Containers::Literals; using namespace Containers::Literals;
auto ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<ResourceItemValue>(); auto prop = Containers::pointer<ResourceItemValue>();
@ -77,8 +78,9 @@ auto ResourcePropertySerialiser::deserialiseProperty(Containers::StringView name
return prop; return prop;
} }
auto ResourcePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool ResourcePropertySerialiser::serialiseProperty(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<ResourceItemValue*>(prop.get());
if(!res_prop) { if(!res_prop) {
@ -88,15 +90,15 @@ auto ResourcePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop
bytes_written += writer.writeUEStringToArray("ID_4_AAE08F17428E229EC7A2209F51081A21"_s) + bytes_written += writer.writeUEStringToArray("ID_4_AAE08F17428E229EC7A2209F51081A21"_s) +
writer.writeUEStringToArray("IntProperty"_s) + writer.writeUEStringToArray("IntProperty"_s) +
writer.writeValueToArray<UnsignedLong>(4ull) + writer.writeValueToArray<std::size_t>(4ull) +
writer.writeValueToArray<char>('\0') + writer.writeValueToArray<char>('\0') +
writer.writeValueToArray<Int>(res_prop->id); writer.writeValueToArray<std::int32_t>(res_prop->id);
bytes_written += writer.writeUEStringToArray("Quantity_3_560F09B5485C365D3041888910019CE3"_s) + bytes_written += writer.writeUEStringToArray("Quantity_3_560F09B5485C365D3041888910019CE3"_s) +
writer.writeUEStringToArray("IntProperty"_s) + writer.writeUEStringToArray("IntProperty"_s) +
writer.writeValueToArray<UnsignedLong>(4ull) + writer.writeValueToArray<std::size_t>(4ull) +
writer.writeValueToArray<char>('\0') + writer.writeValueToArray<char>('\0') +
writer.writeValueToArray<Int>(res_prop->quantity); writer.writeValueToArray<std::int32_t>(res_prop->quantity);
bytes_written += writer.writeUEStringToArray("None"_s); bytes_written += writer.writeUEStringToArray("None"_s);

View file

@ -27,8 +27,9 @@ class ResourcePropertySerialiser : public UnrealPropertySerialiser<ResourceItemV
using ptr = Containers::Pointer<ResourcePropertySerialiser>; using ptr = Containers::Pointer<ResourcePropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -20,9 +20,10 @@
#include "RotatorPropertySerialiser.h" #include "RotatorPropertySerialiser.h"
auto RotatorPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, RotatorPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<RotatorStructProperty>(); auto prop = Containers::pointer<RotatorStructProperty>();
@ -34,8 +35,9 @@ auto RotatorPropertySerialiser::deserialiseProperty(Containers::StringView name,
return prop; return prop;
} }
auto RotatorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool RotatorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{ {
auto rotator = dynamic_cast<RotatorStructProperty*>(prop.get()); auto rotator = dynamic_cast<RotatorStructProperty*>(prop.get());
if(!rotator) { if(!rotator) {
@ -43,8 +45,8 @@ auto RotatorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop,
return false; return false;
} }
bytes_written += writer.writeValueToArray<Float>(rotator->x) + writer.writeValueToArray<Float>(rotator->y) + bytes_written += writer.writeValueToArray<float>(rotator->x) + writer.writeValueToArray<float>(rotator->y) +
writer.writeValueToArray<Float>(rotator->z); writer.writeValueToArray<float>(rotator->z);
return true; return true;
} }

View file

@ -27,8 +27,9 @@ class RotatorPropertySerialiser : public UnrealPropertySerialiser<RotatorStructP
using ptr = Containers::Pointer<RotatorPropertySerialiser>; using ptr = Containers::Pointer<RotatorPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -21,9 +21,10 @@
#include "SetPropertySerialiser.h" #include "SetPropertySerialiser.h"
auto SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
Containers::String item_type; Containers::String item_type;
if(!reader.readUEString(item_type)) { if(!reader.readUEString(item_type)) {
@ -37,14 +38,14 @@ auto SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
return nullptr; return nullptr;
} }
UnsignedInt four_bytes; std::uint32_t four_bytes;
if(!reader.readUnsignedInt(four_bytes) || four_bytes != 0u) { if(!reader.readUint32(four_bytes) || four_bytes != 0u) {
LOG_ERROR_FORMAT("Couldn't read four null bytes in set property {}.", name); LOG_ERROR_FORMAT("Couldn't read four null bytes in set property {}.", name);
return nullptr; return nullptr;
} }
UnsignedInt item_count; std::uint32_t item_count;
if(!reader.readUnsignedInt(item_count)) { if(!reader.readUint32(item_count)) {
LOG_ERROR_FORMAT("Couldn't read set property {}'s item count.", name); LOG_ERROR_FORMAT("Couldn't read set property {}'s item count.", name);
return nullptr; return nullptr;
} }
@ -56,8 +57,9 @@ auto SetPropertySerialiser::deserialiseProperty(Containers::StringView name, Con
return prop; return prop;
} }
auto SetPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool SetPropertySerialiser::serialiseProperty(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<SetProperty*>(prop.get());
if(!set_prop) { if(!set_prop) {
@ -68,11 +70,11 @@ auto SetPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, Uns
writer.writeUEStringToArray(set_prop->itemType); writer.writeUEStringToArray(set_prop->itemType);
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
bytes_written += writer.writeValueToArray<UnsignedInt>(0u); bytes_written += writer.writeValueToArray<std::uint32_t>(0u);
bytes_written += writer.writeValueToArray<UnsignedInt>(UnsignedInt(set_prop->items.size())); bytes_written += writer.writeValueToArray<std::uint32_t>(std::uint32_t(set_prop->items.size()));
UnsignedLong start_pos = writer.arrayPosition(); std::size_t start_pos = writer.arrayPosition();
UnsignedLong dummy_bytes_written = 0; std::size_t dummy_bytes_written = 0;
serialiser.writeSet(set_prop->items, set_prop->itemType, dummy_bytes_written, writer); serialiser.writeSet(set_prop->items, set_prop->itemType, dummy_bytes_written, writer);
bytes_written += writer.arrayPosition() - start_pos; bytes_written += writer.arrayPosition() - start_pos;

View file

@ -27,8 +27,9 @@ class SetPropertySerialiser : public UnrealPropertySerialiser<SetProperty> {
using ptr = Containers::Pointer<SetPropertySerialiser>; using ptr = Containers::Pointer<SetPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -20,21 +20,22 @@
#include "StringPropertySerialiser.h" #include "StringPropertySerialiser.h"
auto StringPropertySerialiser::types() -> Containers::ArrayView<const Containers::String> { StringArrayView
StringPropertySerialiser::types() {
using namespace Containers::Literals; using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, static const Containers::Array<Containers::String> types{InPlaceInit, {
{"NameProperty"_s, "StrProperty"_s, "NameProperty"_s, "StrProperty"_s, "SoftObjectProperty"_s, "ObjectProperty"_s
"SoftObjectProperty"_s, "ObjectProperty"_s}}; }};
return types; return types;
} }
auto StringPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, StringPropertySerialiser::deserialise(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader, PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<StringProperty>(type); auto prop = Containers::pointer<StringProperty>(type);
if(value_length != UnsignedLong(-1)) { if(value_length != std::size_t(-1)) {
char terminator; char terminator;
if(!reader.readChar(terminator) || terminator != '\0') { if(!reader.readChar(terminator) || terminator != '\0') {
LOG_ERROR_FORMAT("Couldn't read a null byte in string property {}.", name); LOG_ERROR_FORMAT("Couldn't read a null byte in string property {}.", name);
@ -52,8 +53,9 @@ auto StringPropertySerialiser::deserialise(Containers::StringView name, Containe
return prop; return prop;
} }
auto StringPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool StringPropertySerialiser::serialise(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<StringProperty*>(prop.get());
if(!str_prop) { if(!str_prop) {
@ -61,7 +63,7 @@ auto StringPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, Unsigned
return false; return false;
} }
if(str_prop->valueLength != UnsignedLong(-1)) { if(str_prop->valueLength != std::size_t(-1)) {
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
} }

View file

@ -27,11 +27,12 @@ class StringPropertySerialiser : public AbstractUnrealPropertySerialiser {
public: public:
using ptr = Containers::Pointer<StringPropertySerialiser>; using ptr = Containers::Pointer<StringPropertySerialiser>;
auto types() -> Containers::ArrayView<const Containers::String> override; StringArrayView types() override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) -> bool override; PropertySerialiser& serialiser) override;
}; };

View file

@ -25,14 +25,16 @@
#include "StructSerialiser.h" #include "StructSerialiser.h"
auto StructSerialiser::types() -> Containers::ArrayView<const Containers::String> { StringArrayView
StructSerialiser::types() {
using namespace Containers::Literals; using namespace Containers::Literals;
static const Containers::Array<Containers::String> types{InPlaceInit, {"StructProperty"_s}}; static const Containers::Array<Containers::String> types{InPlaceInit, {"StructProperty"_s}};
return types; return types;
} }
auto StructSerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, Containers::Array<UnrealPropertyBase::ptr>
UnsignedInt count, BinaryReader& reader, PropertySerialiser& serialiser) -> 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)
{ {
Containers::String item_type; Containers::String item_type;
if(!reader.readUEString(item_type)) { if(!reader.readUEString(item_type)) {
@ -60,10 +62,10 @@ auto StructSerialiser::deserialise(Containers::StringView name, Containers::Stri
prop->structGuid = std::move(guid); prop->structGuid = std::move(guid);
} }
else { else {
for(UnsignedInt i = 0; i < count; i++) { for(std::uint32_t i = 0; i < count; i++) {
auto prop = Containers::pointer<UnrealPropertyBase>(); auto prop = Containers::pointer<UnrealPropertyBase>();
prop = serialiser.readItem(reader, item_type, UnsignedLong(-1), name); prop = serialiser.readItem(reader, item_type, std::size_t(-1), name);
if(!prop) { if(!prop) {
prop = readStructValue(name, item_type, value_length, reader, serialiser); prop = readStructValue(name, item_type, value_length, reader, serialiser);
@ -83,8 +85,9 @@ auto StructSerialiser::deserialise(Containers::StringView name, Containers::Stri
return array; return array;
} }
auto StructSerialiser::deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr StructSerialiser::deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{ {
Containers::String item_type; Containers::String item_type;
if(!reader.readUEString(item_type)) { if(!reader.readUEString(item_type)) {
@ -120,13 +123,14 @@ auto StructSerialiser::deserialise(Containers::StringView name, Containers::Stri
return prop; return prop;
} }
auto StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr> props, Containers::StringView item_type, bool
UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr> 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(*(props.front()->name));
bytes_written += writer.writeUEStringToArray(item_type); bytes_written += writer.writeUEStringToArray(item_type);
UnsignedLong vl_pos = writer.arrayPosition(); std::size_t vl_pos = writer.arrayPosition();
bytes_written += writer.writeValueToArray<UnsignedLong>(0ull); bytes_written += writer.writeValueToArray<std::size_t>(0ull);
auto struct_prop = dynamic_cast<StructProperty*>(props.front().get()); auto struct_prop = dynamic_cast<StructProperty*>(props.front().get());
if(!struct_prop) { if(!struct_prop) {
@ -138,9 +142,9 @@ auto StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr>
bytes_written += writer.writeDataToArray(arrayView(struct_prop->structGuid)); bytes_written += writer.writeDataToArray(arrayView(struct_prop->structGuid));
bytes_written += writer.writeValueToArray<char>('\0'); bytes_written += writer.writeValueToArray<char>('\0');
UnsignedLong vl_start = writer.arrayPosition(); std::size_t vl_start = writer.arrayPosition();
UnsignedLong bytes_written_here = 0; std::size_t bytes_written_here = 0;
for(auto& prop : props) { for(auto& prop : props) {
struct_prop = dynamic_cast<StructProperty*>(prop.get()); struct_prop = dynamic_cast<StructProperty*>(prop.get());
if(!struct_prop) { if(!struct_prop) {
@ -156,15 +160,16 @@ auto StructSerialiser::serialise(Containers::ArrayView<UnrealPropertyBase::ptr>
} }
} }
UnsignedLong vl_stop = writer.arrayPosition() - vl_start; std::size_t vl_stop = writer.arrayPosition() - vl_start;
writer.writeValueToArrayAt(vl_stop, vl_pos); writer.writeValueToArrayAt(vl_stop, vl_pos);
bytes_written += vl_stop; bytes_written += vl_stop;
return true; return true;
} }
auto StructSerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool StructSerialiser::serialise(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<StructProperty*>(prop.get());
if(!struct_prop) { if(!struct_prop) {
@ -177,8 +182,8 @@ auto StructSerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& by
writer.writeValueToArray<char>('\0'); writer.writeValueToArray<char>('\0');
if(!serialiser.writeItem(prop, struct_prop->structType, bytes_written, writer)) { if(!serialiser.writeItem(prop, struct_prop->structType, bytes_written, writer)) {
UnsignedLong dummy_bytes_written = 0; std::size_t dummy_bytes_written = 0;
UnsignedLong vl_start = writer.arrayPosition(); std::size_t vl_start = writer.arrayPosition();
if(!writeStructValue(struct_prop, dummy_bytes_written, writer, serialiser)) { if(!writeStructValue(struct_prop, dummy_bytes_written, writer, serialiser)) {
LOG_ERROR("Couldn't write the struct value."); LOG_ERROR("Couldn't write the struct value.");
return false; return false;
@ -189,8 +194,9 @@ auto StructSerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& by
return true; return true;
} }
auto StructSerialiser::readStructValue(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, StructProperty::ptr
BinaryReader& reader, PropertySerialiser& serialiser) -> StructProperty::ptr StructSerialiser::readStructValue(Containers::StringView name, Containers::StringView type, std::size_t value_length,
BinaryReader& reader, PropertySerialiser& serialiser)
{ {
auto st_prop = Containers::pointer<GenericStructProperty>(); auto st_prop = Containers::pointer<GenericStructProperty>();
st_prop->structType = type; st_prop->structType = type;
@ -212,8 +218,9 @@ auto StructSerialiser::readStructValue(Containers::StringView name, Containers::
return st_prop; return st_prop;
} }
auto StructSerialiser::writeStructValue(StructProperty* prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool StructSerialiser::writeStructValue(StructProperty* prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser)
{ {
auto struct_prop = dynamic_cast<GenericStructProperty*>(prop); auto struct_prop = dynamic_cast<GenericStructProperty*>(prop);
if(!struct_prop) { if(!struct_prop) {

View file

@ -29,20 +29,23 @@ class StructSerialiser : public AbstractUnrealPropertySerialiser, public Abstrac
public: public:
using ptr = Containers::Pointer<StructSerialiser>; using ptr = Containers::Pointer<StructSerialiser>;
auto types() -> Containers::ArrayView<const Containers::String> override; StringArrayView types() override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, PropertyArray deserialise(Containers::StringView name, Containers::StringView type, std::size_t value_length,
UnsignedInt count, BinaryReader& reader, PropertySerialiser& serialiser) -> Containers::Array<UnrealPropertyBase::ptr> override; std::uint32_t count, BinaryReader& reader, PropertySerialiser& serialiser) override;
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override;
auto serialise(Containers::ArrayView<UnrealPropertyBase::ptr> props, Containers::StringView item_type, bool serialise(PropertyArrayView props, Containers::StringView item_type, std::size_t& bytes_written,
UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override; BinaryWriter& writer, PropertySerialiser& serialiser) override;
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override; PropertySerialiser& serialiser) override;
private: private:
auto readStructValue(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, StructProperty::ptr readStructValue(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> StructProperty::ptr; std::size_t value_length, BinaryReader& reader,
auto writeStructValue(StructProperty* prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool; PropertySerialiser& serialiser);
bool writeStructValue(StructProperty* prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser);
} ; } ;

View file

@ -21,13 +21,14 @@
#include "TextPropertySerialiser.h" #include "TextPropertySerialiser.h"
auto TextPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, TextPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<TextProperty>(); auto prop = Containers::pointer<TextProperty>();
Long start_position = reader.position(); auto start_position = reader.position();
char terminator; char terminator;
if(!reader.readChar(terminator) || terminator != '\0') { if(!reader.readChar(terminator) || terminator != '\0') {
@ -61,15 +62,16 @@ auto TextPropertySerialiser::deserialiseProperty(Containers::StringView name, Co
arrayAppend(prop->data, std::move(str)); arrayAppend(prop->data, std::move(str));
interval = reader.position() - start_position; interval = reader.position() - start_position;
} while(UnsignedLong(interval) < value_length); } while(std::size_t(interval) < value_length);
prop->value = prop->data.back(); prop->value = prop->data.back();
return prop; return prop;
} }
auto TextPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool TextPropertySerialiser::serialiseProperty(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<TextProperty*>(prop.get());

View file

@ -27,8 +27,9 @@ class TextPropertySerialiser : public UnrealPropertySerialiser<TextProperty> {
using ptr = Containers::Pointer<TextPropertySerialiser>; using ptr = Containers::Pointer<TextPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -32,12 +32,14 @@ class UnrealPropertySerialiser : public AbstractUnrealPropertySerialiser {
public: public:
using ptr = Containers::Pointer<UnrealPropertySerialiser<T>>; using ptr = Containers::Pointer<UnrealPropertySerialiser<T>>;
auto types() -> Containers::ArrayView<const Containers::String> override { StringArrayView types() override {
static const Containers::Array<Containers::String> types = []{ static const Containers::Array<Containers::String> types = []{
Containers::Array<Containers::String> array; Containers::Array<Containers::String> array;
Containers::Pointer<T> p(new T); Containers::Pointer<T> p(new T);
if(std::is_base_of<StructProperty, T>::value) { if(std::is_base_of<StructProperty, T>::value) {
array = Containers::Array<Containers::String>{InPlaceInit, {dynamic_cast<StructProperty*>(p.get())->structType}}; array = Containers::Array<Containers::String>{InPlaceInit, {
dynamic_cast<StructProperty*>(p.get())->structType
}};
} }
else { else {
array = Containers::Array<Containers::String>{InPlaceInit, {p->propertyType}}; array = Containers::Array<Containers::String>{InPlaceInit, {p->propertyType}};
@ -47,23 +49,24 @@ class UnrealPropertySerialiser : public AbstractUnrealPropertySerialiser {
return types; return types;
} }
auto deserialise(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialise(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) override
{ {
return deserialiseProperty(name, type, value_length, reader, serialiser); return deserialiseProperty(name, type, value_length, reader, serialiser);
} }
auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, bool serialise(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) -> bool override PropertySerialiser& serialiser) override
{ {
return serialiseProperty(prop, bytes_written, writer, serialiser); return serialiseProperty(prop, bytes_written, writer, serialiser);
} }
private: private:
virtual auto deserialiseProperty(Containers::StringView name, Containers::StringView type, virtual UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
UnsignedLong value_length, BinaryReader& reader, std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser) -> typename UnrealPropertyBase::ptr = 0; PropertySerialiser& serialiser) = 0;
virtual auto serialiseProperty(typename UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, virtual bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool = 0; PropertySerialiser& serialiser) = 0;
}; };

View file

@ -20,9 +20,10 @@
#include "Vector2DPropertySerialiser.h" #include "Vector2DPropertySerialiser.h"
auto Vector2DPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, Vector2DPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<Vector2DStructProperty>(); auto prop = Containers::pointer<Vector2DStructProperty>();
@ -34,8 +35,9 @@ auto Vector2DPropertySerialiser::deserialiseProperty(Containers::StringView name
return prop; return prop;
} }
auto Vector2DPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool Vector2DPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{ {
auto vector = dynamic_cast<Vector2DStructProperty*>(prop.get()); auto vector = dynamic_cast<Vector2DStructProperty*>(prop.get());
if(!vector) { if(!vector) {
@ -43,7 +45,7 @@ auto Vector2DPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop
return false; return false;
} }
bytes_written += writer.writeValueToArray<Float>(vector->x) + writer.writeValueToArray<Float>(vector->y); bytes_written += writer.writeValueToArray<float>(vector->x) + writer.writeValueToArray<float>(vector->y);
return true; return true;
} }

View file

@ -27,8 +27,9 @@ class Vector2DPropertySerialiser : public UnrealPropertySerialiser<Vector2DStruc
using ptr = Containers::Pointer<Vector2DPropertySerialiser>; using ptr = Containers::Pointer<Vector2DPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -20,9 +20,10 @@
#include "VectorPropertySerialiser.h" #include "VectorPropertySerialiser.h"
auto VectorPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type, UnrealPropertyBase::ptr
UnsignedLong value_length, BinaryReader& reader, VectorPropertySerialiser::deserialiseProperty(Containers::StringView name, Containers::StringView type,
PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr std::size_t value_length, BinaryReader& reader,
PropertySerialiser& serialiser)
{ {
auto prop = Containers::pointer<VectorStructProperty>(); auto prop = Containers::pointer<VectorStructProperty>();
@ -34,8 +35,9 @@ auto VectorPropertySerialiser::deserialiseProperty(Containers::StringView name,
return prop; return prop;
} }
auto VectorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, bool
BinaryWriter& writer, PropertySerialiser& serialiser) -> bool VectorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written,
BinaryWriter& writer, PropertySerialiser& serialiser)
{ {
auto vector = dynamic_cast<VectorStructProperty*>(prop.get()); auto vector = dynamic_cast<VectorStructProperty*>(prop.get());
if(!vector) { if(!vector) {
@ -43,8 +45,8 @@ auto VectorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop,
return false; return false;
} }
bytes_written += writer.writeValueToArray<Float>(vector->x) + writer.writeValueToArray<Float>(vector->y) + bytes_written += writer.writeValueToArray<float>(vector->x) + writer.writeValueToArray<float>(vector->y) +
writer.writeValueToArray<Float>(vector->z); writer.writeValueToArray<float>(vector->z);
return true; return true;
} }

View file

@ -27,8 +27,9 @@ class VectorPropertySerialiser : public UnrealPropertySerialiser<VectorStructPro
using ptr = Containers::Pointer<VectorPropertySerialiser>; using ptr = Containers::Pointer<VectorPropertySerialiser>;
private: private:
auto deserialiseProperty(Containers::StringView name, Containers::StringView type, UnsignedLong value_length, UnrealPropertyBase::ptr deserialiseProperty(Containers::StringView name, Containers::StringView type,
BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override; std::size_t value_length, BinaryReader& reader,
auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) override;
PropertySerialiser& serialiser) -> bool override; bool serialiseProperty(UnrealPropertyBase::ptr& prop, std::size_t& bytes_written, BinaryWriter& writer,
PropertySerialiser& serialiser) override;
}; };

View file

@ -29,5 +29,5 @@ struct ColourStructProperty : public StructProperty {
using namespace Containers::Literals; using namespace Containers::Literals;
structType = "LinearColor"_s; structType = "LinearColor"_s;
} }
Float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f; float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
}; };

View file

@ -19,12 +19,9 @@
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
#include "StructProperty.h" #include "StructProperty.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
struct DateTimeStructProperty : public StructProperty { struct DateTimeStructProperty : public StructProperty {
using ptr = Containers::Pointer<DateTimeStructProperty>; using ptr = Containers::Pointer<DateTimeStructProperty>;
@ -34,5 +31,5 @@ struct DateTimeStructProperty : public StructProperty {
structType = "DateTime"_s; structType = "DateTime"_s;
} }
UnsignedLong timestamp = 0; std::int64_t timestamp = 0;
}; };

View file

@ -19,14 +19,11 @@
#include <Corrade/Containers/Pointer.h> #include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Magnum/Types.h>
#include "UnrealProperty.h" #include "UnrealProperty.h"
using namespace Corrade; using namespace Corrade;
using namespace Magnum;
struct FloatProperty : public UnrealProperty<Float> { struct FloatProperty : public UnrealProperty<float> {
using ptr = Containers::Pointer<FloatProperty>; using ptr = Containers::Pointer<FloatProperty>;
FloatProperty() { FloatProperty() {

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