diff --git a/.clang-format b/.clang-format index 851691f..99e8abd 100644 --- a/.clang-format +++ b/.clang-format @@ -1,10 +1,10 @@ -BasedOnStyle: LLVM +BasedOnStyle: GNU IndentWidth: 4 TabWidth: 4 -UseTab: ForIndentation +UseTab: Never IndentCaseLabels: False BreakBeforeBraces: Attach -ColumnLimit: 200 +ColumnLimit: 150 AlignConsecutiveAssignments: Consecutive AlignConsecutiveMacros: Consecutive AllowShortBlocksOnASingleLine: Always @@ -19,3 +19,4 @@ AlwaysBreakAfterReturnType: TopLevelDefinitions RemoveBracesLLVM: True AlignEscapedNewlines: Left AccessModifierOffset: -4 +Cpp11BracedListStyle: True diff --git a/src/bnusio.cpp b/src/bnusio.cpp index 82e8528..7c895dc 100644 --- a/src/bnusio.cpp +++ b/src/bnusio.cpp @@ -45,7 +45,7 @@ Keybindings P2_RIGHT_BLUE = {}; namespace bnusio { #define RETURN_FALSE(returnType, functionName, ...) \ - returnType functionName (__VA_ARGS__) { return 0; } + returnType functionName (__VA_ARGS__) { return 0; } extern "C" { RETURN_FALSE (i64, bnusio_ClearSram); @@ -90,15 +90,16 @@ RETURN_FALSE (i64, bnusio_ResetCoin); RETURN_FALSE (i64, bnusio_DecCoin, i32 a1, u16 a2); size_t bnusio_GetFirmwareVersion () { - return 126; + 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 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; @@ -113,53 +114,54 @@ SDLAxis analogBindings[] = { 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; - } + 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; - } + 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; @@ -169,105 +171,107 @@ HWND windowHandle = nullptr; HKL currentLayout; u16 __fastcall bnusio_GetCoin (i32 a1) { - if (a1 != 1) return coin_count; + if (a1 != 1) return coin_count; - if (!inited) { - windowHandle = FindWindowA ("nuFoundation.Window", nullptr); - InitializePoll (windowHandle); - if (autoIME) { - currentLayout = GetKeyboardLayout (0); - auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE); - ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS); - } + if (!inited) { + windowHandle = FindWindowA ("nuFoundation.Window", nullptr); + InitializePoll (windowHandle); + if (autoIME) { + currentLayout = GetKeyboardLayout (0); + auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE); + ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS); + } - for (auto plugin : plugins) { - auto initEvent = GetProcAddress (plugin, "Init"); - if (initEvent) initEvent (); - } + for (auto plugin : plugins) { + auto initEvent = GetProcAddress (plugin, "Init"); + if (initEvent) initEvent (); + } - inited = true; - } + 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); - } - } - } + 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 (); - } + for (auto plugin : plugins) { + auto updateEvent = GetProcAddress (plugin, "Update"); + if (updateEvent) updateEvent (); + } - patches::Qr::Update (); + patches::Qr::Update (); - if (attachCallback) attachCallback (0, 0, attachData); - return coin_count; + 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; + 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 () { - if (autoIME) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS); - for (auto plugin : plugins) { - FARPROC exitEvent = GetProcAddress (plugin, "Exit"); - if (exitEvent) ((event *)exitEvent) (); - } - return 0; + if (autoIME) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS); + for (auto plugin : plugins) { + FARPROC exitEvent = GetProcAddress (plugin, "Exit"); + if (exitEvent) ((event *)exitEvent) (); + } + return 0; } } @@ -291,92 +295,93 @@ HOOK (u64, bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower 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; + // 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; +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 () { - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - toml_table_t *config = config_ptr.get (); - 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 card = openConfigSection (config, "card_reader"); - if (card) { - bool cardEnabled = readConfigBool (card, "enabled", true); - if (cardEnabled) { - 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); - } else { - std::cout << "[Init] Card reader emulation disabled" << std::endl; - } - } - } + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + toml_table_t *config = config_ptr.get (); + 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 card = openConfigSection (config, "card_reader"); + if (card) { + bool cardEnabled = readConfigBool (card, "enabled", true); + if (cardEnabled) { + 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); + } else { + std::cout << "[Init] Card reader emulation disabled" << std::endl; + } + } + } - auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml"; - std::unique_ptr keyconfig_ptr (openConfig (keyconfigPath), toml_free); - if (keyconfig_ptr) { - toml_table_t *keyconfig = keyconfig_ptr.get (); - SetConfigValue (keyconfig, "EXIT", &EXIT); + auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml"; + std::unique_ptr keyconfig_ptr (openConfig (keyconfigPath), toml_free); + if (keyconfig_ptr) { + toml_table_t *keyconfig = keyconfig_ptr.get (); + 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, "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, "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); - } + 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 diff --git a/src/constants.h b/src/constants.h index ae46b73..33222f1 100644 --- a/src/constants.h +++ b/src/constants.h @@ -2,9 +2,9 @@ #include enum class GameVersion : XXH64_hash_t { - UNKNOWN = 0, - JPN00 = 0x4C07355966D815FB, - JPN08 = 0x67C0F3042746D488, - JPN39 = 0x49F643ADB6B18705, - CHN00 = 0xA7EE39F2CC2C57C8, + UNKNOWN = 0, + JPN00 = 0x4C07355966D815FB, + JPN08 = 0x67C0F3042746D488, + JPN39 = 0x49F643ADB6B18705, + CHN00 = 0xA7EE39F2CC2C57C8, }; \ No newline at end of file diff --git a/src/dllmain.cpp b/src/dllmain.cpp index 86789bb..8785489 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -35,165 +35,165 @@ HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown")) { ret 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; + 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); + return originalws2_getaddrinfo (server.c_str (), service, hints, out); } void GetGameVersion () { - wchar_t w_path[MAX_PATH]; - GetModuleFileNameW (nullptr, w_path, MAX_PATH); - std::filesystem::path path (w_path); - - if (!std::filesystem::exists (path) || !path.has_filename ()) { - MessageBoxA (nullptr, "Failed to find executable", nullptr, MB_OK); - ExitProcess (0); - } - - std::ifstream stream (path, std::ios::binary); - if (!stream.is_open ()) { - MessageBoxA (nullptr, "Failed to read executable", nullptr, MB_OK); - ExitProcess (0); - } - - stream.seekg (0, std::ifstream::end); - size_t length = stream.tellg (); - stream.seekg (0, std::ifstream::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::JPN00: - case GameVersion::JPN08: - case GameVersion::JPN39: - case GameVersion::CHN00: break; - default: MessageBoxA (nullptr, "Unknown game version", nullptr, MB_OK); ExitProcess (0); - } + wchar_t w_path[MAX_PATH]; + GetModuleFileNameW (nullptr, w_path, MAX_PATH); + std::filesystem::path path (w_path); + + if (!std::filesystem::exists (path) || !path.has_filename ()) { + MessageBoxA (nullptr, "Failed to find executable", nullptr, MB_OK); + ExitProcess (0); + } + + std::ifstream stream (path, std::ios::binary); + if (!stream.is_open ()) { + MessageBoxA (nullptr, "Failed to read executable", nullptr, MB_OK); + ExitProcess (0); + } + + stream.seekg (0, std::ifstream::end); + size_t length = stream.tellg (); + stream.seekg (0, std::ifstream::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::JPN00: + case GameVersion::JPN08: + case GameVersion::JPN39: + case GameVersion::CHN00: break; + default: MessageBoxA (nullptr, "Unknown game version", nullptr, 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 (nullptr)); - - 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"); + 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 (nullptr)); + + 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 config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - toml_table_t *config = config_ptr.get (); - 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); - autoIME = readConfigBool (patches, "auto_ime", autoIME); - } - } - - if (version == "auto") { - GetGameVersion (); - } else if (version == "JPN00") { - gameVersion = GameVersion::JPN00; - } else if (version == "JPN08") { - gameVersion = GameVersion::JPN08; - } else if (version == "JPN39") { - gameVersion = GameVersion::JPN39; - } else if (version == "CHN00") { - gameVersion = GameVersion::CHN00; - } else { - MessageBoxA (nullptr, "Unknown patch version", nullptr, MB_OK); - ExitProcess (0); - } - - auto pluginPath = std::filesystem::current_path () / "plugins"; - - if (std::filesystem::exists (pluginPath)) { - for (const 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::JPN00: patches::JPN00::Init (); break; - case GameVersion::JPN08: patches::JPN08::Init (); break; - case GameVersion::JPN39: patches::JPN39::Init (); break; - case GameVersion::CHN00: patches::CHN00::Init (); break; - } - } - return true; + 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 config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + toml_table_t *config = config_ptr.get (); + 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); + autoIME = readConfigBool (patches, "auto_ime", autoIME); + } + } + + if (version == "auto") { + GetGameVersion (); + } else if (version == "JPN00") { + gameVersion = GameVersion::JPN00; + } else if (version == "JPN08") { + gameVersion = GameVersion::JPN08; + } else if (version == "JPN39") { + gameVersion = GameVersion::JPN39; + } else if (version == "CHN00") { + gameVersion = GameVersion::CHN00; + } else { + MessageBoxA (nullptr, "Unknown patch version", nullptr, MB_OK); + ExitProcess (0); + } + + auto pluginPath = std::filesystem::current_path () / "plugins"; + + if (std::filesystem::exists (pluginPath)) { + for (const 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::JPN00: patches::JPN00::Init (); break; + case GameVersion::JPN08: patches::JPN08::Init (); break; + case GameVersion::JPN39: patches::JPN39::Init (); break; + case GameVersion::CHN00: patches::CHN00::Init (); break; + } + } + return true; } diff --git a/src/helpers.cpp b/src/helpers.cpp index 918951a..5499668 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -5,107 +5,107 @@ void *consoleHandle = 0; static void toml_myfree (void *p) { - if (p) { - char *pp = (char *)p; - delete[] pp; - } + if (p) { + char *pp = (char *)p; + delete[] pp; + } } toml_table_t * openConfig (std::filesystem::path path) { - if (!std::filesystem::exists (path) || !path.has_filename ()) { - printWarning ("%s (%s): file does not exist\n", __func__, path.string ().c_str ()); - return 0; - } - - std::ifstream stream (path); - if (!stream.is_open ()) { - printWarning ("%s (%s): could not open\n", __func__, path.string ().c_str ()); - return 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); - - char errorbuf[200]; - toml_table_t *config = toml_parse (buf, errorbuf, 200); - stream.close (); - free (buf); - - if (!config) { - printWarning ("%s (%s): %s\n", __func__, path.string ().c_str (), errorbuf); - return 0; - } - - return config; + if (!std::filesystem::exists (path) || !path.has_filename ()) { + printWarning ("%s (%s): file does not exist\n", __func__, path.string ().c_str ()); + return 0; + } + + std::ifstream stream (path); + if (!stream.is_open ()) { + printWarning ("%s (%s): could not open\n", __func__, path.string ().c_str ()); + return 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); + + char errorbuf[200]; + toml_table_t *config = toml_parse (buf, errorbuf, 200); + stream.close (); + free (buf); + + if (!config) { + printWarning ("%s (%s): %s\n", __func__, path.string ().c_str (), errorbuf); + return 0; + } + + return config; } toml_table_t * openConfigSection (toml_table_t *config, const std::string §ionName) { - toml_table_t *section = toml_table_in (config, sectionName.c_str ()); - if (!section) { - printWarning ("%s (%s): cannot find section\n", __func__, sectionName.c_str ()); - return 0; - } + toml_table_t *section = toml_table_in (config, sectionName.c_str ()); + if (!section) { + printWarning ("%s (%s): cannot find section\n", __func__, sectionName.c_str ()); + return 0; + } - return section; + return section; } bool readConfigBool (toml_table_t *table, const std::string &key, bool notFoundValue) { - toml_datum_t data = toml_bool_in (table, key.c_str ()); - if (!data.ok) return notFoundValue; + toml_datum_t data = toml_bool_in (table, key.c_str ()); + if (!data.ok) return notFoundValue; - return (bool)data.u.b; + return (bool)data.u.b; } int64_t readConfigInt (toml_table_t *table, const std::string &key, int64_t notFoundValue) { - toml_datum_t data = toml_int_in (table, key.c_str ()); - if (!data.ok) return notFoundValue; + toml_datum_t data = toml_int_in (table, key.c_str ()); + if (!data.ok) return notFoundValue; - return data.u.i; + return data.u.i; } const std::string readConfigString (toml_table_t *table, const std::string &key, const std::string ¬FoundValue) { - toml_datum_t data = toml_string_in (table, key.c_str ()); - if (!data.ok) return notFoundValue; - std::string str = data.u.s; - toml_myfree (data.u.s); + toml_datum_t data = toml_string_in (table, key.c_str ()); + if (!data.ok) return notFoundValue; + std::string str = data.u.s; + toml_myfree (data.u.s); - return str; + return str; } std::vector readConfigIntArray (toml_table_t *table, const std::string &key, std::vector notFoundValue) { - toml_array_t *array = toml_array_in (table, key.c_str ()); - if (!array) return notFoundValue; + toml_array_t *array = toml_array_in (table, key.c_str ()); + if (!array) return notFoundValue; - std::vector datas; - for (int i = 0;; i++) { - toml_datum_t data = toml_int_at (array, i); - if (!data.ok) break; - datas.push_back (data.u.i); - } + std::vector datas; + for (int i = 0;; i++) { + toml_datum_t data = toml_int_at (array, i); + if (!data.ok) break; + datas.push_back (data.u.i); + } - return datas; + return datas; } void printColour (int colour, const char *format, ...) { - va_list args; - va_start (args, format); + va_list args; + va_start (args, format); - if (consoleHandle == 0) consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE); + if (consoleHandle == 0) consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE); - SetConsoleTextAttribute (consoleHandle, colour); - vprintf (format, args); - SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); + SetConsoleTextAttribute (consoleHandle, colour); + vprintf (format, args); + SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); - va_end (args); + va_end (args); } diff --git a/src/helpers.h b/src/helpers.h index aece032..044c8ec 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -32,78 +32,78 @@ const HMODULE MODULE_HANDLE = GetModuleHandle (nullptr); #endif #define HOOK(returnType, functionName, location, ...) \ - typedef returnType (*functionName) (__VA_ARGS__); \ - functionName original##functionName = NULL; \ - void *where##functionName = (void *)(location); \ - returnType implOf##functionName (__VA_ARGS__) + typedef returnType (*functionName) (__VA_ARGS__); \ + functionName original##functionName = NULL; \ + void *where##functionName = (void *)(location); \ + returnType implOf##functionName (__VA_ARGS__) #define HOOK_DYNAMIC(returnType, callingConvention, functionName, ...) \ - typedef returnType callingConvention (*functionName) (__VA_ARGS__); \ - functionName original##functionName = NULL; \ - void *where##functionName = NULL; \ - returnType callingConvention implOf##functionName (__VA_ARGS__) + typedef returnType callingConvention (*functionName) (__VA_ARGS__); \ + functionName original##functionName = NULL; \ + void *where##functionName = NULL; \ + returnType callingConvention implOf##functionName (__VA_ARGS__) #define VTABLE_HOOK(returnType, className, functionName, ...) \ - typedef returnType (*className##functionName) (className * This, __VA_ARGS__); \ - className##functionName original##className##functionName = NULL; \ - void *where##className##functionName = NULL; \ - returnType implOf##className##functionName (className *This, __VA_ARGS__) + typedef returnType (*className##functionName) (className * This, __VA_ARGS__); \ + className##functionName original##className##functionName = NULL; \ + void *where##className##functionName = NULL; \ + returnType implOf##className##functionName (className *This, __VA_ARGS__) #define INSTALL_HOOK(functionName) \ - { \ - MH_Initialize (); \ - MH_CreateHook ((void *)where##functionName, (void *)implOf##functionName, (void **)(&original##functionName)); \ - MH_EnableHook ((void *)where##functionName); \ - } + { \ + MH_Initialize (); \ + MH_CreateHook ((void *)where##functionName, (void *)implOf##functionName, (void **)(&original##functionName)); \ + MH_EnableHook ((void *)where##functionName); \ + } #define INSTALL_HOOK_DYNAMIC(functionName, location) \ - { \ - where##functionName = (void *)location; \ - INSTALL_HOOK (functionName); \ - } + { \ + where##functionName = (void *)location; \ + INSTALL_HOOK (functionName); \ + } #define INSTALL_VTABLE_HOOK(className, object, functionName, functionIndex) \ - { \ - where##className##functionName = (*(className##functionName ***)object)[functionIndex]; \ - INSTALL_HOOK (className##functionName); \ - } + { \ + where##className##functionName = (*(className##functionName ***)object)[functionIndex]; \ + INSTALL_HOOK (className##functionName); \ + } #define READ_MEMORY(location, type) *(type *)location #define WRITE_MEMORY(location, type, ...) \ - { \ - const type data[] = {__VA_ARGS__}; \ - DWORD oldProtect; \ - VirtualProtect ((void *)(location), sizeof (data), PAGE_EXECUTE_READWRITE, &oldProtect); \ - memcpy ((void *)(location), data, sizeof (data)); \ - VirtualProtect ((void *)(location), sizeof (data), oldProtect, &oldProtect); \ - } + { \ + const type data[] = {__VA_ARGS__}; \ + DWORD oldProtect; \ + VirtualProtect ((void *)(location), sizeof (data), PAGE_EXECUTE_READWRITE, &oldProtect); \ + memcpy ((void *)(location), data, sizeof (data)); \ + VirtualProtect ((void *)(location), sizeof (data), oldProtect, &oldProtect); \ + } #define WRITE_MEMORY_STRING(location, data, length) \ - { \ - DWORD oldProtect; \ - VirtualProtect ((void *)(location), length, PAGE_EXECUTE_READWRITE, &oldProtect); \ - memcpy ((void *)(location), data, length); \ - VirtualProtect ((void *)(location), length, oldProtect, &oldProtect); \ - } + { \ + DWORD oldProtect; \ + VirtualProtect ((void *)(location), length, PAGE_EXECUTE_READWRITE, &oldProtect); \ + memcpy ((void *)(location), data, length); \ + VirtualProtect ((void *)(location), length, oldProtect, &oldProtect); \ + } #define WRITE_NOP(location, count) \ - { \ - DWORD oldProtect; \ - VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \ - for (size_t i = 0; i < (size_t)(count); i++) \ - *((uint8_t *)(location) + i) = 0x90; \ - VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \ - } + { \ + DWORD oldProtect; \ + VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \ + for (size_t i = 0; i < (size_t)(count); i++) \ + *((uint8_t *)(location) + i) = 0x90; \ + VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \ + } #define WRITE_NULL(location, count) \ - { \ - DWORD oldProtect; \ - VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \ - for (size_t i = 0; i < (size_t)(count); i++) \ - *((uint8_t *)(location) + i) = 0x00; \ - VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \ - } + { \ + DWORD oldProtect; \ + VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \ + for (size_t i = 0; i < (size_t)(count); i++) \ + *((uint8_t *)(location) + i) = 0x00; \ + VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \ + } #define COUNTOFARR(arr) sizeof (arr) / sizeof (arr[0]) diff --git a/src/patches/amauth.cpp b/src/patches/amauth.cpp index e38b11b..d726c5a 100644 --- a/src/patches/amauth.cpp +++ b/src/patches/amauth.cpp @@ -33,622 +33,624 @@ const GUID IID_CAuth{0x045A5150, 0xD2B3, 0x4590, {0xA3, 0x8B, 0xC1, 0x15, 0x86, const GUID IID_CAuthFactory{0x4603BB03, 0x058D, 0x43D9, {0xB9, 0x6F, 0x63, 0x9B, 0xE9, 0x08, 0xC1, 0xED}}; typedef struct amcus_network_state { - char mode[16]; - char pcbid[16]; - char dongle_serial[16]; - char shop_router_ip[16]; - char auth_server_ip[16]; - char local_ip[16]; - char subnet_mask[16]; - char gateway[16]; - char primary_dns[16]; - int hop_count; - uint32_t line_type; - uint32_t line_status; - uint32_t content_router_status; - uint32_t shop_router_status; - uint32_t hop_status; + char mode[16]; + char pcbid[16]; + char dongle_serial[16]; + char shop_router_ip[16]; + char auth_server_ip[16]; + char local_ip[16]; + char subnet_mask[16]; + char gateway[16]; + char primary_dns[16]; + int hop_count; + uint32_t line_type; + uint32_t line_status; + uint32_t content_router_status; + uint32_t shop_router_status; + uint32_t hop_status; } amcus_network_state_t; typedef struct amcus_auth_server_resp { - char uri[257]; - char host[257]; - char shop_name[256]; - char shop_nickname[256]; - char region0[16]; - char region_name0[256]; - char region_name1[256]; - char region_name2[256]; - char region_name3[256]; - char place_id[16]; - char setting[16]; - char country[16]; - char timezone[32]; - char res_class[64]; + char uri[257]; + char host[257]; + char shop_name[256]; + char shop_nickname[256]; + char region0[16]; + char region_name0[256]; + char region_name1[256]; + char region_name2[256]; + char region_name3[256]; + char place_id[16]; + char setting[16]; + char country[16]; + char timezone[32]; + char res_class[64]; } amcus_auth_server_resp_t; typedef struct amcus_version_info { - char game_rev[4]; - char auth_type[16]; - char game_id[8]; - char game_ver[8]; - char game_cd[8]; - char cacfg_game_ver[8]; - char game_board_type[4]; - char game_board_id[4]; - char auth_url[256]; + char game_rev[4]; + char auth_type[16]; + char game_id[8]; + char game_ver[8]; + char game_cd[8]; + char cacfg_game_ver[8]; + char game_board_type[4]; + char game_board_id[4]; + char auth_url[256]; } amcus_version_info_t; struct allnet_state {}; /* Memory Size: 144 */ struct mucha_state { - /* Offset: 0 */ /* ENUM32 */ uint32_t state; - /* Offset: 4 */ /* ENUM32 */ uint32_t error; - /* Offset: 8 */ int32_t auth_state; - /* Offset: 12 */ int32_t auth_count; - /* Offset: 16 */ int32_t state_dlexec; - /* Offset: 20 */ int32_t state_dlstep; - /* Offset: 24 */ int32_t state_dllan; - /* Offset: 28 */ int32_t state_dlwan; - /* Offset: 32 */ int32_t state_io; - /* Offset: 36 */ int16_t cacfg_ver_major; - /* Offset: 38 */ int16_t cacfg_ver_minor; - /* Offset: 40 */ int16_t app_ver_major; - /* Offset: 42 */ int16_t app_ver_minor; - /* Offset: 44 */ int16_t dl_ver_major; - /* Offset: 46 */ int16_t dl_ver_minor; - /* Offset: 48 */ int32_t dl_ver_total; - /* Offset: 52 */ int32_t dl_ver_done; - /* Offset: 56 */ int64_t dl_total; - /* Offset: 64 */ int64_t dl_done; - /* Offset: 72 */ int64_t dl_pc_done; - /* Offset: 80 */ int64_t dl_io_total; - /* Offset: 88 */ int64_t dl_io_done; - /* Offset: 96 */ int32_t dl_check_complete; - /* Offset: 100 */ int32_t token_consumed; - /* Offset: 104 */ int32_t token_charged; - /* Offset: 108 */ int32_t token_unit; - /* Offset: 112 */ int32_t token_lower; - /* Offset: 116 */ int32_t token_upper; - /* Offset: 120 */ int32_t token_added; - /* Offset: 124 */ int32_t token_month_lower; - /* Offset: 128 */ int32_t token_month_upper; - /* Offset: 132 */ int32_t is_forced_boot; - /* Offset: 136 */ int32_t Member88; - /* Offset: 140 */ int32_t unknown_a; - /* Offset: 144 */ int32_t unknown_b; + /* Offset: 0 */ /* ENUM32 */ uint32_t state; + /* Offset: 4 */ /* ENUM32 */ uint32_t error; + /* Offset: 8 */ int32_t auth_state; + /* Offset: 12 */ int32_t auth_count; + /* Offset: 16 */ int32_t state_dlexec; + /* Offset: 20 */ int32_t state_dlstep; + /* Offset: 24 */ int32_t state_dllan; + /* Offset: 28 */ int32_t state_dlwan; + /* Offset: 32 */ int32_t state_io; + /* Offset: 36 */ int16_t cacfg_ver_major; + /* Offset: 38 */ int16_t cacfg_ver_minor; + /* Offset: 40 */ int16_t app_ver_major; + /* Offset: 42 */ int16_t app_ver_minor; + /* Offset: 44 */ int16_t dl_ver_major; + /* Offset: 46 */ int16_t dl_ver_minor; + /* Offset: 48 */ int32_t dl_ver_total; + /* Offset: 52 */ int32_t dl_ver_done; + /* Offset: 56 */ int64_t dl_total; + /* Offset: 64 */ int64_t dl_done; + /* Offset: 72 */ int64_t dl_pc_done; + /* Offset: 80 */ int64_t dl_io_total; + /* Offset: 88 */ int64_t dl_io_done; + /* Offset: 96 */ int32_t dl_check_complete; + /* Offset: 100 */ int32_t token_consumed; + /* Offset: 104 */ int32_t token_charged; + /* Offset: 108 */ int32_t token_unit; + /* Offset: 112 */ int32_t token_lower; + /* Offset: 116 */ int32_t token_upper; + /* Offset: 120 */ int32_t token_added; + /* Offset: 124 */ int32_t token_month_lower; + /* Offset: 128 */ int32_t token_month_upper; + /* Offset: 132 */ int32_t is_forced_boot; + /* Offset: 136 */ int32_t Member88; + /* Offset: 140 */ int32_t unknown_a; + /* Offset: 144 */ int32_t unknown_b; }; /* Memory Size: 208 */ typedef struct amcus_state { - /* Offset: 0 */ /* ENUM32 */ uint32_t allnet_state; - /* Offset: 4 */ /* ENUM32 */ uint32_t allnet_error; - /* Offset: 8 */ int32_t allnet_auth_state; - /* Offset: 12 */ int32_t allnet_auth_count; - /* Offset: 16 */ int32_t allnet_last_error; - /* Offset: 24 */ struct mucha_state mucha_state; - /* Offset: 176 */ int64_t clock_status; - /* Offset: 184 */ int64_t name_resolution_timeout; - /* Offset: 192 */ /* ENUM32 */ uint32_t auth_type; - /* Offset: 196 */ /* ENUM32 */ uint32_t cab_mode; - /* Offset: 200 */ /* ENUM32 */ uint32_t state; - /* Offset: 204 */ /* ENUM32 */ uint32_t err; + /* Offset: 0 */ /* ENUM32 */ uint32_t allnet_state; + /* Offset: 4 */ /* ENUM32 */ uint32_t allnet_error; + /* Offset: 8 */ int32_t allnet_auth_state; + /* Offset: 12 */ int32_t allnet_auth_count; + /* Offset: 16 */ int32_t allnet_last_error; + /* Offset: 24 */ struct mucha_state mucha_state; + /* Offset: 176 */ int64_t clock_status; + /* Offset: 184 */ int64_t name_resolution_timeout; + /* Offset: 192 */ /* ENUM32 */ uint32_t auth_type; + /* Offset: 196 */ /* ENUM32 */ uint32_t cab_mode; + /* Offset: 200 */ /* ENUM32 */ uint32_t state; + /* Offset: 204 */ /* ENUM32 */ uint32_t err; } amcus_state_t; typedef struct mucha_boardauth_resp { - /* Offset: 0 */ char url_charge[256]; - /* Offset: 256 */ char url_file[256]; - /* Offset: 512 */ char url_url1[256]; - /* Offset: 768 */ char url_url2[256]; - /* Offset: 1024 */ char url_url3[256]; - - /* Offset: 1280 */ char place_id[16]; - /* Offset: 1296 */ char country_cd[16]; - /* Offset: 1312 */ char shop_name[256]; - /* Offset: 1568 */ char shop_nickname[128]; - /* Offset: 1696 */ char area0[64]; - /* Offset: 1760 */ char area1[64]; - /* Offset: 1824 */ char area2[64]; - /* Offset: 1888 */ char area3[64]; - /* Offset: 1952 */ char area_full0[256]; - /* Offset: 2208 */ char area_full1[256]; - /* Offset: 2464 */ char area_full2[256]; - /* Offset: 2720 */ char area_full3[256]; - - /* Offset: 2976 */ char shop_name_en[64]; - /* Offset: 3040 */ char shop_nickname_en[32]; - /* Offset: 3072 */ char area0_en[32]; - /* Offset: 3104 */ char area1_en[32]; - /* Offset: 3136 */ char area2_en[32]; - /* Offset: 3168 */ char area3_en[32]; - /* Offset: 3200 */ char area_full0_en[128]; - /* Offset: 3328 */ char area_full1_en[128]; - /* Offset: 3456 */ char area_full2_en[128]; - /* Offset: 3584 */ char area_full3_en[128]; - - /* Offset: 3712 */ char prefecture_id[16]; - /* Offset: 3728 */ char expiration_date[16]; - /* Offset: 3744 */ char use_token[16]; - /* Offset: 3760 */ char consume_token[32]; - /* Offset: 3792 */ char dongle_flag[8]; - /* Offset: 3800 */ char force_boot[8]; - /* Offset: 3808 */ char auth_token[384]; - /* Offset: 4192 */ char division_code[16]; + /* Offset: 0 */ char url_charge[256]; + /* Offset: 256 */ char url_file[256]; + /* Offset: 512 */ char url_url1[256]; + /* Offset: 768 */ char url_url2[256]; + /* Offset: 1024 */ char url_url3[256]; + + /* Offset: 1280 */ char place_id[16]; + /* Offset: 1296 */ char country_cd[16]; + /* Offset: 1312 */ char shop_name[256]; + /* Offset: 1568 */ char shop_nickname[128]; + /* Offset: 1696 */ char area0[64]; + /* Offset: 1760 */ char area1[64]; + /* Offset: 1824 */ char area2[64]; + /* Offset: 1888 */ char area3[64]; + /* Offset: 1952 */ char area_full0[256]; + /* Offset: 2208 */ char area_full1[256]; + /* Offset: 2464 */ char area_full2[256]; + /* Offset: 2720 */ char area_full3[256]; + + /* Offset: 2976 */ char shop_name_en[64]; + /* Offset: 3040 */ char shop_nickname_en[32]; + /* Offset: 3072 */ char area0_en[32]; + /* Offset: 3104 */ char area1_en[32]; + /* Offset: 3136 */ char area2_en[32]; + /* Offset: 3168 */ char area3_en[32]; + /* Offset: 3200 */ char area_full0_en[128]; + /* Offset: 3328 */ char area_full1_en[128]; + /* Offset: 3456 */ char area_full2_en[128]; + /* Offset: 3584 */ char area_full3_en[128]; + + /* Offset: 3712 */ char prefecture_id[16]; + /* Offset: 3728 */ char expiration_date[16]; + /* Offset: 3744 */ char use_token[16]; + /* Offset: 3760 */ char consume_token[32]; + /* Offset: 3792 */ char dongle_flag[8]; + /* Offset: 3800 */ char force_boot[8]; + /* Offset: 3808 */ char auth_token[384]; + /* Offset: 4192 */ char division_code[16]; } mucha_boardauth_resp_t; enum daemon_state { - DAEMON_UNKNOWN, - DAEMON_GET_HOP, - DAEMON_GET_TIP, - DAEMON_GET_AIP, - DAEMON_GET_NET_INFO, - DAEMON_INIT, - DAEMON_AUTH_START, - DAEMON_AUTH_BUSY, - DAEMON_AUTH_RETRY, - DAEMON_DL, - DAEMON_EXPORT, - DAEMON_IMPORT, - DAEMON_CONSUME_CHARGE, - DAEMON_NOTIFY_CHARGE, - DAEMON_CHECK_LAN, - DAEMON_IDLE, - DAEMON_FINALIZE, - DAEMON_BUSY + DAEMON_UNKNOWN, + DAEMON_GET_HOP, + DAEMON_GET_TIP, + DAEMON_GET_AIP, + DAEMON_GET_NET_INFO, + DAEMON_INIT, + DAEMON_AUTH_START, + DAEMON_AUTH_BUSY, + DAEMON_AUTH_RETRY, + DAEMON_DL, + DAEMON_EXPORT, + DAEMON_IMPORT, + DAEMON_CONSUME_CHARGE, + DAEMON_NOTIFY_CHARGE, + DAEMON_CHECK_LAN, + DAEMON_IDLE, + DAEMON_FINALIZE, + DAEMON_BUSY }; enum dllan_state { - DLLAN_UNKNOWN = 40, - DLLAN_NONE, - DLLAN_REQ, - DLLAN_DISABLE, - DLLAN_SERVER_NOTHING, - DLLAN_SERVER_VER_NOTHING, - DLLAN_SERVER_CHECKCODE_NOTHING, - DLLAN_SERVER_IMGCHUNK_NOTHING, - DLLAN_COMPLETE + DLLAN_UNKNOWN = 40, + DLLAN_NONE, + DLLAN_REQ, + DLLAN_DISABLE, + DLLAN_SERVER_NOTHING, + DLLAN_SERVER_VER_NOTHING, + DLLAN_SERVER_CHECKCODE_NOTHING, + DLLAN_SERVER_IMGCHUNK_NOTHING, + DLLAN_COMPLETE }; enum dlwan_state { - DLWAN_UNKNOWN = 49, - DLWAN_NONE, - DLWAN_REQ, - DLWAN_COMPLETE, - DLWAN_DISABLE, - DLWAN_WANENV_INVALID, - DLWAN_BASICAUTHKEY_INVALID, - DLWAN_SERVER_VERINFO_NOTHING, - DLWAN_SERVER_VERINFO_VERSION_NOTHING, + DLWAN_UNKNOWN = 49, + DLWAN_NONE, + DLWAN_REQ, + DLWAN_COMPLETE, + DLWAN_DISABLE, + DLWAN_WANENV_INVALID, + DLWAN_BASICAUTHKEY_INVALID, + DLWAN_SERVER_VERINFO_NOTHING, + DLWAN_SERVER_VERINFO_VERSION_NOTHING, }; enum daemon_io_info { - DAEMON_IO_UNKNOWN = 58, - DAEMON_IO_NONE, - DAEMON_IO_IDLE, - DAEMON_IO_EXPORT, - DAEMON_IO_IMPORT, - DAEMON_IO_FAIL, - DAEMON_IO_SUCCESS, + DAEMON_IO_UNKNOWN = 58, + DAEMON_IO_NONE, + DAEMON_IO_IDLE, + DAEMON_IO_EXPORT, + DAEMON_IO_IMPORT, + DAEMON_IO_FAIL, + DAEMON_IO_SUCCESS, }; enum dlexec_state { - DLEXEC_UNKNOWN = 25, - DLEXEC_NONE, - DLEXEC_PROC, - DLEXEC_STOP, - DLEXEC_STOPPING, + DLEXEC_UNKNOWN = 25, + DLEXEC_NONE, + DLEXEC_PROC, + DLEXEC_STOP, + DLEXEC_STOPPING, }; enum dlstep_state { - DLSTEP_UNKNOWN = 30, - DLSTEP_NONE, - DLSTEP_IDLE, - DLSTEP_PARTIMG_CHECK, - DLSTEP_STOP_REQ, - DLSTEP_LAN_VERINFO, - DLSTEP_LAN_CHECKCODE, - DLSTEP_LAN_IMGCHUNK, - DLSTEP_WAN_CHECKCODE, - DLSTEP_WAN_IMGCHUNK, + DLSTEP_UNKNOWN = 30, + DLSTEP_NONE, + DLSTEP_IDLE, + DLSTEP_PARTIMG_CHECK, + DLSTEP_STOP_REQ, + DLSTEP_LAN_VERINFO, + DLSTEP_LAN_CHECKCODE, + DLSTEP_LAN_IMGCHUNK, + DLSTEP_WAN_CHECKCODE, + DLSTEP_WAN_IMGCHUNK, }; enum auth_type { AUTH_TYPE_OFFLINE, AUTH_TYPE_ALLNET, AUTH_TYPE_NBLINE, AUTH_TYPE_CHARGE_NORMAL, AUTH_TYPE_CHARGE_MONTHLY }; enum daemon_mode { - DAEMON_MODE_UNKNOWN, - DAEMON_MODE_SERVER, - DAEMON_MODE_CLIENT, - DAEMON_MODE_STANDALONE, + DAEMON_MODE_UNKNOWN, + DAEMON_MODE_SERVER, + DAEMON_MODE_CLIENT, + DAEMON_MODE_STANDALONE, }; class CAuth : public IUnknown { public: - STDMETHODIMP - QueryInterface (REFIID riid, LPVOID *ppvObj) { - wchar_t *iid_str; - StringFromCLSID (riid, &iid_str); - - if (riid == IID_IUnknown || riid == IID_CAuth) { - *ppvObj = this; - this->AddRef (); - return 0; - } else { - *ppvObj = 0; - return E_NOINTERFACE; - } - } - - STDMETHODIMP_ (ULONG) AddRef () { return this->refCount++; } - STDMETHODIMP_ (ULONG) Release () { - this->refCount--; - if (this->refCount <= 0) { - // delete this; - return 0; - } - return this->refCount; - } - - virtual int64_t Unk3 (uint32_t a1) { - // printf ("Unk3 called\n"); - return 1; - } - - virtual int64_t Unk4 () { - // printf ("Unk4 called\n"); - return 1; - } - - virtual int32_t Unk5 () { - // printf ("Unk5 called\n"); - return 0; - } - - virtual int64_t Unk6 () { - // printf ("Unk6 called\n"); - return 1; - } - - virtual int32_t Unk7 () { - // printf ("Unk7 called\n"); - return 0; - } - - virtual int32_t Unk8 () { - // printf ("Unk8 called\n"); - return 0; - } - - virtual int32_t IAuth_GetUpdaterState (amcus_state_t *arr) { - // printf("IAuth_GetUpdaterState called\n"); - memset (arr, 0, sizeof (*arr)); - // Convert gameVerNum from string to double - double ver_d = std::stod (gameVerNum.c_str ()); - - int ver_top = (int)ver_d; - int ver_btm = (int)(ver_d * 100); - - if (ver_top != 0) ver_btm %= (ver_top * 100); - - arr->allnet_state = DAEMON_IDLE; - arr->allnet_auth_state = 2; - arr->allnet_auth_count = 1; - - arr->mucha_state.state = DAEMON_DL; - arr->mucha_state.auth_state = 2; - arr->mucha_state.auth_count = 1; - arr->mucha_state.state_dlexec = DLEXEC_PROC; - arr->mucha_state.state_dlstep = DLSTEP_IDLE; - arr->mucha_state.state_dllan = DLLAN_DISABLE; - arr->mucha_state.state_dlwan = DLWAN_COMPLETE; - arr->mucha_state.state_io = DAEMON_IO_NONE; - arr->mucha_state.cacfg_ver_major = ver_top; - arr->mucha_state.cacfg_ver_minor = ver_btm; - arr->mucha_state.app_ver_major = ver_top; - arr->mucha_state.app_ver_minor = ver_btm; - arr->mucha_state.dl_check_complete = 1; - arr->mucha_state.token_added = 100; - arr->mucha_state.token_charged = 100; - arr->mucha_state.token_unit = 1; - - arr->clock_status = 1; - arr->auth_type = AUTH_TYPE_ALLNET; - arr->cab_mode = DAEMON_MODE_STANDALONE; - arr->state = DAEMON_IDLE; - - /*memset(a1, 0, sizeof(int32_t) * 0x31); - a1[0] = 15; - a1[2] = 2; - a1[3] = 1; - a1[6] = 9; - a1[8] = 2; - a1[9] = 1; - a1[10] = 27; - a1[11] = 33; - a1[12] = 41; - a1[13] = 50; - a1[14] = 59; - a1[15] = 1179656; - a1[30] = 1; - a1[46] = 1; - a1[47] = 3; - a1[48] = 9;*/ - return 0; - } - - virtual int32_t IAuth_GetCabinetConfig (amcus_network_state_t *state) { - // printf("IAuth_GetCabinetConfig called\n"); - memset (state, 0, sizeof (*state)); - strcpy_s (state->mode, "STANDALONE"); - strcpy_s (state->pcbid, "ABLN1080001"); - strcpy_s (state->dongle_serial, chassisId.c_str ()); - strcpy_s (state->auth_server_ip, server_ip); - strcpy_s (state->local_ip, "127.0.0.1"); - strcpy_s (state->shop_router_ip, "127.0.0.1"); - strcpy_s (state->subnet_mask, "***.***.***.***"); - strcpy_s (state->gateway, "***.***.***.***"); - strcpy_s (state->primary_dns, "***.***.***.***"); - - state->hop_count = 1; - state->line_type = 1; - state->line_status = 1; - state->content_router_status = 1; - state->shop_router_status = 1; - state->hop_status = 1; - return 0; - } - - virtual int32_t IAuth_GetVersionInfo (amcus_version_info_t *version) { - // printf("IAuth_GetVersionInfo called\n"); - memset (version, 0, sizeof (*version)); - strcpy_s (version->game_rev, "1"); - strcpy_s (version->auth_type, "ALL.NET"); - strcpy_s (version->game_id, "SBWY"); - strcpy_s (version->game_ver, "12.20"); - strcpy_s (version->game_cd, "S121"); - strcpy_s (version->cacfg_game_ver, gameVerNum.c_str ()); - strcpy_s (version->game_board_type, "0"); - strcpy_s (version->game_board_id, "PCB"); - strcpy_s (version->auth_url, fullAddress); - return 0; - } - - virtual int32_t Unk12 () { - // printf ("Unk12 called\n"); - return 1; - } - - virtual int32_t Unk13 () { - // printf ("Unk13 called\n"); - return 1; - } - - virtual int32_t IAuth_GetAuthServerResp (amcus_auth_server_resp_t *resp) { - // printf("IAuth_GetAuthServerResp called\n"); - memset (resp, 0, sizeof (*resp)); - strcpy_s (resp->uri, fullAddress); - strcpy_s (resp->host, fullAddress); - - strcpy_s (resp->shop_name, shopId.c_str ()); - strcpy_s (resp->shop_nickname, shopId.c_str ()); - - strcpy_s (resp->region0, "01035"); - - strcpy_s (resp->region_name0, "NAMCO"); - strcpy_s (resp->region_name1, "X"); - strcpy_s (resp->region_name2, "Y"); - strcpy_s (resp->region_name3, "Z"); - strcpy_s (resp->place_id, placeId); - strcpy_s (resp->setting, ""); - strcpy_s (resp->country, countryCode.c_str ()); - strcpy_s (resp->timezone, "+0900"); - strcpy_s (resp->res_class, "PowerOnResponseVer3"); - return 0; - } - - virtual int32_t Unk15 () { - // printf ("Unk15 called\n"); - return 0; - } - - virtual int32_t Unk16 () { - // printf ("Unk16 called\n"); - return 0; - } - - virtual int32_t Unk17 () { - // printf ("Unk17 called\n"); - return 0; - } - - virtual int32_t IAuth_GetMuchaAuthResponse (mucha_boardauth_resp_t *arr) { - // printf("IAuth_GetMuchaAuthResponse called\n"); - - memset (arr, 0, sizeof (*arr)); - strcpy_s (arr->shop_name, sizeof (arr->shop_name), shopId.c_str ()); - strcpy_s (arr->shop_name_en, sizeof (arr->shop_name_en), shopId.c_str ()); - strcpy_s (arr->shop_nickname, sizeof (arr->shop_nickname), shopId.c_str ()); - strcpy_s (arr->shop_nickname_en, sizeof (arr->shop_nickname_en), shopId.c_str ()); - strcpy_s (arr->place_id, sizeof (arr->place_id), placeId); - strcpy_s (arr->country_cd, sizeof (arr->country_cd), countryCode.c_str ()); - - strcpy_s (arr->area0, sizeof (arr->area0), "008"); - strcpy_s (arr->area0_en, sizeof (arr->area0_en), "008"); - strcpy_s (arr->area1, sizeof (arr->area1), "009"); - strcpy_s (arr->area1_en, sizeof (arr->area1_en), "009"); - strcpy_s (arr->area2, sizeof (arr->area2), "010"); - strcpy_s (arr->area2_en, sizeof (arr->area2_en), "010"); - strcpy_s (arr->area3, sizeof (arr->area3), "011"); - strcpy_s (arr->area3_en, sizeof (arr->area3_en), "011"); - - strcpy_s (arr->prefecture_id, sizeof (arr->prefecture_id), "1"); - strcpy_s (arr->expiration_date, sizeof (arr->expiration_date), ""); - strcpy_s (arr->consume_token, sizeof (arr->consume_token), "10"); - strcpy_s (arr->force_boot, sizeof (arr->force_boot), "0"); - strcpy_s (arr->use_token, sizeof (arr->use_token), "11"); - strcpy_s (arr->dongle_flag, sizeof (arr->dongle_flag), "1"); - strcpy_s (arr->auth_token, sizeof (arr->auth_token), "1"); - strcpy_s (arr->division_code, sizeof (arr->division_code), "1"); - - strcpy_s (arr->url_charge, sizeof (arr->url_charge), "http://127.0.0.1/charge/"); - strcpy_s (arr->url_file, sizeof (arr->url_file), "http://127.0.0.1/file/"); - strcpy_s (arr->url_url1, sizeof (arr->url_url1), fullAddress); - strcpy_s (arr->url_url2, sizeof (arr->url_url2), fullAddress); - strcpy_s (arr->url_url3, sizeof (arr->url_url3), "http://127.0.0.1/url3/"); - return 0; - } - - virtual int32_t Unk19 (uint8_t *a1) { - // printf("Unk19 called\n"); - memset (a1, 0, 0x38); - a1[0] = 1; - return 1; - } - - virtual int32_t Unk20 () { - // printf ("Unk20 called\n"); - return 0; - } - - virtual int32_t Unk21 () { - // printf ("Unk21 called\n"); - return 1; - } - - virtual int32_t Unk22 () { - // printf ("Unk22 called\n"); - return 0; - } - - virtual int32_t Unk23 () { - // printf ("Unk23 called\n"); - return 0; - } - - virtual int32_t Unk24 () { - // printf ("Unk24 called\n"); - return 0; - } - - virtual int32_t Unk25 () { - // printf ("Unk25 called\n"); - return 1; - } - - virtual int32_t Unk26 () { - // printf ("Unk26 called\n"); - return 0; - } - - virtual int32_t Unk27 () { - // printf ("Unk27 called\n"); - return 1; - } - - virtual int32_t Unk28 () { - // printf ("Unk28 called\n"); - return 0; - } - - virtual int32_t Unk29 () { - // printf ("Unk29 called\n"); - return 0; - } - - virtual int32_t Unk30 () { - // printf ("Unk30 called\n"); - return 0; - } - - virtual int32_t PrintDebugInfo () { - // printf ("Unk31 called\n"); - return 0; - } - - virtual int32_t Unk32 (void *a1) { - // printf ("Unk32 called\n"); - return 0; - } - - virtual void Unk33 () { - // printf ("Unk33 called\n"); - } + STDMETHODIMP + QueryInterface (REFIID riid, LPVOID *ppvObj) { + wchar_t *iid_str; + StringFromCLSID (riid, &iid_str); + + if (riid == IID_IUnknown || riid == IID_CAuth) { + *ppvObj = this; + this->AddRef (); + return 0; + } else { + *ppvObj = 0; + return E_NOINTERFACE; + } + } + + STDMETHODIMP_ (ULONG) AddRef () { return this->refCount++; } + STDMETHODIMP_ (ULONG) Release () { + this->refCount--; + if (this->refCount <= 0) { + // delete this; + return 0; + } + return this->refCount; + } + + virtual int64_t Unk3 (uint32_t a1) { + // printf ("Unk3 called\n"); + return 1; + } + + virtual int64_t Unk4 () { + // printf ("Unk4 called\n"); + return 1; + } + + virtual int32_t Unk5 () { + // printf ("Unk5 called\n"); + return 0; + } + + virtual int64_t Unk6 () { + // printf ("Unk6 called\n"); + return 1; + } + + virtual int32_t Unk7 () { + // printf ("Unk7 called\n"); + return 0; + } + + virtual int32_t Unk8 () { + // printf ("Unk8 called\n"); + return 0; + } + + virtual int32_t IAuth_GetUpdaterState (amcus_state_t *arr) { + // printf("IAuth_GetUpdaterState called\n"); + memset (arr, 0, sizeof (*arr)); + // Convert gameVerNum from string to double + double ver_d = std::stod (gameVerNum.c_str ()); + + int ver_top = (int)ver_d; + int ver_btm = (int)(ver_d * 100); + + if (ver_top != 0) ver_btm %= (ver_top * 100); + + arr->allnet_state = DAEMON_IDLE; + arr->allnet_auth_state = 2; + arr->allnet_auth_count = 1; + + arr->mucha_state.state = DAEMON_DL; + arr->mucha_state.auth_state = 2; + arr->mucha_state.auth_count = 1; + arr->mucha_state.state_dlexec = DLEXEC_PROC; + arr->mucha_state.state_dlstep = DLSTEP_IDLE; + arr->mucha_state.state_dllan = DLLAN_DISABLE; + arr->mucha_state.state_dlwan = DLWAN_COMPLETE; + arr->mucha_state.state_io = DAEMON_IO_NONE; + arr->mucha_state.cacfg_ver_major = ver_top; + arr->mucha_state.cacfg_ver_minor = ver_btm; + arr->mucha_state.app_ver_major = ver_top; + arr->mucha_state.app_ver_minor = ver_btm; + arr->mucha_state.dl_check_complete = 1; + arr->mucha_state.token_added = 100; + arr->mucha_state.token_charged = 100; + arr->mucha_state.token_unit = 1; + + arr->clock_status = 1; + arr->auth_type = AUTH_TYPE_ALLNET; + arr->cab_mode = DAEMON_MODE_STANDALONE; + arr->state = DAEMON_IDLE; + + /*memset(a1, 0, sizeof(int32_t) * 0x31); + a1[0] = 15; + a1[2] = 2; + a1[3] = 1; + a1[6] = 9; + a1[8] = 2; + a1[9] = 1; + a1[10] = 27; + a1[11] = 33; + a1[12] = 41; + a1[13] = 50; + a1[14] = 59; + a1[15] = 1179656; + a1[30] = 1; + a1[46] = 1; + a1[47] = 3; + a1[48] = 9;*/ + return 0; + } + + virtual int32_t IAuth_GetCabinetConfig (amcus_network_state_t *state) { + // printf("IAuth_GetCabinetConfig called\n"); + memset (state, 0, sizeof (*state)); + strcpy_s (state->mode, "STANDALONE"); + strcpy_s (state->pcbid, "ABLN1080001"); + strcpy_s (state->dongle_serial, chassisId.c_str ()); + strcpy_s (state->auth_server_ip, server_ip); + strcpy_s (state->local_ip, "127.0.0.1"); + strcpy_s (state->shop_router_ip, "127.0.0.1"); + strcpy_s (state->subnet_mask, "***.***.***.***"); + strcpy_s (state->gateway, "***.***.***.***"); + strcpy_s (state->primary_dns, "***.***.***.***"); + + state->hop_count = 1; + state->line_type = 1; + state->line_status = 1; + state->content_router_status = 1; + state->shop_router_status = 1; + state->hop_status = 1; + return 0; + } + + virtual int32_t IAuth_GetVersionInfo (amcus_version_info_t *version) { + // printf("IAuth_GetVersionInfo called\n"); + memset (version, 0, sizeof (*version)); + strcpy_s (version->game_rev, "1"); + strcpy_s (version->auth_type, "ALL.NET"); + strcpy_s (version->game_id, "SBWY"); + strcpy_s (version->game_ver, "12.20"); + strcpy_s (version->game_cd, "S121"); + strcpy_s (version->cacfg_game_ver, gameVerNum.c_str ()); + strcpy_s (version->game_board_type, "0"); + strcpy_s (version->game_board_id, "PCB"); + strcpy_s (version->auth_url, fullAddress); + return 0; + } + + virtual int32_t Unk12 () { + // printf ("Unk12 called\n"); + return 1; + } + + virtual int32_t Unk13 () { + // printf ("Unk13 called\n"); + return 1; + } + + virtual int32_t IAuth_GetAuthServerResp (amcus_auth_server_resp_t *resp) { + // printf("IAuth_GetAuthServerResp called\n"); + memset (resp, 0, sizeof (*resp)); + strcpy_s (resp->uri, fullAddress); + strcpy_s (resp->host, fullAddress); + + strcpy_s (resp->shop_name, shopId.c_str ()); + strcpy_s (resp->shop_nickname, shopId.c_str ()); + + strcpy_s (resp->region0, "01035"); + + strcpy_s (resp->region_name0, "NAMCO"); + strcpy_s (resp->region_name1, "X"); + strcpy_s (resp->region_name2, "Y"); + strcpy_s (resp->region_name3, "Z"); + strcpy_s (resp->place_id, placeId); + strcpy_s (resp->setting, ""); + strcpy_s (resp->country, countryCode.c_str ()); + strcpy_s (resp->timezone, "+0900"); + strcpy_s (resp->res_class, "PowerOnResponseVer3"); + return 0; + } + + virtual int32_t Unk15 () { + // printf ("Unk15 called\n"); + return 0; + } + + virtual int32_t Unk16 () { + // printf ("Unk16 called\n"); + return 0; + } + + virtual int32_t Unk17 () { + // printf ("Unk17 called\n"); + return 0; + } + + virtual int32_t IAuth_GetMuchaAuthResponse (mucha_boardauth_resp_t *arr) { + // printf("IAuth_GetMuchaAuthResponse called\n"); + + memset (arr, 0, sizeof (*arr)); + strcpy_s (arr->shop_name, sizeof (arr->shop_name), shopId.c_str ()); + strcpy_s (arr->shop_name_en, sizeof (arr->shop_name_en), shopId.c_str ()); + strcpy_s (arr->shop_nickname, sizeof (arr->shop_nickname), shopId.c_str ()); + strcpy_s (arr->shop_nickname_en, sizeof (arr->shop_nickname_en), shopId.c_str ()); + strcpy_s (arr->place_id, sizeof (arr->place_id), placeId); + strcpy_s (arr->country_cd, sizeof (arr->country_cd), countryCode.c_str ()); + + strcpy_s (arr->area0, sizeof (arr->area0), "008"); + strcpy_s (arr->area0_en, sizeof (arr->area0_en), "008"); + strcpy_s (arr->area1, sizeof (arr->area1), "009"); + strcpy_s (arr->area1_en, sizeof (arr->area1_en), "009"); + strcpy_s (arr->area2, sizeof (arr->area2), "010"); + strcpy_s (arr->area2_en, sizeof (arr->area2_en), "010"); + strcpy_s (arr->area3, sizeof (arr->area3), "011"); + strcpy_s (arr->area3_en, sizeof (arr->area3_en), "011"); + + strcpy_s (arr->prefecture_id, sizeof (arr->prefecture_id), "1"); + strcpy_s (arr->expiration_date, sizeof (arr->expiration_date), ""); + strcpy_s (arr->consume_token, sizeof (arr->consume_token), "10"); + strcpy_s (arr->force_boot, sizeof (arr->force_boot), "0"); + strcpy_s (arr->use_token, sizeof (arr->use_token), "11"); + strcpy_s (arr->dongle_flag, sizeof (arr->dongle_flag), "1"); + strcpy_s (arr->auth_token, sizeof (arr->auth_token), "1"); + strcpy_s (arr->division_code, sizeof (arr->division_code), "1"); + + strcpy_s (arr->url_charge, sizeof (arr->url_charge), "http://127.0.0.1/charge/"); + strcpy_s (arr->url_file, sizeof (arr->url_file), "http://127.0.0.1/file/"); + strcpy_s (arr->url_url1, sizeof (arr->url_url1), fullAddress); + strcpy_s (arr->url_url2, sizeof (arr->url_url2), fullAddress); + strcpy_s (arr->url_url3, sizeof (arr->url_url3), "http://127.0.0.1/url3/"); + return 0; + } + + virtual int32_t Unk19 (uint8_t *a1) { + // printf("Unk19 called\n"); + memset (a1, 0, 0x38); + a1[0] = 1; + return 1; + } + + virtual int32_t Unk20 () { + // printf ("Unk20 called\n"); + return 0; + } + + virtual int32_t Unk21 () { + // printf ("Unk21 called\n"); + return 1; + } + + virtual int32_t Unk22 () { + // printf ("Unk22 called\n"); + return 0; + } + + virtual int32_t Unk23 () { + // printf ("Unk23 called\n"); + return 0; + } + + virtual int32_t Unk24 () { + // printf ("Unk24 called\n"); + return 0; + } + + virtual int32_t Unk25 () { + // printf ("Unk25 called\n"); + return 1; + } + + virtual int32_t Unk26 () { + // printf ("Unk26 called\n"); + return 0; + } + + virtual int32_t Unk27 () { + // printf ("Unk27 called\n"); + return 1; + } + + virtual int32_t Unk28 () { + // printf ("Unk28 called\n"); + return 0; + } + + virtual int32_t Unk29 () { + // printf ("Unk29 called\n"); + return 0; + } + + virtual int32_t Unk30 () { + // printf ("Unk30 called\n"); + return 0; + } + + virtual int32_t PrintDebugInfo () { + // printf ("Unk31 called\n"); + return 0; + } + + virtual int32_t Unk32 (void *a1) { + // printf ("Unk32 called\n"); + return 0; + } + + virtual void Unk33 () { + // printf ("Unk33 called\n"); + } public: - CAuth () {} + CAuth () {} - virtual ~CAuth () {} + virtual ~CAuth () {} private: - int32_t refCount = 0; + int32_t refCount = 0; }; class CAuthFactory final : public IClassFactory { public: - virtual ~CAuthFactory () = default; - STDMETHODIMP - QueryInterface (REFIID riid, LPVOID *ppvObj) { - wchar_t *iid_str; - StringFromCLSID (riid, &iid_str); - - if (riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_CAuthFactory) { - *ppvObj = this; - return 0; - } else { - *ppvObj = 0; - return E_NOINTERFACE; - } - } - - STDMETHODIMP_ (ULONG) AddRef () { return 2; } - STDMETHODIMP_ (ULONG) Release () { return 1; } - - virtual HRESULT CreateInstance (IUnknown *outer, REFIID riid, void **object) { - if (outer != nullptr) return CLASS_E_NOAGGREGATION; - - CAuth *auth = new CAuth (); - return auth->QueryInterface (riid, object); - } - - virtual HRESULT LockServer (int32_t lock) { return 0; } + virtual ~CAuthFactory () = default; + STDMETHODIMP + QueryInterface (REFIID riid, LPVOID *ppvObj) { + wchar_t *iid_str; + StringFromCLSID (riid, &iid_str); + + if (riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_CAuthFactory) { + *ppvObj = this; + return 0; + } else { + *ppvObj = 0; + return E_NOINTERFACE; + } + } + + STDMETHODIMP_ (ULONG) AddRef () { return 2; } + STDMETHODIMP_ (ULONG) Release () { return 1; } + + virtual HRESULT CreateInstance (IUnknown *outer, REFIID riid, void **object) { + if (outer != nullptr) return CLASS_E_NOAGGREGATION; + + CAuth *auth = new CAuth (); + return auth->QueryInterface (riid, object); + } + + virtual HRESULT LockServer (int32_t lock) { return 0; } }; -static HRESULT (STDAPICALLTYPE *g_origCoCreateInstance) (const IID *const rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, const IID *const riid, LPVOID *ppv); +static HRESULT (STDAPICALLTYPE *g_origCoCreateInstance) (const IID *const rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, const IID *const riid, + LPVOID *ppv); static HRESULT STDAPICALLTYPE CoCreateInstanceHook (const IID *const rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, const IID *const riid, LPVOID *ppv) { - HRESULT result; - - LPOLESTR clsidStr = nullptr; - LPOLESTR iidStr = nullptr; - StringFromIID (*rclsid, &clsidStr); - StringFromIID (*riid, &iidStr); - - if (IsEqualGUID (*rclsid, IID_CAuthFactory) && IsEqualGUID (*riid, IID_CAuth)) { - auto cauth = new CAuth (); - result = cauth->QueryInterface (*riid, ppv); - } else { - result = g_origCoCreateInstance (rclsid, pUnkOuter, dwClsContext, riid, ppv); - } - - CoTaskMemFree (clsidStr); - CoTaskMemFree (iidStr); - return result; + HRESULT result; + + LPOLESTR clsidStr = nullptr; + LPOLESTR iidStr = nullptr; + StringFromIID (*rclsid, &clsidStr); + StringFromIID (*riid, &iidStr); + + if (IsEqualGUID (*rclsid, IID_CAuthFactory) && IsEqualGUID (*riid, IID_CAuth)) { + auto cauth = new CAuth (); + result = cauth->QueryInterface (*riid, ppv); + } else { + result = g_origCoCreateInstance (rclsid, pUnkOuter, dwClsContext, riid, ppv); + } + + CoTaskMemFree (clsidStr); + CoTaskMemFree (iidStr); + return result; } void Init () { - MH_Initialize (); - MH_CreateHookApi (L"ole32.dll", "CoCreateInstance", (LPVOID)CoCreateInstanceHook, (void **)&g_origCoCreateInstance); // NOLINT(clang-diagnostic-microsoft-cast) - MH_EnableHook (nullptr); - - struct addrinfo *res = 0; - getaddrinfo (server.c_str (), "", 0, &res); - for (struct addrinfo *i = res; i != 0; i = i->ai_next) { - if (res->ai_addr->sa_family != AF_INET) continue; - struct sockaddr_in *p = (struct sockaddr_in *)res->ai_addr; - inet_ntop (AF_INET, &p->sin_addr, server_ip, 0x10); - break; - } + MH_Initialize (); + MH_CreateHookApi (L"ole32.dll", "CoCreateInstance", (LPVOID)CoCreateInstanceHook, + (void **)&g_origCoCreateInstance); // NOLINT(clang-diagnostic-microsoft-cast) + MH_EnableHook (nullptr); + + struct addrinfo *res = 0; + getaddrinfo (server.c_str (), "", 0, &res); + for (struct addrinfo *i = res; i != 0; i = i->ai_next) { + if (res->ai_addr->sa_family != AF_INET) continue; + struct sockaddr_in *p = (struct sockaddr_in *)res->ai_addr; + inet_ntop (AF_INET, &p->sin_addr, server_ip, 0x10); + break; + } } } // namespace patches::AmAuth diff --git a/src/patches/audio.cpp b/src/patches/audio.cpp index 915eff6..8e2728e 100644 --- a/src/patches/audio.cpp +++ b/src/patches/audio.cpp @@ -7,15 +7,15 @@ extern GameVersion gameVersion; namespace patches::Audio { typedef struct nusc_init_config { - uint32_t sample_rate; - uint32_t buffer_size; - uint32_t device_mode; - uint32_t channel_count; - const char *asio_driver_name; - bool wasapi_disable_com; - bool wasapi_exclusive; - uint32_t wasapi_exclusive_buffer_size; - void *wasapi_audioses; + uint32_t sample_rate; + uint32_t buffer_size; + uint32_t device_mode; + uint32_t channel_count; + const char *asio_driver_name; + bool wasapi_disable_com; + bool wasapi_exclusive; + uint32_t wasapi_exclusive_buffer_size; + void *wasapi_audioses; } nusc_init_config_t; bool wasapiShared = true; @@ -23,57 +23,57 @@ bool asio = false; std::string asioDriver = ""; HOOK_DYNAMIC (i64, __fastcall, NUSCDeviceInit, void *a1, nusc_init_config_t *a2, nusc_init_config_t *a3, void *a4) { - a2->device_mode = asio; - a2->asio_driver_name = asio ? asioDriver.c_str () : ""; - a2->wasapi_exclusive = asio ? 1 : wasapiShared ? 0 : 1; - return originalNUSCDeviceInit (a1, a2, a3, a4); + a2->device_mode = asio; + a2->asio_driver_name = asio ? asioDriver.c_str () : ""; + a2->wasapi_exclusive = asio ? 1 : wasapiShared ? 0 : 1; + return originalNUSCDeviceInit (a1, a2, a3, a4); } HOOK_DYNAMIC (bool, __fastcall, LoadASIODriver, void *a1, const char *a2) { - auto result = originalLoadASIODriver (a1, a2); - if (!result) { - MessageBoxA (nullptr, "Failed to load ASIO driver", nullptr, MB_OK); - ExitProcess (0); - } - return result; + auto result = originalLoadASIODriver (a1, a2); + if (!result) { + MessageBoxA (nullptr, "Failed to load ASIO driver", nullptr, MB_OK); + ExitProcess (0); + } + return result; } void Init () { - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - auto audio = openConfigSection (config_ptr.get (), "audio"); - if (audio) { - wasapiShared = readConfigBool (audio, "wasapi_shared", wasapiShared); - asio = readConfigBool (audio, "asio", asio); - asioDriver = readConfigString (audio, "asio_driver", asioDriver); - } - } + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + auto audio = openConfigSection (config_ptr.get (), "audio"); + if (audio) { + wasapiShared = readConfigBool (audio, "wasapi_shared", wasapiShared); + asio = readConfigBool (audio, "asio", asio); + asioDriver = readConfigString (audio, "asio_driver", asioDriver); + } + } - switch (gameVersion) { - case GameVersion::JPN00: { - INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140552160)); - INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14055A950)); - break; - } - case GameVersion::JPN08: { - INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140692E00)); - INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14069B750)); - break; - } - case GameVersion::JPN39: { - INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x1407C8620)); - INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407D0F70)); - break; - } - case GameVersion::CHN00: { - INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140777F70)); - INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407808C0)); - break; - } - default: { - break; - } - } + switch (gameVersion) { + case GameVersion::JPN00: { + INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140552160)); + INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14055A950)); + break; + } + case GameVersion::JPN08: { + INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140692E00)); + INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14069B750)); + break; + } + case GameVersion::JPN39: { + INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x1407C8620)); + INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407D0F70)); + break; + } + case GameVersion::CHN00: { + INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140777F70)); + INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407808C0)); + break; + } + default: { + break; + } + } } } // namespace patches::Audio diff --git a/src/patches/qr.cpp b/src/patches/qr.cpp index 776b1de..646d390 100644 --- a/src/patches/qr.cpp +++ b/src/patches/qr.cpp @@ -41,287 +41,288 @@ bool qrPluginRegistered = false; HOOK_DYNAMIC (char, __fastcall, qrInit, i64) { return 1; } HOOK_DYNAMIC (char, __fastcall, qrClose, i64) { return 1; } HOOK_DYNAMIC (char, __fastcall, qrRead, i64 a1) { - *(DWORD *)(a1 + 40) = 1; - *(DWORD *)(a1 + 16) = 1; - *(BYTE *)(a1 + 112) = 0; - return 1; + *(DWORD *)(a1 + 40) = 1; + *(DWORD *)(a1 + 16) = 1; + *(BYTE *)(a1 + 112) = 0; + return 1; } HOOK_DYNAMIC (i64, __fastcall, callQrUnknown, i64) { return 1; } HOOK_DYNAMIC (bool, __fastcall, Send1, i64 a1) { - *(BYTE *)(a1 + 88) = 1; - *(i64 *)(a1 + 32) = *(i64 *)(a1 + 24); - *(WORD *)(a1 + 89) = 0; - return true; + *(BYTE *)(a1 + 88) = 1; + *(i64 *)(a1 + 32) = *(i64 *)(a1 + 24); + *(WORD *)(a1 + 89) = 0; + return true; } HOOK_DYNAMIC (bool, __fastcall, Send2, i64 a1) { - *(WORD *)(a1 + 88) = 0; - *(BYTE *)(a1 + 90) = 0; - return true; + *(WORD *)(a1 + 88) = 0; + *(BYTE *)(a1 + 90) = 0; + return true; } HOOK_DYNAMIC (bool, __fastcall, Send3, i64, char) { return true; } HOOK_DYNAMIC (bool, __fastcall, Send4, i64, const void *, i64) { return true; } HOOK_DYNAMIC (i64, __fastcall, copy_data, i64, void *dest, int length) { - if (gState == State::CopyWait) { - std::cout << "Copy data, length: " << length << std::endl; - - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - - if (gMode == Mode::Card) { - memcpy (dest, accessCode.c_str (), accessCode.size () + 1); - gState = State::Ready; - return accessCode.size () + 1; - } else if (gMode == Mode::Data) { - std::string serial = ""; - u16 type = 0; - std::vector songNoes; - - if (config_ptr) { - auto qr = openConfigSection (config_ptr.get (), "qr"); - if (qr) { - auto data = openConfigSection (qr, "data"); - if (data) { - serial = readConfigString (data, "serial", ""); - type = readConfigInt (data, "type", 0); - songNoes = readConfigIntArray (data, "song_no", songNoes); - } - } - } - - BYTE serial_length = (BYTE)serial.size (); - std::vector byteBuffer = {0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, serial_length, 0x01, 0x00}; - - for (char c : serial) - byteBuffer.push_back ((BYTE)c); - - if (type == 5) { - std::vector folderData = {0xFF, 0xFF}; - - folderData.push_back (songNoes.size () * 2); - - folderData.push_back ((u8)(type & 0xFF)); - folderData.push_back ((u8)((type >> 8) & 0xFF)); - - for (u16 songNo : songNoes) { - folderData.push_back ((u8)(songNo & 0xFF)); - folderData.push_back ((u8)((songNo >> 8) & 0xFF)); - } - - for (auto c : folderData) - byteBuffer.push_back (c); - } - - byteBuffer.push_back (0xEE); - byteBuffer.push_back (0xFF); - - for (auto byteData : byteBuffer) - std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast (byteData) << " "; - std::cout << std::endl; - - memcpy (dest, byteBuffer.data (), byteBuffer.size ()); - gState = State::Ready; - return byteBuffer.size (); - } else if (gMode == Mode::Image) { - std::string imagePath = ""; - - if (config_ptr) { - auto qr = openConfigSection (config_ptr.get (), "qr"); - if (qr) imagePath = readConfigString (qr, "image_path", ""); - } - - std::u8string u8PathStr (imagePath.begin (), imagePath.end ()); - std::filesystem::path u8Path (u8PathStr); - if (!std::filesystem::is_regular_file (u8Path)) { - std::cerr << "Failed to open image: " << u8Path.string () << " (file not found)" - << "\n"; - gState = State::Ready; - return 0; - } - - int width, height, channels; - std::unique_ptr buffer (stbi_load (u8Path.string ().c_str (), &width, &height, &channels, 3), stbi_image_free); - if (!buffer) { - std::cerr << "Failed to read image: " << u8Path << " (" << stbi_failure_reason () << ")" - << "\n"; - gState = State::Ready; - return 0; - } - - ZXing::ImageView image{buffer.get (), width, height, ZXing::ImageFormat::RGB}; - auto result = ReadBarcode (image); - if (!result.isValid ()) { - std::cerr << "Failed to read qr: " << imagePath << " (" << ToString (result.error ()) << ")" - << "\n"; - gState = State::Ready; - return 0; - } - - std::cout << "Valid" << std::endl; - auto byteData = result.bytes (); - std::cout << ZXing::ToHex (byteData) << std::endl; - auto dataSize = byteData.size (); - - memcpy (dest, byteData.data (), dataSize); - gState = State::Ready; - return dataSize; - } else if (gMode == Mode::Plugin) { - FARPROC getEvent = GetProcAddress (gPlugin, "GetQr"); - if (getEvent) { - unsigned char plugin_data[length]; - int buf_len = ((getQrEvent *)getEvent) (length, plugin_data); - if (0 < buf_len && buf_len <= length) { - for (int i = 0; i < buf_len; i++) - std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast (plugin_data[i]) << " "; - std::cout << std::endl; - memcpy (dest, plugin_data, buf_len); - } else { - std::cerr << "QR discard! Length invalid: " << buf_len << ", valid range: 0~" << length << std::endl; - } - gState = State::Ready; - return buf_len; - } else { - gState = State::Ready; - return 0; - } - } - } else if (qrPluginRegistered) { - for (auto plugin : qrPlugins) { - FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr"); - if (usingQrEvent) ((event *)usingQrEvent) (); - } - } - return 0; + if (gState == State::CopyWait) { + std::cout << "Copy data, length: " << length << std::endl; + + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + + if (gMode == Mode::Card) { + memcpy (dest, accessCode.c_str (), accessCode.size () + 1); + gState = State::Ready; + return accessCode.size () + 1; + } else if (gMode == Mode::Data) { + std::string serial = ""; + u16 type = 0; + std::vector songNoes; + + if (config_ptr) { + auto qr = openConfigSection (config_ptr.get (), "qr"); + if (qr) { + auto data = openConfigSection (qr, "data"); + if (data) { + serial = readConfigString (data, "serial", ""); + type = readConfigInt (data, "type", 0); + songNoes = readConfigIntArray (data, "song_no", songNoes); + } + } + } + + BYTE serial_length = (BYTE)serial.size (); + std::vector byteBuffer = {0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, serial_length, 0x01, 0x00}; + + for (char c : serial) + byteBuffer.push_back ((BYTE)c); + + if (type == 5) { + std::vector folderData = {0xFF, 0xFF}; + + folderData.push_back (songNoes.size () * 2); + + folderData.push_back ((u8)(type & 0xFF)); + folderData.push_back ((u8)((type >> 8) & 0xFF)); + + for (u16 songNo : songNoes) { + folderData.push_back ((u8)(songNo & 0xFF)); + folderData.push_back ((u8)((songNo >> 8) & 0xFF)); + } + + for (auto c : folderData) + byteBuffer.push_back (c); + } + + byteBuffer.push_back (0xEE); + byteBuffer.push_back (0xFF); + + for (auto byteData : byteBuffer) + std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast (byteData) << " "; + std::cout << std::endl; + + memcpy (dest, byteBuffer.data (), byteBuffer.size ()); + gState = State::Ready; + return byteBuffer.size (); + } else if (gMode == Mode::Image) { + std::string imagePath = ""; + + if (config_ptr) { + auto qr = openConfigSection (config_ptr.get (), "qr"); + if (qr) imagePath = readConfigString (qr, "image_path", ""); + } + + std::u8string u8PathStr (imagePath.begin (), imagePath.end ()); + std::filesystem::path u8Path (u8PathStr); + if (!std::filesystem::is_regular_file (u8Path)) { + std::cerr << "Failed to open image: " << u8Path.string () << " (file not found)" + << "\n"; + gState = State::Ready; + return 0; + } + + int width, height, channels; + std::unique_ptr buffer (stbi_load (u8Path.string ().c_str (), &width, &height, &channels, 3), + stbi_image_free); + if (!buffer) { + std::cerr << "Failed to read image: " << u8Path << " (" << stbi_failure_reason () << ")" + << "\n"; + gState = State::Ready; + return 0; + } + + ZXing::ImageView image{buffer.get (), width, height, ZXing::ImageFormat::RGB}; + auto result = ReadBarcode (image); + if (!result.isValid ()) { + std::cerr << "Failed to read qr: " << imagePath << " (" << ToString (result.error ()) << ")" + << "\n"; + gState = State::Ready; + return 0; + } + + std::cout << "Valid" << std::endl; + auto byteData = result.bytes (); + std::cout << ZXing::ToHex (byteData) << std::endl; + auto dataSize = byteData.size (); + + memcpy (dest, byteData.data (), dataSize); + gState = State::Ready; + return dataSize; + } else if (gMode == Mode::Plugin) { + FARPROC getEvent = GetProcAddress (gPlugin, "GetQr"); + if (getEvent) { + unsigned char plugin_data[length]; + int buf_len = ((getQrEvent *)getEvent) (length, plugin_data); + if (0 < buf_len && buf_len <= length) { + for (int i = 0; i < buf_len; i++) + std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast (plugin_data[i]) << " "; + std::cout << std::endl; + memcpy (dest, plugin_data, buf_len); + } else { + std::cerr << "QR discard! Length invalid: " << buf_len << ", valid range: 0~" << length << std::endl; + } + gState = State::Ready; + return buf_len; + } else { + gState = State::Ready; + return 0; + } + } + } else if (qrPluginRegistered) { + for (auto plugin : qrPlugins) { + FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr"); + if (usingQrEvent) ((event *)usingQrEvent) (); + } + } + return 0; } void Update () { - if (!qrEnabled) return; - if (gState == State::Ready) { - if (IsButtonTapped (CARD_INSERT_1)) { - if (gameVersion != GameVersion::CHN00) return; - - std::cout << "Insert" << std::endl; - accessCode = "BNTTCNID"; - accessCode += accessCode1; - gState = State::CopyWait; - gMode = Mode::Card; - } else if (IsButtonTapped (CARD_INSERT_2)) { - if (gameVersion != GameVersion::CHN00) return; - - std::cout << "Insert" << std::endl; - accessCode = "BNTTCNID"; - accessCode += accessCode2; - gState = State::CopyWait; - gMode = Mode::Card; - } else if (IsButtonTapped (QR_DATA_READ)) { - std::cout << "Insert" << std::endl; - gState = State::CopyWait; - gMode = Mode::Data; - } else if (IsButtonTapped (QR_IMAGE_READ)) { - std::cout << "Insert" << std::endl; - gState = State::CopyWait; - gMode = Mode::Image; - } else if (qrPluginRegistered) { - for (auto plugin : qrPlugins) { - FARPROC checkEvent = GetProcAddress (plugin, "CheckQr"); - if (checkEvent && ((checkQrEvent *)checkEvent) ()) { - std::cout << "Insert" << std::endl; - gState = State::CopyWait; - gMode = Mode::Plugin; - gPlugin = plugin; - break; - } - } - } - } + if (!qrEnabled) return; + if (gState == State::Ready) { + if (IsButtonTapped (CARD_INSERT_1)) { + if (gameVersion != GameVersion::CHN00) return; + + std::cout << "Insert" << std::endl; + accessCode = "BNTTCNID"; + accessCode += accessCode1; + gState = State::CopyWait; + gMode = Mode::Card; + } else if (IsButtonTapped (CARD_INSERT_2)) { + if (gameVersion != GameVersion::CHN00) return; + + std::cout << "Insert" << std::endl; + accessCode = "BNTTCNID"; + accessCode += accessCode2; + gState = State::CopyWait; + gMode = Mode::Card; + } else if (IsButtonTapped (QR_DATA_READ)) { + std::cout << "Insert" << std::endl; + gState = State::CopyWait; + gMode = Mode::Data; + } else if (IsButtonTapped (QR_IMAGE_READ)) { + std::cout << "Insert" << std::endl; + gState = State::CopyWait; + gMode = Mode::Image; + } else if (qrPluginRegistered) { + for (auto plugin : qrPlugins) { + FARPROC checkEvent = GetProcAddress (plugin, "CheckQr"); + if (checkEvent && ((checkQrEvent *)checkEvent) ()) { + std::cout << "Insert" << std::endl; + gState = State::CopyWait; + gMode = Mode::Plugin; + gPlugin = plugin; + break; + } + } + } + } } void Init () { - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - if (!config_ptr) { - std::cerr << "[Init] Config file not found" << std::endl; - return; - } - auto qr = openConfigSection (config_ptr.get (), "qr"); - if (!qr) { - std::cerr << "[Init] QR config section not found! QR emulation disabled" << std::endl; - qrEnabled = false; - return; - } - qrEnabled = readConfigBool (qr, "enabled", true); - if (!qrEnabled) { - std::cout << "[Init] QR emulation disabled" << std::endl; - return; - } - - for (auto plugin : plugins) { - FARPROC initEvent = GetProcAddress (plugin, "InitQr"); - if (initEvent) ((initQrEvent *)initEvent) (gameVersion); - - FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr"); - if (usingQrEvent) qrPlugins.push_back (plugin); - } - if (qrPlugins.size () > 0) { - std::cout << "QR plugin found!" << std::endl; - qrPluginRegistered = true; - } - - SetConsoleOutputCP (CP_UTF8); - auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); - switch (gameVersion) { - case GameVersion::JPN00: { - INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1b3e0)); - INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1b5b0)); - INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1b600)); - INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xfd40)); - INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1bbb0)); - INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1bbf0)); - INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1bc60)); - // JPN00 has no Send4 - INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1bc30)); - break; - } - case GameVersion::JPN08: { - INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1BA00)); - INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1BBD0)); - INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1BC20)); - INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xFD40)); - INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1C220)); - INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1C260)); - INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1C2D0)); - // JPN08 has no Send4 - INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1C2A0)); - break; - } - case GameVersion::JPN39: { - INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1EDC0)); - INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1EF60)); - INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1EFB0)); - INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x11A70)); - INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1F5B0)); - INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1F5F0)); - INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1F660)); - INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x1F690)); - INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1F630)); - break; - } - case GameVersion::CHN00: { - INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x161B0)); - INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x16350)); - INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x163A0)); - INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x8F60)); - INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x16940)); - INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x16990)); - INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x16A00)); - INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x16A30)); - INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x169D0)); - break; - } - default: { - break; - } - } + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + if (!config_ptr) { + std::cerr << "[Init] Config file not found" << std::endl; + return; + } + auto qr = openConfigSection (config_ptr.get (), "qr"); + if (!qr) { + std::cerr << "[Init] QR config section not found! QR emulation disabled" << std::endl; + qrEnabled = false; + return; + } + qrEnabled = readConfigBool (qr, "enabled", true); + if (!qrEnabled) { + std::cout << "[Init] QR emulation disabled" << std::endl; + return; + } + + for (auto plugin : plugins) { + FARPROC initEvent = GetProcAddress (plugin, "InitQr"); + if (initEvent) ((initQrEvent *)initEvent) (gameVersion); + + FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr"); + if (usingQrEvent) qrPlugins.push_back (plugin); + } + if (qrPlugins.size () > 0) { + std::cout << "QR plugin found!" << std::endl; + qrPluginRegistered = true; + } + + SetConsoleOutputCP (CP_UTF8); + auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); + switch (gameVersion) { + case GameVersion::JPN00: { + INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1b3e0)); + INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1b5b0)); + INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1b600)); + INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xfd40)); + INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1bbb0)); + INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1bbf0)); + INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1bc60)); + // JPN00 has no Send4 + INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1bc30)); + break; + } + case GameVersion::JPN08: { + INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1BA00)); + INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1BBD0)); + INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1BC20)); + INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xFD40)); + INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1C220)); + INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1C260)); + INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1C2D0)); + // JPN08 has no Send4 + INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1C2A0)); + break; + } + case GameVersion::JPN39: { + INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1EDC0)); + INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1EF60)); + INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1EFB0)); + INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x11A70)); + INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1F5B0)); + INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1F5F0)); + INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1F660)); + INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x1F690)); + INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1F630)); + break; + } + case GameVersion::CHN00: { + INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x161B0)); + INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x16350)); + INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x163A0)); + INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x8F60)); + INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x16940)); + INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x16990)); + INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x16A00)); + INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x16A30)); + INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x169D0)); + break; + } + default: { + break; + } + } } } // namespace patches::Qr diff --git a/src/patches/versions/CHN00.cpp b/src/patches/versions/CHN00.cpp index ed4b55a..22ded61 100644 --- a/src/patches/versions/CHN00.cpp +++ b/src/patches/versions/CHN00.cpp @@ -12,16 +12,16 @@ HOOK (i32, HaspEncrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_encrypt")) { 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; + *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; + *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; + memcpy (buffer, haspBuffer + offset, length); + return 0; } i64 (__fastcall *lua_settop) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_settop"); @@ -30,9 +30,9 @@ i64 (__fastcall *lua_pushstring) (u64, u64) = (i64 (__fastcall *) (u64, u64))PR i64 lua_pushtrue (i64 a1) { - lua_settop (a1, 0); - lua_pushboolean (a1, 1); - return 1; + lua_settop (a1, 0); + lua_pushboolean (a1, 1); + return 1; } HOOK (i64, AvailableMode_Dani_AI, ASLR (0x1401AC550), i64 a1) { return lua_pushtrue (a1); } @@ -42,28 +42,28 @@ HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402BC9B0), i64 a1) { return lua_pu 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"; - } + 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; + 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; + 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; + lua_settop (a2, 0); + lua_pushstring (a2, (u64)languageStr ()); + return 1; } HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; } @@ -79,145 +79,145 @@ const std::vector memsetSizeAddresses = {0x140093416, 0x1400934 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); + 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 &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); - } + 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 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 config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - auto patches = openConfigSection (config_ptr.get (), "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); - unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); - auto chn00 = openConfigSection (patches, "chn00"); - if (chn00) { - fixLanguage = readConfigBool (chn00, "fix_language", fixLanguage); - demoMovie = readConfigBool (chn00, "demo_movie", demoMovie); - modeCollabo025 = readConfigBool (chn00, "mode_collabo025", modeCollabo025); - modeCollabo026 = readConfigBool (chn00, "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 (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 directory - 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"); - WRITE_MEMORY (ASLR (0x140C3CF58), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); - WRITE_MEMORY (ASLR (0x140C3CF90), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); - WRITE_MEMORY (ASLR (0x140C3CFC8), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); - WRITE_MEMORY (ASLR (0x140C3D000), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); - - // 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)); - - // Move various files to current directory - WRITE_MEMORY (amHandle + 0xC652, u8, 0xEB); // CreditLogPathA - WRITE_MEMORY (amHandle + 0xC819, u8, 0xEB); // CreditLogPathB - WRITE_MEMORY (amHandle + 0x243BA, u8, 0xEB); // ErrorLogPathA - WRITE_MEMORY (amHandle + 0x24539, u8, 0xEB); // ErrorLogPathB - WRITE_MEMORY (amHandle + 0x24901, u8, 0xEB); // CommonLogPathA - WRITE_MEMORY (amHandle + 0x24A85, u8, 0xEB); // CommonLogPathB - WRITE_MEMORY (amHandle + 0x24DD1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA - WRITE_MEMORY (amHandle + 0x24E47, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB - - patches::Audio::Init (); - patches::Qr::Init (); + i32 xRes = 1920; + i32 yRes = 1080; + bool vsync = false; + 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 config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + auto patches = openConfigSection (config_ptr.get (), "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); + unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); + auto chn00 = openConfigSection (patches, "chn00"); + if (chn00) { + fixLanguage = readConfigBool (chn00, "fix_language", fixLanguage); + demoMovie = readConfigBool (chn00, "demo_movie", demoMovie); + modeCollabo025 = readConfigBool (chn00, "mode_collabo025", modeCollabo025); + modeCollabo026 = readConfigBool (chn00, "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 (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 directory + 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"); + WRITE_MEMORY (ASLR (0x140C3CF58), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); + WRITE_MEMORY (ASLR (0x140C3CF90), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); + WRITE_MEMORY (ASLR (0x140C3CFC8), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); + WRITE_MEMORY (ASLR (0x140C3D000), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); + + // 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)); + + // Move various files to current directory + WRITE_MEMORY (amHandle + 0xC652, u8, 0xEB); // CreditLogPathA + WRITE_MEMORY (amHandle + 0xC819, u8, 0xEB); // CreditLogPathB + WRITE_MEMORY (amHandle + 0x243BA, u8, 0xEB); // ErrorLogPathA + WRITE_MEMORY (amHandle + 0x24539, u8, 0xEB); // ErrorLogPathB + WRITE_MEMORY (amHandle + 0x24901, u8, 0xEB); // CommonLogPathA + WRITE_MEMORY (amHandle + 0x24A85, u8, 0xEB); // CommonLogPathB + WRITE_MEMORY (amHandle + 0x24DD1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA + WRITE_MEMORY (amHandle + 0x24E47, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB + + patches::Audio::Init (); + patches::Qr::Init (); } } // namespace patches::CHN00 diff --git a/src/patches/versions/JPN00.cpp b/src/patches/versions/JPN00.cpp index 042089f..8096d1e 100644 --- a/src/patches/versions/JPN00.cpp +++ b/src/patches/versions/JPN00.cpp @@ -7,9 +7,9 @@ extern 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) +#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::JPN00 { @@ -17,98 +17,100 @@ HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; } const i32 datatableBufferSize = 1024 * 1024 * 12; safetyhook::Allocation datatableBuffer; -const std::vector datatableBufferAddresses = {0x14005A418, 0x14005A445, 0x14005A778, 0x14005A7A5, 0x14005AD58, 0x14005AD85, 0x14005B1F2, 0x14005B221, 0x14005B438, - 0x14005B465, 0x14005B7D8, 0x14005B805, 0x14005BA59, 0x14005BA88, 0x14005BD78, 0x14005BDA7, 0x14005C1B3, 0x14005C1E2, - 0x14005CC52, 0x14005CC81, 0x14005D348, 0x14005D375, 0x14005D668, 0x14005D695, 0x14005D9D2, 0x14005DA04, 0x14005EA04, - 0x14005EA33, 0x14005EC18, 0x14005EC45, 0x14005EEE4, 0x14005EF10, 0x14005F158, 0x14005F185, 0x14005F47C, 0x14005F4A9}; -const std::vector memsetSizeAddresses = {0x14005A412, 0x14005A772, 0x14005AD52, 0x14005B1EC, 0x14005B432, 0x14005B7D2, 0x14005BA53, 0x14005BD72, 0x14005C1AD, - 0x14005CC4C, 0x14005D342, 0x14005D662, 0x14005D9CC, 0x14005E9FE, 0x14005EC12, 0x14005EEDE, 0x14005F152, 0x14005F476}; +const std::vector datatableBufferAddresses + = {0x14005A418, 0x14005A445, 0x14005A778, 0x14005A7A5, 0x14005AD58, 0x14005AD85, 0x14005B1F2, 0x14005B221, 0x14005B438, + 0x14005B465, 0x14005B7D8, 0x14005B805, 0x14005BA59, 0x14005BA88, 0x14005BD78, 0x14005BDA7, 0x14005C1B3, 0x14005C1E2, + 0x14005CC52, 0x14005CC81, 0x14005D348, 0x14005D375, 0x14005D668, 0x14005D695, 0x14005D9D2, 0x14005DA04, 0x14005EA04, + 0x14005EA33, 0x14005EC18, 0x14005EC45, 0x14005EEE4, 0x14005EF10, 0x14005F158, 0x14005F185, 0x14005F47C, 0x14005F4A9}; +const std::vector memsetSizeAddresses + = {0x14005A412, 0x14005A772, 0x14005AD52, 0x14005B1EC, 0x14005B432, 0x14005B7D2, 0x14005BA53, 0x14005BD72, 0x14005C1AD, + 0x14005CC4C, 0x14005D342, 0x14005D662, 0x14005D9CC, 0x14005E9FE, 0x14005EC12, 0x14005EEDE, 0x14005F152, 0x14005F476}; 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); + 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 &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); - } + 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 unlockSongs = true; - - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - auto patches = openConfigSection (config_ptr.get (), "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); - unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); - } - } - - // Apply common config patch - WRITE_MEMORY (ASLR (0x140224B2B), i32, xRes); - WRITE_MEMORY (ASLR (0x140224B32), i32, yRes); - if (!vsync) WRITE_MEMORY (ASLR (0x1403D6189), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); - if (unlockSongs) WRITE_MEMORY (ASLR (0x1401F6B78), u8, 0xB0, 0x01); - - // Bypass errors - WRITE_MEMORY (ASLR (0x14001F0A0), u8, 0xC3); - - // Use TLS v1.2 - WRITE_MEMORY (ASLR (0x140309AC9), u8, 0x10); - - // Move various files to current dir - WRITE_MEMORY (ASLR (0x140018351), u8, 0x02); - WRITE_MEMORY (ASLR (0x1409A7138), char, "./"); - WRITE_MEMORY (ASLR (0x1409D23B8), char, ".\\Setting1.bin"); - WRITE_MEMORY (ASLR (0x1409D23C8), char, ".\\Setting2.bin"); - - // 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 ()); - } - - // Disable live check - auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); - INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x24B80)); - - // Move various files to current directory - WRITE_MEMORY (amHandle + 0x1473F, u8, 0xEB); // CreditLogPathA - WRITE_MEMORY (amHandle + 0x148AA, u8, 0xEB); // CreditLogPathB - WRITE_MEMORY (amHandle + 0x321A7, u8, 0xEB); // ErrorLogPathA - WRITE_MEMORY (amHandle + 0x322FA, u8, 0xEB); // ErrorLogPathB - WRITE_MEMORY (amHandle + 0x326D9, u8, 0xEB); // CommonLogPathA - WRITE_MEMORY (amHandle + 0x3282C, u8, 0xEB); // CommonLogPathB - WRITE_MEMORY (amHandle + 0x32C2A, u8, 0xEB); // BackupDataPathA - WRITE_MEMORY (amHandle + 0x32D7D, u8, 0xEB); // BackupDataPathB - - patches::Audio::Init (); - patches::Qr::Init (); - patches::AmAuth::Init (); + i32 xRes = 1920; + i32 yRes = 1080; + bool vsync = false; + bool unlockSongs = true; + + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + auto patches = openConfigSection (config_ptr.get (), "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); + unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); + } + } + + // Apply common config patch + WRITE_MEMORY (ASLR (0x140224B2B), i32, xRes); + WRITE_MEMORY (ASLR (0x140224B32), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x1403D6189), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); + if (unlockSongs) WRITE_MEMORY (ASLR (0x1401F6B78), u8, 0xB0, 0x01); + + // Bypass errors + WRITE_MEMORY (ASLR (0x14001F0A0), u8, 0xC3); + + // Use TLS v1.2 + WRITE_MEMORY (ASLR (0x140309AC9), u8, 0x10); + + // Move various files to current dir + WRITE_MEMORY (ASLR (0x140018351), u8, 0x02); + WRITE_MEMORY (ASLR (0x1409A7138), char, "./"); + WRITE_MEMORY (ASLR (0x1409D23B8), char, ".\\Setting1.bin"); + WRITE_MEMORY (ASLR (0x1409D23C8), char, ".\\Setting2.bin"); + + // 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 ()); + } + + // Disable live check + auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); + INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x24B80)); + + // Move various files to current directory + WRITE_MEMORY (amHandle + 0x1473F, u8, 0xEB); // CreditLogPathA + WRITE_MEMORY (amHandle + 0x148AA, u8, 0xEB); // CreditLogPathB + WRITE_MEMORY (amHandle + 0x321A7, u8, 0xEB); // ErrorLogPathA + WRITE_MEMORY (amHandle + 0x322FA, u8, 0xEB); // ErrorLogPathB + WRITE_MEMORY (amHandle + 0x326D9, u8, 0xEB); // CommonLogPathA + WRITE_MEMORY (amHandle + 0x3282C, u8, 0xEB); // CommonLogPathB + WRITE_MEMORY (amHandle + 0x32C2A, u8, 0xEB); // BackupDataPathA + WRITE_MEMORY (amHandle + 0x32D7D, u8, 0xEB); // BackupDataPathB + + patches::Audio::Init (); + patches::Qr::Init (); + patches::AmAuth::Init (); } } // namespace patches::JPN00 diff --git a/src/patches/versions/JPN08.cpp b/src/patches/versions/JPN08.cpp index 56f5107..7ff6529 100644 --- a/src/patches/versions/JPN08.cpp +++ b/src/patches/versions/JPN08.cpp @@ -7,9 +7,9 @@ extern 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) +#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::JPN08 { @@ -17,166 +17,168 @@ HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; } const i32 datatableBufferSize = 1024 * 1024 * 12; safetyhook::Allocation datatableBuffer; -const std::vector 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 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}; +const std::vector 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 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); + 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 &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); - } + 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 unlockSongs = true; - - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - auto patches = openConfigSection (config_ptr.get (), "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); - 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 (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 directory - WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02); - WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./"); - WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin"); - WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin"); - - // 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); // CreditLogPathA - WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB); // CreditLogPathB - WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB); // ErrorLogPathA - WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB); // ErrorLogPathB - WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB); // CommonLogPathA - WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB); // CommonLogPathB - WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB); // BackupDataPathA - WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB); // BackupDataPathB - - patches::Audio::Init (); - patches::Qr::Init (); - patches::AmAuth::Init (); + i32 xRes = 1920; + i32 yRes = 1080; + bool vsync = false; + bool unlockSongs = true; + + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + auto patches = openConfigSection (config_ptr.get (), "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); + 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 (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 directory + WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02); + WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./"); + WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin"); + WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin"); + + // 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); // CreditLogPathA + WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB); // CreditLogPathB + WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB); // ErrorLogPathA + WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB); // ErrorLogPathB + WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB); // CommonLogPathA + WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB); // CommonLogPathB + WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB); // BackupDataPathA + WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB); // BackupDataPathB + + patches::Audio::Init (); + patches::Qr::Init (); + patches::AmAuth::Init (); } } // namespace patches::JPN08 diff --git a/src/patches/versions/JPN39.cpp b/src/patches/versions/JPN39.cpp index d8eeeba..3b986bc 100644 --- a/src/patches/versions/JPN39.cpp +++ b/src/patches/versions/JPN39.cpp @@ -7,10 +7,10 @@ namespace patches::JPN39 { HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; } HOOK_DYNAMIC (i64, __fastcall, curl_easy_setopt, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5) { - // printf ("garmc curl_easy_setopt\n"); - originalcurl_easy_setopt (a1, 64, 0, 0, 0); - originalcurl_easy_setopt (a1, 81, 0, 0, 0); - return originalcurl_easy_setopt (a1, a2, a3, a4, a5); + // printf ("garmc curl_easy_setopt\n"); + originalcurl_easy_setopt (a1, 64, 0, 0, 0); + originalcurl_easy_setopt (a1, 81, 0, 0, 0); + return originalcurl_easy_setopt (a1, a2, a3, a4, a5); } const i32 datatableBufferSize = 1024 * 1024 * 12; @@ -24,118 +24,118 @@ const std::vector memsetSizeAddresses = {0x1400ABE26, 0x1400ABE 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); + 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 &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); - } + 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 unlockSongs = true; - - auto configPath = std::filesystem::current_path () / "config.toml"; - std::unique_ptr config_ptr (openConfig (configPath), toml_free); - if (config_ptr) { - auto patches = openConfigSection (config_ptr.get (), "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); - unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); - } - } - - // Apply common config patch - WRITE_MEMORY (ASLR (0x140494533), i32, xRes); - WRITE_MEMORY (ASLR (0x14049453A), i32, yRes); - if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); - if (unlockSongs) WRITE_MEMORY (ASLR (0x1403F45CF), u8, 0xB0, 0x01); - - // Bypass errors - WRITE_MEMORY (ASLR (0x140041A00), u8, 0xC3); - - // Use TLS v1.2 - WRITE_MEMORY (ASLR (0x140580459), u8, 0x10); - - // Disable F/G check - WRITE_MEMORY (ASLR (0x140CD4858), char, "./"); - - // Move various files to current directory - WRITE_MEMORY (ASLR (0x140C8AB60), char, "./"); - WRITE_MEMORY (ASLR (0x140C8AB5C), char, "./"); - WRITE_MEMORY (ASLR (0x140CD4DC0), char, ".\\Setting1.bin"); - WRITE_MEMORY (ASLR (0x140CD4DB0), char, ".\\Setting2.bin"); - WRITE_MEMORY (ASLR (0x140C95B40), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); - WRITE_MEMORY (ASLR (0x140C95BB0), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); - WRITE_MEMORY (ASLR (0x140CC0508), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat"); - WRITE_MEMORY (ASLR (0x140CC0660), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat"); - WRITE_MEMORY (ASLR (0x140CC05E0), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat"); - WRITE_MEMORY (ASLR (0x140CC0830), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat"); - WRITE_MEMORY (ASLR (0x140CC06C0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat"); - WRITE_MEMORY (ASLR (0x140CC0580), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat"); - WRITE_MEMORY (ASLR (0x140C95B78), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); - WRITE_MEMORY (ASLR (0x140C95BE8), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); - WRITE_MEMORY (ASLR (0x140CC0538), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat"); - WRITE_MEMORY (ASLR (0x140CC0690), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat"); - WRITE_MEMORY (ASLR (0x140CC0620), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat"); - WRITE_MEMORY (ASLR (0x140CC0880), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat"); - WRITE_MEMORY (ASLR (0x140CC06F0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat"); - WRITE_MEMORY (ASLR (0x140CC05B0), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat"); - - // 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 ()); - } - - // Disable live check - auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); - INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x42DE0)); - - // Move various files to current directory - WRITE_MEMORY (amHandle + 0x15252, u8, 0xEB); // CreditLogPathA - WRITE_MEMORY (amHandle + 0x15419, u8, 0xEB); // CreditLogPathB - WRITE_MEMORY (amHandle + 0x416DA, u8, 0xEB); // ErrorLogPathA - WRITE_MEMORY (amHandle + 0x41859, u8, 0xEB); // ErrorLogPathB - WRITE_MEMORY (amHandle + 0x41C21, u8, 0xEB); // CommonLogPathA - WRITE_MEMORY (amHandle + 0x41DA5, u8, 0xEB); // CommonLogPathB - WRITE_MEMORY (amHandle + 0x420F1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA - WRITE_MEMORY (amHandle + 0x42167, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB - - // Redirect garmc requests - auto garmcHandle = (u64)GetModuleHandle ("garmc.dll"); - INSTALL_HOOK_DYNAMIC (curl_easy_setopt, (void *)(garmcHandle + 0x1FBBB0)); - - patches::Audio::Init (); - patches::Qr::Init (); - patches::AmAuth::Init (); + i32 xRes = 1920; + i32 yRes = 1080; + bool vsync = false; + bool unlockSongs = true; + + auto configPath = std::filesystem::current_path () / "config.toml"; + std::unique_ptr config_ptr (openConfig (configPath), toml_free); + if (config_ptr) { + auto patches = openConfigSection (config_ptr.get (), "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); + unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); + } + } + + // Apply common config patch + WRITE_MEMORY (ASLR (0x140494533), i32, xRes); + WRITE_MEMORY (ASLR (0x14049453A), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); + if (unlockSongs) WRITE_MEMORY (ASLR (0x1403F45CF), u8, 0xB0, 0x01); + + // Bypass errors + WRITE_MEMORY (ASLR (0x140041A00), u8, 0xC3); + + // Use TLS v1.2 + WRITE_MEMORY (ASLR (0x140580459), u8, 0x10); + + // Disable F/G check + WRITE_MEMORY (ASLR (0x140CD4858), char, "./"); + + // Move various files to current directory + WRITE_MEMORY (ASLR (0x140C8AB60), char, "./"); + WRITE_MEMORY (ASLR (0x140C8AB5C), char, "./"); + WRITE_MEMORY (ASLR (0x140CD4DC0), char, ".\\Setting1.bin"); + WRITE_MEMORY (ASLR (0x140CD4DB0), char, ".\\Setting2.bin"); + WRITE_MEMORY (ASLR (0x140C95B40), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); + WRITE_MEMORY (ASLR (0x140C95BB0), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); + WRITE_MEMORY (ASLR (0x140CC0508), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC0660), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC05E0), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140CC0830), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140CC06C0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140CC0580), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140C95B78), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); + WRITE_MEMORY (ASLR (0x140C95BE8), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); + WRITE_MEMORY (ASLR (0x140CC0538), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC0690), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC0620), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140CC0880), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140CC06F0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140CC05B0), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat"); + + // 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 ()); + } + + // Disable live check + auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); + INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x42DE0)); + + // Move various files to current directory + WRITE_MEMORY (amHandle + 0x15252, u8, 0xEB); // CreditLogPathA + WRITE_MEMORY (amHandle + 0x15419, u8, 0xEB); // CreditLogPathB + WRITE_MEMORY (amHandle + 0x416DA, u8, 0xEB); // ErrorLogPathA + WRITE_MEMORY (amHandle + 0x41859, u8, 0xEB); // ErrorLogPathB + WRITE_MEMORY (amHandle + 0x41C21, u8, 0xEB); // CommonLogPathA + WRITE_MEMORY (amHandle + 0x41DA5, u8, 0xEB); // CommonLogPathB + WRITE_MEMORY (amHandle + 0x420F1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA + WRITE_MEMORY (amHandle + 0x42167, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB + + // Redirect garmc requests + auto garmcHandle = (u64)GetModuleHandle ("garmc.dll"); + INSTALL_HOOK_DYNAMIC (curl_easy_setopt, (void *)(garmcHandle + 0x1FBBB0)); + + patches::Audio::Init (); + patches::Qr::Init (); + patches::AmAuth::Init (); } } // namespace patches::JPN39 \ No newline at end of file diff --git a/src/poll.cpp b/src/poll.cpp index c595b2d..80cd22f 100644 --- a/src/poll.cpp +++ b/src/poll.cpp @@ -3,8 +3,8 @@ #include struct { - const char *string; - uint8_t keycode; + const char *string; + uint8_t keycode; } ConfigKeyboardButtons[] = { // Reference:https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes // Wayback Machine:https://web.archive.org/web/20231223135232/https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes @@ -130,8 +130,8 @@ struct { }; struct { - const char *string; - SDL_GameControllerButton button; + const char *string; + SDL_GameControllerButton button; } ConfigControllerButtons[] = { {"SDL_A", SDL_CONTROLLER_BUTTON_A}, {"SDL_B", SDL_CONTROLLER_BUTTON_B}, @@ -157,27 +157,28 @@ struct { }; struct { - const char *string; - SDLAxis axis; + const char *string; + SDLAxis axis; } ConfigControllerAXIS[] = { - {"SDL_LSTICK_LEFT", SDL_AXIS_LEFT_LEFT}, {"SDL_LSTICK_UP", SDL_AXIS_LEFT_UP}, {"SDL_LSTICK_DOWN", SDL_AXIS_LEFT_DOWN}, {"SDL_LSTICK_RIGHT", SDL_AXIS_LEFT_RIGHT}, - {"SDL_RSTICK_LEFT", SDL_AXIS_RIGHT_LEFT}, {"SDL_RSTICK_UP", SDL_AXIS_RIGHT_UP}, {"SDL_RSTICK_DOWN", SDL_AXIS_RIGHT_DOWN}, {"SDL_RSTICK_RIGHT", SDL_AXIS_RIGHT_RIGHT}, - {"SDL_LTRIGGER", SDL_AXIS_LTRIGGER_DOWN}, {"SDL_RTRIGGER", SDL_AXIS_RTRIGGER_DOWN}, + {"SDL_LSTICK_LEFT", SDL_AXIS_LEFT_LEFT}, {"SDL_LSTICK_UP", SDL_AXIS_LEFT_UP}, {"SDL_LSTICK_DOWN", SDL_AXIS_LEFT_DOWN}, + {"SDL_LSTICK_RIGHT", SDL_AXIS_LEFT_RIGHT}, {"SDL_RSTICK_LEFT", SDL_AXIS_RIGHT_LEFT}, {"SDL_RSTICK_UP", SDL_AXIS_RIGHT_UP}, + {"SDL_RSTICK_DOWN", SDL_AXIS_RIGHT_DOWN}, {"SDL_RSTICK_RIGHT", SDL_AXIS_RIGHT_RIGHT}, {"SDL_LTRIGGER", SDL_AXIS_LTRIGGER_DOWN}, + {"SDL_RTRIGGER", SDL_AXIS_RTRIGGER_DOWN}, }; struct { - const char *string; - Scroll scroll; + const char *string; + Scroll scroll; } ConfigMouseScroll[] = { {"SCROLL_UP", MOUSE_SCROLL_UP}, {"SCROLL_DOWN", MOUSE_SCROLL_DOWN}, }; struct MouseState { - POINT Position; - POINT RelativePosition; - bool ScrolledUp; - bool ScrolledDown; + POINT Position; + POINT RelativePosition; + bool ScrolledUp; + bool ScrolledDown; } currentMouseState, lastMouseState; bool currentKeyboardState[0xFF]; @@ -193,297 +194,299 @@ SDL_GameController *controllers[255]; void SetConfigValue (toml_table_t *table, const char *key, Keybindings *keybind) { - toml_array_t *array = toml_array_in (table, key); - if (!array) { - printWarning ("%s (%s): Cannot find array\n", __func__, key); - return; - } - - memset (keybind, 0, sizeof (*keybind)); - for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++) - keybind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID; - - for (size_t i = 0;; i++) { - toml_datum_t bind = toml_string_at (array, i); - if (!bind.ok) break; - ConfigValue value = StringToConfigEnum (bind.u.s); - free (bind.u.s); - - switch (value.type) { - case keycode: - for (size_t i = 0; i < COUNTOFARR (keybind->keycodes); i++) { - if (keybind->keycodes[i] == 0) { - keybind->keycodes[i] = value.keycode; - break; - } - } - break; - case button: - for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++) { - if (keybind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) { - keybind->buttons[i] = value.button; - break; - } - } - break; - case axis: - for (size_t i = 0; i < COUNTOFARR (keybind->axis); i++) { - if (keybind->axis[i] == 0) { - keybind->axis[i] = value.axis; - break; - } - } - case scroll: - for (size_t i = 0; i < COUNTOFARR (keybind->scroll); i++) { - if (keybind->scroll[i] == 0) { - keybind->scroll[i] = value.scroll; - break; - } - } - break; - default: break; - } - } + toml_array_t *array = toml_array_in (table, key); + if (!array) { + printWarning ("%s (%s): Cannot find array\n", __func__, key); + return; + } + + memset (keybind, 0, sizeof (*keybind)); + for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++) + keybind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID; + + for (size_t i = 0;; i++) { + toml_datum_t bind = toml_string_at (array, i); + if (!bind.ok) break; + ConfigValue value = StringToConfigEnum (bind.u.s); + free (bind.u.s); + + switch (value.type) { + case keycode: + for (size_t i = 0; i < COUNTOFARR (keybind->keycodes); i++) { + if (keybind->keycodes[i] == 0) { + keybind->keycodes[i] = value.keycode; + break; + } + } + break; + case button: + for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++) { + if (keybind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) { + keybind->buttons[i] = value.button; + break; + } + } + break; + case axis: + for (size_t i = 0; i < COUNTOFARR (keybind->axis); i++) { + if (keybind->axis[i] == 0) { + keybind->axis[i] = value.axis; + break; + } + } + case scroll: + for (size_t i = 0; i < COUNTOFARR (keybind->scroll); i++) { + if (keybind->scroll[i] == 0) { + keybind->scroll[i] = value.scroll; + break; + } + } + break; + default: break; + } + } } bool InitializePoll (HWND windowHandle) { - bool hasRumble = true; - SDL_SetMainReady (); - - SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, "1"); - SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); - SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1"); - SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); - - if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) { - if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) { - hasRumble = false; - } else { - printError ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): " - "%s\n", - SDL_GetError ()); - return false; - } - } - - auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt"; - if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1) printError ("%s (): Cannot read gamecontrollerdb.txt\n", __func__); - SDL_GameControllerEventState (SDL_ENABLE); - SDL_JoystickEventState (SDL_ENABLE); - - for (int i = 0; i < SDL_NumJoysticks (); i++) { - if (!SDL_IsGameController (i)) continue; - - SDL_GameController *controller = SDL_GameControllerOpen (i); - if (!controller) { - printWarning ("Could not open gamecontroller %s: %s\n", SDL_GameControllerNameForIndex (i), SDL_GetError ()); - continue; - } - controllers[i] = controller; - } - - window = SDL_CreateWindowFrom (windowHandle); - if (window == NULL) printError ("SDL_CreateWindowFrom (windowHandle): %s\n", SDL_GetError ()); - - atexit (DisposePoll); - - return hasRumble; + bool hasRumble = true; + SDL_SetMainReady (); + + SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, "1"); + SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); + SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1"); + SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); + + if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) { + if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) { + hasRumble = false; + } else { + printError ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): " + "%s\n", + SDL_GetError ()); + return false; + } + } + + auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt"; + if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1) + printError ("%s (): Cannot read gamecontrollerdb.txt\n", __func__); + SDL_GameControllerEventState (SDL_ENABLE); + SDL_JoystickEventState (SDL_ENABLE); + + for (int i = 0; i < SDL_NumJoysticks (); i++) { + if (!SDL_IsGameController (i)) continue; + + SDL_GameController *controller = SDL_GameControllerOpen (i); + if (!controller) { + printWarning ("Could not open gamecontroller %s: %s\n", SDL_GameControllerNameForIndex (i), SDL_GetError ()); + continue; + } + controllers[i] = controller; + } + + window = SDL_CreateWindowFrom (windowHandle); + if (window == NULL) printError ("SDL_CreateWindowFrom (windowHandle): %s\n", SDL_GetError ()); + + atexit (DisposePoll); + + return hasRumble; } void UpdatePoll (HWND windowHandle) { - if (windowHandle == NULL || GetForegroundWindow () != windowHandle) return; - - memcpy (lastKeyboardState, currentKeyboardState, 255); - memcpy (lastControllerButtonsState, currentControllerButtonsState, 21); - lastMouseState = currentMouseState; - lastControllerAxisState = currentControllerAxisState; - - for (uint8_t i = 0; i < 0xFF; i++) - currentKeyboardState[i] = GetAsyncKeyState (i) != 0; - - currentMouseState.ScrolledUp = false; - currentMouseState.ScrolledDown = false; - - GetCursorPos (¤tMouseState.Position); - ScreenToClient (windowHandle, ¤tMouseState.Position); - - SDL_Event event; - SDL_GameController *controller; - while (SDL_PollEvent (&event) != 0) { - switch (event.type) { - case SDL_CONTROLLERDEVICEADDED: - if (!SDL_IsGameController (event.cdevice.which)) break; - - controller = SDL_GameControllerOpen (event.cdevice.which); - if (!controller) { - printError ("%s (): Could not open gamecontroller %s: %s\n", __func__, SDL_GameControllerNameForIndex (event.cdevice.which), SDL_GetError ()); - continue; - } - controllers[event.cdevice.which] = controller; - break; - case SDL_CONTROLLERDEVICEREMOVED: - if (!SDL_IsGameController (event.cdevice.which)) break; - SDL_GameControllerClose (controllers[event.cdevice.which]); - break; - case SDL_MOUSEWHEEL: - if (event.wheel.y > 0) currentMouseState.ScrolledUp = true; - else if (event.wheel.y < 0) currentMouseState.ScrolledDown = true; - break; - case SDL_CONTROLLERBUTTONUP: - case SDL_CONTROLLERBUTTONDOWN: currentControllerButtonsState[event.cbutton.button] = event.cbutton.state; break; - case SDL_CONTROLLERAXISMOTION: - if (event.caxis.value > 1) { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = (float)event.caxis.value / 32767; break; - case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = (float)event.caxis.value / 32767; break; - case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = (float)event.caxis.value / 32767; break; - case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = (float)event.caxis.value / 32767; break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = (float)event.caxis.value / 32767; break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = (float)event.caxis.value / 32767; break; - } - } else if (event.caxis.value < -1) { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftLeft = (float)event.caxis.value / -32768; break; - case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftUp = (float)event.caxis.value / -32768; break; - case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightLeft = (float)event.caxis.value / -32768; break; - case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightUp = (float)event.caxis.value / -32768; break; - } - } else { - switch (event.caxis.axis) { - case SDL_CONTROLLER_AXIS_LEFTX: - currentControllerAxisState.LeftRight = 0; - currentControllerAxisState.LeftLeft = 0; - break; - case SDL_CONTROLLER_AXIS_LEFTY: - currentControllerAxisState.LeftDown = 0; - currentControllerAxisState.LeftUp = 0; - break; - case SDL_CONTROLLER_AXIS_RIGHTX: - currentControllerAxisState.RightRight = 0; - currentControllerAxisState.RightLeft = 0; - break; - case SDL_CONTROLLER_AXIS_RIGHTY: - currentControllerAxisState.RightDown = 0; - currentControllerAxisState.RightUp = 0; - break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = 0; break; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = 0; break; - } - } - break; - } - } + if (windowHandle == NULL || GetForegroundWindow () != windowHandle) return; + + memcpy (lastKeyboardState, currentKeyboardState, 255); + memcpy (lastControllerButtonsState, currentControllerButtonsState, 21); + lastMouseState = currentMouseState; + lastControllerAxisState = currentControllerAxisState; + + for (uint8_t i = 0; i < 0xFF; i++) + currentKeyboardState[i] = GetAsyncKeyState (i) != 0; + + currentMouseState.ScrolledUp = false; + currentMouseState.ScrolledDown = false; + + GetCursorPos (¤tMouseState.Position); + ScreenToClient (windowHandle, ¤tMouseState.Position); + + SDL_Event event; + SDL_GameController *controller; + while (SDL_PollEvent (&event) != 0) { + switch (event.type) { + case SDL_CONTROLLERDEVICEADDED: + if (!SDL_IsGameController (event.cdevice.which)) break; + + controller = SDL_GameControllerOpen (event.cdevice.which); + if (!controller) { + printError ("%s (): Could not open gamecontroller %s: %s\n", __func__, SDL_GameControllerNameForIndex (event.cdevice.which), + SDL_GetError ()); + continue; + } + controllers[event.cdevice.which] = controller; + break; + case SDL_CONTROLLERDEVICEREMOVED: + if (!SDL_IsGameController (event.cdevice.which)) break; + SDL_GameControllerClose (controllers[event.cdevice.which]); + break; + case SDL_MOUSEWHEEL: + if (event.wheel.y > 0) currentMouseState.ScrolledUp = true; + else if (event.wheel.y < 0) currentMouseState.ScrolledDown = true; + break; + case SDL_CONTROLLERBUTTONUP: + case SDL_CONTROLLERBUTTONDOWN: currentControllerButtonsState[event.cbutton.button] = event.cbutton.state; break; + case SDL_CONTROLLERAXISMOTION: + if (event.caxis.value > 1) { + switch (event.caxis.axis) { + case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = (float)event.caxis.value / 32767; break; + case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = (float)event.caxis.value / 32767; break; + case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = (float)event.caxis.value / 32767; break; + case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = (float)event.caxis.value / 32767; break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = (float)event.caxis.value / 32767; break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = (float)event.caxis.value / 32767; break; + } + } else if (event.caxis.value < -1) { + switch (event.caxis.axis) { + case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftLeft = (float)event.caxis.value / -32768; break; + case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftUp = (float)event.caxis.value / -32768; break; + case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightLeft = (float)event.caxis.value / -32768; break; + case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightUp = (float)event.caxis.value / -32768; break; + } + } else { + switch (event.caxis.axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + currentControllerAxisState.LeftRight = 0; + currentControllerAxisState.LeftLeft = 0; + break; + case SDL_CONTROLLER_AXIS_LEFTY: + currentControllerAxisState.LeftDown = 0; + currentControllerAxisState.LeftUp = 0; + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + currentControllerAxisState.RightRight = 0; + currentControllerAxisState.RightLeft = 0; + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + currentControllerAxisState.RightDown = 0; + currentControllerAxisState.RightUp = 0; + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = 0; break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = 0; break; + } + } + break; + } + } } void DisposePoll () { - SDL_DestroyWindow (window); - SDL_Quit (); + SDL_DestroyWindow (window); + SDL_Quit (); } ConfigValue StringToConfigEnum (const char *value) { - ConfigValue rval; - for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); ++i) - if (!strcmp (value, ConfigKeyboardButtons[i].string)) { - rval.type = keycode; - rval.keycode = ConfigKeyboardButtons[i].keycode; - return rval; - } - for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); ++i) - if (!strcmp (value, ConfigControllerButtons[i].string)) { - rval.type = button; - rval.button = ConfigControllerButtons[i].button; - return rval; - } - for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); ++i) - if (!strcmp (value, ConfigControllerAXIS[i].string)) { - rval.type = axis; - rval.axis = ConfigControllerAXIS[i].axis; - return rval; - } - for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); ++i) - if (!strcmp (value, ConfigMouseScroll[i].string)) { - rval.type = scroll; - rval.scroll = ConfigMouseScroll[i].scroll; - return rval; - } - - printError ("%s (%s): Unknown value\n", __func__, value); - return rval; + ConfigValue rval; + for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); ++i) + if (!strcmp (value, ConfigKeyboardButtons[i].string)) { + rval.type = keycode; + rval.keycode = ConfigKeyboardButtons[i].keycode; + return rval; + } + for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); ++i) + if (!strcmp (value, ConfigControllerButtons[i].string)) { + rval.type = button; + rval.button = ConfigControllerButtons[i].button; + return rval; + } + for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); ++i) + if (!strcmp (value, ConfigControllerAXIS[i].string)) { + rval.type = axis; + rval.axis = ConfigControllerAXIS[i].axis; + return rval; + } + for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); ++i) + if (!strcmp (value, ConfigMouseScroll[i].string)) { + rval.type = scroll; + rval.scroll = ConfigMouseScroll[i].scroll; + return rval; + } + + printError ("%s (%s): Unknown value\n", __func__, value); + return rval; } InternalButtonState GetInternalButtonState (Keybindings bindings) { - InternalButtonState buttons = {0}; - - for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); i++) { - if (bindings.keycodes[i] == 0) continue; - if (KeyboardIsReleased (bindings.keycodes[i])) buttons.Released = 1; - if (KeyboardIsDown (bindings.keycodes[i])) buttons.Down = 1; - if (KeyboardIsTapped (bindings.keycodes[i])) buttons.Tapped = 1; - } - for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); i++) { - if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue; - if (ControllerButtonIsReleased (bindings.buttons[i])) buttons.Released = 1; - if (ControllerButtonIsDown (bindings.buttons[i])) buttons.Down = 1; - if (ControllerButtonIsTapped (bindings.buttons[i])) buttons.Tapped = 1; - } - for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); i++) { - if (bindings.axis[i] == 0) continue; - if (float val = ControllerAxisIsReleased (bindings.axis[i])) buttons.Released = val; - if (float val = ControllerAxisIsDown (bindings.axis[i])) buttons.Down = val; - if (float val = ControllerAxisIsTapped (bindings.axis[i])) buttons.Tapped = val; - } - for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); i++) { - if (bindings.scroll[i] == 0) continue; - if (GetMouseScrollIsReleased (bindings.scroll[i])) buttons.Released = 1; - if (GetMouseScrollIsDown (bindings.scroll[i])) buttons.Down = 1; - if (GetMouseScrollIsTapped (bindings.scroll[i])) buttons.Tapped = 1; - } - - return buttons; + InternalButtonState buttons = {0}; + + for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); i++) { + if (bindings.keycodes[i] == 0) continue; + if (KeyboardIsReleased (bindings.keycodes[i])) buttons.Released = 1; + if (KeyboardIsDown (bindings.keycodes[i])) buttons.Down = 1; + if (KeyboardIsTapped (bindings.keycodes[i])) buttons.Tapped = 1; + } + for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); i++) { + if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue; + if (ControllerButtonIsReleased (bindings.buttons[i])) buttons.Released = 1; + if (ControllerButtonIsDown (bindings.buttons[i])) buttons.Down = 1; + if (ControllerButtonIsTapped (bindings.buttons[i])) buttons.Tapped = 1; + } + for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); i++) { + if (bindings.axis[i] == 0) continue; + if (float val = ControllerAxisIsReleased (bindings.axis[i])) buttons.Released = val; + if (float val = ControllerAxisIsDown (bindings.axis[i])) buttons.Down = val; + if (float val = ControllerAxisIsTapped (bindings.axis[i])) buttons.Tapped = val; + } + for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); i++) { + if (bindings.scroll[i] == 0) continue; + if (GetMouseScrollIsReleased (bindings.scroll[i])) buttons.Released = 1; + if (GetMouseScrollIsDown (bindings.scroll[i])) buttons.Down = 1; + if (GetMouseScrollIsTapped (bindings.scroll[i])) buttons.Tapped = 1; + } + + return buttons; } void SetRumble (int left, int right, int length) { - for (size_t i = 0; i < COUNTOFARR (controllers); i++) { - if (!controllers[i] || !SDL_GameControllerHasRumble (controllers[i])) continue; + for (size_t i = 0; i < COUNTOFARR (controllers); i++) { + if (!controllers[i] || !SDL_GameControllerHasRumble (controllers[i])) continue; - SDL_GameControllerRumble (controllers[i], left, right, length); - } + SDL_GameControllerRumble (controllers[i], left, right, length); + } } bool KeyboardIsDown (uint8_t keycode) { - return currentKeyboardState[keycode]; + return currentKeyboardState[keycode]; } bool KeyboardIsUp (uint8_t keycode) { - return !KeyboardIsDown (keycode); + return !KeyboardIsDown (keycode); } bool KeyboardIsTapped (uint8_t keycode) { - return KeyboardIsDown (keycode) && KeyboardWasUp (keycode); + return KeyboardIsDown (keycode) && KeyboardWasUp (keycode); } bool KeyboardIsReleased (uint8_t keycode) { - return KeyboardIsUp (keycode) && KeyboardWasDown (keycode); + return KeyboardIsUp (keycode) && KeyboardWasDown (keycode); } bool KeyboardWasDown (uint8_t keycode) { - return lastKeyboardState[keycode]; + return lastKeyboardState[keycode]; } bool KeyboardWasUp (uint8_t keycode) { - return !KeyboardWasDown (keycode); + return !KeyboardWasDown (keycode); } POINT @@ -500,142 +503,142 @@ GetLastMouseRelativePosition () { return lastMouseState.RelativePosition; } void SetMousePosition (POINT newPosition) { - currentMouseState.Position = newPosition; + currentMouseState.Position = newPosition; } bool GetMouseScrollUp () { - return currentMouseState.ScrolledUp; + return currentMouseState.ScrolledUp; } bool GetMouseScrollDown () { - return currentMouseState.ScrolledDown; + return currentMouseState.ScrolledDown; } bool GetWasMouseScrollUp () { - return lastMouseState.ScrolledUp; + return lastMouseState.ScrolledUp; } bool GetWasMouseScrollDown () { - return lastMouseState.ScrolledDown; + return lastMouseState.ScrolledDown; } bool GetMouseScrollIsReleased (Scroll scroll) { - if (scroll == MOUSE_SCROLL_UP) return !GetMouseScrollUp () && GetWasMouseScrollUp (); - else return !GetMouseScrollDown () && GetWasMouseScrollDown (); + if (scroll == MOUSE_SCROLL_UP) return !GetMouseScrollUp () && GetWasMouseScrollUp (); + else return !GetMouseScrollDown () && GetWasMouseScrollDown (); } bool GetMouseScrollIsDown (Scroll scroll) { - if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp (); - else return GetMouseScrollDown (); + if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp (); + else return GetMouseScrollDown (); } bool GetMouseScrollIsTapped (Scroll scroll) { - if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp () && !GetWasMouseScrollUp (); - else return GetMouseScrollDown () && !GetWasMouseScrollDown (); + if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp () && !GetWasMouseScrollUp (); + else return GetMouseScrollDown () && !GetWasMouseScrollDown (); } bool ControllerButtonIsDown (SDL_GameControllerButton button) { - return currentControllerButtonsState[button]; + return currentControllerButtonsState[button]; } bool ControllerButtonIsUp (SDL_GameControllerButton button) { - return !ControllerButtonIsDown (button); + return !ControllerButtonIsDown (button); } bool ControllerButtonWasDown (SDL_GameControllerButton button) { - return lastControllerButtonsState[button]; + return lastControllerButtonsState[button]; } bool ControllerButtonWasUp (SDL_GameControllerButton button) { - return !ControllerButtonWasDown (button); + return !ControllerButtonWasDown (button); } bool ControllerButtonIsTapped (SDL_GameControllerButton button) { - return ControllerButtonIsDown (button) && ControllerButtonWasUp (button); + return ControllerButtonIsDown (button) && ControllerButtonWasUp (button); } bool ControllerButtonIsReleased (SDL_GameControllerButton button) { - return ControllerButtonIsUp (button) && ControllerButtonWasDown (button); + return ControllerButtonIsUp (button) && ControllerButtonWasDown (button); } float ControllerAxisIsDown (SDLAxis axis) { - switch (axis) { - case SDL_AXIS_LEFT_LEFT: return currentControllerAxisState.LeftLeft; - case SDL_AXIS_LEFT_RIGHT: return currentControllerAxisState.LeftRight; - case SDL_AXIS_LEFT_UP: return currentControllerAxisState.LeftUp; - case SDL_AXIS_LEFT_DOWN: return currentControllerAxisState.LeftDown; - case SDL_AXIS_RIGHT_LEFT: return currentControllerAxisState.RightLeft; - case SDL_AXIS_RIGHT_RIGHT: return currentControllerAxisState.RightRight; - case SDL_AXIS_RIGHT_UP: return currentControllerAxisState.RightUp; - case SDL_AXIS_RIGHT_DOWN: return currentControllerAxisState.RightDown; - case SDL_AXIS_LTRIGGER_DOWN: return currentControllerAxisState.LTriggerDown; - case SDL_AXIS_RTRIGGER_DOWN: return currentControllerAxisState.RTriggerDown; - default: return false; - } + switch (axis) { + case SDL_AXIS_LEFT_LEFT: return currentControllerAxisState.LeftLeft; + case SDL_AXIS_LEFT_RIGHT: return currentControllerAxisState.LeftRight; + case SDL_AXIS_LEFT_UP: return currentControllerAxisState.LeftUp; + case SDL_AXIS_LEFT_DOWN: return currentControllerAxisState.LeftDown; + case SDL_AXIS_RIGHT_LEFT: return currentControllerAxisState.RightLeft; + case SDL_AXIS_RIGHT_RIGHT: return currentControllerAxisState.RightRight; + case SDL_AXIS_RIGHT_UP: return currentControllerAxisState.RightUp; + case SDL_AXIS_RIGHT_DOWN: return currentControllerAxisState.RightDown; + case SDL_AXIS_LTRIGGER_DOWN: return currentControllerAxisState.LTriggerDown; + case SDL_AXIS_RTRIGGER_DOWN: return currentControllerAxisState.RTriggerDown; + default: return false; + } } bool ControllerAxisIsUp (SDLAxis axis) { - return !ControllerAxisIsDown (axis); + return !ControllerAxisIsDown (axis); } float ControllerAxisWasDown (SDLAxis axis) { - switch (axis) { - case SDL_AXIS_LEFT_LEFT: return lastControllerAxisState.LeftLeft; - case SDL_AXIS_LEFT_RIGHT: return lastControllerAxisState.LeftRight; - case SDL_AXIS_LEFT_UP: return lastControllerAxisState.LeftUp; - case SDL_AXIS_LEFT_DOWN: return lastControllerAxisState.LeftDown; - case SDL_AXIS_RIGHT_LEFT: return lastControllerAxisState.RightLeft; - case SDL_AXIS_RIGHT_RIGHT: return lastControllerAxisState.RightRight; - case SDL_AXIS_RIGHT_UP: return lastControllerAxisState.RightUp; - case SDL_AXIS_RIGHT_DOWN: return lastControllerAxisState.RightDown; - case SDL_AXIS_LTRIGGER_DOWN: return lastControllerAxisState.LTriggerDown; - case SDL_AXIS_RTRIGGER_DOWN: return lastControllerAxisState.RTriggerDown; - default: return false; - } + switch (axis) { + case SDL_AXIS_LEFT_LEFT: return lastControllerAxisState.LeftLeft; + case SDL_AXIS_LEFT_RIGHT: return lastControllerAxisState.LeftRight; + case SDL_AXIS_LEFT_UP: return lastControllerAxisState.LeftUp; + case SDL_AXIS_LEFT_DOWN: return lastControllerAxisState.LeftDown; + case SDL_AXIS_RIGHT_LEFT: return lastControllerAxisState.RightLeft; + case SDL_AXIS_RIGHT_RIGHT: return lastControllerAxisState.RightRight; + case SDL_AXIS_RIGHT_UP: return lastControllerAxisState.RightUp; + case SDL_AXIS_RIGHT_DOWN: return lastControllerAxisState.RightDown; + case SDL_AXIS_LTRIGGER_DOWN: return lastControllerAxisState.LTriggerDown; + case SDL_AXIS_RTRIGGER_DOWN: return lastControllerAxisState.RTriggerDown; + default: return false; + } } bool ControllerAxisWasUp (SDLAxis axis) { - return !ControllerAxisWasDown (axis); + return !ControllerAxisWasDown (axis); } bool ControllerAxisIsTapped (SDLAxis axis) { - return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis); + return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis); } bool ControllerAxisIsReleased (SDLAxis axis) { - return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis); + return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis); } bool IsButtonTapped (Keybindings bindings) { - return GetInternalButtonState (bindings).Tapped; + return GetInternalButtonState (bindings).Tapped; } bool IsButtonReleased (Keybindings bindings) { - return GetInternalButtonState (bindings).Released; + return GetInternalButtonState (bindings).Released; } float IsButtonDown (Keybindings bindings) { - return GetInternalButtonState (bindings).Down; + return GetInternalButtonState (bindings).Down; } diff --git a/src/poll.h b/src/poll.h index 670a48b..b7d6826 100644 --- a/src/poll.h +++ b/src/poll.h @@ -6,58 +6,58 @@ #include 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 + 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; + 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]; + 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; - }; + EnumType type; + union { + uint8_t keycode; + SDL_GameControllerButton button; + SDLAxis axis; + Scroll scroll; + }; }; struct InternalButtonState { - float Down; - bool Released; - bool Tapped; + float Down; + bool Released; + bool Tapped; }; bool InitializePoll (HWND windowHandle);