#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <time.h>
#include <ctype.h>
#include <errno.h>
#include <stdbool.h>  // 添加缺失的头文件

// Android 日志支持
#ifdef __ANDROID__
#include <android/log.h>
#define LOG_TAG   "RangeInjector"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#else
#define LOGI(...) printf(__VA_ARGS__)
#define LOGE(...) fprintf(stderr, __VA_ARGS__)
#endif

// 类型定义
typedef long int ADDRESS;
typedef char PACKAGENAME[64];

// 全局变量
int ipid;
time_t last_detect_time = 0;
const int TIMEOUT_SECONDS = 60;
bool program_running = true;
int current_language = 0;  // 0=中文, 1=英文
bool auto_inject_enabled = false;  // 自动循环注入开关
bool first_inject_done = false;    // 首次注入完成标志

// 颜色定义
#define RESET   "\033[0m"
#define RED     "\033[31m"
#define GREEN   "\033[32m"
#define YELLOW  "\033[33m"
#define BLUE    "\033[34m"
#define MAGENTA "\033[35m"
#define CYAN    "\033[36m"
#define BOLD    "\033[1m"

// 服务器类型枚举
typedef enum {
SERVER_UNKNOWN = 0,
SERVER_GLOBAL,  // 国际服
SERVER_TAIWAN,  // 台服
SERVER_CHINESE  // 国服
} ServerType;

// 服务器配置结构体（已删除CB相关偏移）
struct ServerConfig {
ServerType type;
char package_name[64];
char server_name[32];
char server_name_en[32];

// A功能偏移量（国际服/台服额外功能）
long int a_head_offset1;         // 头部范围偏移1
long int a_head_offset2;         // 头部范围偏移2
long int a_chest_offset1;        // 胸部范围偏移1
long int a_chest_offset2;        // 胸部范围偏移2
long int a_abdomen_offset1;      // 腹部范围偏移1
long int a_abdomen_offset2;      // 腹部范围偏移2
long int a_leg_offset1;          // 腿部范围偏移1
long int a_leg_offset2;          // 腿部范围偏移2

// XA功能偏移量
long int xa_wh_offset;           // 全枪无后
long int xa_jd1_offset;          // 有准心聚点
long int xa_jd2_offset;          // 无准心聚点
long int xa_fw4_offset;          // 全身范围偏移1
long int xa_fw5_offset;          // 全身范围偏移2

// 基础偏移
long int base_addr_offset;       // 基础地址偏移
};

// 全局服务器配置数组（已删除CB相关偏移值）
struct ServerConfig server_configs[] = {
// 国服配置
{
SERVER_CHINESE,
"com.tencent.tmgp.dfm",
"国服",
"Chinese Server",
0x90,      // a_head_offset1
0x90,      // a_head_offset2
0x10,      // a_chest_offset1
0x10,      // a_chest_offset2
0x0,       // a_abdomen_offset1
0x0,       // a_abdomen_offset2
0x18,      // a_leg_offset1
0x28,      // a_leg_offset2
-0xFFAA4C0,// xa_wh_offset
-0xFF9D590,// xa_jd1_offset
-0xFF9D594,// xa_jd2_offset
-0x11B9F660,// xa_fw4_offset
-0x11B9F664,// xa_fw5_offset
0x2F98F0   // base_addr_offset
},
// 国际服配置
{
SERVER_GLOBAL,
"com.proxima.dfm",
"国际服",
"Global Server",
0x90,       // a_head_offset1
0x90,       // a_head_offset2
0x10,       // a_chest_offset1
0x10,       // a_chest_offset2
0x0,        // a_abdomen_offset1
0x0,        // a_abdomen_offset2
0x18,       // a_leg_offset1
0x28,       // a_leg_offset2
-0xFAE4E74, // xa_wh_offset
-0xFAD7F44, // xa_jd1_offset
-0xFAD7F48, // xa_jd2_offset
-0x116C833C, // xa_fw4_offset
-0x116C8338, // xa_fw5_offset
0x2FEAA0    // base_addr_offset
},
// 台服配置
{
SERVER_TAIWAN,
"com.garena.game.df",
"台服",
"Taiwan Server",
0x90,       // a_head_offset1
0x90,       // a_head_offset2
0x10,       // a_chest_offset1
0x10,       // a_chest_offset2
0x0,        // a_abdomen_offset1
0x0,        // a_abdomen_offset2
0x18,       // a_leg_offset1
0x28,       // a_leg_offset2
-0x1004B9A8, // xa_wh_offset
-0x1003EA78, // xa_jd1_offset
-0x1003EA7C, // xa_jd2_offset
-0x11C2EE18, // xa_fw4_offset
-0x11C2EE14, // xa_fw5_offset
0x2FC910    // base_addr_offset
}
};

#define NUM_SERVERS (sizeof(server_configs) / sizeof(struct ServerConfig))

// 配置参数结构体（已删除CB相关参数）
struct ConfigParams {
// A功能参数（国际服/台服额外功能）
float a_head_current;
float a_chest_current;
float a_abdomen_current;
float a_leg_current;
bool a_head_enabled;
bool a_chest_enabled;
bool a_abdomen_enabled;
bool a_leg_enabled;

// XA功能参数
float xa_wh_current;
float xa_jd1_current;
float xa_jd2_current;
float xa_fw4_current;
float xa_fw5_current;
bool xa_wh_enabled;
bool xa_jd1_enabled;
bool xa_jd2_enabled;
bool xa_fw_enabled;  // 全身范围总开关
int xa_fw_size;      // 全身范围大小：0=超小，1=小，2=中，3=大
};

// 全局配置变量（已删除CB相关初始化）
struct ConfigParams config_params = {
// A功能默认值
.a_head_current = 12.585f,
.a_chest_current = 21.0f,
.a_abdomen_current = 18.0f,
.a_leg_current = 15.0f,
.a_head_enabled = false,
.a_chest_enabled = false,
.a_abdomen_enabled = false,
.a_leg_enabled = false,

// XA功能默认值
.xa_wh_current = -0.04694629088f,      // 全枪无后关闭值
.xa_jd1_current = 8.47870468e-21f,     // 有准心聚点关闭值
.xa_jd2_current = 8.53159334e-21f,     // 无准心聚点关闭值
.xa_fw4_current = -0.04694461823f,     // 全身范围偏移4关闭值
.xa_fw5_current = -1.14258058e-22f,    // 全身范围偏移5关闭值
.xa_wh_enabled = false,
.xa_jd1_enabled = false,
.xa_jd2_enabled = false,
.xa_fw_enabled = false,
.xa_fw_size = 0
};

// 全身范围大小的值数组
const float xa_fw5_values[] = {
8.6059879e-21f,   // 超小身位
8.63245768e-21f,  // 小身位
8.68539724e-21f,  // 中身位
8.71186702e-21f   // 大身位
};

ServerType current_server = SERVER_UNKNOWN;

// 配置路径常量（已删除CB目录）
#define CONFIG_BASE_DIR "/sdcard/亡客"
#define A_CONFIG_DIR CONFIG_BASE_DIR "/a"
#define XA_CONFIG_DIR CONFIG_BASE_DIR "/xa"
#define AUTO_INJECT_FILE CONFIG_BASE_DIR "/循环.ini"

// 函数声明（已删除CB相关函数）
int getPID(char bm[64]);
long int getZZ(int pid, long int addr);
long int getCb(int pid, const char *module_name);
long int get64(int pid, long int addr);
int WriteAddress_DWORD(PACKAGENAME bm, ADDRESS addr, int value);
int WriteAddress_FLOAT(PACKAGENAME bm, ADDRESS addr, float value);
int killGG();
int killprocess(PACKAGENAME bm);
int isapkrunning(char *bm);
int getPIDEx(const char *packageName);
ServerType detect_server_type();
struct ServerConfig *get_server_config(ServerType type);
void update_detect_time();
bool check_timeout();
void *background_detector(void *arg);
void init_config_files();
void show_main_menu();
void show_a_menu();
void show_xa_menu();
void select_range_a();
void select_range_xa();
void inject_all_functions();
void save_config();
void load_config();
void input_float(const char *prompt_cn, const char *prompt_en, float *value);
void save_value_to_config_file(float value, const char *filename);
void list_all_processes(void);
void clear_input_buffer();
bool write_memory_value(const char *package, long int address, float value, const char *success_msg_cn, const char *success_msg_en, const char *fail_msg_cn, const char *fail_msg_en);
bool inject_a_parameters(const char *package, struct ServerConfig *config, long int libbase, long int base_addr);
void inject_xa_parameters(const char *package, struct ServerConfig *config, long int libbase);
bool resolve_pointer_chain(int pid, long int base_addr, long int offsets[], int offset_count, long int *result);
void show_function_menu();
void select_functions();
void select_language();
void create_language_file();
void safe_get_input(char *buffer, size_t size, const char *prompt_cn, const char *prompt_en);
int get_menu_choice();
void *auto_inject_loop(void *arg);

