From 4d30a8d04e2c6671400bdda6c9df1082534f7c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 7 Jul 2019 23:12:26 +0200 Subject: [PATCH] Start refactoring GameManager zip handling to easier support ISOs in zips --- Core/Util/GameManager.cpp | 69 +++++++++++++++++++++++++++++++-------- Core/Util/GameManager.h | 4 +++ 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 864a16e5a0..e08d815e27 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -125,6 +125,19 @@ void GameManager::Update() { } } +void countSlashes(std::string fileName, int *slashLocation, int *slashCount) { + *slashCount = 0; + int lastSlashLocation = -1; + *slashLocation = -1; + for (size_t i = 0; i < fileName.size(); i++) { + if (fileName[i] == '/') { + (*slashCount)++; + *slashLocation = lastSlashLocation; + lastSlashLocation = (int)i; + } + } +} + bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { if (installInProgress_) { ERROR_LOG(HLE, "Cannot have two installs in progress at the same time"); @@ -155,34 +168,47 @@ bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { int numFiles = zip_get_num_files(z); // First, find all the directories, and precreate them before we fill in with files. - // Also, verify that this is a PSP zip file with the correct layout. - bool isPSP = false; + // Also, verify that this is a PSP zip file with the correct layout. We also try + // to detect simple zipped ISO files, those we'll just "install" to the current + // directory of the Games tab (where else?). + bool isPSPMemstickGame = false; + bool isZippedISO = false; int stripChars = 0; + int isoFileIndex = -1; for (int i = 0; i < numFiles; i++) { const char *fn = zip_get_name(z, i, 0); std::string zippedName = fn; if (zippedName.find("EBOOT.PBP") != std::string::npos) { int slashCount = 0; - int lastSlashLocation = -1; int slashLocation = -1; - for (size_t i = 0; i < zippedName.size(); i++) { - if (zippedName[i] == '/') { - slashCount++; - slashLocation = lastSlashLocation; - lastSlashLocation = (int)i; - } - } - if (slashCount >= 1 && (!isPSP || slashLocation < stripChars + 1)) { + countSlashes(zippedName, &slashLocation, &slashCount); + // TODO: Rewrite this... + if (slashCount >= 1 && (!isPSPMemstickGame || slashLocation < stripChars + 1)) { stripChars = slashLocation + 1; - isPSP = true; + isPSPMemstickGame = true; + break; } else { INFO_LOG(HLE, "Wrong number of slashes (%i) in %s", slashCount, zippedName.c_str()); } + } else if (endsWithNoCase(zippedName, ".iso")) { + int slashCount = 0; + int slashLocation = -1; + countSlashes(zippedName, &slashLocation, &slashCount); + if (slashCount == 1) { + isZippedISO = true; + isoFileIndex = i; + break; + } } } - if (!isPSP) { + if (isPSPMemstickGame) { + // InstallMemstickGame contains code to close z. + return InstallMemstickGame(z, zipfile, pspGame, numFiles, stripChars, deleteAfter); + } else if (isZippedISO) { + return InstallZippedISO(z, isoFileIndex, zipfile, deleteAfter); + } else { ERROR_LOG(HLE, "File not a PSP game, no EBOOT.PBP found."); installProgress_ = 0.0f; installInProgress_ = false; @@ -192,8 +218,11 @@ bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { File::Delete(zipfile); return false; } +} +bool GameManager::InstallMemstickGame(struct zip *z, std::string zipfile, std::string pspGame, int numFiles, int stripChars, bool deleteAfter) { size_t allBytes = 0, bytesCopied = 0; + I18NCategory *sy = GetI18NCategory("System"); // Create all the directories in one pass std::set createdDirs; @@ -250,7 +279,7 @@ bool GameManager::InstallGame(std::string zipfile, bool deleteAfter) { zip_fread(zf, buffer, bs); size_t written = fwrite(buffer, 1, bs, f); if (written != bs) { - ERROR_LOG(HLE, "Wrote %i bytes out of %i - Disk full?", (int)written, (int)bs); + ERROR_LOG(HLE, "Wrote %d bytes out of %d - Disk full?", (int)written, (int)bs); delete [] buffer; buffer = 0; fclose(f); @@ -293,6 +322,7 @@ bail: installProgress_ = 0.0f; installInProgress_ = false; installError_ = sy->T("Storage full"); + // Should we really delete in this case??? if (deleteAfter) { File::Delete(zipfile.c_str()); } @@ -306,6 +336,17 @@ bail: return false; } +bool GameManager::InstallZippedISO(struct zip *z, int isoFileIndex, std::string zipfile, bool deleteAfter) { + + + zip_close(z); + if (deleteAfter) { + File::Delete(zipfile.c_str()); + } + InstallDone(); + return false; +} + bool GameManager::InstallGameOnThread(std::string zipFile, bool deleteAfter) { if (installInProgress_) { return false; diff --git a/Core/Util/GameManager.h b/Core/Util/GameManager.h index 55e22312ba..40dc154c52 100644 --- a/Core/Util/GameManager.h +++ b/Core/Util/GameManager.h @@ -31,6 +31,8 @@ enum class GameManagerState { INSTALLING, }; +struct zip; + class GameManager { public: GameManager(); @@ -68,6 +70,8 @@ public: private: bool InstallGame(std::string zipfile, bool deleteAfter = false); + bool InstallMemstickGame(struct zip *z, std::string zipFile, std::string pspGame, int numFiles, int stripChars, bool deleteAfter); + bool InstallZippedISO(struct zip *z, int isoFileIndex, std::string zipfile, bool deleteAfter); void InstallDone(); std::string GetTempFilename() const;