Merge pull request #7970 from Techjar/netplay-mii-sync

NetPlay: Synchronize Mii data
This commit is contained in:
Connor McLaughlin 2019-04-27 13:26:55 +10:00 committed by GitHub
commit 664cfb2ca5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 111 additions and 8 deletions

View file

@ -60,6 +60,11 @@ std::string GetTMDFileName(u64 title_id, std::optional<FromWhichRoot> from)
return GetTitleContentPath(title_id, from) + "/title.tmd"; 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) bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from, u64* title_id)
{ {
std::string expected_prefix = RootUserPath(from) + "/title/"; std::string expected_prefix = RootUserPath(from) + "/title/";
@ -145,4 +150,4 @@ std::string UnescapeFileName(const std::string& filename)
return result; return result;
} }
} } // namespace Common

View file

@ -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 GetTitleDataPath(u64 title_id, std::optional<FromWhichRoot> from = {});
std::string GetTitleContentPath(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 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. // Returns whether a path is within an installed title's directory.
bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from = {}, 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); std::string EscapePath(const std::string& path);
// Reverses escaping done by EscapeFileName // Reverses escaping done by EscapeFileName
std::string UnescapeFileName(const std::string& filename); std::string UnescapeFileName(const std::string& filename);
} } // namespace Common

View file

@ -888,6 +888,31 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
auto temp_fs = std::make_unique<IOS::HLE::FS::HostFileSystem>(path); auto temp_fs = std::make_unique<IOS::HLE::FS::HostFileSystem>(path);
std::vector<u64> titles; 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; u32 save_count;
packet >> save_count; packet >> save_count;
for (u32 n = 0; n < save_count; n++) 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); u64 title_id = Common::PacketReadU64(packet);
titles.push_back(title_id); titles.push_back(title_id);
temp_fs->CreateDirectory(IOS::PID_KERNEL, IOS::PID_KERNEL, temp_fs->CreateDirectory(IOS::PID_KERNEL, IOS::PID_KERNEL,
Common::GetTitleDataPath(title_id), 0, Common::GetTitleDataPath(title_id), 0, fs_modes);
{IOS::HLE::FS::Mode::ReadWrite, IOS::HLE::FS::Mode::ReadWrite,
IOS::HLE::FS::Mode::ReadWrite});
auto save = WiiSave::MakeNandStorage(temp_fs.get(), title_id); auto save = WiiSave::MakeNandStorage(temp_fs.get(), title_id);
bool exists; bool exists;

View file

@ -48,6 +48,7 @@
#include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/ES.h"
#include "Core/IOS/FS/FileSystem.h" #include "Core/IOS/FS/FileSystem.h"
#include "Core/IOS/IOS.h" #include "Core/IOS/IOS.h"
#include "Core/IOS/Uids.h"
#include "Core/NetPlayClient.h" //for NetPlayUI #include "Core/NetPlayClient.h" //for NetPlayUI
#include "DiscIO/Enums.h" #include "DiscIO/Enums.h"
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" #include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
@ -1518,6 +1519,28 @@ bool NetPlayServer::SyncSaveData()
sf::Packet pac; sf::Packet pac;
pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA); pac << static_cast<MessageId>(NP_MSG_SYNC_SAVE_DATA);
pac << static_cast<MessageId>(SYNC_SAVE_DATA_WII); 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()); pac << static_cast<u32>(saves.size());
for (const auto& pair : saves) for (const auto& pair : saves)

View file

@ -41,6 +41,36 @@ static void CopySave(FS::FileSystem* source, FS::FileSystem* dest, const u64 tit
WiiSave::Copy(source_save.get(), dest_save.get()); 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) static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs)
{ {
const u64 title_id = SConfig::GetInstance().GetTitleID(); const u64 title_id = SConfig::GetInstance().GetTitleID();
@ -71,6 +101,13 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs)
{ {
CopySave(sync_fs, session_fs, title); 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 else
{ {
@ -85,6 +122,13 @@ static void InitializeDeterministicWiiSaves(FS::FileSystem* session_fs)
{ {
CopySave(configured_fs.get(), session_fs, title_id); 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; 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(); 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 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 // FS won't write the save if the directory doesn't exist
const std::string title_path = Common::GetTitleDataPath(title_id); const std::string title_path = Common::GetTitleDataPath(title_id);
if (!configured_fs->GetMetadata(IOS::PID_KERNEL, IOS::PID_KERNEL, title_path)) if (!configured_fs->GetMetadata(IOS::PID_KERNEL, IOS::PID_KERNEL, title_path))