// 工具函数
void clear_input_buffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF);
}

// 安全的输入获取函数
void safe_get_input(char *buffer, size_t size, const char *prompt_cn, const char *prompt_en) {
if (current_language == 0 && prompt_cn) {
printf("%s", prompt_cn);
} else if (current_language == 1 && prompt_en) {
printf("%s", prompt_en);
}
fflush(stdout);

if (fgets(buffer, size, stdin) == NULL) {
buffer[0] = '\0';
} else {
// 移除换行符
size_t len = strlen(buffer);
if (len > 0 && buffer[len-1] == '\n') {
buffer[len-1] = '\0';
}
}
}

// 改进的内存写入函数
bool write_memory_value(const char *package, long int address, float value, 
const char *success_msg_cn, const char *success_msg_en, 
const char *fail_msg_cn, const char *fail_msg_en) {
if (WriteAddress_FLOAT((char *) package, address, value)) {
if (current_language == 0 && success_msg_cn) {
printf("%s", success_msg_cn);
} else if (current_language == 1 && success_msg_en) {
printf("%s", success_msg_en);
}
fflush(stdout);
return true;
} else {
if (current_language == 0 && fail_msg_cn) {
printf("%s", fail_msg_cn);
} else if (current_language == 1 && fail_msg_en) {
printf("%s", fail_msg_en);
}
fflush(stdout);
return false;
}
}

// 改进的WriteAddress_FLOAT函数
int WriteAddress_FLOAT(char *bm, ADDRESS addr, float value) {
pid_t pid = getPID(bm);
if (pid == 0) {
LOGE("无法获取进程PID: %s", bm);
return 0;
}

char lj[64];
snprintf(lj, sizeof(lj), "/proc/%d/mem", pid);
int handle = open(lj, O_RDWR);
if (handle == -1) {
LOGE("打开内存文件失败: %s, 错误: %s", lj, strerror(errno));
return 0;
}

ssize_t bytes_written = pwrite(handle, &value, sizeof(value), addr);
close(handle);

if (bytes_written != sizeof(value)) {
LOGE("写入内存失败: 期望写入%zu字节，实际写入%zd字节", sizeof(value), bytes_written);
return 0;
}

LOGI("成功写入内存: PID=%d, 地址=0x%lx, 值=%f", pid, addr, value);
return 1;
}

// 进程管理函数
int killprocess(PACKAGENAME bm) {
int pid = getPID(bm);
if (pid == 0) return -1;

char ml[32];
snprintf(ml, sizeof(ml), "kill %d", pid);
system(ml);
return 0;
}

int killGG() {
DIR *dir = opendir("/data/data");
if (!dir) return 0;

struct dirent *ptr;
char filepath[256];

while ((ptr = readdir(dir)) != NULL) {
if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) continue;
if (ptr->d_type != DT_DIR) continue;

snprintf(filepath, sizeof(filepath), "/data/data/%s/files", ptr->d_name);
DIR *dirGG = opendir(filepath);
if (!dirGG) continue;

struct dirent *ptrGG;
while ((ptrGG = readdir(dirGG)) != NULL) {
if (strcmp(ptrGG->d_name, ".") == 0 || strcmp(ptrGG->d_name, "..") == 0) continue;
if (ptrGG->d_type != DT_DIR) continue;

if (strstr(ptrGG->d_name, "GG") || strstr(ptrGG->d_name, "AppHidden") || strstr(ptrGG->d_name, "KK-iMdx")) {
killprocess(ptr->d_name);
}
}
closedir(dirGG);
}
closedir(dir);
return 0;
}

int isapkrunning(char *bm) {
return getPID(bm) != 0;
}

// 内存读取函数
long int getCb(int pid, const char *module_name) {
FILE *fp = NULL;
long addr = 0;
char *pch;
char filename[64];
char line[1024];

snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
fp = fopen(filename, "r");
if (fp == NULL) {
LOGE("无法打开maps文件: %s", filename);
return 0;
}

bool found_module = false;
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, module_name)) {
if (strstr(line, "rw-p")) {
found_module = true;
}
}
if (found_module && strstr(line, "[anon:.bss]")) {
pch = strtok(line, "-");
addr = strtoul(pch, NULL, 16);
break;
}
}

fclose(fp);
return addr;
}

long int get64(int pid, long int addr) {
long int value = 0;
char lj[256];

snprintf(lj, sizeof(lj), "/proc/%d/mem", pid);
int handle = open(lj, O_RDONLY);
if (handle == -1) {
LOGE("读取内存失败: 打开文件错误: %s", strerror(errno));
return 0;
}

ssize_t bytes_read = pread(handle, &value, sizeof(value), addr);
close(handle);

if (bytes_read != sizeof(value)) {
LOGE("读取内存失败: 从地址0x%lx读取%zd字节，期望%zu字节", addr, bytes_read, sizeof(value));
return 0;
}

return value;
}

long int getZZ(int pid, long int addr) {
long int var[4] = { 0 };
char lj[256];

snprintf(lj, sizeof(lj), "/proc/%d/mem", pid);
int handle = open(lj, O_RDONLY);
if (handle == -1) {
LOGE("读取内存失败: 打开文件错误: %s", strerror(errno));
return 0;
}

pread(handle, var, 4, addr);
close(handle);
return var[0];
}

// 改进的进程检测函数
int getPIDEx(const char *packageName) {
DIR *dir = opendir("/proc");
if (dir == NULL) {
LOGE("无法打开/proc目录");
return 0;
}

struct dirent *ptr;
FILE *fp;
char filepath[256];
char filetext[1024];
int found_pid = 0;

while ((ptr = readdir(dir)) != NULL) {
if (!isdigit(ptr->d_name[0])) continue;

// 检查cmdline
snprintf(filepath, sizeof(filepath), "/proc/%s/cmdline", ptr->d_name);
fp = fopen(filepath, "r");
if (fp != NULL) {
if (fgets(filetext, sizeof(filetext), fp) != NULL) {
filetext[strcspn(filetext, "\n")] = 0;
if (strcmp(filetext, packageName) == 0 || strstr(filetext, packageName) != NULL) {
found_pid = atoi(ptr->d_name);
fclose(fp);
break;
}
}
fclose(fp);
}

// 检查comm文件
char commPath[256];
snprintf(commPath, sizeof(commPath), "/proc/%s/comm", ptr->d_name);
FILE *commFp = fopen(commPath, "r");
if (commFp != NULL) {
char commName[256];
if (fgets(commName, sizeof(commName), commFp) != NULL) {
commName[strcspn(commName, "\n")] = 0;
if (strstr(commName, packageName) != NULL) {
found_pid = atoi(ptr->d_name);
fclose(commFp);
break;
}
}
fclose(commFp);
}

// 检查status文件
snprintf(filepath, sizeof(filepath), "/proc/%s/status", ptr->d_name);
fp = fopen(filepath, "r");
if (fp != NULL) {
while (fgets(filetext, sizeof(filetext), fp)) {
if (strncmp(filetext, "Name:", 5) == 0) {
char processName[256];
sscanf(filetext, "Name:\t%s", processName);
if (strcmp(processName, packageName) == 0) {
found_pid = atoi(ptr->d_name);
fclose(fp);
break;
}
}
}
fclose(fp);
}
}

closedir(dir);
if (found_pid > 0) {
LOGI("找到进程: PID=%d, 包名=%s", found_pid, packageName);
} else {
LOGI("未找到进程: %s", packageName);
}
return found_pid;
}

int getPID(PACKAGENAME PackageName) {
return getPIDEx(PackageName);
}

// 内存写入函数
int WriteAddress_DWORD(PACKAGENAME bm, ADDRESS addr, int value) {
pid_t pid = getPID(bm);
if (pid == 0) {
LOGE("无法获取进程PID: %s", bm);
return 0;
}

char lj[64];
snprintf(lj, sizeof(lj), "/proc/%d/mem", pid);
int handle = open(lj, O_RDWR);
if (handle == -1) {
LOGE("写入内存失败: 打开文件错误: %s", strerror(errno));
return 0;
}

pwrite(handle, &value, 4, addr);
close(handle);
return 1;
}

