Update main.cpp

This commit is contained in:
gggaa2152 2026-07-25 11:47:45 +08:00 committed by GitHub
parent eee9cbb1b1
commit fddec6c12a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

174
main.cpp
View File

@ -595,6 +595,7 @@ func_req_refresh_t g_req_refresh = nullptr;
struct Vector3 { float x, y, z; };
// 增加 cellIndex 来记录是哪个格子(0-27场上, 28-36备战席)
struct LiveHeroData { int heroId; Vector3 worldPos; Vector3 screenPos; int equipCount; int cellIndex; };
struct DebugHeroTrace {
@ -652,6 +653,21 @@ std::atomic<int> g_ReadIdx{0};
std::atomic<bool> g_is_in_match{false};
uintptr_t g_il2cppBase = 0, g_debug_mgrObj = 0;
void* g_turnStartThisObj = nullptr;
void* g_hexCfgObj = nullptr;
int g_debug_TurnStartCalled = 0, g_debug_hook_3Cd6058_count = 0, g_debug_hook_set_Money_count = 0, g_debug_hook_set_Level_count = 0;
int g_debug_UpdateTurnStart_count = 0, g_debug_set_IsGameEnd_count = 0, g_debug_SendWillRenderCanvases_count = 0;
int g_debug_collected_players_count = 0, g_debug_hook_InitTurnDropCfg_count = 0, g_debug_bg_thread_count = 0;
int g_debug_hook_6A67e48_count = 0;
std::atomic<bool> g_collected_all_players{false};
std::atomic<bool> g_matchFetchRequested{false}, g_matchFetchReady{false};
std::chrono::steady_clock::time_point g_matchFetchTime;
std::atomic<uintptr_t> g_pool_entries1{0};
void PushSnapshot() {
int write_idx = g_WriteIdx.load(std::memory_order_relaxed);
int next_write = 1 - write_idx;
@ -665,21 +681,6 @@ const GameSnapshot* GetSnapshot() {
return &g_Snapshots[read_idx];
}
uintptr_t g_il2cppBase = 0, g_debug_mgrObj = 0;
void* g_turnStartThisObj = nullptr;
void* g_hexCfgObj = nullptr;
int g_debug_TurnStartCalled = 0, g_debug_hook_3Cd6058_count = 0, g_debug_hook_set_Money_count = 0, g_debug_hook_set_Level_count = 0;
int g_debug_UpdateTurnStart_count = 0, g_debug_set_IsGameEnd_count = 0, g_debug_SendWillRenderCanvases_count = 0;
int g_debug_collected_players_count = 0, g_debug_hook_InitTurnDropCfg_count = 0, g_debug_bg_thread_count = 0;
int g_debug_hook_6A67e48_count = 0;
int g_debug_hook_46cce08_count = 0;
std::atomic<bool> g_collected_all_players{false};
std::atomic<bool> g_matchFetchRequested{false}, g_matchFetchReady{false};
std::chrono::steady_clock::time_point g_matchFetchTime;
std::atomic<uintptr_t> g_pool_entries1{0};
// =================================================================
// 极速数学解析引擎
// =================================================================
@ -1214,6 +1215,7 @@ void UpdateEquipAndLiveHeroes() {
pos.y = SAFE_READ(float, battleUnit, g_off_battle_posx + 4, 0.0f);
pos.z = SAFE_READ(float, battleUnit, g_off_battle_posx + 8, 0.0f);
// 【彻底修复追踪线乱跳】:加上严格的野指针检测与边界过滤!
if (std::isnan(pos.x) || std::isnan(pos.y) || std::isnan(pos.z) ||
std::isinf(pos.x) || std::isinf(pos.y) || std::isinf(pos.z) ||
pos.y < -50.0f || pos.y > 200.0f ||
@ -1227,6 +1229,7 @@ void UpdateEquipAndLiveHeroes() {
try { screenPos = w2s((void*)g_BackendData.mainCamera, pos); } catch(...) {}
}
// 屏幕坐标过滤:摄像机背面(z<=0.01)或者转换失败的,直接丢弃
if (screenPos.z <= 0.01f || std::isnan(screenPos.x) || std::isnan(screenPos.y) || std::isinf(screenPos.x) || std::isinf(screenPos.y)) {
continue;
}
@ -2730,6 +2733,9 @@ void DrawEquipUIDebug() {
}
}
// ==========================================
// 【核心修复 3:新增装备席物理坐标透视】
// ==========================================
if (show_equip) {
for (int i = 0; i < 20; i++) {
int col = i / 10;
@ -2746,6 +2752,9 @@ void DrawEquipUIDebug() {
}
}
// ==========================================
// 1. 穿拆装备可视化 (各个格子独立偏移,深绿色)
// ==========================================
if (show_equip) {
if (allHeroData.empty()) {
if (g_cell_equip_offset.find(0) == g_cell_equip_offset.end()) g_cell_equip_offset[0] = ImVec2(0.0f, -80.0f);
@ -2767,6 +2776,7 @@ void DrawEquipUIDebug() {
d->AddCircle(targetPos, drawRadius + 1.5f, IM_COL32(0, 220, 0, 255), 0, 1.5f * g_autoScale);
d->AddText(font, 14.0f*g_autoScale, targetPos + ImVec2(drawRadius+2, -drawRadius-2), IM_COL32(0, 220, 0, 255), "格子0 穿装落点");
} else {
// 点击判定
if (!g_boardLocked && mouseClicked && dragging_idx == -1) {
for (const auto& hero : allHeroData) {
if (g_cell_equip_offset.find(hero.cellIndex) == g_cell_equip_offset.end()) g_cell_equip_offset[hero.cellIndex] = ImVec2(0.0f, -80.0f);
@ -2778,10 +2788,12 @@ void DrawEquipUIDebug() {
}
}
}
// 拖拽应用
if (mouseDown && dragging_idx == 0 && dragging_cell_idx != -1) {
g_cell_equip_offset[dragging_cell_idx].x = drag_start_off_x + (mouse.x - drag_start_mouse.x) / g_autoScale;
g_cell_equip_offset[dragging_cell_idx].y = drag_start_off_y + (mouse.y - drag_start_mouse.y) / g_autoScale;
}
// 渲染
std::unordered_set<int> drawn_cells;
for (const auto& hero : allHeroData) {
if (drawn_cells.count(hero.cellIndex)) continue;
@ -2800,11 +2812,15 @@ void DrawEquipUIDebug() {
}
}
// ==========================================
// 2. 卖出英雄可视化 (各个格子独立起点 -> 统一全局落点)
// ==========================================
if (show_sell) {
ImVec2 dropPos(g_sell_drop_x * g_autoScale, g_sell_drop_y * g_autoScale);
// 点击判定
if (!g_boardLocked && mouseClicked && dragging_idx == -1) {
if (ImLengthSqr(mouse - dropPos) < hitRadius * hitRadius) {
if (ImLengthSqr(mouse - dropPos) < hitRadius * hitRadius) { // 优先点红圈
dragging_idx = 2; drag_start_mouse = mouse;
drag_start_off_x = g_sell_drop_x; drag_start_off_y = g_sell_drop_y;
} else {
@ -2818,6 +2834,7 @@ void DrawEquipUIDebug() {
}
}
}
// 假人补充逻辑
if (dragging_idx == -1 && allHeroData.empty()) {
if (g_cell_sell_offset.find(0) == g_cell_sell_offset.end()) g_cell_sell_offset[0] = ImVec2(0.0f, -80.0f);
ImVec2 grabPos(dummyX + g_cell_sell_offset[0].x * g_autoScale, dummyY + g_cell_sell_offset[0].y * g_autoScale);
@ -2827,17 +2844,19 @@ void DrawEquipUIDebug() {
}
}
// 拖动计算
if (mouseDown) {
if (dragging_idx == 1 && dragging_cell_idx != -1) {
if (dragging_idx == 1 && dragging_cell_idx != -1) { // 拖动独立格子起滑点
g_cell_sell_offset[dragging_cell_idx].x = drag_start_off_x + (mouse.x - drag_start_mouse.x) / g_autoScale;
g_cell_sell_offset[dragging_cell_idx].y = drag_start_off_y + (mouse.y - drag_start_mouse.y) / g_autoScale;
} else if (dragging_idx == 2) {
} else if (dragging_idx == 2) { // 拖动全局落点
g_sell_drop_x = drag_start_off_x + (mouse.x - drag_start_mouse.x) / g_autoScale;
g_sell_drop_y = drag_start_off_y + (mouse.y - drag_start_mouse.y) / g_autoScale;
dropPos = ImVec2(g_sell_drop_x * g_autoScale, g_sell_drop_y * g_autoScale);
}
}
// 渲染假人
if (allHeroData.empty()) {
ImVec2 grabPos(dummyX + g_cell_sell_offset[0].x * g_autoScale, dummyY + g_cell_sell_offset[0].y * g_autoScale);
d->AddCircleFilled(ImVec2(dummyX, dummyY), 4.0f * g_autoScale, IM_COL32(255,255,255,150));
@ -2847,10 +2866,12 @@ void DrawEquipUIDebug() {
d->AddText(font, 14.0f*g_autoScale, grabPos + ImVec2(drawRadius+2, -drawRadius-2), IM_COL32(220, 50, 220, 255), "格子0卖出起滑");
}
// 画单一落点 (深红圈)
d->AddCircleFilled(dropPos, drawRadius * 1.5f, IM_COL32(180, 0, 0, 230));
d->AddCircle(dropPos, drawRadius * 1.5f + 1.5f, IM_COL32(255, 50, 50, 255), 0, 2.0f * g_autoScale);
d->AddText(font, 14.0f*g_autoScale, dropPos + ImVec2(drawRadius*1.5f+2, -drawRadius*1.5f-2), IM_COL32(255, 50, 50, 255), "全局卖出落点");
// 渲染所有真实英雄独立格子起滑点 (深紫圈) 及连线
std::unordered_set<int> drawn_cells;
for (const auto& hero : allHeroData) {
if (drawn_cells.count(hero.cellIndex)) continue;
@ -4122,7 +4143,7 @@ void DrawCardPool(const GameSnapshot* snap) {
void DrawDebugWindow(const GameSnapshot* snap) {
if (!snap || !g_show_debug_window) return;
ImGui::SetNextWindowSize(ImVec2(550 * g_autoScale, 650 * g_autoScale), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(550 * g_autoScale, 600 * g_autoScale), ImGuiCond_FirstUseEver);
if (ImGui::Begin((const char*)u8"调试日志 & 全功能偏移链监控", &g_show_debug_window)) {
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.5f, 1.0f), (const char*)u8"当前渲染帧率 (FPS): %.1f", ImGui::GetIO().Framerate);
@ -4130,121 +4151,6 @@ void DrawDebugWindow(const GameSnapshot* snap) {
if (ImGui::BeginTabBar("DebugTabs")) {
if (ImGui::BeginTabItem((const char*)u8"Hook调用统计")) {
ImGui::BeginChild("HookCountScroll", ImVec2(0, 0), true);
ImGui::TextColored(ImVec4(1, 0.8f, 0.2f, 1), (const char*)u8"【引擎/线程存活状态】");
ImGui::Text("Background Update Thread: %d", g_debug_bg_thread_count);
ImGui::Text("SendWillRenderCanvases (UI): %d", g_debug_SendWillRenderCanvases_count);
ImGui::Separator();
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.5f, 1), (const char*)u8"【业务 Hook 触发次数】");
ImGui::Text("TurnStart (回合开始): %d", g_debug_TurnStartCalled);
ImGui::Text("UpdateTurnStart (回合状态): %d", g_debug_UpdateTurnStart_count);
ImGui::Text("set_IsGameEnd (对局结束): %d", g_debug_set_IsGameEnd_count);
ImGui::Text("InitTurnDropCfg (海克斯): %d", g_debug_hook_InitTurnDropCfg_count);
ImGui::Text("hook_6A67e48 (牌库拦截): %d", g_debug_hook_6A67e48_count);
ImGui::Separator();
ImGui::TextColored(ImVec4(0.5f, 0.8f, 1.0f, 1), (const char*)u8"【玩家属性同步次数】");
ImGui::Text("hook_3Cd6058 (RowIdx): %d", g_debug_hook_3Cd6058_count);
ImGui::Text("hook_set_Money (金币): %d", g_debug_hook_set_Money_count);
ImGui::Text("hook_set_Level (等级): %d", g_debug_hook_set_Level_count);
ImGui::EndChild();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem((const char*)u8"偏移链实时监控")) {
ImGui::BeginChild("PtrScroll", ImVec2(0,0), true);
auto PrintPtr = [](const char* name, uintptr_t ptr, int offset = -1) {
if (offset != -1) {
if (ptr == 0) ImGui::TextColored(ImVec4(1, 0.3f, 0.3f, 1), "%s [+0x%X]: 0x0 (断链!)", name, offset);
else ImGui::Text("%s [+0x%X]: 0x%lX", name, offset, ptr);
} else {
if (ptr == 0) ImGui::TextColored(ImVec4(1, 0.3f, 0.3f, 1), "%s: 0x0", name);
else ImGui::Text("%s: 0x%lX", name, ptr);
}
};
ImGui::TextColored(ImVec4(0, 1, 1, 1), (const char*)u8"【全局基础】");
ImGui::Text("il2cppBase: 0x%lX", g_il2cppBase);
ImGui::Text("ChessBattleModel: 0x%lX", snap->chessBattleModel);
ImGui::Text("MyPlayerId: %d", snap->myPlayerId);
auto myIt = snap->players.find(snap->myPlayerId);
if (snap->myPlayerId != -1 && myIt != snap->players.end()) {
uintptr_t myObj = myIt->second.objAddr;
uintptr_t myLogicObj = myIt->second.logicObjAddr;
ImGui::Separator();
ImGui::TextColored(ImVec4(1, 0.5f, 0.5f, 1), (const char*)u8"【商店偏移链 (Shop Entries)】");
PrintPtr("PlayerObj", myObj);
uintptr_t pBase = SAFE_READ_PTR(myObj, g_off_shop_base);
PrintPtr("ShopBase", pBase, g_off_shop_base);
uintptr_t p20 = SAFE_READ_PTR(pBase, g_off_shop_p20);
PrintPtr("p20", p20, g_off_shop_p20);
uintptr_t entries = SAFE_READ_PTR(p20, g_off_shop_entries);
PrintPtr("Entries", entries, g_off_shop_entries);
if (IsValidPtr(entries)) {
int count = SAFE_READ(int, entries, g_off_entries_count, 0);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.8f, 1), " -> Count (+0x%X): %d", g_off_entries_count, count);
}
ImGui::Separator();
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.5f, 1), (const char*)u8"【英雄实体偏移链 (Hero Array)】");
PrintPtr("LogicObj", myLogicObj);
uintptr_t dyn2b0 = SAFE_READ_PTR(myLogicObj, g_off_hero_dyn);
PrintPtr("HeroDyn", dyn2b0, g_off_hero_dyn);
uintptr_t heroArr = SAFE_READ_PTR(dyn2b0, g_off_hero_arr);
PrintPtr("HeroArray", heroArr, g_off_hero_arr);
if (IsValidPtr(heroArr)) {
int hCount = SAFE_READ(int, heroArr, g_off_hero_count, 0);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.8f, 1), " -> HeroCount (+0x%X): %d", g_off_hero_count, hCount);
}
ImGui::Separator();
ImGui::TextColored(ImVec4(1, 0.8f, 0.2f, 1), (const char*)u8"【装备偏移链 (Equip Array)】");
uintptr_t eqBase = SAFE_READ_PTR(myLogicObj, g_off_equip_base);
PrintPtr("EquipBase", eqBase, g_off_equip_base);
uintptr_t eqArr = SAFE_READ_PTR(eqBase, g_off_equip_arr);
PrintPtr("EquipArray", eqArr, g_off_equip_arr);
if (IsValidPtr(eqArr)) {
int eqCount = SAFE_READ(int, eqArr, g_off_equip_count, 0);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.8f, 1), " -> EquipCount (+0x%X): %d", g_off_equip_count, eqCount);
}
} else {
ImGui::Separator();
ImGui::TextColored(ImVec4(1, 0.3f, 0.3f, 1), (const char*)u8"未获取到本地玩家对象(PlayerObj/LogicObj)!");
}
ImGui::Separator();
ImGui::TextColored(ImVec4(0.8f, 0.4f, 1.0f, 1), (const char*)u8"【牌库池偏移链 (Card Pool)】");
uintptr_t pEntries1 = g_pool_entries1.load(std::memory_order_acquire);
PrintPtr("pool_entries1 (Hook)", pEntries1);
if (IsValidPtr(pEntries1)) {
int e1Count = SAFE_READ(int, pEntries1, g_off_pool_e1_count, 0);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.8f, 1), " -> E1 Count (+0x%X): %d", g_off_pool_e1_count, e1Count);
if (e1Count > 0) {
uintptr_t entry1_ptr = pEntries1 + g_off_pool_e1_head;
PrintPtr(" -> First E1 Addr", entry1_ptr, g_off_pool_e1_head);
uintptr_t value1 = SAFE_READ_PTR(entry1_ptr, g_off_pool_e1_val);
PrintPtr(" -> E1 Value", value1, g_off_pool_e1_val);
uintptr_t entries2 = SAFE_READ_PTR(value1, g_off_pool_entries2);
PrintPtr(" -> Entries2", entries2, g_off_pool_entries2);
if (IsValidPtr(entries2)) {
int e2Count = SAFE_READ(int, entries2, g_off_pool_e2_count, 0);
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.8f, 1), " -> E2 Count (+0x%X): %d", g_off_pool_e2_count, e2Count);
}
}
} else {
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1), (const char*)u8"尚未截获到 pool_entries1");
}
ImGui::EndChild();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem((const char*)u8"3D追踪与装备偏移调试")) {
auto InputHex = [](const char* label, int* v) {
int step = 1, step_fast = 16;