Merge pull request #7970 from Techjar/netplay-mii-sync
NetPlay: Synchronize Mii data
This commit is contained in:
commit
664cfb2ca5
|
@ -60,6 +60,11 @@ std::string GetTMDFileName(u64 title_id, std::optional<FromWhichRoot> from)
|
|||
return GetTitleContentPath(title_id, from) + "/title.tmd";
|
||||
}
|
||||
|
||||
std::string GetMiiDatabasePath(std::optional<FromWhichRoot> from)
|
||||
{
|
||||
return StringFromFormat("%s/shared2/menu/FaceLib/RFL_DB.dat", RootUserPath(from).c_str());
|
||||
}
|
||||
|
||||
bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from, u64* title_id)
|
||||
{
|
||||
std::string expected_prefix = RootUserPath(from) + "/title/";
|
||||
|
@ -145,4 +150,4 @@ std::string UnescapeFileName(const std::string& filename)
|
|||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} // namespace Common
|
||||
|
|
|
@ -31,6 +31,7 @@ std::string GetTitlePath(u64 title_id, std::optional<FromWhichRoot> from = {});
|
|||
std::string GetTitleDataPath(u64 title_id, std::optional<FromWhichRoot> from = {});
|
||||
std::string GetTitleContentPath(u64 title_id, std::optional<FromWhichRoot> from = {});
|
||||
std::string GetTMDFileName(u64 title_id, std::optional<FromWhichRoot> from = {});
|
||||
std::string GetMiiDatabasePath(std::optional<FromWhichRoot> from = {});
|
||||
|
||||
// Returns whether a path is within an installed title's directory.
|
||||
bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from = {},
|
||||
|
@ -42,4 +43,4 @@ std::string EscapeFileName(const std::string& filename);
|
|||
std::string EscapePath(const std::string& path);
|
||||
// Reverses escaping done by EscapeFileName
|
||||
std::string UnescapeFileName(const std::string& filename);
|
||||
}
|
||||
} // namespace Common
|
||||
|
|
|
@ -888,6 +888,31 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
|||
auto temp_fs = std::make_unique<IOS::HLE::FS::HostFileSystem>(path);
|
||||
std::vector<u64> titles;
|
||||
|
||||
const IOS::HLE::FS::Modes fs_modes = {IOS::HLE::FS::Mode::ReadWrite,
|
||||
IOS::HLE::FS::Mode::ReadWrite,
|
||||
IOS::HLE::FS::Mode::ReadWrite};
|
||||
|
||||
// Read the Mii data
|
||||
bool mii_data;
|
||||
packet >> mii_data;
|
||||
if (mii_data)
|
||||
{
|
||||
auto buffer = DecompressPacketIntoBuffer(packet);
|
||||
|
||||
temp_fs->CreateDirectory(IOS::PID_KERNEL, IOS::PID_KERNEL, "/shared2/menu/FaceLib", 0,
|
||||
fs_modes);
|
||||
auto file = temp_fs->CreateAndOpenFile(IOS::PID_KERNEL, IOS::PID_KERNEL,
|
||||
Common::GetMiiDatabasePath(), fs_modes);
|
||||
|
||||
if (!buffer || !file || !file->Write(buffer->data(), buffer->size()))
|
||||
{
|
||||
PanicAlertT("Failed to write Mii data.");
|
||||
SyncSaveDataResponse(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the saves
|
||||
u32 save_count;
|
||||
packet >> save_count;
|
||||
for (u32 n = 0; n < save_count; n++)
|
||||
|
@ -895,9 +920,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
|||
u64 title_id = Common::PacketReadU64(packet);
|
||||
titles.push_back(title_id);
|
||||
temp_fs->CreateDirectory(IOS::PID_KERNEL, IOS::PID_KERNEL,
|
||||
Common::GetTitleDataPath(title_id), 0,
|
||||
{IOS::HLE::FS::Mode::ReadWrite, IOS::HLE::FS::Mode::ReadWrite,
|
||||
IOS::HLE::FS::Mode::ReadWrite});
|
||||
Common::GetTitleDataPath(title_id), 0, fs_modes);
|
||||
auto save = WiiSave::MakeNandStorage(temp_fs.get(), title_id);
|
||||
|
||||
bool exists;
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "Core/IOS/ES/ES.h"
|
||||
#include "Core/IOS/FS/FileSystem.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/IOS/Uids.h"
|
||||
#include "Core/NetPlayClient.h" //for NetPlayUI
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
|
||||
|
@ -1518,6 +1519,28 @@ bool NetPlayServer::SyncSaveData()
|
|||
sf::Packet pac;
|
||||
pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA);
|
||||
pac << static_cast<MessageId>(SYNC_SAVE_DATA_WII);
|
||||
|
||||
// Shove the Mii data into the start the packet
|
||||
{
|
||||
auto file = configured_fs->OpenFile(IOS::PID_KERNEL, IOS::PID_KERNEL,
|
||||
Common::GetMiiDatabasePath(), IOS::HLE::FS::Mode::Read);
|
||||
if (file)
|
||||
{
|
||||
pac << true;
|
||||
|
||||
std::vector<u8> file_data(file->GetStatus()->size);
|
||||
if (!file->Read(file_data.data(), file_data.size()))
|
||||
return false;
|
||||
if (!CompressBufferIntoPacket(file_data, pac))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pac << false; // no mii data
|
||||
}
|
||||
}
|
||||
|
||||
// Carry on with the save files
|
||||
pac << static_cast<u32>(saves.size());
|
||||
|
||||
for (const auto& pair : saves)
|
||||
|
|
|
@ -41,6 +41,36 @@ static void CopySave(FS::FileSystem* source, FS::FileSystem* dest, const u64 tit
|
|||
WiiSave::Copy(source_save.get(), dest_save.get());
|
||||
}
|
||||
|
||||
static bool CopyNandFile(FS::FileSystem* source_fs, const std::string& source_file,
|
||||
FS::FileSystem* dest_fs, const std::string& dest_file)
|
||||
{
|
||||
const auto last_slash = dest_file.find_last_of('/');
|
||||
if (last_slash != std::string::npos && last_slash > 0)
|
||||
{
|
||||
const std::string dir = dest_file.substr(0, last_slash);
|
||||
dest_fs->CreateDirectory(IOS::PID_KERNEL, IOS::PID_KERNEL, dir, 0,
|
||||
{IOS::HLE::FS::Mode::ReadWrite, IOS::HLE::FS::Mode::ReadWrite,
|
||||
IOS::HLE::FS::Mode::ReadWrite});
|
||||
}
|
||||
|
||||
auto source_handle =
|
||||
source_fs->OpenFile(IOS::PID_KERNEL, IOS::PID_KERNEL, source_file, IOS::HLE::FS::Mode::Read);
|
||||
auto dest_handle =
|
||||
dest_fs->CreateAndOpenFile(IOS::PID_KERNEL, IOS::PID_KERNEL, source_file,
|
||||
{IOS::HLE::FS::Mode::ReadWrite, IOS::HLE::FS::Mode::ReadWrite,
|
||||
IOS::HLE::FS::Mode::ReadWrite});
|
||||
if (!source_handle || !dest_handle)
|
||||
return false;
|
||||
|
||||
std::vector<u8> buffer(source_handle->GetStatus()->size);
|
||||
if (!source_handle->Read(buffer.data(), buffer.size()))
|
||||
return false;
|
||||
if (!dest_handle->Write(buffer.data(), buffer.size()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs)
|
||||
{
|
||||
const u64 title_id = SConfig::GetInstance().GetTitleID();
|
||||
|
@ -71,6 +101,13 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs)
|
|||
{
|
||||
CopySave(sync_fs, session_fs, title);
|
||||
}
|
||||
|
||||
// Copy Mii data
|
||||
if (!CopyNandFile(sync_fs, Common::GetMiiDatabasePath(), session_fs,
|
||||
Common::GetMiiDatabasePath()))
|
||||
{
|
||||
WARN_LOG(CORE, "Failed to copy Mii database to the NAND");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -85,6 +122,13 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs)
|
|||
{
|
||||
CopySave(configured_fs.get(), session_fs, title_id);
|
||||
}
|
||||
|
||||
// Copy Mii data
|
||||
if (!CopyNandFile(configured_fs.get(), Common::GetMiiDatabasePath(), session_fs,
|
||||
Common::GetMiiDatabasePath()))
|
||||
{
|
||||
WARN_LOG(CORE, "Failed to copy Mii database to the NAND");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,13 +242,20 @@ void CleanUpWiiFileSystemContents()
|
|||
return;
|
||||
}
|
||||
|
||||
IOS::HLE::EmulationKernel* ios = IOS::HLE::GetIOS();
|
||||
const auto configured_fs = FS::MakeFileSystem(FS::Location::Configured);
|
||||
|
||||
// Copy back Mii data
|
||||
if (!CopyNandFile(ios->GetFS().get(), Common::GetMiiDatabasePath(), configured_fs.get(),
|
||||
Common::GetMiiDatabasePath()))
|
||||
{
|
||||
WARN_LOG(CORE, "Failed to copy Mii database to the NAND");
|
||||
}
|
||||
|
||||
const u64 title_id = SConfig::GetInstance().GetTitleID();
|
||||
|
||||
IOS::HLE::EmulationKernel* ios = IOS::HLE::GetIOS();
|
||||
const auto session_save = WiiSave::MakeNandStorage(ios->GetFS().get(), title_id);
|
||||
|
||||
const auto configured_fs = FS::MakeFileSystem(FS::Location::Configured);
|
||||
|
||||
// FS won't write the save if the directory doesn't exist
|
||||
const std::string title_path = Common::GetTitleDataPath(title_id);
|
||||
if (!configured_fs->GetMetadata(IOS::PID_KERNEL, IOS::PID_KERNEL, title_path))
|
||||
|
|
Loading…
Reference in New Issue