#include <android/log.h>
#include <unistd.h>
#include <thread>
#include <limits>
#include <string>
#include <ctime>
#include <sstream>
#include <iomanip>
#include <vector>

#include <xdl.h>
#include <KittyUtils.h>
#include <KittyMemory.h>
#include <Il2Cpp.h>
#include <ImguiPP.h>
#include <Themes.h>
#include <fstream>
#include <SubstrateHook.h>
#include <CydiaSubstrate.h>
#include "Struct/Gui.hpp"
#include <Struct/main.h>
#include "fonts/FontAwesome6_solid.h"
#include "ImGui/Toggle.h"
#include "exptime.h"
#include "Expirey.h"
#include "KittyMemory/MemoryPatch.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
//#include "mkop.h"
#include "how.h"
#include "bijay.h"
#include "plane.h"
#include "setting.h"


static int bijaytab = 1;
static uintptr_t getModuleBaseAddress(const char* moduleName) {
    FILE* f = fopen("/proc/self/maps", "r");
    if (!f) return 0;

    char line[512];
    uintptr_t base = 0;
    while (fgets(line, sizeof(line), f)) {
        // line example: "7f6b1e0000-7f6b1f0000 r-xp 00000000 08:02 12345 /system/lib/libil2cpp.so"
        if (strstr(line, moduleName)) {
            // parse start address before '-' (hex)
            char* p = strtok(line, "-");
            if (p) {
                base = (uintptr_t)strtoull(p, NULL, 16);
            }
            break;
        }
    }
    fclose(f);
    return base;
}

// returns 0 on failure
static uintptr_t getAbsoluteAddress(const char* moduleName, uintptr_t offset) {
    uintptr_t base = getModuleBaseAddress(moduleName);
    if (!base) return 0;
    return base + offset;
}

bool bypass;


bool isAxlBypassEnabled() {

    FILE* f = fopen("/sdcard/Axl_orignal_apk_block", "r");
    if (f) {
        fclose(f);
        return true; 
    }
    return false;
}





void hack_thread();

// Correct entry point for a standard native library
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    // Store the JavaVM pointer
    jvm = vm;

    // Start the main hack thread
    std::thread(hack_thread).detach();

    return JNI_VERSION_1_6;
}

void (*OpenURL)(String *url);

//========BYPASS========\\


void(*Bypass1)(void* _this);
void _Bypass1(void* _this) {
    return;
}

void(*Bypass2)(void* _this);
void _Bypass2(void* _this) {
    return;
}

// ========================= \\

uintptr_t il2cpp_base = 0;
void *getRealAddr(ulong offset) {
    return reinterpret_cast<void*>(il2cpp_base + offset);
};

namespace Settings {
    static int Tab = 1;
}

bool clearMousePos = true;
bool initImGui = false;
bool isLoggedIn = true; // Add this line to track login state

// User information structure
struct UserInfo {
    std::string username;
    std::string createdBy;
    std::string expiry;
    std::string deviceType;
    std::string hwid;
    std::string hwid2; // Second HWID for double devices
    std::string recordId;
    std::string accountType;
    std::string creatorAccountType; // Store creator's account type
};

UserInfo currentUserInfo;

// AIRTABLE SERVER-BASED AUTHENTICATION SYSTEM USING JNI
const std::string AIRTABLE_TOKEN = "pat4gvRoA8gPAI4Wz.8ce9f7894a41c341e0c825838acda4962a056d22e0cac8111ed52c3f8f488fe6";
const std::string AIRTABLE_BASE_URL = "https://api.airtable.com/v0/appyns7Hg147GniSq/tbls64uNeAgvXrZge";

