#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;
bool program_running = true;
int current_language = 0;  // 0=中文, 1=英文

// 颜色定义
#define GREEN "\033[0;32m"
#define RED "\033[0;31m" 
#define RESET "\033[0m"

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

// 服务器配置结构体
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))

// 配置参数结构体
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=大
};

// 全局配置变量
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;

// 配置路径常量
#define CONFIG_BASE_DIR "/sdcard/亡客"
#define A_CONFIG_DIR CONFIG_BASE_DIR "/a"
#define XA_CONFIG_DIR CONFIG_BASE_DIR "/xa"

// 函数声明
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 isapkrunning(char *bm);
int getPIDEx(const char *packageName);
ServerType detect_server_type();
struct ServerConfig *get_server_config(ServerType type);
void load_config();
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 perform_injection();

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

// 改进的内存写入函数
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 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;
}

// 读取浮点数配置
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 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");
}
}

// 指针链解析函数
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;
}

// A功能注入
bool inject_a_parameters(const char *package, struct ServerConfig *config, long int libbase, long int base_addr) {
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 };

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], 
GREEN "            %s注入成功！\n" RESET,
GREEN "            %s injected successfully!\n" RESET,
RED "            %s注入失败！\n" RESET,
RED "            %s injection failed!\n" RESET)) {
success = true;
}
} else {
printf(RED "            %s指针解析失败！\n" RESET, a_names_cn[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) {
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,
GREEN "            全枪无后注入成功！\n" RESET,
GREEN "            No recoil injected successfully!\n" RESET,
RED "            全枪无后注入失败！\n" RESET,
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 {
printf(RED "            全枪无后关闭失败！\n" RESET);
}
}

// 聚点功能
if (config_params.xa_jd1_enabled) {
// 启用有准心聚点
write_memory_value(package, jd1_addr, 8.84170853e-21f,
GREEN "            有准心聚点注入成功！\n" RESET,
GREEN "            Crosshair bullet focus point injected succeeded!\n" RESET,
RED "            有准心聚点注入失败！\n" RESET,
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,
GREEN "            无准心聚点注入成功！\n" RESET,
GREEN "            No crosshair bullet focus point injected successfully!\n" RESET,
RED "            无准心聚点注入失败！\n" RESET,
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],
GREEN "            XA全身范围注入成功！\n" RESET,
GREEN "            XA full body magic bullet injected successfully!\n" RESET,
RED "            XA全身范围注入失败！\n" RESET,
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 perform_injection() {
// 检测服务器类型
current_server = detect_server_type();
if (current_server == SERVER_UNKNOWN) {
printf("未检测到游戏进程！\n");
return;
}

struct ServerConfig *config = get_server_config(current_server);
if (config == NULL) {
printf("错误: 无法获取服务器配置！\n");
return;
}

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

if (!isapkrunning(bm)) {
printf("错误: 目标进程未运行！\n");
return;
}

ipid = getPID(bm);
if (ipid == 0) {
printf("错误: 无法获取进程ID！\n");
return;
}

printf("进程ID: %d\n", ipid);
printf("服务器: %s\n", config->server_name);

char mname[] = "libUE4.so";    
long int libbase = getCb(ipid, mname);
if (libbase == 0) {
printf("错误: 无法获取模块基址！\n");
return;
}

long int base_addr = libbase + config->base_addr_offset;

// 注入A功能
if (inject_a_parameters(bm, config, libbase, base_addr)) {
//printf("A功能注入完成\n");
} else {
//printf("A功能注入失败\n");
}

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

//printf("所有功能注入完成！\n");
fflush(stdout);
}

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

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);
return server_configs[i].type;
}
}

LOGI("未找到任何支持的服务器");
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;
}

// 主函数
int main(int argc, char **argv) {
if (current_language == 0) {
LOGI("=== 亡客范围注入工具 v4.0 (国服/国际服/台服) ===");
} else {
LOGI("=== WangKe magic bullet Injector v4.0 (Chinese/Global/Taiwan) ===");
}

// 初始化配置目录
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);
}

// 加载配置
load_config();

// 执行注入
perform_injection();

if (current_language == 0) {
//printf("程序执行完成，感谢使用！\n");
} else {
//printf("Program execution completed, thank you for using!\n");
}

return 0;
}