// 改进的超时检测相关函数
void update_detect_time() {
last_detect_time = time(NULL);
}

bool check_timeout() {
static time_t last_game_detected_time = 0;
static bool timeout_warning_shown = false;

time_t current_time = time(NULL);

bool any_server_running = false;
for (int i = 0; i < NUM_SERVERS; i++) {
if (isapkrunning(server_configs[i].package_name)) {
any_server_running = true;
last_game_detected_time = current_time;
if (timeout_warning_shown) {
timeout_warning_shown = false;
LOGI("检测到游戏进程，超时计时重置");
}
break;
}
}

if (!any_server_running && last_game_detected_time > 0) {
if (current_time - last_game_detected_time > TIMEOUT_SECONDS) {
if (!timeout_warning_shown) {
LOGI("60秒未检测到游戏进程，准备退出");
timeout_warning_shown = true;
}
return true;
}
} else if (last_game_detected_time == 0) {
// 首次运行，设置初始时间
last_game_detected_time = current_time;
}

return false;
}

ServerType detect_server_type() {
LOGI("开始检测服务器类型...");
update_detect_time();

for (int i = 0; i < NUM_SERVERS; i++) {
LOGI("检查服务器: %s (%s)", server_configs[i].server_name, server_configs[i].package_name);

if (isapkrunning(server_configs[i].package_name)) {
LOGI("✓ 检测到服务器: %s", server_configs[i].server_name);
update_detect_time();
return server_configs[i].type;
}
}

LOGI("未找到任何支持的服务器，列出所有进程用于调试:");
list_all_processes();
return SERVER_UNKNOWN;
}

struct ServerConfig *get_server_config(ServerType type) {
for (int i = 0; i < NUM_SERVERS; i++) {
if (server_configs[i].type == type) {
return &server_configs[i];
}
}
return NULL;
}

// 文件操作函数（已删除CB目录与配置）
void init_config_files() {
const char* dirs[] = {
CONFIG_BASE_DIR,
A_CONFIG_DIR,
XA_CONFIG_DIR
};

// 创建目录
for (int i = 0; i < sizeof(dirs)/sizeof(dirs[0]); i++) {
mkdir(dirs[i], 0755);
}

// 检查是否需要初始化
FILE* test_file = fopen(CONFIG_BASE_DIR "/pz.ini", "r");
bool use_old_config = true;

if (test_file != NULL) {
fclose(test_file);

// 如果存在pz.ini，检查循环.ini状态
if (access(AUTO_INJECT_FILE, F_OK) == 0) {
auto_inject_enabled = true;
LOGI("检测到循环.ini，启用自动注入");
}

if (current_language == 0) {
printf(GREEN "检测到配置文件，是否使用上次配置？(y/n): ");
} else {
printf(GREEN "Configuration file detected, use previous configuration? (y/n): ");
}
fflush(stdout);

char buffer[256];
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
buffer[strcspn(buffer, "\n")] = 0;
if (buffer[0] == 'y' || buffer[0] == 'Y') {
if (current_language == 0) {
printf("将使用上次保存的配置\n" RESET);
} else {
printf("Will use previous configuration\n" RESET);
}
use_old_config = true;
} else {
if (current_language == 0) {
printf("将创建新配置\n" RESET);
} else {
printf("Will create new configuration\n" RESET);
}
use_old_config = false;
}
}

if (!use_old_config) {
// 用户选择不使用上次配置，删除旧文件
const char* a_files[] = {
A_CONFIG_DIR "/fw1.ini", 
A_CONFIG_DIR "/fw2.ini", 
A_CONFIG_DIR "/fw3.ini", 
A_CONFIG_DIR "/fw4.ini"
};
for (int i = 0; i < 4; i++) {
remove(a_files[i]);
}

const char* xa_files[] = {
XA_CONFIG_DIR "/wh.ini", 
XA_CONFIG_DIR "/jd1.ini", 
XA_CONFIG_DIR "/jd2.ini", 
XA_CONFIG_DIR "/fw.ini", 
XA_CONFIG_DIR "/config.ini"
};
for (int i = 0; i < 5; i++) {
remove(xa_files[i]);
}
remove(CONFIG_BASE_DIR "/pz.ini");
remove(AUTO_INJECT_FILE);  // 删除循环.ini
auto_inject_enabled = false;
}
} else {
use_old_config = false;
auto_inject_enabled = false;
}

if (!use_old_config) {
// A功能配置文件
const char* a_files[] = {
A_CONFIG_DIR "/fw1.ini", 
A_CONFIG_DIR "/fw2.ini", 
A_CONFIG_DIR "/fw3.ini", 
A_CONFIG_DIR "/fw4.ini"
};
const char* a_defaults[] = {"12.585", "21.0", "18.0", "15.0"};

for (int i = 0; i < 4; i++) {
FILE* file = fopen(a_files[i], "w");
if (file != NULL) {
fprintf(file, "%s", a_defaults[i]);
fclose(file);
}
}

// XA功能配置文件
const char* xa_files[] = {
XA_CONFIG_DIR "/wh.ini", 
XA_CONFIG_DIR "/jd1.ini", 
XA_CONFIG_DIR "/jd2.ini", 
XA_CONFIG_DIR "/fw.ini", 
XA_CONFIG_DIR "/config.ini"
};
const char* xa_defaults[] = {"-0.04694629088", "8.47870468e-21", "8.53159334e-21", "0", "0"};

for (int i = 0; i < 5; i++) {
FILE* file = fopen(xa_files[i], "w");
if (file != NULL) {
fprintf(file, "%s", xa_defaults[i]);
fclose(file);
}
}
}
}

// 询问是否使用循环注入
void ask_auto_inject() {
if (access(CONFIG_BASE_DIR "/pz.ini", F_OK) == 0) {
// 如果存在pz.ini，不询问，使用循环.ini的状态
return;
}

system("clear");
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(CYAN "            循环注入设置\n" RESET);
printf(MAGENTA "====================================\n" RESET);
printf(MAGENTA "              是否启用60秒循环注入？\n" RESET);
printf(MAGENTA "            • 启用后程序将每60秒自动重新注入\n" RESET);
printf(MAGENTA "            • 手动注入选项将被隐藏\n" RESET);
printf(MAGENTA "            • 注入过程在后台静默进行\n" RESET);
printf(MAGENTA "====================================\n" RESET);
printf("            " GREEN "请选择(y/n): ");
} else {
printf(CYAN "            Auto Inject Setup\n" RESET);
printf(MAGENTA "====================================\n" RESET);
printf(MAGENTA "              Enable 60-second auto inject?\n" RESET);
printf(MAGENTA "            • Auto inject every 60 seconds\n" RESET);
printf(MAGENTA "            • Manual inject options hidden\n" RESET);
printf(MAGENTA "            • Silent background injection\n" RESET);
printf(MAGENTA "====================================\n" RESET);
printf("            " GREEN "Please select(y/n): ");
}
fflush(stdout);

char buffer[256];
if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
buffer[strcspn(buffer, "\n")] = 0;
if (buffer[0] == 'y' || buffer[0] == 'Y') {
// 创建循环.ini
FILE* file = fopen(AUTO_INJECT_FILE, "w");
if (file != NULL) {
fprintf(file, "@wangkela");
fclose(file);
auto_inject_enabled = true;
if (current_language == 0) {
printf(GREEN "            循环注入已启用\n" RESET);
} else {
printf(GREEN "            Auto inject enabled\n" RESET);
}
} else {
if (current_language == 0) {
printf(RED "            创建循环.ini失败\n" RESET);
} else {
printf(RED "            Failed to create auto inject file\n" RESET);
}
}
} else {
// 删除循环.ini（如果存在）
remove(AUTO_INJECT_FILE);
auto_inject_enabled = false;
if (current_language == 0) {
//printf("循环注入未启用\n" RESET);
} else {
//printf("Auto inject not enabled\n" RESET);
}
}
} else {
remove(AUTO_INJECT_FILE);
auto_inject_enabled = false;
}
system("clear");
}

// 读取浮点数配置
float read_float_from_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
LOGE("无法打开文件: %s", filename);
return 0.0f;
}

float value = 0.0f;
if (fscanf(file, "%f", &value) != 1) {
LOGE("无法从文件读取数值: %s", filename);
}

fclose(file);
return value;
}

// 读取整数配置
int read_int_from_file(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
LOGE("无法打开文件: %s", filename);
return 0;
}

int value = 0;
if (fscanf(file, "%d", &value) != 1) {
LOGE("无法从文件读取数值: %s", filename);
}

