Store: Handle zip files with external URLs and deep paths inside.
This commit is contained in:
parent
5905849182
commit
6e60db7c22
4 changed files with 27 additions and 7 deletions
|
@ -81,8 +81,8 @@ bool GameManager::Uninstall(std::string name) {
|
||||||
void GameManager::Update() {
|
void GameManager::Update() {
|
||||||
if (curDownload_.get() && curDownload_->Done()) {
|
if (curDownload_.get() && curDownload_->Done()) {
|
||||||
INFO_LOG(HLE, "Download completed! Status = %i", curDownload_->ResultCode());
|
INFO_LOG(HLE, "Download completed! Status = %i", curDownload_->ResultCode());
|
||||||
if (curDownload_->ResultCode() == 200) {
|
|
||||||
std::string zipName = curDownload_->outfile();
|
std::string zipName = curDownload_->outfile();
|
||||||
|
if (curDownload_->ResultCode() == 200) {
|
||||||
if (!File::Exists(zipName)) {
|
if (!File::Exists(zipName)) {
|
||||||
ERROR_LOG(HLE, "Downloaded file %s does not exist :(", zipName.c_str());
|
ERROR_LOG(HLE, "Downloaded file %s does not exist :(", zipName.c_str());
|
||||||
curDownload_.reset();
|
curDownload_.reset();
|
||||||
|
@ -93,6 +93,9 @@ void GameManager::Update() {
|
||||||
// Doesn't matter if the install succeeds or not, we delete the temp file to not squander space.
|
// Doesn't matter if the install succeeds or not, we delete the temp file to not squander space.
|
||||||
// TODO: Handle disk full?
|
// TODO: Handle disk full?
|
||||||
deleteFile(zipName.c_str());
|
deleteFile(zipName.c_str());
|
||||||
|
} else {
|
||||||
|
ERROR_LOG(HLE, "Expected HTTP status code 200, got status code %i. Install cancelled.", curDownload_->ResultCode());
|
||||||
|
deleteFile(zipName.c_str());
|
||||||
}
|
}
|
||||||
curDownload_.reset();
|
curDownload_.reset();
|
||||||
}
|
}
|
||||||
|
@ -123,16 +126,23 @@ void GameManager::InstallGame(std::string zipfile) {
|
||||||
// First, find all the directories, and precreate them before we fill in with files.
|
// 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.
|
// Also, verify that this is a PSP zip file with the correct layout.
|
||||||
bool isPSP = false;
|
bool isPSP = false;
|
||||||
|
int stripChars = 0;
|
||||||
for (int i = 0; i < numFiles; i++) {
|
for (int i = 0; i < numFiles; i++) {
|
||||||
const char *fn = zip_get_name(z, i, 0);
|
const char *fn = zip_get_name(z, i, 0);
|
||||||
std::string zippedName = fn;
|
std::string zippedName = fn;
|
||||||
if (zippedName.find("EBOOT.PBP") != std::string::npos) {
|
if (zippedName.find("EBOOT.PBP") != std::string::npos) {
|
||||||
int slashCount = 0;
|
int slashCount = 0;
|
||||||
|
int lastSlashLocation = 0;
|
||||||
|
int slashLocation = 0;
|
||||||
for (size_t i = 0; i < zippedName.size(); i++) {
|
for (size_t i = 0; i < zippedName.size(); i++) {
|
||||||
if (zippedName[i] == '/')
|
if (zippedName[i] == '/') {
|
||||||
slashCount++;
|
slashCount++;
|
||||||
|
slashLocation = lastSlashLocation;
|
||||||
|
lastSlashLocation = i;
|
||||||
}
|
}
|
||||||
if (slashCount == 1) {
|
}
|
||||||
|
if (slashCount >= 1 && (!isPSP || slashLocation < stripChars + 1)) {
|
||||||
|
stripChars = slashLocation + 1;
|
||||||
isPSP = true;
|
isPSP = true;
|
||||||
} else {
|
} else {
|
||||||
INFO_LOG(HLE, "Wrong number of slashes (%i) in %s", slashCount, zippedName.c_str());
|
INFO_LOG(HLE, "Wrong number of slashes (%i) in %s", slashCount, zippedName.c_str());
|
||||||
|
@ -141,7 +151,7 @@ void GameManager::InstallGame(std::string zipfile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPSP) {
|
if (!isPSP) {
|
||||||
ERROR_LOG(HLE, "File not a PSP game");
|
ERROR_LOG(HLE, "File not a PSP game, no EBOOT.PBP found.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +159,7 @@ void GameManager::InstallGame(std::string zipfile) {
|
||||||
for (int i = 0; i < numFiles; i++) {
|
for (int i = 0; i < numFiles; i++) {
|
||||||
const char *fn = zip_get_name(z, i, 0);
|
const char *fn = zip_get_name(z, i, 0);
|
||||||
std::string zippedName = fn;
|
std::string zippedName = fn;
|
||||||
std::string outFilename = pspGame + zippedName;
|
std::string outFilename = pspGame + zippedName.substr(stripChars);
|
||||||
bool isDir = outFilename.back() == '/';
|
bool isDir = outFilename.back() == '/';
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
File::CreateFullPath(outFilename.c_str());
|
File::CreateFullPath(outFilename.c_str());
|
||||||
|
@ -170,6 +180,8 @@ void GameManager::InstallGame(std::string zipfile) {
|
||||||
zip_fread(zf, buffer, size);
|
zip_fread(zf, buffer, size);
|
||||||
zip_fclose(zf);
|
zip_fclose(zf);
|
||||||
|
|
||||||
|
fn += stripChars;
|
||||||
|
|
||||||
std::string outFilename = pspGame + fn;
|
std::string outFilename = pspGame + fn;
|
||||||
bool isDir = outFilename.back() == '/';
|
bool isDir = outFilename.back() == '/';
|
||||||
if (!isDir) {
|
if (!isDir) {
|
||||||
|
|
|
@ -578,7 +578,6 @@ void DrawDownloadsOverlay(UIContext &ctx) {
|
||||||
for (int i = 0; i < progress.size(); i++) {
|
for (int i = 0; i < progress.size(); i++) {
|
||||||
float barWidth = 10 + (dp_xres - 10) * progress[i];
|
float barWidth = 10 + (dp_xres - 10) * progress[i];
|
||||||
Bounds bounds(0, h * i, barWidth, h);
|
Bounds bounds(0, h * i, barWidth, h);
|
||||||
INFO_LOG(HLE, "Bar");
|
|
||||||
UI::Drawable solid(colors[i & 3]);
|
UI::Drawable solid(colors[i & 3]);
|
||||||
ctx.FillRect(solid, bounds);
|
ctx.FillRect(solid, bounds);
|
||||||
}
|
}
|
||||||
|
|
10
UI/Store.cpp
10
UI/Store.cpp
|
@ -88,7 +88,14 @@ void ProductView::Update(const InputState &input_state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UI::EventReturn ProductView::OnInstall(UI::EventParams &e) {
|
UI::EventReturn ProductView::OnInstall(UI::EventParams &e) {
|
||||||
std::string zipUrl = storeBaseUrl + "files/" + entry_.file + ".zip";
|
std::string zipUrl;
|
||||||
|
if (entry_.downloadURL.empty()) {
|
||||||
|
// Construct the URL, easy to predict from our server
|
||||||
|
zipUrl = storeBaseUrl + "files/" + entry_.file + ".zip";
|
||||||
|
} else {
|
||||||
|
// Use the provided URL, for external hosting.
|
||||||
|
zipUrl = entry_.downloadURL;
|
||||||
|
}
|
||||||
if (installButton_) {
|
if (installButton_) {
|
||||||
installButton_->SetEnabled(false);
|
installButton_->SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
@ -165,6 +172,7 @@ void StoreScreen::ParseListing(std::string json) {
|
||||||
e.description = GetTranslatedString(game, "description", "");
|
e.description = GetTranslatedString(game, "description", "");
|
||||||
e.author = game->getString("author", "?");
|
e.author = game->getString("author", "?");
|
||||||
e.size = game->getInt("size");
|
e.size = game->getInt("size");
|
||||||
|
e.downloadURL = game->getString("download-url", "");
|
||||||
const char *file = game->getString("file", 0);
|
const char *file = game->getString("file", 0);
|
||||||
if (!file)
|
if (!file)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct StoreEntry {
|
||||||
std::string iconURL;
|
std::string iconURL;
|
||||||
std::string file; // This is the folder name of the installed one too, and hence a "unique-ish" identifier.
|
std::string file; // This is the folder name of the installed one too, and hence a "unique-ish" identifier.
|
||||||
std::string category;
|
std::string category;
|
||||||
|
std::string downloadURL; // Only set for games that are not hosted on store.ppsspp.org
|
||||||
u64 size;
|
u64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue