Merge pull request #7446 from Techjar/wii-save-full-sync

NetPlay: Add full Wii save sync
This commit is contained in:
Pierre Bourdon
2018-11-21 00:22:50 +01:00
committed by GitHub
18 changed files with 748 additions and 101 deletions

View File

@@ -62,6 +62,7 @@ namespace NetPlay
static std::mutex crit_netplay_client;
static NetPlayClient* netplay_client = nullptr;
static std::unique_ptr<IOS::HLE::FS::FileSystem> s_wii_sync_fs;
static std::vector<u64> s_wii_sync_titles;
static bool s_si_poll_batching;
// called from ---GUI--- thread
@@ -112,7 +113,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlay
if (!traversal_config.use_traversal)
{
// Direct Connection
m_client = enet_host_create(nullptr, 1, 3, 0, 0);
m_client = enet_host_create(nullptr, 1, CHANNEL_COUNT, 0, 0);
if (m_client == nullptr)
{
@@ -124,7 +125,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlay
enet_address_set_host(&addr, address.c_str());
addr.port = port;
m_server = enet_host_connect(m_client, &addr, 3, 0);
m_server = enet_host_connect(m_client, &addr, CHANNEL_COUNT, 0);
if (m_server == nullptr)
{
@@ -338,6 +339,61 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
}
break;
case NP_MSG_CHUNKED_DATA_START:
{
u32 cid;
packet >> cid;
std::string title;
packet >> title;
u64 data_size = Common::PacketReadU64(packet);
m_chunked_data_receive_queue.emplace(cid, sf::Packet{});
std::vector<int> players;
players.push_back(m_local_player->pid);
m_dialog->ShowChunkedProgressDialog(title, data_size, players);
}
break;
case NP_MSG_CHUNKED_DATA_END:
{
u32 cid;
packet >> cid;
OnData(m_chunked_data_receive_queue[cid]);
m_chunked_data_receive_queue.erase(m_chunked_data_receive_queue.find(cid));
m_dialog->HideChunkedProgressDialog();
sf::Packet complete_packet;
complete_packet << static_cast<MessageId>(NP_MSG_CHUNKED_DATA_COMPLETE);
complete_packet << cid;
Send(complete_packet, CHUNKED_DATA_CHANNEL);
}
break;
case NP_MSG_CHUNKED_DATA_PAYLOAD:
{
u32 cid;
packet >> cid;
while (!packet.endOfPacket())
{
u8 byte;
packet >> byte;
m_chunked_data_receive_queue[cid] << byte;
}
m_dialog->SetChunkedProgress(m_local_player->pid,
m_chunked_data_receive_queue[cid].getDataSize());
sf::Packet progress_packet;
progress_packet << static_cast<MessageId>(NP_MSG_CHUNKED_DATA_PROGRESS);
progress_packet << cid;
progress_packet << sf::Uint64{m_chunked_data_receive_queue[cid].getDataSize()};
Send(progress_packet, CHUNKED_DATA_CHANNEL);
}
break;
case NP_MSG_PAD_MAPPING:
{
for (PadMapping& mapping : m_pad_map)
@@ -553,6 +609,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
packet >> m_net_settings.m_SyncSaveData;
packet >> m_net_settings.m_SaveDataRegion;
packet >> m_net_settings.m_SyncCodes;
packet >> m_net_settings.m_SyncAllWiiSaves;
m_net_settings.m_IsHosting = m_local_player->IsHost();
m_net_settings.m_HostInputAuthority = m_host_input_authority;
@@ -732,13 +789,6 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
if (m_local_player->IsHost())
return 0;
const auto game = m_dialog->FindGameFile(m_selected_game);
if (game == nullptr)
{
SyncSaveDataResponse(true); // whatever, we won't be booting anyways
return 0;
}
const std::string path = File::GetUserPath(D_USER_IDX) + "Wii" GC_MEMCARD_NETPLAY DIR_SEP;
if (File::Exists(path) && !File::DeleteDirRecursively(path))
@@ -749,16 +799,25 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
}
auto temp_fs = std::make_unique<IOS::HLE::FS::HostFileSystem>(path);
temp_fs->CreateDirectory(IOS::PID_KERNEL, IOS::PID_KERNEL,
Common::GetTitleDataPath(game->GetTitleID()), 0,
{IOS::HLE::FS::Mode::ReadWrite, IOS::HLE::FS::Mode::ReadWrite,
IOS::HLE::FS::Mode::ReadWrite});
auto save = WiiSave::MakeNandStorage(temp_fs.get(), game->GetTitleID());
std::vector<u64> titles;
bool exists;
packet >> exists;
if (exists)
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});
auto save = WiiSave::MakeNandStorage(temp_fs.get(), title_id);
bool exists;
packet >> exists;
if (!exists)
continue;
// Header
WiiSave::Header header;
packet >> header.tid;
@@ -824,7 +883,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
}
}
SetWiiSyncFS(std::move(temp_fs));
SetWiiSyncData(std::move(temp_fs), titles);
SyncSaveDataResponse(true);
}
break;
@@ -1050,11 +1109,11 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
return 0;
}
void NetPlayClient::Send(const sf::Packet& packet)
void NetPlayClient::Send(const sf::Packet& packet, const u8 channel_id)
{
ENetPacket* epac =
enet_packet_create(packet.getData(), packet.getDataSize(), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(m_server, 0, epac);
enet_peer_send(m_server, channel_id, epac);
}
void NetPlayClient::DisplayPlayersPing()
@@ -1104,11 +1163,11 @@ void NetPlayClient::Disconnect()
m_server = nullptr;
}
void NetPlayClient::SendAsync(sf::Packet&& packet)
void NetPlayClient::SendAsync(sf::Packet&& packet, const u8 channel_id)
{
{
std::lock_guard<std::recursive_mutex> lkq(m_crit.async_queue_write);
m_async_queue.Push(std::move(packet));
m_async_queue.Push(AsyncQueueEntry{std::move(packet), channel_id});
}
ENetUtil::WakeupThread(m_client);
}
@@ -1136,7 +1195,10 @@ void NetPlayClient::ThreadFunc()
net = enet_host_service(m_client, &netEvent, 250);
while (!m_async_queue.Empty())
{
Send(m_async_queue.Front());
{
auto& e = m_async_queue.Front();
Send(e.packet, e.channel_id);
}
m_async_queue.Pop();
}
if (net > 0)
@@ -1557,7 +1619,7 @@ void NetPlayClient::OnConnectReady(ENetAddress addr)
if (m_connection_state == ConnectionState::WaitingForTraversalClientConnectReady)
{
m_connection_state = ConnectionState::Connecting;
enet_host_connect(m_client, &addr, 0, 0);
enet_host_connect(m_client, &addr, CHANNEL_COUNT, 0);
}
}
@@ -1867,7 +1929,7 @@ bool NetPlayClient::StopGame()
// stop game
m_dialog->StopGame();
ClearWiiSyncFS();
ClearWiiSyncData();
return true;
}
@@ -2068,12 +2130,18 @@ IOS::HLE::FS::FileSystem* GetWiiSyncFS()
return s_wii_sync_fs.get();
}
void SetWiiSyncFS(std::unique_ptr<IOS::HLE::FS::FileSystem> fs)
const std::vector<u64>& GetWiiSyncTitles()
{
s_wii_sync_fs = std::move(fs);
return s_wii_sync_titles;
}
void ClearWiiSyncFS()
void SetWiiSyncData(std::unique_ptr<IOS::HLE::FS::FileSystem> fs, const std::vector<u64>& titles)
{
s_wii_sync_fs = std::move(fs);
s_wii_sync_titles.insert(s_wii_sync_titles.end(), titles.begin(), titles.end());
}
void ClearWiiSyncData()
{
// We're just assuming it will always be here because it is
const std::string path = File::GetUserPath(D_USER_IDX) + "Wii" GC_MEMCARD_NETPLAY DIR_SEP;
@@ -2081,6 +2149,7 @@ void ClearWiiSyncFS()
File::DeleteDirRecursively(path);
s_wii_sync_fs.reset();
s_wii_sync_titles.clear();
}
void SetSIPollBatching(bool state)
@@ -2094,6 +2163,16 @@ void SendPowerButtonEvent()
netplay_client->SendPowerButtonEvent();
}
bool IsSyncingAllWiiSaves()
{
std::lock_guard<std::mutex> lk(crit_netplay_client);
if (netplay_client)
return netplay_client->GetNetSettings().m_SyncAllWiiSaves;
return false;
}
void NetPlay_Enable(NetPlayClient* const np)
{
std::lock_guard<std::mutex> lk(crit_netplay_client);