diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a0aa25a..a1c8e24 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,6 +28,83 @@ set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)
corrade_add_resource(Assets assets.conf)
+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/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/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)
+
add_executable(MassBuilderSaveTool WIN32
main.cpp
SaveTool/SaveTool.h
@@ -78,6 +155,7 @@ target_link_libraries(MassBuilderSaveTool PRIVATE
Magnum::GL
Magnum::Sdl2Application
MagnumIntegration::ImGui
+ UESaveFile
efsw
zip
cpr::cpr
diff --git a/src/UESaveFile/BinaryReader.cpp b/src/UESaveFile/BinaryReader.cpp
new file mode 100644
index 0000000..6a9b942
--- /dev/null
+++ b/src/UESaveFile/BinaryReader.cpp
@@ -0,0 +1,122 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+
+#include "BinaryReader.h"
+
+BinaryReader::BinaryReader(const std::string& filename) {
+ _file = std::fopen(filename.c_str(), "rb");
+
+ if(!_file) {
+ Utility::Error{} << "Couldn't open" << filename.c_str() << "for reading:\n"
+ << std::strerror(errno);
+ }
+}
+
+BinaryReader::~BinaryReader() {
+ closeFile();
+}
+
+auto BinaryReader::open() -> bool {
+ return _file;
+}
+
+auto BinaryReader::eof() -> bool {
+ return std::feof(_file) != 0;
+}
+
+auto BinaryReader::position() -> Long {
+ return _ftelli64(_file);
+}
+
+void BinaryReader::closeFile() {
+ std::fclose(_file);
+ _file = nullptr;
+}
+
+auto BinaryReader::readChar(char& value) -> bool {
+ return std::fread(&value, sizeof(char), 1, _file) == 1;
+}
+
+auto BinaryReader::readByte(Byte& value) -> bool {
+ return std::fread(&value, sizeof(Byte), 1, _file) == 1;
+}
+
+auto BinaryReader::readUnsignedByte(UnsignedByte& value) -> bool {
+ return std::fread(&value, sizeof(UnsignedByte), 1, _file) == 1;
+}
+
+auto BinaryReader::readShort(Short& value) -> bool {
+ return std::fread(&value, sizeof(Short), 1, _file) == 1;
+}
+
+auto BinaryReader::readUnsignedShort(UnsignedShort& value) -> bool {
+ return std::fread(&value, sizeof(UnsignedShort), 1, _file) == 1;
+}
+
+auto BinaryReader::readInt(Int& value) -> bool {
+ return std::fread(&value, sizeof(Int), 1, _file) == 1;
+}
+
+auto BinaryReader::readUnsignedInt(UnsignedInt& value) -> bool {
+ return std::fread(&value, sizeof(UnsignedInt), 1, _file) == 1;
+}
+
+auto BinaryReader::readLong(Long& value) -> bool {
+ return std::fread(&value, sizeof(Long), 1, _file) == 1;
+}
+
+auto BinaryReader::readUnsignedLong(UnsignedLong& value) -> bool {
+ return std::fread(&value, sizeof(UnsignedLong), 1, _file) == 1;
+}
+
+auto BinaryReader::readFloat(Float& value) -> bool {
+ return std::fread(&value, sizeof(Float), 1, _file) == 1;
+}
+
+auto BinaryReader::readDouble(Double& value) -> bool {
+ return std::fread(&value, sizeof(Double), 1, _file) == 1;
+}
+
+auto BinaryReader::readArray(Containers::Array& array, std::size_t count) -> bool {
+ if(array.size() < count) {
+ array = Containers::Array{ValueInit, count};
+ }
+
+ return std::fread(array.data(), sizeof(char), count, _file) == count;
+}
+
+auto BinaryReader::readUEString(std::string& str) -> bool {
+ UnsignedInt length = 0;
+ if(!readUnsignedInt(length) || length == 0) {
+ return false;
+ }
+
+ str = std::string{};
+ str.resize(length - 1);
+
+ return std::fread(&str[0], sizeof(char), length, _file) == length;
+}
+
+auto BinaryReader::peekChar() -> Int {
+ Int c;
+ c = std::fgetc(_file);
+ std::ungetc(c, _file);
+ return c;
+}
diff --git a/src/UESaveFile/BinaryReader.h b/src/UESaveFile/BinaryReader.h
new file mode 100644
index 0000000..c2a52b5
--- /dev/null
+++ b/src/UESaveFile/BinaryReader.h
@@ -0,0 +1,65 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+using namespace Corrade;
+using namespace Magnum;
+
+class BinaryReader {
+ public:
+ explicit BinaryReader(const std::string& filename);
+ ~BinaryReader();
+
+ auto open() -> bool;
+ auto eof() -> bool;
+ auto position() -> Long;
+
+ void closeFile();
+
+ auto readChar(char& value) -> bool;
+ auto readByte(Byte& value) -> bool;
+ auto readUnsignedByte(UnsignedByte& value) -> bool;
+ auto readShort(Short& value) -> bool;
+ auto readUnsignedShort(UnsignedShort& value) -> bool;
+ auto readInt(Int& value) -> bool;
+ auto readUnsignedInt(UnsignedInt& value) -> bool;
+ auto readLong(Long& value) -> bool;
+ auto readUnsignedLong(UnsignedLong& value) -> bool;
+ auto readFloat(Float& value) -> bool;
+ auto readDouble(Double& value) -> bool;
+ auto readArray(Containers::Array& array, std::size_t count) -> bool;
+
+ template
+ auto readStaticArray(Containers::StaticArray& array) -> bool {
+ return std::fread(array.data(), sizeof(char), S, _file) == S;
+ }
+
+ auto readUEString(std::string& str) -> bool;
+
+ auto peekChar() -> Int;
+
+ private:
+ std::FILE* _file = nullptr;
+};
diff --git a/src/UESaveFile/BinaryWriter.cpp b/src/UESaveFile/BinaryWriter.cpp
new file mode 100644
index 0000000..76c2b03
--- /dev/null
+++ b/src/UESaveFile/BinaryWriter.cpp
@@ -0,0 +1,133 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+
+#include "BinaryWriter.h"
+
+BinaryWriter::BinaryWriter(const std::string& filename) {
+ _file = std::fopen(filename.c_str(), "wb");
+ if(!_file) {
+ Utility::Error{} << "Couldn't open" << filename.c_str() << "for reading:\n"
+ << std::strerror(errno);
+ }
+}
+
+BinaryWriter::~BinaryWriter() {
+ closeFile();
+}
+
+auto BinaryWriter::open() -> bool {
+ return _file;
+}
+
+void BinaryWriter::closeFile() {
+ std::fflush(_file);
+ std::fclose(_file);
+ _file = nullptr;
+}
+
+auto BinaryWriter::position() -> Long {
+ return _ftelli64(_file);
+}
+
+auto BinaryWriter::arrayPosition() const -> UnsignedLong {
+ return _index;
+}
+
+auto BinaryWriter::flushToFile() -> bool {
+ bool ret = writeArray(_data);
+ std::fflush(_file);
+ _data = Containers::Array{};
+ _index = 0;
+ return ret;
+}
+
+auto BinaryWriter::writeChar(char value) -> bool {
+ return std::fwrite(&value, sizeof(char), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeByte(Byte value) -> bool {
+ return std::fwrite(&value, sizeof(Byte), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeUnsignedByte(UnsignedByte value) -> bool {
+ return std::fwrite(&value, sizeof(UnsignedByte), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeShort(Short value) -> bool {
+ return std::fwrite(&value, sizeof(Short), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeUnsignedShort(UnsignedShort value) -> bool {
+ return std::fwrite(&value, sizeof(UnsignedShort), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeInt(Int value) -> bool {
+ return std::fwrite(&value, sizeof(Int), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeUnsignedInt(UnsignedInt value) -> bool {
+ return std::fwrite(&value, sizeof(UnsignedInt), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeLong(Long value) -> bool {
+ return std::fwrite(&value, sizeof(Long), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeUnsignedLong(UnsignedLong value) -> bool {
+ return std::fwrite(&value, sizeof(UnsignedLong), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeFloat(Float value) -> bool {
+ return std::fwrite(&value, sizeof(Float), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeDouble(Double value) -> bool {
+ return std::fwrite(&value, sizeof(Double), 1, _file) == 1;
+}
+
+auto BinaryWriter::writeArray(Containers::ArrayView array) -> bool {
+ if(array.size() == 0) {
+ return false;
+ }
+
+ return std::fwrite(array.data(), sizeof(char), array.size(), _file) == array.size();
+}
+
+auto BinaryWriter::writeUEString(const std::string& str) -> bool {
+ if(str.length() > UINT32_MAX) {
+ Utility::Error{} << "BinaryWriter::writeUEString(): string is too big.";
+ return false;
+ }
+
+ writeUnsignedInt(static_cast(str.length()) + 1);
+
+ if(str.length() > 0) {
+ std::size_t count = std::fwrite(&str[0], sizeof(char), str.length(), _file);
+ if(count != str.length()) {
+ return false;
+ }
+ }
+ return writeChar('\0');
+}
+
+auto BinaryWriter::writeUEStringToArray(const std::string& value) -> UnsignedLong {
+ Containers::ArrayView view{value.c_str(), value.length()};
+ return writeValueToArray(UnsignedInt(value.length()) + 1u) + writeDataToArray(view) + writeValueToArray('\0');
+}
diff --git a/src/UESaveFile/BinaryWriter.h b/src/UESaveFile/BinaryWriter.h
new file mode 100644
index 0000000..50ea2b7
--- /dev/null
+++ b/src/UESaveFile/BinaryWriter.h
@@ -0,0 +1,99 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+using namespace Corrade;
+using namespace Magnum;
+
+class BinaryWriter {
+ public:
+ explicit BinaryWriter(const std::string& filename);
+ ~BinaryWriter();
+
+ auto open() -> bool;
+
+ void closeFile();
+
+ auto position() -> Long;
+
+ auto arrayPosition() const -> UnsignedLong;
+ auto flushToFile() -> bool;
+
+ auto writeByte(Byte value) -> bool;
+ auto writeChar(char value) -> bool;
+ auto writeUnsignedByte(UnsignedByte value) -> bool;
+ auto writeShort(Short value) -> bool;
+ auto writeUnsignedShort(UnsignedShort value) -> bool;
+ auto writeInt(Int value) -> bool;
+ auto writeUnsignedInt(UnsignedInt value) -> bool;
+ auto writeLong(Long value) -> bool;
+ auto writeUnsignedLong(UnsignedLong value) -> bool;
+ auto writeFloat(Float value) -> bool;
+ auto writeDouble(Double value) -> bool;
+ auto writeArray(Containers::ArrayView array) -> bool;
+
+ template
+ auto writeStaticArray(Containers::StaticArrayView array) -> bool {
+ return std::fwrite(array.data(), sizeof(char), S, _file) == S;
+ }
+
+ auto writeUEString(const std::string& str) -> bool;
+
+ template::value, T, T&>>
+ auto writeValueToArray(U value) -> UnsignedLong {
+ Containers::ArrayView view{&value, 1};
+ return writeDataToArray(view);
+ }
+
+ auto writeUEStringToArray(const std::string& value) -> UnsignedLong;
+
+ template
+ void writeValueToArrayAt(T& value, UnsignedLong position) {
+ Containers::ArrayView view{&value, 1};
+ writeDataToArrayAt(view, position);
+ }
+
+ template
+ auto writeDataToArray(Containers::ArrayView view) -> UnsignedLong {
+ arrayAppend(_data, Containers::arrayCast(view));
+ _index += sizeof(T) * view.size();
+ return sizeof(T) * view.size();
+ }
+
+ template
+ void writeDataToArrayAt(Containers::ArrayView view, UnsignedLong position) {
+ auto casted_view = Containers::arrayCast(view);
+ for(UnsignedLong i = 0; i < casted_view.size(); i++) {
+ _data[position + i] = casted_view[i];
+ }
+ }
+
+ private:
+ FILE* _file = nullptr;
+
+ Containers::Array _data;
+ UnsignedLong _index = 0;
+};
diff --git a/src/UESaveFile/Debug.cpp b/src/UESaveFile/Debug.cpp
new file mode 100644
index 0000000..6d60d35
--- /dev/null
+++ b/src/UESaveFile/Debug.cpp
@@ -0,0 +1,76 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "Types/UnrealPropertyBase.h"
+#include "Types/ArrayProperty.h"
+#include "Types/SetProperty.h"
+#include "Types/StructProperty.h"
+#include "Types/GenericStructProperty.h"
+
+#include "Debug.h"
+
+Utility::Debug& operator<<(Utility::Debug& debug, const ArrayProperty* prop) {
+ return debug << (*prop->name).c_str() << Utility::Debug::nospace << ":" <<
+ prop->propertyType.c_str() << "of" << prop->items.size() << prop->itemType.c_str();
+}
+
+Utility::Debug& operator<<(Utility::Debug& debug, const SetProperty* prop) {
+ return debug << (*prop->name).c_str() << Utility::Debug::nospace << ":" <<
+ prop->propertyType.c_str() << "of" << prop->items.size() << prop->itemType.c_str();
+}
+
+Utility::Debug& operator<<(Utility::Debug& debug, const GenericStructProperty* prop) {
+ debug << (*prop->name).c_str() << Utility::Debug::nospace << ":" <<
+ prop->structType.c_str() << "(" << Utility::Debug::nospace << prop->propertyType.c_str() << Utility::Debug::nospace <<
+ ") Contents:";
+ for(const auto& item : prop->properties) {
+ debug << "\n " << Utility::Debug::nospace << item.get();
+ }
+ return debug;
+}
+
+Utility::Debug& operator<<(Utility::Debug& debug, const StructProperty* prop) {
+ auto cast = dynamic_cast(prop);
+ if(cast) {
+ return debug << cast;
+ }
+
+ return debug << (*prop->name).c_str() << Utility::Debug::nospace << ":" <<
+ prop->structType.c_str() << "(" << Utility::Debug::nospace << prop->propertyType.c_str() << Utility::Debug::nospace << ")";
+}
+
+Utility::Debug& operator<<(Utility::Debug& debug, const UnrealPropertyBase* prop) {
+ if(prop->propertyType == "ArrayProperty") {
+ auto array_prop = dynamic_cast(prop);
+ if(array_prop) {
+ return debug << array_prop;
+ }
+ }
+ else if(prop->propertyType == "SetProperty") {
+ auto set_prop = dynamic_cast(prop);
+ if(set_prop) {
+ return debug << set_prop;
+ }
+ }
+ else if(prop->propertyType == "StructProperty") {
+ auto struct_prop = dynamic_cast(prop);
+ if(struct_prop) {
+ return debug << struct_prop;
+ }
+ }
+
+ return debug << (*prop->name).c_str() << Utility::Debug::nospace << ":" << prop->propertyType.c_str();
+}
diff --git a/src/UESaveFile/Debug.h b/src/UESaveFile/Debug.h
new file mode 100644
index 0000000..016d7e0
--- /dev/null
+++ b/src/UESaveFile/Debug.h
@@ -0,0 +1,33 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+struct ArrayProperty;
+struct SetProperty;
+struct GenericStructProperty;
+struct StructProperty;
+struct UnrealPropertyBase;
+
+using namespace Corrade;
+
+Utility::Debug& operator<<(Utility::Debug& debug, const ArrayProperty* prop);
+Utility::Debug& operator<<(Utility::Debug& debug, const SetProperty* prop);
+Utility::Debug& operator<<(Utility::Debug& debug, const GenericStructProperty* prop);
+Utility::Debug& operator<<(Utility::Debug& debug, const StructProperty* prop);
+Utility::Debug& operator<<(Utility::Debug& debug, const UnrealPropertyBase* prop);
diff --git a/src/UESaveFile/PropertySerialiser.cpp b/src/UESaveFile/PropertySerialiser.cpp
new file mode 100644
index 0000000..4c64756
--- /dev/null
+++ b/src/UESaveFile/PropertySerialiser.cpp
@@ -0,0 +1,252 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include "Serialisers/ArrayPropertySerialiser.h"
+#include "Serialisers/BoolPropertySerialiser.h"
+#include "Serialisers/BytePropertySerialiser.h"
+#include "Serialisers/ColourPropertySerialiser.h"
+#include "Serialisers/DateTimePropertySerialiser.h"
+#include "Serialisers/EnumPropertySerialiser.h"
+#include "Serialisers/FloatPropertySerialiser.h"
+#include "Serialisers/GuidPropertySerialiser.h"
+#include "Serialisers/IntPropertySerialiser.h"
+#include "Serialisers/MapPropertySerialiser.h"
+#include "Serialisers/RotatorPropertySerialiser.h"
+#include "Serialisers/StringPropertySerialiser.h"
+#include "Serialisers/SetPropertySerialiser.h"
+#include "Serialisers/StructSerialiser.h"
+#include "Serialisers/TextPropertySerialiser.h"
+#include "Serialisers/VectorPropertySerialiser.h"
+#include "Serialisers/Vector2DPropertySerialiser.h"
+
+#include "Types/NoneProperty.h"
+
+#include "BinaryReader.h"
+#include "BinaryWriter.h"
+
+#include "PropertySerialiser.h"
+
+
+PropertySerialiser::PropertySerialiser() {
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+ arrayAppend(_serialisers, Containers::pointer());
+
+ arrayAppend(_collectionSerialisers, Containers::pointer());
+}
+
+auto PropertySerialiser::read(BinaryReader& reader) -> UnrealPropertyBase::ptr {
+ if(reader.peekChar() < 0 || reader.eof()) {
+ return nullptr;
+ }
+
+ std::string name;
+ if(!reader.readUEString(name)) {
+ return nullptr;
+ }
+
+ if(name == "None") {
+ return Containers::pointer();
+ }
+
+ std::string type;
+ if(!reader.readUEString(type)) {
+ return nullptr;
+ }
+
+ UnsignedLong value_length;
+ if(!reader.readUnsignedLong(value_length)) {
+ return nullptr;
+ }
+
+ return deserialise(std::move(name), std::move(type), value_length, reader);
+}
+
+auto PropertySerialiser::readItem(BinaryReader& reader, std::string type, UnsignedLong value_length, std::string name) -> UnrealPropertyBase::ptr {
+ if(reader.peekChar() < 0 || reader.eof()) {
+ return nullptr;
+ }
+
+ return deserialise(std::move(name), std::move(type), value_length, reader);
+}
+
+auto PropertySerialiser::readSet(BinaryReader& reader, const std::string& item_type, UnsignedInt count) -> Containers::Array {
+ if(reader.peekChar() < 0 || reader.eof()) {
+ return nullptr;
+ }
+
+ auto serialiser = getCollectionSerialiser(item_type);
+
+ Containers::Array array;
+
+ if(serialiser) {
+ std::string name;
+ if(!reader.readUEString(name)) {
+ return nullptr;
+ }
+
+ std::string type;
+ if(!reader.readUEString(type)) {
+ return nullptr;
+ }
+
+ UnsignedLong value_length;
+ if(!reader.readUnsignedLong(value_length)) {
+ return nullptr;
+ }
+
+ array = serialiser->deserialise(name, type, value_length, count, reader, *this);
+
+ for(auto& item : array) {
+ if(item->name == Containers::NullOpt) {
+ item->name.emplace(name);
+ }
+ }
+ }
+ else {
+ for(UnsignedInt i = 0; i < count; i++) {
+ auto item = readItem(reader, item_type, -1, "");
+ arrayAppend(array, std::move(item));
+ }
+ }
+
+ return array;
+}
+
+auto PropertySerialiser::deserialise(std::string name, std::string type, UnsignedLong value_length,
+ BinaryReader& reader) -> UnrealPropertyBase::ptr
+{
+ UnrealPropertyBase::ptr prop;
+ auto serialiser = getSerialiser(type);
+
+ if(serialiser == nullptr) {
+ return nullptr;
+ }
+
+ prop = serialiser->deserialise(name, type, value_length, reader, *this);
+
+ if(!prop) {
+ !Utility::Error{} << "No prop in" << __func__;
+ return nullptr;
+ }
+
+ prop->name = std::move(name);
+ prop->propertyType = std::move(type);
+
+ return prop;
+}
+
+auto PropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, const std::string& item_type, UnsignedLong& bytes_written,
+ BinaryWriter& writer) -> bool
+{
+ auto serialiser = getSerialiser(item_type);
+ if(!serialiser) {
+ return false;
+ }
+ return serialiser->serialise(prop, bytes_written, writer, *this);
+}
+
+auto PropertySerialiser::write(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool {
+ if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast(prop.get())) {
+ bytes_written += writer.writeUEStringToArray(*prop->name);
+ return true;
+ }
+
+ bytes_written += writer.writeUEStringToArray(*prop->name);
+ bytes_written += writer.writeUEStringToArray(prop->propertyType);
+
+ UnsignedLong value_length = 0;
+ UnsignedLong vl_position = writer.arrayPosition();
+
+ bytes_written += writer.writeValueToArray(value_length);
+
+ bool ret = serialise(prop, prop->propertyType, value_length, writer);
+
+ writer.writeValueToArrayAt(value_length, vl_position);
+
+ bytes_written += value_length;
+
+ return ret;
+}
+
+auto PropertySerialiser::writeItem(UnrealPropertyBase::ptr& prop, const std::string& item_type,
+ UnsignedLong& bytes_written, BinaryWriter& writer) -> bool
+{
+ if(prop->name == "None" && prop->propertyType == "NoneProperty" && dynamic_cast(prop.get())) {
+ bytes_written += writer.writeUEStringToArray(*prop->name);
+ return true;
+ }
+
+ return serialise(prop, item_type, bytes_written, writer);
+}
+
+auto PropertySerialiser::writeSet(Containers::ArrayView props, const std::string& item_type,
+ UnsignedLong& bytes_written, BinaryWriter& writer) -> bool
+{
+ auto serialiser = getCollectionSerialiser(item_type);
+ if(serialiser) {
+ return serialiser->serialise(props, item_type, bytes_written, writer, *this);
+ }
+ else {
+ for(auto& prop : props) {
+ if(!writeItem(prop, item_type, bytes_written, writer)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
+
+auto PropertySerialiser::getSerialiser(const std::string& item_type) -> AbstractUnrealPropertySerialiser* {
+ for(auto& item : _serialisers) {
+ for(const std::string& serialiser_type : item->types()) {
+ if(item_type == serialiser_type) {
+ return item.get();
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+auto PropertySerialiser::getCollectionSerialiser(const std::string& item_type) -> AbstractUnrealCollectionPropertySerialiser* {
+ for(auto& item : _collectionSerialisers) {
+ for(const std::string& serialiser_type : item->types()) {
+ if(item_type == serialiser_type) {
+ return item.get();
+ }
+ }
+ }
+
+ return nullptr;
+}
diff --git a/src/UESaveFile/PropertySerialiser.h b/src/UESaveFile/PropertySerialiser.h
new file mode 100644
index 0000000..8757aea
--- /dev/null
+++ b/src/UESaveFile/PropertySerialiser.h
@@ -0,0 +1,51 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include "Serialisers/AbstractUnrealPropertySerialiser.h"
+#include "Serialisers/AbstractUnrealCollectionPropertySerialiser.h"
+
+#include "Types/UnrealPropertyBase.h"
+
+using namespace Corrade;
+
+class BinaryReader;
+class BinaryWriter;
+
+class PropertySerialiser {
+ public:
+ PropertySerialiser();
+
+ auto read(BinaryReader& reader) -> UnrealPropertyBase::ptr;
+ auto readItem(BinaryReader& reader, std::string type, UnsignedLong value_length, std::string name) -> UnrealPropertyBase::ptr;
+ auto readSet(BinaryReader& reader, const std::string& item_type, UnsignedInt count) -> Containers::Array;
+ auto deserialise(std::string name, std::string type, UnsignedLong value_length, BinaryReader& reader) -> UnrealPropertyBase::ptr;
+
+ auto serialise(UnrealPropertyBase::ptr& prop, const std::string& item_type, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool;
+ auto write(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool;
+ auto writeItem(UnrealPropertyBase::ptr& prop, const std::string& item_type, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool;
+ auto writeSet(Containers::ArrayView props, const std::string& item_type, UnsignedLong& bytes_written, BinaryWriter& writer) -> bool;
+
+ private:
+ auto getSerialiser(const std::string& item_type) -> AbstractUnrealPropertySerialiser*;
+ auto getCollectionSerialiser(const std::string& item_type) -> AbstractUnrealCollectionPropertySerialiser*;
+
+ Containers::Array _serialisers;
+ Containers::Array _collectionSerialisers;
+};
diff --git a/src/UESaveFile/Serialisers/AbstractUnrealCollectionPropertySerialiser.h b/src/UESaveFile/Serialisers/AbstractUnrealCollectionPropertySerialiser.h
new file mode 100644
index 0000000..df004d4
--- /dev/null
+++ b/src/UESaveFile/Serialisers/AbstractUnrealCollectionPropertySerialiser.h
@@ -0,0 +1,47 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "../Types/UnrealPropertyBase.h"
+
+using namespace Corrade;
+using namespace Magnum;
+
+class BinaryReader;
+class BinaryWriter;
+class PropertySerialiser;
+
+class AbstractUnrealCollectionPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ virtual ~AbstractUnrealCollectionPropertySerialiser() = default;
+
+ virtual auto types() -> Containers::ArrayView = 0;
+
+ virtual auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, UnsignedInt count, BinaryReader& reader, PropertySerialiser& serialiser) -> Containers::Array = 0;
+
+ virtual auto serialise(Containers::ArrayView props, const std::string& item_type, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool = 0;
+};
diff --git a/src/UESaveFile/Serialisers/AbstractUnrealPropertySerialiser.h b/src/UESaveFile/Serialisers/AbstractUnrealPropertySerialiser.h
new file mode 100644
index 0000000..6605550
--- /dev/null
+++ b/src/UESaveFile/Serialisers/AbstractUnrealPropertySerialiser.h
@@ -0,0 +1,46 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+#include
+
+#include
+
+#include "../Types/UnrealPropertyBase.h"
+
+using namespace Corrade;
+using namespace Magnum;
+
+class BinaryReader;
+class BinaryWriter;
+class PropertySerialiser;
+
+class AbstractUnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ virtual ~AbstractUnrealPropertySerialiser() = default;
+
+ virtual auto types() -> Containers::ArrayView = 0;
+
+ virtual auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr = 0;
+
+ virtual auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool = 0;
+};
diff --git a/src/UESaveFile/Serialisers/AbstractUnrealStructSerialiser.h b/src/UESaveFile/Serialisers/AbstractUnrealStructSerialiser.h
new file mode 100644
index 0000000..e52175b
--- /dev/null
+++ b/src/UESaveFile/Serialisers/AbstractUnrealStructSerialiser.h
@@ -0,0 +1,46 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "../Types/UnrealPropertyBase.h"
+
+using namespace Corrade;
+using namespace Magnum;
+
+class BinaryReader;
+class BinaryWriter;
+
+class AbstractUnrealStructSerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ virtual ~AbstractUnrealStructSerialiser() = default;
+
+ virtual auto supportsType(const std::string& type) -> bool = 0;
+
+ virtual auto deserialise(BinaryReader& reader) -> UnrealPropertyBase::ptr = 0;
+
+ virtual auto serialise(UnrealPropertyBase::ptr& structProp, BinaryWriter& writer, UnsignedLong& bytes_written) -> bool = 0;
+};
diff --git a/src/UESaveFile/Serialisers/ArrayPropertySerialiser.cpp b/src/UESaveFile/Serialisers/ArrayPropertySerialiser.cpp
new file mode 100644
index 0000000..70cff56
--- /dev/null
+++ b/src/UESaveFile/Serialisers/ArrayPropertySerialiser.cpp
@@ -0,0 +1,66 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+#include "../PropertySerialiser.h"
+
+#include "ArrayPropertySerialiser.h"
+
+auto ArrayPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ std::string item_type;
+ if(!reader.readUEString(item_type)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ UnsignedInt item_count;
+ if(!reader.readUnsignedInt(item_count)) {
+ return nullptr;
+ }
+
+ auto prop = Containers::pointer();
+ prop->itemType = std::move(item_type);
+ prop->items = serialiser.readSet(reader, prop->itemType, item_count);
+
+ return prop;
+}
+
+auto ArrayPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto array_prop = dynamic_cast(prop.get());
+ if(!array_prop) {
+ return false;
+ }
+
+ writer.writeUEStringToArray(array_prop->itemType);
+ writer.writeValueToArray('\0');
+ bytes_written += writer.writeValueToArray(UnsignedInt(array_prop->items.size()));
+
+ UnsignedLong start_pos = writer.arrayPosition();
+ UnsignedLong dummy_bytes_written = 0;
+ bool ret = serialiser.writeSet(array_prop->items, array_prop->itemType, dummy_bytes_written, writer);
+ bytes_written += writer.arrayPosition() - start_pos;
+
+ return ret;
+}
diff --git a/src/UESaveFile/Serialisers/ArrayPropertySerialiser.h b/src/UESaveFile/Serialisers/ArrayPropertySerialiser.h
new file mode 100644
index 0000000..f05db71
--- /dev/null
+++ b/src/UESaveFile/Serialisers/ArrayPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/ArrayProperty.h"
+
+class ArrayPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/BoolPropertySerialiser.cpp b/src/UESaveFile/Serialisers/BoolPropertySerialiser.cpp
new file mode 100644
index 0000000..10e761f
--- /dev/null
+++ b/src/UESaveFile/Serialisers/BoolPropertySerialiser.cpp
@@ -0,0 +1,61 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "BoolPropertySerialiser.h"
+
+auto BoolPropertySerialiser::types() -> Containers::ArrayView {
+ static const Containers::Array types{InPlaceInit, {"BoolProperty"}};
+ return types;
+}
+
+auto BoolPropertySerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ if(value_length != 0) {
+ return nullptr;
+ }
+
+ Short value;
+ if(!reader.readShort(value)) {
+ return nullptr;
+ }
+
+ if(value > 1 || value < 0) {
+ return nullptr;
+ }
+
+ auto prop = Containers::pointer();
+ prop->value = value;
+
+ return prop;
+}
+
+auto BoolPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto bool_prop = dynamic_cast(prop.get());
+
+ if(!bool_prop) {
+ return false;
+ }
+
+ writer.writeValueToArray(Short(bool_prop->value));
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/BoolPropertySerialiser.h b/src/UESaveFile/Serialisers/BoolPropertySerialiser.h
new file mode 100644
index 0000000..1b0bb3d
--- /dev/null
+++ b/src/UESaveFile/Serialisers/BoolPropertySerialiser.h
@@ -0,0 +1,32 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "AbstractUnrealPropertySerialiser.h"
+
+#include "../Types/BoolProperty.h"
+
+class BoolPropertySerialiser : public AbstractUnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ auto types() -> Containers::ArrayView override;
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/BytePropertySerialiser.cpp b/src/UESaveFile/Serialisers/BytePropertySerialiser.cpp
new file mode 100644
index 0000000..4cc597f
--- /dev/null
+++ b/src/UESaveFile/Serialisers/BytePropertySerialiser.cpp
@@ -0,0 +1,75 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "BytePropertySerialiser.h"
+
+auto BytePropertySerialiser::types() -> Containers::ArrayView {
+ static const Containers::Array types{InPlaceInit, {"ByteProperty"}};
+ return types;
+}
+
+auto BytePropertySerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readUEString(prop->enumType)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ if(!reader.readUEString(prop->enumValue)) {
+ return nullptr;
+ }
+
+ //UnsignedInt count = 0;
+ //if(!reader.readUnsignedInt(count)) {
+ // return nullptr;
+ //}
+
+ //if(!reader.readArray(prop->value, count)) {
+ // return nullptr;
+ //}
+
+ return prop;
+}
+
+auto BytePropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto byte_prop = dynamic_cast(prop.get());
+
+ if(!byte_prop) {
+ return false;
+ }
+
+ //writer.writeValueToArray('\0');
+ //bytes_written += writer.writeValueToArray(byte_prop->value.size());
+ //bytes_written += writer.writeDataToArray(byte_prop->value);
+
+ writer.writeUEStringToArray(byte_prop->enumType);
+ writer.writeValueToArray('\0');
+ bytes_written += writer.writeUEStringToArray(byte_prop->enumValue);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/BytePropertySerialiser.h b/src/UESaveFile/Serialisers/BytePropertySerialiser.h
new file mode 100644
index 0000000..3fd882d
--- /dev/null
+++ b/src/UESaveFile/Serialisers/BytePropertySerialiser.h
@@ -0,0 +1,32 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "AbstractUnrealPropertySerialiser.h"
+
+#include "../Types/ByteProperty.h"
+
+class BytePropertySerialiser : public AbstractUnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ auto types() -> Containers::ArrayView override;
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/ColourPropertySerialiser.cpp b/src/UESaveFile/Serialisers/ColourPropertySerialiser.cpp
new file mode 100644
index 0000000..befd069
--- /dev/null
+++ b/src/UESaveFile/Serialisers/ColourPropertySerialiser.cpp
@@ -0,0 +1,49 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "ColourPropertySerialiser.h"
+
+auto ColourPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readFloat(prop->r) || !reader.readFloat(prop->g) ||
+ !reader.readFloat(prop->b) || !reader.readFloat(prop->a))
+ {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto ColourPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto colour_prop = dynamic_cast(prop.get());
+
+ if(!colour_prop) {
+ return false;
+ }
+
+ bytes_written += writer.writeValueToArray(colour_prop->r) + writer.writeValueToArray(colour_prop->g) +
+ writer.writeValueToArray(colour_prop->b) + writer.writeValueToArray(colour_prop->a);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/ColourPropertySerialiser.h b/src/UESaveFile/Serialisers/ColourPropertySerialiser.h
new file mode 100644
index 0000000..f858739
--- /dev/null
+++ b/src/UESaveFile/Serialisers/ColourPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/ColourStructProperty.h"
+
+class ColourPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/DateTimePropertySerialiser.cpp b/src/UESaveFile/Serialisers/DateTimePropertySerialiser.cpp
new file mode 100644
index 0000000..615449e
--- /dev/null
+++ b/src/UESaveFile/Serialisers/DateTimePropertySerialiser.cpp
@@ -0,0 +1,46 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "DateTimePropertySerialiser.h"
+
+auto DateTimePropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readUnsignedLong(prop->timestamp)) {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto DateTimePropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto dt_prop = dynamic_cast(prop.get());
+
+ if(!dt_prop) {
+ return false;
+ }
+
+ bytes_written += writer.writeValueToArray(dt_prop->timestamp);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/DateTimePropertySerialiser.h b/src/UESaveFile/Serialisers/DateTimePropertySerialiser.h
new file mode 100644
index 0000000..b0e43ac
--- /dev/null
+++ b/src/UESaveFile/Serialisers/DateTimePropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/DateTimeStructProperty.h"
+
+class DateTimePropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/EnumPropertySerialiser.cpp b/src/UESaveFile/Serialisers/EnumPropertySerialiser.cpp
new file mode 100644
index 0000000..cd7364c
--- /dev/null
+++ b/src/UESaveFile/Serialisers/EnumPropertySerialiser.cpp
@@ -0,0 +1,62 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "EnumPropertySerialiser.h"
+
+auto EnumPropertySerialiser::types() -> Containers::ArrayView {
+ static const Containers::Array types{InPlaceInit, {"EnumProperty"}};
+ return types;
+}
+
+auto EnumPropertySerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readUEString(prop->enumType)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ if(!reader.readUEString(prop->value)) {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto EnumPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto enum_prop = dynamic_cast(prop.get());
+
+ if(!enum_prop) {
+ return false;
+ }
+
+ writer.writeUEStringToArray(enum_prop->enumType);
+ writer.writeValueToArray('\0');
+ bytes_written += writer.writeUEStringToArray(enum_prop->value);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/EnumPropertySerialiser.h b/src/UESaveFile/Serialisers/EnumPropertySerialiser.h
new file mode 100644
index 0000000..ab4335f
--- /dev/null
+++ b/src/UESaveFile/Serialisers/EnumPropertySerialiser.h
@@ -0,0 +1,32 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "AbstractUnrealPropertySerialiser.h"
+
+#include "../Types/EnumProperty.h"
+
+class EnumPropertySerialiser : public AbstractUnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ auto types() -> Containers::ArrayView override;
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/FloatPropertySerialiser.cpp b/src/UESaveFile/Serialisers/FloatPropertySerialiser.cpp
new file mode 100644
index 0000000..c13a72e
--- /dev/null
+++ b/src/UESaveFile/Serialisers/FloatPropertySerialiser.cpp
@@ -0,0 +1,57 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "FloatPropertySerialiser.h"
+
+auto FloatPropertySerialiser::types() -> Containers::ArrayView {
+ static const Containers::Array types{InPlaceInit, {"FloatProperty"}};
+ return types;
+}
+
+auto FloatPropertySerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ if(!reader.readFloat(prop->value)) {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto FloatPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto float_prop = dynamic_cast(prop.get());
+
+ if(!float_prop) {
+ return false;
+ }
+
+ writer.writeValueToArray('\0');
+ bytes_written += writer.writeValueToArray(float_prop->value);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/FloatPropertySerialiser.h b/src/UESaveFile/Serialisers/FloatPropertySerialiser.h
new file mode 100644
index 0000000..c4e45ab
--- /dev/null
+++ b/src/UESaveFile/Serialisers/FloatPropertySerialiser.h
@@ -0,0 +1,32 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "AbstractUnrealPropertySerialiser.h"
+
+#include "../Types/FloatProperty.h"
+
+class FloatPropertySerialiser : public AbstractUnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ auto types() -> Containers::ArrayView override;
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/GuidPropertySerialiser.cpp b/src/UESaveFile/Serialisers/GuidPropertySerialiser.cpp
new file mode 100644
index 0000000..9fe235b
--- /dev/null
+++ b/src/UESaveFile/Serialisers/GuidPropertySerialiser.cpp
@@ -0,0 +1,47 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "GuidPropertySerialiser.h"
+
+auto GuidPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readStaticArray(prop->guid)) {
+ Utility::Error{} << "Couldn't read guid in" << __func__;
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto GuidPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto guid_prop = dynamic_cast(prop.get());
+
+ if(!guid_prop) {
+ return false;
+ }
+
+ bytes_written += writer.writeDataToArray({guid_prop->guid.data(), guid_prop->guid.size()});
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/GuidPropertySerialiser.h b/src/UESaveFile/Serialisers/GuidPropertySerialiser.h
new file mode 100644
index 0000000..7dd1d67
--- /dev/null
+++ b/src/UESaveFile/Serialisers/GuidPropertySerialiser.h
@@ -0,0 +1,31 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/GuidStructProperty.h"
+
+class GuidPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/IntPropertySerialiser.cpp b/src/UESaveFile/Serialisers/IntPropertySerialiser.cpp
new file mode 100644
index 0000000..5c70d45
--- /dev/null
+++ b/src/UESaveFile/Serialisers/IntPropertySerialiser.cpp
@@ -0,0 +1,66 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "IntPropertySerialiser.h"
+
+auto IntPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(value_length == UnsignedLong(-1)) {
+ if(!reader.readInt(prop->value)) {
+ return nullptr;
+ }
+
+ prop->valueLength = UnsignedLong(-1);
+ return prop;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ if(!reader.readInt(prop->value)) {
+ return nullptr;
+ }
+
+ prop->name.emplace(name);
+
+ return prop;
+}
+
+auto IntPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto int_prop = dynamic_cast(prop.get());
+
+ if(!int_prop) {
+ return false;
+ }
+
+ if(prop->valueLength != UnsignedLong(-1)) {
+ writer.writeValueToArray('\0');
+ }
+
+ bytes_written += writer.writeValueToArray(int_prop->value);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/IntPropertySerialiser.h b/src/UESaveFile/Serialisers/IntPropertySerialiser.h
new file mode 100644
index 0000000..8274299
--- /dev/null
+++ b/src/UESaveFile/Serialisers/IntPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/IntProperty.h"
+
+class IntPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/MapPropertySerialiser.cpp b/src/UESaveFile/Serialisers/MapPropertySerialiser.cpp
new file mode 100644
index 0000000..27b721d
--- /dev/null
+++ b/src/UESaveFile/Serialisers/MapPropertySerialiser.cpp
@@ -0,0 +1,124 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+#include "../PropertySerialiser.h"
+
+#include "../Types/NoneProperty.h"
+
+#include "MapPropertySerialiser.h"
+
+auto MapPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readUEString(prop->keyType)) {
+ return nullptr;
+ }
+
+ if(!reader.readUEString(prop->valueType)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ UnsignedInt null;
+ if(!reader.readUnsignedInt(null) || null != 0u) {
+ return nullptr;
+ }
+
+ UnsignedInt count;
+ if(!reader.readUnsignedInt(count)) {
+ return nullptr;
+ }
+
+ // Begin dirty code because the MapProperty format doesn't seem to match any of the GVAS reading stuff I've found,
+ // so I'm just gonna write stuff that matches the only MapProperty I can find in MB's save files.
+
+ arrayReserve(prop->map, count);
+
+ for(UnsignedInt i = 0; i < count; i++) {
+ MapProperty::KeyValuePair pair;
+
+ if(prop->keyType == "IntProperty") {
+ pair.key = serialiser.readItem(reader, prop->keyType, -1, name);
+ if(pair.key == nullptr) {
+ return nullptr;
+ }
+ }
+ else { // Add other branches depending on key type, should more maps appear in the future.
+ return nullptr;
+ }
+
+ UnrealPropertyBase::ptr value_item;
+ while((value_item = serialiser.read(reader)) != nullptr) {
+ arrayAppend(pair.values, std::move(value_item));
+
+ if(pair.values.back()->name == "None" &&
+ pair.values.back()->propertyType == "NoneProperty" &&
+ dynamic_cast(pair.values.back().get()) != nullptr)
+ {
+ break;
+ }
+ }
+
+ arrayAppend(prop->map, std::move(pair));
+ }
+
+ // End dirty code
+
+ return prop;
+}
+
+auto MapPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto map_prop = dynamic_cast(prop.get());
+ if(!map_prop) {
+ return false;
+ }
+
+ writer.writeUEStringToArray(map_prop->keyType);
+ writer.writeUEStringToArray(map_prop->valueType);
+ writer.writeValueToArray('\0');
+
+ UnsignedLong value_start = writer.arrayPosition();
+ writer.writeValueToArray(0u);
+
+ writer.writeValueToArray(UnsignedInt(map_prop->map.size()));
+
+ UnsignedLong dummy_bytes_written = 0;
+ for(auto& pair : map_prop->map) {
+ if(!serialiser.writeItem(pair.key, map_prop->keyType, dummy_bytes_written, writer)) {
+ return false;
+ }
+
+ for(auto& value : pair.values) {
+ if(!serialiser.write(value, dummy_bytes_written, writer)) {
+ return false;
+ }
+ }
+ }
+
+ bytes_written += (writer.arrayPosition() - value_start);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/MapPropertySerialiser.h b/src/UESaveFile/Serialisers/MapPropertySerialiser.h
new file mode 100644
index 0000000..aba537b
--- /dev/null
+++ b/src/UESaveFile/Serialisers/MapPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/MapProperty.h"
+
+class MapPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/RotatorPropertySerialiser.cpp b/src/UESaveFile/Serialisers/RotatorPropertySerialiser.cpp
new file mode 100644
index 0000000..4be77bf
--- /dev/null
+++ b/src/UESaveFile/Serialisers/RotatorPropertySerialiser.cpp
@@ -0,0 +1,47 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "RotatorPropertySerialiser.h"
+
+auto RotatorPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto RotatorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto rotator = dynamic_cast(prop.get());
+
+ if(!rotator) {
+ return false;
+ }
+
+ bytes_written += writer.writeValueToArray(rotator->x) + writer.writeValueToArray(rotator->y) +
+ writer.writeValueToArray(rotator->z);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/RotatorPropertySerialiser.h b/src/UESaveFile/Serialisers/RotatorPropertySerialiser.h
new file mode 100644
index 0000000..9a7192e
--- /dev/null
+++ b/src/UESaveFile/Serialisers/RotatorPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/RotatorStructProperty.h"
+
+class RotatorPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/SetPropertySerialiser.cpp b/src/UESaveFile/Serialisers/SetPropertySerialiser.cpp
new file mode 100644
index 0000000..7b81683
--- /dev/null
+++ b/src/UESaveFile/Serialisers/SetPropertySerialiser.cpp
@@ -0,0 +1,73 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+#include "../PropertySerialiser.h"
+
+#include "SetPropertySerialiser.h"
+
+auto SetPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ std::string item_type;
+ if(!reader.readUEString(item_type)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ UnsignedInt four_bytes;
+ if(!reader.readUnsignedInt(four_bytes) || four_bytes != 0u) {
+ return nullptr;
+ }
+
+ UnsignedInt item_count;
+ if(!reader.readUnsignedInt(item_count)) {
+ return nullptr;
+ }
+
+ auto prop = Containers::pointer();
+ prop->itemType = std::move(item_type);
+ prop->items = serialiser.readSet(reader, prop->itemType, item_count);
+
+ return prop;
+}
+
+auto SetPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto set_prop = dynamic_cast(prop.get());
+ if(!set_prop) {
+ return false;
+ }
+
+ writer.writeUEStringToArray(set_prop->itemType);
+ writer.writeValueToArray('\0');
+
+ bytes_written += writer.writeValueToArray(0u);
+ bytes_written += writer.writeValueToArray(UnsignedInt(set_prop->items.size()));
+
+ UnsignedLong start_pos = writer.arrayPosition();
+ UnsignedLong dummy_bytes_written = 0;
+ serialiser.writeSet(set_prop->items, set_prop->itemType, dummy_bytes_written, writer);
+ bytes_written += writer.arrayPosition() - start_pos;
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/SetPropertySerialiser.h b/src/UESaveFile/Serialisers/SetPropertySerialiser.h
new file mode 100644
index 0000000..a19f560
--- /dev/null
+++ b/src/UESaveFile/Serialisers/SetPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/SetProperty.h"
+
+class SetPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/StringPropertySerialiser.cpp b/src/UESaveFile/Serialisers/StringPropertySerialiser.cpp
new file mode 100644
index 0000000..c455fd5
--- /dev/null
+++ b/src/UESaveFile/Serialisers/StringPropertySerialiser.cpp
@@ -0,0 +1,64 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "StringPropertySerialiser.h"
+
+auto StringPropertySerialiser::types() -> Containers::ArrayView {
+ static const Containers::Array types{InPlaceInit, {"NameProperty", "StrProperty", "SoftObjectProperty", "ObjectProperty"}};
+ return types;
+}
+
+auto StringPropertySerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer(type);
+
+ if(value_length != UnsignedLong(-1)) {
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+ }
+
+ if(!reader.readUEString(prop->value)) {
+ return nullptr;
+ }
+
+ prop->valueLength = value_length;
+
+ return prop;
+}
+
+auto StringPropertySerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto str_prop = dynamic_cast(prop.get());
+
+ if(!str_prop) {
+ return false;
+ }
+
+ if(str_prop->valueLength != UnsignedLong(-1)) {
+ writer.writeValueToArray('\0');
+ }
+
+ bytes_written += writer.writeUEStringToArray(str_prop->value);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/StringPropertySerialiser.h b/src/UESaveFile/Serialisers/StringPropertySerialiser.h
new file mode 100644
index 0000000..0c9e69b
--- /dev/null
+++ b/src/UESaveFile/Serialisers/StringPropertySerialiser.h
@@ -0,0 +1,32 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "AbstractUnrealPropertySerialiser.h"
+
+#include "../Types/StringProperty.h"
+
+class StringPropertySerialiser : public AbstractUnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ auto types() -> Containers::ArrayView override;
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/StructSerialiser.cpp b/src/UESaveFile/Serialisers/StructSerialiser.cpp
new file mode 100644
index 0000000..58d08d4
--- /dev/null
+++ b/src/UESaveFile/Serialisers/StructSerialiser.cpp
@@ -0,0 +1,210 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+#include "../PropertySerialiser.h"
+
+#include "../Types/GenericStructProperty.h"
+#include "../Types/NoneProperty.h"
+
+#include "StructSerialiser.h"
+
+auto StructSerialiser::types() -> Containers::ArrayView {
+ static const Containers::Array types{InPlaceInit, {"StructProperty"}};
+ return types;
+}
+
+auto StructSerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ UnsignedInt count, BinaryReader& reader, PropertySerialiser& serialiser) -> Containers::Array
+{
+ std::string item_type;
+ if(!reader.readUEString(item_type)) {
+ return nullptr;
+ }
+
+ Containers::StaticArray<16, char> guid{ValueInit};
+ if(!reader.readStaticArray(guid)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ Containers::Array array;
+
+ if(count == 0) {
+ auto prop = Containers::pointer();
+ prop->structType = std::move(item_type);
+ prop->structGuid = std::move(guid);
+ }
+ else {
+ for(UnsignedInt i = 0; i < count; i++) {
+ auto prop = readStructValue(name, item_type, value_length, reader, serialiser);
+
+ if(!prop) {
+ return nullptr;
+ }
+
+ prop->structGuid = guid;
+
+ arrayAppend(array, std::move(prop));
+ }
+ }
+
+ return array;
+}
+
+auto StructSerialiser::deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ std::string item_type;
+ if(!reader.readUEString(item_type)) {
+ return nullptr;
+ }
+
+ if(item_type == "None") {
+ return Containers::pointer();
+ }
+
+ Containers::StaticArray<16, char> guid{ValueInit};
+ if(!reader.readStaticArray(guid)) {
+ return nullptr;
+ }
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ UnrealPropertyBase::ptr prop = serialiser.readItem(reader, item_type, value_length, name);
+
+ if(!prop) {
+ prop = readStructValue(name, item_type, value_length, reader, serialiser);
+ if(prop) {
+ dynamic_cast(prop.get())->structGuid = std::move(guid);
+ }
+ }
+
+ return prop;
+}
+
+auto StructSerialiser::serialise(Containers::ArrayView props, const std::string& item_type,
+ UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ bytes_written += writer.writeUEStringToArray(*(props.front()->name));
+ bytes_written += writer.writeUEStringToArray(item_type);
+ UnsignedLong vl_pos = writer.arrayPosition();
+ bytes_written += writer.writeValueToArray(0ull);
+
+ auto struct_prop = dynamic_cast(props.front().get());
+ if(!struct_prop) {
+ return false;
+ }
+
+ bytes_written += writer.writeUEStringToArray(struct_prop->structType);
+ bytes_written += writer.writeDataToArray(arrayView(struct_prop->structGuid));
+ bytes_written += writer.writeValueToArray('\0');
+
+ UnsignedLong vl_start = writer.arrayPosition();
+
+ UnsignedLong bytes_written_here = 0;
+ for(auto& prop : props) {
+ struct_prop = dynamic_cast(prop.get());
+
+ if(!struct_prop) {
+ return false;
+ }
+
+ if(!writeStructValue(struct_prop, bytes_written_here, writer, serialiser)) {
+ return false;
+ }
+ }
+
+ UnsignedLong vl_stop = writer.arrayPosition() - vl_start;
+ writer.writeValueToArrayAt(vl_stop, vl_pos);
+ bytes_written += vl_stop;
+
+ return true;
+}
+
+auto StructSerialiser::serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto struct_prop = dynamic_cast(prop.get());
+
+ if(!struct_prop) {
+ return false;
+ }
+
+ writer.writeUEStringToArray(struct_prop->structType);
+ writer.writeDataToArray(arrayView(struct_prop->structGuid));
+ writer.writeValueToArray('\0');
+
+ if(!serialiser.writeItem(prop, struct_prop->structType, bytes_written, writer)) {
+ UnsignedLong dummy_bytes_written = 0;
+ UnsignedLong vl_start = writer.arrayPosition();
+ if(!writeStructValue(struct_prop, dummy_bytes_written, writer, serialiser)) {
+ return false;
+ }
+ bytes_written += writer.arrayPosition() - vl_start;
+ }
+
+ return true;
+}
+
+auto StructSerialiser::readStructValue(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> StructProperty::ptr
+{
+ auto st_prop = Containers::pointer();
+ st_prop->structType = type;
+
+ UnrealPropertyBase::ptr prop;
+ while((prop = serialiser.read(reader)) != nullptr) {
+ arrayAppend(st_prop->properties, std::move(prop));
+
+ if(st_prop->properties.back()->name == "None" &&
+ st_prop->properties.back()->propertyType == "NoneProperty" &&
+ dynamic_cast(st_prop->properties.back().get()) != nullptr)
+ {
+ break;
+ }
+ }
+
+ st_prop->name.emplace(name);
+
+ return st_prop;
+}
+
+auto StructSerialiser::writeStructValue(StructProperty* prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto struct_prop = dynamic_cast(prop);
+
+ if(!struct_prop) {
+ return false;
+ }
+
+ for(auto& item : struct_prop->properties) {
+ if(!serialiser.write(item, bytes_written, writer)) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/StructSerialiser.h b/src/UESaveFile/Serialisers/StructSerialiser.h
new file mode 100644
index 0000000..e219360
--- /dev/null
+++ b/src/UESaveFile/Serialisers/StructSerialiser.h
@@ -0,0 +1,45 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "AbstractUnrealCollectionPropertySerialiser.h"
+#include "AbstractUnrealPropertySerialiser.h"
+#include "AbstractUnrealStructSerialiser.h"
+
+#include "../Types/StructProperty.h"
+
+class StructSerialiser : public AbstractUnrealPropertySerialiser, public AbstractUnrealCollectionPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ auto types() -> Containers::ArrayView override;
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, UnsignedInt count,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> Containers::Array override;
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+
+ auto serialise(Containers::ArrayView props, const std::string& item_type, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+
+ private:
+ auto readStructValue(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> StructProperty::ptr;
+ auto writeStructValue(StructProperty* prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool;
+};
diff --git a/src/UESaveFile/Serialisers/TextPropertySerialiser.cpp b/src/UESaveFile/Serialisers/TextPropertySerialiser.cpp
new file mode 100644
index 0000000..72a0f54
--- /dev/null
+++ b/src/UESaveFile/Serialisers/TextPropertySerialiser.cpp
@@ -0,0 +1,84 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "TextPropertySerialiser.h"
+
+auto TextPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ Long start_position = reader.position();
+
+ char terminator;
+ if(!reader.readChar(terminator) || terminator != '\0') {
+ return nullptr;
+ }
+
+ if(reader.peekChar() > 0) {
+ if(!reader.readArray(prop->flags, 8)) {
+ return nullptr;
+ }
+ }
+ else {
+ if(!reader.readArray(prop->flags, 4)) {
+ return nullptr;
+ }
+ }
+
+ if(!reader.readChar(prop->id)) {
+ return nullptr;
+ }
+
+ auto interval = reader.position() - start_position;
+
+ do {
+ std::string str;
+
+ if(!reader.readUEString(str)) {
+ return nullptr;
+ }
+
+ arrayAppend(prop->data, std::move(str));
+
+ interval = reader.position() - start_position;
+ } while(UnsignedLong(interval) < value_length);
+
+ prop->value = prop->data.back();
+
+ return prop;
+}
+
+auto TextPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto text_prop = dynamic_cast(prop.get());
+
+ if(!text_prop) {
+ return false;
+ }
+
+ writer.writeValueToArray('\0');
+ bytes_written += writer.writeDataToArray(text_prop->flags);
+ for(const auto& str : text_prop->data) {
+ bytes_written += writer.writeUEStringToArray(str);
+ }
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/TextPropertySerialiser.h b/src/UESaveFile/Serialisers/TextPropertySerialiser.h
new file mode 100644
index 0000000..3b99676
--- /dev/null
+++ b/src/UESaveFile/Serialisers/TextPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/TextProperty.h"
+
+class TextPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/UnrealPropertySerialiser.h b/src/UESaveFile/Serialisers/UnrealPropertySerialiser.h
new file mode 100644
index 0000000..0364908
--- /dev/null
+++ b/src/UESaveFile/Serialisers/UnrealPropertySerialiser.h
@@ -0,0 +1,58 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include "AbstractUnrealPropertySerialiser.h"
+#include "../Types/StructProperty.h"
+
+template
+class UnrealPropertySerialiser : public AbstractUnrealPropertySerialiser {
+ static_assert(std::is_base_of::value, "T must be derived from UnrealPropertyBase.");
+
+ public:
+ using ptr = Containers::Pointer>;
+
+ auto types() -> Containers::ArrayView override {
+ static const Containers::Array types = []{
+ Containers::Array array;
+ Containers::Pointer p(new T);
+ if(std::is_base_of::value) {
+ array = Containers::Array{InPlaceInit, {dynamic_cast(p.get())->structType}};
+ }
+ else {
+ array = Containers::Array{InPlaceInit, {p->propertyType}};
+ }
+ return array;
+ }();
+ return types;
+ }
+
+ auto deserialise(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override {
+ return deserialiseProperty(name, type, value_length, reader, serialiser);
+ }
+
+ auto serialise(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override {
+ return serialiseProperty(prop, bytes_written, writer, serialiser);
+ }
+
+ private:
+ virtual auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> typename UnrealPropertyBase::ptr = 0;
+
+ virtual auto serialiseProperty(typename UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool = 0;
+};
diff --git a/src/UESaveFile/Serialisers/Vector2DPropertySerialiser.cpp b/src/UESaveFile/Serialisers/Vector2DPropertySerialiser.cpp
new file mode 100644
index 0000000..f272d6f
--- /dev/null
+++ b/src/UESaveFile/Serialisers/Vector2DPropertySerialiser.cpp
@@ -0,0 +1,46 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "Vector2DPropertySerialiser.h"
+
+auto Vector2DPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y)) {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto Vector2DPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto vector = dynamic_cast(prop.get());
+
+ if(!vector) {
+ return false;
+ }
+
+ bytes_written += writer.writeValueToArray(vector->x) + writer.writeValueToArray(vector->y);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/Vector2DPropertySerialiser.h b/src/UESaveFile/Serialisers/Vector2DPropertySerialiser.h
new file mode 100644
index 0000000..c754bda
--- /dev/null
+++ b/src/UESaveFile/Serialisers/Vector2DPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/Vector2DStructProperty.h"
+
+class Vector2DPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Serialisers/VectorPropertySerialiser.cpp b/src/UESaveFile/Serialisers/VectorPropertySerialiser.cpp
new file mode 100644
index 0000000..feaa803
--- /dev/null
+++ b/src/UESaveFile/Serialisers/VectorPropertySerialiser.cpp
@@ -0,0 +1,47 @@
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "../BinaryReader.h"
+#include "../BinaryWriter.h"
+
+#include "VectorPropertySerialiser.h"
+
+auto VectorPropertySerialiser::deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length,
+ BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr
+{
+ auto prop = Containers::pointer();
+
+ if(!reader.readFloat(prop->x) || !reader.readFloat(prop->y) || !reader.readFloat(prop->z)) {
+ return nullptr;
+ }
+
+ return prop;
+}
+
+auto VectorPropertySerialiser::serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written,
+ BinaryWriter& writer, PropertySerialiser& serialiser) -> bool
+{
+ auto vector = dynamic_cast(prop.get());
+
+ if(!vector) {
+ return false;
+ }
+
+ bytes_written += writer.writeValueToArray(vector->x) + writer.writeValueToArray(vector->y) +
+ writer.writeValueToArray(vector->z);
+
+ return true;
+}
diff --git a/src/UESaveFile/Serialisers/VectorPropertySerialiser.h b/src/UESaveFile/Serialisers/VectorPropertySerialiser.h
new file mode 100644
index 0000000..3afb0dc
--- /dev/null
+++ b/src/UESaveFile/Serialisers/VectorPropertySerialiser.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealPropertySerialiser.h"
+
+#include "../Types/VectorStructProperty.h"
+
+class VectorPropertySerialiser : public UnrealPropertySerialiser {
+ public:
+ using ptr = Containers::Pointer;
+
+ private:
+ auto deserialiseProperty(const std::string& name, const std::string& type, UnsignedLong value_length, BinaryReader& reader, PropertySerialiser& serialiser) -> UnrealPropertyBase::ptr override;
+ auto serialiseProperty(UnrealPropertyBase::ptr& prop, UnsignedLong& bytes_written, BinaryWriter& writer, PropertySerialiser& serialiser) -> bool override;
+};
diff --git a/src/UESaveFile/Types/ArrayProperty.h b/src/UESaveFile/Types/ArrayProperty.h
new file mode 100644
index 0000000..b01a9ba
--- /dev/null
+++ b/src/UESaveFile/Types/ArrayProperty.h
@@ -0,0 +1,40 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include "UnrealPropertyBase.h"
+
+struct ArrayProperty : public UnrealPropertyBase {
+ using ptr = Containers::Pointer;
+
+ ArrayProperty() {
+ propertyType = "ArrayProperty";
+ }
+
+ auto at(std::size_t index) -> UnrealPropertyBase* {
+ if(index >= items.size()) {
+ return nullptr;
+ }
+
+ return items[index].get();
+ }
+
+ std::string itemType;
+ Containers::Array items;
+};
diff --git a/src/UESaveFile/Types/BoolProperty.h b/src/UESaveFile/Types/BoolProperty.h
new file mode 100644
index 0000000..f80a3b9
--- /dev/null
+++ b/src/UESaveFile/Types/BoolProperty.h
@@ -0,0 +1,27 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealProperty.h"
+
+struct BoolProperty : public UnrealProperty {
+ using ptr = Containers::Pointer;
+
+ BoolProperty() {
+ propertyType = "BoolProperty";
+ }
+};
diff --git a/src/UESaveFile/Types/ByteProperty.h b/src/UESaveFile/Types/ByteProperty.h
new file mode 100644
index 0000000..8587d2e
--- /dev/null
+++ b/src/UESaveFile/Types/ByteProperty.h
@@ -0,0 +1,33 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+
+#include "UnrealProperty.h"
+
+struct ByteProperty : public UnrealProperty> {
+ using ptr = Containers::Pointer;
+
+ ByteProperty() {
+ propertyType = "ByteProperty";
+ }
+
+ // For some reason, M.A.S.S. Builder stores EnumProperties as ByteProperties. Ugh...
+ std::string enumType;
+ std::string enumValue;
+};
diff --git a/src/UESaveFile/Types/ColourStructProperty.h b/src/UESaveFile/Types/ColourStructProperty.h
new file mode 100644
index 0000000..6df355d
--- /dev/null
+++ b/src/UESaveFile/Types/ColourStructProperty.h
@@ -0,0 +1,27 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "StructProperty.h"
+
+struct ColourStructProperty : public StructProperty {
+ using ptr = Containers::Pointer;
+ ColourStructProperty() {
+ structType = "LinearColor";
+ }
+ Float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
+};
diff --git a/src/UESaveFile/Types/DateTimeStructProperty.h b/src/UESaveFile/Types/DateTimeStructProperty.h
new file mode 100644
index 0000000..86da227
--- /dev/null
+++ b/src/UESaveFile/Types/DateTimeStructProperty.h
@@ -0,0 +1,29 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "StructProperty.h"
+
+struct DateTimeStructProperty : public StructProperty {
+ using ptr = Containers::Pointer;
+
+ DateTimeStructProperty() {
+ structType = "DateTime";
+ }
+
+ UnsignedLong timestamp = 0;
+};
diff --git a/src/UESaveFile/Types/EnumProperty.h b/src/UESaveFile/Types/EnumProperty.h
new file mode 100644
index 0000000..e9418af
--- /dev/null
+++ b/src/UESaveFile/Types/EnumProperty.h
@@ -0,0 +1,29 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealProperty.h"
+
+struct EnumProperty : public UnrealProperty {
+ using ptr = Containers::Pointer;
+
+ EnumProperty() {
+ propertyType = "EnumProperty";
+ }
+
+ std::string enumType;
+};
diff --git a/src/UESaveFile/Types/FloatProperty.h b/src/UESaveFile/Types/FloatProperty.h
new file mode 100644
index 0000000..1594959
--- /dev/null
+++ b/src/UESaveFile/Types/FloatProperty.h
@@ -0,0 +1,27 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include "UnrealProperty.h"
+
+struct FloatProperty : public UnrealProperty {
+ using ptr = Containers::Pointer;
+
+ FloatProperty() {
+ propertyType = "FloatProperty";
+ }
+};
diff --git a/src/UESaveFile/Types/GenericStructProperty.h b/src/UESaveFile/Types/GenericStructProperty.h
new file mode 100644
index 0000000..93b6b88
--- /dev/null
+++ b/src/UESaveFile/Types/GenericStructProperty.h
@@ -0,0 +1,43 @@
+#pragma once
+
+// MassBuilderSaveTool
+// Copyright (C) 2021 Guillaume Jacquemin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see