1
1
mirror of synced 2025-02-17 10:48:36 +01:00

Renormalize code

This commit is contained in:
esuo1198 2024-03-23 20:08:42 +09:00
parent 1672c2cd2a
commit 0060482146
19 changed files with 4457 additions and 4456 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text eol=crlf

View File

@ -1,15 +1,15 @@
all:
@meson compile -C build
@strip build/bnusio.dll
setup:
@meson setup build --cross cross-mingw-64.txt
dist-no-7z: all
@mkdir -p out/
@cp build/bnusio.dll out/
@cp -r dist/* out/
dist: dist-no-7z
@cd out && 7z a -t7z ../dist.7z .
@rm -rf out
all:
@meson compile -C build
@strip build/bnusio.dll
setup:
@meson setup build --cross cross-mingw-64.txt
dist-no-7z: all
@mkdir -p out/
@cp build/bnusio.dll out/
@cp -r dist/* out/
dist: dist-no-7z
@cd out && 7z a -t7z ../dist.7z .
@rm -rf out

View File

@ -1,11 +1,11 @@
[binaries]
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
strip = 'x86_64-w64-mingw32-strip'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[binaries]
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
strip = 'x86_64-w64-mingw32-strip'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

60
dist/config.toml vendored
View File

@ -1,31 +1,31 @@
[amauth]
server = "127.0.0.1"
port = "54430"
chassis_id = "284111080000"
shop_id = "TAIKO ARCADE LOADER"
game_ver = "00.00"
country_code = "JPN"
[patches]
version = "auto"
res = { x = 1920, y = 1080 }
windowed = false
vsync = false
shared_audio = true
unlock_songs = true
[patches.cn_jun_2023]
fix_language = false
demo_movie = true
mode_collabo025 = false
mode_collabo026 = false
[qr]
data = { serial = "", type = 0, song_no = [] }
image_path = ""
[drum]
wait_period = 4
[controller]
[amauth]
server = "127.0.0.1"
port = "54430"
chassis_id = "284111080000"
shop_id = "TAIKO ARCADE LOADER"
game_ver = "00.00"
country_code = "JPN"
[patches]
version = "auto"
res = { x = 1920, y = 1080 }
windowed = false
vsync = false
shared_audio = true
unlock_songs = true
[patches.cn_jun_2023]
fix_language = false
demo_movie = true
mode_collabo025 = false
mode_collabo026 = false
[qr]
data = { serial = "", type = 0, song_no = [] }
image_path = ""
[drum]
wait_period = 4
[controller]
analog = false

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +1,76 @@
project('TaikoArcadeLoader', 'c', 'cpp', version: '1.0.0', default_options : ['c_std=c11', 'cpp_std=c++23'])
warning_level = 3
debug = true
optimization = 3
b_lto = true
b_pgo = 'use'
cmake = import('cmake')
opt_var = cmake.subproject_options()
opt_var.set_override_option('cpp_std', 'c++23')
cpp = meson.get_compiler('cpp')
add_project_arguments(
cpp.get_supported_arguments(
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10',
),
language: 'cpp',
)
add_project_link_arguments(
cpp.get_supported_arguments(
'-static',
#'-s',
'-lws2_32',
'-lssp',
'-lntdll',
),
language: 'cpp',
)
minhook = subproject('minhook')
tomlc99 = subproject('tomlc99')
sdl2 = subproject('sdl2', default_options: ['default_library=static', 'test=false', 'use_render=disabled'])
xxhash = subproject('xxhash', default_options: ['default_library=static', 'cli=false'])
opt_var.add_cmake_defines({'SAFETYHOOK_FETCH_ZYDIS': true})
safetyhook_proj = cmake.subproject('safetyhook', options: opt_var)
safetyhook_dep = safetyhook_proj.dependency('safetyhook')
zydis_dep = safetyhook_proj.dependency('Zydis')
stb = subproject('stb')
opt_var.add_cmake_defines({'BUILD_EXAMPLES': false})
zxing_proj = cmake.subproject('zxing', options: opt_var)
zxing_dep = zxing_proj.dependency('ZXing')
library(
'bnusio',
link_with: [
minhook.get_variable('minhook_lib'),
tomlc99.get_variable('tomlc99_lib'),
sdl2.get_variable('sdl2'),
xxhash.get_variable('xxhash'),
],
include_directories: [
'src',
minhook.get_variable('minhook_inc'),
tomlc99.get_variable('tomlc99_inc'),
sdl2.get_variable('core_inc'),
xxhash.get_variable('inc'),
],
dependencies: [stb.get_variable('stb_dep'),
zxing_dep,
safetyhook_dep,
zydis_dep,
],
sources : [
'src/dllmain.cpp',
'src/helpers.cpp',
'src/poll.cpp',
'src/bnusio.cpp',
'src/patches/jp_nov_2020.cpp',
'src/patches/cn_jun_2023.cpp',
'src/patches/jp_apr_2023.cpp',
'src/patches/amauth.cpp',
'src/patches/qr.cpp',
],
name_prefix: ''
)
project('TaikoArcadeLoader', 'c', 'cpp', version: '1.0.0', default_options : ['c_std=c11', 'cpp_std=c++23'])
warning_level = 3
debug = true
optimization = 3
b_lto = true
b_pgo = 'use'
cmake = import('cmake')
opt_var = cmake.subproject_options()
opt_var.set_override_option('cpp_std', 'c++23')
cpp = meson.get_compiler('cpp')
add_project_arguments(
cpp.get_supported_arguments(
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10',
),
language: 'cpp',
)
add_project_link_arguments(
cpp.get_supported_arguments(
'-static',
#'-s',
'-lws2_32',
'-lssp',
'-lntdll',
),
language: 'cpp',
)
minhook = subproject('minhook')
tomlc99 = subproject('tomlc99')
sdl2 = subproject('sdl2', default_options: ['default_library=static', 'test=false', 'use_render=disabled'])
xxhash = subproject('xxhash', default_options: ['default_library=static', 'cli=false'])
opt_var.add_cmake_defines({'SAFETYHOOK_FETCH_ZYDIS': true})
safetyhook_proj = cmake.subproject('safetyhook', options: opt_var)
safetyhook_dep = safetyhook_proj.dependency('safetyhook')
zydis_dep = safetyhook_proj.dependency('Zydis')
stb = subproject('stb')
opt_var.add_cmake_defines({'BUILD_EXAMPLES': false})
zxing_proj = cmake.subproject('zxing', options: opt_var)
zxing_dep = zxing_proj.dependency('ZXing')
library(
'bnusio',
link_with: [
minhook.get_variable('minhook_lib'),
tomlc99.get_variable('tomlc99_lib'),
sdl2.get_variable('sdl2'),
xxhash.get_variable('xxhash'),
],
include_directories: [
'src',
minhook.get_variable('minhook_inc'),
tomlc99.get_variable('tomlc99_inc'),
sdl2.get_variable('core_inc'),
xxhash.get_variable('inc'),
],
dependencies: [stb.get_variable('stb_dep'),
zxing_dep,
safetyhook_dep,
zydis_dep,
],
sources : [
'src/dllmain.cpp',
'src/helpers.cpp',
'src/poll.cpp',
'src/bnusio.cpp',
'src/patches/jp_nov_2020.cpp',
'src/patches/cn_jun_2023.cpp',
'src/patches/jp_apr_2023.cpp',
'src/patches/amauth.cpp',
'src/patches/qr.cpp',
],
name_prefix: ''
)

View File

@ -1,365 +1,365 @@
#include "constants.h"
#include "helpers.h"
#include "patches/patches.h"
#include "poll.h"
extern std::vector<HMODULE> plugins;
extern char accessCode1[21];
extern char chipId1[33];
extern char accessCode2[21];
extern char chipId2[33];
extern GameVersion version;
typedef i32 (*callbackAttach) (i32, i32, i32 *);
typedef void (*callbackTouch) (i32, i32, u8[168], u64);
typedef void event ();
typedef void waitTouchEvent (callbackTouch, u64);
bool waitingForTouch = false;
callbackTouch touchCallback;
u64 touchData;
callbackAttach attachCallback;
i32 *attachData;
Keybindings EXIT = {.keycodes = {VK_ESCAPE}};
Keybindings TEST = {.keycodes = {VK_F1}};
Keybindings SERVICE = {.keycodes = {VK_F2}};
Keybindings DEBUG_UP = {.keycodes = {VK_UP}};
Keybindings DEBUG_DOWN = {.keycodes = {VK_DOWN}};
Keybindings DEBUG_ENTER = {.keycodes = {VK_RETURN}};
Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_CONTROLLER_BUTTON_START}};
Keybindings CARD_INSERT_1 = {.keycodes = {'P'}};
Keybindings CARD_INSERT_2 = {};
Keybindings QR_DATA_READ = {.keycodes = {'Q'}};
Keybindings QR_IMAGE_READ = {.keycodes = {'W'}};
Keybindings P1_LEFT_BLUE = {.keycodes = {'D'}, .axis = {SDL_AXIS_LEFT_DOWN}};
Keybindings P1_LEFT_RED = {.keycodes = {'F'}, .axis = {SDL_AXIS_LEFT_RIGHT}};
Keybindings P1_RIGHT_RED = {.keycodes = {'J'}, .axis = {SDL_AXIS_RIGHT_RIGHT}};
Keybindings P1_RIGHT_BLUE = {.keycodes = {'K'}, .axis = {SDL_AXIS_RIGHT_DOWN}};
Keybindings P2_LEFT_BLUE = {};
Keybindings P2_LEFT_RED = {};
Keybindings P2_RIGHT_RED = {};
Keybindings P2_RIGHT_BLUE = {};
namespace bnusio {
#define RETURN_FALSE(returnType, functionName, ...) \
returnType functionName (__VA_ARGS__) { return 0; }
extern "C" {
RETURN_FALSE (i64, bnusio_ClearSram);
RETURN_FALSE (i64, bnusio_Communication, i32 a1);
RETURN_FALSE (i64, bnusio_DecService, i32 a1, u16 a2);
RETURN_FALSE (void *, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3);
RETURN_FALSE (i64, bnusio_GetCDOut, u8 a1);
RETURN_FALSE (void *, bnusio_GetCoinError, i32 a1);
RETURN_FALSE (i64, bnusio_GetCoinLock, u8 a1);
RETURN_FALSE (u64, bnusio_GetEncoder);
RETURN_FALSE (void *, bnusio_GetExpansionMode);
RETURN_FALSE (u8, bnusio_GetGout, u8 a1);
RETURN_FALSE (i64, bnusio_GetHopOut, u8 a1);
RETURN_FALSE (char *, bnusio_GetIoBoardName);
RETURN_FALSE (u16, bnusio_GetRegisterU16, i16 a1);
RETURN_FALSE (u8, bnusio_GetRegisterU8, u16 a1);
RETURN_FALSE (void *, bnusio_GetService, i32 a1);
RETURN_FALSE (void *, bnusio_GetServiceError, i32 a1);
RETURN_FALSE (u16, bnusio_GetStatusU16, u16 a1);
RETURN_FALSE (u8, bnusio_GetStatusU8, u16 a1);
RETURN_FALSE (u64, bnusio_GetSwIn64);
RETURN_FALSE (void *, bnusio_GetSystemError);
RETURN_FALSE (u8, bnusio_IsConnected);
RETURN_FALSE (u8, bnusio_IsWideUsio);
RETURN_FALSE (i64, bnusio_Open);
RETURN_FALSE (i32, bnusio_ResetIoBoard);
RETURN_FALSE (i64, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3);
RETURN_FALSE (i64, bnusio_SetCDOut, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetCoinLock, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetExpansionMode, i16 a1);
RETURN_FALSE (i64, bnusio_SetGout, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetHopOut, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetHopperLimit, u16 a1, i16 a2);
RETURN_FALSE (i64, bnusio_SetHopperRequest, u16 a1, i16 a2);
RETURN_FALSE (void *, bnusio_SetPLCounter, i16 a1);
RETURN_FALSE (i64, bnusio_SetRegisterU16, u16 a1, u16 a2);
RETURN_FALSE (i64, bnusio_SetRegisterU8, u16 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetSystemError, i16 a1);
RETURN_FALSE (i64, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4);
RETURN_FALSE (i64, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4);
RETURN_FALSE (i64, bnusio_ResetCoin);
RETURN_FALSE (i64, bnusio_DecCoin, i32 a1, u16 a2);
size_t
bnusio_GetFirmwareVersion () {
return 126;
}
u16 drumMin = 15000;
u16 drumMax = 30000;
u16 drumWaitPeriod = 4;
u16 lastHitValue = drumMin;
Keybindings *analogButtons[] = {&P1_LEFT_BLUE, &P1_LEFT_RED, &P1_RIGHT_RED, &P1_RIGHT_BLUE, &P2_LEFT_BLUE, &P2_LEFT_RED, &P2_RIGHT_RED, &P2_RIGHT_BLUE};
u16 buttonWaitPeriodP1 = 0;
u16 buttonWaitPeriodP2 = 0;
std::queue<u8> buttonQueueP1;
std::queue<u8> buttonQueueP2;
bool useTaikoController;
SDLAxis analogBindings[] = {
SDL_AXIS_LEFT_LEFT, SDL_AXIS_LEFT_RIGHT, SDL_AXIS_LEFT_DOWN, SDL_AXIS_LEFT_UP, // P1: LB, LR, RR, RB
SDL_AXIS_RIGHT_LEFT, SDL_AXIS_RIGHT_RIGHT, SDL_AXIS_RIGHT_DOWN, SDL_AXIS_RIGHT_UP, // P2: LB, LR, RR, RB
};
u16
bnusio_GetAnalogIn (u8 which) {
u16 analogValue;
if (useTaikoController) {
analogValue = (u16)(32768 * ControllerAxisIsDown (analogBindings[which]));
if (analogValue > 100) return analogValue;
return 0;
}
auto button = analogButtons[which];
if (which == 0) {
if (buttonWaitPeriodP1 > 0) buttonWaitPeriodP1--;
if (buttonWaitPeriodP2 > 0) buttonWaitPeriodP2--;
}
bool isP1 = which / 4 == 0;
if ((isP1 && !buttonQueueP1.empty ()) || (!isP1 && !buttonQueueP2.empty ())) {
if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0) || (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) {
if (isP1) {
buttonQueueP1.pop ();
buttonWaitPeriodP1 = drumWaitPeriod;
} else {
buttonQueueP2.pop ();
buttonWaitPeriodP2 = drumWaitPeriod;
}
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
}
if (IsButtonTapped (*button)) {
if (isP1) buttonQueueP1.push (which);
else buttonQueueP2.push (which);
}
return 0;
} else if (IsButtonTapped (*button)) {
if (isP1 && buttonWaitPeriodP1 > 0) {
buttonQueueP1.push (which);
return 0;
} else if (!isP1 && buttonWaitPeriodP2 > 0) {
buttonQueueP2.push (which);
return 0;
}
if (isP1) buttonWaitPeriodP1 = drumWaitPeriod;
else buttonWaitPeriodP2 = drumWaitPeriod;
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
} else {
return 0;
}
}
bool testEnabled = false;
int coin_count = 0;
bool inited = false;
HWND windowHandle = 0;
u16 __fastcall bnusio_GetCoin (i32 a1) {
if (a1 != 1) return coin_count;
if (!inited) {
windowHandle = FindWindowA ("nuFoundation.Window", 0);
InitializePoll (windowHandle);
for (auto plugin : plugins) {
auto initEvent = GetProcAddress (plugin, "Init");
if (initEvent) initEvent ();
}
inited = true;
}
UpdatePoll (windowHandle);
if (IsButtonTapped (COIN_ADD) && !testEnabled) coin_count++;
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
if (IsButtonTapped (EXIT)) ExitProcess (0);
if (waitingForTouch) {
static u8 cardData[168] = {0x01, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x2E, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x5C, 0x97, 0x44, 0xF0, 0x88, 0x04, 0x00, 0x43, 0x26, 0x2C, 0x33, 0x00, 0x04, 0x06, 0x10, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4E, 0x42, 0x47, 0x49, 0x43, 0x36, 0x00, 0x00, 0xFA, 0xE9, 0x69, 0x00, 0xF6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool hasInserted = false;
if (IsButtonTapped (CARD_INSERT_1)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard1Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card1Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId1, 33);
memcpy (cardData + 0x50, accessCode1, 21);
touchCallback (0, 0, cardData, touchData);
}
} else if (IsButtonTapped (CARD_INSERT_2)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard2Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card2Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId2, 33);
memcpy (cardData + 0x50, accessCode2, 21);
touchCallback (0, 0, cardData, touchData);
}
}
}
for (auto plugin : plugins) {
auto updateEvent = GetProcAddress (plugin, "Update");
if (updateEvent) updateEvent ();
}
patches::Qr::Update ();
if (attachCallback) attachCallback (0, 0, attachData);
return coin_count;
}
u32
bnusio_GetSwIn () {
u32 sw = 0;
sw |= (u32)testEnabled << 7;
sw |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
sw |= (u32)IsButtonDown (SERVICE) << 14;
return sw;
}
i64
bnusio_Close () {
for (auto plugin : plugins) {
FARPROC exitEvent = GetProcAddress (plugin, "Exit");
if (exitEvent) ((event *)exitEvent) ();
}
return 0;
}
}
HOOK (u64, bngrw_DevReset, PROC_ADDRESS ("bngrw.dll", "BngRwDevReset")) { return 1; }
HOOK (u64, bngrw_ReadMifare, PROC_ADDRESS ("bngrw.dll", "BngRwExReadMifareAllBlock")) { return 0xFFFFFF9C; }
HOOK (void, bngrw_fin, PROC_ADDRESS ("bngrw.dll", "BngRwFin")) { return; }
HOOK (u64, bngrw_GetFwVersion, PROC_ADDRESS ("bngrw.dll", "BngRwGetFwVersion")) { return 0; }
HOOK (u64, bngrw_GetStationID, PROC_ADDRESS ("bngrw.dll", "BngRwGetStationID")) { return 0; }
HOOK (u64, bngrw_GetRetryCount, PROC_ADDRESS ("bngrw.dll", "BngRwGetTotalRetryCount")) { return 0; }
HOOK (u64, bngrw_IsCmdExec, PROC_ADDRESS ("bngrw.dll", "BngRwIsCmdExec")) { return 0xFFFFFFFF; }
HOOK (u64, bngrw_ReqAction, PROC_ADDRESS ("bngrw.dll", "BngRwReqAction")) { return 1; }
HOOK (u64, bngrw_ReqAiccAuth, PROC_ADDRESS ("bngrw.dll", "BngRwReqAiccAuth")) { return 1; }
HOOK (u64, bngrw_ReqBeep, PROC_ADDRESS ("bngrw.dll", "BngRwReqBeep")) { return 1; }
HOOK (u64, bngrw_ReqFwCleanup, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwCleanup")) { return 1; }
HOOK (u64, bngrw_ReqFwVersionUp, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwVersionUp")) { return 1; }
HOOK (i32, bngrw_ReqLatchID, PROC_ADDRESS ("bngrw.dll", "BngRwReqLatchID")) { return 1; }
HOOK (u64, bngrw_ReqLed, PROC_ADDRESS ("bngrw.dll", "BngRwReqLed")) { return 1; }
HOOK (i32, bngrw_ReqSendMail, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendMailTo")) { return 1; }
HOOK (i32, bngrw_ReqSendUrl, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendUrlTo")) { return 1; }
HOOK (u64, bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower")) { return 0; }
HOOK (i32, bngrw_reqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel")) { return 1; }
HOOK (u64, bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit")) { return 0; }
HOOK (u64, bngrw_attach, PROC_ADDRESS ("bngrw.dll", "BngRwAttach"), i32 a1, char *a2, i32 a3, i32 a4, i32 (*callback) (i32, i32, i32 *), i32 *a6) {
// This is way too fucking jank
attachCallback = callback;
attachData = a6;
return 1;
}
HOOK (u64, bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, void (*callback) (i32, i32, u8[168], u64), u64 a5) {
waitingForTouch = true;
touchCallback = callback;
touchData = a5;
for (auto plugin : plugins) {
FARPROC touchEvent = GetProcAddress (plugin, "WaitTouch");
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, a5);
}
return 1;
}
void
Init () {
INSTALL_HOOK (bngrw_DevReset);
INSTALL_HOOK (bngrw_ReadMifare);
INSTALL_HOOK (bngrw_fin);
INSTALL_HOOK (bngrw_GetFwVersion);
INSTALL_HOOK (bngrw_GetStationID);
INSTALL_HOOK (bngrw_GetRetryCount);
INSTALL_HOOK (bngrw_IsCmdExec);
INSTALL_HOOK (bngrw_ReqAction);
INSTALL_HOOK (bngrw_ReqAiccAuth);
INSTALL_HOOK (bngrw_ReqBeep);
INSTALL_HOOK (bngrw_ReqFwCleanup);
INSTALL_HOOK (bngrw_ReqFwVersionUp);
INSTALL_HOOK (bngrw_ReqLatchID);
INSTALL_HOOK (bngrw_ReqLed);
INSTALL_HOOK (bngrw_ReqSendMail);
INSTALL_HOOK (bngrw_ReqSendUrl);
INSTALL_HOOK (bngrw_ReqSetLedPower);
INSTALL_HOOK (bngrw_reqCancel);
INSTALL_HOOK (bngrw_Init)
INSTALL_HOOK (bngrw_attach);
INSTALL_HOOK (bngrw_reqWaitTouch);
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto drum = openConfigSection (config, "drum");
if (drum) drumWaitPeriod = readConfigInt (drum, "wait_period", drumWaitPeriod);
auto taikoController = openConfigSection (config, "controller");
if (taikoController) {
useTaikoController = readConfigBool (taikoController, "analog", useTaikoController);
if (useTaikoController) printf ("Using analog input mode. All the keyboard drum inputs have been disabled.\n");
}
}
auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyconfig_ptr (openConfig (keyconfigPath), toml_free);
toml_table_t *keyconfig = keyconfig_ptr.get ();
if (keyconfig) {
SetConfigValue (keyconfig, "EXIT", &EXIT);
SetConfigValue (keyconfig, "TEST", &TEST);
SetConfigValue (keyconfig, "SERVICE", &SERVICE);
SetConfigValue (keyconfig, "DEBUG_UP", &DEBUG_UP);
SetConfigValue (keyconfig, "DEBUG_DOWN", &DEBUG_DOWN);
SetConfigValue (keyconfig, "DEBUG_ENTER", &DEBUG_ENTER);
SetConfigValue (keyconfig, "COIN_ADD", &COIN_ADD);
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_RED", &P1_RIGHT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_RED", &P2_LEFT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_RED", &P2_RIGHT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
}
}
} // namespace bnusio
#include "constants.h"
#include "helpers.h"
#include "patches/patches.h"
#include "poll.h"
extern std::vector<HMODULE> plugins;
extern char accessCode1[21];
extern char chipId1[33];
extern char accessCode2[21];
extern char chipId2[33];
extern GameVersion version;
typedef i32 (*callbackAttach) (i32, i32, i32 *);
typedef void (*callbackTouch) (i32, i32, u8[168], u64);
typedef void event ();
typedef void waitTouchEvent (callbackTouch, u64);
bool waitingForTouch = false;
callbackTouch touchCallback;
u64 touchData;
callbackAttach attachCallback;
i32 *attachData;
Keybindings EXIT = {.keycodes = {VK_ESCAPE}};
Keybindings TEST = {.keycodes = {VK_F1}};
Keybindings SERVICE = {.keycodes = {VK_F2}};
Keybindings DEBUG_UP = {.keycodes = {VK_UP}};
Keybindings DEBUG_DOWN = {.keycodes = {VK_DOWN}};
Keybindings DEBUG_ENTER = {.keycodes = {VK_RETURN}};
Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_CONTROLLER_BUTTON_START}};
Keybindings CARD_INSERT_1 = {.keycodes = {'P'}};
Keybindings CARD_INSERT_2 = {};
Keybindings QR_DATA_READ = {.keycodes = {'Q'}};
Keybindings QR_IMAGE_READ = {.keycodes = {'W'}};
Keybindings P1_LEFT_BLUE = {.keycodes = {'D'}, .axis = {SDL_AXIS_LEFT_DOWN}};
Keybindings P1_LEFT_RED = {.keycodes = {'F'}, .axis = {SDL_AXIS_LEFT_RIGHT}};
Keybindings P1_RIGHT_RED = {.keycodes = {'J'}, .axis = {SDL_AXIS_RIGHT_RIGHT}};
Keybindings P1_RIGHT_BLUE = {.keycodes = {'K'}, .axis = {SDL_AXIS_RIGHT_DOWN}};
Keybindings P2_LEFT_BLUE = {};
Keybindings P2_LEFT_RED = {};
Keybindings P2_RIGHT_RED = {};
Keybindings P2_RIGHT_BLUE = {};
namespace bnusio {
#define RETURN_FALSE(returnType, functionName, ...) \
returnType functionName (__VA_ARGS__) { return 0; }
extern "C" {
RETURN_FALSE (i64, bnusio_ClearSram);
RETURN_FALSE (i64, bnusio_Communication, i32 a1);
RETURN_FALSE (i64, bnusio_DecService, i32 a1, u16 a2);
RETURN_FALSE (void *, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3);
RETURN_FALSE (i64, bnusio_GetCDOut, u8 a1);
RETURN_FALSE (void *, bnusio_GetCoinError, i32 a1);
RETURN_FALSE (i64, bnusio_GetCoinLock, u8 a1);
RETURN_FALSE (u64, bnusio_GetEncoder);
RETURN_FALSE (void *, bnusio_GetExpansionMode);
RETURN_FALSE (u8, bnusio_GetGout, u8 a1);
RETURN_FALSE (i64, bnusio_GetHopOut, u8 a1);
RETURN_FALSE (char *, bnusio_GetIoBoardName);
RETURN_FALSE (u16, bnusio_GetRegisterU16, i16 a1);
RETURN_FALSE (u8, bnusio_GetRegisterU8, u16 a1);
RETURN_FALSE (void *, bnusio_GetService, i32 a1);
RETURN_FALSE (void *, bnusio_GetServiceError, i32 a1);
RETURN_FALSE (u16, bnusio_GetStatusU16, u16 a1);
RETURN_FALSE (u8, bnusio_GetStatusU8, u16 a1);
RETURN_FALSE (u64, bnusio_GetSwIn64);
RETURN_FALSE (void *, bnusio_GetSystemError);
RETURN_FALSE (u8, bnusio_IsConnected);
RETURN_FALSE (u8, bnusio_IsWideUsio);
RETURN_FALSE (i64, bnusio_Open);
RETURN_FALSE (i32, bnusio_ResetIoBoard);
RETURN_FALSE (i64, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3);
RETURN_FALSE (i64, bnusio_SetCDOut, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetCoinLock, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetExpansionMode, i16 a1);
RETURN_FALSE (i64, bnusio_SetGout, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetHopOut, u8 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetHopperLimit, u16 a1, i16 a2);
RETURN_FALSE (i64, bnusio_SetHopperRequest, u16 a1, i16 a2);
RETURN_FALSE (void *, bnusio_SetPLCounter, i16 a1);
RETURN_FALSE (i64, bnusio_SetRegisterU16, u16 a1, u16 a2);
RETURN_FALSE (i64, bnusio_SetRegisterU8, u16 a1, u8 a2);
RETURN_FALSE (i64, bnusio_SetSystemError, i16 a1);
RETURN_FALSE (i64, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4);
RETURN_FALSE (i64, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4);
RETURN_FALSE (i64, bnusio_ResetCoin);
RETURN_FALSE (i64, bnusio_DecCoin, i32 a1, u16 a2);
size_t
bnusio_GetFirmwareVersion () {
return 126;
}
u16 drumMin = 15000;
u16 drumMax = 30000;
u16 drumWaitPeriod = 4;
u16 lastHitValue = drumMin;
Keybindings *analogButtons[] = {&P1_LEFT_BLUE, &P1_LEFT_RED, &P1_RIGHT_RED, &P1_RIGHT_BLUE, &P2_LEFT_BLUE, &P2_LEFT_RED, &P2_RIGHT_RED, &P2_RIGHT_BLUE};
u16 buttonWaitPeriodP1 = 0;
u16 buttonWaitPeriodP2 = 0;
std::queue<u8> buttonQueueP1;
std::queue<u8> buttonQueueP2;
bool useTaikoController;
SDLAxis analogBindings[] = {
SDL_AXIS_LEFT_LEFT, SDL_AXIS_LEFT_RIGHT, SDL_AXIS_LEFT_DOWN, SDL_AXIS_LEFT_UP, // P1: LB, LR, RR, RB
SDL_AXIS_RIGHT_LEFT, SDL_AXIS_RIGHT_RIGHT, SDL_AXIS_RIGHT_DOWN, SDL_AXIS_RIGHT_UP, // P2: LB, LR, RR, RB
};
u16
bnusio_GetAnalogIn (u8 which) {
u16 analogValue;
if (useTaikoController) {
analogValue = (u16)(32768 * ControllerAxisIsDown (analogBindings[which]));
if (analogValue > 100) return analogValue;
return 0;
}
auto button = analogButtons[which];
if (which == 0) {
if (buttonWaitPeriodP1 > 0) buttonWaitPeriodP1--;
if (buttonWaitPeriodP2 > 0) buttonWaitPeriodP2--;
}
bool isP1 = which / 4 == 0;
if ((isP1 && !buttonQueueP1.empty ()) || (!isP1 && !buttonQueueP2.empty ())) {
if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0) || (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) {
if (isP1) {
buttonQueueP1.pop ();
buttonWaitPeriodP1 = drumWaitPeriod;
} else {
buttonQueueP2.pop ();
buttonWaitPeriodP2 = drumWaitPeriod;
}
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
}
if (IsButtonTapped (*button)) {
if (isP1) buttonQueueP1.push (which);
else buttonQueueP2.push (which);
}
return 0;
} else if (IsButtonTapped (*button)) {
if (isP1 && buttonWaitPeriodP1 > 0) {
buttonQueueP1.push (which);
return 0;
} else if (!isP1 && buttonWaitPeriodP2 > 0) {
buttonQueueP2.push (which);
return 0;
}
if (isP1) buttonWaitPeriodP1 = drumWaitPeriod;
else buttonWaitPeriodP2 = drumWaitPeriod;
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
} else {
return 0;
}
}
bool testEnabled = false;
int coin_count = 0;
bool inited = false;
HWND windowHandle = 0;
u16 __fastcall bnusio_GetCoin (i32 a1) {
if (a1 != 1) return coin_count;
if (!inited) {
windowHandle = FindWindowA ("nuFoundation.Window", 0);
InitializePoll (windowHandle);
for (auto plugin : plugins) {
auto initEvent = GetProcAddress (plugin, "Init");
if (initEvent) initEvent ();
}
inited = true;
}
UpdatePoll (windowHandle);
if (IsButtonTapped (COIN_ADD) && !testEnabled) coin_count++;
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
if (IsButtonTapped (EXIT)) ExitProcess (0);
if (waitingForTouch) {
static u8 cardData[168] = {0x01, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x2E, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x5C, 0x97, 0x44, 0xF0, 0x88, 0x04, 0x00, 0x43, 0x26, 0x2C, 0x33, 0x00, 0x04, 0x06, 0x10, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4E, 0x42, 0x47, 0x49, 0x43, 0x36, 0x00, 0x00, 0xFA, 0xE9, 0x69, 0x00, 0xF6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool hasInserted = false;
if (IsButtonTapped (CARD_INSERT_1)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard1Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card1Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId1, 33);
memcpy (cardData + 0x50, accessCode1, 21);
touchCallback (0, 0, cardData, touchData);
}
} else if (IsButtonTapped (CARD_INSERT_2)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard2Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card2Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId2, 33);
memcpy (cardData + 0x50, accessCode2, 21);
touchCallback (0, 0, cardData, touchData);
}
}
}
for (auto plugin : plugins) {
auto updateEvent = GetProcAddress (plugin, "Update");
if (updateEvent) updateEvent ();
}
patches::Qr::Update ();
if (attachCallback) attachCallback (0, 0, attachData);
return coin_count;
}
u32
bnusio_GetSwIn () {
u32 sw = 0;
sw |= (u32)testEnabled << 7;
sw |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
sw |= (u32)IsButtonDown (SERVICE) << 14;
return sw;
}
i64
bnusio_Close () {
for (auto plugin : plugins) {
FARPROC exitEvent = GetProcAddress (plugin, "Exit");
if (exitEvent) ((event *)exitEvent) ();
}
return 0;
}
}
HOOK (u64, bngrw_DevReset, PROC_ADDRESS ("bngrw.dll", "BngRwDevReset")) { return 1; }
HOOK (u64, bngrw_ReadMifare, PROC_ADDRESS ("bngrw.dll", "BngRwExReadMifareAllBlock")) { return 0xFFFFFF9C; }
HOOK (void, bngrw_fin, PROC_ADDRESS ("bngrw.dll", "BngRwFin")) { return; }
HOOK (u64, bngrw_GetFwVersion, PROC_ADDRESS ("bngrw.dll", "BngRwGetFwVersion")) { return 0; }
HOOK (u64, bngrw_GetStationID, PROC_ADDRESS ("bngrw.dll", "BngRwGetStationID")) { return 0; }
HOOK (u64, bngrw_GetRetryCount, PROC_ADDRESS ("bngrw.dll", "BngRwGetTotalRetryCount")) { return 0; }
HOOK (u64, bngrw_IsCmdExec, PROC_ADDRESS ("bngrw.dll", "BngRwIsCmdExec")) { return 0xFFFFFFFF; }
HOOK (u64, bngrw_ReqAction, PROC_ADDRESS ("bngrw.dll", "BngRwReqAction")) { return 1; }
HOOK (u64, bngrw_ReqAiccAuth, PROC_ADDRESS ("bngrw.dll", "BngRwReqAiccAuth")) { return 1; }
HOOK (u64, bngrw_ReqBeep, PROC_ADDRESS ("bngrw.dll", "BngRwReqBeep")) { return 1; }
HOOK (u64, bngrw_ReqFwCleanup, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwCleanup")) { return 1; }
HOOK (u64, bngrw_ReqFwVersionUp, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwVersionUp")) { return 1; }
HOOK (i32, bngrw_ReqLatchID, PROC_ADDRESS ("bngrw.dll", "BngRwReqLatchID")) { return 1; }
HOOK (u64, bngrw_ReqLed, PROC_ADDRESS ("bngrw.dll", "BngRwReqLed")) { return 1; }
HOOK (i32, bngrw_ReqSendMail, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendMailTo")) { return 1; }
HOOK (i32, bngrw_ReqSendUrl, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendUrlTo")) { return 1; }
HOOK (u64, bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower")) { return 0; }
HOOK (i32, bngrw_reqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel")) { return 1; }
HOOK (u64, bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit")) { return 0; }
HOOK (u64, bngrw_attach, PROC_ADDRESS ("bngrw.dll", "BngRwAttach"), i32 a1, char *a2, i32 a3, i32 a4, i32 (*callback) (i32, i32, i32 *), i32 *a6) {
// This is way too fucking jank
attachCallback = callback;
attachData = a6;
return 1;
}
HOOK (u64, bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, void (*callback) (i32, i32, u8[168], u64), u64 a5) {
waitingForTouch = true;
touchCallback = callback;
touchData = a5;
for (auto plugin : plugins) {
FARPROC touchEvent = GetProcAddress (plugin, "WaitTouch");
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, a5);
}
return 1;
}
void
Init () {
INSTALL_HOOK (bngrw_DevReset);
INSTALL_HOOK (bngrw_ReadMifare);
INSTALL_HOOK (bngrw_fin);
INSTALL_HOOK (bngrw_GetFwVersion);
INSTALL_HOOK (bngrw_GetStationID);
INSTALL_HOOK (bngrw_GetRetryCount);
INSTALL_HOOK (bngrw_IsCmdExec);
INSTALL_HOOK (bngrw_ReqAction);
INSTALL_HOOK (bngrw_ReqAiccAuth);
INSTALL_HOOK (bngrw_ReqBeep);
INSTALL_HOOK (bngrw_ReqFwCleanup);
INSTALL_HOOK (bngrw_ReqFwVersionUp);
INSTALL_HOOK (bngrw_ReqLatchID);
INSTALL_HOOK (bngrw_ReqLed);
INSTALL_HOOK (bngrw_ReqSendMail);
INSTALL_HOOK (bngrw_ReqSendUrl);
INSTALL_HOOK (bngrw_ReqSetLedPower);
INSTALL_HOOK (bngrw_reqCancel);
INSTALL_HOOK (bngrw_Init)
INSTALL_HOOK (bngrw_attach);
INSTALL_HOOK (bngrw_reqWaitTouch);
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto drum = openConfigSection (config, "drum");
if (drum) drumWaitPeriod = readConfigInt (drum, "wait_period", drumWaitPeriod);
auto taikoController = openConfigSection (config, "controller");
if (taikoController) {
useTaikoController = readConfigBool (taikoController, "analog", useTaikoController);
if (useTaikoController) printf ("Using analog input mode. All the keyboard drum inputs have been disabled.\n");
}
}
auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyconfig_ptr (openConfig (keyconfigPath), toml_free);
toml_table_t *keyconfig = keyconfig_ptr.get ();
if (keyconfig) {
SetConfigValue (keyconfig, "EXIT", &EXIT);
SetConfigValue (keyconfig, "TEST", &TEST);
SetConfigValue (keyconfig, "SERVICE", &SERVICE);
SetConfigValue (keyconfig, "DEBUG_UP", &DEBUG_UP);
SetConfigValue (keyconfig, "DEBUG_DOWN", &DEBUG_DOWN);
SetConfigValue (keyconfig, "DEBUG_ENTER", &DEBUG_ENTER);
SetConfigValue (keyconfig, "COIN_ADD", &COIN_ADD);
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_RED", &P1_RIGHT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_RED", &P2_LEFT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_RED", &P2_RIGHT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
}
}
} // namespace bnusio

View File

@ -1,3 +1,3 @@
namespace bnusio {
void Init ();
} // namespace bnusio
namespace bnusio {
void Init ();
} // namespace bnusio

View File

@ -1,192 +1,192 @@
#include "bnusio.h"
#include "constants.h"
#include "helpers.h"
#include "patches/patches.h"
#include "poll.h"
GameVersion gameVersion = GameVersion::UNKNOWN;
std::vector<HMODULE> plugins;
std::string server = "127.0.0.1";
std::string port = "54430";
std::string chassisId = "284111080000";
std::string shopId = "TAIKO ARCADE LOADER";
std::string gameVerNum = "00.00";
std::string countryCode = "JPN";
char fullAddress[256] = {'\0'};
char placeId[16] = {'\0'};
char accessCode1[21] = "00000000000000000001";
char accessCode2[21] = "00000000000000000002";
char chipId1[33] = "00000000000000000000000000000001";
char chipId2[33] = "00000000000000000000000000000002";
HOOK (i32, ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"), bool) { return originalShowMouse (true); }
HOOK (i32, ExitWindows, PROC_ADDRESS ("user32.dll", "ExitWindowsEx")) {
ExitProcess (0);
return true;
}
HOOK (i32, XinputGetState, PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetState")) { return ERROR_DEVICE_NOT_CONNECTED; }
HOOK (i32, XinputSetState, PROC_ADDRESS ("xinput9_1_0.dll", "XInputSetState")) { return ERROR_DEVICE_NOT_CONNECTED; }
HOOK (i32, XinputGetCapabilites, PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetCapabilities")) { return ERROR_DEVICE_NOT_CONNECTED; }
HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown")) { return 1; }
HOOK (i64, UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")) { return 0; }
HOOK (i64, UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")) { return 0; }
HOOK (i64, UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"), i32 a1, char *a2) {
strcpy (a2, chassisId.c_str ());
return 0;
}
HOOK (i32, ws2_getaddrinfo, PROC_ADDRESS ("ws2_32.dll", "getaddrinfo"), const char *node, char *service, void *hints, void *out) {
return originalws2_getaddrinfo (server.c_str (), service, hints, out);
}
void
GetGameVersion () {
wchar_t w_path[MAX_PATH];
GetModuleFileNameW (0, w_path, MAX_PATH);
std::filesystem::path path (w_path);
if (!std::filesystem::exists (path) || !path.has_filename ()) {
MessageBoxA (0, "Failed to find executable", 0, MB_OK);
ExitProcess (0);
}
std::ifstream stream (path, std::ios::binary);
if (!stream.is_open ()) {
MessageBoxA (0, "Failed to read executable", 0, MB_OK);
ExitProcess (0);
}
stream.seekg (0, stream.end);
size_t length = stream.tellg ();
stream.seekg (0, stream.beg);
char *buf = (char *)calloc (length + 1, sizeof (char));
stream.read (buf, length);
gameVersion = (GameVersion)XXH64 (buf, length, 0);
stream.close ();
free (buf);
switch (gameVersion) {
case GameVersion::JP_NOV_2020:
case GameVersion::CN_JUN_2023:
case GameVersion::JP_APR_2023: break;
default: MessageBoxA (0, "Unknown game version", 0, MB_OK); ExitProcess (0);
}
}
void
createCard () {
const char hexCharacterTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char buf[64] = {0};
srand (time (0));
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode1", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId1", buf, ".\\card.ini");
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode2", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId2", buf, ".\\card.ini");
}
BOOL
DllMain (HMODULE module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) {
// This is bad, dont do this
// I/O in DllMain can easily cause a deadlock
std::string version = "auto";
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto amauth = openConfigSection (config, "amauth");
if (amauth) {
server = readConfigString (amauth, "server", server);
port = readConfigString (amauth, "port", port);
chassisId = readConfigString (amauth, "chassis_id", chassisId);
shopId = readConfigString (amauth, "shop_id", shopId);
gameVerNum = readConfigString (amauth, "game_ver", gameVerNum);
countryCode = readConfigString (amauth, "country_code", countryCode);
std::strcat (fullAddress, server.c_str ());
std::strcat (fullAddress, ":");
std::strcat (fullAddress, port.c_str ());
std::strcat (placeId, countryCode.c_str ());
std::strcat (placeId, "0FF0");
}
auto patches = openConfigSection (config, "patches");
if (patches) version = readConfigString (patches, "version", version);
}
if (version == "auto") {
GetGameVersion ();
} else if (version == "jp_nov_2020") {
gameVersion = GameVersion::JP_NOV_2020;
} else if (version == "cn_jun_2023") {
gameVersion = GameVersion::CN_JUN_2023;
} else if (version == "jp_apr_2023") {
gameVersion = GameVersion::JP_APR_2023;
} else {
MessageBoxA (0, "Unknown patch version", 0, MB_OK);
ExitProcess (0);
}
auto pluginPath = std::filesystem::current_path () / "plugins";
if (std::filesystem::exists (pluginPath)) {
for (auto entry : std::filesystem::directory_iterator (pluginPath)) {
if (entry.path ().extension () == ".dll") {
auto name = entry.path ().wstring ();
HMODULE hModule = LoadLibraryW (name.c_str ());
if (!hModule) {
wchar_t buf[128];
wsprintfW (buf, L"Failed to load plugin %ls", name.c_str ());
MessageBoxW (0, buf, name.c_str (), MB_ICONERROR);
} else {
plugins.push_back (hModule);
}
}
}
}
if (!std::filesystem::exists (".\\card.ini")) createCard ();
GetPrivateProfileStringA ("card", "accessCode1", accessCode1, accessCode1, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId1", chipId1, chipId1, 33, ".\\card.ini");
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 33, ".\\card.ini");
INSTALL_HOOK (ShowMouse);
INSTALL_HOOK (ExitWindows);
INSTALL_HOOK (XinputGetState);
INSTALL_HOOK (XinputSetState);
INSTALL_HOOK (XinputGetCapabilites);
INSTALL_HOOK (ssleay_Shutdown);
INSTALL_HOOK (UsbFinderInitialize);
INSTALL_HOOK (UsbFinderRelease);
INSTALL_HOOK (UsbFinderGetSerialNumber);
INSTALL_HOOK (ws2_getaddrinfo);
bnusio::Init ();
switch (gameVersion) {
case GameVersion::UNKNOWN: break;
case GameVersion::JP_NOV_2020: patches::JP_NOV_2020::Init (); break;
case GameVersion::CN_JUN_2023: patches::CN_JUN_2023::Init (); break;
case GameVersion::JP_APR_2023: patches::JP_APR_2023::Init (); break;
}
}
return true;
}
#include "bnusio.h"
#include "constants.h"
#include "helpers.h"
#include "patches/patches.h"
#include "poll.h"
GameVersion gameVersion = GameVersion::UNKNOWN;
std::vector<HMODULE> plugins;
std::string server = "127.0.0.1";
std::string port = "54430";
std::string chassisId = "284111080000";
std::string shopId = "TAIKO ARCADE LOADER";
std::string gameVerNum = "00.00";
std::string countryCode = "JPN";
char fullAddress[256] = {'\0'};
char placeId[16] = {'\0'};
char accessCode1[21] = "00000000000000000001";
char accessCode2[21] = "00000000000000000002";
char chipId1[33] = "00000000000000000000000000000001";
char chipId2[33] = "00000000000000000000000000000002";
HOOK (i32, ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"), bool) { return originalShowMouse (true); }
HOOK (i32, ExitWindows, PROC_ADDRESS ("user32.dll", "ExitWindowsEx")) {
ExitProcess (0);
return true;
}
HOOK (i32, XinputGetState, PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetState")) { return ERROR_DEVICE_NOT_CONNECTED; }
HOOK (i32, XinputSetState, PROC_ADDRESS ("xinput9_1_0.dll", "XInputSetState")) { return ERROR_DEVICE_NOT_CONNECTED; }
HOOK (i32, XinputGetCapabilites, PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetCapabilities")) { return ERROR_DEVICE_NOT_CONNECTED; }
HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown")) { return 1; }
HOOK (i64, UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")) { return 0; }
HOOK (i64, UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")) { return 0; }
HOOK (i64, UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"), i32 a1, char *a2) {
strcpy (a2, chassisId.c_str ());
return 0;
}
HOOK (i32, ws2_getaddrinfo, PROC_ADDRESS ("ws2_32.dll", "getaddrinfo"), const char *node, char *service, void *hints, void *out) {
return originalws2_getaddrinfo (server.c_str (), service, hints, out);
}
void
GetGameVersion () {
wchar_t w_path[MAX_PATH];
GetModuleFileNameW (0, w_path, MAX_PATH);
std::filesystem::path path (w_path);
if (!std::filesystem::exists (path) || !path.has_filename ()) {
MessageBoxA (0, "Failed to find executable", 0, MB_OK);
ExitProcess (0);
}
std::ifstream stream (path, std::ios::binary);
if (!stream.is_open ()) {
MessageBoxA (0, "Failed to read executable", 0, MB_OK);
ExitProcess (0);
}
stream.seekg (0, stream.end);
size_t length = stream.tellg ();
stream.seekg (0, stream.beg);
char *buf = (char *)calloc (length + 1, sizeof (char));
stream.read (buf, length);
gameVersion = (GameVersion)XXH64 (buf, length, 0);
stream.close ();
free (buf);
switch (gameVersion) {
case GameVersion::JP_NOV_2020:
case GameVersion::CN_JUN_2023:
case GameVersion::JP_APR_2023: break;
default: MessageBoxA (0, "Unknown game version", 0, MB_OK); ExitProcess (0);
}
}
void
createCard () {
const char hexCharacterTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char buf[64] = {0};
srand (time (0));
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode1", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId1", buf, ".\\card.ini");
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode2", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId2", buf, ".\\card.ini");
}
BOOL
DllMain (HMODULE module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) {
// This is bad, dont do this
// I/O in DllMain can easily cause a deadlock
std::string version = "auto";
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto amauth = openConfigSection (config, "amauth");
if (amauth) {
server = readConfigString (amauth, "server", server);
port = readConfigString (amauth, "port", port);
chassisId = readConfigString (amauth, "chassis_id", chassisId);
shopId = readConfigString (amauth, "shop_id", shopId);
gameVerNum = readConfigString (amauth, "game_ver", gameVerNum);
countryCode = readConfigString (amauth, "country_code", countryCode);
std::strcat (fullAddress, server.c_str ());
std::strcat (fullAddress, ":");
std::strcat (fullAddress, port.c_str ());
std::strcat (placeId, countryCode.c_str ());
std::strcat (placeId, "0FF0");
}
auto patches = openConfigSection (config, "patches");
if (patches) version = readConfigString (patches, "version", version);
}
if (version == "auto") {
GetGameVersion ();
} else if (version == "jp_nov_2020") {
gameVersion = GameVersion::JP_NOV_2020;
} else if (version == "cn_jun_2023") {
gameVersion = GameVersion::CN_JUN_2023;
} else if (version == "jp_apr_2023") {
gameVersion = GameVersion::JP_APR_2023;
} else {
MessageBoxA (0, "Unknown patch version", 0, MB_OK);
ExitProcess (0);
}
auto pluginPath = std::filesystem::current_path () / "plugins";
if (std::filesystem::exists (pluginPath)) {
for (auto entry : std::filesystem::directory_iterator (pluginPath)) {
if (entry.path ().extension () == ".dll") {
auto name = entry.path ().wstring ();
HMODULE hModule = LoadLibraryW (name.c_str ());
if (!hModule) {
wchar_t buf[128];
wsprintfW (buf, L"Failed to load plugin %ls", name.c_str ());
MessageBoxW (0, buf, name.c_str (), MB_ICONERROR);
} else {
plugins.push_back (hModule);
}
}
}
}
if (!std::filesystem::exists (".\\card.ini")) createCard ();
GetPrivateProfileStringA ("card", "accessCode1", accessCode1, accessCode1, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId1", chipId1, chipId1, 33, ".\\card.ini");
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 33, ".\\card.ini");
INSTALL_HOOK (ShowMouse);
INSTALL_HOOK (ExitWindows);
INSTALL_HOOK (XinputGetState);
INSTALL_HOOK (XinputSetState);
INSTALL_HOOK (XinputGetCapabilites);
INSTALL_HOOK (ssleay_Shutdown);
INSTALL_HOOK (UsbFinderInitialize);
INSTALL_HOOK (UsbFinderRelease);
INSTALL_HOOK (UsbFinderGetSerialNumber);
INSTALL_HOOK (ws2_getaddrinfo);
bnusio::Init ();
switch (gameVersion) {
case GameVersion::UNKNOWN: break;
case GameVersion::JP_NOV_2020: patches::JP_NOV_2020::Init (); break;
case GameVersion::CN_JUN_2023: patches::CN_JUN_2023::Init (); break;
case GameVersion::JP_APR_2023: patches::JP_APR_2023::Init (); break;
}
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,212 +1,212 @@
#include "helpers.h"
#include "patches.h"
#include <safetyhook.hpp>
extern std::string chassisId;
namespace patches::CN_JUN_2023 {
u8 *haspBuffer;
HOOK (i32, HaspDecrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_decrypt")) { return 0; }
HOOK (i32, HaspEncrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_encrypt")) { return 0; }
HOOK (i32, HaspLogout, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_logout")) { return 0; }
HOOK (i32, HaspWrite, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_write")) { return 0; }
HOOK (i32, HaspLogin, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_login"), i32, char *, i32 *id) {
*id = 1;
return 0;
}
HOOK (i32, HaspGetInfo, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_get_info"), const char *, const char *, void *, const char **a4) {
*a4 = "type=\"HASP-HL\"";
return 0;
}
HOOK (i32, HaspRead, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_read"), i32, i32, i32 offset, i32 length, void *buffer) {
memcpy (buffer, haspBuffer + offset, length);
return 0;
}
i64 (__fastcall *lua_settop) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_settop");
i64 (__fastcall *lua_pushboolean) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushboolean");
i64 (__fastcall *lua_pushstring) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushstring");
i64
lua_pushtrue (i64 a1) {
lua_settop (a1, 0);
lua_pushboolean (a1, 1);
return 1;
}
HOOK (i64, AvailableMode_Dani_AI, ASLR (0x1401AC550), i64 a1) { return lua_pushtrue (a1); }
HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402BFF70), i64 *, i64 a2) { return lua_pushtrue (a2); }
HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402BC9B0), i64 a1) { return lua_pushtrue (a1); }
int language = 0;
const char *
languageStr () {
switch (language) {
case 1: return "en_us";
case 2: return "cn_tw";
case 3: return "kor";
case 4: return "cn_cn";
default: return "jpn";
}
}
HOOK (i64, GetLanguage, ASLR (0x140023720), i64 a1) {
auto result = originalGetLanguage (a1);
language = *((u32 *)result);
return result;
}
HOOK (i64, GetRegionLanguage, ASLR (0x1401AC300), i64 a1) {
lua_settop (a1, 0);
lua_pushstring (a1, (u64)languageStr ());
return 1;
}
HOOK (i64, GetCabinetLanguage, ASLR (0x1401AF270), i64, i64 a2) {
lua_settop (a2, 0);
lua_pushstring (a2, (u64)languageStr ());
return 1;
}
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
const i32 datatableBufferSize = 1024 * 1024 * 12;
safetyhook::Allocation datatableBuffer1;
safetyhook::Allocation datatableBuffer2;
safetyhook::Allocation datatableBuffer3;
const std::vector<uintptr_t> datatableBuffer1Addresses = {0x140093430, 0x1400934A1, 0x1400934CB, 0x14009353C};
const std::vector<uintptr_t> datatableBuffer2Addresses = {0x14009341C, 0x14009354B, 0x14009357E};
const std::vector<uintptr_t> datatableBuffer3Addresses = {0x14009356F, 0x140093585, 0x1400935AF};
const std::vector<uintptr_t> memsetSizeAddresses = {0x140093416, 0x14009342A, 0x140093569};
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool sharedAudio = true;
bool unlockSongs = true;
bool fixLanguage = false;
bool demoMovie = true;
bool modeCollabo025 = false;
bool modeCollabo026 = false;
haspBuffer = (u8 *)malloc (0xD40);
memset (haspBuffer, 0, 0xD40);
strcpy ((char *)(haspBuffer + 0xD00), chassisId.c_str ());
u8 crc = 0;
for (int i = 0; i < 62; i++)
crc += haspBuffer[0xD00 + i];
haspBuffer[0xD3E] = crc;
haspBuffer[0xD3F] = haspBuffer[0xD3E] ^ 0xFF;
INSTALL_HOOK (HaspDecrypt);
INSTALL_HOOK (HaspEncrypt);
INSTALL_HOOK (HaspLogout);
INSTALL_HOOK (HaspWrite);
INSTALL_HOOK (HaspLogin);
INSTALL_HOOK (HaspGetInfo);
INSTALL_HOOK (HaspRead);
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto patches = openConfigSection (config, "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
auto cn_jun_2023 = openConfigSection (patches, "cn_jun_2023");
if (cn_jun_2023) {
fixLanguage = readConfigBool (cn_jun_2023, "fix_language", fixLanguage);
demoMovie = readConfigBool (cn_jun_2023, "demo_movie", demoMovie);
modeCollabo025 = readConfigBool (cn_jun_2023, "mode_collabo025", modeCollabo025);
modeCollabo026 = readConfigBool (cn_jun_2023, "mode_collabo026", modeCollabo026);
}
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (sharedAudio) WRITE_MEMORY (ASLR (0x140777F87), u8, 0xEB);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
// Disable SSLVerify
WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00);
// Move various files to current dir
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin");
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x03000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
}
// Fix language
if (fixLanguage) {
INSTALL_HOOK (GetLanguage);
INSTALL_HOOK (GetRegionLanguage);
INSTALL_HOOK (GetCabinetLanguage);
}
// Disable demo movie
if (!demoMovie) WRITE_MEMORY (ASLR (0x14047D387), u8, 0x00);
// Enable mode
INSTALL_HOOK (AvailableMode_Dani_AI);
if (modeCollabo025) INSTALL_HOOK (AvailableMode_Collabo025);
if (modeCollabo026) INSTALL_HOOK (AvailableMode_Collabo026);
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x25A00));
patches::Qr::Init ();
}
} // namespace patches::CN_JUN_2023
#include "helpers.h"
#include "patches.h"
#include <safetyhook.hpp>
extern std::string chassisId;
namespace patches::CN_JUN_2023 {
u8 *haspBuffer;
HOOK (i32, HaspDecrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_decrypt")) { return 0; }
HOOK (i32, HaspEncrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_encrypt")) { return 0; }
HOOK (i32, HaspLogout, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_logout")) { return 0; }
HOOK (i32, HaspWrite, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_write")) { return 0; }
HOOK (i32, HaspLogin, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_login"), i32, char *, i32 *id) {
*id = 1;
return 0;
}
HOOK (i32, HaspGetInfo, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_get_info"), const char *, const char *, void *, const char **a4) {
*a4 = "type=\"HASP-HL\"";
return 0;
}
HOOK (i32, HaspRead, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_read"), i32, i32, i32 offset, i32 length, void *buffer) {
memcpy (buffer, haspBuffer + offset, length);
return 0;
}
i64 (__fastcall *lua_settop) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_settop");
i64 (__fastcall *lua_pushboolean) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushboolean");
i64 (__fastcall *lua_pushstring) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushstring");
i64
lua_pushtrue (i64 a1) {
lua_settop (a1, 0);
lua_pushboolean (a1, 1);
return 1;
}
HOOK (i64, AvailableMode_Dani_AI, ASLR (0x1401AC550), i64 a1) { return lua_pushtrue (a1); }
HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402BFF70), i64 *, i64 a2) { return lua_pushtrue (a2); }
HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402BC9B0), i64 a1) { return lua_pushtrue (a1); }
int language = 0;
const char *
languageStr () {
switch (language) {
case 1: return "en_us";
case 2: return "cn_tw";
case 3: return "kor";
case 4: return "cn_cn";
default: return "jpn";
}
}
HOOK (i64, GetLanguage, ASLR (0x140023720), i64 a1) {
auto result = originalGetLanguage (a1);
language = *((u32 *)result);
return result;
}
HOOK (i64, GetRegionLanguage, ASLR (0x1401AC300), i64 a1) {
lua_settop (a1, 0);
lua_pushstring (a1, (u64)languageStr ());
return 1;
}
HOOK (i64, GetCabinetLanguage, ASLR (0x1401AF270), i64, i64 a2) {
lua_settop (a2, 0);
lua_pushstring (a2, (u64)languageStr ());
return 1;
}
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
const i32 datatableBufferSize = 1024 * 1024 * 12;
safetyhook::Allocation datatableBuffer1;
safetyhook::Allocation datatableBuffer2;
safetyhook::Allocation datatableBuffer3;
const std::vector<uintptr_t> datatableBuffer1Addresses = {0x140093430, 0x1400934A1, 0x1400934CB, 0x14009353C};
const std::vector<uintptr_t> datatableBuffer2Addresses = {0x14009341C, 0x14009354B, 0x14009357E};
const std::vector<uintptr_t> datatableBuffer3Addresses = {0x14009356F, 0x140093585, 0x1400935AF};
const std::vector<uintptr_t> memsetSizeAddresses = {0x140093416, 0x14009342A, 0x140093569};
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool sharedAudio = true;
bool unlockSongs = true;
bool fixLanguage = false;
bool demoMovie = true;
bool modeCollabo025 = false;
bool modeCollabo026 = false;
haspBuffer = (u8 *)malloc (0xD40);
memset (haspBuffer, 0, 0xD40);
strcpy ((char *)(haspBuffer + 0xD00), chassisId.c_str ());
u8 crc = 0;
for (int i = 0; i < 62; i++)
crc += haspBuffer[0xD00 + i];
haspBuffer[0xD3E] = crc;
haspBuffer[0xD3F] = haspBuffer[0xD3E] ^ 0xFF;
INSTALL_HOOK (HaspDecrypt);
INSTALL_HOOK (HaspEncrypt);
INSTALL_HOOK (HaspLogout);
INSTALL_HOOK (HaspWrite);
INSTALL_HOOK (HaspLogin);
INSTALL_HOOK (HaspGetInfo);
INSTALL_HOOK (HaspRead);
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto patches = openConfigSection (config, "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
auto cn_jun_2023 = openConfigSection (patches, "cn_jun_2023");
if (cn_jun_2023) {
fixLanguage = readConfigBool (cn_jun_2023, "fix_language", fixLanguage);
demoMovie = readConfigBool (cn_jun_2023, "demo_movie", demoMovie);
modeCollabo025 = readConfigBool (cn_jun_2023, "mode_collabo025", modeCollabo025);
modeCollabo026 = readConfigBool (cn_jun_2023, "mode_collabo026", modeCollabo026);
}
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (sharedAudio) WRITE_MEMORY (ASLR (0x140777F87), u8, 0xEB);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
// Disable SSLVerify
WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00);
// Move various files to current dir
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin");
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x03000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
}
// Fix language
if (fixLanguage) {
INSTALL_HOOK (GetLanguage);
INSTALL_HOOK (GetRegionLanguage);
INSTALL_HOOK (GetCabinetLanguage);
}
// Disable demo movie
if (!demoMovie) WRITE_MEMORY (ASLR (0x14047D387), u8, 0x00);
// Enable mode
INSTALL_HOOK (AvailableMode_Dani_AI);
if (modeCollabo025) INSTALL_HOOK (AvailableMode_Collabo025);
if (modeCollabo026) INSTALL_HOOK (AvailableMode_Collabo026);
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x25A00));
patches::Qr::Init ();
}
} // namespace patches::CN_JUN_2023

View File

@ -1,185 +1,185 @@
#include "helpers.h"
#include "patches.h"
#include <safetyhook.hpp>
const u64 song_data_size = 1024 * 1024 * 64;
void *song_data;
#define RDX_MOV 0x48, 0xBA
#define R8_MOV 0x49, 0xB8
#define GENERATE_MOV(instruction, location) \
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), (u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), \
(u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
namespace patches::JP_NOV_2020 {
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
const i32 datatableBufferSize = 1024 * 1024 * 12;
safetyhook::Allocation datatableBuffer;
const std::vector<uintptr_t> datatableBufferAddresses = {0x14006D9A6, 0x14006D9D3, 0x14006E048, 0x14006E075, 0x14006E3A8, 0x14006E3D5, 0x14006E988, 0x14006E9B5, 0x14006EE22, 0x14006EE51, 0x14006F068,
0x14006F095, 0x14006F2F8, 0x14006F325, 0x14006F698, 0x14006F6C5, 0x14006F919, 0x14006F948, 0x14006FC38, 0x14006FC67, 0x14007006C, 0x140070099,
0x1400703E3, 0x140070412, 0x140070EB3, 0x140070EE2, 0x140071748, 0x140071775, 0x140071A68, 0x140071A95, 0x140071DD2, 0x140071E04, 0x140072E44,
0x140072E73, 0x140073058, 0x140073085, 0x140073374, 0x1400733A0, 0x1400735E8, 0x140073615, 0x14007390C, 0x140073939, 0x140073E73, 0x140073EA6,
0x140074A8D, 0x140074ABC, 0x140075082, 0x1400750B1, 0x140075524, 0x140075550, 0x1400758A2, 0x1400758D1, 0x140075D88, 0x140075DB5, 0x1403BA8FD};
const std::vector<uintptr_t> memsetSizeAddresses = {0x14006D9A0, 0x14006E042, 0x14006E3A2, 0x14006E982, 0x14006EE1C, 0x14006F062, 0x14006F2F2, 0x14006F692, 0x14006F913,
0x14006FC32, 0x140070066, 0x1400703DD, 0x140070EAD, 0x140071742, 0x140071A62, 0x140071DCC, 0x140072E3E, 0x140073052,
0x14007336E, 0x1400735E2, 0x140073906, 0x140073E6D, 0x140074A87, 0x14007507C, 0x14007551E, 0x14007589C, 0x140075D82};
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool sharedAudio = true;
bool unlockSongs = true;
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto patches = openConfigSection (config, "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (sharedAudio) WRITE_MEMORY (ASLR (0x140692E17), u8, 0xEB);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10);
// Move various files to current dir
WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./");
WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin");
WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02);
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x01000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
}
// Remove song limit
{
WRITE_MEMORY (ASLR (0x140313726), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000);
WRITE_MEMORY (ASLR (0x14030643B), i32, 9000);
WRITE_MEMORY (ASLR (0x140306507), i32, 9000);
WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000);
WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000);
WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000);
WRITE_MEMORY (ASLR (0x140306893), i32, 9000);
WRITE_MEMORY (ASLR (0x14030698B), i32, 9000);
WRITE_MEMORY (ASLR (0x140313666), i32, 9000);
WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000);
WRITE_MEMORY (ASLR (0x140313B04), i32, 9000);
WRITE_MEMORY (ASLR (0x140313C24), i32, 9000);
WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000);
WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000);
WRITE_MEMORY (ASLR (0x140226146), i32, 9000);
WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000);
WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000);
WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000);
WRITE_MEMORY (ASLR (0x140315608), i32, 9000);
WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000);
WRITE_MEMORY (ASLR (0x140314059), i32, 9000);
WRITE_MEMORY (ASLR (0x140226063), i32, 9000);
WRITE_MEMORY (ASLR (0x14022609F), i32, 9000);
WRITE_MEMORY (ASLR (0x140226296), i32, 9000);
WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F46), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F97), i32, 9000);
song_data = malloc (song_data_size);
memset (song_data, 0, song_data_size);
// Song data
WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data));
// Crown data
WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data));
// Score ranks
WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069AC), u8, 0x90, 0x90, 0x90, 0x90, 0x90);
// Unknown
WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data));
}
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x35A00));
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB);
patches::Qr::Init ();
patches::AmAuth::Init ();
}
} // namespace patches::JP_NOV_2020
#include "helpers.h"
#include "patches.h"
#include <safetyhook.hpp>
const u64 song_data_size = 1024 * 1024 * 64;
void *song_data;
#define RDX_MOV 0x48, 0xBA
#define R8_MOV 0x49, 0xB8
#define GENERATE_MOV(instruction, location) \
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), (u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), \
(u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
namespace patches::JP_NOV_2020 {
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
const i32 datatableBufferSize = 1024 * 1024 * 12;
safetyhook::Allocation datatableBuffer;
const std::vector<uintptr_t> datatableBufferAddresses = {0x14006D9A6, 0x14006D9D3, 0x14006E048, 0x14006E075, 0x14006E3A8, 0x14006E3D5, 0x14006E988, 0x14006E9B5, 0x14006EE22, 0x14006EE51, 0x14006F068,
0x14006F095, 0x14006F2F8, 0x14006F325, 0x14006F698, 0x14006F6C5, 0x14006F919, 0x14006F948, 0x14006FC38, 0x14006FC67, 0x14007006C, 0x140070099,
0x1400703E3, 0x140070412, 0x140070EB3, 0x140070EE2, 0x140071748, 0x140071775, 0x140071A68, 0x140071A95, 0x140071DD2, 0x140071E04, 0x140072E44,
0x140072E73, 0x140073058, 0x140073085, 0x140073374, 0x1400733A0, 0x1400735E8, 0x140073615, 0x14007390C, 0x140073939, 0x140073E73, 0x140073EA6,
0x140074A8D, 0x140074ABC, 0x140075082, 0x1400750B1, 0x140075524, 0x140075550, 0x1400758A2, 0x1400758D1, 0x140075D88, 0x140075DB5, 0x1403BA8FD};
const std::vector<uintptr_t> memsetSizeAddresses = {0x14006D9A0, 0x14006E042, 0x14006E3A2, 0x14006E982, 0x14006EE1C, 0x14006F062, 0x14006F2F2, 0x14006F692, 0x14006F913,
0x14006FC32, 0x140070066, 0x1400703DD, 0x140070EAD, 0x140071742, 0x140071A62, 0x140071DCC, 0x140072E3E, 0x140073052,
0x14007336E, 0x1400735E2, 0x140073906, 0x140073E6D, 0x140074A87, 0x14007507C, 0x14007551E, 0x14007589C, 0x140075D82};
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool sharedAudio = true;
bool unlockSongs = true;
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
toml_table_t *config = config_ptr.get ();
if (config) {
auto patches = openConfigSection (config, "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (sharedAudio) WRITE_MEMORY (ASLR (0x140692E17), u8, 0xEB);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10);
// Move various files to current dir
WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./");
WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin");
WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02);
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x01000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
}
// Remove song limit
{
WRITE_MEMORY (ASLR (0x140313726), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000);
WRITE_MEMORY (ASLR (0x14030643B), i32, 9000);
WRITE_MEMORY (ASLR (0x140306507), i32, 9000);
WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000);
WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000);
WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000);
WRITE_MEMORY (ASLR (0x140306893), i32, 9000);
WRITE_MEMORY (ASLR (0x14030698B), i32, 9000);
WRITE_MEMORY (ASLR (0x140313666), i32, 9000);
WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000);
WRITE_MEMORY (ASLR (0x140313B04), i32, 9000);
WRITE_MEMORY (ASLR (0x140313C24), i32, 9000);
WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000);
WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000);
WRITE_MEMORY (ASLR (0x140226146), i32, 9000);
WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000);
WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000);
WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000);
WRITE_MEMORY (ASLR (0x140315608), i32, 9000);
WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000);
WRITE_MEMORY (ASLR (0x140314059), i32, 9000);
WRITE_MEMORY (ASLR (0x140226063), i32, 9000);
WRITE_MEMORY (ASLR (0x14022609F), i32, 9000);
WRITE_MEMORY (ASLR (0x140226296), i32, 9000);
WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F46), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F97), i32, 9000);
song_data = malloc (song_data_size);
memset (song_data, 0, song_data_size);
// Song data
WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data));
// Crown data
WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data));
// Score ranks
WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069AC), u8, 0x90, 0x90, 0x90, 0x90, 0x90);
// Unknown
WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data));
}
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x35A00));
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB);
WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB);
patches::Qr::Init ();
patches::AmAuth::Init ();
}
} // namespace patches::JP_NOV_2020

View File

@ -1,18 +1,18 @@
namespace patches {
namespace JP_NOV_2020 {
void Init ();
} // namespace JP_NOV_2020
namespace CN_JUN_2023 {
void Init ();
} // namespace CN_JUN_2023
namespace JP_APR_2023 {
void Init ();
} // namespace JP_APR_2023
namespace AmAuth {
void Init ();
} // namespace AmAuth
namespace Qr {
void Init ();
void Update ();
} // namespace Qr
} // namespace patches
namespace patches {
namespace JP_NOV_2020 {
void Init ();
} // namespace JP_NOV_2020
namespace CN_JUN_2023 {
void Init ();
} // namespace CN_JUN_2023
namespace JP_APR_2023 {
void Init ();
} // namespace JP_APR_2023
namespace AmAuth {
void Init ();
} // namespace AmAuth
namespace Qr {
void Init ();
void Update ();
} // namespace Qr
} // namespace patches

File diff suppressed because it is too large Load Diff

View File

@ -1,103 +1,103 @@
#pragma once
#include <SDL.h>
#include <stdbool.h>
#include <stdint.h>
#include <toml.h>
#include <windows.h>
enum SDLAxis {
SDL_AXIS_NULL,
SDL_AXIS_LEFT_LEFT,
SDL_AXIS_LEFT_RIGHT,
SDL_AXIS_LEFT_UP,
SDL_AXIS_LEFT_DOWN,
SDL_AXIS_RIGHT_LEFT,
SDL_AXIS_RIGHT_RIGHT,
SDL_AXIS_RIGHT_UP,
SDL_AXIS_RIGHT_DOWN,
SDL_AXIS_LTRIGGER_DOWN,
SDL_AXIS_RTRIGGER_DOWN,
SDL_AXIS_MAX
};
struct SDLAxisState {
float LeftLeft;
float LeftRight;
float LeftUp;
float LeftDown;
float RightLeft;
float RightRight;
float RightUp;
float RightDown;
float LTriggerDown;
float RTriggerDown;
};
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
struct Keybindings {
uint8_t keycodes[255];
SDL_GameControllerButton buttons[255];
SDLAxis axis[255];
Scroll scroll[2];
};
enum EnumType { none, keycode, button, axis, scroll };
struct ConfigValue {
EnumType type;
union {
uint8_t keycode;
SDL_GameControllerButton button;
SDLAxis axis;
Scroll scroll;
};
};
struct InternalButtonState {
float Down;
bool Released;
bool Tapped;
};
bool InitializePoll (HWND windowHandle);
void UpdatePoll (HWND windowHandle);
void DisposePoll ();
ConfigValue StringToConfigEnum (const char *value);
void SetConfigValue (toml_table_t *table, const char *key, Keybindings *keybind);
InternalButtonState GetInternalButtonState (Keybindings bindings);
void SetRumble (int left, int right, int length);
bool KeyboardIsDown (uint8_t keycode);
bool KeyboardIsUp (uint8_t keycode);
bool KeyboardIsTapped (uint8_t keycode);
bool KeyboardIsReleased (uint8_t keycode);
bool KeyboardWasDown (uint8_t keycode);
bool KeyboardWasUp (uint8_t keycode);
POINT GetMousePosition ();
POINT GetLastMousePosition ();
POINT GetMouseRelativePosition ();
POINT GetLastMouseRelativePosition ();
void SetMousePosition (POINT newPosition);
bool GetMouseScrollUp ();
bool GetMouseScrollDown ();
bool GetWasMouseScrollUp ();
bool GetWasMouseScrollDown ();
bool GetMouseScrollIsReleased (Scroll scroll);
bool GetMouseScrollIsDown (Scroll scroll);
bool GetMouseScrollIsTapped (Scroll scroll);
bool ControllerButtonIsDown (SDL_GameControllerButton button);
bool ControllerButtonIsUp (SDL_GameControllerButton button);
bool ControllerButtonWasDown (SDL_GameControllerButton button);
bool ControllerButtonWasUp (SDL_GameControllerButton button);
bool ControllerButtonIsTapped (SDL_GameControllerButton button);
bool ControllerButtonIsReleased (SDL_GameControllerButton button);
float ControllerAxisIsDown (SDLAxis axis);
bool ControllerAxisIsUp (SDLAxis axis);
float ControllerAxisWasDown (SDLAxis axis);
bool ControllerAxisWasUp (SDLAxis axis);
bool ControllerAxisIsTapped (SDLAxis axis);
bool ControllerAxisIsReleased (SDLAxis axis);
bool IsButtonTapped (Keybindings bindings);
bool IsButtonReleased (Keybindings bindings);
float IsButtonDown (Keybindings bindings);
#pragma once
#include <SDL.h>
#include <stdbool.h>
#include <stdint.h>
#include <toml.h>
#include <windows.h>
enum SDLAxis {
SDL_AXIS_NULL,
SDL_AXIS_LEFT_LEFT,
SDL_AXIS_LEFT_RIGHT,
SDL_AXIS_LEFT_UP,
SDL_AXIS_LEFT_DOWN,
SDL_AXIS_RIGHT_LEFT,
SDL_AXIS_RIGHT_RIGHT,
SDL_AXIS_RIGHT_UP,
SDL_AXIS_RIGHT_DOWN,
SDL_AXIS_LTRIGGER_DOWN,
SDL_AXIS_RTRIGGER_DOWN,
SDL_AXIS_MAX
};
struct SDLAxisState {
float LeftLeft;
float LeftRight;
float LeftUp;
float LeftDown;
float RightLeft;
float RightRight;
float RightUp;
float RightDown;
float LTriggerDown;
float RTriggerDown;
};
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
struct Keybindings {
uint8_t keycodes[255];
SDL_GameControllerButton buttons[255];
SDLAxis axis[255];
Scroll scroll[2];
};
enum EnumType { none, keycode, button, axis, scroll };
struct ConfigValue {
EnumType type;
union {
uint8_t keycode;
SDL_GameControllerButton button;
SDLAxis axis;
Scroll scroll;
};
};
struct InternalButtonState {
float Down;
bool Released;
bool Tapped;
};
bool InitializePoll (HWND windowHandle);
void UpdatePoll (HWND windowHandle);
void DisposePoll ();
ConfigValue StringToConfigEnum (const char *value);
void SetConfigValue (toml_table_t *table, const char *key, Keybindings *keybind);
InternalButtonState GetInternalButtonState (Keybindings bindings);
void SetRumble (int left, int right, int length);
bool KeyboardIsDown (uint8_t keycode);
bool KeyboardIsUp (uint8_t keycode);
bool KeyboardIsTapped (uint8_t keycode);
bool KeyboardIsReleased (uint8_t keycode);
bool KeyboardWasDown (uint8_t keycode);
bool KeyboardWasUp (uint8_t keycode);
POINT GetMousePosition ();
POINT GetLastMousePosition ();
POINT GetMouseRelativePosition ();
POINT GetLastMouseRelativePosition ();
void SetMousePosition (POINT newPosition);
bool GetMouseScrollUp ();
bool GetMouseScrollDown ();
bool GetWasMouseScrollUp ();
bool GetWasMouseScrollDown ();
bool GetMouseScrollIsReleased (Scroll scroll);
bool GetMouseScrollIsDown (Scroll scroll);
bool GetMouseScrollIsTapped (Scroll scroll);
bool ControllerButtonIsDown (SDL_GameControllerButton button);
bool ControllerButtonIsUp (SDL_GameControllerButton button);
bool ControllerButtonWasDown (SDL_GameControllerButton button);
bool ControllerButtonWasUp (SDL_GameControllerButton button);
bool ControllerButtonIsTapped (SDL_GameControllerButton button);
bool ControllerButtonIsReleased (SDL_GameControllerButton button);
float ControllerAxisIsDown (SDLAxis axis);
bool ControllerAxisIsUp (SDLAxis axis);
float ControllerAxisWasDown (SDLAxis axis);
bool ControllerAxisWasUp (SDLAxis axis);
bool ControllerAxisIsTapped (SDLAxis axis);
bool ControllerAxisIsReleased (SDLAxis axis);
bool IsButtonTapped (Keybindings bindings);
bool IsButtonReleased (Keybindings bindings);
float IsButtonDown (Keybindings bindings);

View File

@ -1,21 +1,21 @@
--- minhook/meson.build
+++ minhook/meson.build
@@ -0,0 +1,18 @@
+project('minhook', 'c', version: '1.0.0')
+
+minhook_inc = include_directories('include')
+minhook_lib = static_library(
+ 'minhook',
+ include_directories: minhook_inc,
+ sources: [
+ 'src/buffer.c',
+ 'src/hook.c',
+ 'src/trampoline.c',
+ 'src/hde/hde32.c',
+ 'src/hde/hde64.c'
+ ]
+)
+minhook_dep = declare_dependency(
+ link_with: minhook_lib,
+ include_directories: minhook_inc,
+)
--- minhook/meson.build
+++ minhook/meson.build
@@ -0,0 +1,18 @@
+project('minhook', 'c', version: '1.0.0')
+
+minhook_inc = include_directories('include')
+minhook_lib = static_library(
+ 'minhook',
+ include_directories: minhook_inc,
+ sources: [
+ 'src/buffer.c',
+ 'src/hook.c',
+ 'src/trampoline.c',
+ 'src/hde/hde32.c',
+ 'src/hde/hde64.c'
+ ]
+)
+minhook_dep = declare_dependency(
+ link_with: minhook_lib,
+ include_directories: minhook_inc,
+)

View File

@ -1,15 +1,15 @@
--- tomlc99/meson.build
+++ tomlc99/meson.build
@@ -0,0 +1,12 @@
+project('tomlc99', 'c', version: '1.0.0')
+
+tomlc99_inc = include_directories('.')
+tomlc99_lib = static_library(
+ 'tomlc99',
+ include_directories: tomlc99_inc,
+ sources: ['toml.c']
+)
+tomlc99_dep = declare_dependency(
+ link_with: tomlc99_lib,
+ include_directories: tomlc99_inc,
+)
--- tomlc99/meson.build
+++ tomlc99/meson.build
@@ -0,0 +1,12 @@
+project('tomlc99', 'c', version: '1.0.0')
+
+tomlc99_inc = include_directories('.')
+tomlc99_lib = static_library(
+ 'tomlc99',
+ include_directories: tomlc99_inc,
+ sources: ['toml.c']
+)
+tomlc99_dep = declare_dependency(
+ link_with: tomlc99_lib,
+ include_directories: tomlc99_inc,
+)

View File

@ -1,7 +1,7 @@
[wrap-git]
url = https://github.com/cursey/safetyhook.git
revision = v0.4.1
method = cmake
[provide]
safetyhook = safetyhook_dep
[wrap-git]
url = https://github.com/cursey/safetyhook.git
revision = v0.4.1
method = cmake
[provide]
safetyhook = safetyhook_dep

View File

@ -1,4 +1,4 @@
[wrap-git]
url = https://github.com/cktan/tomlc99.git
revision = master
diff_files = tomlc99.patch
[wrap-git]
url = https://github.com/cktan/tomlc99.git
revision = master
diff_files = tomlc99.patch