fclose(file);
return value;
}

// 保存值到配置文件
void save_value_to_config_file(float value, const char *filename) {
char dir_path[256];
strcpy(dir_path, filename);
char *last_slash = strrchr(dir_path, '/');
if (last_slash != NULL) {
*last_slash = '\0';
mkdir(dir_path, 0755);
}

FILE *file = fopen(filename, "w");
if (file != NULL) {
if (value == (int) value) {
fprintf(file, "%.1f", value);
} else {
fprintf(file, "%g", value);
}
fclose(file);
}
}

void save_int_to_config_file(int value, const char *filename) {
char dir_path[256];
strcpy(dir_path, filename);
char *last_slash = strrchr(dir_path, '/');
if (last_slash != NULL) {
*last_slash = '\0';
mkdir(dir_path, 0755);
}

FILE *file = fopen(filename, "w");
if (file != NULL) {
fprintf(file, "%d", value);
fclose(file);
}
}

void save_config() {
FILE *file = fopen(CONFIG_BASE_DIR "/pz.ini", "w");
if (file != NULL) {
fprintf(file, "1");
fclose(file);
}
if (current_language == 0) {
printf("             保存配置成功\n");
} else {
printf("             Configuration saved successfully\n");
}
fflush(stdout);
}

// 加载配置（已删除CB配置加载）
void load_config() {
// 加载A功能配置
if (access(A_CONFIG_DIR "/fw1.ini", F_OK) == 0) {
config_params.a_head_current = read_float_from_file(A_CONFIG_DIR "/fw1.ini");
config_params.a_head_enabled = (config_params.a_head_current != 12.585f);
}

if (access(A_CONFIG_DIR "/fw2.ini", F_OK) == 0) {
config_params.a_chest_current = read_float_from_file(A_CONFIG_DIR "/fw2.ini");
config_params.a_chest_enabled = (config_params.a_chest_current != 21.0f);
}

if (access(A_CONFIG_DIR "/fw3.ini", F_OK) == 0) {
config_params.a_abdomen_current = read_float_from_file(A_CONFIG_DIR "/fw3.ini");
config_params.a_abdomen_enabled = (config_params.a_abdomen_current != 18.0f);
}

if (access(A_CONFIG_DIR "/fw4.ini", F_OK) == 0) {
config_params.a_leg_current = read_float_from_file(A_CONFIG_DIR "/fw4.ini");
config_params.a_leg_enabled = (config_params.a_leg_current != 15.0f);
}

// 加载XA功能配置
if (access(XA_CONFIG_DIR "/wh.ini", F_OK) == 0) {
config_params.xa_wh_current = read_float_from_file(XA_CONFIG_DIR "/wh.ini");
config_params.xa_wh_enabled = (config_params.xa_wh_current != -0.04694629088f);
}

if (access(XA_CONFIG_DIR "/jd1.ini", F_OK) == 0) {
config_params.xa_jd1_current = read_float_from_file(XA_CONFIG_DIR "/jd1.ini");
config_params.xa_jd1_enabled = (config_params.xa_jd1_current != 8.47870468e-21f);
}

if (access(XA_CONFIG_DIR "/jd2.ini", F_OK) == 0) {
config_params.xa_jd2_current = read_float_from_file(XA_CONFIG_DIR "/jd2.ini");
config_params.xa_jd2_enabled = (config_params.xa_jd2_current != 8.53159334e-21f);
}

if (access(XA_CONFIG_DIR "/fw.ini", F_OK) == 0) {
int fw_enabled = read_int_from_file(XA_CONFIG_DIR "/fw.ini");
config_params.xa_fw_enabled = (fw_enabled == 1);
}

if (access(XA_CONFIG_DIR "/config.ini", F_OK) == 0) {
config_params.xa_fw_size = read_int_from_file(XA_CONFIG_DIR "/config.ini");
}
}

// 输入浮点数函数
void input_float(const char *prompt_cn, const char *prompt_en, float *value) {
char buffer[256];
float temp;

while (1) {
if (current_language == 0) {
printf("%s", prompt_cn);
} else {
printf("%s", prompt_en);
}
fflush(stdout);

if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
if (sscanf(buffer, "%f", &temp) == 1) {
*value = temp;
break;
} else {
if (current_language == 0) {
printf("            输入无效，请输入数字！\n");
} else {
printf("            Invalid input, please enter a number!\n");
}
}
} else {
if (current_language == 0) {
printf("            输入错误！\n");
} else {
printf("            Input error!\n");
}
break;
}
}
}

// 指针链解析函数
bool resolve_pointer_chain(int pid, long int base_addr, long int offsets[], int offset_count, long int *result) {
long int current_addr = base_addr;

for (int i = 0; i < offset_count; i++) {
long int pointer_value = get64(pid, current_addr);

if (pointer_value == 0) {
return false;
}

long int next_addr = pointer_value + offsets[i];
current_addr = next_addr;
}

*result = current_addr;
return true;
}

// 循环注入线程函数
void *auto_inject_loop(void *arg) {
LOGI("循环注入线程启动");

while (program_running && auto_inject_enabled) {
// 检查游戏进程是否还在运行
if (current_server == SERVER_UNKNOWN) {
current_server = detect_server_type();
if (current_server == SERVER_UNKNOWN) {
// 可以选择是否显示提示信息
if (current_language == 0) {
// printf(RED "循环注入: 未检测到游戏进程，等待中...\n" RESET);
} else {
// printf(RED "Auto inject: Game process not detected, waiting...\n" RESET);
}
sleep(5);
continue;
}
}

struct ServerConfig *config = get_server_config(current_server);
if (config == NULL) {
sleep(5);
continue;
}

PACKAGENAME bm;
strcpy(bm, config->package_name);

if (!isapkrunning(bm)) {
if (current_language == 0) {
// printf(YELLOW "循环注入: 目标进程未运行，等待中...\n" RESET);
} else {
// printf(YELLOW "Auto inject: Target process not running, waiting...\n" RESET);
}
sleep(5);
continue;
}

// 执行注入
ipid = getPID(bm);
if (ipid == 0) {
sleep(5);
continue;
}

char mname[] = "libUE4.so";    
long int libbase = getCb(ipid, mname);
if (libbase == 0) {
sleep(5);
continue;
}

long int base_addr = libbase + config->base_addr_offset;

// 静默注入（不显示界面信息）
inject_a_parameters(bm, config, libbase, base_addr);
inject_xa_parameters(bm, config, libbase);

if (!first_inject_done) {
first_inject_done = true;
if (current_language == 0) {
//printf(GREEN "循环注入: 首次注入完成\n" RESET);
} else {
//printf(GREEN "Auto inject: First injection completed\n" RESET);
}
}

// 等待60秒再进行下一次注入
for (int i = 0; i < 60 && program_running && auto_inject_enabled; i++) {
sleep(1);
}
}

LOGI("循环注入线程结束");
return NULL;
}


// 检查是否应该静默输出
bool should_silent_output() {
FILE *file = fopen("/sdcard/亡客/循环.ini", "r");
if (file != NULL) {
fclose(file);
return true;
}
return false;
}

