diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 8d5f9a6b80..571a314d0b 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -747,6 +747,7 @@ FCompressedBuffer FSerializer::GetCompressedOutput() FCompressedBuffer buff; WriteObjects(); EndObject(); + buff.filename = nullptr; buff.mSize = (unsigned)w->mOutString.GetSize(); buff.mZipFlags = 0; buff.mCRC32 = crc32(0, (const Bytef*)w->mOutString.GetString(), buff.mSize); diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 1048ad487c..83427161ec 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -593,7 +593,7 @@ static std::pair time_to_dos(struct tm *time) // //========================================================================== -int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, std::pair &dostime) +static int AppendToZip(FileWriter *zip_file, const FCompressedBuffer &content, std::pair &dostime) { FZipLocalFileHeader local; int position; @@ -608,7 +608,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c local.CRC32 = content.mCRC32; local.UncompressedSize = LittleLong(content.mSize); local.CompressedSize = LittleLong(content.mCompressedSize); - local.NameLength = LittleShort((unsigned short)strlen(filename)); + local.NameLength = LittleShort((unsigned short)strlen(content.filename)); local.ExtraLength = 0; // Fill in local directory header. @@ -617,7 +617,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c // Write out the header, file name, and file data. if (zip_file->Write(&local, sizeof(local)) != sizeof(local) || - zip_file->Write(filename, strlen(filename)) != strlen(filename) || + zip_file->Write(content.filename, strlen(content.filename)) != strlen(content.filename) || zip_file->Write(content.mBuffer, content.mCompressedSize) != content.mCompressedSize) { return -1; @@ -634,7 +634,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c // //========================================================================== -int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, std::pair &dostime, int position) +int AppendCentralDirectory(FileWriter *zip_file, const FCompressedBuffer &content, std::pair &dostime, int position) { FZipCentralDirectoryInfo dir; @@ -650,23 +650,23 @@ int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompress dir.CRC32 = content.mCRC32; dir.CompressedSize32 = LittleLong(content.mCompressedSize); dir.UncompressedSize32 = LittleLong(content.mSize); - dir.NameLength = LittleShort((unsigned short)strlen(filename)); + dir.NameLength = LittleShort((unsigned short)strlen(content.filename)); dir.ExtraLength = 0; dir.CommentLength = 0; dir.StartingDiskNumber = 0; dir.InternalAttributes = 0; dir.ExternalAttributes = 0; - dir.LocalHeaderOffset32 = LittleLong(position); + dir.LocalHeaderOffset32 = LittleLong((unsigned)position); if (zip_file->Write(&dir, sizeof(dir)) != sizeof(dir) || - zip_file->Write(filename, strlen(filename)) != strlen(filename)) + zip_file->Write(content.filename, strlen(content.filename)) != strlen(content.filename)) { return -1; } return 0; } -bool WriteZip(const char *filename, TArray &filenames, TArray &content) +bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t contentcount) { // try to determine local time struct tm *ltime; @@ -677,14 +677,12 @@ bool WriteZip(const char *filename, TArray &filenames, TArray positions; - if (filenames.Size() != content.Size()) return false; - auto f = FileWriter::Open(filename); if (f != nullptr) { - for (unsigned i = 0; i < filenames.Size(); i++) + for (size_t i = 0; i < contentcount; i++) { - int pos = AppendToZip(f, filenames[i], content[i], dostime); + int pos = AppendToZip(f, content[i], dostime); if (pos == -1) { delete f; @@ -695,9 +693,9 @@ bool WriteZip(const char *filename, TArray &filenames, TArrayTell(); - for (unsigned i = 0; i < filenames.Size(); i++) + for (size_t i = 0; i < contentcount; i++) { - if (AppendCentralDirectory(f, filenames[i], content[i], dostime, positions[i]) < 0) + if (AppendCentralDirectory(f, content[i], dostime, positions[i]) < 0) { delete f; remove(filename); @@ -710,8 +708,8 @@ bool WriteZip(const char *filename, TArray &filenames, TArrayTell() - dirofs)); dirend.ZipCommentLength = 0; if (f->Write(&dirend, sizeof(dirend)) != sizeof(dirend)) diff --git a/src/common/filesystem/fs_findfile.h b/src/common/filesystem/fs_findfile.h index 3c81009af0..85d328d437 100644 --- a/src/common/filesystem/fs_findfile.h +++ b/src/common/filesystem/fs_findfile.h @@ -19,7 +19,9 @@ struct FileListEntry using FileList = std::vector; +struct FCompressedBuffer; bool ScanDirectory(std::vector& list, const char* dirpath, const char* match, bool nosubdir = false, bool readhidden = false); +bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t contentcount); inline void FixPathSeparator(char* path) { diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index df68d7c8de..c40e1c5980 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -91,6 +91,7 @@ struct FCompressedBuffer int mZipFlags; unsigned mCRC32; char *mBuffer; + const char* filename; bool Decompress(char *destbuffer); void Clean() diff --git a/src/g_game.cpp b/src/g_game.cpp index e4b47082ef..d1374a9254 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -90,6 +90,7 @@ #include "doommenu.h" #include "screenjob.h" #include "i_interface.h" +#include "fs_findfile.h" static FRandom pr_dmspawn ("DMSpawn"); @@ -111,7 +112,6 @@ void G_DoAutoSave (); void G_DoQuickSave (); void STAT_Serialize(FSerializer &file); -bool WriteZip(const char *filename, TArray &filenames, TArray &content); CVARD_NAMED(Int, gameskill, skill, 2, CVAR_SERVERINFO|CVAR_LATCH, "sets the skill for the next newly started game") CVAR(Bool, save_formatted, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // use formatted JSON for saves (more readable but a larger files and a bit slower. @@ -2416,13 +2416,14 @@ void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, c savegame_filenames.Push("info.json"); savegame_content.Push(savegameglobals.GetCompressedOutput()); savegame_filenames.Push("globals.json"); - G_WriteSnapshots (savegame_filenames, savegame_content); + for (unsigned i = 0; i < savegame_content.Size(); i++) + savegame_content[i].filename = savegame_filenames[i].GetChars(); bool succeeded = false; - if (WriteZip(filename, savegame_filenames, savegame_content)) + if (WriteZip(filename, savegame_content.Data(), savegame_content.Size())) { // Check whether the file is ok by trying to open it. FResourceFile *test = FResourceFile::OpenResourceFile(filename, true);