Permalink
Browse files

Merge pull request #7222 from Techjar/netplay-sync-saves

NetPlay save data synchronization
  • Loading branch information...
spycrab committed Jul 21, 2018
2 parents bcd2a76 + 4407854 commit c141511c87a8edfa1f273e8fdb13609def89efa8
Showing with 1,249 additions and 208 deletions.
  1. +1 −0 Source/Core/Common/CMakeLists.txt
  2. +2 −0 Source/Core/Common/Common.vcxproj
  3. +2 −0 Source/Core/Common/Common.vcxproj.filters
  4. +1 −0 Source/Core/Common/CommonPaths.h
  5. +38 −0 Source/Core/Common/SFMLHelper.cpp
  6. +23 −0 Source/Core/Common/SFMLHelper.h
  7. +6 −0 Source/Core/Core/Config/MainSettings.cpp
  8. +3 −0 Source/Core/Core/Config/MainSettings.h
  9. +19 −0 Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp
  10. +0 −54 Source/Core/Core/ConfigManager.cpp
  11. +0 −3 Source/Core/Core/ConfigManager.h
  12. +1 −0 Source/Core/Core/Core.vcxproj
  13. +3 −0 Source/Core/Core/Core.vcxproj.filters
  14. +40 −11 Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp
  15. +59 −3 Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
  16. +2 −0 Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.h
  17. +49 −0 Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp
  18. +1 −0 Source/Core/Core/HW/GCMemcard/GCMemcardRaw.h
  19. +1 −90 Source/Core/Core/HW/WiiSave.cpp
  20. +112 −0 Source/Core/Core/HW/WiiSaveStructs.h
  21. +2 −2 Source/Core/Core/Movie.cpp
  22. +343 −6 Source/Core/Core/NetPlayClient.cpp
  23. +18 −0 Source/Core/Core/NetPlayClient.h
  24. +24 −1 Source/Core/Core/NetPlayProto.h
  25. +386 −7 Source/Core/Core/NetPlayServer.cpp
  26. +7 −0 Source/Core/Core/NetPlayServer.h
  27. +37 −9 Source/Core/Core/WiiRoot.cpp
  28. +1 −1 Source/Core/Core/WiiRoot.h
  29. +3 −0 Source/Core/DolphinQt/MainWindow.cpp
  30. +51 −15 Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp
  31. +6 −0 Source/Core/DolphinQt/NetPlay/NetPlayDialog.h
  32. +8 −6 Source/Core/DolphinQt/Settings/GameCubePane.cpp