// A功能注入
bool inject_a_parameters(const char *package, struct ServerConfig *config, long int libbase, long int base_addr) {
bool silent_mode = should_silent_output();

long int a_offsets[][2] = {
{ config->a_head_offset1, config->a_head_offset2 },      // 头部范围
{ config->a_chest_offset1, config->a_chest_offset2 },    // 胸部范围
{ config->a_abdomen_offset1, config->a_abdomen_offset2 },// 腹部范围
{ config->a_leg_offset1, config->a_leg_offset2 }         // 腿部范围
};

float *a_values[] = {
&config_params.a_head_current,
&config_params.a_chest_current,
&config_params.a_abdomen_current,
&config_params.a_leg_current
};

bool *a_enabled[] = {
&config_params.a_head_enabled,
&config_params.a_chest_enabled,
&config_params.a_abdomen_enabled,
&config_params.a_leg_enabled
};

const char *a_names_cn[] = { "头部范围", "胸部范围", "腹部范围", "腿部范围" };
const char *a_names_en[] = { "Head magic bullet", "Chest magic bullet", "Abdomen magic bullet", "Leg magic bullet" };
const float a_defaults[] = { 12.585f, 21.0f, 18.0f, 15.0f };
const char *a_filenames[] = { "fw1.ini", "fw2.ini", "fw3.ini", "fw4.ini" };

bool all_success = true;

for (int i = 0; i < 4; i++) {
if (*a_enabled[i]) {
bool success = false;
long int final_addr = 0;

// 尝试两套偏移
for (int j = 0; j < 2; j++) {
long int chain_offsets[6] = {
0x8,            // 第一次跳转偏移
0x240,          // 第二次跳转偏移
0x40,           // 第三次跳转偏移
a_offsets[i][j],// 第四次跳转偏移
0x48,           // 第五次跳转偏移
0x48            // 第六次跳转偏移
};

if (resolve_pointer_chain(ipid, base_addr, chain_offsets, 6, &final_addr)) {
if (write_memory_value(package, final_addr, *a_values[i], NULL, NULL, NULL, NULL)) {
success = true;
if (j == 0 && !silent_mode) {
if (current_language == 0) {
printf(GREEN "            %s注入成功！\n" RESET, a_names_cn[i]);
} else {
printf(GREEN "            %s injected successfully!\n" RESET, a_names_en[i]);
}
}
} else {
if (!silent_mode) {
if (current_language == 0) {
printf(RED "            %s注入失败！\n" RESET, a_names_cn[i]);
} else {
printf(RED "            %s injection failed!\n" RESET, a_names_en[i]);
}
}
}
} else {
if (!silent_mode) {
if (current_language == 0) {
printf(RED "            %s指针解析失败！\n" RESET, a_names_cn[i]);
} else {
printf(RED "            %s pointer resolution failed!\n" RESET, a_names_en[i]);
}
}
}
}

if (!success) {
all_success = false;
}
} else {
// 关闭功能 - 恢复默认值
for (int j = 0; j < 2; j++) {
long int chain_offsets[6] = {
0x8,            // 第一次跳转偏移
0x240,          // 第二次跳转偏移
0x40,           // 第三次跳转偏移
a_offsets[i][j],// 第四次跳转偏移
0x48,           // 第五次跳转偏移
0x48            // 第六次跳转偏移
};

long int final_addr;
if (resolve_pointer_chain(ipid, base_addr, chain_offsets, 6, &final_addr)) {
write_memory_value(package, final_addr, a_defaults[i], NULL, NULL, NULL, NULL);
}
}
}
}

return all_success;
}

// XA功能注入
void inject_xa_parameters(const char *package, struct ServerConfig *config, long int libbase) {
bool silent_mode = should_silent_output();

long int wh_addr = libbase + config->xa_wh_offset;  // 全枪无后
long int jd1_addr = libbase + config->xa_jd1_offset;// 有准心聚点
long int jd2_addr = libbase + config->xa_jd2_offset;// 无准心聚点
long int fw4_addr = libbase + config->xa_fw4_offset;// 全身范围偏移1
long int fw5_addr = libbase + config->xa_fw5_offset;// 全身范围偏移2

// 全枪无后
if (config_params.xa_wh_enabled) {
write_memory_value(package, wh_addr, 8.84170853e-21f,
silent_mode ? NULL : GREEN "            全枪无后注入成功！\n" RESET,
silent_mode ? NULL : GREEN "            No recoil injected successfully!\n" RESET,
silent_mode ? NULL : RED "            全枪无后注入失败！\n" RESET,
silent_mode ? NULL : RED "            No recoil injection failed!\n" RESET);
} else {
if (write_memory_value(package, wh_addr, -0.04694629088f, NULL, NULL, NULL, NULL)) {
config_params.xa_wh_current = -0.04694629088f;
save_value_to_config_file(-0.04694629088f, XA_CONFIG_DIR "/wh.ini");
} else {
if (!silent_mode) {
if (current_language == 0) {
printf(RED "            全枪无后关闭失败！\n" RESET);
} else {
printf(RED "            Failed to disable no recoil!\n" RESET);
}
}
}
}

// 聚点功能
if (config_params.xa_jd1_enabled) {
// 启用有准心聚点
write_memory_value(package, jd1_addr, 8.84170853e-21f,
silent_mode ? NULL : GREEN "            有准心聚点注入成功！\n" RESET,
silent_mode ? NULL : GREEN "            Crosshair bullet focus point injected succeeded!\n" RESET,
silent_mode ? NULL : RED "            有准心聚点注入失败！\n" RESET,
silent_mode ? NULL : RED "            Crosshair bullet focus point injection failed!\n" RESET);
// 关闭无准心聚点
write_memory_value(package, jd2_addr, 8.53159334e-21f, NULL, NULL, NULL, NULL);

// 管理配置文件
remove(XA_CONFIG_DIR "/jd2.ini");
save_value_to_config_file(8.84170853e-21f, XA_CONFIG_DIR "/jd1.ini");
} else if (config_params.xa_jd2_enabled) {
// 启用无准心聚点
write_memory_value(package, jd2_addr, 8.84170853e-21f,
silent_mode ? NULL : GREEN "            无准心聚点注入成功！\n" RESET,
silent_mode ? NULL : GREEN "            No crosshair bullet focus point injected successfully!\n" RESET,
silent_mode ? NULL : RED "            无准心聚点注入失败！\n" RESET,
silent_mode ? NULL : RED "            No crosshair bullet focus point injection failed!\n" RESET);
// 关闭有准心聚点
write_memory_value(package, jd1_addr, 8.47870468e-21f, NULL, NULL, NULL, NULL);

// 管理配置文件
remove(XA_CONFIG_DIR "/jd1.ini");
save_value_to_config_file(8.84170853e-21f, XA_CONFIG_DIR "/jd2.ini");
} else {
// 关闭所有聚点
write_memory_value(package, jd1_addr, 8.47870468e-21f, NULL, NULL, NULL, NULL);
write_memory_value(package, jd2_addr, 8.53159334e-21f, NULL, NULL, NULL, NULL);
remove(XA_CONFIG_DIR "/jd1.ini");
remove(XA_CONFIG_DIR "/jd2.ini");
}

// 全身范围
if (config_params.xa_fw_enabled) {
// 设置偏移4
write_memory_value(package, fw4_addr, 8.52494924e-21f, NULL, NULL, NULL, NULL);
// 设置偏移5（根据选择的尺寸）
write_memory_value(package, fw5_addr, xa_fw5_values[config_params.xa_fw_size],
silent_mode ? NULL : GREEN "            XA全身范围注入成功！\n" RESET,
silent_mode ? NULL : GREEN "            XA full body magic bullet injected successfully!\n" RESET,
silent_mode ? NULL : RED "            XA全身范围注入失败！\n" RESET,
silent_mode ? NULL : RED "            XA full body magic bullet injection failed!\n" RESET);
} else {
// 关闭全身范围
write_memory_value(package, fw4_addr, -0.04694461823f, NULL, NULL, NULL, NULL);
write_memory_value(package, fw5_addr, -1.14258058e-22f, NULL, NULL, NULL, NULL);
}
}

// 主菜单显示函数（修改版）
void show_main_menu() {
auto_inject_enabled = (access(AUTO_INJECT_FILE, F_OK) == 0);
struct ServerConfig *config = get_server_config(current_server);

printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(CYAN "         亡客公益频道@wangkela\n" RESET);
printf(CYAN "            当前版本：4.0\n" RESET);
} else {
printf(CYAN "         WangKe Public Channel@wangkela\n" RESET);
printf(CYAN "            Current Version: 4.0\n" RESET);
}

if (current_server == SERVER_GLOBAL) {
if (current_language == 0) {
printf(GREEN "          当前服务器: 国际服\n" RESET);
} else {
printf(GREEN "          Current Server: Global\n" RESET);
}
} else if (current_server == SERVER_TAIWAN) {
if (current_language == 0) {
printf(BLUE "            当前服务器: 台服\n" RESET);
} else {
printf(BLUE "            Current Server: Taiwan\n" RESET);
}
} else if (current_server == SERVER_CHINESE) {
if (current_language == 0) {
printf(RED "            当前服务器: 国服\n" RESET);
} else {
printf(RED "            Current Server: Chinese\n" RESET);
}
} else {
if (current_language == 0) {
printf(YELLOW "          当前服务器: 未检测\n" RESET);
} else {
printf(YELLOW "          Current Server: Not Detected\n" RESET);
}
}

// 显示自动注入状态
if (auto_inject_enabled) {
if (current_language == 0) {
printf(YELLOW "            自动注入: 运行中\n" RESET);
} else {
printf(YELLOW "            Auto Inject: Running\n" RESET);
}
}

printf(MAGENTA "====================================\n" RESET);

