Netplay: Sync codes
Adds a tickbox to the server's window to syncronize codes. Codes are temporarily sent to each client and are used for the duration of the session. Saves the "sync codes" tickbox as per PR Netplay: Properly save hosting settings #7483
This commit is contained in:
1 parent
0140009114
commit
469f29350f
17 files changed
+545
-7
No files matched your search
@@ -33,8 +33,10 @@
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Common/Timer.h"
|
||||
#include "Common/Version.h"
|
||||
#include "Core/ActionReplay.h"
|
||||
#include "Core/Config/NetplaySettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/GeckoCode.h"
|
||||
#include "Core/HW/EXI/EXI_DeviceIPL.h"
|
||||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/SI/SI_DeviceGCController.h"
|
||||
@@ -549,6 +551,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;
|
||||
|
||||
m_net_settings.m_IsHosting = m_local_player->IsHost();
|
||||
m_net_settings.m_HostInputAuthority = m_host_input_authority;
|
||||
@@ -644,6 +647,9 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
{
|
||||
case SYNC_SAVE_DATA_NOTIFY:
|
||||
{
|
||||
if (m_local_player->IsHost())
|
||||
return 0;
|
||||
|
||||
packet >> m_sync_save_data_count;
|
||||
m_sync_save_data_success_count = 0;
|
||||
|
||||
@@ -823,6 +829,163 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
}
|
||||
break;
|
||||
|
||||
case NP_MSG_SYNC_CODES:
|
||||
{
|
||||
// Recieve Data Packet
|
||||
MessageId sub_id;
|
||||
packet >> sub_id;
|
||||
|
||||
// Check Which Operation to Perform with This Packet
|
||||
switch (sub_id)
|
||||
{
|
||||
case SYNC_CODES_NOTIFY:
|
||||
{
|
||||
// Set both codes as unsynced
|
||||
m_sync_gecko_codes_complete = false;
|
||||
m_sync_ar_codes_complete = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case SYNC_CODES_NOTIFY_GECKO:
|
||||
{
|
||||
// Return if this is the host
|
||||
if (m_local_player->IsHost())
|
||||
return 0;
|
||||
|
||||
// Receive Number of Codelines to Receive
|
||||
packet >> m_sync_gecko_codes_count;
|
||||
|
||||
m_sync_gecko_codes_success_count = 0;
|
||||
|
||||
NOTICE_LOG(ACTIONREPLAY, "Receiving %d Gecko codelines", m_sync_gecko_codes_count);
|
||||
|
||||
// Check if no codes to sync, if so return as finished
|
||||
if (m_sync_gecko_codes_count == 0)
|
||||
{
|
||||
m_sync_gecko_codes_complete = true;
|
||||
SyncCodeResponse(true);
|
||||
}
|
||||
else
|
||||
m_dialog->AppendChat(GetStringT("Synchronizing gecko codes..."));
|
||||
}
|
||||
break;
|
||||
|
||||
case SYNC_CODES_DATA_GECKO:
|
||||
{
|
||||
// Return if this is the host
|
||||
if (m_local_player->IsHost())
|
||||
return 0;
|
||||
|
||||
// Create a synced code vector
|
||||
std::vector<Gecko::GeckoCode> synced_codes;
|
||||
// Create a GeckoCode
|
||||
Gecko::GeckoCode gcode;
|
||||
gcode = Gecko::GeckoCode();
|
||||
// Initialize gcode
|
||||
gcode.name = "Synced Codes";
|
||||
gcode.enabled = true;
|
||||
|
||||
// Receive code contents from packet
|
||||
for (int i = 0; i < m_sync_gecko_codes_count; i++)
|
||||
{
|
||||
Gecko::GeckoCode::Code new_code;
|
||||
packet >> new_code.address;
|
||||
packet >> new_code.data;
|
||||
|
||||
NOTICE_LOG(ACTIONREPLAY, "Received %08x %08x", new_code.address, new_code.data);
|
||||
|
||||
gcode.codes.push_back(std::move(new_code));
|
||||
|
||||
if (++m_sync_gecko_codes_success_count >= m_sync_gecko_codes_count)
|
||||
{
|
||||
m_sync_gecko_codes_complete = true;
|
||||
SyncCodeResponse(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Add gcode containing all codes to Gecko Code vector
|
||||
synced_codes.push_back(std::move(gcode));
|
||||
|
||||
// Clear Vector if received 0 codes (match host's end when using no codes)
|
||||
if (m_sync_gecko_codes_count == 0)
|
||||
synced_codes.clear();
|
||||
|
||||
// Copy this to the vector located in GeckoCode.cpp
|
||||
Gecko::UpdateSyncedCodes(synced_codes);
|
||||
}
|
||||
break;
|
||||
|
||||
case SYNC_CODES_NOTIFY_AR:
|
||||
{
|
||||
// Return if this is the host
|
||||
if (m_local_player->IsHost())
|
||||
return 0;
|
||||
|
||||
// Receive Number of Codelines to Receive
|
||||
packet >> m_sync_ar_codes_count;
|
||||
|
||||
m_sync_ar_codes_success_count = 0;
|
||||
|
||||
NOTICE_LOG(ACTIONREPLAY, "Receiving %d AR codelines", m_sync_ar_codes_count);
|
||||
|
||||
// Check if no codes to sync, if so return as finished
|
||||
if (m_sync_ar_codes_count == 0)
|
||||
{
|
||||
m_sync_ar_codes_complete = true;
|
||||
SyncCodeResponse(true);
|
||||
}
|
||||
else
|
||||
m_dialog->AppendChat(GetStringT("Synchronizing AR codes..."));
|
||||
}
|
||||
break;
|
||||
|
||||
case SYNC_CODES_DATA_AR:
|
||||
{
|
||||
// Return if this is the host
|
||||
if (m_local_player->IsHost())
|
||||
return 0;
|
||||
|
||||
// Create a synced code vector
|
||||
std::vector<ActionReplay::ARCode> synced_codes;
|
||||
// Create an ARCode
|
||||
ActionReplay::ARCode arcode;
|
||||
arcode = ActionReplay::ARCode();
|
||||
// Initialize arcode
|
||||
arcode.name = "Synced Codes";
|
||||
arcode.active = true;
|
||||
|
||||
// Receive code contents from packet
|
||||
for (int i = 0; i < m_sync_ar_codes_count; i++)
|
||||
{
|
||||
ActionReplay::AREntry new_code;
|
||||
packet >> new_code.cmd_addr;
|
||||
packet >> new_code.value;
|
||||
|
||||
NOTICE_LOG(ACTIONREPLAY, "Received %08x %08x", new_code.cmd_addr, new_code.value);
|
||||
arcode.ops.push_back(new_code);
|
||||
|
||||
if (++m_sync_ar_codes_success_count >= m_sync_ar_codes_count)
|
||||
{
|
||||
m_sync_ar_codes_complete = true;
|
||||
SyncCodeResponse(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Add arcode containing all codes to AR Code vector
|
||||
synced_codes.push_back(std::move(arcode));
|
||||
|
||||
// Clear Vector if received 0 codes (match host's end when using no codes)
|
||||
if (m_sync_ar_codes_count == 0)
|
||||
synced_codes.clear();
|
||||
|
||||
// Copy this to the vector located in ActionReplay.cpp
|
||||
ActionReplay::UpdateSyncedCodes(synced_codes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NP_MSG_COMPUTE_MD5:
|
||||
{
|
||||
std::string file_identifier;
|
||||
@@ -1193,6 +1356,34 @@ void NetPlayClient::SyncSaveDataResponse(const bool success)
|
||||
}
|
||||
}
|
||||
|
||||
void NetPlayClient::SyncCodeResponse(const bool success)
|
||||
{
|
||||
// If something failed, immediately report back that code sync failed
|
||||
if (!success)
|
||||
{
|
||||
m_dialog->AppendChat(GetStringT("Error processing Codes."));
|
||||
|
||||
sf::Packet response_packet;
|
||||
response_packet << static_cast<MessageId>(NP_MSG_SYNC_CODES);
|
||||
response_packet << static_cast<MessageId>(SYNC_CODES_FAILURE);
|
||||
|
||||
Send(response_packet);
|
||||
return;
|
||||
}
|
||||
|
||||
// If both gecko and AR codes have completely finished transferring, report back as successful
|
||||
if (m_sync_gecko_codes_complete && m_sync_ar_codes_complete)
|
||||
{
|
||||
m_dialog->AppendChat(GetStringT("Codes received!"));
|
||||
|
||||
sf::Packet response_packet;
|
||||
response_packet << static_cast<MessageId>(NP_MSG_SYNC_CODES);
|
||||
response_packet << static_cast<MessageId>(SYNC_CODES_SUCCESS);
|
||||
|
||||
Send(response_packet);
|
||||
}
|
||||
}
|
||||
|
||||
bool NetPlayClient::DecompressPacketIntoFile(sf::Packet& packet, const std::string& file_path)
|
||||
{
|
||||
u64 file_size = Common::PacketReadU64(packet);
|
||||
|
||||
Reference in new issue
Block a user