Core/WiiRoot: Handle the combination of NetPlay and savegame redirects.
This commit is contained in:
parent
387d148357
commit
b928900f6e
|
@ -155,6 +155,11 @@ const std::vector<u64>& BootSessionData::GetWiiSyncTitles() const
|
|||
return m_wii_sync_titles;
|
||||
}
|
||||
|
||||
const std::string& BootSessionData::GetWiiSyncRedirectFolder() const
|
||||
{
|
||||
return m_wii_sync_redirect_folder;
|
||||
}
|
||||
|
||||
void BootSessionData::InvokeWiiSyncCleanup() const
|
||||
{
|
||||
if (m_wii_sync_cleanup)
|
||||
|
@ -162,10 +167,12 @@ void BootSessionData::InvokeWiiSyncCleanup() const
|
|||
}
|
||||
|
||||
void BootSessionData::SetWiiSyncData(std::unique_ptr<IOS::HLE::FS::FileSystem> fs,
|
||||
std::vector<u64> titles, WiiSyncCleanupFunction cleanup)
|
||||
std::vector<u64> titles, std::string redirect_folder,
|
||||
WiiSyncCleanupFunction cleanup)
|
||||
{
|
||||
m_wii_sync_fs = std::move(fs);
|
||||
m_wii_sync_titles = std::move(titles);
|
||||
m_wii_sync_redirect_folder = std::move(redirect_folder);
|
||||
m_wii_sync_cleanup = std::move(cleanup);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,9 +66,10 @@ public:
|
|||
|
||||
IOS::HLE::FS::FileSystem* GetWiiSyncFS() const;
|
||||
const std::vector<u64>& GetWiiSyncTitles() const;
|
||||
const std::string& GetWiiSyncRedirectFolder() const;
|
||||
void InvokeWiiSyncCleanup() const;
|
||||
void SetWiiSyncData(std::unique_ptr<IOS::HLE::FS::FileSystem> fs, std::vector<u64> titles,
|
||||
WiiSyncCleanupFunction cleanup);
|
||||
std::string redirect_folder, WiiSyncCleanupFunction cleanup);
|
||||
|
||||
private:
|
||||
std::optional<std::string> m_savestate_path;
|
||||
|
@ -76,6 +77,7 @@ private:
|
|||
|
||||
std::unique_ptr<IOS::HLE::FS::FileSystem> m_wii_sync_fs;
|
||||
std::vector<u64> m_wii_sync_titles;
|
||||
std::string m_wii_sync_redirect_folder;
|
||||
WiiSyncCleanupFunction m_wii_sync_cleanup;
|
||||
};
|
||||
|
||||
|
|
|
@ -1077,6 +1077,7 @@ void NetPlayClient::OnSyncSaveDataGCI(sf::Packet& packet)
|
|||
void NetPlayClient::OnSyncSaveDataWii(sf::Packet& packet)
|
||||
{
|
||||
const std::string path = File::GetUserPath(D_USER_IDX) + "Wii" GC_MEMCARD_NETPLAY DIR_SEP;
|
||||
std::string redirect_path = File::GetUserPath(D_USER_IDX) + "Redirect" GC_MEMCARD_NETPLAY DIR_SEP;
|
||||
|
||||
if (File::Exists(path) && !File::DeleteDirRecursively(path))
|
||||
{
|
||||
|
@ -1084,6 +1085,12 @@ void NetPlayClient::OnSyncSaveDataWii(sf::Packet& packet)
|
|||
SyncSaveDataResponse(false);
|
||||
return;
|
||||
}
|
||||
if (File::Exists(redirect_path) && !File::DeleteDirRecursively(redirect_path))
|
||||
{
|
||||
PanicAlertFmtT("Failed to reset NetPlay redirect folder. Verify your write permissions.");
|
||||
SyncSaveDataResponse(false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto temp_fs = std::make_unique<IOS::HLE::FS::HostFileSystem>(path);
|
||||
std::vector<u64> titles;
|
||||
|
@ -1190,7 +1197,19 @@ void NetPlayClient::OnSyncSaveDataWii(sf::Packet& packet)
|
|||
}
|
||||
}
|
||||
|
||||
SetWiiSyncData(std::move(temp_fs), std::move(titles));
|
||||
bool has_redirected_save;
|
||||
packet >> has_redirected_save;
|
||||
if (has_redirected_save)
|
||||
{
|
||||
if (!DecompressPacketIntoFolder(packet, redirect_path))
|
||||
{
|
||||
PanicAlertFmtT("Failed to write redirected save.");
|
||||
SyncSaveDataResponse(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SetWiiSyncData(std::move(temp_fs), std::move(titles), std::move(redirect_path));
|
||||
SyncSaveDataResponse(true);
|
||||
}
|
||||
|
||||
|
@ -1721,11 +1740,17 @@ bool NetPlayClient::StartGame(const std::string& path)
|
|||
|
||||
// boot game
|
||||
auto boot_session_data = std::make_unique<BootSessionData>();
|
||||
boot_session_data->SetWiiSyncData(std::move(m_wii_sync_fs), std::move(m_wii_sync_titles), [] {
|
||||
boot_session_data->SetWiiSyncData(
|
||||
std::move(m_wii_sync_fs), std::move(m_wii_sync_titles), std::move(m_wii_sync_redirect_folder),
|
||||
[] {
|
||||
// on emulation end clean up the Wii save sync directory -- see OnSyncSaveDataWii()
|
||||
const std::string path = File::GetUserPath(D_USER_IDX) + "Wii" GC_MEMCARD_NETPLAY DIR_SEP;
|
||||
if (File::Exists(path))
|
||||
File::DeleteDirRecursively(path);
|
||||
const std::string redirect_path =
|
||||
File::GetUserPath(D_USER_IDX) + "Redirect" GC_MEMCARD_NETPLAY DIR_SEP;
|
||||
if (File::Exists(redirect_path))
|
||||
File::DeleteDirRecursively(redirect_path);
|
||||
});
|
||||
m_dialog->BootGame(path, std::move(boot_session_data));
|
||||
|
||||
|
@ -2501,10 +2526,11 @@ void NetPlayClient::AdjustPadBufferSize(const unsigned int size)
|
|||
}
|
||||
|
||||
void NetPlayClient::SetWiiSyncData(std::unique_ptr<IOS::HLE::FS::FileSystem> fs,
|
||||
std::vector<u64> titles)
|
||||
std::vector<u64> titles, std::string redirect_folder)
|
||||
{
|
||||
m_wii_sync_fs = std::move(fs);
|
||||
m_wii_sync_titles = std::move(titles);
|
||||
m_wii_sync_redirect_folder = std::move(redirect_folder);
|
||||
}
|
||||
|
||||
SyncIdentifier NetPlayClient::GetSDCardIdentifier()
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
virtual void HideChunkedProgressDialog() = 0;
|
||||
virtual void SetChunkedProgress(int pid, u64 progress) = 0;
|
||||
|
||||
virtual void SetHostWiiSyncTitles(std::vector<u64> titles) = 0;
|
||||
virtual void SetHostWiiSyncData(std::vector<u64> titles, std::string redirect_folder) = 0;
|
||||
};
|
||||
|
||||
class Player
|
||||
|
@ -157,7 +157,8 @@ public:
|
|||
|
||||
void AdjustPadBufferSize(unsigned int size);
|
||||
|
||||
void SetWiiSyncData(std::unique_ptr<IOS::HLE::FS::FileSystem> fs, std::vector<u64> titles);
|
||||
void SetWiiSyncData(std::unique_ptr<IOS::HLE::FS::FileSystem> fs, std::vector<u64> titles,
|
||||
std::string redirect_folder);
|
||||
|
||||
static SyncIdentifier GetSDCardIdentifier();
|
||||
|
||||
|
@ -328,6 +329,7 @@ private:
|
|||
|
||||
std::unique_ptr<IOS::HLE::FS::FileSystem> m_wii_sync_fs;
|
||||
std::vector<u64> m_wii_sync_titles;
|
||||
std::string m_wii_sync_redirect_folder;
|
||||
};
|
||||
|
||||
void NetPlay_Enable(NetPlayClient* const np);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "Common/Version.h"
|
||||
|
||||
#include "Core/ActionReplay.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/NetplaySettings.h"
|
||||
|
@ -60,6 +61,7 @@
|
|||
#include "Core/SyncIdentifier.h"
|
||||
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/RiivolutionPatcher.h"
|
||||
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
|
@ -1616,6 +1618,17 @@ bool NetPlayServer::SyncSaveData()
|
|||
save_count++;
|
||||
}
|
||||
|
||||
std::optional<DiscIO::Riivolution::SavegameRedirect> redirected_save;
|
||||
if (wii_save && game->GetBlobType() == DiscIO::BlobType::MOD_DESCRIPTOR)
|
||||
{
|
||||
auto boot_params = BootParameters::GenerateFromFile(game->GetFilePath());
|
||||
if (boot_params)
|
||||
{
|
||||
redirected_save =
|
||||
DiscIO::Riivolution::ExtractSavegameRedirect(boot_params->riivolution_patches);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& config : m_gba_config)
|
||||
{
|
||||
if (config.enabled && config.has_rom)
|
||||
|
@ -1818,8 +1831,20 @@ bool NetPlayServer::SyncSaveData()
|
|||
}
|
||||
}
|
||||
|
||||
if (redirected_save)
|
||||
{
|
||||
pac << true;
|
||||
if (!CompressFolderIntoPacket(redirected_save->m_target_path, pac))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pac << false; // no redirected save
|
||||
}
|
||||
|
||||
// Set titles for host-side loading in WiiRoot
|
||||
m_dialog->SetHostWiiSyncTitles(std::move(titles));
|
||||
m_dialog->SetHostWiiSyncData(std::move(titles),
|
||||
redirected_save ? redirected_save->m_target_path : "");
|
||||
|
||||
SendChunkedToClients(std::move(pac), 1, "Wii Save Synchronization");
|
||||
}
|
||||
|
|
|
@ -35,9 +35,19 @@ namespace Core
|
|||
namespace FS = IOS::HLE::FS;
|
||||
|
||||
static std::string s_temp_wii_root;
|
||||
static std::string s_temp_redirect_root;
|
||||
static bool s_wii_root_initialized = false;
|
||||
static std::vector<IOS::HLE::FS::NandRedirect> s_nand_redirects;
|
||||
|
||||
// When Temp NAND + Redirects are both active, we need to keep track of where each redirect path
|
||||
// should be copied back to after a successful session finish.
|
||||
struct TempRedirectPath
|
||||
{
|
||||
std::string real_path;
|
||||
std::string temp_path;
|
||||
};
|
||||
static std::vector<TempRedirectPath> s_temp_nand_redirects;
|
||||
|
||||
const std::vector<IOS::HLE::FS::NandRedirect>& GetActiveNandRedirects()
|
||||
{
|
||||
return s_nand_redirects;
|
||||
|
@ -175,6 +185,28 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs,
|
|||
WARN_LOG_FMT(CORE, "Failed to copy Mii database to the NAND");
|
||||
}
|
||||
}
|
||||
|
||||
const auto& netplay_redirect_folder = boot_session_data.GetWiiSyncRedirectFolder();
|
||||
if (!netplay_redirect_folder.empty())
|
||||
File::CopyDir(netplay_redirect_folder, s_temp_redirect_root + "/");
|
||||
}
|
||||
}
|
||||
|
||||
static void MoveToBackupIfExists(const std::string& path)
|
||||
{
|
||||
if (File::Exists(path))
|
||||
{
|
||||
const std::string backup_path = path.substr(0, path.size() - 1) + ".backup" DIR_SEP;
|
||||
WARN_LOG_FMT(IOS_FS, "Temporary directory at {} exists, moving to backup...", path);
|
||||
|
||||
// If backup exists, delete it as we don't want a mess
|
||||
if (File::Exists(backup_path))
|
||||
{
|
||||
WARN_LOG_FMT(IOS_FS, "Temporary backup directory at {} exists, deleting...", backup_path);
|
||||
File::DeleteDirRecursively(backup_path);
|
||||
}
|
||||
|
||||
File::CopyDir(path, backup_path, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,24 +217,13 @@ void InitializeWiiRoot(bool use_temporary)
|
|||
if (use_temporary)
|
||||
{
|
||||
s_temp_wii_root = File::GetUserPath(D_USER_IDX) + "WiiSession" DIR_SEP;
|
||||
s_temp_redirect_root = File::GetUserPath(D_USER_IDX) + "RedirectSession" DIR_SEP;
|
||||
WARN_LOG_FMT(IOS_FS, "Using temporary directory {} for minimal Wii FS", s_temp_wii_root);
|
||||
WARN_LOG_FMT(IOS_FS, "Using temporary directory {} for redirected saves", s_temp_redirect_root);
|
||||
|
||||
// If directory exists, make a backup
|
||||
if (File::Exists(s_temp_wii_root))
|
||||
{
|
||||
const std::string backup_path =
|
||||
s_temp_wii_root.substr(0, s_temp_wii_root.size() - 1) + ".backup" DIR_SEP;
|
||||
WARN_LOG_FMT(IOS_FS, "Temporary Wii FS directory exists, moving to backup...");
|
||||
|
||||
// If backup exists, delete it as we don't want a mess
|
||||
if (File::Exists(backup_path))
|
||||
{
|
||||
WARN_LOG_FMT(IOS_FS, "Temporary Wii FS backup directory exists, deleting...");
|
||||
File::DeleteDirRecursively(backup_path);
|
||||
}
|
||||
|
||||
File::CopyDir(s_temp_wii_root, backup_path, true);
|
||||
}
|
||||
MoveToBackupIfExists(s_temp_wii_root);
|
||||
MoveToBackupIfExists(s_temp_redirect_root);
|
||||
|
||||
File::SetUserPath(D_SESSION_WIIROOT_IDX, s_temp_wii_root);
|
||||
}
|
||||
|
@ -221,6 +242,9 @@ void ShutdownWiiRoot()
|
|||
{
|
||||
File::DeleteDirRecursively(s_temp_wii_root);
|
||||
s_temp_wii_root.clear();
|
||||
File::DeleteDirRecursively(s_temp_redirect_root);
|
||||
s_temp_redirect_root.clear();
|
||||
s_temp_nand_redirects.clear();
|
||||
}
|
||||
|
||||
s_nand_redirects.clear();
|
||||
|
@ -312,7 +336,8 @@ void InitializeWiiFileSystemContents(
|
|||
if (!CopySysmenuFilesToFS(fs.get(), File::GetSysDirectory() + WII_USER_DIR, ""))
|
||||
WARN_LOG_FMT(CORE, "Failed to copy initial System Menu files to the NAND");
|
||||
|
||||
if (WiiRootIsTemporary())
|
||||
const bool is_temp_nand = WiiRootIsTemporary();
|
||||
if (is_temp_nand)
|
||||
{
|
||||
// Generate a SYSCONF with default settings for the temporary Wii NAND.
|
||||
SysConf sysconf{fs};
|
||||
|
@ -320,16 +345,26 @@ void InitializeWiiFileSystemContents(
|
|||
|
||||
InitializeDeterministicWiiSaves(fs.get(), boot_session_data);
|
||||
}
|
||||
else if (save_redirect)
|
||||
|
||||
if (save_redirect)
|
||||
{
|
||||
const u64 title_id = SConfig::GetInstance().GetTitleID();
|
||||
std::string source_path = Common::GetTitleDataPath(title_id);
|
||||
|
||||
if (is_temp_nand)
|
||||
{
|
||||
// remember the actual path for copying back on shutdown and redirect to a temp folder instead
|
||||
s_temp_nand_redirects.emplace_back(
|
||||
TempRedirectPath{save_redirect->m_target_path, s_temp_redirect_root});
|
||||
save_redirect->m_target_path = s_temp_redirect_root;
|
||||
}
|
||||
|
||||
if (!File::IsDirectory(save_redirect->m_target_path))
|
||||
{
|
||||
File::CreateFullPath(save_redirect->m_target_path + "/");
|
||||
if (save_redirect->m_clone)
|
||||
{
|
||||
File::CopyDir(Common::GetTitleDataPath(title_id, Common::FROM_CONFIGURED_ROOT),
|
||||
File::CopyDir(Common::GetTitleDataPath(title_id, Common::FROM_SESSION_ROOT),
|
||||
save_redirect->m_target_path);
|
||||
}
|
||||
}
|
||||
|
@ -347,7 +382,16 @@ void CleanUpWiiFileSystemContents(const BootSessionData& boot_session_data)
|
|||
return;
|
||||
}
|
||||
|
||||
// copy back the temp nand redirected files to where they should normally be redirected to
|
||||
for (const auto& redirect : s_temp_nand_redirects)
|
||||
File::CopyDir(redirect.temp_path, redirect.real_path + "/", true);
|
||||
|
||||
IOS::HLE::EmulationKernel* ios = IOS::HLE::GetIOS();
|
||||
|
||||
// clear the redirects in the session FS, otherwise the back-copy might grab redirected files
|
||||
s_nand_redirects.clear();
|
||||
ios->GetFS()->SetNandRedirects({});
|
||||
|
||||
const auto configured_fs = FS::MakeFileSystem(FS::Location::Configured);
|
||||
|
||||
// Copy back Mii data
|
||||
|
|
|
@ -1179,9 +1179,9 @@ void NetPlayDialog::SetChunkedProgress(const int pid, const u64 progress)
|
|||
});
|
||||
}
|
||||
|
||||
void NetPlayDialog::SetHostWiiSyncTitles(std::vector<u64> titles)
|
||||
void NetPlayDialog::SetHostWiiSyncData(std::vector<u64> titles, std::string redirect_folder)
|
||||
{
|
||||
auto client = Settings::Instance().GetNetPlayClient();
|
||||
if (client)
|
||||
client->SetWiiSyncData(nullptr, std::move(titles));
|
||||
client->SetWiiSyncData(nullptr, std::move(titles), std::move(redirect_folder));
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
void HideChunkedProgressDialog() override;
|
||||
void SetChunkedProgress(int pid, u64 progress) override;
|
||||
|
||||
void SetHostWiiSyncTitles(std::vector<u64> titles) override;
|
||||
void SetHostWiiSyncData(std::vector<u64> titles, std::string redirect_folder) override;
|
||||
|
||||
signals:
|
||||
void Stop();
|
||||
|
|
Loading…
Reference in New Issue