if (auto_inject_enabled) {
// 自动注入模式下只显示部分选项
if (current_language == 0) {
printf(MAGENTA "             1. 选择功能\n" RESET);            
printf(MAGENTA "             2. 保存配置\n" RESET);
printf(MAGENTA "             3. 退出程序\n" RESET);
} else {
printf(MAGENTA "             1. Select Functions\n" RESET);            
printf(MAGENTA "             2. Save Configuration\n" RESET);
printf(MAGENTA "             3. Exit Program\n" RESET);
}
} else {
// 正常模式显示所有选项
if (current_language == 0) {
printf(MAGENTA "             1. 选择功能\n" RESET);
printf(MAGENTA "             2. 注入功能\n" RESET);           
printf(MAGENTA "             3. 保存配置\n" RESET);
printf(MAGENTA "             4. 退出程序\n" RESET);
} else {
printf(MAGENTA "             1. Select Functions\n" RESET);
printf(MAGENTA "             2. Inject Functions\n" RESET);
printf(MAGENTA "             3. Save Configuration\n" RESET);
printf(MAGENTA "             4. Exit Program\n" RESET);
}
}
printf(MAGENTA "====================================\n" RESET);
}


// 功能选择菜单（已删除CB选项）
void show_function_menu() {
system("clear");
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(CYAN "             功能选择菜单\n" RESET);
} else {
printf(CYAN "             Function Selection Menu\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(MAGENTA "              1. A功能\n" RESET);
printf(MAGENTA "              2. XA功能\n" RESET);
printf(MAGENTA "              3. 返回菜单\n" RESET);
} else {
printf(MAGENTA "              1. A Functions\n" RESET);
printf(MAGENTA "              2. XA Functions\n" RESET);
printf(MAGENTA "              3. Back to Menu\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf("            " GREEN "请选择(1-3): ");
} else {
printf("            " GREEN "Please select(1-3): ");
}
fflush(stdout);
}

// 改进的选择功能函数（已删除CB分支）
void select_functions() {
char input[256];

while (1) {
show_function_menu();

if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}

if (input[0] == '\n') {
continue;
}

char choice = input[0];

switch (choice) {
case '1':
system("clear");
select_range_a();
// 选择完A功能后返回功能选择菜单，不是直接返回主菜单
break;
case '2':
system("clear");
select_range_xa();
// 选择完XA功能后返回功能选择菜单，不是直接返回主菜单
break;
case '3':
system("clear");
return;  // 返回主菜单
default:
if (current_language == 0) {
printf("            无效选择，请重新输入！\n");
} else {
printf("            Invalid selection, please try again!\n");
}
fflush(stdout);
sleep(1);
break;
}
}
}


// A功能菜单
void show_a_menu() {
system("clear");
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(CYAN "              A功能菜单\n" RESET);
} else {
printf(CYAN "             A Functions Menu\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(MAGENTA "              1.头部范围 [%s]\n" RESET, config_params.a_head_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              2.胸部范围 [%s]\n" RESET, config_params.a_chest_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              3.腹部范围 [%s]\n" RESET, config_params.a_abdomen_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              4.腿部范围 [%s]\n" RESET, config_params.a_leg_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              5.返回菜单\n" RESET);
} else {
printf(MAGENTA "          1.Head magic bullet [%s]\n" RESET, config_params.a_head_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "          2.Chest magic bullet [%s]\n" RESET, config_params.a_chest_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "          3.Abdomen magic bullet [%s]\n" RESET, config_params.a_abdomen_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "          4.Leg magic bullet [%s]\n" RESET, config_params.a_leg_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "          5.Back to Menu\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf("            " GREEN "请选择(1-5): ");
} else {
printf("            " GREEN "Please select(1-5): ");
}
fflush(stdout);
}

// XA功能菜单
void show_xa_menu() {
system("clear");
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(CYAN "              XA功能菜单\n" RESET);
} else {
printf(CYAN "             XA Functions Menu\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);

if (current_language == 0) {
printf(MAGENTA "              1.全枪无后 [%s]\n" RESET, config_params.xa_wh_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              2.有准心聚点 [%s]\n" RESET, config_params.xa_jd1_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              3.无准心聚点 [%s]\n" RESET, config_params.xa_jd2_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);
printf(MAGENTA "              4.全身范围 [%s]\n" RESET, config_params.xa_fw_enabled ? GREEN "开启" MAGENTA : RED "关闭" MAGENTA);

if (config_params.xa_fw_enabled) {
static const char* size_names_cn[] = {"超小身位", "小身位", "中身位", "大身位"};
if (config_params.xa_fw_size >= 0 && config_params.xa_fw_size < 4) {
printf(MAGENTA "              5.身位大小 [%s]\n" RESET, size_names_cn[config_params.xa_fw_size]);
} else {
printf(MAGENTA "              5.身位大小 [未知]\n" RESET);
}
} else {
printf(MAGENTA "              5.身位大小 [未开启]\n" RESET);
}
printf(MAGENTA "              6.返回菜单\n" RESET);
} else {
printf(MAGENTA "              1.No Recoil [%s]\n" RESET, config_params.xa_wh_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "              2.With Crosshair Focus [%s]\n" RESET, config_params.xa_jd1_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "              3.Without Crosshair Focus [%s]\n" RESET, config_params.xa_jd2_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);
printf(MAGENTA "              4.Full Body magic bullet [%s]\n" RESET, config_params.xa_fw_enabled ? GREEN "ON" MAGENTA : RED "OFF" MAGENTA);

if (config_params.xa_fw_enabled) {
static const char* size_names_en[] = {"Extra Small", "Small", "Medium", "Large"};
if (config_params.xa_fw_size >= 0 && config_params.xa_fw_size < 4) {
printf(MAGENTA "              5.Body Size [%s]\n" RESET, size_names_en[config_params.xa_fw_size]);
} else {
printf(MAGENTA "              5.Body Size [Unknown]\n" RESET);
}
} else {
printf(MAGENTA "              5.Body Size [Not Enabled]\n" RESET);
}
printf(MAGENTA "              6.Back to Menu\n" RESET);
}

printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf("            " GREEN "请选择(1-6): ");
} else {
printf("            " GREEN "Please select(1-6): ");
}
fflush(stdout);
}

// A功能选择
void select_range_a() {
char input[256];

while (1) {
show_a_menu();

if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}

if (input[0] == '\n') {
continue;
}

char choice = input[0];

switch (choice) {
case '1': {
if (config_params.a_head_enabled) {
config_params.a_head_current = 12.585f;
config_params.a_head_enabled = false;
save_value_to_config_file(12.585f, A_CONFIG_DIR "/fw1.ini");
} else {
float new_value;
input_float("            请输入头部范围数值:", "            Enter head magic bullet value:", &new_value);
config_params.a_head_current = new_value;
config_params.a_head_enabled = true;
save_value_to_config_file(config_params.a_head_current, A_CONFIG_DIR "/fw1.ini");
}
break;
}
case '2': {
if (config_params.a_chest_enabled) {
config_params.a_chest_current = 21.0f;
config_params.a_chest_enabled = false;
save_value_to_config_file(21.0f, A_CONFIG_DIR "/fw2.ini");
} else {
float new_value;
input_float("            请输入胸部范围数值:", "            Enter chest magic bullet value:", &new_value);
config_params.a_chest_current = new_value;
config_params.a_chest_enabled = true;
save_value_to_config_file(config_params.a_chest_current, A_CONFIG_DIR "/fw2.ini");
}
break;
}
case '3': {
if (config_params.a_abdomen_enabled) {
config_params.a_abdomen_current = 18.0f;
config_params.a_abdomen_enabled = false;
save_value_to_config_file(18.0f, A_CONFIG_DIR "/fw3.ini");
} else {
float new_value;
input_float("            请输入腹部范围数值:", "            Enter abdomen magic bullet value:", &new_value);
config_params.a_abdomen_current = new_value;
config_params.a_abdomen_enabled = true;
save_value_to_config_file(config_params.a_abdomen_current, A_CONFIG_DIR "/fw3.ini");
}
break;
}
case '4': {
if (config_params.a_leg_enabled) {
config_params.a_leg_current = 15.0f;
config_params.a_leg_enabled = false;
save_value_to_config_file(15.0f, A_CONFIG_DIR "/fw4.ini");
} else {
float new_value;
input_float("            请输入腿部范围数值:", "            Enter leg magic bullet value:", &new_value);
config_params.a_leg_current = new_value;
config_params.a_leg_enabled = true;
save_value_to_config_file(config_params.a_leg_current, A_CONFIG_DIR "/fw4.ini");
}
break;
}
case '5':
system("clear");
return;
default:
if (current_language == 0) {
printf("            无效选择，请重新输入！\n");
} else {
printf("            Invalid selection, please try again!\n");
}
sleep(1);
break;
}
}
}

