Skip to content

Commit 4a880c1

Browse files
committed
feat: Check title version before doing game specific patches
1 parent 79ccad1 commit 4a880c1

File tree

4 files changed

+61
-11
lines changed

4 files changed

+61
-11
lines changed

src/patches/account_settings.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
#include "inkay_config.h"
2525

2626
#include <function_patcher/function_patching.h>
27-
#include <vector>
28-
#include <optional>
29-
#include <coreinit/debug.h>
27+
3028
#include <coreinit/filesystem.h>
3129
#include <coreinit/title.h>
32-
#include <nsysnet/nssl.h>
30+
31+
#include <vector>
32+
#include <optional>
3333

3434
#include "ca_pem.h" // generated at buildtime
3535

@@ -163,7 +163,7 @@ bool hotpatchAccountSettings() {
163163
}
164164

165165
void unpatchAccountSettings() {
166-
for (auto handle: account_patches) {
166+
for (const auto handle: account_patches) {
167167
FunctionPatcher_RemoveFunctionPatch(handle);
168168
}
169169
account_patches.clear();

src/patches/game_peertopeer.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,23 @@ using namespace std::string_view_literals;
2828

2929
static struct {
3030
std::array<uint64_t, 3> tid;
31+
uint16_t version;
3132
uint32_t min_port_addr;
3233
uint32_t max_port_addr;
3334
std::string_view rpx;
34-
} generic_patch_games [] = {
35-
{ // MARIO KART 8
36-
{ 0x00050000'1010ec00, 0x00050000'1010ed00, 0x00050000'1010eb00 },
35+
} generic_patch_games[] = {
36+
{
37+
// MARIO KART 8
38+
{0x00050000'1010ec00, 0x00050000'1010ed00, 0x00050000'1010eb00},
39+
81,
3740
0x101a9a52,
3841
0x101a9a54,
3942
"Turbo.rpx"sv,
4043
},
41-
{ // Splatoon
42-
{ 0x00050000'10176900, 0x00050000'10176a00, 0x00050000'10162b00 },
44+
{
45+
// Splatoon
46+
{0x00050000'10176900, 0x00050000'10176a00, 0x00050000'10162b00},
47+
288,
4348
0x101e8952,
4449
0x101e8954,
4550
"Gambit.rpx"sv,
@@ -48,8 +53,16 @@ static struct {
4853

4954
static void generic_peertopeer_patch() {
5055
uint64_t tid = OSGetTitleID();
56+
uint16_t title_version = 0;
57+
if (const auto version_opt = get_current_title_version(); !version_opt) {
58+
DEBUG_FUNCTION_LINE("Failed to detect current title version");
59+
return;
60+
} else {
61+
title_version = *version_opt;
62+
DEBUG_FUNCTION_LINE("Title version detected: %d", title_version);
63+
}
5164

52-
for (const auto& patch : generic_patch_games) {
65+
for (const auto &patch: generic_patch_games) {
5366
if (std::ranges::find(patch.tid, tid) == patch.tid.end()) continue;
5467

5568
std::optional<OSDynLoad_NotifyData> game = search_for_rpl(patch.rpx);
@@ -58,6 +71,12 @@ static void generic_peertopeer_patch() {
5871
return;
5972
}
6073

74+
if (title_version != patch.version) {
75+
DEBUG_FUNCTION_LINE("Unexpected title version. Expected %d but got %d (%s)", patch.version, title_version,
76+
patch.rpx.data());
77+
continue;
78+
}
79+
6180
auto port = get_console_peertopeer_port();
6281
DEBUG_FUNCTION_LINE_VERBOSE("Will use port %d. %08x", port, game->textAddr);
6382

@@ -76,6 +95,10 @@ static void minecraft_peertopeer_patch() {
7695
DEBUG_FUNCTION_LINE("Couldn't find minecraft rpx!");
7796
return;
7897
}
98+
if (const auto version_opt = get_current_title_version(); !version_opt || *version_opt != 688) {
99+
DEBUG_FUNCTION_LINE("Wrong mincecraft version detected");
100+
return;
101+
}
79102

80103
auto port = get_console_peertopeer_port();
81104
DEBUG_FUNCTION_LINE_VERBOSE("Will use port %d. %08x", port, minecraft->textAddr);

src/utils/rpl_info.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#include <vector>
1717
#include <algorithm>
1818
#include <string_view>
19+
#include <coreinit/mcp.h>
20+
#include <coreinit/title.h>
21+
22+
#include "logger.h"
1923

2024
// if we get more than like.. two callsites for this, it should really be refactored out rather than doing a fresh
2125
// search every time
@@ -37,3 +41,24 @@ std::optional<OSDynLoad_NotifyData> search_for_rpl(std::string_view name) {
3741

3842
return *rpl;
3943
}
44+
45+
std::optional<uint16_t> get_current_title_version() {
46+
const auto mcpHandle = MCP_Open();
47+
MCPTitleListType titleInfo;
48+
int32_t res = -1;
49+
const uint64_t curTitleId = OSGetTitleID();
50+
if ((curTitleId & 0x0000000F00000000) == 0) {
51+
res = MCP_GetTitleInfo(mcpHandle, curTitleId | 0x0000000E00000000, &titleInfo);
52+
}
53+
if (res != 0) {
54+
res = MCP_GetTitleInfo(mcpHandle, curTitleId, &titleInfo);
55+
}
56+
MCP_Close(mcpHandle);
57+
if (res != 0) {
58+
DEBUG_FUNCTION_LINE("Failed to get title version of %016llX.", curTitleId);
59+
return {};
60+
}
61+
MCP_Close(mcpHandle);
62+
const auto tmp_result = titleInfo.titleVersion; // make the compiler happy because we access a packed struct
63+
return tmp_result;
64+
}

src/utils/rpl_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@ constexpr void *rpl_addr(OSDynLoad_NotifyData rpl, uint32_t cemu_addr) {
2626
return (void *)(rpl.dataAddr + cemu_addr - 0x1000'0000);
2727
}
2828
}
29+
30+
std::optional<uint16_t> get_current_title_version();

0 commit comments

Comments
 (0)