// JNI-based HTTP request function
std::string makeHttpRequest(const std::string& url, const std::string& authToken) {
    if (!jvm) return "";
    
    JNIEnv* env = nullptr;
    jvm->AttachCurrentThread(&env, nullptr);
    if (!env) return "";
    
    try {
        // Get URL class
        jclass urlClass = env->FindClass("java/net/URL");
        if (!urlClass) {
            jvm->DetachCurrentThread();
            return "";
        }
        
        // Create URL object
        jmethodID urlConstructor = env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
        jstring jUrl = env->NewStringUTF(url.c_str());
        jobject urlObject = env->NewObject(urlClass, urlConstructor, jUrl);
        
        // Open connection
        jmethodID openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
        jobject connection = env->CallObjectMethod(urlObject, openConnectionMethod);
        
        // Cast to HttpURLConnection
        jclass httpConnectionClass = env->FindClass("java/net/HttpURLConnection");
        
        // Set request method to GET
        jmethodID setRequestMethodMethod = env->GetMethodID(httpConnectionClass, "setRequestMethod", "(Ljava/lang/String;)V");
        jstring getMethod = env->NewStringUTF("GET");
        env->CallVoidMethod(connection, setRequestMethodMethod, getMethod);
        
        // Set Authorization header
        jmethodID setRequestPropertyMethod = env->GetMethodID(httpConnectionClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
        jstring authHeaderName = env->NewStringUTF("Authorization");
        std::string authHeaderValue = "Bearer " + authToken;
        jstring authHeaderVal = env->NewStringUTF(authHeaderValue.c_str());
        env->CallVoidMethod(connection, setRequestPropertyMethod, authHeaderName, authHeaderVal);
        
        // Set Content-Type header
        jstring contentTypeHeader = env->NewStringUTF("Content-Type");
        jstring contentTypeValue = env->NewStringUTF("application/json");
        env->CallVoidMethod(connection, setRequestPropertyMethod, contentTypeHeader, contentTypeValue);
        
        // Get response code
        jmethodID getResponseCodeMethod = env->GetMethodID(httpConnectionClass, "getResponseCode", "()I");
        jint responseCode = env->CallIntMethod(connection, getResponseCodeMethod);
        
        if (responseCode != 200) {
            LOGD("HTTP request failed with code: %d", responseCode);
            jvm->DetachCurrentThread();
            return "";
        }
        
        // Get input stream
        jmethodID getInputStreamMethod = env->GetMethodID(httpConnectionClass, "getInputStream", "()Ljava/io/InputStream;");
        jobject inputStream = env->CallObjectMethod(connection, getInputStreamMethod);
        
        // Read response
        jclass inputStreamClass = env->FindClass("java/io/InputStream");
        jmethodID readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
        
        std::string response = "";
        jbyteArray buffer = env->NewByteArray(1024);
        jint bytesRead;
        
        while ((bytesRead = env->CallIntMethod(inputStream, readMethod, buffer)) > 0) {
            jbyte* bytes = env->GetByteArrayElements(buffer, nullptr);
            response.append(reinterpret_cast<char*>(bytes), bytesRead);
            env->ReleaseByteArrayElements(buffer, bytes, JNI_ABORT);
        }
        
        // Close input stream
        jmethodID closeMethod = env->GetMethodID(inputStreamClass, "close", "()V");
        env->CallVoidMethod(inputStream, closeMethod);
        
        // Disconnect
        jmethodID disconnectMethod = env->GetMethodID(httpConnectionClass, "disconnect", "()V");
        env->CallVoidMethod(connection, disconnectMethod);
        
        jvm->DetachCurrentThread();
        return response;
        
    } catch (...) {
        LOGD("Exception in HTTP request");
        jvm->DetachCurrentThread();
        return "";
    }
}

// Generate secure device HWID with multiple identifiers
std::string generateHWID() {
    if (!jvm) return "";
    
    JNIEnv* env = nullptr;
    jvm->AttachCurrentThread(&env, nullptr);
    if (!env) return "";
    
    try {
        std::string hwid = "";
        
        // Get Build class for hardware info
        jclass buildClass = env->FindClass("android/os/Build");
        if (buildClass) {
            // Get multiple hardware identifiers
            jfieldID serialField = env->GetStaticFieldID(buildClass, "SERIAL", "Ljava/lang/String;");
            jfieldID modelField = env->GetStaticFieldID(buildClass, "MODEL", "Ljava/lang/String;");
            jfieldID manufacturerField = env->GetStaticFieldID(buildClass, "MANUFACTURER", "Ljava/lang/String;");
            jfieldID boardField = env->GetStaticFieldID(buildClass, "BOARD", "Ljava/lang/String;");
            jfieldID brandField = env->GetStaticFieldID(buildClass, "BRAND", "Ljava/lang/String;");
            jfieldID deviceField = env->GetStaticFieldID(buildClass, "DEVICE", "Ljava/lang/String;");
            jfieldID hardwareField = env->GetStaticFieldID(buildClass, "HARDWARE", "Ljava/lang/String;");
            jfieldID productField = env->GetStaticFieldID(buildClass, "PRODUCT", "Ljava/lang/String;");
            
            jstring serialStr = (jstring)env->GetStaticObjectField(buildClass, serialField);
            jstring modelStr = (jstring)env->GetStaticObjectField(buildClass, modelField);
            jstring manufacturerStr = (jstring)env->GetStaticObjectField(buildClass, manufacturerField);
            jstring boardStr = (jstring)env->GetStaticObjectField(buildClass, boardField);
            jstring brandStr = (jstring)env->GetStaticObjectField(buildClass, brandField);
            jstring deviceStr = (jstring)env->GetStaticObjectField(buildClass, deviceField);
            jstring hardwareStr = (jstring)env->GetStaticObjectField(buildClass, hardwareField);
            jstring productStr = (jstring)env->GetStaticObjectField(buildClass, productField);
            
            const char* serial = env->GetStringUTFChars(serialStr, 0);
            const char* model = env->GetStringUTFChars(modelStr, 0);
            const char* manufacturer = env->GetStringUTFChars(manufacturerStr, 0);
            const char* board = env->GetStringUTFChars(boardStr, 0);
            const char* brand = env->GetStringUTFChars(brandStr, 0);
            const char* device = env->GetStringUTFChars(deviceStr, 0);
            const char* hardware = env->GetStringUTFChars(hardwareStr, 0);
            const char* product = env->GetStringUTFChars(productStr, 0);
            
            // Create comprehensive HWID
            hwid = std::string(manufacturer) + "|" + std::string(brand) + "|" + 
                   std::string(model) + "|" + std::string(device) + "|" + 
                   std::string(board) + "|" + std::string(hardware) + "|" + 
                   std::string(product) + "|" + std::string(serial);
            
            env->ReleaseStringUTFChars(serialStr, serial);
            env->ReleaseStringUTFChars(modelStr, model);
            env->ReleaseStringUTFChars(manufacturerStr, manufacturer);
            env->ReleaseStringUTFChars(boardStr, board);
            env->ReleaseStringUTFChars(brandStr, brand);
            env->ReleaseStringUTFChars(deviceStr, device);
            env->ReleaseStringUTFChars(hardwareStr, hardware);
            env->ReleaseStringUTFChars(productStr, product);
        }
        
        // Get additional system identifiers
        jclass systemClass = env->FindClass("android/provider/Settings$Secure");
        if (systemClass) {
            // Get Android ID
            jmethodID getStringMethod = env->GetStaticMethodID(systemClass, "getString", 
                "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;");
            
            // Get content resolver
            jclass activityThreadClass = env->FindClass("android/app/ActivityThread");
            jmethodID currentApplicationMethod = env->GetStaticMethodID(activityThreadClass, 
                "currentApplication", "()Landroid/app/Application;");
            jobject application = env->CallStaticObjectMethod(activityThreadClass, currentApplicationMethod);
            
            if (application) {
                jclass contextClass = env->FindClass("android/content/Context");
                jmethodID getContentResolverMethod = env->GetMethodID(contextClass, 
                    "getContentResolver", "()Landroid/content/ContentResolver;");
                jobject contentResolver = env->CallObjectMethod(application, getContentResolverMethod);
                
                if (contentResolver) {
                    jstring androidIdKey = env->NewStringUTF("android_id");
                    jstring androidIdStr = (jstring)env->CallStaticObjectMethod(systemClass, 
                        getStringMethod, contentResolver, androidIdKey);
                    
                    if (androidIdStr) {
                        const char* androidId = env->GetStringUTFChars(androidIdStr, 0);
                        hwid += "|" + std::string(androidId);
                        env->ReleaseStringUTFChars(androidIdStr, androidId);
                    }
                }
            }
        }
        
        jvm->DetachCurrentThread();
        
        // Create hash of the combined string for shorter HWID
        std::hash<std::string> hasher;
        size_t hashValue = hasher(hwid);
        
        std::stringstream ss;
        ss << std::hex << hashValue;
        return "ARMODS_" + ss.str();
        
    } catch (...) {
        LOGD("Exception generating HWID");
        jvm->DetachCurrentThread();
        return "";
    }
}

#include <unordered_map>
#include "imgui.h"

// animation progress store करने के लिए
static std::unordered_map<ImGuiID, float> s_line_anim;

// BigMenuCheckbox: बड़े item जैसा दिखने वाला checkbox
// label: दिखने वाला टेक्स्ट
// state: pointer to bool (on/off)
// sizeHint.y controls height (default 48)
// ==========================
// ✅ FIXED CUSTOM CHECKBOX
// ==========================
// ===============================
// 🔥 Animated Line Button Function
// ===============================
bool MyCustomCheckbox(const char* label, bool* state, ImVec2 size = ImVec2(0, 40.0f))
{
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (!window || window->SkipItems)
        return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    ImGuiID id = window->GetID(label);

    float avail_x = (size.x == 0) ? ImGui::GetContentRegionAvail().x : size.x;
    ImRect bb(window->DC.CursorPos, ImVec2(window->DC.CursorPos.x + avail_x, window->DC.CursorPos.y + size.y));
    ImGui::ItemSize(bb, style.FramePadding.y);
    if (!ImGui::ItemAdd(bb, id))
        return false;

    bool hovered, held;
    bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);

    if (pressed)
        *state = !*state;

    // Animation setup
    float target = *state ? 1.0f : 0.0f;
    if (s_line_anim.find(id) == s_line_anim.end())
        s_line_anim[id] = target;

    s_line_anim[id] = ImLerp(s_line_anim[id], target, g.IO.DeltaTime * 8.0f);
    float anim = s_line_anim[id];

    // Base line color interpolation
    ImVec4 blue = ImVec4(0.1f, 0.6f, 1.0f, 1.0f);
    ImVec4 red  = ImVec4(1.0f, 0.2f, 0.2f, 1.0f);
    ImVec4 line_color = ImLerp(blue, red, anim);

    // Calculate animated line "leak" length
    float line_progress = ImLerp(0.2f, 1.0f, anim);

    // Draw main text
    ImVec2 text_size = ImGui::CalcTextSize(label);
    ImVec2 text_pos = ImVec2(bb.Min.x + 10.0f, bb.Min.y + (size.y - text_size.y) * 0.5f);
    window->DrawList->AddText(text_pos, ImGui::GetColorU32(ImVec4(1,1,1,0.9f)), label);

    // Draw animated bottom line (like leak animation)
    float line_thickness = 3.0f;
    float line_length = (bb.Max.x - bb.Min.x) * line_progress;
    ImVec2 line_start = ImVec2(bb.Min.x, bb.Max.y - 3.0f);
    ImVec2 line_end = ImVec2(bb.Min.x + line_length, bb.Max.y - 3.0f);

    // Line background faint (off color)
    window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Max.y - 3.0f),
                              ImVec2(bb.Max.x, bb.Max.y - 3.0f),
                              ImGui::GetColorU32(ImVec4(0.2f,0.2f,0.3f,0.2f)), line_thickness);

    // Main animated line
    window->DrawList->AddLine(line_start, line_end, ImGui::GetColorU32(line_color), line_thickness);

    // Small glowing leak effect at line end
    ImVec4 glow_color = ImVec4(line_color.x, line_color.y, line_color.z, 0.6f);
    window->DrawList->AddCircleFilled(line_end, 4.0f, ImGui::GetColorU32(glow_color));

    // Hover pulse
    if (hovered)
        window->DrawList->AddRect(bb.Min, bb.Max, ImGui::GetColorU32(ImVec4(1,1,1,0.05f)), 4.0f);

    return pressed;
}
/*
// === Global animation map (add this globally once) ===
static std::unordered_map<ImGuiID, float> s_checkbox_anim;

// === Custom Checkbox Function ===
bool MyCustomCheckbox(const char* label, bool* state, ImVec2 size = ImVec2(0, 35.0f))
{
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (!window || window->SkipItems)
        return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    ImGuiID id = window->GetID(label);

    float avail_x = (size.x == 0) ? ImGui::GetContentRegionAvail().x : size.x;
    ImRect bb(window->DC.CursorPos, ImVec2(window->DC.CursorPos.x + avail_x, window->DC.CursorPos.y + size.y));
    ImGui::ItemSize(bb, style.FramePadding.y);
    if (!ImGui::ItemAdd(bb, id))
        return false;

    bool hovered, held;
    bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);
    if (pressed)
        *state = !*state;

    // === Animation setup ===
    float target = *state ? 1.0f : 0.0f;
    if (s_checkbox_anim.find(id) == s_checkbox_anim.end())
        s_checkbox_anim[id] = target;

    s_checkbox_anim[id] = ImLerp(s_checkbox_anim[id], target, g.IO.DeltaTime * 12.0f);
    float anim = s_checkbox_anim[id];

    // === Colors ===
    ImVec4 box_on  = ImVec4(0.1f, 0.7f, 1.0f, 1.0f);
    ImVec4 box_off = ImVec4(0.25f, 0.25f, 0.25f, 1.0f);
    ImVec4 tick_col = ImVec4(1, 1, 1, anim);

    // === Checkbox box ===
    float box_size = size.y * 0.65f;
    ImVec2 box_pos = ImVec2(bb.Min.x + 10.0f, bb.Min.y + (size.y - box_size) * 0.5f);
    ImRect box_rect(box_pos, ImVec2(box_pos.x + box_size, box_pos.y + box_size));

    ImVec4 box_color = ImLerp(box_off, box_on, anim);
    window->DrawList->AddRectFilled(box_rect.Min, box_rect.Max, ImGui::GetColorU32(box_color), 6.0f);

    // === Border glow ===
    if (hovered)
  //      window->DrawList->AddRect(box_rect.Min - ImVec2(2, 2), box_rect.Max + ImVec2(2, 2),
                 //                 ImGui::GetColorU32(ImVec4(0.1f, 0.7f, 1.0f, 0.6f)), 8.0f, 0, 2.0f);

    // === Checkmark (smooth animation) ===
    if (anim > 0.05f)
    {
        ImVec2 center = ImVec2((box_rect.Min.x + box_rect.Max.x) * 0.5f, (box_rect.Min.y + box_rect.Max.y) * 0.5f);
        float check_scale = ImLerp(0.0f, 1.0f, anim);
        float check_size = box_size * 0.4f * check_scale;
        window->DrawList->AddLine(ImVec2(center.x - check_size, center.y),
                                  ImVec2(center.x - check_size / 4, center.y + check_size),
                                  ImGui::GetColorU32(tick_col), 2.5f);
        window->DrawList->AddLine(ImVec2(center.x - check_size / 4, center.y + check_size),
                                  ImVec2(center.x + check_size, center.y - check_size * 0.7f),
                                  ImGui::GetColorU32(tick_col), 2.5f);
    }

    // === Text label ===
    ImVec2 text_size = ImGui::CalcTextSize(label);
    ImVec2 text_pos = ImVec2(box_rect.Max.x + 10.0f, bb.Min.y + (size.y - text_size.y) * 0.5f);
    window->DrawList->AddText(text_pos, ImGui::GetColorU32(ImVec4(1, 1, 1, 0.95f)), label);

    return pressed;
}
*/

