1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-22 11:51:27 +08:00

fix: ingame ui penetration

This commit is contained in:
0O0o0oOoO00
2025-09-08 19:35:50 +08:00
parent 409cddd6fc
commit 9861246fd8
2 changed files with 100 additions and 7 deletions

View File

@@ -13,6 +13,23 @@
#include "il2cpp.hpp"
#include "dobby.h"
extern ImVec2 g_window_pos;
extern ImVec2 g_window_size;
#define IMGUI_WND_EDGE 50
bool ImGui_IsPosInWnd(float x, float y) {
auto start_x = g_window_pos.x - IMGUI_WND_EDGE;
auto start_y = g_window_pos.y - IMGUI_WND_EDGE;
auto end_x = g_window_pos.x + g_window_size.x + IMGUI_WND_EDGE;
auto end_y = g_window_pos.y + g_window_size.y + IMGUI_WND_EDGE;
if (x >= start_x && x <= end_x && y >= start_y && y <= end_y) {
return true;
}
return false;
}
using eglSwapBuffers_fnT = EGLBoolean(EGLDisplay dpy, EGLSurface surface);
eglSwapBuffers_fnT* old_eglSwapBuffers = nullptr;
@@ -20,6 +37,7 @@ EGLint g_width = 0;
EGLint g_height = 0;
std::atomic<bool> g_imgui_started = false;
bool g_need_ui_penetration = false;
EGLBoolean my_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
ui_eglSwapBuffers(dpy, surface);
@@ -58,7 +76,7 @@ int64_t my_Input(void* thiz, void* ex_ab, void* ex_ac)
g_use_native_input.store(true);
}
if (g_imgui_started.load() && CrackerUI::get_instance().is_ui_showed()) {
if (g_imgui_started.load() && CrackerUI::get_instance().is_ui_showed() && g_need_ui_penetration) {
ImGui_ImplAndroid_HandleInputEvent((AInputEvent *) thiz);
}
@@ -88,7 +106,7 @@ int64_t my_Consume(void* thiz, int64_t arg1, char arg2, int64_t arg3, uint32_t*
g_use_native_input.store(true);
}
if (g_imgui_started.load() && CrackerUI::get_instance().is_ui_showed()) {
if (g_imgui_started.load() && CrackerUI::get_instance().is_ui_showed() && g_need_ui_penetration) {
ImGui_ImplAndroid_HandleInputEvent(*input_event);
}
@@ -106,7 +124,13 @@ bool has_hooked = false;
#define TOUCH_PHASE_ENDED 3
#define TOUCH_PHASE_CANCELED 4
void My_ImGui_ImplAndroid_HandleInputEvent(const UnityEngine_Touch_o& touch) {
int My_ImGui_ImplAndroid_HandleInputEvent(const UnityEngine_Touch_o& touch) {
auto x = touch.fields.m_Position.fields.x;
auto y = g_height - touch.fields.m_Position.fields.y;
if (!ImGui_IsPosInWnd(x, y)) {
return 1;
}
auto& io = ImGui::GetIO();
// SPDLOG_INFO("Touch (RawX = {}, RawY = {}), (X = {}, Y = {}), (DeltaX = {}, DeltaY = {})",
@@ -119,18 +143,18 @@ void My_ImGui_ImplAndroid_HandleInputEvent(const UnityEngine_Touch_o& touch) {
io.AddMouseSourceEvent(ImGuiMouseSource_TouchScreen);
switch(phase) {
case TOUCH_PHASE_BEGAN:
io.AddMousePosEvent(touch.fields.m_Position.fields.x, g_height - touch.fields.m_Position.fields.y);
io.AddMousePosEvent(x, y);
io.AddMouseButtonEvent(0, true);
io.AddMouseButtonEvent(1, true);
io.AddMouseButtonEvent(2, true);
break;
case TOUCH_PHASE_MOVED:
case TOUCH_PHASE_STATIONARY:
io.AddMousePosEvent(touch.fields.m_Position.fields.x, g_height - touch.fields.m_Position.fields.y);
io.AddMousePosEvent(x, y);
break;
case TOUCH_PHASE_ENDED:
case TOUCH_PHASE_CANCELED:
io.AddMousePosEvent(touch.fields.m_Position.fields.x, g_height - touch.fields.m_Position.fields.y);
io.AddMousePosEvent(x, y);
io.AddMouseButtonEvent(0, false);
io.AddMouseButtonEvent(1, false);
io.AddMouseButtonEvent(2, false);
@@ -138,12 +162,13 @@ void My_ImGui_ImplAndroid_HandleInputEvent(const UnityEngine_Touch_o& touch) {
default:
break;
}
return 0;
}
using GlobalClickEventMgr_HandlePinchOnTouch_fnT = void(void* thiz, UnityEngine_Touch_array* touches);
GlobalClickEventMgr_HandlePinchOnTouch_fnT* old_GlobalClickEventMgr_HandlePinchOnTouch = nullptr;
void my_GlobalClickEventMgr_HandlePinchOnTouch(void* thiz, UnityEngine_Touch_array* touches) {
if (touches != nullptr && !g_use_native_input.load() && g_imgui_started.load() && CrackerUI::get_instance().is_ui_showed()) {
if (touches != nullptr && !g_use_native_input.load() && g_imgui_started.load() && CrackerUI::get_instance().is_ui_showed() && g_need_ui_penetration) {
for(int i = 0; i < touches->max_length; i++) {
My_ImGui_ImplAndroid_HandleInputEvent(touches->m_Items[i]);
}
@@ -181,6 +206,56 @@ static GlobalClickEventMgr_HandlePinchOnTouch_fnT* get_GlobalClickEventMgr_Handl
return fn;
}
using UnityEngine_Input_GetTouch_fnT = UnityEngine_Touch_o*(UnityEngine_Touch_o* ret, int32_t index);
static UnityEngine_Input_GetTouch_fnT* get_UnityEngine_Input_GetTouch() {
static UnityEngine_Input_GetTouch_fnT* fn = []() {
Il2CppDomain* domain = il2cpp_domain_get();
size_t assembly_count = 0;
Il2CppAssembly** assemblies = il2cpp_domain_get_assemblies(domain, &assembly_count);
Il2CppClass* cls = nullptr;
for (size_t i = 0; i < assembly_count; ++i) {
Il2CppImage* image = il2cpp_assembly_get_image(assemblies[i]);
Il2CppClass* klass = il2cpp_class_from_name(image, "UnityEngine", "Input");
if (klass != nullptr) {
cls = klass;
break;
}
}
if (cls != nullptr) {
MethodInfo* method_info = il2cpp_class_get_method_from_name(cls, "GetTouch", 1);
if (method_info != nullptr) {
auto method = reinterpret_cast<UnityEngine_Input_GetTouch_fnT*>(method_info->methodPointer);
SPDLOG_INFO("Found UnityEngine.Input.GetTouch at {}", (void*)method_info->methodPointer);
return method;
}
}
SPDLOG_ERROR("Failed to get UnityEngine.Input.GetTouch");
throw std::runtime_error("Failed to get UnityEngine.Input.GetTouch");
}();
return fn;
}
UnityEngine_Input_GetTouch_fnT* old_UnityEngine_Input_GetTouch = nullptr;
UnityEngine_Touch_o* my_UnityEngine_Input_GetTouch(UnityEngine_Touch_o* ret, int32_t index) {
auto touch = old_UnityEngine_Input_GetTouch(ret, index);
if (g_imgui_started.load() && !g_need_ui_penetration && touch != nullptr) {
if (My_ImGui_ImplAndroid_HandleInputEvent(*touch) == 0) {
touch->fields.m_RawPosition.fields.x = 0;
touch->fields.m_RawPosition.fields.y = 0;
touch->fields.m_Position.fields.x = 0;
touch->fields.m_Position.fields.y = 0;
touch->fields.m_PositionDelta.fields.x = 0;
touch->fields.m_PositionDelta.fields.y = 0;
touch->fields.m_Phase = TOUCH_PHASE_CANCELED;
}
}
return touch;
}
void do_ui_hook() {
if (has_hooked) {
return;
@@ -197,6 +272,15 @@ void do_ui_hook() {
SPDLOG_INFO("Hook GlobalClickEventMgr.HandlePinchOnTouch failed: {}", dobby_hook_status);
}
dobby_hook_status = DobbyHook(
reinterpret_cast<void*>(get_UnityEngine_Input_GetTouch()),
reinterpret_cast<void*>(my_UnityEngine_Input_GetTouch),
reinterpret_cast<void**>(&old_UnityEngine_Input_GetTouch)
);
if (dobby_hook_status != 0) {
SPDLOG_INFO("Hook UnityEngine.Input.GetTouch failed: {}", dobby_hook_status);
}
has_hooked = true;
SPDLOG_INFO("Hook ingame ui done!");
}