@@ -36,6 +36,7 @@ add_library(common
QoSSession.cpp
Random.cpp
SDCardUtil.cpp
SFMLHelper.cpp
SettingsHandler.cpp
StringUtil.cpp
SymbolDB.cpp
@@ -147,6 +147,7 @@
<ClInclude Include="Result.h" />
<ClInclude Include="ScopeGuard.h" />
<ClInclude Include="SDCardUtil.h" />
<ClInclude Include="SFMLHelper.h" />
<ClInclude Include="Semaphore.h" />
<ClInclude Include="SettingsHandler.h" />
<ClInclude Include="SPSCQueue.h" />
@@ -210,6 +211,7 @@
<ClCompile Include="QoSSession.cpp" />
<ClCompile Include="Random.cpp" />
<ClCompile Include="SDCardUtil.cpp" />
<ClCompile Include="SFMLHelper.cpp" />
<ClCompile Include="SettingsHandler.cpp" />
<ClCompile Include="StringUtil.cpp" />
<ClCompile Include="SymbolDB.cpp" />
@@ -68,6 +68,7 @@
<ClInclude Include="Result.h" />
<ClInclude Include="ScopeGuard.h" />
<ClInclude Include="SDCardUtil.h" />
<ClInclude Include="SFMLHelper.h" />
<ClInclude Include="SettingsHandler.h" />
<ClInclude Include="SPSCQueue.h" />
<ClInclude Include="StringUtil.h" />
@@ -299,6 +300,7 @@
<ClCompile Include="Profiler.cpp" />
<ClCompile Include="Random.cpp" />
<ClCompile Include="SDCardUtil.cpp" />
<ClCompile Include="SFMLHelper.cpp" />
<ClCompile Include="SettingsHandler.cpp" />
<ClCompile Include="StringUtil.cpp" />
<ClCompile Include="SymbolDB.cpp" />
@@ -109,6 +109,7 @@
#define GC_SRAM "SRAM.raw"
#define GC_MEMCARDA "MemoryCardA"
#define GC_MEMCARDB "MemoryCardB"
#define GC_MEMCARD_NETPLAY "NetPlayTemp"
#define WII_STATE "state.dat"
@@ -0,0 +1,38 @@
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "Common/SFMLHelper.h"
#include <SFML/Network/Packet.hpp>
namespace Common
{
// This only exists as a helper for BigEndianValue
u16 PacketReadU16(sf::Packet& packet)
{
u16 tmp;
packet >> tmp;
return tmp;
}
// This only exists as a helper for BigEndianValue
u32 PacketReadU32(sf::Packet& packet)
{
u32 tmp;
packet >> tmp;
return tmp;
}
u64 PacketReadU64(sf::Packet& packet)
{
u32 low, high;
packet >> low >> high;
return low | (static_cast<u64>(high) << 32);
}
void PacketWriteU64(sf::Packet& packet, const u64 value)
{
packet << static_cast<u32>(value) << static_cast<u32>(value >> 32);
}
} // namespace Common
@@ -0,0 +1,23 @@
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include "Common/CommonTypes.h"
namespace sf
{
class Packet;
}
namespace Common
{
template <typename value_type>
struct BigEndianValue;
u16 PacketReadU16(sf::Packet& packet);
u32 PacketReadU32(sf::Packet& packet);
u64 PacketReadU64(sf::Packet& packet);
void PacketWriteU64(sf::Packet& packet, u64 value);
} // namespace Common
@@ -36,6 +36,12 @@ const ConfigInfo<std::string> MAIN_MEMCARD_A_PATH{{System::Main, "Core", "Memcar
const ConfigInfo<std::string> MAIN_MEMCARD_B_PATH{{System::Main, "Core", "MemcardBPath"}, ""};
const ConfigInfo<std::string> MAIN_AGP_CART_A_PATH{{System::Main, "Core", "AgpCartAPath"}, ""};
const ConfigInfo<std::string> MAIN_AGP_CART_B_PATH{{System::Main, "Core", "AgpCartBPath"}, ""};
const ConfigInfo<std::string> MAIN_GCI_FOLDER_A_PATH_OVERRIDE{
{System::Main, "Core", "GCIFolderAPathOverride"}, ""};
const ConfigInfo<std::string> MAIN_GCI_FOLDER_B_PATH_OVERRIDE{
{System::Main, "Core", "GCIFolderBPathOverride"}, ""};
const ConfigInfo<bool> MAIN_GCI_FOLDER_CURRENT_GAME_ONLY{
{System::Main, "Core", "GCIFolderCurrentGameOnly"}, false};
const ConfigInfo<int> MAIN_SLOT_A{{System::Main, "Core", "SlotA"},
ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER};
const ConfigInfo<int> MAIN_SLOT_B{{System::Main, "Core", "SlotB"},
@@ -37,6 +37,9 @@ extern const ConfigInfo<std::string> MAIN_MEMCARD_A_PATH;
extern const ConfigInfo<std::string> MAIN_MEMCARD_B_PATH;
extern const ConfigInfo<std::string> MAIN_AGP_CART_A_PATH;
extern const ConfigInfo<std::string> MAIN_AGP_CART_B_PATH;
extern const ConfigInfo<std::string> MAIN_GCI_FOLDER_A_PATH_OVERRIDE;
extern const ConfigInfo<std::string> MAIN_GCI_FOLDER_B_PATH_OVERRIDE;
extern const ConfigInfo<bool> MAIN_GCI_FOLDER_CURRENT_GAME_ONLY;
extern const ConfigInfo<int> MAIN_SLOT_A;
extern const ConfigInfo<int> MAIN_SLOT_B;
extern const ConfigInfo<int> MAIN_SERIAL_PORT_1;
@@ -6,7 +6,9 @@
#include <memory>
#include "Common/CommonPaths.h"
#include "Common/Config/Config.h"
#include "Common/FileUtil.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
#include "Core/NetPlayProto.h"
@@ -39,6 +41,23 @@ class NetPlayConfigLayerLoader final : public Config::ConfigLayerLoader
layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, m_settings.m_ProgressiveScan);
layer->Set(Config::SYSCONF_PAL60, m_settings.m_PAL60);
if (m_settings.m_SyncSaveData)
{
if (!m_settings.m_IsHosting)
{
const std::string path = File::GetUserPath(D_GCUSER_IDX) + GC_MEMCARD_NETPLAY DIR_SEP;
layer->Set(Config::MAIN_GCI_FOLDER_A_PATH_OVERRIDE, path + "Card A");
layer->Set(Config::MAIN_GCI_FOLDER_B_PATH_OVERRIDE, path + "Card B");
const std::string file = File::GetUserPath(D_GCUSER_IDX) + GC_MEMCARD_NETPLAY + "%c." +
m_settings.m_SaveDataRegion + ".raw";
layer->Set(Config::MAIN_MEMCARD_A_PATH, StringFromFormat(file.c_str(), 'A'));
layer->Set(Config::MAIN_MEMCARD_B_PATH, StringFromFormat(file.c_str(), 'B'));
}
layer->Set(Config::MAIN_GCI_FOLDER_CURRENT_GAME_ONLY, true);
}
}
void Save(Config::Layer* layer) override
@@ -227,8 +227,6 @@ void SConfig::SaveCoreSettings(IniFile& ini)
core->Set("AudioLatency", iLatency);
core->Set("AudioStretch", m_audio_stretch);
core->Set("AudioStretchMaxLatency", m_audio_stretch_max_latency);
core->Set("MemcardAPath", m_strMemoryCardA);
core->Set("MemcardBPath", m_strMemoryCardB);
core->Set("AgpCartAPath", m_strGbaCartA);
core->Set("AgpCartBPath", m_strGbaCartB);
core->Set("SlotA", m_EXIDevice[0]);
@@ -505,8 +503,6 @@ void SConfig::LoadCoreSettings(IniFile& ini)
core->Get("AudioLatency", &iLatency, 20);
core->Get("AudioStretch", &m_audio_stretch, false);
core->Get("AudioStretchMaxLatency", &m_audio_stretch_max_latency, 80);
core->Get("MemcardAPath", &m_strMemoryCardA);
core->Get("MemcardBPath", &m_strMemoryCardB);
core->Get("AgpCartAPath", &m_strGbaCartA);
core->Get("AgpCartBPath", &m_strGbaCartB);
core->Get("SlotA", (int*)&m_EXIDevice[0], ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER);
@@ -947,62 +943,12 @@ bool SConfig::SetPathsAndGameMetadata(const BootParameters& boot)
// Set up paths
const std::string region_dir = GetDirectoryForRegion(ToGameCubeRegion(m_region));
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, region_dir, true);
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, region_dir, false);
m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
m_strBootROM = GetBootROMPath(region_dir);
return true;
}
void SConfig::CheckMemcardPath(std::string& memcardPath, const std::string& gameRegion,
bool isSlotA)
{
std::string ext("." + gameRegion + ".raw");
if (memcardPath.empty())
{
// Use default memcard path if there is no user defined name
std::string defaultFilename = isSlotA ? GC_MEMCARDA : GC_MEMCARDB;
memcardPath = File::GetUserPath(D_GCUSER_IDX) + defaultFilename + ext;
}
else
{
std::string filename = memcardPath;
std::string region = filename.substr(filename.size() - 7, 3);
bool hasregion = false;
hasregion |= region.compare(USA_DIR) == 0;
hasregion |= region.compare(JAP_DIR) == 0;
hasregion |= region.compare(EUR_DIR) == 0;
if (!hasregion)
{
// filename doesn't have region in the extension
if (File::Exists(filename))
{
// If the old file exists we are polite and ask if we should copy it
std::string oldFilename = filename;
filename.replace(filename.size() - 4, 4, ext);
if (PanicYesNoT("Memory Card filename in Slot %c is incorrect\n"
"Region not specified\n\n"
"Slot %c path was changed to\n"
"%s\n"
"Would you like to copy the old file to this new location?\n",
isSlotA ? 'A' : 'B', isSlotA ? 'A' : 'B', filename.c_str()))
{
if (!File::Copy(oldFilename, filename))
PanicAlertT("Copy failed");
}
}
memcardPath = filename; // Always correct the path!
}
else if (region.compare(gameRegion) != 0)
{
// filename has region, but it's not == gameRegion
// Just set the correct filename, the EXI Device will create it if it doesn't exist
memcardPath = filename.replace(filename.size() - ext.size(), ext.size(), ext);
}
}
}
DiscIO::Language SConfig::GetCurrentLanguage(bool wii) const
{
int language_value;
@@ -212,7 +212,6 @@ struct SConfig
static const char* GetDirectoryForRegion(DiscIO::Region region);
std::string GetBootROMPath(const std::string& region_directory) const;
bool SetPathsAndGameMetadata(const BootParameters& boot);
void CheckMemcardPath(std::string& memcardPath, const std::string& gameRegion, bool isSlotA);
DiscIO::Language GetCurrentLanguage(bool wii) const;
IniFile LoadDefaultGameIni() const;
@@ -223,8 +222,6 @@ struct SConfig
static IniFile LoadLocalGameIni(const std::string& id, std::optional<u16> revision);
static IniFile LoadGameIni(const std::string& id, std::optional<u16> revision);
std::string m_strMemoryCardA;
std::string m_strMemoryCardB;
std::string m_strGbaCartA;
std::string m_strGbaCartB;
ExpansionInterface::TEXIDevices m_EXIDevice[3];
@@ -448,6 +448,7 @@
<ClInclude Include="HW\WiimoteReal\WiimoteReal.h" />
<ClInclude Include="HW\WiimoteReal\WiimoteRealBase.h" />
<ClInclude Include="HW\WiiSave.h" />
<ClInclude Include="HW\WiiSaveStructs.h" />
<ClInclude Include="HW\WII_IPC.h" />
<ClInclude Include="IOS\Device.h" />
<ClInclude Include="IOS\DeviceStub.h" />
@@ -1272,6 +1272,9 @@
<ClInclude Include="HW\WiiSave.h">
<Filter>HW %28Flipper/Hollywood%29</Filter>
</ClInclude>
<ClInclude Include="HW\WiiSaveStructs.h">
<Filter>HW %28Flipper/Hollywood%29</Filter>
</ClInclude>
<ClInclude Include="DSP\DSPAssembler.h">
<Filter>DSPCore</Filter>
</ClInclude>
@@ -13,12 +13,14 @@
#include "Common/ChunkFile.h"
#include "Common/CommonPaths.h"
#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Common/Logging/Log.h"
#include "Common/NandPaths.h"
#include "Common/StringUtil.h"
#include "Core/CommonTitles.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/CoreTiming.h"
#include "Core/HW/EXI/EXI.h"
@@ -31,6 +33,7 @@
#include "Core/HW/Sram.h"
#include "Core/HW/SystemTimers.h"
#include "Core/Movie.h"
#include "Core/NetPlayProto.h"
#include "DiscIO/Enums.h"
namespace ExpansionInterface
@@ -169,24 +172,46 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb)
std::string strDirectoryName = File::GetUserPath(D_GCUSER_IDX);
bool migrate = true;
if (Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::IsUsingMemcard(card_index) &&
Movie::IsStartingFromClearSave())
{
strDirectoryName += "Movie" DIR_SEP;
migrate = false;
}
strDirectoryName = strDirectoryName + SConfig::GetDirectoryForRegion(region) + DIR_SEP +
StringFromFormat("Card %c", 'A' + card_index);
const std::string path_override =
Config::Get(card_index == 0 ? Config::MAIN_GCI_FOLDER_A_PATH_OVERRIDE :
Config::MAIN_GCI_FOLDER_B_PATH_OVERRIDE);
if (!path_override.empty())
{
strDirectoryName = path_override;
migrate = false;
}
else
{
strDirectoryName = strDirectoryName + SConfig::GetDirectoryForRegion(region) + DIR_SEP +
StringFromFormat("Card %c", 'A' + card_index);
}
const File::FileInfo file_info(strDirectoryName);
if (!file_info.Exists()) // first use of memcard folder, migrate automatically
if (!file_info.Exists())
{
MigrateFromMemcardFile(strDirectoryName + DIR_SEP, card_index);
if (migrate) // first use of memcard folder, migrate automatically
MigrateFromMemcardFile(strDirectoryName + DIR_SEP, card_index);
else
File::CreateFullPath(strDirectoryName + DIR_SEP);
}
else if (!file_info.IsDirectory())
{
if (File::Rename(strDirectoryName, strDirectoryName + ".original"))
{
PanicAlertT("%s was not a directory, moved to *.original", strDirectoryName.c_str());
MigrateFromMemcardFile(strDirectoryName + DIR_SEP, card_index);
if (migrate)
MigrateFromMemcardFile(strDirectoryName + DIR_SEP, card_index);
else
File::CreateFullPath(strDirectoryName + DIR_SEP);
}
else // we tried but the user wants to crash
{
@@ -204,17 +229,21 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb)
void CEXIMemoryCard::SetupRawMemcard(u16 sizeMb)
{
std::string filename = (card_index == 0) ? SConfig::GetInstance().m_strMemoryCardA :
SConfig::GetInstance().m_strMemoryCardB;
const bool is_slot_a = card_index == 0;
std::string filename = is_slot_a ? Config::Get(Config::MAIN_MEMCARD_A_PATH) :
Config::Get(Config::MAIN_MEMCARD_B_PATH);
if (Movie::IsPlayingInput() && Movie::IsConfigSaved() && Movie::IsUsingMemcard(card_index) &&
Movie::IsStartingFromClearSave())
filename = File::GetUserPath(D_GCUSER_IDX) +
StringFromFormat("Movie%s.raw", (card_index == 0) ? "A" : "B");
filename =
File::GetUserPath(D_GCUSER_IDX) + StringFromFormat("Movie%s.raw", is_slot_a ? "A" : "B");
const std::string region_dir =
SConfig::GetDirectoryForRegion(SConfig::ToGameCubeRegion(SConfig::GetInstance().m_region));
MemoryCard::CheckPath(filename, region_dir, is_slot_a);
if (sizeMb == MemCard251Mb)
{
filename.insert(filename.find_last_of("."), ".251");
}
memorycard = std::make_unique<MemoryCard>(filename, card_index, sizeMb);
}
Oops, something went wrong.

0 comments on commit c141511

Please sign in to comment.