// Rainbow Text Function for ImGui
void ImGui_RainbowText(const char* text, float speed = 1.0f) {
    ImDrawList* draw_list = ImGui::GetWindowDrawList();
    ImVec2 pos = ImGui::GetCursorScreenPos();
    ImGuiStyle& style = ImGui::GetStyle();

    float time = ImGui::GetTime() * speed;
    float x = pos.x;
    float y = pos.y;

    for (int i = 0; text[i] != '\0'; i++) {
        float hue = fmodf((time + i * 0.1f), 1.0f);  // Hue change per character
        ImVec4 color;
        ImGui::ColorConvertHSVtoRGB(hue, 1.0f, 1.0f, color.x, color.y, color.z);
        color.w = 1.0f;

        char buf[2] = { text[i], 0 }; // single char
        draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(),
                           ImVec2(x, y), ImGui::ColorConvertFloat4ToU32(color), buf);

        x += ImGui::CalcTextSize(buf).x; // move to next char position
    }
    ImGui::Dummy(ImVec2(x - pos.x, ImGui::GetTextLineHeight())); // reserve space
}

// Update HWID in Airtable (supports single and double device with separate fields)
bool updateHWIDInAirtable(const std::string& recordId, const std::string& hwid, const std::string& deviceType, const std::string& field = "HWID") {
    if (!jvm) return false;
    
    JNIEnv* env = nullptr;
    if (jvm->AttachCurrentThread(&env, nullptr) != JNI_OK) {
        return false;
    }
    
    try {
        // Construct PATCH URL
        std::string url = AIRTABLE_BASE_URL + "/" + recordId;
        
        // Create JSON payload for the specified field
        std::string jsonPayload = "{\"fields\":{\"" + field + "\":\"" + hwid + "\"}}";
        
        // Get URL class
        jclass urlClass = env->FindClass("java/net/URL");
        jmethodID urlConstructor = env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
        jstring jUrl = env->NewStringUTF(url.c_str());
        jobject urlObject = env->NewObject(urlClass, urlConstructor, jUrl);
        
        // Open connection
        jmethodID openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
        jobject connection = env->CallObjectMethod(urlObject, openConnectionMethod);
        
        // Cast to HttpURLConnection
        jclass httpConnectionClass = env->FindClass("java/net/HttpURLConnection");
        
        // Set request method to PATCH
        jmethodID setRequestMethodMethod = env->GetMethodID(httpConnectionClass, "setRequestMethod", "(Ljava/lang/String;)V");
        jstring patchMethod = env->NewStringUTF("PATCH");
        env->CallVoidMethod(connection, setRequestMethodMethod, patchMethod);
        
        // Set headers
        jmethodID setRequestPropertyMethod = env->GetMethodID(httpConnectionClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
        
        jstring authHeaderName = env->NewStringUTF("Authorization");
        std::string authHeaderValue = "Bearer " + AIRTABLE_TOKEN;
        jstring authHeaderVal = env->NewStringUTF(authHeaderValue.c_str());
        env->CallVoidMethod(connection, setRequestPropertyMethod, authHeaderName, authHeaderVal);
        
        jstring contentTypeHeader = env->NewStringUTF("Content-Type");
        jstring contentTypeValue = env->NewStringUTF("application/json");
        env->CallVoidMethod(connection, setRequestPropertyMethod, contentTypeHeader, contentTypeValue);
        
        // Enable output
        jmethodID setDoOutputMethod = env->GetMethodID(httpConnectionClass, "setDoOutput", "(Z)V");
        env->CallVoidMethod(connection, setDoOutputMethod, JNI_TRUE);
        
        // Write JSON payload
        jmethodID getOutputStreamMethod = env->GetMethodID(httpConnectionClass, "getOutputStream", "()Ljava/io/OutputStream;");
        jobject outputStream = env->CallObjectMethod(connection, getOutputStreamMethod);
        
        jclass outputStreamClass = env->FindClass("java/io/OutputStream");
        jmethodID writeMethod = env->GetMethodID(outputStreamClass, "write", "([B)V");
        
        jbyteArray jsonBytes = env->NewByteArray(jsonPayload.length());
        env->SetByteArrayRegion(jsonBytes, 0, jsonPayload.length(), (jbyte*)jsonPayload.c_str());
        env->CallVoidMethod(outputStream, writeMethod, jsonBytes);
        
        jmethodID flushMethod = env->GetMethodID(outputStreamClass, "flush", "()V");
        env->CallVoidMethod(outputStream, flushMethod);
        
        // Get response code
        jmethodID getResponseCodeMethod = env->GetMethodID(httpConnectionClass, "getResponseCode", "()I");
        jint responseCode = env->CallIntMethod(connection, getResponseCodeMethod);
        
        jvm->DetachCurrentThread();
        return responseCode == 200;
        
    } catch (...) {
        LOGD("Exception updating HWID");
        jvm->DetachCurrentThread();
        return false;
    }
}

// Enhanced JSON parser for Airtable response with full user info
bool parseAirtableResponse(const std::string& jsonResponse, const std::string& username, const std::string& password) {
    // Look for records array
    size_t recordsPos = jsonResponse.find("\"records\":");
    if (recordsPos == std::string::npos) {
        LOGD("No records found in response");
        return false;
    }
    
    // Look for username field
    size_t usernamePos = jsonResponse.find("\"Username\":\"" + username + "\"");
    if (usernamePos == std::string::npos) {
        LOGD("Username not found in response");
        return false;
    }
    
    // Look for password field after username
    size_t passwordSearchStart = usernamePos;
    size_t passwordPos = jsonResponse.find("\"Password\":\"" + password + "\"", passwordSearchStart);
    if (passwordPos == std::string::npos) {
        LOGD("Password not found or incorrect");
        return false;
    }
    
    // Extract record ID
    size_t idPos = jsonResponse.find("\"id\":\"", 0);
    if (idPos != std::string::npos) {
        size_t idStart = idPos + 6;
        size_t idEnd = jsonResponse.find("\"", idStart);
        if (idEnd != std::string::npos) {
            currentUserInfo.recordId = jsonResponse.substr(idStart, idEnd - idStart);
        }
    }
    
    // Extract CreatedBy (creator username)
    size_t createdByPos = jsonResponse.find("\"CreatedBy\":", passwordSearchStart);
    if (createdByPos != std::string::npos) {
        size_t createdByStart = jsonResponse.find("\"", createdByPos + 12);
        size_t createdByEnd = jsonResponse.find("\"", createdByStart + 1);
        if (createdByStart != std::string::npos && createdByEnd != std::string::npos) {
            currentUserInfo.createdBy = jsonResponse.substr(createdByStart + 1, createdByEnd - createdByStart - 1);
            
            // Query creator's AccountType by making another API call
            std::string creatorQuery = AIRTABLE_BASE_URL + "?filterByFormula={Username}='" + currentUserInfo.createdBy + "'";
            std::string creatorResponse = makeHttpRequest(creatorQuery, AIRTABLE_TOKEN);
            
            // Extract creator's AccountType
            size_t creatorAccountTypePos = creatorResponse.find("\"AccountType\":");
            if (creatorAccountTypePos != std::string::npos) {
                size_t creatorAccountTypeStart = creatorResponse.find("\"", creatorAccountTypePos + 14);
                size_t creatorAccountTypeEnd = creatorResponse.find("\"", creatorAccountTypeStart + 1);
                if (creatorAccountTypeStart != std::string::npos && creatorAccountTypeEnd != std::string::npos) {
                    currentUserInfo.creatorAccountType = creatorResponse.substr(creatorAccountTypeStart + 1, creatorAccountTypeEnd - creatorAccountTypeStart - 1);
                }
            }
        }
    }
    
    // Extract Expiry with better parsing
    size_t expiryPos = jsonResponse.find("\"Expiry\":", passwordSearchStart);
    if (expiryPos != std::string::npos) {
        // Look for the value after the colon
        size_t colonPos = expiryPos + 9; // Skip "Expiry":
        size_t valueStart = jsonResponse.find_first_not_of(" \t", colonPos);
        
        if (valueStart != std::string::npos) {
            if (jsonResponse[valueStart] == '"') {
                // String value
                size_t expiryStart = valueStart + 1;
                size_t expiryEnd = jsonResponse.find('"', expiryStart);
                if (expiryEnd != std::string::npos) {
                    currentUserInfo.expiry = jsonResponse.substr(expiryStart, expiryEnd - expiryStart);
                }
            } else {
                // Number value (no quotes)
                size_t expiryEnd = jsonResponse.find_first_of(",}\n\r", valueStart);
                if (expiryEnd != std::string::npos) {
                    currentUserInfo.expiry = jsonResponse.substr(valueStart, expiryEnd - valueStart);
                }
            }
            
            LOGD("Extracted expiry: %s", currentUserInfo.expiry.c_str());
            
            // Check if account is expired
            if (!currentUserInfo.expiry.empty() && currentUserInfo.expiry != "9999") {
                try {
                    long long expiry = std::stoll(currentUserInfo.expiry);
                    long long currentTime = time(0);
                    LOGD("Expiry timestamp: %lld, Current time: %lld", expiry, currentTime);
                    
                    if (expiry < currentTime) {
                        LOGD("Account expired - blocking login");
                        return false;
                    }
                } catch (const std::exception& e) {
                    LOGD("Error parsing expiry timestamp: %s", e.what());
                    return false;
                }
            }
        }
    }
    
    // Extract Device type
    size_t devicePos = jsonResponse.find("\"Device\":", passwordSearchStart);
    if (devicePos != std::string::npos) {
        size_t deviceStart = jsonResponse.find("\"", devicePos + 9);
        size_t deviceEnd = jsonResponse.find("\"", deviceStart + 1);
        if (deviceStart != std::string::npos && deviceEnd != std::string::npos) {
            currentUserInfo.deviceType = jsonResponse.substr(deviceStart + 1, deviceEnd - deviceStart - 1);
        }
    }
    
    // Extract current HWID
    size_t hwidPos = jsonResponse.find("\"HWID\":", passwordSearchStart);
    if (hwidPos != std::string::npos) {
        size_t hwidStart = jsonResponse.find("\"", hwidPos + 7);
        size_t hwidEnd = jsonResponse.find("\"", hwidStart + 1);
        if (hwidStart != std::string::npos && hwidEnd != std::string::npos) {
            currentUserInfo.hwid = jsonResponse.substr(hwidStart + 1, hwidEnd - hwidStart - 1);
        }
    }
    
    // Extract HWID2 for double devices
    size_t hwid2Pos = jsonResponse.find("\"HWID2\":", passwordSearchStart);
    if (hwid2Pos != std::string::npos) {
        size_t hwid2Start = jsonResponse.find("\"", hwid2Pos + 8);
        size_t hwid2End = jsonResponse.find("\"", hwid2Start + 1);
        if (hwid2Start != std::string::npos && hwid2End != std::string::npos) {
            currentUserInfo.hwid2 = jsonResponse.substr(hwid2Start + 1, hwid2End - hwid2Start - 1);
        }
    }
    
    // Extract AccountType for role display
    size_t accountTypePos = jsonResponse.find("\"AccountType\":", passwordSearchStart);
    if (accountTypePos != std::string::npos) {
        size_t accountTypeStart = jsonResponse.find("\"", accountTypePos + 14);
        size_t accountTypeEnd = jsonResponse.find("\"", accountTypeStart + 1);
        if (accountTypeStart != std::string::npos && accountTypeEnd != std::string::npos) {
            currentUserInfo.accountType = jsonResponse.substr(accountTypeStart + 1, accountTypeEnd - accountTypeStart - 1);
        }
    }
    
    // Store username
    currentUserInfo.username = username;
    
    // Handle device binding based on device type
    std::string deviceHWID = generateHWID();
    LOGD("Device HWID: %s", deviceHWID.c_str());
    LOGD("Stored HWID: %s", currentUserInfo.hwid.c_str());
    
    if (currentUserInfo.deviceType == "single" || currentUserInfo.deviceType.empty()) {
        if (currentUserInfo.hwid.empty()) {
            // First time login - store HWID in HWID field
            if (updateHWIDInAirtable(currentUserInfo.recordId, deviceHWID, "single", "HWID")) {
                currentUserInfo.hwid = deviceHWID;
                LOGD("HWID stored successfully");
            } else {
                LOGD("Failed to store HWID");
                return false;
            }
        } else {
            // Check if HWID matches
            if (currentUserInfo.hwid != deviceHWID) {
                LOGD("HWID mismatch - key already used on another device");
                return false;
            }
        }
    } else if (currentUserInfo.deviceType == "double") {
        // Check if current device matches HWID or HWID2
        if (currentUserInfo.hwid == deviceHWID || currentUserInfo.hwid2 == deviceHWID) {
            LOGD("Device already bound - login successful");
        } else {
            // Try to bind to available slot
            if (currentUserInfo.hwid.empty()) {
                // Bind to HWID field
                if (updateHWIDInAirtable(currentUserInfo.recordId, deviceHWID, "double", "HWID")) {
                    currentUserInfo.hwid = deviceHWID;
                    LOGD("First device HWID stored successfully");
                } else {
                    LOGD("Failed to store first device HWID");
                    return false;
                }
            } else if (currentUserInfo.hwid2.empty()) {
                // Bind to HWID2 field
                if (updateHWIDInAirtable(currentUserInfo.recordId, deviceHWID, "double", "HWID2")) {
                    currentUserInfo.hwid2 = deviceHWID;
                    LOGD("Second device HWID stored successfully");
                } else {
                    LOGD("Failed to store second device HWID");
                    return false;
                }
            } else {
                // Both slots occupied
                LOGD("Maximum devices reached (2/2) - key already used");
                return false;
            }
        }
    } else if (currentUserInfo.deviceType == "unlimited") {
        // Unlimited devices - no HWID restriction
        LOGD("Unlimited device type - no HWID restriction");
    }
    
    LOGD("Authentication successful");
    return true;
}

// Validate user credentials against Airtable using JNI HTTP
bool validateUserCredentials(const std::string& username, const std::string& password) {
    // URL encode the username for the filter
    std::string encodedUsername = username;
    // Simple URL encoding for spaces and special characters
    size_t pos = 0;
    while ((pos = encodedUsername.find(" ", pos)) != std::string::npos) {
        encodedUsername.replace(pos, 1, "%20");
        pos += 3;
    }
    
    // Construct URL with filter
    std::string url = AIRTABLE_BASE_URL + "?filterByFormula={Username}='" + encodedUsername + "'";
    
    LOGD("Making request to: %s", url.c_str());
    
    // Make HTTP request
    std::string response = makeHttpRequest(url, AIRTABLE_TOKEN);
    
    if (response.empty()) {
        LOGD("HTTP request failed or returned empty response");
        return false;
    }
    
    LOGD("Airtable response: %s", response.c_str());
    
    // Parse response and validate credentials
    return parseAirtableResponse(response, username, password);
}

// Parse user:pass format from clipboard
std::pair<std::string, std::string> parseUserPass(const std::string& input) {
    size_t colonPos = input.find(':');
    if (colonPos == std::string::npos) {
        return std::make_pair("", "");
    }
    
    std::string username = input.substr(0, colonPos);
    std::string password = input.substr(colonPos + 1);
    
    // Trim whitespace
    username.erase(0, username.find_first_not_of(" \t\n\r"));
    username.erase(username.find_last_not_of(" \t\n\r") + 1);
    password.erase(0, password.find_first_not_of(" \t\n\r"));
    password.erase(password.find_last_not_of(" \t\n\r") + 1);
    
    return std::make_pair(username, password);
}

// JNI function to get text from the Android clipboard
std::string getClipboardText() {
    if (!jvm) return "";

    JNIEnv* env = nullptr;
    jvm->AttachCurrentThread(&env, nullptr);
    if (!env) return "";

    // Find the necessary Android classes
    jclass activityThreadClass = env->FindClass("android/app/ActivityThread");
    if (!activityThreadClass) {
        jvm->DetachCurrentThread();
        return "";
    }
    jmethodID currentApplicationMethod = env->GetStaticMethodID(activityThreadClass, "currentApplication", "()Landroid/app/Application;");
    if (!currentApplicationMethod) {
        jvm->DetachCurrentThread();
        return "";
    }
    jobject application = env->CallStaticObjectMethod(activityThreadClass, currentApplicationMethod);
    if (!application) {
        jvm->DetachCurrentThread();
        return "";
    }
    jclass contextClass = env->FindClass("android/content/Context");
    if (!contextClass) {
        jvm->DetachCurrentThread();
        return "";
    }
    jmethodID getSystemServiceMethod = env->GetMethodID(contextClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
    if (!getSystemServiceMethod) {
        jvm->DetachCurrentThread();
        return "";
    }
    jfieldID clipboardServiceField = env->GetStaticFieldID(contextClass, "CLIPBOARD_SERVICE", "Ljava/lang/String;");
    if (!clipboardServiceField) {
        jvm->DetachCurrentThread();
        return "";
    }
    jobject clipboardService = env->GetStaticObjectField(contextClass, clipboardServiceField);

    // Get the ClipboardManager
    jobject clipboardManager = env->CallObjectMethod(application, getSystemServiceMethod, clipboardService);
    if (!clipboardManager) {
        jvm->DetachCurrentThread();
        return "";
    }
    jclass clipboardManagerClass = env->FindClass("android/content/ClipboardManager");
    if (!clipboardManagerClass) {
        jvm->DetachCurrentThread();
        return "";
    }
    jmethodID getPrimaryClipMethod = env->GetMethodID(clipboardManagerClass, "getPrimaryClip", "()Landroid/content/ClipData;");
    if (!getPrimaryClipMethod) {
        jvm->DetachCurrentThread();
        return "";
    }
    jobject clipData = env->CallObjectMethod(clipboardManager, getPrimaryClipMethod);
    if (!clipData) {
        jvm->DetachCurrentThread();
        return "";
    }
    jclass clipDataClass = env->FindClass("android/content/ClipData");
    if (!clipDataClass) {
        jvm->DetachCurrentThread();
        return "";
    }
    jmethodID getItemAtMethod = env->GetMethodID(clipDataClass, "getItemAt", "(I)Landroid/content/ClipData$Item;");
    if (!getItemAtMethod) {
        jvm->DetachCurrentThread();
        return "";
    }
    jobject clipItem = env->CallObjectMethod(clipData, getItemAtMethod, 0);
    if (!clipItem) {
        jvm->DetachCurrentThread();
        return "";
    }
    jclass clipItemClass = env->FindClass("android/content/ClipData$Item");
    if (!clipItemClass) {
        jvm->DetachCurrentThread();
        return "";
    }
    jmethodID coerceToTextMethod = env->GetMethodID(clipItemClass, "coerceToText", "(Landroid/content/Context;)Ljava/lang/CharSequence;");
    if (!coerceToTextMethod) {
        jvm->DetachCurrentThread();
        return "";
    }
    jobject charSequence = env->CallObjectMethod(clipItem, coerceToTextMethod, application);
    if (!charSequence) {
        jvm->DetachCurrentThread();
        return "";
    }

    // Convert the Java string to a C++ string
    jclass charSequenceClass = env->FindClass("java/lang/CharSequence");
    jmethodID toStringMethod = env->GetMethodID(charSequenceClass, "toString", "()Ljava/lang/String;");
    jstring javaString = (jstring)env->CallObjectMethod(charSequence, toStringMethod);
    const char* nativeString = env->GetStringUTFChars(javaString, 0);
    std::string result(nativeString);
    env->ReleaseStringUTFChars(javaString, nativeString);

    // Detach the thread and return
    jvm->DetachCurrentThread();
    return result;
}






#include "imGui/stb_image.h"

#include "AxlMods.h"

//#include "AxlMods.h"

struct TextureInfo { ImTextureID textureId; int x; int y; int w; int h; };
static TextureInfo textureInfo;
TextureInfo createTexture(char *ImagePath) {
int w, h, n;
stbi_uc *data = stbi_load(ImagePath, &w, &h, &n, 0);
GLuint texture;
glGenTextures(1, &texture);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if (n == 3) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}stbi_image_free(data);
textureInfo.textureId = reinterpret_cast<ImTextureID>((GLuint *) texture);
textureInfo.w = w;
textureInfo.h = h;
return textureInfo;
}TextureInfo CreateTexture(const unsigned char* buf, int len) {
TextureInfo image;
unsigned char* image_data = stbi_load_from_memory(buf, len, &image.w, &image.h, NULL, 0);
if (image_data == NULL) perror("文件不存在"); GLuint image_texture;
glGenTextures(1, &image_texture);
glBindTexture(GL_TEXTURE_2D, image_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //对于非二次方纹理，这在 WebGL 上是必需的
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //相同的
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.w, image.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
stbi_image_free(image_data);
image.textureId = (ImTextureID)image_texture;
return image;
}

TextureInfo AxlMods;
extern TextureInfo AxlMods;

TextureInfo how;
extern TextureInfo how;

TextureInfo bijay;
extern TextureInfo bijay;

TextureInfo plane;
extern TextureInfo plane;

TextureInfo setting;
extern TextureInfo setting;


void InitTexture() {
how = CreateTexture(how_data, sizeof(how_data));
bijay = CreateTexture(bijay_data, sizeof(bijay_data));
plane = CreateTexture(plane_data, sizeof(plane_data));
setting = CreateTexture(setting_data, sizeof(setting_data));
//AxlMods = CreateTexture(AxlMods_data, sizeof(AxlMods_data));
}



void SetupImgui() {
	
	//IMGUI_CHECKVERSION();

    IMGUI_CHECKVERSION();
    InitTexture();
	
    ImGui::CreateContext();
    ImGui_ImplAndroid_Init(nullptr);
    ImGuiIO& io = ImGui::GetIO();
    ImGuiStyle* style = &ImGui::GetStyle();
   // io.Fonts->AddFontFromMemoryTTF((void *)BaiduZY_data, BaiduZY_size, 35.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
    //io.DisplaySize = ImVec2((float)g_GlWidth, (float)g_GlHeight);

    ImVec4 whiteColor(1.0f, 1.0f, 1.0f, 1.0f);
    style->WindowTitleAlign = ImVec2(0.5f,0.5f);

  //  ImGui::StyleColorsLight();
    ImGui::StyleColorsDark();//   Màu Xanh Nước Biển

    ImGui_ImplOpenGL3_Init("#version 100");
static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0x0900, 0x097F, 0,};
ImFontConfig font_config;
ImFontConfig icons_config;
ImFontConfig CustomFont;
CustomFont.FontDataOwnedByAtlas = false;
icons_config.MergeMode = true;
icons_config.PixelSnapH = true;
icons_config.OversampleH = 2.5;
icons_config.OversampleV = 2.5;
//=====================================| 𝗙𝗢𝗡𝗧𝗦
io.Fonts->AddFontFromMemoryTTF((void *)BaiduZY_data, BaiduZY_size, 25.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
io.Fonts->AddFontFromMemoryCompressedTTF(font_awesome_data, font_awesome_size, 25.0f, &icons_config, icons_ranges);
        ImGui::GetStyle().ScaleAllSizes(3.0f);
}


inline EGLBoolean (*old_eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
inline EGLBoolean hook_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
    eglQuerySurface(dpy, surface, EGL_WIDTH, &g_GlWidth);
    eglQuerySurface(dpy, surface, EGL_HEIGHT, &g_GlHeight);

    if (!g_IsSetup) {
        prevWidth = g_GlWidth;
        prevHeight = g_GlHeight;
        SetupImgui();
        g_IsSetup = true;
    }
	
		    ImGuiIO &io = ImGui::GetIO();
	//Darkness();
	// Thiết lập màu chủ đề
	ImVec4* colors = ImGui::GetStyle().Colors;

	//ImVec4* colors = ImGui::GetStyle().Colors;

//ImGuiIO &io = ImGui::GetIO();
//ImGuiStyle& style = ImGui::GetStyle(); // ✅ ADD THIS LINE


/*
// --- Layout & Spacing ---
Style->WindowPadding = ImVec2(10, 10);
Style->WindowRounding = 5.0f;
Style->FramePadding = ImVec2(10, 8);
Style->ItemSpacing = ImVec2(8, 8);
Style->FrameRounding = 4.0f;
Style->ChildRounding = 3.0f;
Style->WindowBorderSize = 1.0f;
Style->FrameBorderSize = 0.8f;
Style->PopupRounding = 4.0f;
Style->ScrollbarSize = 18.0f;
Style->ScrollbarRounding = 5.0f;
Style->GrabRounding = 5.0f;
Style->GrabMinSize = 10.0f;
Style->TabRounding = 3.0f;
Style->TabBorderSize = 0.0f;
Style->ButtonTextAlign = ImVec2(0.5f, 0.5f);
Style->WindowTitleAlign = ImVec2(0.5f, 0.5f);
*/
// --- COLOR SCHEME (Dark with Neon Accents) ---
//ImVec4* colors = Style->Colors;

// Backgrounds
colors[ImGuiCol_WindowBg]          = ImColor(10, 10, 10, 255);   // Deep black window background
colors[ImGuiCol_ChildBg]           = ImColor(0, 0, 0, 255);   // Slightly lighter for child areas
colors[ImGuiCol_PopupBg]           = ImColor(20, 20, 20, 255);
colors[ImGuiCol_MenuBarBg]         = ImColor(15, 15, 15, 255);

// Text
colors[ImGuiCol_Text]              = ImColor(255, 255, 255, 255);  // White text
colors[ImGuiCol_TextDisabled]      = ImColor(150, 150, 150, 255);
colors[ImGuiCol_TextSelectedBg]    = ImColor(255, 0, 120, 60);     // Soft pink select highlight

// Frames (Inputs, buttons)
colors[ImGuiCol_FrameBg]           = ImColor(25, 25, 25, 255);
colors[ImGuiCol_FrameBgHovered]    = ImColor(255, 0, 120, 70);
colors[ImGuiCol_FrameBgActive]     = ImColor(255, 0, 120, 100);

// Headers (for collapsing/active sections)
colors[ImGuiCol_Header]            = ImColor(255, 0, 120, 60);
colors[ImGuiCol_HeaderHovered]     = ImColor(255, 0, 120, 100);
colors[ImGuiCol_HeaderActive]      = ImColor(255, 0, 120, 140);

// Buttons
colors[ImGuiCol_Button]            = ImColor(255, 0, 120, 160);    // Neon pink
colors[ImGuiCol_ButtonHovered]     = ImColor(255, 0, 120, 200);
colors[ImGuiCol_ButtonActive]      = ImColor(255, 0, 120, 255);

// Accent (Check, Slider)
colors[ImGuiCol_CheckMark]         = ImColor(0, 255, 255, 255);    // Cyan check
colors[ImGuiCol_SliderGrab]        = ImColor(255, 0, 120, 255);
colors[ImGuiCol_SliderGrabActive]  = ImColor(255, 0, 180, 255);

// Borders & Separators
colors[ImGuiCol_Border]            = ImColor(255, 255, 255, 255);
colors[ImGuiCol_Separator]         = ImColor(255, 255, 255, 255);

// Tabs
colors[ImGuiCol_Tab]               = ImColor(20, 20, 20, 255);
colors[ImGuiCol_TabHovered]        = ImColor(255, 0, 120, 255);
colors[ImGuiCol_TabActive]         = ImColor(255, 0, 120, 255);
colors[ImGuiCol_TabUnfocused]      = ImColor(20, 20, 20, 255);
colors[ImGuiCol_TabUnfocusedActive]= ImColor(255, 0, 120, 180);

// Title Bars
colors[ImGuiCol_TitleBg]           = ImColor(10, 10, 10, 255);
colors[ImGuiCol_TitleBgActive]     = ImColor(10, 10, 10, 255);
colors[ImGuiCol_TitleBgCollapsed]  = ImColor(10, 10, 10, 255);

// Scrollbars
colors[ImGuiCol_ScrollbarBg]       = ImColor(15, 15, 15, 0);
colors[ImGuiCol_ScrollbarGrab]     = ImColor(255, 0, 120, 0);
colors[ImGuiCol_ScrollbarGrabHovered] = ImColor(255, 0, 120, 0);
colors[ImGuiCol_ScrollbarGrabActive]  = ImColor(255, 0, 120, 0);

// Resize & Navigation
colors[ImGuiCol_ResizeGrip]        = ImColor(255, 0, 120, 80);
colors[ImGuiCol_ResizeGripHovered] = ImColor(255, 0, 120, 130);
colors[ImGuiCol_ResizeGripActive]  = ImColor(255, 0, 120, 255);
colors[ImGuiCol_NavHighlight]      = ImColor(255, 0, 120, 255);

// Overlay / Modal
colors[ImGuiCol_NavWindowingHighlight] = ImColor(255, 255, 255, 80);
colors[ImGuiCol_NavWindowingDimBg]     = ImColor(0, 0, 0, 80);
colors[ImGuiCol_ModalWindowDimBg]      = ImColor(0, 0, 0, 100);

	
	// ImGui frame ke andar call karo
RenderExpiredBoxTopLeft("LICENSE STATUS");


    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplAndroid_NewFrame(g_GlWidth, g_GlHeight);
    ImGui::NewFrame();

    // Touch input handling (your existing code)
    int touchCount = (((int (*)())(Class_Input__get_touchCount))());
    if (touchCount > 0) {
        UnityEngine_Touch_Fields touch = ((UnityEngine_Touch_Fields(*)(int))(Class_Input__GetTouch))(0);
        float reverseY = io.DisplaySize.y - touch.m_Position.fields.y;
        switch (touch.m_Phase) {
            case TouchPhase::Began:
            case TouchPhase::Stationary:
                io.MousePos = ImVec2(touch.m_Position.fields.x, reverseY);
                io.MouseDown[0] = true;
                break;
            case TouchPhase::Ended:
            case TouchPhase::Canceled:
                io.MouseDown[0] = false;
                clearMousePos = true;
                break;
            case TouchPhase::Moved:
                io.MousePos = ImVec2(touch.m_Position.fields.x, reverseY);
                break;
            default:
                break;
        }
    }
    
	
	        ImGuiStyle& menu = ImGui::GetStyle();
	
	
	    menu.ScrollbarRounding = 9.0f;
	    menu.ScrollbarSize     = 0.0f;
	    menu.ButtonTextAlign   = ImVec2(0.5f, 0.5f);
	
	
    DrawESP(g_GlWidth, g_GlHeight);

			
	// Default window flag
static bool show = false; 
static bool clickInProgress = false;
static float clickStartTime = 0;

// अब तुम्हारा original code चलता है ↓
if (show == false) {
            ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
    if (ImGui::Begin(OBFUSCATE("GUJJU DIGITAL MODS V24"), 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground)) {
        const auto& pWindowDrawList = ImGui::GetWindowDrawList();    
        const auto& p = ImGui::GetWindowPos();      
        ImGui::SetCursorPos(ImVec2(5, 5));
        ImVec2 imageSize(90,90);
        ImGui::Image(bijay.textureId, imageSize);        

        if (ImGui::IsItemHovered()) {
            if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
                clickInProgress = true;
                clickStartTime = ImGui::GetTime();
            }
        }
        if (clickInProgress && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
            clickInProgress = false;
            float currentTime = ImGui::GetTime();
            float clickDuration = currentTime - clickStartTime;
            if (clickDuration < 0.2f) {
                show = true;
            }
        }
    }
    ImGui::End();
}

if (show) {
	    ExpireDate exp;
    exp.setExpirationDate(30,11,2925);//d,m,y
    if (exp.isExpired()) {

    ImGui::Begin(OBFUSCATE("GUJJU DIGITAL MODS IS EXPIRED JOIN TG FOR NEW UPDATE️"));

ImGui::Text(OBFUSCATE("GUJJU DIGITAL MODS IS EXPIRE!!!"));
ImGui::Text(OBFUSCATE(" YOUR MOD MENU EXPIRED \n JOIN TELEGRAM FOR MORE UPDATEA \n Contact: @Gmd6296 For New Updates !!!"));
if (ImGui::Button(OBFUSCATE("     TELEGRAM CHNL UPDATE   "))) {
OpenURL(Il2CppString::Create(OBFUSCATE("https://t.me/+Gb2nn3Gk7mo4ODhl")));
}
if (ImGui::Button(OBFUSCATE("      CONTECT OWNER : GUJJU DIGITAL MODS V24"))) {
OpenURL(Il2CppString::Create(OBFUSCATE("https://t.me/+Gb2nn3Gk7mo4ODhl")));
}
			           //ImGui::SameLine(180.0f);
if (ImGui::Button(OBFUSCATE("NEW UPDATE"))) {
OpenURL(Il2CppString::Create(OBFUSCATE("https://t.me/+Gb2nn3Gk7mo4ODhl")));
}

ImGui::End();

} else {		
            
if (show) {

ImGui::SetNextWindowSize(ImVec2(640,615), ImGuiCond_Once);
if (ImGui::Begin(("Lyra"), &show ,ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize)){


if (bijaytab == 1) {


ImVec2 winPos = ImGui::GetWindowPos();
ImVec2 winSize = ImGui::GetWindowSize();
auto bg = ImGui::GetBackgroundDrawList();

// 🔹 Child background color
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0, 0, 0, 255).Value);

ImVec2 available_space = ImGui::GetContentRegionAvail();
float desired_width = available_space.x;
float inner_width = desired_width;
float inner_height = 35.0f;

ImGui::BeginChild(ImGui::GetID("Header"), ImVec2(inner_width, inner_height));

// 📏 Get window data
ImVec2 VR = ImGui::GetWindowPos();
ImDrawList* draw = ImGui::GetWindowDrawList();
ImVec2 child_max_content = ImGui::GetContentRegionMax();
float child_width = child_max_content.x;
float child_height = child_max_content.y;

// 🌈 Dynamic rainbow color
float t = ImGui::GetTime();
float r = (sin(t) + 1.0f) * 0.5f;
float g = (sin(t + 2.0f) + 1.0f) * 0.5f;
float b = (sin(t + 4.0f) + 1.0f) * 0.5f;

ImU32 dynamic_color = IM_COL32(
    static_cast<int>(r * 255),
    static_cast<int>(g * 255),
    static_cast<int>(b * 255),
    255
);
// 📝 Centered text
const char* text_label = "ANKIT X LIVE 999";
ImVec2 text_size = ImGui::CalcTextSize(text_label);
float text_x = VR.x + (child_width - text_size.x) / 2.0f;
float text_y = VR.y + (child_height - text_size.y) / 2.0f;

// 🟢 Draw rainbow text
draw->AddText(ImVec2(text_x, text_y), dynamic_color, text_label);

ImGui::EndChild();
ImGui::PopStyleColor();
ImGui::PopStyleVar();
ImGui::PopStyleColor(3);

// 🔴 Close Button (Top-Right)
ImGui::SameLine(ImGui::GetWindowSize().x - 45);
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(200, 0, 0, 255));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(255, 0, 0, 0));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(150, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f);

if (ImGui::Button("X", ImVec2(150, 90)))
{
    show = false; // Close menu
}


static int selectedTab = 0;
ImGui::BeginChild("Sidebar", ImVec2(130, 0), true);
ImGui::SetCursorPosY(30);

// 🔴 Common clickable image function
auto DrawClickableImage = [&](ImTextureID tex, ImVec2 size, int tabIndex, const char* id) {
    ImVec2 pos = ImGui::GetCursorScreenPos();
    ImGui::Image(tex, size);

    // Invisible button for click area
    ImGui::SetCursorScreenPos(pos);
    ImGui::InvisibleButton(id, size);

    // Hover highlight
    if (ImGui::IsItemHovered()) {
        ImDrawList* draw_list = ImGui::GetWindowDrawList();
        draw_list->AddRect(pos, ImVec2(pos.x + size.x, pos.y + size.y),
                           IM_COL32(255, 0, 0, 120), 6.0f, 0, 3.0f);
    }

    // On click: change tab
    if (ImGui::IsItemClicked()) {
        selectedTab = tabIndex;
    }

    ImGui::Spacing();
};
// 🖼️ 4 images (tabs)
DrawClickableImage(setting.textureId, ImVec2(83, 83), 0, "##settingImg");
DrawClickableImage(how.textureId,     ImVec2(77, 77), 1, "##howImg");
DrawClickableImage(bijay.textureId,   ImVec2(87, 87), 2, "##bijayImg");
DrawClickableImage(plane.textureId,   ImVec2(77, 77), 3, "##planeImg");
ImGui_RainbowText("12/11/2026", 0.1f); // speed = 2.0
ImGui::EndChild();
ImGui::SameLine();
// 🟢 Main Tab Content Area
ImGui::BeginChild("TabContent", ImVec2(0, 0), true);

// -------- TAB 1 CONTENT --------
if (selectedTab == 0)
{
    ImGui_RainbowText("AIM FUNCTION", 2.0f); // speed = 2.0
    ImGui::Separator();
                			MyCustomCheckbox("ACTIVE FUCTION", &Enable);

                            MyCustomCheckbox("AIMBOT", &Aimbot);
							
                            MyCustomCheckbox("AIM FIRE", &AimFire);
							
                            MyCustomCheckbox("AIM LOCK", &Socpe);

		                    //ImGui::Checkbox("TelyPort Enemy", &Mass.Sucks);

           					 ImGui::SliderFloat(OBFUSCATE("AIM FOV"), &Size, 0.0f, 360.0f, "%.f");
}

// -------- TAB 2 CONTENT --------
else if (selectedTab == 1)
{
        ImGui_RainbowText("ESP FUNCTION", 2.0f); // speed = 2.0
        ImGui::Separator();
        MyCustomCheckbox("ESP BOX", &box);
        MyCustomCheckbox("ESP HEALTH", &Target);
        MyCustomCheckbox("ESP NAME", &Health);
        MyCustomCheckbox("ESP DISTANCE", &Distance);
     ImGui::Checkbox("ESP LINE", &Line);
/*
							ImGui::Checkbox("ESP BOX", &box);
							
                            ImGui::Checkbox("ESP HEALTH", &Target);

                            ImGui::Checkbox("ESP NAME", &Health);						
							
                            ImGui::Checkbox("ESP DISTANC3", &Distance);
    */
}

// -------- TAB 3 CONTENT --------
else if (selectedTab == 2)
{
ImGui_RainbowText("EXTRA FUNCTION", 2.0f); // speed = 2.0
   ImGui::Dummy(ImVec2(0.0f, 25.0f));
//    ImGui_RainbowText("RAMBO COLOR TEXT EFFECT!", 2.0f); // speed = 2.0
        ImGui::Separator();//::Separator();
        
    
          //        MyCustomCheckbox("BYPASS ANTICHEAT (Must)", &AntiCheat);
         //       MyCustomCheckbox("SPEED 50x", &SpeedHack);
}

// -------- TAB 4 CONTENT --------
else if (selectedTab == 3)
{
ImGui_RainbowText("COLOUR PICKUP", 2.0f); // speed = 2.0
ImGui::Dummy(ImVec2(0.0f, 25.0f));
//    ImGui_RainbowText("RAMBO COLOR TEXT EFFECT!", 2.0f); // speed = 2.0
        ImGui::Separator();
    
    	//   ImGui::ColorEdit3("ESP Color", (float*)&ESPColor);
}

ImGui::EndChild();

}





if (bijaytab == 2) {

	
            ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
  				 ImGui::Begin("GUJJU DIGITAL MODS V24" ,&show, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoResize); {
               
					 ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 p1 = ImGui::GetWindowPos();
ImVec2 p2 = ImVec2(p1.x + ImGui::GetWindowSize().x, p1.y + ImGui::GetWindowSize().y);

// Gradient inside the window with same colors as background
draw_list->AddRectFilledMultiColor(
    p1, p2,
    IM_COL32(0, 255, 240, 255),   // Top-left     #00FFF0  (💧 नीला-हरा / सियान)
    IM_COL32(200, 0, 255, 255),   // Top-right    #C800FF  (💜 गहरा बैंगनी)
    IM_COL32(200, 0, 255, 255),   // Bottom-right #C800FF  (💜 गहरा बैंगनी)
    IM_COL32(0, 255, 240, 255)    // Bottom-left  #00FFF0  (💧 नीला-हरा / सियान)
);
					 
					 if (!show) {
                    show = false;
                }
				
      	            if (ImGui::BeginTabBar("##tabbar", ImGuiTabBarFlags_None)) {
						
          	            if (ImGui::BeginTabItem(OBFUSCATE("GUJJU"))) {
							
							ImGui::Checkbox("ACTIVE FUCTION", &Enable);

                            ImGui::Checkbox("AIMBOT", &Aimbot);
							
                            ImGui::Checkbox("AIM FIRE", &AimFire);
							
                            ImGui::Checkbox("AIM LOCK", &Socpe);

		                    //ImGui::Checkbox("TelyPort Enemy", &Mass.Sucks);

           					 ImGui::SliderFloat(OBFUSCATE("AIM FOV"), &Size, 0.0f, 360.0f, "%.f");
                            if (ImGui::Button(OBFUSCATE("JOIN TG GUJJU DIGITAL MODS"))){
                            OpenURL(Il2CppString::Create(OBFUSCATE("https://t.me/+Gb2nn3Gk7mo4ODhl")));
    							 }			

                    ImGui::EndTabItem();
                        }
          	            if (ImGui::BeginTabItem(OBFUSCATE("DIGITAL"))) {
                            

							//ImGui::Checkbox("Active Function", &Enable);

							ImGui::Checkbox("ESP LINE", &Line);

							ImGui::Checkbox("ESP BOX", &box);
							
                            ImGui::Checkbox("ESP HEALTH", &Target);

                            ImGui::Checkbox("ESP NAME", &Health);						
							
                            ImGui::Checkbox("ESP DISTANC3", &Distance);
							
							//ImGui::Checkbox("Reset Guest", &Convidado);
                            ImGui::EndTabItem();
                        
						}
						ImGui::EndTabItem();
                        }
          	            if (ImGui::BeginTabItem(OBFUSCATE("MODS"))) {
						

float windowWidth = ImGui::GetWindowSize().x;
ImGui::PushItemWidth(windowWidth * 0.4f);  // 60% width
ImGui::SliderFloat(OBFUSCATE("HEADSHOT RATE"), &headshotPercentage, 0.0f, 100.0f, "%.1f%%");
ImGui::PopItemWidth();

     				//		ImGui::Checkbox("Joystick", &speedrun);        
	    			//		ImGui::Checkbox("RUN 50x", &isSpeedSafe);
	    					//ImGui::Checkbox("Camera", &camxa);
	    					//ImGui::Checkbox("Fast Switch", &fastswitch);
							//ImGui::Checkbox("Reset Guest", &Convidado);
                            ImGui::EndTabItem();
							}
					}
					}
					
					}
					} // end
					 
				}
    ImGui::End();
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    return old_eglSwapBuffers(dpy, surface);
}
}

