mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 04:02:42 +01:00
Added installation for additional packages to game boot
This commit is contained in:
parent
8901cc9ae6
commit
6702c14b88
@ -24,6 +24,12 @@ inline void strcpy_trunc(char (&dst)[N], const char (&src)[N2])
|
||||
dst[count] = '\0';
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
inline bool ends_with(const std::string& src, const char (&end)[N])
|
||||
{
|
||||
return src.size() >= N - 1 && src.compare(src.size() - (N - 1), N - 1, end, N - 1) == 0;
|
||||
}
|
||||
|
||||
namespace fmt
|
||||
{
|
||||
std::string replace_first(const std::string& src, const std::string& from, const std::string& to);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include "../Crypto/unself.h"
|
||||
#include "../Crypto/unpkg.h"
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include <thread>
|
||||
@ -212,6 +213,7 @@ void Emulator::Init()
|
||||
fs::create_dir(dev_hdd0 + "game/");
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/");
|
||||
fs::create_dir(dev_hdd0 + "game/TEST12345/USRDIR/");
|
||||
fs::create_dir(dev_hdd0 + "game/.locks/");
|
||||
fs::create_dir(dev_hdd0 + "home/");
|
||||
fs::create_dir(dev_hdd0 + "home/00000001/");
|
||||
fs::create_dir(dev_hdd0 + "home/00000001/exdata/");
|
||||
@ -265,6 +267,51 @@ bool Emulator::BootGame(const std::string& path, bool direct, bool add_only)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Emulator::InstallPkg(const std::string& path)
|
||||
{
|
||||
LOG_SUCCESS(GENERAL, "Installing package: %s", path);
|
||||
|
||||
atomic_t<double> progress(0.);
|
||||
int int_progress = 0;
|
||||
{
|
||||
// Run PKG unpacking asynchronously
|
||||
scope_thread worker("PKG Installer", [&]
|
||||
{
|
||||
if (pkg_install(path, progress))
|
||||
{
|
||||
progress = 1.;
|
||||
return;
|
||||
}
|
||||
|
||||
progress = -1.;
|
||||
});
|
||||
|
||||
// Wait for the completion
|
||||
while (std::this_thread::sleep_for(5ms), std::abs(progress) < 1.)
|
||||
{
|
||||
// TODO: update unified progress dialog
|
||||
double pval = progress;
|
||||
pval < 0 ? pval += 1. : pval;
|
||||
pval *= 100.;
|
||||
|
||||
if (static_cast<int>(pval) > int_progress)
|
||||
{
|
||||
int_progress = static_cast<int>(pval);
|
||||
LOG_SUCCESS(GENERAL, "... %u%%", int_progress);
|
||||
}
|
||||
|
||||
m_cb.process_events();
|
||||
}
|
||||
}
|
||||
|
||||
if (progress >= 1.)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Emulator::GetHddDir()
|
||||
{
|
||||
const std::string& emu_dir_ = g_cfg.vfs.emulator_dir;
|
||||
@ -453,7 +500,8 @@ void Emulator::Load(bool add_only)
|
||||
}
|
||||
else if (!Emu.disc.empty())
|
||||
{
|
||||
vfs::mount("dev_bdvd", Emu.disc);
|
||||
bdvd_dir = Emu.disc;
|
||||
vfs::mount("dev_bdvd", bdvd_dir);
|
||||
LOG_NOTICE(LOADER, "Disk: %s", vfs::get("/dev_bdvd"));
|
||||
}
|
||||
else if (_cat == "DG" || _cat == "GD")
|
||||
@ -468,6 +516,73 @@ void Emulator::Load(bool add_only)
|
||||
return;
|
||||
}
|
||||
|
||||
// Install PKGDIR, INSDIR, PS3_EXTRA
|
||||
if (!bdvd_dir.empty())
|
||||
{
|
||||
const std::string ins_dir = vfs::get("/dev_bdvd/PS3_GAME/INSDIR/");
|
||||
const std::string pkg_dir = vfs::get("/dev_bdvd/PS3_GAME/PKGDIR/");
|
||||
const std::string extra_dir = vfs::get("/dev_bdvd/PS3_GAME/PS3_EXTRA/");
|
||||
fs::file lock_file;
|
||||
|
||||
if (fs::is_dir(ins_dir) || fs::is_dir(pkg_dir) || fs::is_dir(extra_dir))
|
||||
{
|
||||
// Create lock file to prevent double installation
|
||||
lock_file.open(hdd0_game + ".locks/" + m_title_id, fs::read + fs::create + fs::excl);
|
||||
}
|
||||
|
||||
if (lock_file && fs::is_dir(ins_dir))
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Found INSDIR: %s", ins_dir);
|
||||
|
||||
for (auto&& entry : fs::dir{ins_dir})
|
||||
{
|
||||
if (!entry.is_directory && ends_with(entry.name, ".PKG") && !InstallPkg(ins_dir + entry.name))
|
||||
{
|
||||
LOG_ERROR(LOADER, "Failed to install /dev_bdvd/PS3_GAME/INSDIR/%s", entry.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lock_file && fs::is_dir(pkg_dir))
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Found PKGDIR: %s", pkg_dir);
|
||||
|
||||
for (auto&& entry : fs::dir{pkg_dir})
|
||||
{
|
||||
if (entry.is_directory && entry.name.compare(0, 3, "PKG", 3) == 0)
|
||||
{
|
||||
const std::string pkg_file = pkg_dir + entry.name + "/INSTALL.PKG";
|
||||
|
||||
if (fs::is_file(pkg_file) && !InstallPkg(pkg_file))
|
||||
{
|
||||
LOG_ERROR(LOADER, "Failed to install /dev_bdvd/PS3_GAME/PKGDIR/%s/INSTALL.PKG", entry.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lock_file && fs::is_dir(extra_dir))
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Found PS3_EXTRA: %s", extra_dir);
|
||||
|
||||
for (auto&& entry : fs::dir{extra_dir})
|
||||
{
|
||||
if (entry.is_directory && entry.name[0] == 'D')
|
||||
{
|
||||
const std::string pkg_file = extra_dir + entry.name + "/DATA000.PKG";
|
||||
|
||||
if (fs::is_file(pkg_file) && !InstallPkg(pkg_file))
|
||||
{
|
||||
LOG_ERROR(LOADER, "Failed to install /dev_bdvd/PS3_GAME/PKGDIR/%s/DATA000.PKG", entry.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check game updates
|
||||
const std::string hdd0_boot = hdd0_game + m_title_id + "/USRDIR/EBOOT.BIN";
|
||||
|
||||
|
@ -245,6 +245,7 @@ public:
|
||||
}
|
||||
|
||||
bool BootGame(const std::string& path, bool direct = false, bool add_only = false);
|
||||
bool InstallPkg(const std::string& path);
|
||||
|
||||
static std::string GetHddDir();
|
||||
static std::string GetLibDir();
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include "Loader/PUP.h"
|
||||
#include "Loader/TAR.h"
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
#include "Utilities/Thread.h"
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
Loading…
Reference in New Issue
Block a user