Fix QRImage/QRData read error | add SceneChange hook | lua (not finished)

This commit is contained in:
ptmaster
2025-04-12 17:54:59 +08:00
parent 176451d38a
commit f594d34bf2
13 changed files with 411 additions and 322 deletions
+3 -1
View File
@@ -61,7 +61,7 @@ endif()
# Fetch zxing-cpp
FetchContent_Declare(
zxing_cpp
URL https://github.com/zxing-cpp/zxing-cpp/archive/refs/tags/v2.2.1.zip
URL https://github.com/zxing-cpp/zxing-cpp/archive/refs/tags/v2.3.0.zip
)
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(zxing_cpp)
@@ -171,6 +171,8 @@ set(SOURCES
src/patches/testmode.cpp
src/patches/timer.cpp
src/patches/language.cpp
src/patches/lua.cpp
src/patches/statusmonitor.cpp
# src/patches/unlimitsong.cpp
src/patches/versions/JPN00.cpp
src/patches/versions/JPN08.cpp
-113
View File
@@ -1,113 +0,0 @@
#include <iostream>
#include <regex>
#include "logger.h"
static Logger *loggerInstance = nullptr;
void *consoleHandle = nullptr;
std::mutex logMutex; // Mutex for thread-safe logging
char timeStr[64];
time_t rawTime;
tm *timeInfo;
SYSTEMTIME systemTime;
void
InitializeLogger (const LogLevel level, const bool logToFile, const std::string& logPath) {
if (loggerInstance == nullptr) {
loggerInstance = static_cast<Logger *> (malloc (sizeof (Logger)));
if (consoleHandle == nullptr) consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE);
}
loggerInstance->logLevel = level;
if (logToFile) {
loggerInstance->logFile = fopen (logPath.c_str (), "w"); // Open in write mode
if (!loggerInstance->logFile) LogMessage (LogLevel::WARN, std::string ("Failed to open TaikoArcadeLoader.log for writing."));
} else loggerInstance->logFile = nullptr; // No file logging
}
void
LogMessageHandler (const char *function, const char *codeFile, int codeLine, LogLevel messageLevel, const char *format, ...) {
// Return if no logger or log level is too high
if (loggerInstance == nullptr || messageLevel > loggerInstance->logLevel) return;
// Lock for thread safety
std::lock_guard lock (logMutex);
// Format the user-provided message
va_list args;
va_start (args, format);
int requiredSize = vsnprintf (nullptr, 0, format, args) + 1; // +1 for null terminator
std::unique_ptr<char[]> buffer (new char[requiredSize]); // Allocate buffer dynamically
vsnprintf (buffer.get (), requiredSize, format, args); // Format the string
std::string formattedMessage (buffer.get ()); // Convert to std::string
va_end (args);
// Determine log type string
std::string logType = GetLogLevelString (messageLevel);
// Shrink function name by regex
std::string short_function (function);
std::regex re(R"(.*? (([\w<>]+::)*[\w]+( [()<>+-]+)?)\(\w+.*?\))");
short_function = std::regex_replace (short_function, re, "$1");
// Remove the absolute path of the build dir
constexpr std::string_view build_dir = XSTRING (SOURCE_ROOT);
std::string_view filename = codeFile;
filename.remove_prefix (build_dir.size ());
// Get current time and milliseconds
SYSTEMTIME systemTime;
GetSystemTime (&systemTime);
time_t rawTime = time (nullptr);
tm *timeInfo = localtime (&rawTime);
std::ostringstream timeStamp;
timeStamp << std::put_time (timeInfo, "%Y/%m/%d %H:%M:%S") << "." << std::setw (3) << std::setfill ('0') << systemTime.wMilliseconds;
// Construct the log message
std::ostringstream logStream;
logStream << short_function << " (" << filename << ":" << codeLine << "): " << formattedMessage;
std::string logMessage = logStream.str ();
// Print the log message
std::cout << "[" << timeStamp.str () << "] "; // Timestamp
SetConsoleTextAttribute (consoleHandle, GetLogLevelColor (messageLevel)); // Set Level color
std::cout << logType; // Level
if (messageLevel != LogLevel::ERROR) {
SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); // Reset console color
}
std::cout << logMessage << std::endl; // Log message
if (messageLevel == LogLevel::ERROR) {
SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); // Reset console color
}
std::cout.flush (); // Flush to ensure immediate writing
if (loggerInstance->logFile != nullptr) {
fprintf (loggerInstance->logFile, "[%s] %s%s\n", timeStamp.str ().c_str (), logType.c_str (), logMessage.c_str ());
fflush (loggerInstance->logFile); // Flush to ensure immediate writing
}
}
void
LogMessageHandler (const char *function, const char *codeFile, const int codeLine, const LogLevel messageLevel, const wchar_t *format, ...) {
const std::string utf8Message = ConvertWideToUtf8 (format); // Convert wide string to UTF-8
va_list args;
va_start (args, format);
LogMessageHandler (function, codeFile, codeLine, messageLevel, utf8Message.c_str (), args); // Delegate to the original handler
va_end (args);
}
bool
EnableLogging (LogLevel messageLevel) {
return loggerInstance != nullptr && messageLevel <= loggerInstance->logLevel;
}
void
CleanupLogger () {
if (loggerInstance != nullptr) {
if (loggerInstance->logFile) fclose (loggerInstance->logFile);
free (loggerInstance);
loggerInstance = nullptr;
}
}
-123
View File
@@ -1,123 +0,0 @@
#pragma once
#include "helpers.h"
#include <source_location>
#include <string_view>
#include <format>
#include <wincon.h>
#define STRING(x) #x
#define XSTRING(x) STRING (x)
enum class LogLevel {
NONE = 0,
#ifdef ERROR
#undef ERROR
ERROR,
#endif
WARN,
INFO,
DEBUG,
HOOKS
};
/**
* Logger Struct Used to Store Logging Preferences and State
*/
typedef struct {
LogLevel logLevel;
FILE *logFile;
} Logger;
/* Initializes a global Logger instance. */
void InitializeLogger (LogLevel level, bool logToFile, const std::string& logPath);
void LogMessageHandler (const char *function, const char *codeFile, int codeLine, LogLevel messageLevel, const char *format, ...);
void LogMessageHandler (const char *function, const char *codeFile, int codeLine, LogLevel messageLevel, const wchar_t *format, ...);
bool EnableLogging (LogLevel level);
/* *
* Logs a message with file and line information, if the log level permits.
*
* Use template magic to replace macros and get proper typing support...
*/
template <typename... Args>
struct LogMessage {
LogMessage (const LogLevel level, const std::string_view format, Args &&...args,
const std::source_location &loc = std::source_location::current ()) {
if (!EnableLogging (level)) return;
std::string formatted_message = std::vformat(std::string(format), std::make_format_args(args...));
LogMessageHandler (loc.function_name (), loc.file_name (), loc.line (), level, formatted_message.c_str ());
}
LogMessage (const LogLevel level, const std::wstring_view format, Args &&...args,
const std::source_location &loc = std::source_location::current ()) {
if (!EnableLogging (level)) return;
std::wstring formatted_message = std::vformat(std::wstring(format), std::make_wformat_args(args...));
LogMessageHandler (loc.function_name (), loc.file_name (), loc.line (), level, formatted_message.c_str ());
}
};
/* *
* Logs a message with file and line information, if the log level permits.
*/
template <>
struct LogMessage<void> {
LogMessage (const LogLevel level, const std::string_view format, const std::source_location &loc = std::source_location::current ()) {
LogMessageHandler (loc.function_name (), loc.file_name (), loc.line (), level, format.data ());
}
LogMessage (const LogLevel level, const std::wstring_view format, const std::source_location &loc = std::source_location::current ()) {
LogMessageHandler (loc.function_name (), loc.file_name (), loc.line (), level, format.data ());
}
};
LogMessage (LogLevel level, std::string_view format) -> LogMessage<void>;
LogMessage (LogLevel level, std::wstring_view format) -> LogMessage<void>;
template <typename... Args>
LogMessage (LogLevel level, std::string_view format, Args &&...ts) -> LogMessage<Args...>;
template <typename... Args>
LogMessage (LogLevel level, std::wstring_view format, Args &&...ts) -> LogMessage<Args...>;
/* Converts a string to a LogLevel type. */
inline LogLevel
GetLogLevel (const std::string &logLevelStr) {
if (logLevelStr == "DEBUG") return LogLevel::DEBUG;
else if (logLevelStr == "INFO") return LogLevel::INFO;
else if (logLevelStr == "WARN") return LogLevel::WARN;
else if (logLevelStr == "ERROR") return LogLevel::ERROR;
else if (logLevelStr == "HOOKS") return LogLevel::HOOKS;
return LogLevel::NONE;
}
/* Converts a LogLevel type to a string for logging. */
inline std::string
GetLogLevelString (LogLevel messageLevel) {
switch (messageLevel) {
case LogLevel::DEBUG: return "DEBUG: ";
case LogLevel::INFO: return "INFO: ";
case LogLevel::WARN: return "WARN: ";
case LogLevel::ERROR: return "ERROR: ";
case LogLevel::HOOKS: return "HOOKS: ";
default: return "NONE: ";
}
}
/* Converts a LogLevel type to an int for colors display in the console. */
inline int
GetLogLevelColor (const LogLevel messageLevel) {
// Colors: https://i.sstatic.net/ZG625.png
switch (messageLevel) {
case LogLevel::DEBUG: return FOREGROUND_BLUE | FOREGROUND_INTENSITY; // Pale Blue
case LogLevel::INFO: return FOREGROUND_GREEN | FOREGROUND_INTENSITY; // Pale Green
case LogLevel::WARN: return FOREGROUND_RED | FOREGROUND_GREEN; // Bright Yellow
case LogLevel::ERROR: return FOREGROUND_RED; // Bright RED
case LogLevel::HOOKS: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY; // Pale Purple
default: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
}
/* Cleans up the logger, closing files if necessary. */
void CleanupLogger ();
+2 -2
View File
@@ -149,9 +149,9 @@ ConfigManager::updateQrConfig () {
return false;
}
auto result = rfl::toml::read<struct qrConfig, rfl::DefaultIfMissing> (stream);
auto result = rfl::toml::read<struct globalConfig, rfl::DefaultIfMissing> (stream);
if (result) {
config.qr = result.value ();
config.qr = result.value ().qr;
return true;
}
+36
View File
@@ -12,4 +12,40 @@ enum class GameVersion : XXH64_hash_t {
enum StatusType {
CardStatus = 1,
QrStatus = 2
};
enum SceneStatus {
SceneNone = -1,
SceneLoading = 0,
SceneTestMode,
SceneNotice,
SceneCopyright,
SceneBNLogo,
SceneTitle,
SceneAttractMovie,
SceneMusicIntro,
SceneCaution,
SceneEntry = 50,
SceneSelectAiEnso = 100,
SceneStartAiEnso,
SceneResultAiEnso,
SceneResultAllAiEnso,
SceneSelectKimetsu = 200,
SceneStartKimetsu,
SceneResultKimetsu,
SceneSelectOnePiece = 300,
SceneStartOnePiece,
SceneResultOnePiece,
SceneSelectAiSoshina = 400,
SceneStartAiSoshina,
SceneResultAiSoshina,
SceneSelectAoharu = 500,
SceneStartAoharu,
SceneResultAoharu,
SceneSelectEnso = 10000,
SceneStartEnso,
SceneResultEnso,
SceneSelectDani = 20000,
SceneStartDani,
SceneResultDani,
};
+2
View File
@@ -274,6 +274,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
case GameVersion::CHN00: patches::CHN00::Init (); break;
}
patches::Lua::Init ();
patches::Scanner::Init ();
patches::Audio::Init ();
// patches::Dxgi::Init ();
@@ -282,6 +283,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
patches::TestMode::Init ();
patches::LayeredFs::Init ();
// patches::UnlimitSong::Init ();
patches::StatusMonitor::Init ();
std::chrono::duration<double> duration = std::chrono::high_resolution_clock::now() - start;
LogMessage (LogLevel::DEBUG, "=== Finished Loading patches!");
+158
View File
@@ -0,0 +1,158 @@
#include "constants.h"
#include "helpers.h"
#include "patches.h"
namespace patches::Lua {
#define LUA_GLOBALSINDEX -10002
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
LuaState globalLuaState = 0;
FUNCTION_PTR (lua_CFunction, lua_atpanic, PROC_ADDRESS ("lua51.dll", "lua_atpanic"), LuaState, lua_CFunction);
FUNCTION_PTR (void, lua_call, PROC_ADDRESS ("lua51.dll", "lua_call"), LuaState, int, int);
FUNCTION_PTR (int, lua_checkstack, PROC_ADDRESS ("lua51.dll", "lua_checkstack"), LuaState, int);
FUNCTION_PTR (void, lua_concat, PROC_ADDRESS ("lua51.dll", "lua_concat"), LuaState, int);
FUNCTION_PTR (int, lua_cpcall, PROC_ADDRESS ("lua51.dll", "lua_cpcall"), LuaState, lua_CFunction, void *);
FUNCTION_PTR (void, lua_createtable, PROC_ADDRESS ("lua51.dll", "lua_createtable"), LuaState, int, int);
FUNCTION_PTR (int, lua_equal, PROC_ADDRESS ("lua51.dll", "lua_equal"), LuaState, int, int);
FUNCTION_PTR (int, lua_error, PROC_ADDRESS ("lua51.dll", "lua_error"), LuaState);
FUNCTION_PTR (void, lua_getfenv, PROC_ADDRESS ("lua51.dll", "lua_getfenv"), LuaState, int);
FUNCTION_PTR (void, lua_getfield, PROC_ADDRESS ("lua51.dll", "lua_getfield"), LuaState, int, const char *);
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
// FUNCTION_PTR (void, lua_getglobal, PROC_ADDRESS ("lua51.dll", "lua_getglobal"), LuaState, const char *);
FUNCTION_PTR (void, lua_getlocal, PROC_ADDRESS ("lua51.dll", "lua_getlocal"), LuaState, const char *);
FUNCTION_PTR (int, lua_getmetatable, PROC_ADDRESS ("lua51.dll", "lua_getmetatable"), LuaState, int);
FUNCTION_PTR (void, lua_gettable, PROC_ADDRESS ("lua51.dll", "lua_gettable"), LuaState, int);
FUNCTION_PTR (int, lua_gettop, PROC_ADDRESS ("lua51.dll", "lua_gettop"), LuaState);
FUNCTION_PTR (void, lua_insert, PROC_ADDRESS ("lua51.dll", "lua_gettop"), LuaState, int);
FUNCTION_PTR (int, lua_isboolean, PROC_ADDRESS ("lua51.dll", "lua_isboolean"), LuaState, int);
FUNCTION_PTR (int, lua_iscfunction, PROC_ADDRESS ("lua51.dll", "lua_iscfunction"), LuaState, int);
FUNCTION_PTR (int, lua_isfunction, PROC_ADDRESS ("lua51.dll", "lua_isfunction"), LuaState, int);
FUNCTION_PTR (int, lua_islightuserdata, PROC_ADDRESS ("lua51.dll", "lua_islightuserdata"), LuaState, int);
FUNCTION_PTR (int, lua_isnil, PROC_ADDRESS ("lua51.dll", "lua_isnil"), LuaState, int);
FUNCTION_PTR (int, lua_isnone, PROC_ADDRESS ("lua51.dll", "lua_isnone"), LuaState, int);
FUNCTION_PTR (int, lua_isnoneornil, PROC_ADDRESS ("lua51.dll", "lua_isnoneornil"), LuaState, int);
FUNCTION_PTR (int, lua_isnumber, PROC_ADDRESS ("lua51.dll", "lua_isnumber"), LuaState, int);
FUNCTION_PTR (int, lua_isstring, PROC_ADDRESS ("lua51.dll", "lua_isstring"), LuaState, int);
FUNCTION_PTR (int, lua_istable, PROC_ADDRESS ("lua51.dll", "lua_istable"), LuaState, int);
FUNCTION_PTR (int, lua_isthread, PROC_ADDRESS ("lua51.dll", "lua_isthread"), LuaState, int);
FUNCTION_PTR (int, lua_isuserdata, PROC_ADDRESS ("lua51.dll", "lua_isuserdata"), LuaState, int);
FUNCTION_PTR (int, lua_lessthan, PROC_ADDRESS ("lua51.dll", "lua_lessthan"), LuaState, int, int);
FUNCTION_PTR (void, lua_newtable, PROC_ADDRESS ("lua51.dll", "lua_newtable"), LuaState);
FUNCTION_PTR (LuaState, lua_newthread, PROC_ADDRESS ("lua51.dll", "lua_newthread"), LuaState);
FUNCTION_PTR (void *, lua_newuserdata, PROC_ADDRESS ("lua51.dll", "lua_newuserdata"), LuaState, size_t);
FUNCTION_PTR (int, lua_next, PROC_ADDRESS ("lua51.dll", "lua_next"), LuaState, int);
FUNCTION_PTR (size_t, lua_objlen, PROC_ADDRESS ("lua51.dll", "lua_objlen"), LuaState, int);
FUNCTION_PTR (int, lua_pcall, PROC_ADDRESS ("lua51.dll", "lua_pcall"), LuaState, int, int, int);
FUNCTION_PTR (void, lua_pop, PROC_ADDRESS ("lua51.dll", "lua_pop"), LuaState, int);
FUNCTION_PTR (void, lua_pushboolean, PROC_ADDRESS ("lua51.dll", "lua_pushboolean"), LuaState, int);
FUNCTION_PTR (void, lua_pushcclosure, PROC_ADDRESS ("lua51.dll", "lua_pushcclosure"), LuaState, lua_CFunction, int);
FUNCTION_PTR (void, lua_pushcfunction, PROC_ADDRESS ("lua51.dll", "lua_pushcfunction"), LuaState, lua_CFunction);
FUNCTION_PTR (const char *, lua_pushfstring, PROC_ADDRESS ("lua51.dll", "lua_pushfstring"), LuaState, const char *, ...);
FUNCTION_PTR (void, lua_pushinteger, PROC_ADDRESS ("lua51.dll", "lua_pushinteger"), LuaState, i64);
FUNCTION_PTR (void, lua_pushlightuserdata, PROC_ADDRESS ("lua51.dll", "lua_pushlightuserdata"), LuaState, void *);
FUNCTION_PTR (void, lua_pushliteral, PROC_ADDRESS ("lua51.dll", "lua_pushliteral"), LuaState, const char *);
FUNCTION_PTR (void, lua_pushlstring, PROC_ADDRESS ("lua51.dll", "lua_pushlstring"), LuaState, const char *, size_t);
FUNCTION_PTR (void, lua_pushnil, PROC_ADDRESS ("lua51.dll", "lua_pushnil"), LuaState);
FUNCTION_PTR (void, lua_pushnumber, PROC_ADDRESS ("lua51.dll", "lua_pushnumber"), LuaState, double);
FUNCTION_PTR (void, lua_pushstring, PROC_ADDRESS ("lua51.dll", "lua_pushstring"), LuaState, const char *);
FUNCTION_PTR (int, lua_pushthread, PROC_ADDRESS ("lua51.dll", "lua_pushthread"), LuaState);
FUNCTION_PTR (void, lua_pushvalue, PROC_ADDRESS ("lua51.dll", "lua_pushvalue"), LuaState, int);
FUNCTION_PTR (void, lua_pushvfstring, PROC_ADDRESS ("lua51.dll", "lua_pushvfstring"), LuaState, const char *, va_list);
FUNCTION_PTR (void, lua_rawget, PROC_ADDRESS ("lua51.dll", "lua_rawget"), LuaState, int);
FUNCTION_PTR (void, lua_rawgeti, PROC_ADDRESS ("lua51.dll", "lua_rawgeti"), LuaState, int, int);
FUNCTION_PTR (void, lua_rawset, PROC_ADDRESS ("lua51.dll", "lua_rawset"), LuaState, int);
FUNCTION_PTR (void, lua_rawseti, PROC_ADDRESS ("lua51.dll", "lua_rawseti"), LuaState, int, int);
FUNCTION_PTR (void, lua_remove, PROC_ADDRESS ("lua51.dll", "lua_remove"), LuaState, int);
FUNCTION_PTR (void, lua_replace, PROC_ADDRESS ("lua51.dll", "lua_replace"), LuaState, int);
FUNCTION_PTR (int, lua_resume, PROC_ADDRESS ("lua51.dll", "lua_resume"), LuaState, int);
FUNCTION_PTR (int, lua_setfenv, PROC_ADDRESS ("lua51.dll", "lua_setfenv"), LuaState, int);
FUNCTION_PTR (void, lua_setfield, PROC_ADDRESS ("lua51.dll", "lua_setfield"), LuaState, int, const char *);
FUNCTION_PTR (void, lua_setglobal, PROC_ADDRESS ("lua51.dll", "lua_setglobal"), LuaState, const char *);
FUNCTION_PTR (int, lua_setmetatable, PROC_ADDRESS ("lua51.dll", "lua_setmetatable"), LuaState, int);
FUNCTION_PTR (void, lua_settable, PROC_ADDRESS ("lua51.dll", "lua_settable"), LuaState, int);
FUNCTION_PTR (void, lua_settop, PROC_ADDRESS ("lua51.dll", "lua_settop"), LuaState, int);
FUNCTION_PTR (int, lua_status, PROC_ADDRESS ("lua51.dll", "lua_status"), LuaState);
FUNCTION_PTR (int, lua_toboolean, PROC_ADDRESS ("lua51.dll", "lua_toboolean"), LuaState, int);
FUNCTION_PTR (lua_CFunction, lua_tocfunction, PROC_ADDRESS ("lua51.dll", "lua_tocfunction"), LuaState, int);
FUNCTION_PTR (i64, lua_tointeger, PROC_ADDRESS ("lua51.dll", "lua_tointeger"), LuaState, int);
FUNCTION_PTR (const char *, lua_tolstring, PROC_ADDRESS ("lua51.dll", "lua_tolstring"), LuaState, int, size_t *);
FUNCTION_PTR (double, lua_tonumber, PROC_ADDRESS ("lua51.dll", "lua_tonumber"), LuaState, int);
FUNCTION_PTR (void *, lua_topointer, PROC_ADDRESS ("lua51.dll", "lua_topointer"), LuaState, int);
FUNCTION_PTR (const char *, lua_tostring, PROC_ADDRESS ("lua51.dll", "lua_tostring"), LuaState, int);
FUNCTION_PTR (LuaState, lua_tothread, PROC_ADDRESS ("lua51.dll", "lua_tothread"), LuaState, int);
FUNCTION_PTR (void *, lua_touserdata, PROC_ADDRESS ("lua51.dll", "lua_touserdata"), LuaState, int);
FUNCTION_PTR (int, lua_type, PROC_ADDRESS ("lua51.dll", "lua_type"), LuaState, int);
FUNCTION_PTR (const char *, lua_typename, PROC_ADDRESS ("lua51.dll", "lua_typename"), LuaState, int);
FUNCTION_PTR (i32, luaL_loadstring, PROC_ADDRESS ("lua51.dll", "luaL_loadstring"), i64, const char *);
FAST_HOOK (i64, luaL_newstate, PROC_ADDRESS ("lua51.dll", "luaL_newstate")) {
// LogMessage (LogLevel::INFO, "Lua::NewState");
globalLuaState = originalluaL_newstate.call<i64> ();
// LogMessage (LogLevel::INFO, "1");
// lua_getglobal (globalLuaState, "package");
// LogMessage (LogLevel::INFO, "2");
// lua_getfield (globalLuaState, -1, "path");
// LogMessage (LogLevel::INFO, "3");
// const char *path = lua_tostring(globalLuaState, -1);
// LogMessage (LogLevel::INFO, "4");
// lua_pop (globalLuaState, 2);
// LogMessage (LogLevel::INFO, "Lua package.path={}", path);
return globalLuaState;
}
#define LUA_MULTRET (-1)
#define luaL_dostring(L, s) (luaL_loadstring (L, s) || lua_pcall (L, 0, LUA_MULTRET, 0))
void
Init () {
INSTALL_FAST_HOOK (luaL_newstate);
}
void
Execute (std::string code) {
luaL_dostring (globalLuaState, code.c_str ());
}
void
RegisterMethod (std::string base, std::string methodName, lua_CFunction method) {
return; // WAIT IMPLEMENT
}
void
SetTop (i64 lua_State, i32 index) {
lua_settop (lua_State, index);
}
void
Replace (i64 lua_State, i32 index) {
lua_replace (lua_State, index);
}
void
PushCClosure (i64 lua_State, lua_CFunction func, i32 index) {
lua_pushcclosure (lua_State, func, index);
}
void
PushBoolean (i64 lua_State, bool value) {
lua_pushboolean (lua_State, value);
}
void
PushString (i64 lua_State, std::string value) {
lua_pushstring (lua_State, value.c_str());
}
bool
ToBoolean (i64 lua_State, i32 index) {
return lua_toboolean (lua_State, index);
}
const char *
ToLString (i64 lua_State, i32 index, size_t *size) {
return lua_tolstring(lua_State, index, size);
}
}
+29 -11
View File
@@ -95,24 +95,25 @@ void InitCardReader (CommitCardCallback touch);
void InitQRScanner (CommitQrCallback scan);
void InitQRLogin (CommitQrLoginCallback login);
void UpdateStatus (size_t type, bool status);
void UpdateScene (SceneStatus last, SceneStatus next);
// Plugins Loader
void LoadPlugins ();
} // namespace Plugins
namespace Scanner {
enum class State { Disable, Ready, CopyWait };
void Init ();
void Update ();
void Init ();
void Update ();
namespace Card {
typedef int32_t (*CallbackAttach) (int32_t, int32_t, int32_t *);
typedef void (*CallbackTouch) (int32_t, int32_t, uint8_t[168], uint64_t);
void Init ();
void Update ();
bool Commit (std::string accessCode, std::string chipId);
void Init ();
void Update ();
bool Commit (std::string accessCode, std::string chipId);
} // namespace Card
namespace Qr {
void Init ();
void Update ();
bool Commit (std::vector<uint8_t> &buffer);
void Init ();
void Update ();
bool Commit (std::vector<uint8_t> &buffer);
bool CommitLogin (std::string accessCode);
std::vector<uint8_t> &ReadQRData (std::vector<uint8_t> &buffer);
std::vector<uint8_t> &ReadQRImage (std::vector<uint8_t> &buffer);
@@ -135,9 +136,26 @@ typedef struct {
std::string text;
int fontType;
} WordInfo;
void Init ();
void SetupAccessor (u64 appAccessor, RefDataTableManager refDataTableManager);
void Init ();
void SetupAccessor (u64 appAccessor, RefDataTableManager refDataTableManager);
WordInfo *GetWordInfo (std::string &key);
void SetWordInfo (WordInfo *wordInfo);
void SetWordInfo (WordInfo *wordInfo);
}
namespace Lua {
typedef i64 LuaState;
typedef int (*lua_CFunction) (LuaState L);
void Init ();
void Execute (std::string code);
void RegisterMethod (std::string base, std::string methodName, std::function<lua_CFunction> method);
void SetTop (i64 lua_State, i32 index);
void Replace (i64 lua_State, i32 index);
void PushCClosure (i64 lua_State, lua_CFunction func, i32 index);
void PushBoolean (i64 lua_State, bool value);
void PushString (i64 lua_State, std::string value);
bool ToBoolean (i64 lua_State, i32 index);
const char *ToLString (i64 lua_State, i32 index, size_t *size);
} // namespace lua
namespace StatusMonitor {
void Init();
} // namespace StatusMonitor
} // namespace patches
+9
View File
@@ -16,6 +16,7 @@ namespace patches::Plugins {
typedef void (*SendQRScannerEvent) (CommitQrCallback scan);
typedef void (*SendQRLoginEvent) (CommitQrLoginCallback login);
typedef void (*StatusChangeEvent) (size_t type, bool status);
typedef void (*SceneChangeEvent) (SceneStatus last, SceneStatus next);
std::mutex updateMutex;
std::condition_variable updateCV;
@@ -84,6 +85,14 @@ namespace patches::Plugins {
if (event) ((StatusChangeEvent)event) (type, status);
}
}
void
UpdateScene (SceneStatus last, SceneStatus next) {
// printWarning ("Send UpdateScene last=%d next=%d", last, next);
for (auto plugin : plugins) {
auto event = GetProcAddress (plugin, "UpdateScene");
if (event) ((SceneChangeEvent)event) (last, next);
}
}
// Plugins Loader
void LoadPlugins () {
+4
View File
@@ -378,6 +378,8 @@ namespace Qr {
u16 type = Config::ConfigManager::instance ().getQrConfig ().data.type;
std::vector<int> songNoes = Config::ConfigManager::instance ().getQrConfig ().data.song_no;
LogMessage (LogLevel::INFO, "Read QRData, serial: {}", serial);
buffer.clear ();
std::vector<uint8_t> header = { 0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, (uint8_t)serial.size (), 0x01, 0x00 };
@@ -400,6 +402,8 @@ namespace Qr {
ReadQRImage (std::vector<uint8_t> &buffer) {
std::string imagePath = Config::ConfigManager::instance ().getQrConfig ().image_path;
LogMessage (LogLevel::INFO, "Read QRImage, pathpath: {}", imagePath);
buffer.clear ();
std::u8string u8PathStr (imagePath.begin (), imagePath.end ());
std::filesystem::path u8Path (u8PathStr);
+110
View File
@@ -0,0 +1,110 @@
#include "constants.h"
#include "helpers.h"
#include "patches.h"
extern GameVersion gameVersion;
namespace patches::StatusMonitor {
SceneStatus currentScene = SceneStatus::SceneNone;
#define DEFINE_SCENE(sceneName) \
typedef char (*sceneName) (i64 a1, i64 a2, i64 a3); \
SafetyHookInline original##sceneName; \
char implOf##sceneName (i64 a1, i64 a2, i64 a3) { \
char result = original##sceneName.fastcall <char>(a1, a2, a3); \
if (currentScene != SceneStatus::##sceneName) { \
LogMessage (LogLevel::INFO, "Switch to {}", #sceneName); \
Plugins::UpdateScene (currentScene, SceneStatus::##sceneName); \
currentScene = SceneStatus::##sceneName; \
} \
return result; \
}
// Attract
DEFINE_SCENE (SceneLoading)
DEFINE_SCENE (SceneTestMode)
DEFINE_SCENE (SceneNotice)
DEFINE_SCENE (SceneCopyright)
DEFINE_SCENE (SceneBNLogo)
DEFINE_SCENE (SceneTitle)
DEFINE_SCENE (SceneAttractMovie)
DEFINE_SCENE (SceneMusicIntro)
DEFINE_SCENE (SceneCaution)
// Entry
DEFINE_SCENE (SceneEntry)
// AiEnso
DEFINE_SCENE (SceneSelectAiEnso)
DEFINE_SCENE (SceneStartAiEnso)
DEFINE_SCENE (SceneResultAiEnso)
DEFINE_SCENE (SceneResultAllAiEnso)
// Kimetsu
DEFINE_SCENE (SceneSelectKimetsu)
DEFINE_SCENE (SceneStartKimetsu)
DEFINE_SCENE (SceneResultKimetsu)
// OnePiece
DEFINE_SCENE (SceneSelectOnePiece)
DEFINE_SCENE (SceneStartOnePiece)
DEFINE_SCENE (SceneResultOnePiece)
// AiSoshina
DEFINE_SCENE (SceneSelectAiSoshina)
DEFINE_SCENE (SceneStartAiSoshina)
DEFINE_SCENE (SceneResultAiSoshina)
// Aoharu
DEFINE_SCENE (SceneSelectAoharu)
DEFINE_SCENE (SceneStartAoharu)
DEFINE_SCENE (SceneResultAoharu)
// Enso
DEFINE_SCENE (SceneSelectEnso)
DEFINE_SCENE (SceneStartEnso)
DEFINE_SCENE (SceneResultEnso)
// Dani
DEFINE_SCENE (SceneSelectDani)
DEFINE_SCENE (SceneStartDani)
DEFINE_SCENE (SceneResultDani)
void Init() {
switch (gameVersion) {
case GameVersion::JPN39: {
// Attract
INSTALL_FAST_HOOK_DYNAMIC (SceneTestMode, ASLR (0x140479520));
INSTALL_FAST_HOOK_DYNAMIC (SceneCopyright, ASLR (0x140446B90));
INSTALL_FAST_HOOK_DYNAMIC (SceneBNLogo, ASLR (0x140433960));
INSTALL_FAST_HOOK_DYNAMIC (SceneTitle, ASLR (0x14045A4F0));
INSTALL_FAST_HOOK_DYNAMIC (SceneAttractMovie, ASLR (0x1404320C0));
INSTALL_FAST_HOOK_DYNAMIC (SceneMusicIntro, ASLR (0x1404572B0));
INSTALL_FAST_HOOK_DYNAMIC (SceneCaution, ASLR (0x140433E60));
// Entry
INSTALL_FAST_HOOK_DYNAMIC (SceneEntry, ASLR (0x14044EBD0));
// AiEnso
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectAiEnso, ASLR (0x140424E20));
INSTALL_FAST_HOOK_DYNAMIC (SceneStartAiEnso, ASLR (0x14040F7B0));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultAiEnso, ASLR (0x14041F130));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultAllAiEnso, ASLR (0x14041C900));
// Kimetsu
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectKimetsu, ASLR (0x140452DB0));
INSTALL_FAST_HOOK_DYNAMIC (SceneStartKimetsu, ASLR (0x14041B760));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultKimetsu, ASLR (0x140450020));
// OnePiece
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectOnePiece, ASLR (0x140436770));
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectOnePiece, ASLR (0x14041BA50));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultOnePiece, ASLR (0x140434940));
// AiSoshina
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectAiSoshina, ASLR (0x14043B3D0));
INSTALL_FAST_HOOK_DYNAMIC (SceneStartAiSoshina, ASLR (0x140410610));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultAiSoshina, ASLR (0x140439510));
// Aoharu
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectAoharu, ASLR (0x14042EA90));
INSTALL_FAST_HOOK_DYNAMIC (SceneStartAoharu, ASLR (0x14040FE50));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultAoharu, ASLR (0x14042DB00));
// Enso
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectEnso, ASLR (0x1404584C0));
INSTALL_FAST_HOOK_DYNAMIC (SceneStartEnso, ASLR (0x1404114E0));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultEnso, ASLR (0x140416760));
// Dani
INSTALL_FAST_HOOK_DYNAMIC (SceneSelectDani, ASLR (0x14044BBA0));
INSTALL_FAST_HOOK_DYNAMIC (SceneStartDani, ASLR (0x140410BA0));
INSTALL_FAST_HOOK_DYNAMIC (SceneResultDani, ASLR (0x1404478B0));
}
}
}
}
+9 -9
View File
@@ -28,14 +28,14 @@ HOOK (i32, HaspRead, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_read"), i32, i3
return 0;
}
FUNCTION_PTR (i64, lua_settop, PROC_ADDRESS ("lua51.dll", "lua_settop"), u64, u64);
FUNCTION_PTR (i64, lua_pushboolean, PROC_ADDRESS ("lua51.dll", "lua_pushboolean"), u64, u64);
FUNCTION_PTR (i64, lua_pushstring, PROC_ADDRESS ("lua51.dll", "lua_pushstring"), u64, u64);
// FUNCTION_PTR (i64, lua_settop, PROC_ADDRESS ("lua51.dll", "lua_settop"), u64, u64);
// FUNCTION_PTR (i64, lua_pushboolean, PROC_ADDRESS ("lua51.dll", "lua_pushboolean"), u64, u64);
// FUNCTION_PTR (i64, lua_pushstring, PROC_ADDRESS ("lua51.dll", "lua_pushstring"), u64, u64);
i64
lua_pushtrue (const i64 a1) {
lua_settop (a1, 0);
lua_pushboolean (a1, 1);
Lua::SetTop (a1, 0);
Lua::PushBoolean (a1, 1);
return 1;
}
@@ -60,14 +60,14 @@ HOOK (i64, GetLanguage, ASLR (0x140023720), i64 a1) {
}
HOOK (i64, GetRegionLanguage, ASLR (0x1401AC300), i64 a1) {
LogMessage (LogLevel::HOOKS, "GetRegionLanguage was called");
lua_settop (a1, 0);
lua_pushstring (a1, reinterpret_cast<u64> (languageStr (language)));
Lua::SetTop (a1, 0);
Lua::PushString (a1, languageStr (language));
return 1;
}
HOOK (i64, GetCabinetLanguage, ASLR (0x1401AF270), i64, i64 a2) {
LogMessage (LogLevel::HOOKS, "GetCabinetLanguage was called");
lua_settop (a2, 0);
lua_pushstring (a2, reinterpret_cast<u64> (languageStr (language)));
Lua::SetTop (a2, 0);
Lua::PushString (a2, languageStr (language));
return 1;
}
+49 -63
View File
@@ -29,28 +29,14 @@ FAST_HOOK_DYNAMIC (void, garmc_logger_log, i64 a1, int a2, void *a3, char a4) {
FUNCTION_PTR (i64, GetPlayDataManagerRef, ASLR (0x140024AC0), i64);
i64 lua_State = 0;
FAST_HOOK (i64, luaL_newstate, PROC_ADDRESS ("lua51.dll", "luaL_newstate")) { return lua_State = originalluaL_newstate.call<i64> (); }
FUNCTION_PTR (void, lua_settop, PROC_ADDRESS ("lua51.dll", "lua_settop"), i64, i32);
FUNCTION_PTR (void, lua_replace, PROC_ADDRESS ("lua51.dll", "lua_replace"), i64, i32);
FUNCTION_PTR (void, lua_pushcclosure, PROC_ADDRESS ("lua51.dll", "lua_pushcclosure"), i64, i64, i32);
FUNCTION_PTR (void, lua_pushboolean, PROC_ADDRESS ("lua51.dll", "lua_pushboolean"), i64, i32);
FUNCTION_PTR (const char *, lua_pushstring, PROC_ADDRESS ("lua51.dll", "lua_pushstring"), i64, const char *);
FUNCTION_PTR (i32, lua_toboolean, PROC_ADDRESS ("lua51.dll", "lua_toboolean"), i64, i32);
FUNCTION_PTR (const char *, lua_tolstring, PROC_ADDRESS ("lua51.dll", "lua_tolstring"), u64, i32, size_t *);
FUNCTION_PTR (i32, lua_pcall, PROC_ADDRESS ("lua51.dll", "lua_pcall"), i64, i32, i32, i32);
FUNCTION_PTR (i32, luaL_loadstring, PROC_ADDRESS ("lua51.dll", "luaL_loadstring"), i64, const char *);
#define LUA_MULTRET (-1)
#define luaL_dostring(L, s) (luaL_loadstring (L, s) || lua_pcall (L, 0, LUA_MULTRET, 0))
FUNCTION_PTR (u64, RefTestModeMain, ASLR (0x1400337C0), u64);
FUNCTION_PTR (u64, RefPlayDataManager, ASLR (0x140024AC0), u64);
FUNCTION_PTR (i64, GetUserCount, ASLR (0x1403F1080), u64);
i64
lua_pushbool (const i64 a1, const bool val) {
lua_settop (a1, 0);
lua_pushboolean (a1, val);
lua_pushbool (Lua::LuaState a1, const bool val) {
Lua::SetTop (a1, 0);
Lua::PushBoolean (a1, val);
return 1;
}
@@ -138,67 +124,67 @@ FAST_HOOK (i64, AvailableMode_AprilFool001, ASLR (0x1402DE5B0), i64 a1) {
return originalAvailableMode_AprilFool001.fastcall<i64> (a1);
}
TestMode::Value *freezeTimer = TestMode::CreateValue (L"ModFreezeTimer");
i64 __fastcall lua_freeze_timer (const i64 a1) {
int lua_freeze_timer (Lua::LuaState a1) {
LogMessage (LogLevel::HOOKS, "lua_freeze_timer was called");
const int tournamentMode = tournmentMode->Read ();
if (tournamentMode == 1) return lua_pushbool (a1, true);
if (tournamentMode == 1) return (int)lua_pushbool (a1, true);
const int status = freezeTimer-> Read ();
if (status == 1) return lua_pushbool (a1, true);
return lua_pushbool (a1, false);
if (status == 1) return (int)lua_pushbool (a1, true);
return (int)lua_pushbool (a1, false);
}
MID_HOOK (FreezeTimer, ASLR (0x14019FF51), SafetyHookContext &ctx) {
LogMessage (LogLevel::HOOKS, "FreezeTimer was called");
const auto a1 = ctx.rdi;
const int v9 = static_cast<int> (ctx.rax + 1);
lua_pushcclosure (a1, reinterpret_cast<i64> (&lua_freeze_timer), v9);
Lua::PushCClosure (a1, lua_freeze_timer, v9);
ctx.rip = ASLR (0x14019FF65);
}
void
ExecuteSendResultData () {
luaL_dostring(lua_State, R"(
local currentGameMode = PlayDataManager.GetPlayMode()
Lua::Execute(R"(
local currentGameMode = PlayDataManager.GetPlayMode()
if currentGameMode == GameMode.kEnso then
if g_entryType == 0 then
NetAccess.SendResultData(0)
elseif g_entryType == 1 then
NetAccess.SendResultData(1)
else
NetAccess.SendResultData(0)
NetAccess.SendResultData(1)
if currentGameMode == GameMode.kEnso then
if g_entryType == 0 then
NetAccess.SendResultData(0)
elseif g_entryType == 1 then
NetAccess.SendResultData(1)
else
NetAccess.SendResultData(0)
NetAccess.SendResultData(1)
end
elseif currentGameMode == GameMode.kAI then
if g_joinSide_ == 1 then
NetAccess.SendAiResultData(0)
elseif g_joinSide_ == 2 then
NetAccess.SendAiResultData(1)
end
elseif currentGameMode == GameMode.kCollabo025 then
if g_joinSide_ == 1 then
NetAccess.SendCollabo025AiResultData(0)
elseif g_joinSide_ == 2 then
NetAccess.SendCollabo025AiResultData(1)
end
elseif currentGameMode == GameMode.kCollabo026 then
if g_joinSide_ == 1 then
NetAccess.SendCollabo026AiResultData(0)
elseif g_joinSide_ == 2 then
NetAccess.SendCollabo026AiResultData(1)
end
elseif currentGameMode == GameMode.kAprilFool001 then
if g_entryType == 0 then
NetAccess.SendAprilFoolResultData(0)
elseif g_entryType == 1 then
NetAccess.SendAprilFoolResultData(1)
else
NetAccess.SendAprilFoolResultData(0)
NetAccess.SendAprilFoolResultData(1)
end
end
elseif currentGameMode == GameMode.kAI then
if g_joinSide_ == 1 then
NetAccess.SendAiResultData(0)
elseif g_joinSide_ == 2 then
NetAccess.SendAiResultData(1)
end
elseif currentGameMode == GameMode.kCollabo025 then
if g_joinSide_ == 1 then
NetAccess.SendCollabo025AiResultData(0)
elseif g_joinSide_ == 2 then
NetAccess.SendCollabo025AiResultData(1)
end
elseif currentGameMode == GameMode.kCollabo026 then
if g_joinSide_ == 1 then
NetAccess.SendCollabo026AiResultData(0)
elseif g_joinSide_ == 2 then
NetAccess.SendCollabo026AiResultData(1)
end
elseif currentGameMode == GameMode.kAprilFool001 then
if g_entryType == 0 then
NetAccess.SendAprilFoolResultData(0)
elseif g_entryType == 1 then
NetAccess.SendAprilFoolResultData(1)
else
NetAccess.SendAprilFoolResultData(0)
NetAccess.SendAprilFoolResultData(1)
end
end
QR.StartQRExecAll(SceneType.kResult)
)"
QR.StartQRExecAll(SceneType.kResult)
)"
);
}
@@ -340,7 +326,7 @@ Init () {
// Hook to get AppAccessor and ComponentAccessor
INSTALL_FAST_HOOK (DeviceCheck);
INSTALL_FAST_HOOK (luaL_newstate);
// INSTALL_FAST_HOOK (luaL_newstate);
// INSTALL_FAST_HOOK (AcquireMostCompatibleDisplayMode);
// Window Size