Skip to content
Permalink
Browse files

NetPlay: Synchronize Mii data

It's bundled with the Wii saves for simplicity, since it's quite small.
  • Loading branch information...
Techjar committed Apr 8, 2019
1 parent 22f5590 commit 1b8eda827bc16acc449ad66ed9cb5d228d515c3b
@@ -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
@@ -866,16 +866,39 @@ 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++)
{
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"
@@ -1490,6 +1491,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))

0 comments on commit 1b8eda8

Please sign in to comment.
You can’t perform that action at this time.