Compare commits

...

2 commits

Author SHA1 Message Date
a290542f6e
Gvas: add support for UE5 saves.
Fuckers at Epic added four more bytes to the file header, and not
even equivalent Rust libraries know what those bytes are for.
2024-07-13 15:03:30 +02:00
3e0c0bb7a4
Application: disable the tree view for backups.
As mentioned in the commit, something's wrong. Probably on ImGui's
side, but I'll have to investigate more.
2024-07-13 13:29:42 +02:00
3 changed files with 117 additions and 56 deletions

View file

@ -175,50 +175,50 @@ Application::drawBackupListPopup() {
ImGui::TableSetColumnIndex(3); ImGui::TableSetColumnIndex(3);
ImGui::TextUnformatted("Actions"); ImGui::TextUnformatted("Actions");
drawBackupFolder(_backupManager->vfs()); //drawBackupFolder(_backupManager->vfs());
//for(std::size_t i = 0; i < _backupManager->backups().size(); ++i) { for(std::size_t i = 0; i < _backupManager->backups().size(); ++i) {
// auto& backup = _backupManager->backups()[i]; auto& backup = _backupManager->backups()[i];
// ImGui::TableNextRow(); ImGui::TableNextRow();
// ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
// ImGui::TextUnformatted(backup.company.cbegin(), backup.company.cend()); ImGui::TextUnformatted(backup.company.cbegin(), backup.company.cend());
// if(ImGui::IsItemHovered() && ImGui::BeginTooltip()) { if(ImGui::IsItemHovered() && ImGui::BeginTooltip()) {
// for(const auto& file : backup.includedFiles) { for(const auto& file : backup.includedFiles) {
// ImGui::TextUnformatted(file.cbegin()); ImGui::TextUnformatted(file.cbegin());
// } }
// ImGui::EndTooltip(); ImGui::EndTooltip();
// } }
// ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
// ImGui::Text("%.4i-%.2i-%.2i %.2i:%.2i:%.2i", ImGui::Text("%.4i-%.2i-%.2i %.2i:%.2i:%.2i",
// backup.timestamp.year, backup.timestamp.year,
// backup.timestamp.month, backup.timestamp.month,
// backup.timestamp.day, backup.timestamp.day,
// backup.timestamp.hour, backup.timestamp.hour,
// backup.timestamp.minute, backup.timestamp.minute,
// backup.timestamp.second); backup.timestamp.second);
// ImGui::TableSetColumnIndex(2); ImGui::TableSetColumnIndex(2);
// ImGui::TextUnformatted(backup.demo ? "Demo" : "Full"); ImGui::TextUnformatted(backup.demo ? "Demo" : "Full");
// ImGui::TableSetColumnIndex(3); ImGui::TableSetColumnIndex(3);
// ImGui::PushID(int(i)); ImGui::PushID(int(i));
// if(ImGui::SmallButton(ICON_FA_UNDO)) { if(ImGui::SmallButton(ICON_FA_UNDO)) {
// backup_index = i; backup_index = i;
// ImGui::OpenPopup("Restore backup##RestoreBackupModal"); ImGui::OpenPopup("Restore backup##RestoreBackupModal");
// } }
// drawTooltip("Restore"); drawTooltip("Restore");
// drawBackupRestorePopup(backup_index); drawBackupRestorePopup(backup_index);
// ImGui::SameLine(0.0f, 2.0f); ImGui::SameLine(0.0f, 2.0f);
// if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) { if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) {
// backup_index = i; backup_index = i;
// ImGui::OpenPopup("Delete backup##DeleteBackupModal"); ImGui::OpenPopup("Delete backup##DeleteBackupModal");
// } }
// drawTooltip("Delete"); drawTooltip("Delete");
// drawBackupDeletePopup(backup_index); drawBackupDeletePopup(backup_index);
// ImGui::PopID(); ImGui::PopID();
//} }
ImGui::EndTable(); ImGui::EndTable();
} }

View file