typedef unsigned long DWORD;
static uintptr_t libBase;

inline void StartGUI() {
    void *ptr_eglSwapBuffer = DobbySymbolResolver("/system/lib/libEGL.so", "eglSwapBuffers");
    if (ptr_eglSwapBuffer != nullptr) {
        DobbyHook((void *)ptr_eglSwapBuffer, (void *)hook_eglSwapBuffers, (void **)&old_eglSwapBuffers);
        LOGD("GUI started successfully");
    }
}
/*
bool(*get_ResetGuest)(bool* instance);
bool _get_ResetGuest(bool* instance) {
    if (Convidado) {
        return true;
    }
    return get_ResetGuest(instance);
}
*/
void hack_thread() {
    // Sleep for a few seconds to give the app time to load
    sleep(5);
    
    pid_t pid = getpid();
    LOGD("Hack Thread initiated for PID: %i", pid);

    // Wait until libil2cpp.so is loaded
    do {
        il2cpp_base = get_module_base(pid, "libil2cpp.so");
        sleep(1);
    } while (il2cpp_base == 0);

    LOGD("libil2cpp.so found at address: 0x%" PRIxPTR, il2cpp_base);

    // Now that the library is loaded, we can proceed
    Il2CppAttach();
    
    // If you have Your own bypass then past here 🙂
    // =======

	/*
	
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x801555C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7EB6D1C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x8012C38), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x8013250), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x5F5E200), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B2D0C8), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B2D010), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B9B398), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B5281C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2BCC944), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B33C6C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7F44778), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x30BEB24), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B00AB0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B375AC), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7F36B50), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7EA5C34), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2CB549C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2CE88A0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x30BC4F4), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B4A468), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x6F605D8), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB113900), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB113918), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x878552C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x6F5A0D8), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2E7E680), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x5507608), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB0236D8), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x265EAA0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x31FC8B0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x559B114), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x30BD59C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2E85908), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B19070), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2EAB870), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2B9861C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x80155C8), "20 00 80 D2 C0 03 5F D6");

MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2FA02B0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7334EF4), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7067CC0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7EB4EC0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2FAFF1C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2FD8834), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2FB1C04), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x3932C00), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x3066370), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x3066708), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x87E23AC), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x30C7A40), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2EA7CF8), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2FAFF1C), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB023658), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB0609D8), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7BAD0FC), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x656AE54), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7604CD0), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x7BAC8B4), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB02EC50), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0xB028768), "20 00 80 D2 C0 03 5F D6");
MemoryPatch::createWithHex(getAbsoluteAddress("libil2cpp.so", 0x2FD9424), "20 00 80 D2 C0 03 5F D6");
*/
//=========================IDK WORKING OR NOT=======================//
	
	
        // ResetGuest
   // DobbyHook(Il2CppGetMethodOffset(OBFUSCATE("Assembly-CSharp.dll"), OBFUSCATE("COW"), OBFUSCATE("GameConfig") , OBFUSCATE("get_ResetGuest"), 0), (void *) _get_ResetGuest, (void **) &get_ResetGuest);
  
	
	
	
	
	OpenURL = (void (*)(String *))Il2CppGetMethodOffset("UnityEngine.CoreModule.dll","UnityEngine","Application","OpenURL",1);

    
	
	
    //=======
    
    StartGUI();
}