// XA功能选择
void select_range_xa() {
char input[256];

while (1) {
show_xa_menu();

if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}

if (input[0] == '\n') {
continue;
}

char choice = input[0];

switch (choice) {
case '1': {
config_params.xa_wh_enabled = !config_params.xa_wh_enabled;
if (config_params.xa_wh_enabled) {
config_params.xa_wh_current = 8.84170853e-21f;
save_value_to_config_file(8.84170853e-21f, XA_CONFIG_DIR "/wh.ini");
} else {
config_params.xa_wh_current = -0.04694629088f;
save_value_to_config_file(-0.04694629088f, XA_CONFIG_DIR "/wh.ini");
}
break;
}
case '2': {
if (config_params.xa_jd1_enabled) {
config_params.xa_jd1_enabled = false;
config_params.xa_jd2_enabled = false;
remove(XA_CONFIG_DIR "/jd1.ini");
remove(XA_CONFIG_DIR "/jd2.ini");
if (current_language == 0) {
printf("            有准心聚点已关闭\n");
} else {
printf("            With crosshair focus disabled\n");
}
} else {
config_params.xa_jd1_enabled = true;
config_params.xa_jd2_enabled = false;
save_value_to_config_file(8.84170853e-21f, XA_CONFIG_DIR "/jd1.ini");
remove(XA_CONFIG_DIR "/jd2.ini");
if (current_language == 0) {
printf("            已选择有准心聚点\n");
} else {
printf("            Selected: With crosshair focus\n");
}
}
sleep(1);
break;
}
case '3': {
if (config_params.xa_jd2_enabled) {
config_params.xa_jd2_enabled = false;
config_params.xa_jd1_enabled = false;
remove(XA_CONFIG_DIR "/jd1.ini");
remove(XA_CONFIG_DIR "/jd2.ini");
if (current_language == 0) {
printf("            无准心聚点已关闭\n");
} else {
printf("            Without crosshair focus disabled\n");
}
} else {
config_params.xa_jd2_enabled = true;
config_params.xa_jd1_enabled = false;
save_value_to_config_file(8.84170853e-21f, XA_CONFIG_DIR "/jd2.ini");
remove(XA_CONFIG_DIR "/jd1.ini");
if (current_language == 0) {
printf("            已选择无准心聚点\n");
} else {
printf("            Selected: Without crosshair focus\n");
}
}
sleep(1);
break;
}
case '4': {
config_params.xa_fw_enabled = !config_params.xa_fw_enabled;
save_int_to_config_file(config_params.xa_fw_enabled ? 1 : 0, XA_CONFIG_DIR "/fw.ini");
break;
}
case '5': {
if (config_params.xa_fw_enabled) {
system("clear");
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(CYAN "            选择身位大小\n" RESET);
} else {
printf(CYAN "            Select Body Size\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf(MAGENTA "              1. 超小身位\n" RESET);
printf(MAGENTA "              2. 小身位\n" RESET);
printf(MAGENTA "              3. 中身位\n" RESET);
printf(MAGENTA "              4. 大身位\n" RESET);
printf(MAGENTA "              5. 返回菜单\n" RESET);
} else {
printf(MAGENTA "              1. Extra Small\n" RESET);
printf(MAGENTA "              2. Small\n" RESET);
printf(MAGENTA "              3. Medium\n" RESET);
printf(MAGENTA "              4. Large\n" RESET);
printf(MAGENTA "              5. Back to Menu\n" RESET);
}
printf(MAGENTA "====================================\n" RESET);
if (current_language == 0) {
printf("            " GREEN "请选择(1-5): ");
} else {
printf("            " GREEN "Please select(1-5): ");
}
fflush(stdout);

if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}

char size_choice = input[0];

switch (size_choice) {
case '1':
config_params.xa_fw_size = 0;
break;
case '2':
config_params.xa_fw_size = 1;
break;
case '3':
config_params.xa_fw_size = 2;
break;
case '4':
config_params.xa_fw_size = 3;
break;
case '5':
break;
default:
if (current_language == 0) {
printf("            无效选择！\n");
} else {
printf("            Invalid selection!\n");
}
sleep(1);
break;
}
save_int_to_config_file(config_params.xa_fw_size, XA_CONFIG_DIR "/config.ini");
} else {
if (current_language == 0) {
printf("            请先开启全身范围功能！\n");
} else {
printf("            Please enable full body magic bullet first!\n");
}
sleep(1);
}
break;
}
case '6':
system("clear");
return;
default:
if (current_language == 0) {
printf("            无效选择，请重新输入！\n");
} else {
printf("            Invalid selection, please try again!\n");
}
sleep(1);
break;
}
}
}

// 注入所有功能（已删除CB注入）
void inject_all_functions() {
if (current_server == SERVER_UNKNOWN) {
current_server = detect_server_type();
if (current_server == SERVER_UNKNOWN) {
if (current_language == 0) {
printf("             未检测到游戏进程！\n");
} else {
printf("             Game process not detected!\n");
}
fflush(stdout);
return;
}
}

struct ServerConfig *config = get_server_config(current_server);
if (config == NULL) {
if (current_language == 0) {
printf("            错误: 无法获取服务器配置！\n");
} else {
printf("            Error: Cannot get server configuration!\n");
}
fflush(stdout);
return;
}

PACKAGENAME bm;
strcpy(bm, config->package_name);

if (!isapkrunning(bm)) {
if (current_language == 0) {
printf("            错误: 目标进程未运行！\n");
} else {
printf("            Error: Target process is not running!\n");
}
fflush(stdout);
return;
}

ipid = getPID(bm);
if (ipid == 0) {
if (current_language == 0) {
printf("            错误: 无法获取进程ID！\n");
} else {
printf("            Error: Cannot get process ID!\n");
}
fflush(stdout);
return;
}

if (current_language == 0) {
printf("            进程ID: %d\n", ipid);
printf("            服务器: %s\n", config->server_name);
} else {
printf("            Process ID: %d\n", ipid);
printf("            Server: %s\n", config->server_name_en);
}
fflush(stdout);

char mname[] = "libUE4.so";    
long int libbase = getCb(ipid, mname);
if (libbase == 0) {
if (current_language == 0) {
printf("            错误: 无法获取模块基址！\n");
} else {
printf("            Error: Cannot get module base address!\n");
}
fflush(stdout);
return;
}

long int base_addr = libbase + config->base_addr_offset;

// 注入A功能
if (inject_a_parameters(bm, config, libbase, base_addr)) {
if (current_language == 0) {
//printf("            A功能注入完成\n");
} else {
//printf("            A functions injected successfully\n");
}
} else {
if (current_language == 0) {
//printf("            A功能注入失败\n");
} else {
//printf("            A functions injection failed\n");
}
}

// 注入XA功能
inject_xa_parameters(bm, config, libbase);

if (current_language == 0) {
//printf("            所有功能注入完成！\n");
} else {
//printf("            All functions injected successfully!\n");
}
fflush(stdout);
}

// 调试函数
void list_all_processes(void) {
DIR *dir = opendir("/proc");
if (dir == NULL) return;

struct dirent *ptr;
FILE *fp;
char filepath[256];
char filetext[1024];

LOGI("=== 当前运行的进程列表 ===");

while ((ptr = readdir(dir)) != NULL) {
if (!isdigit(ptr->d_name[0])) continue;

snprintf(filepath, sizeof(filepath), "/proc/%s/cmdline", ptr->d_name);
fp = fopen(filepath, "r");
if (fp != NULL) {
if (fgets(filetext, sizeof(filetext), fp) != NULL) {
filetext[strcspn(filetext, "\n")] = 0;
if (strlen(filetext) > 0) {
LOGI("PID: %s, Cmdline: %s", ptr->d_name, filetext);
}
}
fclose(fp);
}
}
closedir(dir);
LOGI("=========================");
}

// 后台检测线程
void *background_detector(void *arg) {
while (program_running) {
sleep(1);

if (check_timeout()) {
bool all_servers_stopped = true;

for (int i = 0; i < NUM_SERVERS; i++) {
if (isapkrunning(server_configs[i].package_name)) {
all_servers_stopped = false;
LOGI("检测到服务器仍在运行: %s", server_configs[i].server_name);
break;
}
}

if (all_servers_stopped) {
if (current_language == 0) {
printf(RED "\n");
printf("====================================\n");
printf("           60秒未检测到游戏进程\n");
printf("           程序自动退出\n");
printf("====================================\n");
printf(RESET "\n");
} else {
printf(RED "\n");
printf("====================================\n");
printf("           No game process detected for 60 seconds\n");
printf("           Program will exit automatically\n");
printf("====================================\n");
printf(RESET "\n");
}
fflush(stdout);
sleep(2);
exit(0);
}
}
}
return NULL;
}