@ -95,16 +95,39 @@ File::saveToFile() {
return false; return false;
} }
if(!writer.writeArray(arrayView(_magicBytes)) || if(!writer.writeArray(arrayView(_magicBytes))) {
!writer.writeUint32(_saveVersion) || _lastError = "Couldn't write the magic bytes."_s;
!writer.writeUint32(_packageVersion) || LOG_ERROR(_lastError);
!writer.writeUint16(_engineVersion.major) || return false;
!writer.writeUint16(_engineVersion.minor) || }
!writer.writeUint16(_engineVersion.patch) ||
!writer.writeUint32(_engineVersion.build) || if(!writer.writeUint32(_saveVersion)) {
_lastError = "Couldn't write the save version."_s;
LOG_ERROR(_lastError);
return false;
}
if(!writer.writeUint32(_packageVersion)) {
_lastError = "Couldn't write the package version."_s;
LOG_ERROR(_lastError);
return false;
}
if(_saveVersion == 3) {
if(!writer.writeUint32(_unknown)) {
_lastError = "Couldn't write some unknown bytes."_s;
LOG_ERROR(_lastError);
return false;
}
}
if(!writer.writeUint16(_engineVersion.major) ||
!writer.writeUint16(_engineVersion.minor) ||
!writer.writeUint16(_engineVersion.patch) ||
!writer.writeUint32(_engineVersion.build) ||
!writer.writeUEString(_engineVersion.buildId)) !writer.writeUEString(_engineVersion.buildId))
{ {
_lastError = "Couldn't write the header."_s; _lastError = "Couldn't write the engine version."_s;
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
return false; return false;
} }
@ -198,15 +221,53 @@ File::loadData() {
return; return;
} }
if(!reader.readUint32(_saveVersion) || if(!reader.readUint32(_saveVersion)) {
!reader.readUint32(_packageVersion) || _lastError = "Couldn't read save version.";
!reader.readUint16(_engineVersion.major) || LOG_ERROR(_lastError);
!reader.readUint16(_engineVersion.minor) || return;
!reader.readUint16(_engineVersion.patch) || }
!reader.readUint32(_engineVersion.build) ||
!reader.readUEString(_engineVersion.buildId)) if(!reader.readUint32(_packageVersion)) {
_lastError = "Couldn't read package version.";
LOG_ERROR(_lastError);
return;
}
if(_saveVersion == 3) {
if(!reader.readUint32(_unknown)) {
_lastError = "Couldn't read some unknown bytes.";
LOG_ERROR(_lastError);
return;
}
}
if(!reader.readUint16(_engineVersion.major)) {
_lastError = "Couldn't read major engine version.";
LOG_ERROR(_lastError);
return;
}
if(!reader.readUint16(_engineVersion.minor)) {
_lastError = "Couldn't read minor engine version.";
LOG_ERROR(_lastError);
return;
}
if(!reader.readUint16(_engineVersion.patch)) {
_lastError = "Couldn't read patch engine version.";
LOG_ERROR(_lastError);
return;
}
if(!reader.readUint32(_engineVersion.build)) {
_lastError = "Couldn't read engine build.";
LOG_ERROR(_lastError);
return;
}
if(!reader.readUEString(_engineVersion.buildId))
{ {
_lastError = "Couldn't read version data."; _lastError = "Couldn't read engine build ID string.";
LOG_ERROR(_lastError); LOG_ERROR(_lastError);
return; return;
} }

View file

@ -17,7 +17,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <Corrade/Containers/ArrayView.h> #include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/Reference.h> #include <Corrade/Containers/Reference.h>
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Corrade/Containers/String.h> #include <Corrade/Containers/String.h>
@ -73,6 +72,7 @@ class File {
std::uint32_t _saveVersion = 0; std::uint32_t _saveVersion = 0;
std::uint32_t _packageVersion = 0; std::uint32_t _packageVersion = 0;
std::uint32_t _unknown = 0;
struct { struct {
std::uint16_t major = 0; std::uint16_t major = 0;
std::uint16_t minor = 0; std::uint16_t minor = 0;