55
66#include " common/Assertions.h"
77#include " common/ByteSwap.h"
8+ #include " common/Console.h"
89#include " common/FileSystem.h"
910#include " common/Path.h"
1011#include " common/SmallString.h"
1112#include " common/StringUtil.h"
12- #include " common/ZipHelpers .h"
13+ #include " common/ZipFile .h"
1314
1415#include " Achievements.h"
1516#include " Config.h"
@@ -149,6 +150,7 @@ namespace Patch
149150
150151 template <typename F>
151152 static void EnumeratePnachFiles (const std::string_view serial, u32 crc, bool cheats, bool for_ui, const F& f);
153+ static std::optional<std::string> ReadPnachFileFromZip (const std::string& filename);
152154
153155 static bool PatchStringHasUnlabelledPatch (const std::string& pnach_data);
154156 static void ExtractPatchInfo (std::vector<PatchInfo>* dst, const std::string& pnach_data, u32 * num_unlabelled_patches);
@@ -170,7 +172,7 @@ namespace Patch
170172 const char * PATCH_ENABLE_CONFIG_KEY = " Enable" ;
171173 const char * PATCH_DISABLE_CONFIG_KEY = " Disable" ;
172174
173- static zip_t * s_patches_zip;
175+ static ZipArchive s_patches_zip;
174176 static std::vector<PatchGroup> s_gamedb_patches;
175177 static std::vector<PatchGroup> s_game_patches;
176178 static std::vector<PatchGroup> s_cheat_patches;
@@ -338,15 +340,16 @@ u32 Patch::LoadPatchesFromString(std::vector<PatchGroup>* patch_list, const std:
338340
339341bool Patch::OpenPatchesZip ()
340342{
341- if (s_patches_zip)
343+ if (s_patches_zip. IsValid () )
342344 return true ;
343345
344346 const std::string filename = Path::Combine (EmuFolders::Resources, PATCHES_ZIP_NAME );
345347
346- zip_error ze = {};
347- zip_source_t * zs = zip_source_file_create (filename.c_str (), 0 , 0 , &ze);
348- if (zs && !(s_patches_zip = zip_open_from_source (zs, ZIP_RDONLY , &ze)))
348+ Error error;
349+ if (!s_patches_zip.Open (filename.c_str (), ZIP_RDONLY , nullptr , &error))
349350 {
351+ Console.ErrorFmt (" Failed to open {}: {}" , filename, error.GetDescription ());
352+
350353 static bool warning_shown = false ;
351354 if (!warning_shown)
352355 {
@@ -357,13 +360,9 @@ bool Patch::OpenPatchesZip()
357360 warning_shown = true ;
358361 }
359362
360- // have to clean up source
361- Console.Error (" Failed to open %s: %s" , filename.c_str (), zip_error_strerror (&ze));
362- zip_source_free (zs);
363363 return false ;
364364 }
365365
366- std::atexit ([]() { zip_close (s_patches_zip); });
367366 return true ;
368367}
369368
@@ -443,18 +442,47 @@ void Patch::EnumeratePnachFiles(const std::string_view serial, u32 crc, bool che
443442 if (cheats || unlabeled_patch_found || !OpenPatchesZip ())
444443 return ;
445444
446- // Prefer filename with serial.
447- std::string zip_filename = GetPnachTemplate (serial, crc, true , false , false );
448- std::optional<std::string> pnach_data (ReadFileInZipToString (s_patches_zip, zip_filename.c_str ()));
445+ std::string zip_filename;
446+ std::optional<std::string> pnach_data;
447+
448+ {
449+ // Prefer filename with serial.
450+ zip_filename = GetPnachTemplate (serial, crc, true , false , false );
451+ pnach_data = ReadPnachFileFromZip (zip_filename);
452+ }
453+
449454 if (!pnach_data.has_value ())
450455 {
451456 zip_filename = GetPnachTemplate (serial, crc, false , false , false );
452- pnach_data = ReadFileInZipToString (s_patches_zip, zip_filename. c_str () );
457+ pnach_data = ReadPnachFileFromZip ( zip_filename);
453458 }
459+
454460 if (pnach_data.has_value ())
455461 f (std::move (zip_filename), std::move (pnach_data.value ()));
456462}
457463
464+ std::optional<std::string> Patch::ReadPnachFileFromZip (const std::string& filename)
465+ {
466+ std::optional<ZipEntryIndex> pnach_index =
467+ s_patches_zip.LocateFile (filename.c_str (), ZIP_FL_NOCASE , nullptr );
468+ if (!pnach_index.has_value ())
469+ {
470+ // The file doesn't exist.
471+ return std::nullopt ;
472+ }
473+
474+ Error error;
475+ std::optional<std::string> pnach_data = s_patches_zip.ReadTextFile (*pnach_index, 0 , &error);
476+ if (!pnach_data.has_value ())
477+ {
478+ Console.ErrorFmt (" Failed to read pnach file '{}' from patches zip: {}." ,
479+ filename, error.GetDescription ());
480+ return std::nullopt ;
481+ }
482+
483+ return pnach_data;
484+ }
485+
458486bool Patch::PatchStringHasUnlabelledPatch (const std::string& pnach_data)
459487{
460488 std::istringstream ss (pnach_data);
0 commit comments