// 语言选择函数（完整版）
void select_language() {
system("clear");
printf(MAGENTA "====================================\n" RESET);
printf(CYAN "             Language Select\n" RESET);
printf(CYAN "             选择语言\n" RESET);
printf(MAGENTA "====================================\n" RESET);
printf(MAGENTA "              1. 中文 (Chinese)\n" RESET);
printf(MAGENTA "              2. 英语 (English)\n" RESET);
printf(MAGENTA "====================================\n" RESET);
printf("" GREEN "请选择(1-2)[Please select(1-2)]: ");
fflush(stdout);

char input[256];
if (fgets(input, sizeof(input), stdin) != NULL) {
char choice = input[0];

if (choice == '1') {
current_language = 0;  // 中文
printf("            已选择中文\n");
} else if (choice == '2') {
current_language = 1;  // 英文
printf("            Selected English\n");
} else {
printf("            Invalid selection, default to Chinese\n");
current_language = 0;  // 默认中文
}
} else {
current_language = 0;  // 默认中文
}
fflush(stdout);
}

// 创建语言文件函数
void create_language_file() {
char filepath_cn[256];
char filepath_en[256];

snprintf(filepath_cn, sizeof(filepath_cn), CONFIG_BASE_DIR "/中文.ini");
snprintf(filepath_en, sizeof(filepath_en), CONFIG_BASE_DIR "/English.ini");

// 检查pz.ini是否存在
FILE *pz_file = fopen(CONFIG_BASE_DIR "/pz.ini", "r");
bool pz_exists = (pz_file != NULL);
if (pz_file) fclose(pz_file);

if (!pz_exists) {
// 如果pz.ini不存在，删除所有语言文件
remove(filepath_cn);
remove(filepath_en);
}

// 根据选择的语言创建对应文件
if (current_language == 0) {
FILE *file = fopen(filepath_cn, "w");
if (file != NULL) {
fprintf(file, "@wangkela");
fclose(file);
}
remove(filepath_en);
} else {
FILE *file = fopen(filepath_en, "w");
if (file != NULL) {
fprintf(file, "@wangkela");
fclose(file);
}
remove(filepath_cn);
}
}

// 主函数（完整版）
int main(int argc, char **argv) {
char input[256];
char choice;

// 检查语言文件是否存在
char chinese_file[256];
char english_file[256];
snprintf(chinese_file, sizeof(chinese_file), CONFIG_BASE_DIR "/中文.ini");
snprintf(english_file, sizeof(english_file), CONFIG_BASE_DIR "/English.ini");
bool lang_file_exists = false;

// 检查语言文件是否存在
if (access(chinese_file, F_OK) == 0) {
lang_file_exists = true;
current_language = 0;  // 中文
} else if (access(english_file, F_OK) == 0) {
lang_file_exists = true;
current_language = 1;  // 英文
}

// 如果语言配置文件存在，检查 pz.ini 是否存在
if (lang_file_exists) {
FILE *pz_file = fopen(CONFIG_BASE_DIR "/pz.ini", "r");
bool pz_exists = (pz_file != NULL);
if (pz_file) fclose(pz_file);

if (!pz_exists) {
// 如果pz.ini不存在，删除所有语言文件
remove(chinese_file);
remove(english_file);
lang_file_exists = false;  // 标记为语言文件不存在
}
}

if (current_language == 0) {
LOGI("=== 亡客范围注入工具 v4.0 (国服/国际服/台服) ===");
} else {
LOGI("=== WangKe magic bullet Injector v4.0 (Chinese/Global/Taiwan) ===");
}

// 如果没有语言配置文件，则显示语言选择菜单
if (!lang_file_exists) {
select_language();
create_language_file();
} else {
if (current_language == 0) {
LOGI("已加载中文语言设置");
} else {
LOGI("English language settings loaded");
}
}

// 询问是否使用循环注入（仅在首次运行且没有pz.ini时）
if (access(CONFIG_BASE_DIR "/pz.ini", F_OK) != 0) {
ask_auto_inject();
}

// 初始化配置文件
init_config_files();

// 加载配置
load_config();

// 创建后台检测线程
pthread_t detector_thread;
if (pthread_create(&detector_thread, NULL, background_detector, NULL) != 0) {
LOGE("创建后台检测线程失败");
} else {
pthread_detach(detector_thread);
LOGI("后台检测线程已启动");
}

// 如果启用了自动注入，创建自动注入线程
pthread_t auto_inject_thread;
if (auto_inject_enabled) {
if (pthread_create(&auto_inject_thread, NULL, auto_inject_loop, NULL) != 0) {
LOGE("创建自动注入线程失败");
auto_inject_enabled = false;
remove(AUTO_INJECT_FILE);  // 创建失败则删除文件
if (current_language == 0) {
printf(RED "自动注入启动失败\n" RESET);
} else {
printf(RED "Auto inject startup failed\n" RESET);
}
} else {
pthread_detach(auto_inject_thread);
LOGI("自动注入线程已启动");
if (current_language == 0) {
printf(GREEN "自动注入已启用\n");
} else {
printf(GREEN "Auto inject enabled\n");
}           
}
}

// 检测服务器类型
current_server = detect_server_type();
update_detect_time();

if (current_server == SERVER_UNKNOWN) {
update_detect_time();
}

// 显示主菜单并处理用户选择
while (1) {
if (check_timeout()) {
if (current_language == 0) {
printf(RED "\n");
printf("====================================\n");
printf("           60秒未检测到游戏进程\n");
printf("           程序自动退出\n");
printf("====================================\n");
printf(RESET "\n");
} else {
printf(RED "\n");
printf("====================================\n");
printf("           No game process detected for 60 seconds\n");
printf("           Program will exit automatically\n");
printf("====================================\n");
printf(RESET "\n");
}
fflush(stdout);
sleep(2);
program_running = false;
exit(0);
}

show_main_menu();

// 修正选项数量计算
int max_choice;
if (auto_inject_enabled) {
max_choice = 3;  // 自动注入模式：1.选择功能 2.保存配置 3.退出程序
} else {
max_choice = 4;  // 正常模式：1.选择功能 2.注入功能 3.保存配置 4.退出程序
}

if (current_language == 0) {
printf("            " GREEN "请选择操作(1-%d): ", max_choice);
} else {
printf("            " GREEN "Please select operation(1-%d): ", max_choice);
}
fflush(stdout);

// 使用fgets替代getchar，解决输入缓冲问题
if (fgets(input, sizeof(input), stdin) == NULL) {
if (feof(stdin)) {
break;
}
continue;
}

// 处理空行
if (input[0] == '\n') {
system("clear");
continue;
}

choice = input[0];  // 获取第一个字符

switch (choice) {
case '1':
select_functions();
update_detect_time();
break;
case '2':
if (auto_inject_enabled) {
// 自动注入模式下，选项2是保存配置
save_config();
} else {
// 正常模式下，选项2是注入功能
inject_all_functions();
}
update_detect_time();
break;
case '3':
if (auto_inject_enabled) {
// 自动注入模式下，选项3是退出
program_running = false;
auto_inject_enabled = false;  // 确保自动注入线程退出
if (current_language == 0) {
printf("            程序退出，感谢使用！");
} else {
printf("            Program exiting, thank you for using!");
}
fflush(stdout);
return 0;
} else {
// 正常模式下，选项3是保存配置
save_config();
update_detect_time();
}
break;
case '4':
if (!auto_inject_enabled) {
// 只有正常模式下才有选项4（退出）
program_running = false;
auto_inject_enabled = false;  // 确保自动注入线程退出
if (current_language == 0) {
printf("            程序退出，感谢使用！");
} else {
printf("            Program exiting, thank you for using!");
}
fflush(stdout);
return 0;
}
break;
default:
if (current_language == 0) {
printf("            无效选择，请重新输入！\n");
} else {
printf("            Invalid selection, please try again!\n");
}
fflush(stdout);
sleep(1);
update_detect_time();
break;
}
}

program_running = false;
auto_inject_enabled = false;  // 确保自动注入线程退出
sleep(1);  // 给线程一点时间退出
return 0;
}
