forked from PretendoNetwork/Inkay
feat(p2p): Allow overriding the p2p udp port for Minecraft
the idea is that you might port forward this in your router and give yourself NAT type A for free
This commit is contained in:
parent
a1375ca608
commit
22bebff027
10 changed files with 258 additions and 40 deletions
|
|
@ -22,6 +22,7 @@
|
|||
#include <kernel/kernel.h>
|
||||
#include <coreinit/memorymap.h>
|
||||
#include <algorithm>
|
||||
#include <coreinit/cache.h>
|
||||
|
||||
bool replace(uint32_t start, uint32_t size, const char *original_val, size_t original_val_sz, const char *new_val,
|
||||
size_t new_val_sz) {
|
||||
|
|
@ -71,3 +72,18 @@ void replaceBulk(uint32_t start, uint32_t size, std::span<const replacement> rep
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool replace_instruction(uint32_t *inst, uint32_t orignal_value, uint32_t new_value) {
|
||||
if (*inst != orignal_value) return false;
|
||||
|
||||
KernelCopyData(
|
||||
OSEffectiveToPhysical((uint32_t) inst),
|
||||
OSEffectiveToPhysical((uint32_t) &new_value),
|
||||
sizeof(new_value)
|
||||
);
|
||||
DCFlushRange(inst, sizeof(new_value));
|
||||
ICInvalidateRange(inst, sizeof(new_value));
|
||||
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("%08x is now %08x", inst, *inst);
|
||||
return *inst == new_value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,3 +27,5 @@ struct replacement {
|
|||
};
|
||||
|
||||
void replaceBulk(uint32_t start, uint32_t size, std::span<const replacement> replacements);
|
||||
|
||||
bool replace_instruction(uint32_t *inst, uint32_t orignal_value, uint32_t new_value);
|
||||
|
|
|
|||
39
src/utils/rpl_info.cpp
Normal file
39
src/utils/rpl_info.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* Copyright 2024 Pretendo Network contributors <pretendo.network>
|
||||
Copyright 2024 Ash Logan <ash@heyquark.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby
|
||||
granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rpl_info.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
|
||||
// if we get more than like.. two callsites for this, it should really be refactored out rather than doing a fresh
|
||||
// search every time
|
||||
std::optional<OSDynLoad_NotifyData> search_for_rpl(std::string_view name) {
|
||||
int num_rpls = OSDynLoad_GetNumberOfRPLs();
|
||||
if (!num_rpls)
|
||||
return std::nullopt;
|
||||
|
||||
// allocates but we free it at return
|
||||
std::vector<OSDynLoad_NotifyData> rpls(num_rpls);
|
||||
if (!OSDynLoad_GetRPLInfo(0, num_rpls, rpls.data()))
|
||||
return std::nullopt;
|
||||
|
||||
auto rpl = std::find_if(rpls.begin(), rpls.end(), [=](const OSDynLoad_NotifyData &rpl) {
|
||||
return std::string_view(rpl.name).ends_with(name);
|
||||
});
|
||||
if (rpl == rpls.end())
|
||||
return std::nullopt;
|
||||
|
||||
return *rpl;
|
||||
}
|
||||
28
src/utils/rpl_info.h
Normal file
28
src/utils/rpl_info.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright 2024 Pretendo Network contributors <pretendo.network>
|
||||
Copyright 2024 Ash Logan <ash@heyquark.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby
|
||||
granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <coreinit/dynload.h>
|
||||
|
||||
std::optional<OSDynLoad_NotifyData> search_for_rpl(std::string_view name);
|
||||
|
||||
constexpr uint32_t *rpl_addr(OSDynLoad_NotifyData rpl, uint32_t cemu_addr) {
|
||||
if (cemu_addr < 0x1000'0000) {
|
||||
return (uint32_t *)(rpl.textAddr + cemu_addr - 0x0200'0000);
|
||||
} else {
|
||||
return (uint32_t *)(rpl.dataAddr + cemu_addr - 0x1000'0000);
|
||||
}
|
||||
}
|
||||
13
src/utils/scope_exit.h
Normal file
13
src/utils/scope_exit.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
#include <functional>
|
||||
|
||||
// https://stackoverflow.com/a/61242721
|
||||
template<typename F>
|
||||
struct scope_exit
|
||||
{
|
||||
F func;
|
||||
explicit scope_exit(F&& f): func(std::forward<F>(f)) {}
|
||||
~scope_exit() { func(); }
|
||||
};
|
||||
|
||||
template<typename F> scope_exit(F&& frv) -> scope_exit<F>;
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
/* Copyright 2024 Pretendo Network contributors <pretendo.network>
|
||||
Copyright 2024 Ash Logan <ash@heyquark.com>
|
||||
Copyright 2023 Maschell
|
||||
Copyright 2020-2022 V10lator <v10lator@myway.de>
|
||||
Copyright 2022 Xpl0itU <DaThinkingChair@protonmail.com>
|
||||
|
||||
|
|
@ -19,7 +20,9 @@
|
|||
|
||||
#include "sysconfig.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/scope_exit.h"
|
||||
|
||||
#include <coreinit/mcp.h>
|
||||
#include <coreinit/userconfig.h>
|
||||
#include <optional>
|
||||
|
||||
|
|
@ -28,30 +31,69 @@ nn::swkbd::LanguageType get_system_language() {
|
|||
if (cached_language) return *cached_language;
|
||||
|
||||
UCHandle handle = UCOpen();
|
||||
if (handle >= 0) {
|
||||
nn::swkbd::LanguageType language;
|
||||
|
||||
UCSysConfig settings __attribute__((__aligned__(0x40))) = {
|
||||
.name = "cafe.language",
|
||||
.access = 0,
|
||||
.dataType = UC_DATATYPE_UNSIGNED_INT,
|
||||
.error = UC_ERROR_OK,
|
||||
.dataSize = sizeof(language),
|
||||
.data = &language,
|
||||
};
|
||||
|
||||
UCError err = UCReadSysConfig(handle, 1, &settings);
|
||||
UCClose(handle);
|
||||
if (err != UC_ERROR_OK) {
|
||||
DEBUG_FUNCTION_LINE("Error reading UC: %d!", err);
|
||||
return nn::swkbd::LanguageType::English;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("System language found: %d", language);
|
||||
cached_language = language;
|
||||
return language;
|
||||
}
|
||||
} else {
|
||||
if (handle < 0) {
|
||||
DEBUG_FUNCTION_LINE("Error opening UC: %d", handle);
|
||||
return nn::swkbd::LanguageType::English;
|
||||
}
|
||||
scope_exit uc_c([&] { UCClose(handle); });
|
||||
|
||||
nn::swkbd::LanguageType language;
|
||||
|
||||
alignas(0x40) UCSysConfig settings = {
|
||||
.name = "cafe.language",
|
||||
.access = 0,
|
||||
.dataType = UC_DATATYPE_UNSIGNED_INT,
|
||||
.error = UC_ERROR_OK,
|
||||
.dataSize = sizeof(language),
|
||||
.data = &language,
|
||||
};
|
||||
|
||||
UCError err = UCReadSysConfig(handle, 1, &settings);
|
||||
if (err != UC_ERROR_OK) {
|
||||
DEBUG_FUNCTION_LINE("Error reading UC: %d!", err);
|
||||
return nn::swkbd::LanguageType::English;
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("System language found: %d", language);
|
||||
cached_language = language;
|
||||
return language;
|
||||
}
|
||||
|
||||
static std::optional<MCPSysProdSettings> mcp_config;
|
||||
static std::optional<MCPSystemVersion> mcp_os_version;
|
||||
static void get_mcp_config() {
|
||||
int mcp = MCP_Open();
|
||||
scope_exit mcp_c([&] { MCP_Close(mcp); });
|
||||
|
||||
alignas(0x40) MCPSysProdSettings config {};
|
||||
if (MCP_GetSysProdSettings(mcp, &config)) {
|
||||
DEBUG_FUNCTION_LINE("Could not get MCP system config!");
|
||||
return;
|
||||
}
|
||||
mcp_config = config;
|
||||
|
||||
//get os version
|
||||
MCPSystemVersion os_version;
|
||||
if (MCP_GetSystemVersion(mcp, &os_version)) {
|
||||
DEBUG_FUNCTION_LINE("Could not get MCP system config!");
|
||||
return;
|
||||
}
|
||||
mcp_os_version = os_version;
|
||||
|
||||
DEBUG_FUNCTION_LINE_VERBOSE("Running on %d.%d.%d%c; %s%s",
|
||||
os_version.major, os_version.minor, os_version.patch, os_version.region
|
||||
config.code_id, config.serial_id
|
||||
);
|
||||
}
|
||||
|
||||
const char * get_console_serial() {
|
||||
if (!mcp_config) get_mcp_config();
|
||||
|
||||
return mcp_config ? mcp_config->serial_id : "123456789";
|
||||
}
|
||||
|
||||
MCPSystemVersion get_console_os_version() {
|
||||
if (!mcp_os_version) get_mcp_config();
|
||||
|
||||
return mcp_os_version.value_or((MCPSystemVersion) { .major = 5, .minor = 5, .patch = 5, .region = 'E' });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
#define INKAY_SYSCONFIG_H
|
||||
|
||||
#include <nn/swkbd.h>
|
||||
#include <coreinit/mcp.h>
|
||||
|
||||
nn::swkbd::LanguageType get_system_language();
|
||||
const char * get_console_serial();
|
||||
MCPSystemVersion get_console_os_version();
|
||||
|
||||
#endif //INKAY_SYSCONFIG_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue