Skip to content

Commit

Permalink
Add default support for WiiLink + configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
noahpistilli committed Jun 17, 2023
1 parent 63090d4 commit fa0f536
Show file tree
Hide file tree
Showing 18 changed files with 288 additions and 21 deletions.
5 changes: 5 additions & 0 deletions Data/Sys/GameSettings/HAF.ini
@@ -0,0 +1,5 @@
# HAFE01 - Forecast Channel

[WC24Patch]
$Main
weather.wapp.wii.com:fore.wiilink24.com:1
20 changes: 0 additions & 20 deletions Data/Sys/GameSettings/HAT.ini

This file was deleted.

38 changes: 38 additions & 0 deletions Data/Sys/GameSettings/HATE01.ini
@@ -0,0 +1,38 @@
# HATE01 - Nintendo Channel (NTSC-U)

[Core]
# Values set here will override the main Dolphin settings.

[OnLoad]
# Add memory patches to be loaded once on boot here.

[OnFrame]
# Add memory patches to be applied every frame here.

[ActionReplay]
# Add action replay cheats here.

[Video]

[Video_Settings]

[Video_Hacks]
ImmediateXFBEnable = False

[Gecko]
$SSL Patch [Papelli]
2A35AB5C 00003A2F
80010000 0035AA4D
8A00570F 0035AA4C
80010000 0035AACD
8A00380F 0035AACC
80010000 0035AB0D
8A004A0F 0035AB0C
80010000 0035AB5D
8A00390F 0035AB5C
E2000001 00000000

