mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-06 02:12:39 +00:00
In NandPaths.cpp, the `std::initializer_list<char>` of illegal characters has been turned into a `char[]` (similar to the one in GameList.cpp). The reverse iteration in ResourcePack.cpp seemed to provide no benefits, and doing without it it seemed to have no ill effects.
162 lines
4.2 KiB
C++
162 lines
4.2 KiB
C++
// Copyright 2023 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
// WC24PatchEngine
|
|
// Allows for replacing URLs used in WC24 requests
|
|
|
|
#include "Core/WC24PatchEngine.h"
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <fmt/format.h>
|
|
|
|
#include "Common/Contains.h"
|
|
#include "Common/IniFile.h"
|
|
#include "Common/StringUtil.h"
|
|
|
|
#include "Core/CheatCodes.h"
|
|
#include "Core/CommonTitles.h"
|
|
#include "Core/Config/MainSettings.h"
|
|
#include "Core/ConfigManager.h"
|
|
|
|
namespace WC24PatchEngine
|
|
{
|
|
static constexpr std::array<u64, 15> s_wc24_channels{
|
|
Titles::NINTENDO_CHANNEL_NTSC_U,
|
|
Titles::NINTENDO_CHANNEL_NTSC_J,
|
|
Titles::NINTENDO_CHANNEL_PAL,
|
|
Titles::FORECAST_CHANNEL_NTSC_U,
|
|
Titles::FORECAST_CHANNEL_NTSC_J,
|
|
Titles::FORECAST_CHANNEL_PAL,
|
|
Titles::NEWS_CHANNEL_NTSC_U,
|
|
Titles::NEWS_CHANNEL_NTSC_J,
|
|
Titles::NEWS_CHANNEL_PAL,
|
|
Titles::EVERYBODY_VOTES_CHANNEL_NTSC_U,
|
|
Titles::EVERYBODY_VOTES_CHANNEL_NTSC_J,
|
|
Titles::EVERYBODY_VOTES_CHANNEL_PAL,
|
|
Titles::REGION_SELECT_CHANNEL_NTSC_U,
|
|
Titles::REGION_SELECT_CHANNEL_NTSC_J,
|
|
Titles::REGION_SELECT_CHANNEL_PAL,
|
|
};
|
|
|
|
static std::vector<NetworkPatch> s_patches;
|
|
|
|
static bool DeserializeLine(const std::string& line, NetworkPatch* patch)
|
|
{
|
|
const std::vector<std::string> items = SplitString(line, ':');
|
|
|
|
if (items.size() != 3)
|
|
return false;
|
|
|
|
patch->source = items[0];
|
|
patch->replacement = items[1];
|
|
|
|
if (!TryParse(items[2], &patch->is_kd))
|
|
return false;
|
|
|
|
return patch;
|
|
}
|
|
|
|
static void LoadPatchSection(const Common::IniFile& ini)
|
|
{
|
|
std::vector<std::string> lines;
|
|
NetworkPatch patch;
|
|
ini.GetLines("WC24Patch", &lines);
|
|
|
|
for (const std::string& line : lines)
|
|
{
|
|
if (line.empty())
|
|
continue;
|
|
|
|
if (line[0] == '$')
|
|
{
|
|
patch.name = line.substr(1, line.size() - 1);
|
|
}
|
|
else
|
|
{
|
|
if (DeserializeLine(line, &patch))
|
|
{
|
|
s_patches.push_back(patch);
|
|
}
|
|
}
|
|
}
|
|
|
|
ReadEnabledAndDisabled(ini, "WC24Patch", &s_patches);
|
|
}
|
|
|
|
static bool IsWC24Channel()
|
|
{
|
|
const auto& sconfig = SConfig::GetInstance();
|
|
return Common::Contains(s_wc24_channels, sconfig.GetTitleID());
|
|
}
|
|
|
|
static void LoadPatches()
|
|
{
|
|
const auto& sconfig = SConfig::GetInstance();
|
|
// We can only load WC24 Channels.
|
|
if (!IsWC24Channel())
|
|
return;
|
|
|
|
Common::IniFile ini;
|
|
// If WiiLink is enabled then we load the Default Ini as that has the WiiLink URLs.
|
|
if (Config::Get(Config::MAIN_WII_WIILINK_ENABLE))
|
|
ini = sconfig.LoadDefaultGameIni();
|
|
else
|
|
ini = sconfig.LoadLocalGameIni();
|
|
|
|
LoadPatchSection(ini);
|
|
}
|
|
|
|
void Reload()
|
|
{
|
|
s_patches.clear();
|
|
LoadPatches();
|
|
}
|
|
|
|
std::optional<std::string> GetNetworkPatch(std::string_view source, IsKD is_kd)
|
|
{
|
|
const auto patch = std::ranges::find_if(s_patches, [&source, &is_kd](const NetworkPatch& p) {
|
|
return p.source == source && p.is_kd == is_kd && p.enabled;
|
|
});
|
|
if (patch == s_patches.end())
|
|
return std::nullopt;
|
|
|
|
return patch->replacement;
|
|
}
|
|
|
|
// When we patch for the Socket, we aren't given the URL. Instead, it is in a Host header
|
|
// in the payload that the socket is going to send. We need to manually find which patch to apply.
|
|
std::optional<std::string> GetNetworkPatchByPayload(std::string_view source)
|
|
{
|
|
size_t pos{};
|
|
while (pos < source.size())
|
|
{
|
|
const size_t end_of_line = source.find("\r\n", pos);
|
|
if (source.substr(pos).starts_with("Host: "))
|
|
{
|
|
const std::string_view domain =
|
|
source.substr(pos + 6, end_of_line == std::string_view::npos ? std::string_view::npos :
|
|
(end_of_line - pos - 6));
|
|
for (const WC24PatchEngine::NetworkPatch& patch : s_patches)
|
|
{
|
|
if (patch.is_kd != WC24PatchEngine::IsKD{true} && domain == patch.source && patch.enabled)
|
|
{
|
|
return fmt::format("{}Host: {}{}", source.substr(0, pos), patch.replacement,
|
|
end_of_line == std::string_view::npos ? "" :
|
|
source.substr(end_of_line));
|
|
}
|
|
}
|
|
|
|
// No matching patch
|
|
return std::nullopt;
|
|
}
|
|
|
|
if (end_of_line == std::string_view::npos)
|
|
break;
|
|
|
|
pos = end_of_line + 2;
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
} // namespace WC24PatchEngine
|