1
1
mirror of synced 2025-02-03 04:47:08 +01:00

Add QR emulation for 08.18

This commit is contained in:
esuo1198 2023-09-21 02:40:39 +09:00
parent d25a3743f2
commit 92c3e6aa81
3 changed files with 122 additions and 127 deletions

View File

@ -223,7 +223,7 @@ u16 __fastcall bnusio_GetCoin (i32 a1) {
if (updateEvent) updateEvent ();
}
if (version == GameVersion::CN_JUN_2023) patches::Qr::Update();
patches::Qr::Update();
return coin_count;
}

View File

@ -126,6 +126,8 @@ Init () {
WRITE_MEMORY ((u64)amHandle + 0x148AF, u8, 0xEB);
WRITE_MEMORY ((u64)amHandle + 0x14A1A, u8, 0xEB);
patches::Qr::Init ();
patches::AmAuth::Init ();
}
} // namespace patches::JP_NOV_2020

View File

@ -1,168 +1,161 @@
#include "constants.h"
#include "helpers.h"
#include "poll.h"
#include "patches.h"
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>
#include <fstream>
extern GameVersion version;
extern Keybindings QR_CARD_READ;
extern Keybindings QR_DATA_READ;
namespace patches::Qr {
enum class State
{
Ready,
CopyWait,
AfterCopy1,
AfterCopy2,
enum class State {
Ready,
CopyWait,
AfterCopy1,
AfterCopy2,
};
enum class Mode
{
Card,
Data
};
enum class Mode { Card, Data };
State gState = State::Ready;
Mode gMode = Mode::Card;
Mode gMode = Mode::Card;
HOOK_DYNAMIC (char, __fastcall, qrInit, int64_t a1) { return 1; }
HOOK_DYNAMIC (char, __fastcall, qrRead, int64_t a1)
{
*reinterpret_cast<DWORD*>(a1 + 40) = 1;
*reinterpret_cast<DWORD*>(a1 + 16) = 1;
*reinterpret_cast<BYTE*>(a1 + 112) = 0;
return 1;
HOOK_DYNAMIC (char, __fastcall, qrRead, int64_t a1) {
*reinterpret_cast<DWORD *> (a1 + 40) = 1;
*reinterpret_cast<DWORD *> (a1 + 16) = 1;
*reinterpret_cast<BYTE *> (a1 + 112) = 0;
return 1;
}
HOOK_DYNAMIC (char, __fastcall, qrClose, int64_t a1) { return 1; }
HOOK_DYNAMIC (int64_t, __fastcall, callQrUnknown, int64_t a1)
{
switch (gState)
{
case State::Ready:
case State::CopyWait:
{
return 1;
}
case State::AfterCopy1:
{
gState = State::AfterCopy2;
return 1;
}
case State::AfterCopy2:
{
return 1;
}
default:
return 0;
}
HOOK_DYNAMIC (int64_t, __fastcall, callQrUnknown, int64_t a1) {
switch (gState) {
case State::Ready:
case State::CopyWait: {
return 1;
}
case State::AfterCopy1: {
gState = State::AfterCopy2;
return 1;
}
case State::AfterCopy2: {
return 1;
}
default: return 0;
}
}
HOOK_DYNAMIC (bool, __fastcall, Send1, int64_t, const void*, int64_t) { return true; }
HOOK_DYNAMIC (bool, __fastcall, Send1, int64_t, const void *, int64_t) { return true; }
HOOK_DYNAMIC (bool, __fastcall, Send2, int64_t a1, char a2) { return true; }
HOOK_DYNAMIC (bool, __fastcall, Send3, int64_t a1)
{
*(WORD*)(a1 + 88) = 0;
*(BYTE*)(a1 + 90) = 0;
return true;
HOOK_DYNAMIC (bool, __fastcall, Send3, int64_t a1) {
*(WORD *)(a1 + 88) = 0;
*(BYTE *)(a1 + 90) = 0;
return true;
}
HOOK_DYNAMIC (bool, __fastcall, Send4, int64_t a1)
{
*(BYTE*)(a1 + 88) = 1;
*(int64_t*)(a1 + 32) = *(int64_t*)(a1 + 24);
*(WORD*)(a1 + 89) = 0;
return true;
HOOK_DYNAMIC (bool, __fastcall, Send4, int64_t a1) {
*(BYTE *)(a1 + 88) = 1;
*(int64_t *)(a1 + 32) = *(int64_t *)(a1 + 24);
*(WORD *)(a1 + 89) = 0;
return true;
}
HOOK_DYNAMIC (int64_t, __fastcall, copy_data, int64_t this_, void* dest, int length)
{
if (gState == State::CopyWait)
{
std::cout << "Copy data, length: " << length << std::endl;
auto configPath = std::filesystem::current_path () / "config.toml";
toml_table_t *config = openConfig (configPath);
std::string data = "";
HOOK_DYNAMIC (int64_t, __fastcall, copy_data, int64_t this_, void *dest, int length) {
if (gState == State::CopyWait) {
std::cout << "Copy data, length: " << length << std::endl;
auto configPath = std::filesystem::current_path () / "config.toml";
toml_table_t *config = openConfig (configPath);
std::string data = "";
if (gMode == Mode::Card)
{
if (config) {
data = readConfigString (config, "qr_card_string", "");
toml_free (config);
}
if (gMode == Mode::Card) {
if (config) {
data = readConfigString (config, "qr_card_string", "");
toml_free (config);
}
memcpy(dest, data.c_str(), data.size() + 1);
gState = State::AfterCopy1;
return data.size() + 1;
}
else if (gMode == Mode::Data)
{
if (config) {
data = readConfigString (config, "qr_data_string", "");
toml_free (config);
}
memcpy (dest, data.c_str (), data.size () + 1);
gState = State::AfterCopy1;
return data.size () + 1;
} else if (gMode == Mode::Data) {
if (config) {
data = readConfigString (config, "qr_data_string", "");
toml_free (config);
}
BYTE data_length = static_cast<BYTE>(data.size());
std::vector<BYTE> byteBuffer = {
0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, data_length, 0x01, 0x00
};
BYTE data_length = static_cast<BYTE> (data.size ());
std::vector<BYTE> byteBuffer = {0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, data_length, 0x01, 0x00};
for (char c : data) {
byteBuffer.push_back(static_cast<BYTE>(c));
}
for (char c : data)
byteBuffer.push_back (static_cast<BYTE> (c));
byteBuffer.push_back(0xEE);
byteBuffer.push_back(0xFF);
byteBuffer.push_back (0xEE);
byteBuffer.push_back (0xFF);
memcpy(dest, byteBuffer.data(), byteBuffer.size());
gState = State::AfterCopy1;
return byteBuffer.size();
}
}
return 0;
memcpy (dest, byteBuffer.data (), byteBuffer.size ());
gState = State::AfterCopy1;
return byteBuffer.size ();
}
}
return 0;
}
int gCount = 0;
void
Update () {
if (gState == State::AfterCopy2)
{
gCount++;
if (gCount > 10)
{
gCount = 0;
gState = State::Ready;
}
}
if (gState == State::Ready)
{
if (IsButtonTapped(QR_CARD_READ))
{
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Card;
}
else if (IsButtonTapped(QR_DATA_READ))
{
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Data;
}
}
if (gState == State::AfterCopy2) {
gCount++;
if (gCount > 10) {
gCount = 0;
gState = State::Ready;
}
}
if (gState == State::Ready) {
if (IsButtonTapped (QR_CARD_READ)) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Card;
} else if (IsButtonTapped (QR_DATA_READ)) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Data;
}
}
}
void
Init () {
auto amHandle = reinterpret_cast<uintptr_t>(GetModuleHandle ("AMFrameWork.dll"));
INSTALL_HOOK_DYNAMIC (qrInit, reinterpret_cast<LPVOID>(amHandle + 0x161B0));
INSTALL_HOOK_DYNAMIC (qrRead, reinterpret_cast<LPVOID>(amHandle + 0x163A0));
INSTALL_HOOK_DYNAMIC (qrClose, reinterpret_cast<LPVOID>(amHandle + 0x16350));
INSTALL_HOOK_DYNAMIC (callQrUnknown, reinterpret_cast<LPVOID>(amHandle + 0x8F60));
INSTALL_HOOK_DYNAMIC (Send1, reinterpret_cast<LPVOID>(amHandle + 0x16A30));
INSTALL_HOOK_DYNAMIC (Send2, reinterpret_cast<LPVOID>(amHandle + 0x16A00));
INSTALL_HOOK_DYNAMIC (Send3, reinterpret_cast<LPVOID>(amHandle + 0x16990));
INSTALL_HOOK_DYNAMIC (Send4, reinterpret_cast<LPVOID>(amHandle + 0x16940));
INSTALL_HOOK_DYNAMIC (copy_data, reinterpret_cast<LPVOID>(amHandle + 0x169D0));
auto amHandle = reinterpret_cast<uintptr_t> (GetModuleHandle ("AMFrameWork.dll"));
switch (version) {
case GameVersion::JP_NOV_2020: {
INSTALL_HOOK_DYNAMIC (qrInit, reinterpret_cast<LPVOID> (amHandle + 0x1BA00));
INSTALL_HOOK_DYNAMIC (qrRead, reinterpret_cast<LPVOID> (amHandle + 0x1BC20));
INSTALL_HOOK_DYNAMIC (qrClose, reinterpret_cast<LPVOID> (amHandle + 0x1BBD0));
INSTALL_HOOK_DYNAMIC (callQrUnknown, reinterpret_cast<LPVOID> (amHandle + 0xFD40));
// 08.18 has no Send1
INSTALL_HOOK_DYNAMIC (Send2, reinterpret_cast<LPVOID> (amHandle + 0x1C2D0));
INSTALL_HOOK_DYNAMIC (Send3, reinterpret_cast<LPVOID> (amHandle + 0x1C260));
INSTALL_HOOK_DYNAMIC (Send4, reinterpret_cast<LPVOID> (amHandle + 0x1C220));
INSTALL_HOOK_DYNAMIC (copy_data, reinterpret_cast<LPVOID> (amHandle + 0x1C2A0));
break;
}
case GameVersion::CN_JUN_2023: {
INSTALL_HOOK_DYNAMIC (qrInit, reinterpret_cast<LPVOID> (amHandle + 0x161B0));
INSTALL_HOOK_DYNAMIC (qrRead, reinterpret_cast<LPVOID> (amHandle + 0x163A0));
INSTALL_HOOK_DYNAMIC (qrClose, reinterpret_cast<LPVOID> (amHandle + 0x16350));
INSTALL_HOOK_DYNAMIC (callQrUnknown, reinterpret_cast<LPVOID> (amHandle + 0x8F60));
INSTALL_HOOK_DYNAMIC (Send1, reinterpret_cast<LPVOID> (amHandle + 0x16A30));
INSTALL_HOOK_DYNAMIC (Send2, reinterpret_cast<LPVOID> (amHandle + 0x16A00));
INSTALL_HOOK_DYNAMIC (Send3, reinterpret_cast<LPVOID> (amHandle + 0x16990));
INSTALL_HOOK_DYNAMIC (Send4, reinterpret_cast<LPVOID> (amHandle + 0x16940));
INSTALL_HOOK_DYNAMIC (copy_data, reinterpret_cast<LPVOID> (amHandle + 0x169D0));
break;
}
default: {
break;
}
}
}
} // namespace patches::Qr