#include #include #include "ui.hpp" #include "hook.hpp" #include "logger.hpp" #include "imgui/imgui.h" #include "imgui/imgui_impl_android.h" #include "imgui/imgui_impl_opengl3.h" #include "imgui/imgui_internal.h" #include "font.hpp" CrackerUI::CrackerUI() {} void CrackerUI::init(EGLint width, EGLint height) { if(m_has_inited) { return; } ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2((float) width, (float) height); ImGui_ImplOpenGL3_Init(); ImGui::StyleColorsDark(); io.Fonts->AddFontFromMemoryTTF( g_imgui_font_data, sizeof(g_imgui_font_data), m_font_size, nullptr, io.Fonts->GetGlyphRangesChineseFull() ); m_constrain_min = ImVec2(0, 0); m_constrain_max = ImVec2(width, height); m_has_inited = true; } #define CONFIG_FLAG(n) m_cracker_config.flag.n #define SHIP_PROPERTY(n) m_cracker_config.globle_ship_properties.n #define FILL_SHIP_PROPERTY(n) m_cracker_config.globle_ship_properties.n = m_all_ship_properties void CrackerUI::draw_menu() { ImGui::Begin("AzurLane Crack"); ImVec2 window_pos = ImGui::GetWindowPos(); ImVec2 window_size = ImGui::GetWindowSize(); ImVec2 new_pos = window_pos; new_pos.x = ImClamp(new_pos.x, m_constrain_min.x, m_constrain_max.x - window_size.x); new_pos.y = ImClamp(new_pos.y, m_constrain_min.y, m_constrain_max.y - window_size.y); if (new_pos.x != window_pos.x || new_pos.y != window_pos.y) { ImGui::SetWindowPos(new_pos); } ImGui::SameLine(); if(ImGui::Button("刷新")) { m_cracker_config = Cracker::Instance().get_config(); } ImGui::SameLine(); if(ImGui::Button("应用")) { Cracker::Instance().apply_config(m_cracker_config); } ImGui::SameLine(); if(ImGui::Button("关闭UI")) { m_is_show_ui.store(false); } if(ImGui::BeginTabBar("MainTab")) { if(ImGui::BeginTabItem("杂项")) { if(ImGui::BeginTable("MiscTable", 2)) { ImGui::TableNextColumn(); ImGui::Checkbox("章节图快速移动", &CONFIG_FLAG(FAST_STAGE_MOVE_CRACK)); ImGui::Checkbox("大世界快速移动", &CONFIG_FLAG(OPSI_FAST_MOVE)); ImGui::Checkbox("移除战列子弹时间", &CONFIG_FLAG(NO_BB_ANIMATION)); ImGui::Checkbox("移除低心情警告", &CONFIG_FLAG(NO_EMOTION_WARNING)); ImGui::Checkbox("跳过战斗胜利庆祝", &CONFIG_FLAG(SKIP_BATTLE_CELEBRATE)); ImGui::Checkbox("演习我方伤害增加 X %", &CONFIG_FLAG(EXERCISE_MORE_POWER)); ImGui::TableNextColumn(); ImGui::Checkbox("移除困难图属性限制", &CONFIG_FLAG(REMOVE_HARD_MODE_SHIP_PROPERTIES_LIMIT)); ImGui::Checkbox("移除困难图舰种限制", &CONFIG_FLAG(REMOVE_HARD_MODE_SHIP_TYPE_LIMIT)); ImGui::Checkbox("快速出怪", &CONFIG_FLAG(FAST_WAVE)); ImGui::Checkbox("怪自杀", &CONFIG_FLAG(MONSTER_KILL_SELF)); ImGui::Checkbox("无伤害无击杀", &CONFIG_FLAG(NO_DAMAGE)); ImGui::Checkbox("演习锁血", &CONFIG_FLAG(EXERCISE_GOD_MOD)); ImGui::EndTable(); } ImGui::DragInt("(%)##Exercise Power Rate", &m_cracker_config.exercise_more_power_rate); ImGui::EndTabItem(); } if(ImGui::BeginTabItem("倍率")) { ImGui::Checkbox("倍率##GG", &CONFIG_FLAG(GG_FACTOR)); ImGui::DragInt("##Factor Rate", &m_cracker_config.gg_factor); ImGui::Checkbox("修改属性", &CONFIG_FLAG(GLOBAL_SHIP_PROPERTIES_CRACK)); ImGui::SameLine(); if(ImGui::Button("填充")) { FILL_SHIP_PROPERTY(armor); FILL_SHIP_PROPERTY(speed); FILL_SHIP_PROPERTY(antiaircraft); FILL_SHIP_PROPERTY(oxy_recovery_bench); FILL_SHIP_PROPERTY(torpedo); FILL_SHIP_PROPERTY(hit); FILL_SHIP_PROPERTY(sonarRange); FILL_SHIP_PROPERTY(attack_duration); FILL_SHIP_PROPERTY(raid_distance); FILL_SHIP_PROPERTY(oxy_recovery_surface); FILL_SHIP_PROPERTY(oxy_recovery); FILL_SHIP_PROPERTY(dodge); FILL_SHIP_PROPERTY(luck); FILL_SHIP_PROPERTY(reload); FILL_SHIP_PROPERTY(oxy_cost); FILL_SHIP_PROPERTY(durability); FILL_SHIP_PROPERTY(air); FILL_SHIP_PROPERTY(oxy_max); FILL_SHIP_PROPERTY(cannon); FILL_SHIP_PROPERTY(antisub); } ImGui::SameLine(); ImGui::DragInt("##AllShipProperties", &m_all_ship_properties); if(ImGui::BeginTable("MiscTable", 2)) { ImGui::TableNextColumn(); ImGui::Text("装甲类型"); ImGui::DragInt("##Armor", &SHIP_PROPERTY(armor)); ImGui::Text("航速"); ImGui::DragInt("##Speed", &SHIP_PROPERTY(speed)); ImGui::Text("防空"); ImGui::DragInt("##AntiAircraft", &SHIP_PROPERTY(antiaircraft)); ImGui::Text("OxyRecoveryBench"); ImGui::DragInt("##OxyRecoveryBench", &SHIP_PROPERTY(oxy_recovery_bench)); ImGui::Text("雷击"); ImGui::DragInt("##Torpedo", &SHIP_PROPERTY(torpedo)); ImGui::Text("命中"); ImGui::DragInt("##Hit", &SHIP_PROPERTY(hit)); ImGui::Text("反潜范围"); ImGui::DragInt("##SonarRange", &SHIP_PROPERTY(sonarRange)); ImGui::Text("攻击间隔"); ImGui::DragInt("##AttackDuration", &SHIP_PROPERTY(attack_duration)); ImGui::Text("雷达范围"); ImGui::DragInt("##RaidDistance", &SHIP_PROPERTY(raid_distance)); ImGui::Text("OxyRecoverySurface"); ImGui::DragInt("##OxyRecoverySurface", &SHIP_PROPERTY(oxy_recovery_surface)); ImGui::TableNextColumn(); ImGui::Text("OxyRecovery"); ImGui::DragInt("##OxyRecovery", &SHIP_PROPERTY(oxy_recovery)); ImGui::Text("机动"); ImGui::DragInt("##Dodge", &SHIP_PROPERTY(dodge)); ImGui::Text("幸运"); ImGui::DragInt("##Luck", &SHIP_PROPERTY(luck)); ImGui::Text("装填"); ImGui::DragInt("##Reload", &SHIP_PROPERTY(reload)); ImGui::Text("氧气消耗"); ImGui::DragInt("##OxyCost", &SHIP_PROPERTY(oxy_cost)); ImGui::Text("耐久"); ImGui::DragInt("##Durability", &SHIP_PROPERTY(durability)); ImGui::Text("航空"); ImGui::DragInt("##Air", &SHIP_PROPERTY(air)); ImGui::Text("氧气"); ImGui::DragInt("##OxyMax", &SHIP_PROPERTY(oxy_max)); ImGui::Text("炮击"); ImGui::DragInt("##Cannon", &SHIP_PROPERTY(cannon)); ImGui::Text("反潜"); ImGui::DragInt("##AntiSub", &SHIP_PROPERTY(antisub)); ImGui::EndTable(); } ImGui::EndTabItem(); } if(ImGui::BeginTabItem("全局加速")) { ImGui::Checkbox("全局加速##Global Speedup", &CONFIG_FLAG(GLOBAL_SPEEDUP)); ImGui::InputInt("##Global Speedup Rate", &m_cracker_config.global_speedup_rate); ImGui::Checkbox("更好的全局加速", &CONFIG_FLAG(BETTER_GLOBAL_SPEEDUP)); ImGui::InputInt("##Better Global Speedup Rate", &m_cracker_config.better_global_speedup_rate); ImGui::EndTabItem(); } if(ImGui::BeginTabItem("设置")) { ImGui::Text("字体大小"); ImGui::InputFloat("##FontSizeRate", &m_font_size, 1.0, 1.0); ImGui::EndTabItem(); } ImGui::EndTabBar(); } ImGui::End(); } void CrackerUI::render_ui() { if (!m_is_show_ui.load()) { return; } ImGuiIO& io = ImGui::GetIO(); ImGui_ImplOpenGL3_NewFrame(); ImGui::NewFrame(); ImGui::PushFont(nullptr, m_font_size); draw_menu(); ImGui::PopFont(); ImGui::EndFrame(); ImGui::Render(); glViewport(0, 0, (int) io.DisplaySize.x, (int) io.DisplaySize.y); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); } void CrackerUI::show_ui() { m_is_show_ui.store(true); } void CrackerUI::close_ui() { m_is_show_ui.store(false); } CrackerUI& CrackerUI::get_instance() { static CrackerUI instance; return instance; } void ui_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { EGLint width, height; eglQuerySurface(dpy, surface, EGL_WIDTH, &width); eglQuerySurface(dpy, surface, EGL_HEIGHT, &height); auto& ui = CrackerUI::get_instance(); ui.init(width, height); ui.render_ui(); }