[WC24Patch]
$Main
a248.e.akamai.net:nc.wiinoma.com:0
entu.wapp.wii.com:ncc.wiilink24.com:1
2 changes: 2 additions & 0 deletions Source/Core/Core/CMakeLists.txt
Expand Up @@ -516,6 +516,8 @@ add_library(core
System.h
TitleDatabase.cpp
TitleDatabase.h
WC24PatchEngine.cpp
WC24PatchEngine.h
WiiRoot.cpp
WiiRoot.h
WiiUtils.cpp
Expand Down
24 changes: 24 additions & 0 deletions Source/Core/Core/CommonTitles.h
Expand Up @@ -15,6 +15,30 @@ constexpr u64 SHOP = 0x0001000248414241;

constexpr u64 KOREAN_SHOP = 0x000100024841424b;

constexpr u64 FORECAST_CHANNEL_NTSC_U = 0x0001000248414645;

constexpr u64 FORECAST_CHANNEL_NTSC_J = 0x000100024841464a;

constexpr u64 FORECAST_CHANNEL_PAL = 0x0001000248414650;

constexpr u64 NINTENDO_CHANNEL_NTSC_U = 0x0001000148415445;

constexpr u64 NINTENDO_CHANNEL_NTSC_J = 0x000100014841544a;

constexpr u64 NINTENDO_CHANNEL_PAL = 0x0001000148415450;

constexpr u64 NEWS_CHANNEL_NTSC_U = 0x0001000248414745;

constexpr u64 NEWS_CHANNEL_NTSC_J = 0x000100024841474a;

constexpr u64 NEWS_CHANNEL_PAL = 0x0001000248414750;

constexpr u64 EVERYBODY_VOTES_CHANNEL_NTSC_U = 0x0001000148414a45;

constexpr u64 EVERYBODY_VOTES_CHANNEL_NTSC_J = 0x0001000148414a4a;

constexpr u64 EVERYBODY_VOTES_CHANNEL_PAL = 0x0001000148414a50;

constexpr u64 IOS(u32 major_version)
{
return 0x0000000100000000 | major_version;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/Config/MainSettings.cpp
Expand Up @@ -241,6 +241,7 @@ const Info<bool> MAIN_ALLOW_SD_WRITES{{System::Main, "Core", "WiiSDCardAllowWrit
const Info<bool> MAIN_ENABLE_SAVESTATES{{System::Main, "Core", "EnableSaveStates"}, false};
const Info<bool> MAIN_REAL_WII_REMOTE_REPEAT_REPORTS{
{System::Main, "Core", "RealWiiRemoteRepeatReports"}, true};
const Info<bool> MAIN_WII_WIILINK_ENABLE{{System::Main, "Core", "EnableWiiLink"}, true};

// Empty means use the Dolphin default URL
const Info<std::string> MAIN_WII_NUS_SHOP_URL{{System::Main, "Core", "WiiNusShopUrl"}, ""};
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/Config/MainSettings.h
Expand Up @@ -150,6 +150,7 @@ extern const Info<DiscIO::Region> MAIN_FALLBACK_REGION;
extern const Info<bool> MAIN_REAL_WII_REMOTE_REPEAT_REPORTS;
extern const Info<s32> MAIN_OVERRIDE_BOOT_IOS;
extern const Info<std::string> MAIN_WII_NUS_SHOP_URL;
extern const Info<bool> MAIN_WII_WIILINK_ENABLE;

// Main.DSP

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/ConfigManager.cpp
Expand Up @@ -54,6 +54,7 @@
#include "Core/TitleDatabase.h"
#include "VideoCommon/HiresTextures.h"

#include "Core/WC24PatchEngine.h"
#include "DiscIO/Enums.h"
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeWad.h"
Expand Down Expand Up @@ -206,6 +207,7 @@ void SConfig::OnNewTitleLoad(const Core::CPUThreadGuard& guard)
HLE::Reload(system);
PatchEngine::Reload();
HiresTexture::Update();
WC24PatchEngine::Reload();
}

void SConfig::LoadDefaults()
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/Core/IOS/Network/IP/Top.cpp
Expand Up @@ -32,6 +32,7 @@
#include "Core/IOS/Network/MACUtils.h"
#include "Core/IOS/Network/Socket.h"
#include "Core/System.h"
#include "Core/WC24PatchEngine.h"

#ifdef _WIN32
#include <iphlpapi.h>
Expand Down Expand Up @@ -1056,6 +1057,11 @@ IPCReply NetIPTopDevice::HandleGetAddressInfoRequest(const IOCtlVRequest& reques
if (!request.in_vectors.empty() && request.in_vectors[0].size > 0)
{
nodeNameStr = memory.GetString(request.in_vectors[0].address, request.in_vectors[0].size);
if (std::optional<std::string> patch =
WC24PatchEngine::GetNetworkPatch(nodeNameStr, WC24PatchEngine::IsKD{false}))
{
nodeNameStr = patch.value();
}
pNodeName = nodeNameStr.c_str();
}

Expand Down
5 changes: 5 additions & 0 deletions Source/Core/Core/IOS/Network/KD/NWC24DL.cpp
Expand Up @@ -140,4 +140,9 @@ void NWC24Dl::SetVersion(u32 version)
m_data.header.version = Common::swap32(version);
}

u32 NWC24Dl::GetHighTitleID(u16 entry_index) const
{
return Common::swap32(m_data.entries[entry_index].high_title_id);
}

} // namespace IOS::HLE::NWC24
1 change: 1 addition & 0 deletions Source/Core/Core/IOS/Network/KD/NWC24DL.h
Expand Up @@ -33,6 +33,7 @@ class NWC24Dl final
std::string GetDownloadURL(u16 entry_index, std::optional<u8> subtask_id) const;
std::string GetVFFPath(u16 entry_index) const;
WC24PubkMod GetWC24PubkMod(u16 entry_index) const;
u32 GetHighTitleID(u16 entry_index) const;

u32 Magic() const;
void SetMagic(u32 magic);
Expand Down
18 changes: 17 additions & 1 deletion Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp
Expand Up @@ -24,6 +24,7 @@
#include "Core/IOS/Network/Socket.h"
#include "Core/IOS/Uids.h"
#include "Core/System.h"
#include "Core/WC24PatchEngine.h"

namespace IOS::HLE
{
Expand Down Expand Up @@ -217,7 +218,22 @@ NWC24::ErrorCode NetKDRequestDevice::KDDownload(const u16 entry_index,

// Content metadata
const std::string content_name = m_dl_list.GetVFFContentName(entry_index, subtask_id);
const std::string url = m_dl_list.GetDownloadURL(entry_index, subtask_id);
std::string url = m_dl_list.GetDownloadURL(entry_index, subtask_id);

// Reroute to custom server if enabled.
const std::vector<std::string> parts = SplitString(url, '/');
if (parts.size() < 3)
{
// Invalid URL
LogError(ErrorType::KD_Download, NWC24::WC24_ERR_SERVER);
return NWC24::WC24_ERR_SERVER;
}

if (std::optional<std::string> patch =
WC24PatchEngine::GetNetworkPatch(parts[2], WC24PatchEngine::IsKD{true}))
{
url = ReplaceAll(url, parts[2], patch.value());
}

INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_DOWNLOAD_NOW_EX - NI - URL: {}", url);

Expand Down
7 changes: 7 additions & 0 deletions Source/Core/Core/IOS/Network/Socket.cpp
Expand Up @@ -27,6 +27,7 @@
#include "Core/IOS/IOS.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "Core/WC24PatchEngine.h"

#ifdef _WIN32
#define ERRORCODE(name) WSA##name
Expand Down Expand Up @@ -581,6 +582,12 @@ void WiiSocket::Update(bool read, bool write, bool except)

// Not a string, Windows requires a const char* for sendto
const char* data = (const char*)memory.GetPointer(BufferIn);
const std::optional<std::string> patch = WC24PatchEngine::GetNetworkPatchByPayload(data);
if (patch)
{
data = patch->c_str();
BufferInSize = static_cast<u32>(patch->size());
}

// Act as non blocking when SO_MSG_NONBLOCK is specified
forceNonBlock = ((flags & SO_MSG_NONBLOCK) == SO_MSG_NONBLOCK);
Expand Down
136 changes: 136 additions & 0 deletions Source/Core/Core/WC24PatchEngine.cpp
@@ -0,0 +1,136 @@
// 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 "Common/StringUtil.h"
#include "Core/CheatCodes.h"
#include "Core/CommonTitles.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"

namespace WC24PatchEngine
{
static std::array<u64, 12> s_wc24_channels{
// Nintendo Channel
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,
};

static std::vector<NetworkPatch> s_patches;

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;
}

void LoadPatchSection(const Common::IniFile& ini)
{
std::vector<std::string> lines;
NetworkPatch patch;
ini.GetLines("WC24Patch", &lines);

for (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);
}

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);
}

bool IsWC24Channel()
{
const auto& sconfig = SConfig::GetInstance();
const auto found =
std::find(s_wc24_channels.begin(), s_wc24_channels.end(), sconfig.GetTitleID());

return found != s_wc24_channels.end();
}

void Reload()
{
s_patches.clear();
LoadPatches();
}

std::optional<std::string> GetNetworkPatch(const std::string& source, IsKD is_kd)
{
const auto patch =
std::find_if(s_patches.begin(), s_patches.end(), [&source, &is_kd](NetworkPatch& patch) {
return patch.source == source && patch.is_kd == is_kd;
});
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)
{
for (const NetworkPatch& patch : s_patches)
{
if (source.find(patch.source) != std::string::npos && patch.is_kd != IsKD{true})
// We found the correct patch, return it!
return ReplaceAll(std::string{source}, patch.source, patch.replacement);
}

return std::nullopt;
}
} // namespace WC24PatchEngine
30 changes: 30 additions & 0 deletions Source/Core/Core/WC24PatchEngine.h
@@ -0,0 +1,30 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <optional>
#include <string>

#include "Common/IniFile.h"

namespace WC24PatchEngine
{
enum class IsKD : bool;

struct NetworkPatch final
{
std::string name;
std::string source;
std::string replacement;
bool enabled = false;
IsKD is_kd = IsKD{false};
};

void Reload();
bool DeserializeLine(const std::string& line, NetworkPatch* patch);
bool IsWC24Channel();
void LoadPatchSection(const Common::IniFile& ini);
std::optional<std::string> GetNetworkPatch(const std::string& source, IsKD is_kd);
std::optional<std::string> GetNetworkPatchByPayload(std::string_view source);
} // namespace WC24PatchEngine

0 comments on commit fa0f536

Please sign in to comment.