jubeat: support p3io games
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#define LOG_MODULE "eamuse-hook"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static const char *jbhook_eamuse_konami_url = "eamuse.konami.";
|
||||
|
||||
static int(STDCALL *real_getaddrinfo)(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static DWORD WINAPI my_GetIpAddrTable(
|
||||
PMIB_IPADDRTABLE pIpAddrTable,
|
||||
PULONG pdwSize,
|
||||
BOOL bOrder
|
||||
);
|
||||
|
||||
static const struct hook_symbol eamuse_hook_syms[] = {
|
||||
{
|
||||
.name = "getaddrinfo",
|
||||
.ordinal = 176,
|
||||
.patch = my_getaddrinfo,
|
||||
.link = (void **) &real_getaddrinfo,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hook_symbol network_hook_syms[] = {
|
||||
{
|
||||
.name = "GetIpAddrTable",
|
||||
.patch = my_GetIpAddrTable,
|
||||
},
|
||||
};
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult)
|
||||
{
|
||||
log_misc("my_getaddrinfo: %s, %s", pNodeName, pServiceName);
|
||||
|
||||
/* resolve eamuse.konami.fun/com to 127.0.0.1 to avoid lag spikes every
|
||||
150 seconds which might happen in-game as well */
|
||||
if (!strncmp(
|
||||
pNodeName,
|
||||
jbhook_eamuse_konami_url,
|
||||
strlen(jbhook_eamuse_konami_url))) {
|
||||
log_info("Resolve konami.eamuse.XXX -> localhost");
|
||||
pNodeName = "localhost";
|
||||
}
|
||||
|
||||
return real_getaddrinfo(pNodeName, pServiceName, pHints, ppResult);
|
||||
}
|
||||
|
||||
static DWORD get_best_ip(void) {
|
||||
PIP_ADAPTER_INFO info = NULL;
|
||||
struct net_addr addr;
|
||||
// fallback to a very obviously wrong value
|
||||
DWORD ret = (5 << 24) | (7 << 16) | (3 << 8) | (0 << 0);
|
||||
ULONG sz = 0;
|
||||
|
||||
// this uses our hooked GetAdaptersInfo from hooklib/adapter.c, thus using
|
||||
// the preferred interface instead of the default order
|
||||
log_assert(GetAdaptersInfo(info, &sz) == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
info = malloc(sz);
|
||||
|
||||
if(GetAdaptersInfo(info, &sz) != NO_ERROR) {
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
if(!net_str_parse(info->IpAddressList.IpAddress.String, &addr)) {
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
// MS docs say this should be in network byte order, but we need to return
|
||||
// host byte order for the game to not throw the IP error
|
||||
ret = addr.ipv4.addr;
|
||||
|
||||
CLEANUP:
|
||||
free(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* In new games via network.dll:network_addr_is_changed and in old games
|
||||
* directly, this function is called to compare the current IP address vs the IP
|
||||
* address when the game was first loaded. If the two are different, an error is
|
||||
* printed. It can be dismissed but will show up every ~10 seconds, impeding
|
||||
* gameplay. Because GetAdaptersInfo is hooked to return a (sometimes) different
|
||||
* adapter, computers with multiple interfaces will often fail this comparison
|
||||
* check. By also hooking this function, the IP addresses of the two calls will
|
||||
* agree.
|
||||
*/
|
||||
static DWORD WINAPI my_GetIpAddrTable(
|
||||
PMIB_IPADDRTABLE pIpAddrTable,
|
||||
PULONG pdwSize,
|
||||
BOOL bOrder
|
||||
) {
|
||||
ULONG in = *pdwSize;
|
||||
// 1 element return table
|
||||
*pdwSize = sizeof(MIB_IPADDRTABLE) + sizeof(MIB_IPADDRROW);
|
||||
|
||||
if(in < *pdwSize) {
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
pIpAddrTable->dwNumEntries = 1;
|
||||
pIpAddrTable->table[0].dwAddr = get_best_ip();
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void jbhook_util_eamuse_hook_init(void)
|
||||
{
|
||||
hook_table_apply(
|
||||
NULL, "ws2_32.dll", eamuse_hook_syms, lengthof(eamuse_hook_syms));
|
||||
hook_table_apply(
|
||||
NULL, "iphlpapi.dll", network_hook_syms, lengthof(network_hook_syms));
|
||||
|
||||
log_info("Inserted eamuse hooks");
|
||||
}
|
||||
Reference in New Issue
Block a user