
struct sConfig {

struct sPlayerESP {
    bool Alert;
    bool Line;
    bool Box;
    bool Skeleton;
    bool NoBot;
    bool LootBox;
    bool 血量;
    bool 剩余人数;
    bool 名字;
    bool 距离;
    
    float RadarX;
    float RadarY;
    bool Radar;
    bool RadarDraw2;
    bool Radar1;
    bool Radar2;
    bool Radar3;
    bool Radar4;
   
};
sPlayerESP PlayerESP{0};

struct sOTHER {
    bool HIDEESP;
};
sOTHER OTHER{0};

};
sConfig Config{0};




bool 提示=true;
bool 物资功能=false;
bool 单机设置=true;
bool 联机调试=false;
bool 功能设置=false;
bool 物资调试=false;
bool 坐标调试=false;

bool HIDEESP = true;
bool 人数 = false;
bool 世界 = false;
bool 更多功能 = false;

bool 高跳 = false;
float 高度 = 500.0f;

bool chongchongche = false;
float chongchongche1;
float chongchongche2;
float tocdoquay = 0.0f;

bool 人物变大 = false;
float 巨人 = 1.0f;

bool 飞天跳开 = false;
bool 飞天跳关 = false;
bool 飞天2 = false;
bool 飞天1 = false;
bool 飞天关 = false;

bool 能量加速开 = false;
bool 能量加速关 = false;

bool 伤害测试2 = false;
bool 枪械一套 = false;
bool 枪械变大 = false;
float Gun_Size = 1.0f;
bool 开启伤害 = false;
float 伤害值 = 0.0f;
float 伤害倍率 = 1.0f;

bool 广角 = false;
float 视角 = 90.0f;

bool 自控初始化 = false;
bool 喇叭飞天 = false;
bool 载具加速 = false;
bool 转圈 = false;
bool 转圈2 = false;
bool 无视碰撞开 = false;
bool 无视重力开 = false;
bool 老爷模式 = false;
bool 飞船模式 = false;
float 载具速度 = 1.0f;
float 喇叭高度 = 1.0f;
float XXXC = 3.0f;
bool 开发者菜单 = false;
bool 修复着陆 = false;
bool 修复部分 = false;
bool 修复车辆 = false;
bool DamageFix = false;
float 驾驶员X偏移 = 100.0f;
float 驾驶员Y偏移 = 0.0f;
float 驾驶员Z偏移 = 80.0f;
float 乘客X偏移 = 50.0f;
float 乘客Y偏移 = 50.0f;
float 乘客Z偏移 = 80.0f;
extern void 执行单次生成();
extern void 更新建筑跟随状态();
extern void 探测并添加附近建筑(float Radius);
extern void 清空建筑列表();
extern void 加载选中的建筑();
extern void 获取对象();
inline bool 建筑跟随模式 = false;
inline float 建筑探测半径 = 1000.0f;
inline float 建筑生成偏移 = 500.0f;
inline char 建筑路径输入[256] = {0};

bool(*ogm)();
bool gm(){
return true;
}
void CreateItem(int ItemType, int TypeSpecificID, int Count) {
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=ItemType;
Item.TypeSpecificID=TypeSpecificID;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(Count);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
 
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}

void src(int ItemType, int TypeSpecificID, int Count) {
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=ItemType;
Item.TypeSpecificID=TypeSpecificID;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(Count);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
    
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}

// 武器皮肤 - 类型1 (正确)
void AKM_Chicheng() { src(1, 101001001, 10); }
void AKM_Rongyao() { src(1, 101001002, 10); }
void AKM_Wumujinwen() { src(1, 101001003, 10); }
void AKM_Xueshi() { src(1, 101001004, 10); }
void AKM_Kuangnu() { src(1, 101001005, 10); }

void M16A4_Shachi() { src(1, 101002001, 10); }
void M16A4_Qingyao() { src(1, 101002002, 10); }
void M16A4_Wumujinwen() { src(1, 101002003, 10); }
void M16A4_Huangshi() { src(1, 101002004, 10); }
void M16A4_Yezhanyinghao() { src(1, 101002005, 10); }
void M16A4_Kuangnu() { src(1, 101002006, 10); }

void SCARL_Kuangnu() { src(1, 101003001, 10); }
void SCARL_Wumujinwen() { src(1, 101003002, 10); }
void SCARL_Chicheng() { src(1, 101003003, 10); }
void SCARL_Xueshi() { src(1, 101003004, 10); }

void M416_RocketGirl() { src(1, 101004001, 10); }
void M416_Wumujinwen() { src(1, 101004002, 10); }
void M416_Kuishe() { src(1, 101004003, 10); }
void M416_Tuya() { src(1, 101004004, 10); }
void M416_Shamofengbao() { src(1, 101004005, 10); }
void M416_Xueyumicai() { src(1, 101004006, 10); }
void M416_Xueshi() { src(1, 101004007, 10); }
void M416_Chicheng() { src(1, 101004008, 10); }
void M416_Spring() { src(1, 101004009, 10); }

void GROZA_Kuangnu() { src(1, 101005001, 10); }
void AUG_Xueshi() { src(1, 101006001, 10); }

void UZI_Kuangnu() { src(1, 102001001, 10); }

void UMP9_Chicheng() { src(1, 102002001, 10); }
void UMP9_Rongyao() { src(1, 102002002, 10); }
void UMP9_RocketGirl() { src(1, 102002003, 10); }
void UMP9_Spring() { src(1, 102002004, 10); }

void Kar98K_Qingyao() { src(1, 103001001, 10); }
void Kar98K_Wumujinwen() { src(1, 103001002, 10); }
void Kar98K_FireLava() { src(1, 103001003, 10); }
void Kar98K_Xueshi() { src(1, 103001004, 10); }
void Kar98K_Spring() { src(1, 103001005, 10); }

void AWM_Rainbow() { src(1, 103003001, 10); }
void SKS_Chicheng() { src(1, 103004001, 10); }

void S686_Chicheng() { src(1, 104001001, 10); }

void P92_Kuangnu() { src(1, 106001001, 10); }
void P1911_Qingyao() { src(1, 106002001, 10); }

void Crowbar_RedNight() { src(1, 108002001, 10); }

void Pan_DoubleYolk() { src(1, 108004001, 10); }
void Pan_Survivor() { src(1, 108004002, 10); }
void Pan_NoHunt() { src(1, 108004003, 10); }
void Pan_RottenTomato() { src(1, 108004004, 10); }
void Pan_Forward() { src(1, 108004005, 10); }
void Pan_RedNight() { src(1, 108004006, 10); }

// 表情动作 - 类型22 (正确)
void 你好() { src(22, 2200101, 20); }
void 感谢() { src(22, 2200201, 20); }
void 鼓掌() { src(22, 2200301, 20); }
void 大笑() { src(22, 2200401, 20); }
void 来这里() { src(22, 2200501, 20); }
void 走() { src(22, 2200601, 20); }
void 否定() { src(22, 2200701, 20); }
void 肯定() { src(22, 2200801, 20); }
void 投降() { src(22, 2200901, 20); }
void 愤怒() { src(22, 2201001, 20); }
void 摇摆舞() { src(22, 2201101, 20); }
void 电摇() { src(22, 2201201, 20); }
void 拍灰舞() { src(22, 2201301, 20); }
void 俄舞() { src(22, 2201401, 20); }
void 安静() { src(22, 2201501, 20); }
void 雀跃() { src(22, 2201601, 20); }
void 崩溃() { src(22, 2201701, 20); }
void 海带舞() { src(22, 2201801, 20); }
void 街舞() { src(22, 2201901, 20); }
void 壁虎步() { src(22, 2202001, 20); }
void 机械舞() { src(22, 2202101, 20); }
void 蹦迪舞() { src(22, 2202201, 20); }
void 斗舞() { src(22, 2202301, 20); }
void 秀舞() { src(22, 2202401, 20); }
void 拉票舞() { src(22, 2202501, 20); }
void 创造舞() { src(22, 2202601, 20); }
void 三连赞() { src(22, 2202701, 20); }
void 桑巴舞() { src(22, 2202801, 20); }
void 空翻() { src(22, 2202901, 20); }
void 摇篮舞() { src(22, 2203001, 20); }
void 摆裙舞() { src(22, 2203101, 20); }
void 吃鸡舞() { src(22, 2203201, 20); }
void 抖胸舞() { src(22, 2203301, 20); }
void 青蛙舞() { src(22, 2203401, 20); }
void 甩手舞() { src(22, 2203501, 20); }
void 点赞() { src(22, 2203601, 20); }
void 欢庆舞() { src(22, 2203701, 20); }
void 螃蟹舞() { src(22, 2203801, 20); }
void 快看我() { src(22, 2203901, 20); }
void 难过() { src(22, 2204001, 20); }
void 扭秧歌() { src(22, 2204101, 20); }
void 拜年男() { src(22, 2204201, 20); }
void 红包来了() { src(22, 2204301, 20); }
void 拜年女() { src(22, 2204401, 20); }

// 服装 - 类型4 (正确)
void 雪地吉利服() { src(4, 403038, 10); }
void 晶翼女神套装() { src(4, 403409, 10); }
void 黑曜金尊套装() { src(4, 403410, 10); }
void 火箭少女101() { src(4, 453021, 10); }
void 至尊金龙外套() { src(4, 403188, 10); }
void S1战斗裤() { src(4, 404049, 10); }
void S1战斗外套() { src(4, 403124, 10); }
void 小黄衣() { src(4, 403017, 10); }
void 小黄裤() { src(4, 404001, 10); }
void 黑色连帽大衣() { src(4, 403184, 10); }
void 西部牛仔面罩() { src(4, 402037, 10); }
void 黑色rock() { src(4, 403178, 10); }
void 青色面罩() { src(4, 402032, 10); }
void 师傅专用外套() { src(4, 403075, 10); }
void 时尚圣诞套装() { src(4, 403393, 10); }
void 卡路里套装() { src(4, 403408, 10); }

// 货币 - 类型100 (正确)
void 现金() { src(100, 1011, 520); }
void Q币() { src(100, 1012, 520); }
void 点券() { src(100, 1006, 520); }

// 特效道具 - 类型30 (正确)
void 新年烟花() { src(30, 3000301, 50); }
void 新年爆竹() { src(30, 3000302, 50); }
void 红包() { src(30, 3001027, 50); }
void 坚甲() { src(30, 3001028, 50); }
void 利爪() { src(30, 3001029, 50); }
void 小鸡() { src(30, 3002001, 50); }
void 鸡蛋() { src(30, 3002002, 50); }
void 南瓜() { src(30, 3001013, 50); }
void 圣诞糖果() { src(30, 3001014, 50); }
void 西瓜() { src(30, 3001001, 50); }
void 小黄鸭() { src(30, 3001002, 90); }
void 鸡() { src(30, 3001003, 90); }

// 道具/材料 - 类型16 (正确)
void 机密情报() { src(16, 1602056, 50); }
void 鸡神奖杯() { src(16, 1602046, 50); }
void 胜利手雷() { src(16, 1602039, 50); }
void 足球() { src(16, 1602030, 50); }

// 消耗品 - 类型6 (正确，但需要修正参数个数)
void 震爆弹() { src(6, 602001, 50); }
void 烟雾弹() { src(6, 602002, 50); }
void 燃烧瓶() { src(6, 602003, 50); }
void 破片手榴弹() { src(6, 602004, 50); }
void 跳舞弹() { src(6, 602006, 50); }
// 修正参数个数错误：
void 大春雷() { src(6, 602010, 50); }      // 原来有4个参数
void 鞭炮() { src(6, 602011, 50); }        // 原来有4个参数
void 小春雷() { src(6, 602012, 50); }      // 原来有4个参数
void 南瓜炸弹() { src(6, 602013, 50); }    // 原来有4个参数
void 苹果() { src(6, 602005, 50); }
void 圣诞玩具苹果() { src(6, 602007, 50); }
void 圣诞小鸡玩偶() { src(6, 602008, 50); }
void 冬季雪球() { src(6, 602009, 50); }
void 肾上腺素() { src(6, 601002, 50); }

// 武器 - 类型1 (正确)
void AKM() { src(1, 101001, 10); }
void M416() { src(1, 101004, 10); }
void AWM() { src(1, 103003, 10); }
void M16A4() { src(1, 101002, 10); }
void GROZA() { src(1, 101005, 10); }
void SCARL() { src(1, 101003, 10); }
void AUG() { src(1, 101006, 10); }
void QBZ() { src(1, 101007, 10); }
void M762() { src(1, 101008, 10); }
void MK47() { src(1, 101009, 10); }
void G36C() { src(1, 101010, 10); }
void UZI() { src(1, 102001, 10); }
void UMP9() { src(1, 102002, 10); }
void Vector() { src(1, 102003, 10); }
void Thompson() { src(1, 102004, 10); }
void PP19() { src(1, 102005, 10); }
void Kar98K() { src(1, 103001, 10); }
void M24() { src(1, 103002, 10); }
void SKS() { src(1, 103004, 10); }
void VSS() { src(1, 103005, 10); }
void Mini14() { src(1, 103006, 10); }
void Mk14() { src(1, 103007, 10); }
void Win94() { src(1, 103008, 10); }
void SLR() { src(1, 103009, 10); }
void QBU() { src(1, 103010, 10); }
void S686() { src(1, 104001, 10); }
void S1897() { src(1, 104002, 10); }
void S12K() { src(1, 104003, 10); }
void M249() { src(1, 105001, 10); }
void DP28() { src(1, 105002, 10); }
void P92() { src(1, 106001, 10); }
void P1911() { src(1, 106002, 10); }
void R1895() { src(1, 106003, 10); }
void P18C() { src(1, 106004, 10); }
void R45() { src(1, 106005, 10); }
void SawedOff() { src(1, 106006, 10); }
void SignalGun() { src(1, 106007, 10); }
void Scorpion() { src(1, 106008, 10); }
void ChickenFirework() { src(1, 106095, 10); }
void LanternFirework() { src(1, 106096, 10); }
void BeastSignal() { src(1, 106097, 10); }
void ChristmasSignal() { src(1, 106098, 10); }
void NewYearFirework() { src(1, 106099, 10); }
void Crossbow() { src(1, 107001, 10); }
void RiotShield() { src(1, 107003, 10); }
void Machete() { src(1, 108001, 10); }
void Crowbar() { src(1, 108002, 10); }
void Sickle() { src(1, 108003, 10); }
void Pan() { src(1, 108004, 10); }

// 弹药 - 类型3 (正确)
void Bullet762() { src(3, 302001, 900); }
void Bullet556() { src(3, 303001, 900); }
void ShotgunShell() { src(3, 304001, 900); }
void Bullet45() { src(3, 305001, 900); }
void Magnum() { src(3, 306001, 900); }
void SignalFlare() { src(3, 308001, 900); }
void Arrow() { src(3, 307001, 900); }
void FireworkShell() { src(3, 308002, 900); }
void BeastBait() { src(3, 308003, 900); }

// 配件 - 类型2 (修正：之前是类型1，应该改为类型2)
void Choke() { src(2, 201001, 10); }
void SMGCompensator() { src(2, 201002, 10); }
void SniperCompensator() { src(2, 201003, 10); }
void SMGFlashHider() { src(2, 201004, 10); }
void SniperFlashHider() { src(2, 201005, 10); }
void SMGSilencer() { src(2, 201006, 10); }
void SniperSilencer() { src(2, 201007, 10); }
void PistolSilencer() { src(2, 201008, 10); }
void RifleCompensator() { src(2, 201009, 10); }
void RifleFlashHider() { src(2, 201010, 10); }
void RifleSilencer() { src(2, 201011, 10); }
void Duckbill() { src(2, 201012, 10); }
void AngledGrip() { src(2, 202001, 10); }
void VerticalGrip() { src(2, 202002, 10); }
void LightGrip() { src(2, 202004, 10); }
void HalfGrip() { src(2, 202005, 10); }
void ThumbGrip() { src(2, 202006, 10); }
void LaserSight() { src(2, 202007, 10); }
void RedDot() { src(2, 203001, 10); }
void Holographic() { src(2, 203002, 10); }
void Scope2x() { src(2, 203003, 10); }
void Scope4x() { src(2, 203004, 10); }
void Scope8x() { src(2, 203005, 10); }
void CantedSight() { src(2, 203018, 10); }
void PistolExtMag() { src(2, 204001, 10); }
void PistolQuickMag() { src(2, 204002, 10); }
void PistolQuickExtMag() { src(2, 204003, 10); }
void SMGExtMag() { src(2, 204004, 10); }
void SMGQuickMag() { src(2, 204005, 10); }
void SMGQuickExtMag() { src(2, 204006, 10); }
void SniperExtMag() { src(2, 204007, 10); }
void SniperQuickMag() { src(2, 204008, 10); }
void SniperQuickExtMag() { src(2, 204009, 10); }
void ShotgunBulletLoops() { src(2, 204010, 10); }
void RifleExtMag() { src(2, 204011, 10); }
void RifleQuickMag() { src(2, 204012, 10); }
void RifleQuickExtMag() { src(2, 204013, 10); }
void Kar98kLoops() { src(2, 204014, 10); }
void UziStock() { src(2, 205001, 10); }
void TacticalStock() { src(2, 205002, 10); }
void CheekPad() { src(2, 205003, 10); }
void Quiver() { src(2, 205004, 10); }

// 装备 - 类型5 (正确)
void 夜视仪() { src(5, 504001, 10); }
void HelmetLv3() { src(5, 502003, 10); }
void VestLv3() { src(5, 503003, 10); }
void BackpackLv3() { src(5, 501003, 10); }
void HelmetLv1() { src(5, 502001, 10); }
void VestLv1() { src(5, 503001, 10); }
void BackpackLv1() { src(5, 501004, 10); }
void HelmetLv2() { src(5, 502002, 10); }
void VestLv2() { src(5, 503002, 10); }
void BackpackLv2() { src(5, 501005, 10); }
void ChristmasHelmet() { src(5, 502010, 10); }
void BeastHelmet() { src(5, 502011, 10); }
// 一键刷新所有皮肤武器
void SpawnAllSkinWeapons() {
    AKM_Chicheng(); AKM_Rongyao(); AKM_Wumujinwen(); AKM_Xueshi(); AKM_Kuangnu();
    M16A4_Shachi(); M16A4_Qingyao(); M16A4_Wumujinwen(); M16A4_Huangshi(); M16A4_Yezhanyinghao(); M16A4_Kuangnu();
    SCARL_Kuangnu(); SCARL_Wumujinwen(); SCARL_Chicheng(); SCARL_Xueshi();
    M416_RocketGirl(); M416_Wumujinwen(); M416_Kuishe(); M416_Tuya(); M416_Shamofengbao(); 
    M416_Xueyumicai(); M416_Xueshi(); M416_Chicheng(); M416_Spring();
    GROZA_Kuangnu(); AUG_Xueshi();
    UZI_Kuangnu();
    Kar98K_Qingyao(); Kar98K_Wumujinwen(); Kar98K_FireLava(); Kar98K_Xueshi(); Kar98K_Spring();
    AWM_Rainbow();
    
    Crowbar_RedNight();
    Pan_DoubleYolk(); Pan_Survivor(); Pan_NoHunt(); Pan_RottenTomato(); Pan_Forward(); Pan_RedNight();
}
void 一键生成其他物资() {
    红包(); 坚甲(); 利爪(); 小鸡(); 鸡蛋(); 南瓜(); 圣诞糖果(); 
    西瓜(); 小黄鸭(); 鸡(); 机密情报(); 鸡神奖杯(); 胜利手雷(); 足球(); 
    震爆弹(); 烟雾弹(); 燃烧瓶(); 破片手榴弹(); 跳舞弹(); 大春雷(); 
    鞭炮(); 小春雷(); 南瓜炸弹(); 苹果(); 圣诞玩具苹果(); 圣诞小鸡玩偶(); 
    冬季雪球(); 肾上腺素(); Q币(); 现金(); 点券(); 新年爆竹(); 新年烟花();
}
void 一键生成衣服() {
    雪地吉利服();晶翼女神套装();黑曜金尊套装();火箭少女101();至尊金龙外套();S1战斗裤();S1战斗外套();小黄衣();小黄裤();黑色连帽大衣();西部牛仔面罩();黑色rock();青色面罩();师傅专用外套();时尚圣诞套装();卡路里套装();
}

void 一键生成动作() {
    你好(); 感谢(); 鼓掌(); 大笑(); 来这里(); 走(); 否定(); 肯定(); 投降(); 愤怒(); 
    摇摆舞(); 电摇(); 拍灰舞(); 俄舞(); 安静(); 雀跃(); 崩溃(); 海带舞(); 街舞(); 
    壁虎步(); 机械舞(); 蹦迪舞(); 斗舞(); 秀舞(); 拉票舞(); 创造舞(); 三连赞(); 
    桑巴舞(); 空翻(); 摇篮舞(); 摆裙舞(); 吃鸡舞(); 抖胸舞(); 青蛙舞(); 甩手舞(); 
    点赞(); 欢庆舞(); 螃蟹舞(); 快看我(); 难过(); 扭秧歌(); 拜年男(); 红包来了(); 
    拜年女();
}
void SpawnAllWeapons() {
    AKM(); M416(); AWM(); M16A4(); GROZA(); SCARL(); AUG(); QBZ(); M762(); MK47(); G36C(); 
    UZI(); UMP9(); Vector(); Thompson(); PP19(); Kar98K(); M24(); SKS(); VSS(); Mini14(); 
    Mk14(); Win94(); SLR(); QBU(); S686(); S1897(); S12K(); M249(); DP28(); P92(); P1911(); 
    R1895(); P18C(); R45(); SawedOff(); SignalGun(); Scorpion(); ChickenFirework(); LanternFirework(); 
    BeastSignal(); ChristmasSignal(); NewYearFirework(); Crossbow(); RiotShield(); Machete(); 
    Crowbar(); Sickle(); Pan();
}

void SpawnAllAmmo() {
    Bullet762(); Bullet556(); ShotgunShell(); Bullet45(); Magnum(); SignalFlare(); 
    Arrow(); FireworkShell(); BeastBait();
}

void SpawnAllAttachments() {
    Choke(); SMGCompensator(); SniperCompensator(); SMGFlashHider(); SniperFlashHider(); 
    SMGSilencer(); SniperSilencer(); PistolSilencer(); RifleCompensator(); RifleFlashHider(); 
    RifleSilencer(); Duckbill(); AngledGrip(); VerticalGrip(); LightGrip(); HalfGrip(); 
    ThumbGrip(); LaserSight(); RedDot(); Holographic(); Scope2x(); Scope4x(); Scope8x(); 
    CantedSight(); PistolExtMag(); PistolQuickMag(); PistolQuickExtMag(); SMGExtMag(); 
    SMGQuickMag(); SMGQuickExtMag(); SniperExtMag(); SniperQuickMag(); SniperQuickExtMag(); 
    ShotgunBulletLoops(); RifleExtMag(); RifleQuickMag(); RifleQuickExtMag(); Kar98kLoops(); 
    UziStock(); TacticalStock(); CheekPad(); Quiver();
}

void SpawnAllGear() {
    HelmetLv3(); VestLv3(); BackpackLv3(); HelmetLv1(); VestLv1(); BackpackLv1(); 夜视仪();
    HelmetLv2(); VestLv2(); BackpackLv2(); ChristmasHelmet(); BeastHelmet();
}




void SpawnItemM1(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=501003;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}
void SpawnItemM2(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=502003;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}
void SpawnItemM3(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=503003;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}



void SpawnItemM4(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=404049;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}
void SpawnItemM5(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=403124;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}



void SpawnItemM6(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=404001;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}
void SpawnItemM7(){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=5;
Item.TypeSpecificID=403017;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(1);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}
void SpawnItem(int ItemID,int ItemType,int Count){
获取对象();
FTransform Transform;
if(PlayerCharacter){
Transform=PlayerCharacter->GetTransform();
}
AActor*Actor=UGameplayStatics::BeginSpawningActorFromClass(GetWorld(),APickUpWrapperActor::StaticClass(),Transform,true,UGameplayStatics::GetPlayerController(GetWorld(),0));
APickUpWrapperActor*PickUpActor=reinterpret_cast<APickUpWrapperActor*>(Actor);
if(PickUpActor){
FItemDefineID Item;
Item.Type=ItemType;
Item.TypeSpecificID=ItemID;
PickUpActor->SetDefineID(Item);
PickUpActor->SetCountOnServerAfterSpawn(Count);
PickUpActor->ShowMesh(true);
    PickUpActor->ShowActor();     
     UGameplayStatics::FinishSpawningActor(PickUpActor,Transform);
PickUpActor->RegisterToPlayerPickUpList();
}
}

static bool bDisableTimeouts = false;  // 默认启用超时检查
// 判断物品类型
int getItemType(int itemID) {
    // 1. 货币类 (1000-1015)
    if (itemID >= 1000 && itemID <= 1015) {
        return 100;
    }
    
    // 2. 武器类 (101001-108004)
    if ((itemID >= 101001 && itemID <= 101010) ||      // 突击步枪
        (itemID >= 102001 && itemID <= 102006) ||      // 冲锋枪
        (itemID >= 103001 && itemID <= 103010) ||      // 狙击枪
        (itemID >= 104001 && itemID <= 104003) ||      // 霰弹枪
        (itemID >= 105001 && itemID <= 105002) ||      // 轻机枪
        (itemID >= 106001 && itemID <= 106099) ||      // 手枪/特殊武器
        (itemID == 107001 || itemID == 107003) ||      // 十字弩/防爆盾
        (itemID >= 108001 && itemID <= 108004)) {      // 近战武器
        return 1;
    }
    
    // 3. 配件类 (201001-296008)
    if ((itemID >= 201001 && itemID <= 201012) ||      // 枪口类
        (itemID >= 202001 && itemID <= 202007) ||      // 握把类
        (itemID >= 203001 && itemID <= 203018) ||      // 瞄准镜类
        (itemID >= 203104 && itemID <= 203104) ||      // 瞄准镜测试皮肤
        (itemID >= 204001 && itemID <= 204014) ||      // 弹匣类
        (itemID >= 205001 && itemID <= 205006) ||      // 枪托类
        (itemID >= 281002 && itemID <= 281004) ||      // 默认枪口
        (itemID >= 283009 && itemID <= 283010) ||      // 默认枪口
        (itemID >= 291001 && itemID <= 291010) ||      // 突击步枪默认弹匣
        (itemID >= 292001 && itemID <= 292006) ||      // 冲锋枪默认弹匣
        (itemID >= 293002 && itemID <= 293010) ||      // 狙击枪默认弹匣
        (itemID >= 294003 && itemID <= 294003) ||      // 霰弹枪默认弹匣
        (itemID >= 295001 && itemID <= 295002) ||      // 轻机枪默认弹匣
        (itemID >= 296001 && itemID <= 296008)) {      // 手枪默认弹匣
        return 2;
    }
    
    // 4. 弹药类 (301001-308003)
    if ((itemID >= 301001 && itemID <= 301001) ||      // 9毫米子弹
        (itemID >= 302001 && itemID <= 302001) ||      // 7.62毫米子弹
        (itemID >= 303001 && itemID <= 303001) ||      // 5.56毫米子弹
        (itemID >= 304001 && itemID <= 304001) ||      // 12口径霰弹
        (itemID >= 305001 && itemID <= 305001) ||      // .45口径子弹
        (itemID >= 306001 && itemID <= 306001) ||      // .300马格南子弹
        (itemID >= 307001 && itemID <= 307001) ||      // 弩箭
        (itemID >= 308001 && itemID <= 308003)) {      // 信号弹/烟花弹/年兽诱饵弹
        return 3;
    }
    
    // 5. 服装类 (400997-407008)
    if ((itemID >= 400997 && itemID <= 400999) ||      // 创建头
        (itemID >= 401003 && itemID <= 401992) ||      // 帽子类
        (itemID >= 401992001 && itemID <= 401992002) || // 经典脸型体验
        (itemID >= 401993 && itemID <= 401999) ||      // 经典脸型
        (itemID >= 402001 && itemID <= 402079) ||      // 面罩/眼镜类
        (itemID >= 403001 && itemID <= 403999) ||      // 上衣类
        (itemID >= 404001 && itemID <= 404231) ||      // 下装类
        (itemID >= 405001 && itemID <= 405999) ||      // 鞋子类
        (itemID >= 406001 && itemID <= 406003) ||      // 头发
        (itemID >= 406001001 && itemID <= 406001002) || // 经典发型体验
        (itemID >= 40601001 && itemID <= 40606009) ||  // 经典发型
        (itemID >= 407001001 && itemID <= 407001004) || // 脸涂
        (itemID >= 407008 && itemID <= 407008) ||      // 海岛探路者墨镜
        (itemID >= 410001 && itemID <= 410039) ||      // 套装类
        (itemID >= 453001 && itemID <= 455003) ||      // 合作定制服装
        (itemID >= 473001 && itemID <= 474009)) {      // 腾讯系定制服装
        return 4;
    }
    
    // 6. 防具/背包类 (501001-504001)
    if ((itemID >= 501001 && itemID <= 501006) ||      // 背包
        (itemID >= 502001 && itemID <= 502011) ||      // 头盔
        (itemID >= 503001 && itemID <= 503003) ||      // 防弹衣
        (itemID >= 504001 && itemID <= 504001)) {      // 夜视仪
        return 5;
    }
    
    // 7. 消耗品类 (601001-603001)
    if ((itemID >= 601001 && itemID <= 601061) ||      // 医疗品
        (itemID >= 602001 && itemID <= 602014) ||      // 投掷物
        (itemID >= 603001 && itemID <= 603001)) {      // 燃料
        return 6;
    }
    
    // 8. 降落伞类 (701001-703086)
    if ((itemID >= 701001 && itemID <= 703086)) {
        return 4;  // 注意：根据文件，降落伞也是类型4
    }
    
    // 9. 宝箱/礼盒类 (1500001-1601002)
    if ((itemID >= 1500001 && itemID <= 1500008) ||    // 军备宝箱
        (itemID >= 1501001 && itemID <= 1514005) ||    // 各种宝箱礼盒
        (itemID == 1601002)) {                         // 改名卡
        return 15;
    }
    
    // 10. 道具/材料类 (1601001-1602118)
    if ((itemID == 1601001) ||                         // 重置角色卡
        (itemID >= 1602001 && itemID <= 1602118)) {    // 各种道具材料
        return 16;
    }
    
    // 11. 军团相关 (1701001)
    if (itemID == 1701001) {
        return 17;
    }
    
    // 12. 头像框类 (2001001-2004308)
    if ((itemID >= 2001001 && itemID <= 2004308)) {
        return 20;
    }
    
    // 13. 经验/金币卡类 (2101001-2105001)
    if ((itemID >= 2101001 && itemID <= 2105001)) {
        return 21;
    }
    
    // 14. 表情动作类 (2200101-2204401)
    if ((itemID >= 2200101 && itemID <= 2204401)) {
        return 22;
    }
    
    // 15. 时效房卡类 (2401001-2408055)
    if ((itemID >= 2401001 && itemID <= 2408055)) {
        return 24;
    }
    
    // 16. 模式体验房卡类 (2501001-2508001)
    if ((itemID >= 2501001 && itemID <= 2508001)) {
        return 25;
    }
    
    // 17. 特效道具类 (3000301-3002002)
    if ((itemID >= 3000301 && itemID <= 3002002)) {
        return 30;
    }
    
    // 18. 浇水完成证明类 (4001001-4001006)
    if ((itemID >= 4001001 && itemID <= 4001006)) {
        return 40;
    }
    
    // 19. 武器皮肤配件 (100100101-200400103)
    if ((itemID >= 100100101 && itemID <= 100400903) ||  // M416等武器皮肤配件
        (itemID >= 200200101 && itemID <= 200400103)) {  // UMP9等武器皮肤配件
        return 2;  // 注意：根据文件，这些是类型2
    }
    
    // 20. 武器皮肤 (101001001-108004006)
    if ((itemID >= 101001001 && itemID <= 108004006)) {
        return 1;  // 注意：根据文件，武器皮肤是类型1
    }
    
    // 默认返回1（武器类）
    return 1;
}


#undef bind  // fix NDK macro collision with std::bind
using namespace std;
#define STATUS_ICON_RUNNING "◆"  // 实心圆
#define STATUS_ICON_STOPPED "◆"  // 空心圆
static std::mutex g_log_mutex;
static std::vector<std::string> g_log_lines;
static const size_t MAX_LOG_LINES = 2000;
static bool g_AutoWeaponFixEnabled = false;
static bool enabled = false;
class UDPProxy {
public:
    UDPProxy(int local_port=7788, const std::string &target_ip="192.168.100.100", int target_port=7777)
        : local_port(local_port), target_ip(target_ip), target_port(target_port),
          sockfd(-1), running(false) {}

    ~UDPProxy() { stop(); }

    bool start() {
        if (running.load()) return true;

        // 创建新的日志文件名
        {
            auto now = std::chrono::system_clock::now();
            std::time_t t = std::chrono::system_clock::to_time_t(now);
            std::tm tm = *std::localtime(&t);
            char buf[128];
            snprintf(buf, sizeof(buf), "/sdcard/udp_proxy_%04d%02d%02d_%02d%02d%02d.log",
                     tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
            logfile = buf;
        }

        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0) {
            push_log(std::string("[ERR] socket create failed: ") + strerror(errno));
            return false;
        }
        int opt = 1;
        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

        sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons(local_port);

        if (::bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
            push_log(std::string("[ERR] bind failed: ") + strerror(errno));
            close(sockfd);
            sockfd = -1;
            return false;
        }

        // 日志头
        {
            std::ofstream f(logfile, std::ios::app);
            if (f.is_open()) {
                f << std::string(80, '=') << "\nUDP代理日志 - 启动时间: " << timestamp_date()
                  << "\n监听端口: " << local_port << " -> 目标地址: " << target_ip << ":" << target_port
                  << "\n" << std::string(80, '=') << "\n\n";
            }
        }

        running.store(true);
        worker = std::thread(&UDPProxy::recv_loop, this);
        push_log(std::string("[启动] 监听 ") + std::to_string(local_port) + " -> 转发到 " +
                 target_ip + ":" + std::to_string(target_port));
        return true;
    }

    void stop() {
        if (!running.load()) return;
        running.store(false);
        if (sockfd != -1) { close(sockfd); sockfd = -1; }
        if (worker.joinable()) worker.join();
        push_log(std::string("[STOP] 服务端已关闭"));
    }

    bool is_running() const { return running.load(); }

    void get_logs(std::vector<std::string>& out) {
        std::lock_guard<std::mutex> lk(log_mutex);
        out = logs;
    }

private:
    int local_port;
    std::string target_ip;
    int target_port;
    int sockfd;
    std::atomic<bool> running;
    std::thread worker;

    std::mutex log_mutex;
    std::vector<std::string> logs;

    std::mutex clients_mutex;
    std::map<std::pair<std::string,int>, long long> client_timestamps;

    std::string logfile;

    // 时间函数
    static std::string timestamp_ms() {
        using namespace std::chrono;
        auto now = system_clock::now();
        auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
        auto t = system_clock::to_time_t(now);
        std::tm tm = *std::localtime(&t);
        char buf[64];
        snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03lld", tm.tm_hour, tm.tm_min, tm.tm_sec, (long long)ms.count());
        return buf;
    }

    static std::string timestamp_date() {
        auto t = std::time(nullptr);
        std::tm tm = *std::localtime(&t);
        char buf[64];
        snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
                 tm.tm_hour, tm.tm_min, tm.tm_sec);
        return buf;
    }

    static std::string to_hex(const uint8_t *buf, size_t len) {
        std::ostringstream oss;
        oss << std::hex << std::setfill('0');
        for (size_t i = 0; i < len; ++i) oss << std::setw(2) << (int)(buf[i] & 0xFF);
        return oss.str();
    }

    void push_log(const std::string &s) {
        std::lock_guard<std::mutex> lk(log_mutex);
        logs.push_back(s);
        if (logs.size() > 2000) logs.erase(logs.begin(), logs.begin() + (logs.size() - 2000));
        std::ofstream f(logfile, std::ios::app);
        if (f.is_open()) f << s << "\n";
    }

    void push_packet_log(const std::string &direction, double delay, ssize_t len, const std::string &ip, int port, const std::string &hexdata) {
        std::ostringstream ss;
        ss << timestamp_ms() << " | " << direction << " | 延迟: " << std::fixed << std::setprecision(2)
           << delay << "ms | 长度: " << len << "字节 | 地址: " << ip << ":" << port;
        push_log(ss.str());
        push_log("原始数据: " + hexdata);
    }

    void recv_loop() {
        while (running.load()) {
            sockaddr_in addr;
            socklen_t addrlen = sizeof(addr);
            uint8_t buf[65536];
            ssize_t len = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &addrlen);
            if (len < 0) {
                if (!running.load()) break;
                push_log(std::string("[ERR] recvfrom failed: ") + strerror(errno));
                continue;
            }

            auto t0 = std::chrono::high_resolution_clock::now();
            char ipbuf[64];
            inet_ntop(AF_INET, &addr.sin_addr, ipbuf, sizeof(ipbuf));
            int port = ntohs(addr.sin_port);
            bool from_client = (port != target_port);

            if (from_client) {
                {
                    std::lock_guard<std::mutex> lk(clients_mutex);
                    client_timestamps[{ipbuf, port}] =
                        std::chrono::duration_cast<std::chrono::milliseconds>(
                            std::chrono::system_clock::now().time_since_epoch()).count();
                }

                sockaddr_in target{};
                target.sin_family = AF_INET;
                inet_pton(AF_INET, target_ip.c_str(), &target.sin_addr);
                target.sin_port = htons(target_port);
                sendto(sockfd, buf, len, 0, (struct sockaddr*)&target, sizeof(target));

                auto t1 = std::chrono::high_resolution_clock::now();
                double delay = std::chrono::duration<double, std::milli>(t1 - t0).count();
                push_packet_log("客户端->服务端", delay, len, ipbuf, port, to_hex(buf, len));
            } else {
                std::pair<std::string,int> latest;
                bool found = false;
                {
                    std::lock_guard<std::mutex> lk(clients_mutex);
                    long long best = 0;
                    for (auto &kv : client_timestamps) {
                        if (kv.second > best) { best = kv.second; latest = kv.first; found = true; }
                    }
                }
                if (found) {
                    sockaddr_in dst{};
                    dst.sin_family = AF_INET;
                    inet_pton(AF_INET, latest.first.c_str(), &dst.sin_addr);
                    dst.sin_port = htons(latest.second);
                    sendto(sockfd, buf, len, 0, (struct sockaddr*)&dst, sizeof(dst));

                    auto t1 = std::chrono::high_resolution_clock::now();
                    double delay = std::chrono::duration<double, std::milli>(t1 - t0).count();
                    push_packet_log("服务端->客户端", delay, len, latest.first, latest.second, to_hex(buf, len));
                }
            }
        }
    }
};

static UDPProxy* g_proxy = nullptr;

extern "C" bool StartPacketProxy() {
    if (g_proxy && g_proxy->is_running()) return true;
    g_proxy = new UDPProxy();
    return g_proxy->start();
}

extern "C" void StopPacketProxy() {
    if (g_proxy) {
        g_proxy->stop();
        delete g_proxy;
        g_proxy = nullptr;
    }
}

extern "C" void GetPacketProxyLogs(std::vector<std::string>& out) {
    if (g_proxy) g_proxy->get_logs(out);
}



///===========抓包结束=========///
inline void push_log(const string &s) {
    std::lock_guard<std::mutex> lk(g_log_mutex);
    if (g_log_lines.size() >= MAX_LOG_LINES) {
        g_log_lines.erase(g_log_lines.begin(), g_log_lines.begin() + (g_log_lines.size() - MAX_LOG_LINES + 1));
    }
    g_log_lines.push_back(s);
    std::cout << s << std::endl;
}

static string bytes_to_hex_lower(const uint8_t *buf, size_t len) {
    std::ostringstream oss;
    oss << std::hex << std::setfill('0');
    for (size_t i = 0; i < len; ++i) {
        oss << std::setw(2) << (int)(buf[i] & 0xFF);
    }
    string s = oss.str();
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
    return s;
}

static vector<uint8_t> hex_to_bytes(const string &hex_in) {
    string filtered;
    filtered.reserve(hex_in.size());
    for (char c : hex_in) {
        if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) filtered.push_back(c);
    }
    if (filtered.size() % 2 == 1) filtered.insert(filtered.begin(), '0');
    vector<uint8_t> out;
    out.reserve(filtered.size()/2);
    for (size_t i = 0; i + 1 < filtered.size(); i += 2) {
        unsigned int byte = 0;
        std::stringstream ss;
        ss << std::hex << filtered.substr(i,2);
        ss >> byte;
        out.push_back(static_cast<uint8_t>(byte & 0xFF));
    }
    return out;
}

static string current_time_str() {
    using namespace std::chrono;
    auto now = system_clock::now();
    auto t = system_clock::to_time_t(now);
    std::tm tm = *std::localtime(&t);
    char buf[64];
    auto ms = duration_cast<milliseconds>(now.time_since_epoch()).count() % 1000;
    std::snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03lld", tm.tm_hour, tm.tm_min, tm.tm_sec, (long long)ms);
    return string(buf);
}


class GameUDPProxy {
private:
    // 成员变量
    int listen_port;
    std::string target_host;
    int target_port;
    std::string log_file;
    std::atomic<bool> running;  // 改为 atomic
    int sockfd;
    sockaddr_in client_address;
    std::thread worker;  // 添加线程成员
    
    // 响应数据存储
    std::vector<std::vector<uint8_t>> response_data;
    size_t response_index;
    std::string current_map;

public:
    GameUDPProxy(int listen_port=7788, const std::string &target_host="127.0.0.1", 
                 int target_port=7777, const std::string &log_file="")
    : listen_port(listen_port), target_host(target_host), target_port(target_port),
      log_file(log_file), running(false), sockfd(-1), response_index(0), current_map("无")
    {
        // 构造函数中不自动加载数据
    }

    ~GameUDPProxy() {
        stop();
    }

    bool start() {
        if (running.load()) return true;

        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0) {
            push_log(std::string("[错误] 套接字创建失败: ") + strerror(errno));
            return false;
        }

        int opt = 1;
        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

        sockaddr_in addr;
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons(listen_port);

        if (::bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
            push_log(std::string("[错误] 绑定失败: ") + strerror(errno));
            close(sockfd);
            sockfd = -1;
            return false;
        }

        running.store(true);
        
        // 启动日志头
        push_log(repeat_string("=", 80));
        push_log(std::string("UDP代理启动 - 时间: ") + get_current_time());
        push_log(std::string("监听端口: ") + std::to_string(listen_port) + " -> 目标地址: " + target_host + ":" + std::to_string(target_port));
        push_log(std::string("当前地图数据: ") + current_map);
        push_log(repeat_string("=", 80));
        push_log("代理服务已启动，等待客户端连接...");

        // 在新线程中运行
        worker = std::thread(&GameUDPProxy::run, this);
        
        return true;
    }

    void stop() {
        running.store(false);
        if (sockfd != -1) {
            close(sockfd);
            sockfd = -1;
        }
        if (worker.joinable()) {
            worker.join();
        }
        push_log("代理服务已停止");
    }

    bool is_running() const { 
        return running.load(); 
    }

    // 设置地图数据
    bool set_map_data(const std::string& map_choice) {
        std::map<std::string, std::string> map_files = {
            {"1", "训练场"},
            {"2", "海岛"}, 
            {"3", "雪地"},
            {"4", "雨林"},
            {"5", "沙漠"}
        };
        
        if (map_files.find(map_choice) != map_files.end()) {
            current_map = map_files[map_choice];
            
            // 根据选择设置对应的数据
            const char* log_data = nullptr;
            if (map_choice == "1") {
                log_data = TRAINING_LOG_DATA;
            } else if (map_choice == "2") {
                log_data = ISLAND_LOG_DATA;
            } else if (map_choice == "3") {
                log_data = SNOW_LOG_DATA;
            }else if (map_choice == "4") {
                log_data = YULINH_LOG_DATA;
            }else if (map_choice == "5") {
                log_data = SANOP_LOG_DATA;
            }
            
            response_data.clear();  // 清空原有数据
            response_index = 0;
            
            if (log_data) {
                load_response_data_from_string(log_data);
                
                // 立即在日志中显示地图切换信息
                std::ostringstream ss;
                ss << "已切换到地图: " << current_map << " (数据条数: " << response_data.size() << ")";
                push_log(ss.str());
                
                return true;
            }
        }
        return false;
    }

    std::string get_current_map() const { 
        return current_map; 
    }

private:
    // 从字符串加载响应数据
    void load_response_data_from_string(const char* log_content) {
        std::istringstream iss(log_content);
        std::string line;
        
        // 解析服务端->客户端的数据
        std::vector<std::string> lines;
        while (std::getline(iss, line)) {
            lines.push_back(line);
        }
        
        for (size_t i = 0; i < lines.size(); i++) {
            if (lines[i].find("服务端->客户端") != std::string::npos && i + 1 < lines.size()) {
                if (lines[i + 1].find("原始数据:") != std::string::npos) {
                    size_t pos = lines[i + 1].find("原始数据: ");
                    if (pos != std::string::npos) {
                        std::string hex_data = lines[i + 1].substr(pos + 10);
                        // 移除可能的空格
                        hex_data.erase(std::remove(hex_data.begin(), hex_data.end(), ' '), hex_data.end());
                        
                        try {
                            auto bytes = hex_to_bytes(hex_data);
                            if (!bytes.empty()) {
                                response_data.push_back(bytes);
                            }
                        } catch (...) {
                            push_log("[错误] 解析十六进制数据失败: " + hex_data);
                        }
                    }
                }
            }
        }
    }

    // 根据客户端数据获取对应的服务端响应
    std::vector<uint8_t> get_response_for_client(const std::vector<uint8_t>& client_data) {
        if (response_data.empty()) {
            // 如果没有预加载的数据，返回默认响应
            return hex_to_bytes("19137909a95516a2a40ba6feb8f8c91c94d7388ee999a66004");
        }
        
        // 简单策略：轮询返回预加载的响应数据
        response_index = (response_index + 1) % response_data.size();
        return response_data[response_index];
    }

    void run() {
        while (running.load()) {
            sockaddr_in client_addr;
            socklen_t client_len = sizeof(client_addr);
            uint8_t buffer[4096];
            
            // 设置超时，避免阻塞无法退出
            struct timeval tv;
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
            
            ssize_t len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 
                                 (struct sockaddr*)&client_addr, &client_len);
            
            if (len < 0) {
                if (!running.load()) break;
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    continue;
                }
                if (errno != EAGAIN && errno != EWOULDBLOCK) {
                    push_log(std::string("[错误] 接收数据失败: ") + strerror(errno));
                }
                continue;
            }
            
            if (len == 0) {
                continue;
            }
            
            client_address = client_addr;
            
            // 记录客户端消息
            std::vector<uint8_t> data(buffer, buffer + len);
            log_packet("客户端->服务端", 0.24, len, client_addr, data);
            
            // 处理客户端请求并发送响应
            handle_client_request(data, client_addr);
        }
    }

    void handle_client_request(const std::vector<uint8_t>& client_data, const sockaddr_in& client_addr) {
        try {
            // 获取对应的服务端响应
            auto response_data_vec = get_response_for_client(client_data);
            
            // 模拟网络延迟
            std::this_thread::sleep_for(std::chrono::milliseconds(45));
            
            // 发送响应
            ssize_t sent = sendto(sockfd, response_data_vec.data(), response_data_vec.size(), 0,
                                 (struct sockaddr*)&client_addr, sizeof(client_addr));
            
            if (sent > 0) {
                // 记录服务端响应
                log_packet("服务端->客户端", 0.33, response_data_vec.size(), client_addr, response_data_vec);
            } else {
                push_log(std::string("[错误] 发送响应失败: ") + strerror(errno));
            }
            
        } catch (const std::exception& e) {
            push_log(std::string("[错误] 处理客户端请求失败: ") + e.what());
        }
    }

    // 记录数据包日志
    void log_packet(const std::string& direction, double delay, size_t len, 
                   const sockaddr_in& addr, const std::vector<uint8_t>& data) {
        char ipbuf[64];
        inet_ntop(AF_INET, &addr.sin_addr, ipbuf, sizeof(ipbuf));
        int port = ntohs(addr.sin_port);
        
        std::ostringstream ss;
        ss << current_time_str() << " | " << direction << " | 延迟: " 
           << std::fixed << std::setprecision(2) << delay << "ms | 长度: " 
           << len << "字节 | 地址: " << ipbuf << ":" << port;
        push_log(ss.str());
        push_log("原始数据: " + bytes_to_hex_lower(data.data(), data.size()));
        push_log(repeat_string("-", 60));
    }

    // 获取当前时间字符串（带毫秒）
    std::string current_time_str() {
        auto now = std::chrono::system_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()) % 1000;
        auto t = std::chrono::system_clock::to_time_t(now);
        std::tm tm = *std::localtime(&t);
        char buf[64];
        std::snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%03lld", 
                     tm.tm_hour, tm.tm_min, tm.tm_sec, (long long)ms.count());
        return std::string(buf);
    }

    // 获取当前日期时间字符串
    std::string get_current_time() {
        auto now = std::chrono::system_clock::now();
        std::time_t t = std::chrono::system_clock::to_time_t(now);
        std::tm tm = *std::localtime(&t);
        char buf[64];
        std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
        return std::string(buf);
    }

    // 字符串重复辅助函数
    std::string repeat_string(const std::string& str, int n) {
        std::string result;
        for (int i = 0; i < n; ++i) {
            result += str;
        }
        return result;
    }
};

// 全局代理实例
static GameUDPProxy* g_proxy_server = nullptr;

// 启动代理服务
extern "C" bool StartEmbeddedUDPServer() {
    if (g_proxy_server && g_proxy_server->is_running()) return true;
    
    try {
        // 如果还没有创建实例，先创建
        if (!g_proxy_server) {
            g_proxy_server = new GameUDPProxy(7788, "127.0.0.1", 7777, "");
        }
        return g_proxy_server->start();
    } catch (...) {
        push_log("[错误] 启动嵌入式服务器异常");
        return false;
    }
}

// 停止代理服务
extern "C" void StopEmbeddedUDPServer() {
    try {
        if (g_proxy_server) {
            g_proxy_server->stop();
            delete g_proxy_server;
            g_proxy_server = nullptr;
        }
    } catch (...) {
        push_log("[错误] 停止嵌入式服务器异常");
    }
}

// 设置地图数据
extern "C" bool SetProxyMapData(const std::string& map_choice) {
    // 确保代理实例存在
    if (!g_proxy_server) {
        g_proxy_server = new GameUDPProxy(7788, "127.0.0.1", 7777, "");
    }
    return g_proxy_server->set_map_data(map_choice);
}

// 获取当前地图
extern "C" std::string GetProxyCurrentMap() {
    if (g_proxy_server) {
        return g_proxy_server->get_current_map();
    }
    return "无";
}

// 获取代理日志
extern "C" void GetEmbeddedLogs(std::vector<std::string>& out_lines) {
    std::lock_guard<std::mutex> lk(g_log_mutex);
    out_lines = g_log_lines;
}


// ==== Original main.cpp content follows ====

// ====================================================
// 车辆修复专用日志系统 - 独立于现有日志系统
// ====================================================

namespace VehicleFixLog {
    static std::vector<std::string> LogEntries;
    static std::mutex LogMutex;
    static const int MAX_LOG_ENTRIES = 500;
    
    // 添加日志
    void AddLog(const std::string& message) {
        std::lock_guard<std::mutex> lock(LogMutex);
        
        // 获取当前时间 - 修复编译错误
        time_t now = time(0);
        struct tm* tstruct = localtime(&now);
        if (tstruct) {
            char buf[80];
            strftime(buf, sizeof(buf), "[%H:%M:%S] ", tstruct);
            std::string fullMessage = std::string(buf) + message;
            LogEntries.push_back(fullMessage);
        } else {
            LogEntries.push_back(message);
        }
        
        // 限制日志数量
        if (LogEntries.size() > MAX_LOG_ENTRIES) {
            LogEntries.erase(LogEntries.begin());
        }
    }
    
    // 清空日志
    void ClearLogs() {
        std::lock_guard<std::mutex> lock(LogMutex);
        LogEntries.clear();
    }
    
    // 获取日志副本
    std::vector<std::string> GetLogs() {
        std::lock_guard<std::mutex> lock(LogMutex);
        return LogEntries;
    }
    
    // 获取最近N条日志
    std::vector<std::string> GetRecentLogs(int count) {
        std::lock_guard<std::mutex> lock(LogMutex);
        if (LogEntries.size() <= count) {
            return LogEntries;
        }
        return std::vector<std::string>(LogEntries.end() - count, LogEntries.end());
    }
}

// 车辆修复日志宏
#define VEHICLE_LOG(...) \
    do { \
        char buffer[512]; \
        snprintf(buffer, sizeof(buffer), __VA_ARGS__); \
        VehicleFixLog::AddLog(buffer); \
    } while(0)

// 错误处理函数
void HandleVehicleFixError(const std::string& errorMessage, 
                          SDK::ASTExtraBaseCharacter* Char = nullptr,
                          SDK::ASTExtraVehicleBase* Vehicle = nullptr)
{
    std::string errorLog = "[错误] ";
    errorLog += errorMessage;
    
    if (Char) {
        errorLog += " | 角色: ";
        if (Char->PlayerState) {
            errorLog += Char->PlayerState->PlayerName.ToString();
        } else {
            errorLog += "未知";
        }
    }
    
    if (Vehicle) {
        char addrBuffer[20];
        snprintf(addrBuffer, sizeof(addrBuffer), "%p", Vehicle);
        errorLog += " | 车辆地址: ";
        errorLog += addrBuffer;
    }
    
    VEHICLE_LOG("%s", errorLog.c_str());
}

// ====================================================
// 车辆修复系统数据结构
// ====================================================

struct PlayerInfo
{
    SDK::APlayerState* PS;
    std::string Name;
    int UID;
    SDK::ASTExtraBaseCharacter* Character;

    // --- 车辆信息 ---
    bool bInVehicle = false;
    SDK::ASTExtraVehicleBase* Vehicle = nullptr;
    int VehicleSeatIdx = -1;
};

std::vector<PlayerInfo> RegisteredPlayers;

// 状态跟踪
std::map<SDK::APlayerController*, int> LastSeatIndices;
std::map<SDK::APlayerController*, SDK::ASTExtraVehicleBase*> LastVehicles;
std::map<SDK::APlayerController*, bool> PlayerInVehicleState;

// ====================================================
// 辅助函数
// ====================================================

// 辅助函数：构建座位Socket名称
std::string GetSeatSocketName(int SeatIndex)
{
    if (SeatIndex == 0)
        return "seat_driver";
    else
        return "seat_passenger_" + std::to_string(SeatIndex);
}

inline std::string GetObjectClassNameEx(UObject* Object)
{
    if (!Object) return "NULL_OBJ";
    if (!Object->ClassPrivate) return "NULL_CLASS";

    try
    {
        return Object->ClassPrivate->NamePrivate.GetName();
    }
    catch (...)
    {
        return "ERR";
    }
}

// ====================================================
// 玩家管理函数
// ====================================================

void RegisterPlayer(SDK::APlayerState* PS, SDK::ASTExtraBaseCharacter* C)
{
    PlayerInfo info;
    info.PS = PS;
    info.Name = PS->PlayerName.ToString();
    info.UID = PS->PlayerID;
    info.Character = C;
    info.Vehicle = C->CurrentVehicle;
    info.VehicleSeatIdx = C->VehicleSeatIdx;
    info.bInVehicle = (C->CurrentVehicle != nullptr);

    RegisteredPlayers.push_back(info);
    
    VEHICLE_LOG("[玩家管理] 注册玩家: %s (UID: %d) | 车辆: %s | 座位: %d", 
               info.Name.c_str(), 
               info.UID,
               info.bInVehicle ? "是" : "否",
               info.VehicleSeatIdx);
}

bool IsHostPlayer(SDK::APlayerState* PS, SDK::UWorld* World)
{
    if (!PS || !World) return false;

    auto* GI = World->OwningGameInstance;
    if (!GI || GI->LocalPlayers.Num() == 0) return false;

    auto* LocalPC = GI->LocalPlayers[0]->PlayerController;
    if (!LocalPC) return false;

    return PS->Owner == LocalPC;
}

SDK::ASTExtraBaseCharacter* GetCharacterFromController(SDK::APlayerController* PC)
{
    if (!PC) {
        VEHICLE_LOG("[角色获取] 控制器为空指针");
        return nullptr;
    }
    
    static SDK::ASTExtraPlayerController* CachedSTPC = nullptr;
    static SDK::ASTExtraBaseCharacter* CachedCharacter = nullptr;
    
    if (CachedSTPC == PC && CachedCharacter)
        return CachedCharacter;
    
    SDK::ASTExtraPlayerController* STPC = nullptr;
    if (PC->IsA(SDK::ASTExtraPlayerController::StaticClass()))
    {
        STPC = (SDK::ASTExtraPlayerController*)PC;
        if (STPC->STExtraBaseCharacter)
        {
            CachedSTPC = STPC;
            CachedCharacter = STPC->STExtraBaseCharacter;
            return CachedCharacter;
        }
    }
    
    SDK::ASTExtraBaseCharacter* fromUtil = SDK::USTExtraVehicleUtils::GetCharacter(STPC ? STPC : (SDK::ASTExtraPlayerController*)PC);
    if (fromUtil)
    {
        CachedSTPC = STPC;
        CachedCharacter = fromUtil;
        return fromUtil;
    }
    
    if (PC->Pawn && PC->Pawn->IsA(SDK::ASTExtraBaseCharacter::StaticClass()))
    {
        CachedSTPC = STPC;
        CachedCharacter = (SDK::ASTExtraBaseCharacter*)PC->Pawn;
        return CachedCharacter;
    }

    return nullptr;
}

bool IsKnown(SDK::APlayerState* ps)
{
    for (size_t i = 0; i < RegisteredPlayers.size(); i++)
    {
        if (!RegisteredPlayers[i].PS) 
            continue;
            
        if (RegisteredPlayers[i].PS == ps)
            return true;
    }
    return false;
}

inline float GetLocalTime()
{
    static auto start_time = std::chrono::high_resolution_clock::now();
    auto now = std::chrono::high_resolution_clock::now();
    return std::chrono::duration<float>(now - start_time).count();
}

// ====================================================
// 车辆调试函数
// ====================================================

void DebugVehicleReplication(SDK::ASTExtraVehicleBase* Vehicle)
{
    if (!Vehicle) {
        VEHICLE_LOG("[车辆调试] 车辆为空指针");
        return;
    }
    
    VEHICLE_LOG("[车辆调试] 地址: %p | 引擎启动: %d | 反作弊: %d | 座位数量: %d",
                Vehicle,
                Vehicle->bIsEngineStarted,
                Vehicle->bEnableAntiCheat,
                (Vehicle->VehicleSeats ? Vehicle->VehicleSeats->SeatOccupiers.Num() : 0));
}

// ====================================================
// 服务端车辆修复逻辑
// ====================================================

void ProcessServerVehicleFix(SDK::ASTExtraPlayerController* STEPC,
                            SDK::ASTExtraBaseCharacter* Char,
                            SDK::ASTExtraVehicleBase* State_Vehicle)
{
    if (!STEPC) {
        HandleVehicleFixError("STEPC为空指针");
        return;
    }
    
    if (!Char) {
        HandleVehicleFixError("角色为空指针");
        return;
    }
    
    if (!State_Vehicle) {
        HandleVehicleFixError("车辆为空指针", Char);
        return;
    }
    
    if (!STEPC->VehicleUserComp) {
        HandleVehicleFixError("VehicleUserComp为空指针", Char, State_Vehicle);
        return;
    }
    
    // 确保VehicleUserComp的Character指向正确的角色
    if (!STEPC->VehicleUserComp->Character && Char)
    {
        STEPC->VehicleUserComp->Character = (SDK::ASTExtraPlayerCharacter*)Char;
        VEHICLE_LOG("[服务端修复] 设置VehicleUserComp角色");
    }
    
 /*   // 调试信息：打印当前车辆状态
    VEHICLE_LOG("[服务端修复] 玩家: %s | 车辆状态: %d | 当前座位: %d | 引擎已启动: %d",
                Char->PlayerState ? Char->PlayerState->PlayerName.ToString().c_str() : "未知",
                (int)STEPC->VehicleUserComp->VehicleUserState,
                Char->VehicleSeatIdx,
                State_Vehicle->bIsEngineStarted);*/
    
    // 主要车辆修复逻辑
    if (STEPC->VehicleUserComp->VehicleUserState == SDK::ESTExtraVehicleUserState::ESTExtraVehicleUserState__EVUS_AsDriver &&
        State_Vehicle->VehicleSeats && 
        State_Vehicle->VehicleSeats->SeatOccupiers.Num() > 0)
    {
        // 检查驾驶员座位是否为空
        SDK::ASTExtraPlayerCharacter* CurrentDriver = State_Vehicle->VehicleSeats->SeatOccupiers[0];
        
        if (CurrentDriver == nullptr)
        {
            // 驾驶员座位为空，执行完整的上车流程
            VEHICLE_LOG("[服务端修复] 驾驶员座位为空，开始修复...");
            
            // 1. 请求进入车辆
            STEPC->VehicleUserComp->ReqEnterVehicle(State_Vehicle, SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_DriversSeat);
            
            // 2. 设置座位占用者
            State_Vehicle->VehicleSeats->SeatOccupiers[0] = (SDK::ASTExtraPlayerCharacter*)Char;
            
            // 3. 启动车辆引擎并禁用反作弊
            State_Vehicle->bIsEngineStarted = true;
            State_Vehicle->bEnableAntiCheat = false;
            
            // 4. 调用车辆座位附加处理函数
            State_Vehicle->HandleOnSeatAttached(
                (SDK::ASTExtraPlayerCharacter*)Char,
                SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_DriversSeat,
                0
            );
            
            // 5. 更新角色状态
            Char->ForcePlayerUpdateAnimation();
            Char->VehicleSeatIdx = 0;
            Char->bWasOnVehicle = true;
            Char->CurrentVehicle = State_Vehicle;
            
            // 6. 强制网络更新
            Char->ForceNetUpdate();
            State_Vehicle->ForceNetUpdate();
            
            VEHICLE_LOG("[服务端修复] 驾驶员座位已修复并占用");
        }
        else if (CurrentDriver != (SDK::ASTExtraPlayerCharacter*)Char)
        {
            // 驾驶员座位已被其他角色占用，处理座位冲突
            VEHICLE_LOG("[服务端修复] 驾驶员座位已被其他玩家占用，尝试寻找空座位...");
            
            // 寻找其他空座位
            bool bFoundEmptySeat = false;
            for (int seatIdx = 1; seatIdx < State_Vehicle->VehicleSeats->SeatOccupiers.Num(); seatIdx++)
            {
                if (State_Vehicle->VehicleSeats->SeatOccupiers[seatIdx] == nullptr)
                {
                    // 找到空座位，作为乘客上车
                    STEPC->VehicleUserComp->ReqEnterVehicle(
                        State_Vehicle,
                        SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_PassengersSeat
                    );
                    
                    State_Vehicle->VehicleSeats->SeatOccupiers[seatIdx] = (SDK::ASTExtraPlayerCharacter*)Char;
                    
                    // 调用乘客座位附加处理
                    State_Vehicle->HandleOnSeatAttached(
                        (SDK::ASTExtraPlayerCharacter*)Char,
                        SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_PassengersSeat,
                        seatIdx
                    );
                    
                    Char->ForcePlayerUpdateAnimation();
                    Char->VehicleSeatIdx = seatIdx;
                    Char->bWasOnVehicle = true;
                    Char->CurrentVehicle = State_Vehicle;
                    
                    Char->ForceNetUpdate();
                    State_Vehicle->ForceNetUpdate();
                    
                    VEHICLE_LOG("[服务端修复] 玩家已放置到乘客座位 %d", seatIdx);
                    bFoundEmptySeat = true;
                    break;
                }
            }
            
            if (!bFoundEmptySeat)
            {
                VEHICLE_LOG("[服务端修复] 没有可用空座位");
            }
        }
        else
        {
            // 当前角色已经是驾驶员，确保状态正确
            Char->CurrentVehicle = State_Vehicle;
            Char->bWasOnVehicle = true;
            Char->ForceNetUpdate();
            State_Vehicle->ForceNetUpdate();
            VEHICLE_LOG("[服务端修复] 玩家已经是驾驶员，状态已更新");
        }
    }
    else if (STEPC->VehicleUserComp->VehicleUserState == SDK::ESTExtraVehicleUserState::ESTExtraVehicleUserState__EVUS_ASPassenger &&
             State_Vehicle->VehicleSeats && 
             State_Vehicle->VehicleSeats->SeatOccupiers.Num() > 0)
    {
        // 乘客状态逻辑
        bool bIsInVehicle = false;
        int currentSeatIdx = -1;
        
        // 检查角色是否在车辆座位上
        for (int seatIdx = 0; seatIdx < State_Vehicle->VehicleSeats->SeatOccupiers.Num(); seatIdx++)
        {
            if (State_Vehicle->VehicleSeats->SeatOccupiers[seatIdx] == (SDK::ASTExtraPlayerCharacter*)Char)
            {
                bIsInVehicle = true;
                currentSeatIdx = seatIdx;
                break;
            }
        }
        
        if (bIsInVehicle)
        {
            // 角色在车辆上，确保状态正确
            Char->VehicleSeatIdx = currentSeatIdx;
            Char->bWasOnVehicle = true;
            Char->CurrentVehicle = State_Vehicle;
            Char->ForceNetUpdate();
            VEHICLE_LOG("[服务端修复] 玩家在乘客座位 %d，状态已更新", currentSeatIdx);
        }
        else
        {
            // 角色不在车辆上，尝试作为乘客上车
            VEHICLE_LOG("[服务端修复] 玩家不在车辆上，尝试作为乘客上车...");
            for (int seatIdx = 1; seatIdx < State_Vehicle->VehicleSeats->SeatOccupiers.Num(); seatIdx++)
            {
                if (State_Vehicle->VehicleSeats->SeatOccupiers[seatIdx] == nullptr)
                {
                    STEPC->VehicleUserComp->ReqEnterVehicle(
                        State_Vehicle,
                        SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_PassengersSeat
                    );
                    
                    State_Vehicle->VehicleSeats->SeatOccupiers[seatIdx] = (SDK::ASTExtraPlayerCharacter*)Char;
                    
                    State_Vehicle->HandleOnSeatAttached(
                        (SDK::ASTExtraPlayerCharacter*)Char,
                        SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_PassengersSeat,
                        seatIdx
                    );
                    
                    Char->ForcePlayerUpdateAnimation();
                    Char->VehicleSeatIdx = seatIdx;
                    Char->bWasOnVehicle = true;
                    Char->CurrentVehicle = State_Vehicle;
                    
                    Char->ForceNetUpdate();
                    State_Vehicle->ForceNetUpdate();
                    
                    VEHICLE_LOG("[服务端修复] 玩家已作为乘客进入座位 %d", seatIdx);
                    break;
                }
            }
        }
    }
    else
    {
        // 不在车辆上的状态处理 - 修复枚举错误
        VEHICLE_LOG("[服务端修复] 玩家不在车辆上，状态: %d", (int)STEPC->VehicleUserComp->VehicleUserState);
        if (Char->CurrentVehicle)
        {
            // 清理旧车辆座位
            SDK::ASTExtraVehicleBase* OldVehicle = Char->CurrentVehicle;
            int OldSeatIdx = Char->VehicleSeatIdx;
            
            if (OldSeatIdx >= 0 && OldSeatIdx < OldVehicle->VehicleSeats->SeatOccupiers.Num())
            {
                if (OldVehicle->VehicleSeats->SeatOccupiers[OldSeatIdx] == (SDK::ASTExtraPlayerCharacter*)Char)
                {
                    OldVehicle->VehicleSeats->SeatOccupiers[OldSeatIdx] = nullptr;
                }
            }
            
            Char->CurrentVehicle = nullptr;
            Char->VehicleSeatIdx = -1;
            Char->bWasOnVehicle = false;
            
            Char->ForceNetUpdate();
            OldVehicle->ForceNetUpdate();
            
            VEHICLE_LOG("[服务端修复] 玩家已从车辆移除");
        }
    }
}

// ====================================================
// 客户端车辆位置和视角修复
// ====================================================

void ProcessClientVehicleFix(SDK::ASTExtraPlayerController* STEPC,
                           SDK::ASTExtraBaseCharacter* Char,
                           SDK::ASTExtraVehicleBase* Vehicle,
                           int SeatIdx,
                           bool bIsLocalPlayer)
{
    if (!STEPC) {
        HandleVehicleFixError("STEPC为空指针");
        return;
    }
    
    if (!Char) {
        HandleVehicleFixError("角色为空指针");
        return;
    }
    
    if (!Vehicle) {
        HandleVehicleFixError("车辆为空指针", Char);
        return;
    }
    
    bool bIsDriver = (SeatIdx == 0);
    
    // 只有本地玩家才执行客户端特定的修复
    if (bIsLocalPlayer)
    {
        VEHICLE_LOG("[客户端修复] 本地玩家 | 座位: %d | 是驾驶员: %s", 
                   SeatIdx, 
                   bIsDriver ? "是" : "否");
        
        // 1. 角色位置和附加修复
        if (Vehicle->RootComponent)
        {
            // 先分离角色（如果已附加）
            Char->K2_DetachFromActor(
                (SDK::EDetachmentRule)1,
                (SDK::EDetachmentRule)1,
                (SDK::EDetachmentRule)1);
            
            // 使用K2_AttachToComponent将角色附加到车辆的根组件
            SDK::FName SocketName = SDK::FName();
            Char->K2_AttachToComponent(Vehicle->RootComponent, SocketName,
                (SDK::EAttachmentRule)1,
                (SDK::EAttachmentRule)1,
                (SDK::EAttachmentRule)1,
                false);
            
            // 设置相对位置和旋转
            SDK::FTransform RelativeTransform;
            
            // 根据座位设置不同的相对位置
            if (bIsDriver)
            {
                // 驾驶员位置：使用用户调节的偏移
                RelativeTransform.Translation.X = 驾驶员X偏移;   // 前方
                RelativeTransform.Translation.Y = 驾驶员Y偏移;   // 中心
                RelativeTransform.Translation.Z = 驾驶员Z偏移;   // 高度
            }
            else
            {
                // 乘客位置：根据座位索引调整
                RelativeTransform.Translation.X = 乘客X偏移;                           // 稍微靠前
                RelativeTransform.Translation.Y = (SeatIdx % 2 == 0 ? 乘客Y偏移 : -乘客Y偏移);  // 左右交替
                RelativeTransform.Translation.Z = 乘客Z偏移;                           // 高度
            }
            
            // 设置旋转
            RelativeTransform.Rotation.X = 0.0f;
            RelativeTransform.Rotation.Y = 0.0f;
            RelativeTransform.Rotation.Z = 0.0f;
            RelativeTransform.Rotation.W = 1.0f;
            
            // 缩放
            RelativeTransform.Scale3D.X = 1.0f;
            RelativeTransform.Scale3D.Y = 1.0f;
            RelativeTransform.Scale3D.Z = 1.0f;
            
            // 应用相对变换
            SDK::FHitResult SweepHitResult;
            Char->K2_SetActorRelativeTransform(RelativeTransform, false, true, &SweepHitResult);
            
            // 更新座位索引
            Char->VehicleSeatIdx = SeatIdx;
            
            VEHICLE_LOG("[客户端修复] 角色已附加到车辆，相对位置: (%.1f, %.1f, %.1f)",
                       RelativeTransform.Translation.X,
                       RelativeTransform.Translation.Y,
                       RelativeTransform.Translation.Z);
        }
        
        // 2. 控制权转移
        if (Char->Controller)
        {
            if (bIsDriver)
            {
                // 驾驶员：控制权转移给车辆
                Char->Controller->Possess(Vehicle);
                
                // 设置摄像机跟随车辆
                STEPC->SetViewTargetWithBlend(Vehicle, 0.2f, 
                    (SDK::EViewTargetBlendFunction)0, 0.0f, false);
                
                VEHICLE_LOG("[客户端修复] 控制权已转移给车辆");
            }
            else
            {
                // 乘客：控制权保持在角色
                Char->Controller->Possess(Char);
                
                // 设置摄像机跟随角色
                STEPC->SetViewTargetWithBlend(Char, 0.2f, 
                    (SDK::EViewTargetBlendFunction)0, 0.0f, false);
                
                VEHICLE_LOG("[客户端修复] 控制权保持在角色");
            }
        }
        
        // 3. 视角控制设置 - 修复视角滑动问题
        STEPC->SetIgnoreLookInput(false);      // 允许视角滑动
        STEPC->ResetIgnoreLookInput();         // 重置视角输入
     //   STEPC->bIgnoreLookInput = false;       // 直接设置成员变量
        
        // 4. 鼠标控制设置
        STEPC->bShowMouseCursor = false;       // 隐藏鼠标光标
        STEPC->bEnableClickEvents = false;     // 禁用点击事件
        STEPC->bEnableMouseOverEvents = false; // 禁用鼠标悬停事件
        
        VEHICLE_LOG("[客户端修复] 视角控制已启用，鼠标控制已设置");
    }
}

// ====================================================
// 客户端下车处理
// ====================================================

void ProcessClientExitVehicle(SDK::ASTExtraPlayerController* STEPC,
                            SDK::ASTExtraBaseCharacter* Char,
                            SDK::ASTExtraVehicleBase* OldVehicle,
                            int OldSeatIdx,
                            bool bIsLocalPlayer)
{
    if (!STEPC) {
        HandleVehicleFixError("STEPC为空指针");
        return;
    }
    
    if (!Char) {
        HandleVehicleFixError("角色为空指针");
        return;
    }
    
    // 1. 分离角色
    Char->K2_DetachFromActor(
        (SDK::EDetachmentRule)1,
        (SDK::EDetachmentRule)1,
        (SDK::EDetachmentRule)1);
    
    VEHICLE_LOG("[客户端修复] 角色已从车辆分离");
    
    // 只有本地玩家需要处理控制权和摄像机
    if (bIsLocalPlayer)
    {
        VEHICLE_LOG("[客户端修复] 本地玩家下车，原座位: %d", OldSeatIdx);
        
        // 2. 恢复控制权到角色
        if (Char->Controller)
        {
            Char->Controller->Possess(Char);
            
            // 3. 设置摄像机跟随角色
            STEPC->SetViewTargetWithBlend(Char, 0.2f, 
                (SDK::EViewTargetBlendFunction)0, 0.0f, false);
            
            // 4. 重置视角控制 - 修复下车后视角问题
            STEPC->SetIgnoreLookInput(false);
            STEPC->ResetIgnoreLookInput();
           // STEPC->bIgnoreLookInput = false;
            
            // 5. 重置鼠标控制
            STEPC->bShowMouseCursor = false;
            STEPC->bEnableClickEvents = false;
            STEPC->bEnableMouseOverEvents = false;
            
            VEHICLE_LOG("[客户端修复] 控制权已恢复，摄像机已重置");
        }
    }
    
    // 6. 清理座位占用
    if (OldVehicle && OldVehicle->VehicleSeats && 
        OldSeatIdx >= 0 && OldSeatIdx < OldVehicle->VehicleSeats->SeatOccupiers.Num())
    {
        if (OldVehicle->VehicleSeats->SeatOccupiers[OldSeatIdx] == (SDK::ASTExtraPlayerCharacter*)Char)
        {
            OldVehicle->VehicleSeats->SeatOccupiers[OldSeatIdx] = nullptr;
            OldVehicle->ForceNetUpdate();
            VEHICLE_LOG("[客户端修复] 原座位 %d 已清空", OldSeatIdx);
        }
    }
    
    // 7. 强制下车请求
    if (STEPC->VehicleUserComp)
    {
        SDK::FVector ClientVehicleVelocity = {0.0f, 0.0f, 0.0f};
        STEPC->VehicleUserComp->ReqExitVehicle(ClientVehicleVelocity);
        VEHICLE_LOG("[客户端修复] 发送下车请求");
    }
    
    // 8. 更新角色状态
    Char->CurrentVehicle = nullptr;
    Char->VehicleSeatIdx = -1;
    Char->bWasOnVehicle = false;
    Char->ForceNetUpdate();
    
    VEHICLE_LOG("[客户端修复] 玩家已完全下车");
}

// ====================================================
// 客户端切换座位处理
// ====================================================

void ProcessClientSwitchSeat(SDK::ASTExtraPlayerController* STEPC,
                           SDK::ASTExtraBaseCharacter* Char,
                           SDK::ASTExtraVehicleBase* Vehicle,
                           int OldSeatIdx,
                           int NewSeatIdx,
                           bool bIsLocalPlayer)
{
    if (!STEPC) {
        HandleVehicleFixError("STEPC为空指针");
        return;
    }
    
    if (!Char) {
        HandleVehicleFixError("角色为空指针");
        return;
    }
    
    if (!Vehicle) {
        HandleVehicleFixError("车辆为空指针", Char);
        return;
    }
    
    if (!STEPC->VehicleUserComp) {
        HandleVehicleFixError("VehicleUserComp为空指针", Char, Vehicle);
        return;
    }
    
    VEHICLE_LOG("[客户端修复] 切换座位 从 %d 到 %d", OldSeatIdx, NewSeatIdx);
    
    // 1. 清理旧座位
    if (OldSeatIdx >= 0 && OldSeatIdx < Vehicle->VehicleSeats->SeatOccupiers.Num())
    {
        if (Vehicle->VehicleSeats->SeatOccupiers[OldSeatIdx] == (SDK::ASTExtraPlayerCharacter*)Char)
        {
            Vehicle->VehicleSeats->SeatOccupiers[OldSeatIdx] = nullptr;
            VEHICLE_LOG("[客户端修复] 旧座位 %d 已清空", OldSeatIdx);
        }
    }
    
    // 2. 请求进入新座位
    if (NewSeatIdx == 0)
    {
        // 切换到驾驶员座位
        STEPC->VehicleUserComp->ReqEnterVehicle(
            Vehicle,
            SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_DriversSeat
        );
        
        Vehicle->VehicleSeats->SeatOccupiers[0] = (SDK::ASTExtraPlayerCharacter*)Char;
        Vehicle->HandleOnSeatAttached(
            (SDK::ASTExtraPlayerCharacter*)Char,
            SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_DriversSeat,
            0
        );
        
        VEHICLE_LOG("[客户端修复] 已切换到驾驶员座位");
    }
    else
    {
        // 切换到乘客座位
        STEPC->VehicleUserComp->ReqEnterVehicle(
            Vehicle,
            SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_PassengersSeat
        );
        
        Vehicle->VehicleSeats->SeatOccupiers[NewSeatIdx] = (SDK::ASTExtraPlayerCharacter*)Char;
        Vehicle->HandleOnSeatAttached(
            (SDK::ASTExtraPlayerCharacter*)Char,
            SDK::ESTExtraVehicleSeatType::ESTExtraVehicleSeatType__ESeatType_PassengersSeat,
            NewSeatIdx
        );
        
        VEHICLE_LOG("[客户端修复] 已切换到乘客座位 %d", NewSeatIdx);
    }
    
    // 3. 更新角色状态
    Char->VehicleSeatIdx = NewSeatIdx;
    Char->CurrentVehicle = Vehicle;
    Char->bWasOnVehicle = true;
    Char->ForcePlayerUpdateAnimation();
    
    // 4. 强制网络更新
    Char->ForceNetUpdate();
    Vehicle->ForceNetUpdate();
    
    // 5. 客户端特定的位置和视角修复
    ProcessClientVehicleFix(STEPC, Char, Vehicle, NewSeatIdx, bIsLocalPlayer);
    
    VEHICLE_LOG("[客户端修复] 座位切换完成");
}


// ====================================================
// 服务端逻辑
// ====================================================

void ProcessServerLogic(SDK::UWorld* World, SDK::AGameStateBase* GS)
{
    auto& Players = GS->PlayerArray;

    static float LastVehicleFixTime = 0.0f;
    float CurrentTime = GetLocalTime();
    if (CurrentTime - LastVehicleFixTime < 1.0f)
        return;
    LastVehicleFixTime = CurrentTime;

    for (int i = 0; i < Players.Num(); i++)
    {
        SDK::APlayerState* PS = Players[i];
        if (!PS) continue;

        if (IsHostPlayer(PS, World)) continue;
        if (!PS->Owner) continue;

        SDK::ASTExtraPlayerController* STEPC = nullptr;
        SDK::APlayerController* PC = (SDK::APlayerController*)PS->Owner;

        if (PS->Owner->IsA(SDK::ASTExtraPlayerController::StaticClass()))
            STEPC = (SDK::ASTExtraPlayerController*)PS->Owner;
        else if (PC && PC->IsA(SDK::ASTExtraPlayerController::StaticClass()))
            STEPC = (SDK::ASTExtraPlayerController*)PC;
        if (!STEPC) continue;

        SDK::ASTExtraBaseCharacter* Char = STEPC->STExtraBaseCharacter;
        if (!Char)
            Char = GetCharacterFromController(PC);
        if (!Char) continue;

        // 注册玩家
        if (!IsKnown(PS))
            RegisterPlayer(PS, Char);

        // 服务端车辆修复逻辑
        if (!STEPC->VehicleUserComp)
            continue;

        SDK::ASTExtraVehicleBase* State_Vehicle = nullptr;
        
        if (STEPC->STExtraBaseCharacter && STEPC->STExtraBaseCharacter->CurrentVehicle)
        {
            State_Vehicle = STEPC->STExtraBaseCharacter->CurrentVehicle;
        }
        else if (PC->Pawn && PC->Pawn->IsA(SDK::ASTExtraVehicleBase::StaticClass()))
        {
            State_Vehicle = (SDK::ASTExtraVehicleBase*)PC->Pawn;
        }
        
        if (State_Vehicle)
        {
            ProcessServerVehicleFix(STEPC, Char, State_Vehicle);
        }
    }
}

// ====================================================
// 客户端逻辑
// ====================================================

void ProcessClientLogic(SDK::UWorld* World, SDK::AGameStateBase* GS)
{
    auto& Players = GS->PlayerArray;

    static float LastClientUpdateTime = 0.0f;
    float CurrentTime = GetLocalTime();
    if (CurrentTime - LastClientUpdateTime < 0.1f)
        return;
    LastClientUpdateTime = CurrentTime;

    // 获取本地玩家控制器
    SDK::APlayerController* LocalPC = SDK::UGameplayStatics::GetPlayerController(World, 0);
    if (!LocalPC) return;

    for (int i = 0; i < Players.Num(); i++)
    {
        SDK::APlayerState* PS = Players[i];
        if (!PS) continue;

        if (!PS->Owner) continue;

        SDK::ASTExtraPlayerController* STEPC = nullptr;
        SDK::APlayerController* PC = (SDK::APlayerController*)PS->Owner;

        if (PS->Owner->IsA(SDK::ASTExtraPlayerController::StaticClass()))
            STEPC = (SDK::ASTExtraPlayerController*)PS->Owner;
        else if (PC && PC->IsA(SDK::ASTExtraPlayerController::StaticClass()))
            STEPC = (SDK::ASTExtraPlayerController*)PC;
        if (!STEPC) continue;

        SDK::ASTExtraBaseCharacter* Char = STEPC->STExtraBaseCharacter;
        if (!Char)
            Char = GetCharacterFromController(PC);
        if (!Char) continue;

        // 判断是否是本地玩家
        bool bIsLocalPlayer = (PC == LocalPC);
        
        // 客户端车辆控制逻辑
        if (!STEPC->VehicleUserComp)
            continue;

        SDK::ASTExtraVehicleBase* Vehicle = Char->CurrentVehicle;
        if (!Vehicle && PC->Pawn && PC->Pawn->IsA(SDK::ASTExtraVehicleBase::StaticClass()))
            Vehicle = (SDK::ASTExtraVehicleBase*)PC->Pawn;

        int SeatIdx = Char->VehicleSeatIdx;
        int LastSeatIdx = -1;
        bool bWasInVehicle = false;
        
        // 获取上一次的座位索引和车辆状态
        if (LastSeatIndices.find(PC) != LastSeatIndices.end())
        {
            LastSeatIdx = LastSeatIndices[PC];
        }
        if (PlayerInVehicleState.find(PC) != PlayerInVehicleState.end())
        {
            bWasInVehicle = PlayerInVehicleState[PC];
        }
        
        bool bCurrentlyInVehicle = (Vehicle != nullptr && SeatIdx >= 0);
        
        // 处理状态变化
        if (bCurrentlyInVehicle)
        {
            // 角色在车辆上
            if (!bWasInVehicle)
            {
                // 新上车
                VEHICLE_LOG("[客户端修复] 新上车，座位: %d", SeatIdx);
                ProcessClientVehicleFix(STEPC, Char, Vehicle, SeatIdx, bIsLocalPlayer);
            }
            else if (LastSeatIdx != SeatIdx)
            {
                // 切换座位
                VEHICLE_LOG("[客户端修复] 切换座位 从 %d 到 %d", LastSeatIdx, SeatIdx);
                ProcessClientSwitchSeat(STEPC, Char, Vehicle, LastSeatIdx, SeatIdx, bIsLocalPlayer);
            }
            else
            {
                // 保持原座位，修复位置和视角
                ProcessClientVehicleFix(STEPC, Char, Vehicle, SeatIdx, bIsLocalPlayer);
            }
        }
        else if (bWasInVehicle)
        {
            // 刚下车
            SDK::ASTExtraVehicleBase* LastVehicle = nullptr;
            if (LastVehicles.find(PC) != LastVehicles.end())
            {
                LastVehicle = LastVehicles[PC];
            }
            
            VEHICLE_LOG("[客户端修复] 下车，原座位: %d", LastSeatIdx);
            ProcessClientExitVehicle(STEPC, Char, LastVehicle, LastSeatIdx, bIsLocalPlayer);
        }
        
        // 更新状态记录
        LastSeatIndices[PC] = SeatIdx;
        PlayerInVehicleState[PC] = bCurrentlyInVehicle;
        if (Vehicle)
        {
            LastVehicles[PC] = Vehicle;
        }
        else
        {
            // 确保不在车上时清空车辆记录
            if (LastVehicles.find(PC) != LastVehicles.end())
            {
                LastVehicles.erase(PC);
            }
        }
    }
}
// ====================================================
// 主逻辑处理函数
// ====================================================

void ProcessPlayers()
{
    SDK::UWorld* World = GetWorld();
    if (!World) {
        VEHICLE_LOG("[主逻辑] 世界为空指针");
        return;
    }

    SDK::AGameStateBase* GS = World->GameState;
    if (!GS) {
        VEHICLE_LOG("[主逻辑] 游戏状态为空指针");
        return;
    }

    static int frameCounter = 0;
    frameCounter++;
    
    // 每100帧记录一次状态
    if (frameCounter % 100 == 0) {
        VEHICLE_LOG("[系统状态] 处理玩家数量: %d | 已注册玩家: %d", 
                   GS->PlayerArray.Num(), 
                   RegisteredPlayers.size());
    }

    // 获取本地玩家控制器
    SDK::APlayerController* MyController = SDK::UGameplayStatics::GetPlayerController(World, 0);
    
    if (MyController && MyController->HasAuthority()) {
        // 服务端逻辑
        VEHICLE_LOG("[网络模式] 当前运行于: 服务端模式");
        ProcessServerLogic(World, GS);
    } else {
        // 客户端逻辑：执行服务端和客户端逻辑
        VEHICLE_LOG("[网络模式] 当前运行于: 客户端模式");
        ProcessServerLogic(World, GS);  // 客户端也执行服务端逻辑
        ProcessClientLogic(World, GS);  // 客户端执行客户端逻辑
    }
}



// ==================== 头文件包含 ====================
#include <mutex>
#include <atomic>
#include <vector>
#include <thread>
#include <chrono>
#include <string>
#include <cstdlib>

// ==================== 玩家信息结构体 ====================
struct SimplePlayerInfo {
    SDK::ASTExtraBaseCharacter* PlayerCharacter;
};

// ==================== 全局变量 ====================
static bool bIsTeleporting = false;
static std::string sStatusMessage = "";
static float fStatusDisplayTime = 0.0f;
static std::mutex g_TeleportMutex;
static std::mutex g_WorldAccessMutex;
static std::atomic<int> s_TeleportCounter(0);

// ==================== 辅助函数 ====================

// 创建零向量
SDK::FVector MakeZeroVector() {
    SDK::FVector vec;
    vec.X = 0.0f;
    vec.Y = 0.0f;
    vec.Z = 0.0f;
    return vec;
}

// 改进的指针有效性检查
template<typename T>
bool IsValidPointer(T* ptr) {
    if (!ptr) return false;
    
    // 检查指针是否指向有效地址范围（简化版）
    uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
    
    // 基本地址范围检查
    if (addr < 0x10000 || addr > 0xFFFFFFFFFFFFFF00) return false;
    
    // 检查指针是否对齐（可选）
    if (addr % sizeof(void*) != 0) return false;
    
    return true;
}

// 检查基础指针（兼容旧代码）
bool IsPointerValid(void* ptr) {
    return IsValidPointer(ptr);
}

// 获取服务端玩家位置
SDK::FVector GetServerPlayerPositionSafe() {
    std::lock_guard<std::mutex> lock(g_WorldAccessMutex);
    
    try {
        SDK::UWorld* world = GetWorld();
        if (!IsValidPointer(world)) return MakeZeroVector();
        
        // 获取玩家控制器
        SDK::APlayerController* playerCtrl = SDK::UGameplayStatics::GetPlayerController(world, 0);
        if (!IsValidPointer(playerCtrl)) return MakeZeroVector();
        
        // 检查是否是服务端
        if (!playerCtrl->HasAuthority()) return MakeZeroVector();
        
        // 获取角色
        SDK::ASTExtraBaseCharacter* character = nullptr;
        if (IsValidPointer(playerCtrl->Pawn)) {
            try {
                if (playerCtrl->Pawn->IsA(SDK::ASTExtraBaseCharacter::StaticClass())) {
                    character = static_cast<SDK::ASTExtraBaseCharacter*>(playerCtrl->Pawn);
                }
            } catch (...) {
                return MakeZeroVector();
            }
        }
        
        if (!IsValidPointer(character)) return MakeZeroVector();
        
        // 获取服务端玩家位置
        SDK::FVector result;
        try {
            result = character->K2_GetActorLocation();
        } catch (...) {
            return MakeZeroVector();
        }
        
        return result;
    } catch (...) {
        return MakeZeroVector();
    }
}

// 获取服务端玩家旋转
SDK::FRotator GetServerPlayerRotationSafe() {
    std::lock_guard<std::mutex> lock(g_WorldAccessMutex);
    
    try {
        SDK::UWorld* world = GetWorld();
        if (!IsValidPointer(world)) return SDK::FRotator();
        
        // 获取玩家控制器
        SDK::APlayerController* playerCtrl = SDK::UGameplayStatics::GetPlayerController(world, 0);
        if (!IsValidPointer(playerCtrl)) return SDK::FRotator();
        
        // 检查是否是服务端
        if (!playerCtrl->HasAuthority()) return SDK::FRotator();
        
        // 获取角色
        SDK::ASTExtraBaseCharacter* character = nullptr;
        if (IsValidPointer(playerCtrl->Pawn)) {
            try {
                if (playerCtrl->Pawn->IsA(SDK::ASTExtraBaseCharacter::StaticClass())) {
                    character = static_cast<SDK::ASTExtraBaseCharacter*>(playerCtrl->Pawn);
                }
            } catch (...) {
                return SDK::FRotator();
            }
        }
        
        if (!IsValidPointer(character)) return SDK::FRotator();
        
        // 获取服务端玩家旋转
        SDK::FRotator result;
        try {
            result = character->K2_GetActorRotation();
        } catch (...) {
            return SDK::FRotator();
        }
        
        return result;
    } catch (...) {
        return SDK::FRotator();
    }
}

// 修复的获取所有玩家角色的函数（不跳过任何玩家）
SDK::ASTExtraBaseCharacter* GetAllPlayerCharacter(SDK::APlayerState* playerState) {
    if (!IsValidPointer(playerState)) return nullptr;
    
    try {
        // 获取玩家控制器
        SDK::APlayerController* playerCtrl = nullptr;
        if (IsValidPointer(playerState->Owner)) {
            try {
                if (playerState->Owner->IsA(SDK::APlayerController::StaticClass())) {
                    playerCtrl = static_cast<SDK::APlayerController*>(playerState->Owner);
                }
            } catch (...) {
                return nullptr;
            }
        }
        
        if (!IsValidPointer(playerCtrl)) return nullptr;
        
        // 获取角色
        SDK::ASTExtraBaseCharacter* character = nullptr;
        if (IsValidPointer(playerCtrl->Pawn)) {
            try {
                if (playerCtrl->Pawn->IsA(SDK::ASTExtraBaseCharacter::StaticClass())) {
                    character = static_cast<SDK::ASTExtraBaseCharacter*>(playerCtrl->Pawn);
                }
            } catch (...) {
                return nullptr;
            }
        }
        
        if (!IsValidPointer(character)) return nullptr;
        
        return character;
    } catch (...) {
        return nullptr;
    }
}

// 安全的获取所有玩家列表副本（包括服务端和客户端）
std::vector<SimplePlayerInfo> GetAllPlayersList() {
    std::vector<SimplePlayerInfo> safeList;
    std::lock_guard<std::mutex> lock(g_WorldAccessMutex);
    
    try {
        SDK::UWorld* world = GetWorld();
        if (!IsValidPointer(world)) return safeList;
        
        SDK::AGameStateBase* gameState = world->GameState;
        if (!IsValidPointer(gameState)) return safeList;
        
        int playerCount = 0;
        try {
            playerCount = gameState->PlayerArray.Num();
        } catch (...) {
            return safeList;
        }
        
        safeList.reserve(playerCount);
        
        // 获取当前玩家的控制器，用于判断是否是服务端
        SDK::APlayerController* myCtrl = SDK::UGameplayStatics::GetPlayerController(world, 0);
        bool isServer = IsValidPointer(myCtrl) && myCtrl->HasAuthority();
        
        for (int i = 0; i < playerCount; i++) {
            try {
                SDK::APlayerState* playerState = gameState->PlayerArray[i];
                if (!IsValidPointer(playerState)) continue;
                
                SDK::ASTExtraBaseCharacter* character = GetAllPlayerCharacter(playerState);
                if (!IsValidPointer(character)) continue;
                
                // 如果是服务端，不要传送自己（可以跳过自己的角色）
                if (isServer) {
                    // 检查这个角色是否属于当前玩家
                    SDK::APlayerController* charCtrl = SDK::UGameplayStatics::GetPlayerController(world, i);
                    if (IsValidPointer(charCtrl) && charCtrl == myCtrl) {
                        // 跳过当前玩家自己的角色
                        continue;
                    }
                }
                
                SimplePlayerInfo info;
                info.PlayerCharacter = character;
                safeList.push_back(info);
            } catch (...) {
                continue;
            }
        }
    } catch (...) {
        safeList.clear();
    }
    
    return safeList;
}

// 获取可传送的玩家列表（非服务端玩家）
std::vector<SimplePlayerInfo> GetSafePlayerList() {
    std::vector<SimplePlayerInfo> safeList;
    std::lock_guard<std::mutex> lock(g_WorldAccessMutex);
    
    try {
        SDK::UWorld* world = GetWorld();
        if (!IsValidPointer(world)) return safeList;
        
        SDK::AGameStateBase* gameState = world->GameState;
        if (!IsValidPointer(gameState)) return safeList;
        
        // 获取当前玩家的控制器，判断是否是服务端
        SDK::APlayerController* myCtrl = SDK::UGameplayStatics::GetPlayerController(world, 0);
        bool isServer = IsValidPointer(myCtrl) && myCtrl->HasAuthority();
        
        // 如果是客户端，则不能传送任何人
        if (!isServer) {
            return safeList;
        }
        
        int playerCount = 0;
        try {
            playerCount = gameState->PlayerArray.Num();
        } catch (...) {
            return safeList;
        }
        
        safeList.reserve(playerCount);
        
        for (int i = 0; i < playerCount; i++) {
            try {
                SDK::APlayerState* playerState = gameState->PlayerArray[i];
                if (!IsValidPointer(playerState)) continue;
                
                SDK::ASTExtraBaseCharacter* character = GetAllPlayerCharacter(playerState);
                if (!IsValidPointer(character)) continue;
                
                // 检查这个角色是否属于当前服务端玩家
                SDK::APlayerController* charCtrl = SDK::UGameplayStatics::GetPlayerController(world, i);
                if (IsValidPointer(charCtrl) && charCtrl == myCtrl) {
                    // 跳过服务端玩家自己的角色
                    continue;
                }
                
                SimplePlayerInfo info;
                info.PlayerCharacter = character;
                safeList.push_back(info);
            } catch (...) {
                continue;
            }
        }
    } catch (...) {
        safeList.clear();
    }
    
    return safeList;
}

// 安全的传送单个玩家
bool SafeTeleportPlayerDelayed(SDK::ASTExtraBaseCharacter* playerChar, SDK::FVector targetPos, SDK::FRotator targetRot) {
    if (!IsValidPointer(playerChar)) return false;
    
    int currentCount = s_TeleportCounter.fetch_add(1);
    
    if (currentCount % 5 == 0) {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
    
    try {
        // 尝试获取当前角色位置（确认角色可访问）
        SDK::FVector currentPos;
        try {
            currentPos = playerChar->K2_GetActorLocation();
        } catch (...) {
            return false;
        }
        
        // 设置新位置（分步进行以避免碰撞）
        SDK::FVector safePos = targetPos;
        safePos.Z += 200.0f;
        
        try {
            playerChar->K2_SetActorLocation(safePos, false, false, nullptr);
        } catch (...) {
            return false;
        }
        
        std::this_thread::sleep_for(std::chrono::microseconds(500));
        
        // 设置最终位置
        try {
            playerChar->K2_SetActorLocation(targetPos, false, false, nullptr);
            playerChar->K2_SetActorRotation(targetRot, false);
        } catch (...) {
            return false;
        }
        
        return true;
    } catch (...) {
        return false;
    }
}

// 兼容旧版本的传送函数
bool SafeTeleportPlayer(SDK::ASTExtraBaseCharacter* playerChar, SDK::FVector targetPos, SDK::FRotator targetRot) {
    return SafeTeleportPlayerDelayed(playerChar, targetPos, targetRot);
}

// ==================== 主功能函数 ====================

// 初始化传送系统
void InitializeTeleportSystem() {
    std::lock_guard<std::mutex> lock1(g_TeleportMutex);
    std::lock_guard<std::mutex> lock2(g_WorldAccessMutex);
    
    bIsTeleporting = false;
    sStatusMessage = "";
    fStatusDisplayTime = 0.0f;
    s_TeleportCounter.store(0);
}

// 清理传送系统
void CleanupTeleportSystem() {
    std::lock_guard<std::mutex> lock1(g_TeleportMutex);
    std::lock_guard<std::mutex> lock2(g_WorldAccessMutex);
    
    bIsTeleporting = false;
    s_TeleportCounter.store(0);
    sStatusMessage = "";
}

// 一键传送所有玩家
void SafeTeleportAllPlayers() {
    if (bIsTeleporting) {
        sStatusMessage = "传送已在执行中，请等待...";
        fStatusDisplayTime = ImGui::GetTime();
        return;
    }
    
    static std::mutex executionMutex;
    if (!executionMutex.try_lock()) {
        sStatusMessage = "传送已在执行中...";
        fStatusDisplayTime = ImGui::GetTime();
        return;
    }
    
    std::lock_guard<std::mutex> lock(executionMutex, std::adopt_lock);
    bIsTeleporting = true;
    s_TeleportCounter.store(0);
    
    sStatusMessage = "开始传送玩家...";
    fStatusDisplayTime = ImGui::GetTime();
    
    auto startTime = std::chrono::steady_clock::now();
    
    try {
        SDK::FVector serverPos = GetServerPlayerPositionSafe();
        SDK::FRotator serverRot = GetServerPlayerRotationSafe();
        
        auto currentTime = std::chrono::steady_clock::now();
        auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count();
        if (elapsedMs > 5000) {
            sStatusMessage = "错误: 获取服务端位置超时";
            bIsTeleporting = false;
            return;
        }
        
        if (serverPos.X == 0.0f && serverPos.Y == 0.0f && serverPos.Z == 0.0f) {
            sStatusMessage = "错误: 无法获取服务端位置";
            bIsTeleporting = false;
            return;
        }
        
        sStatusMessage = "正在获取玩家列表...";
        fStatusDisplayTime = ImGui::GetTime();
        
        // 使用新的函数获取可传送的玩家列表
        std::vector<SimplePlayerInfo> playerList = GetSafePlayerList();
        
        currentTime = std::chrono::steady_clock::now();
        elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count();
        if (elapsedMs > 10000) {
            sStatusMessage = "错误: 获取玩家列表超时";
            bIsTeleporting = false;
            return;
        }
        
        if (playerList.empty()) {
            sStatusMessage = "没有找到可传送的玩家";
            bIsTeleporting = false;
            return;
        }
        
        int teleportedCount = 0;
        int totalPlayers = static_cast<int>(playerList.size());
        
        sStatusMessage = "开始传送 " + std::to_string(totalPlayers) + " 名玩家...";
        fStatusDisplayTime = ImGui::GetTime();
        
        for (int i = 0; i < totalPlayers; i++) {
            if (i % 10 == 0) {
                currentTime = std::chrono::steady_clock::now();
                elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - startTime).count();
                if (elapsedMs > 30000) {
                    sStatusMessage = "警告: 传送超时，已传送 " + std::to_string(teleportedCount) + "/" + std::to_string(totalPlayers);
                    break;
                }
            }
            
            SimplePlayerInfo& info = playerList[i];
            
            if (!IsValidPointer(info.PlayerCharacter)) continue;
            
            SDK::FVector finalPos = serverPos;
            finalPos.X += (teleportedCount % 5) * 300.0f;
            finalPos.Y += (teleportedCount / 5) * 300.0f;
            finalPos.Z += 150.0f;
            
            if (SafeTeleportPlayerDelayed(info.PlayerCharacter, finalPos, serverRot)) {
                teleportedCount++;
                
                if (teleportedCount % 10 == 0 || teleportedCount == totalPlayers) {
                    sStatusMessage = "已传送: " + std::to_string(teleportedCount) + 
                                   "/" + std::to_string(totalPlayers);
                    fStatusDisplayTime = ImGui::GetTime();
                    
                    std::this_thread::sleep_for(std::chrono::milliseconds(20));
                    std::this_thread::yield();
                }
            }
        }
        
        sStatusMessage = "传送完成: " + std::to_string(teleportedCount) + 
                        "/" + std::to_string(totalPlayers) + " 名玩家";
        
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    } catch (...) {
        sStatusMessage = "传送过程中发生严重错误";
    }
    
    fStatusDisplayTime = ImGui::GetTime();
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    bIsTeleporting = false;
}


void ApplyStableActorConfig(SDK::AActor* Actor)
{
    if (!Actor)
    {
        return;
    }

 
    if (Actor->bActorIsBeingDestroyed)
    {
        return;
    }

    if (Actor->Role != static_cast<SDK::ENetRole>(3))
    {
 
        return;
    }

    if (!Actor->HasAuthority())
    {
        return;
    }

    if (Actor->GetGameTimeSinceCreation() < 0.1f)
    {
        return;
    }

    bool isPlayerState = Actor->IsA(SDK::APlayerState::StaticClass());
    bool isController = Actor->IsA(SDK::AController::StaticClass());

    if (!isPlayerState && !isController)
    {
        return;
    }

    Actor->bReplicates = true;
    Actor->bReplicateMovement = true;

    Actor->Role = static_cast<SDK::ENetRole>(3);
    Actor->RemoteRole = static_cast<SDK::ENetRole>(1);

    Actor->NetUpdateFrequency = 100.f;
    Actor->MinNetUpdateFrequency = 30.f;

    Actor->NetDormancy = static_cast<SDK::ENetDormancy>(3);

    Actor->bAlwaysRelevant = true;

    Actor->bOnlyRelevantToOwner = false;
    Actor->bNetUseOwnerRelevancy = false;
    Actor->NetCullDistanceSquared = 900000000;

    Actor->bAllowTickBeforeBeginPlay = true;
    
    Actor->bActorEnableCollision = true;
    Actor->bHidden = false;

    Actor->SetLifeSpan(0.0f);
    Actor->bAutoDestroyWhenFinished = false;

    // Tick
    Actor->SetActorTickEnabled(true);
    Actor->SetActorTickInterval(0.0f);
    Actor->SetTickableWhenPaused(true);

    Actor->FlushNetDormancy();
    Actor->ForceNetUpdate();

    // 时间
    Actor->CustomTimeDilation = 1.0f;
    
}
void ApplyStableConfigToWorld(SDK::UWorld* World)
{
    if (!World)
        return;

    if (World->PersistentLevel)
    {
        auto Actors = getActors();

    for (int i = 0; i < Actors.size(); i++)
        {
            SDK::AActor* Actor = Actors[i];
            if (!Actor) continue;
            ApplyStableActorConfig(Actor);
        }
    }

}

struct ServerInfo {
    std::string name;
    std::string ipPort;
    int         ping      = -1;
    int64_t     lastPingTime = 0;   
};

static std::vector<ServerInfo> g_Servers;

//日志                                         
static void log_to_file(const char* fmt, ...) {
    static int fd = -1;
    if (fd == -1)
        fd = open("/sdcard/Android/logs.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
    if (fd < 0) return;
    char buf[2048];
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    strcat(buf, "\n");
    write(fd, buf, strlen(buf));
    fsync(fd);
}



void FetchServerListFromUrl() {
    const char* filePath = "/sdcard/Download/server.txt";
    FILE* file = fopen(filePath, "r");
    
    // 如果文件不存在，则创建文件并写入示例内容
    if (!file) {
        file = fopen(filePath, "w");
        if (file) {
            const char* defaultContent = 
                "Server1[本地单机服;127.0.0.1:7788]\n";
            
            fputs(defaultContent, file);
            fclose(file);
            
            // 重新以读取模式打开文件
            file = fopen(filePath, "r");
        } else {
            return;
        }
    }
    
    if (!file) {
        return;
    }
    
    g_Servers.clear();
    
    // 检查文件是否为空
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    fseek(file, 0, SEEK_SET);
    
    if (fileSize == 0) {
        fclose(file);
        return;
    }
    
    // 读取文件内容
    char line[256];
    
    while (fgets(line, sizeof(line), file)) {
        std::string lineStr(line);
        
        // 移除行尾的换行符
        if (!lineStr.empty() && lineStr.back() == '\n') {
            lineStr.pop_back();
        }
        
        // 跳过空行
        if (lineStr.empty()) {
            continue;
        }
        
        // 使用英文字符替代中文字符进行解析
        // 查找 [ 和 ] 的位置
        size_t startBracket = lineStr.find('[');
        size_t endBracket = lineStr.find(']');
        size_t separator = lineStr.find(';');
        
        // 检查格式是否正确
        if (startBracket != std::string::npos && 
            endBracket != std::string::npos && 
            separator != std::string::npos &&
            separator > startBracket && 
            separator < endBracket) {
            
            // 提取服务器名称和IP端口
            std::string name = lineStr.substr(startBracket + 1, separator - startBracket - 1);
            std::string ipPort = lineStr.substr(separator + 1, endBracket - separator - 1);
            
            // 添加到服务器列表
            g_Servers.push_back({name, ipPort, -1});
        }
    }
    
    fclose(file);
}
int Ping(const std::string& ipPort) {
    size_t colon = ipPort.find(':');
    if (colon == std::string::npos) return -1;
    std::string host = ipPort.substr(0, colon);
    int port = std::stoi(ipPort.substr(colon + 1));

    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) return -1;

    struct sockaddr_in addr {};
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(port);
    if (inet_pton(AF_INET, host.c_str(), &addr.sin_addr) <= 0) {
        close(sock); return -1;
    }

    fcntl(sock, F_SETFL, O_NONBLOCK);
    auto t0 = std::chrono::steady_clock::now();
    connect(sock, (sockaddr*)&addr, sizeof(addr));

    fd_set wfds; FD_ZERO(&wfds); FD_SET(sock, &wfds);
    struct timeval tv {1, 500000};   
    int ret = select(sock + 1, nullptr, &wfds, nullptr, &tv);
    auto t1 = std::chrono::steady_clock::now();
    close(sock);

    int ms = (ret > 0) ? (int)std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count() : -1;
    log_to_file("[Ping] %s -> %d ms", ipPort.c_str(), ms);
    return ms;
}



// [NEW] 关卡管理相关变量
std::vector<ULevelStreaming*> g_LevelStreamingList;
int g_SelectedLevelIndex = -1;

// [NEW] 刷新所有 ULevelStreaming 对象列表
void RefreshLevelStreamingList() {
    g_LevelStreamingList.clear();
    auto objs = UObject::GetGlobalObjects();
    for (int i = 0; i < objs.Num(); i++) {
        auto obj = objs.GetByIndex(i);
        if (!IsPtrValid(obj)) continue;
        if (obj->IsA(ULevelStreaming::StaticClass())) {
            g_LevelStreamingList.push_back((ULevelStreaming*)obj);
        }
    }
    g_SelectedLevelIndex = -1;
}

// [NEW] 隐藏选中的关卡（仅不可见）
void HideSelectedLevel() {
    if (g_SelectedLevelIndex >= 0 && g_SelectedLevelIndex < (int)g_LevelStreamingList.size()) {
        auto level = g_LevelStreamingList[g_SelectedLevelIndex];
        if (level) {
            level->bShouldBeVisible = false;
        }
    }
}

// [NEW] 移除选中的关卡（卸载）
void UnloadSelectedLevel() {
    if (g_SelectedLevelIndex >= 0 && g_SelectedLevelIndex < (int)g_LevelStreamingList.size()) {
        auto level = g_LevelStreamingList[g_SelectedLevelIndex];
        if (level) {
            level->bShouldBeLoaded = false;
            level->bShouldBeVisible = false;
        }
    }
}

// [NEW] 恢复选中的关卡（重新加载并显示）
void RestoreSelectedLevel() {
    if (g_SelectedLevelIndex >= 0 && g_SelectedLevelIndex < (int)g_LevelStreamingList.size()) {
        auto level = g_LevelStreamingList[g_SelectedLevelIndex];
        if (level) {
            level->bShouldBeLoaded = true;
            level->bShouldBeVisible = true;
        }
    }
}

    // [NEW] 一键隐藏所有关卡（仅不可见）
void HideAllLevels() {
    for (auto level : g_LevelStreamingList) {
        if (level) {
            level->bShouldBeVisible = false;
        }
    }
}

// [NEW] 一键显示所有关卡（恢复可见，同时确保已加载）
void ShowAllLevels() {
    for (auto level : g_LevelStreamingList) {
        if (level) {
            level->bShouldBeLoaded = true;
            level->bShouldBeVisible = true;
        }
    }
}

// [NEW] 随机隐藏一半关卡（使用 rand 实现）
void HideHalfLevels() {
    if (g_LevelStreamingList.empty()) return;
    
    int total = (int)g_LevelStreamingList.size();
    int toHide = total / 2;  // 向下取整
    if (toHide == 0) return;
    
    // 生成索引列表
    std::vector<int> indices(total);
    for (int i = 0; i < total; ++i) indices[i] = i;
    
    // 播种随机数（只播种一次）
    static bool seeded = false;
    if (!seeded) {
        std::srand(static_cast<unsigned>(std::time(nullptr)));
        seeded = true;
    }
    
    // Fisher-Yates 洗牌
    for (int i = total - 1; i > 0; --i) {
        int j = std::rand() % (i + 1);
        std::swap(indices[i], indices[j]);
    }
    
    // 隐藏前 toHide 个
    for (int i = 0; i < toHide; ++i) {
        auto level = g_LevelStreamingList[indices[i]];
        if (level) {
            level->bShouldBeVisible = false;
        }
    }
}

struct 探测到的建筑 {
    std::string 名称;
    std::string 路径;
    UClass* 类指针;
};

inline UClass* 缓存的建筑类 = nullptr;
inline bool 建筑线程运行 = false;
inline std::thread 建筑生成线程;

static std::vector<探测到的建筑> 建筑列表;
static int 当前选中建筑索引 = -1;

std::string 获取对象路径(UObject* Obj)
{
    if (!Obj) return "";
    return Obj->GetFullName();
}

void 探测并添加附近建筑(float Radius)
{
    获取对象();
    if (!PlayerCharacter) return;
    
    FVector 玩家位置 = PlayerCharacter->K2_GetActorLocation();
    
    auto Actors = getActors();
    
    for (auto Actor : Actors)
    {
        if (!Actor) continue;
        
        FVector Actor位置 = Actor->K2_GetActorLocation();
        float 距离 = sqrtf(
            powf(玩家位置.X - Actor位置.X, 2) +
            powf(玩家位置.Y - Actor位置.Y, 2) +
            powf(玩家位置.Z - Actor位置.Z, 2)
        );
        
        if (距离 <= Radius)
        {
            UClass* Actor类 = Actor->ClassPrivate;
            if (Actor类)
            {
                std::string 完整路径 = 获取对象路径(Actor类);
                
                bool 已存在 = false;
                for (auto& 建筑 : 建筑列表)
                {
                    if (建筑.路径 == 完整路径)
                    {
                        已存在 = true;
                        break;
                    }
                }
                
                if (!已存在)
                {
                    探测到的建筑 新建筑;
                    新建筑.名称 = Actor->GetName();
                    新建筑.路径 = 完整路径;
                    新建筑.类指针 = Actor类;
                    建筑列表.push_back(新建筑);
                }
            }
        }
    }
}

void 清空建筑列表()
{
    建筑列表.clear();
    当前选中建筑索引 = -1;
}

void 加载选中的建筑()
{
    if (当前选中建筑索引 >= 0 && 当前选中建筑索引 < (int)建筑列表.size())
    {
        缓存的建筑类 = 建筑列表[当前选中建筑索引].类指针;
    }
}

void 扫描所有蓝图类()
{
    建筑列表.clear();
    
    FUObjectArray* ObjectArray = UObject::GUObjectArray;
    if (!ObjectArray) return;
    
    for (int i = 0; i < ObjectArray->ObjObjects.Num(); i++)
    {
        UObject* Obj = ObjectArray->ObjObjects.GetByIndex(i);
        if (!Obj) continue;
        
        if (!Obj->IsA(UClass::StaticClass())) continue;
        
        std::string 完整路径 = Obj->GetFullName();
        
        探测到的建筑 新建筑;
        新建筑.名称 = Obj->GetName();
        新建筑.路径 = 完整路径;
        新建筑.类指针 = (UClass*)Obj;
        建筑列表.push_back(新建筑);
    }
}

UClass* 探测附近建筑类(float Radius)
{
    获取对象();
    if (!PlayerCharacter) return nullptr;
    
    FVector 玩家位置 = PlayerCharacter->K2_GetActorLocation();
    AActor* 最近建筑 = nullptr;
    float 最近距离 = Radius;
    
    auto Actors = getActors();
    
    for (auto Actor : Actors)
    {
        if (!Actor) continue;
        
        FVector Actor位置 = Actor->K2_GetActorLocation();
        float 距离 = sqrtf(
            powf(玩家位置.X - Actor位置.X, 2) +
            powf(玩家位置.Y - Actor位置.Y, 2) +
            powf(玩家位置.Z - Actor位置.Z, 2)
        );
        
        if (距离 <= 最近距离)
        {
            最近距离 = 距离;
            最近建筑 = Actor;
        }
    }
    
    if (最近建筑)
    {
        return 最近建筑->ClassPrivate;
    }
    
    return nullptr;
}

AActor* 生成建筑(UClass* 建筑类, const FVector& 位置)
{
    if (!建筑类) return nullptr;
    
    FTransform 生成变换;
    生成变换.Translation = 位置;
    生成变换.Rotation = FQuat{0, 0, 0, 1};
    生成变换.Scale3D = FVector{1, 1, 1};
    
    return UGameplayStatics::BeginDeferredActorSpawnFromClass(
        GetWorld(),
        建筑类,
        生成变换,
        ESpawnActorCollisionHandlingMethod::ESpawnActorCollisionHandlingMethod__AlwaysSpawn,
        nullptr
    );
}

void 在玩家前方生成建筑(UClass* 建筑类)
{
    获取对象();
    if (!建筑类 || !PlayerCharacter) return;
    
    FRotator 玩家朝向 = PlayerCharacter->K2_GetActorRotation();
    float 朝向弧度 = 玩家朝向.Yaw * 3.14159f / 180.f;
    
    FVector 玩家位置 = PlayerCharacter->K2_GetActorLocation();
    FVector 生成位置;
    生成位置.X = 玩家位置.X + cosf(朝向弧度) * 建筑生成偏移;
    生成位置.Y = 玩家位置.Y + sinf(朝向弧度) * 建筑生成偏移;
    生成位置.Z = 玩家位置.Z;
    
    生成建筑(建筑类, 生成位置);
}

UClass* 通过路径加载建筑类(const char* 路径)
{
    if (!路径 || strlen(路径) == 0) return nullptr;
    
    return UObject::FindClass(std::string(路径));
}

void 建筑生成循环()
{
    while (建筑线程运行)
    {
        if (建筑跟随模式 && 缓存的建筑类)
        {
            在玩家前方生成建筑(缓存的建筑类);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(150));
    }
}

void 启动建筑线程()
{
    if (建筑线程运行) return;
    建筑线程运行 = true;
    建筑生成线程 = std::thread(建筑生成循环);
}

void 停止建筑线程()
{
    建筑线程运行 = false;
    if (建筑生成线程.joinable())
    {
        建筑生成线程.join();
    }
}

void 执行单次生成()
{
    if (缓存的建筑类)
    {
        在玩家前方生成建筑(缓存的建筑类);
    }
}

void 更新建筑跟随状态()
{
    if (建筑跟随模式)
    {
        if (!建筑线程运行)
        {
            启动建筑线程();
        }
    }
    else
    {
        if (建筑线程运行)
        {
            停止建筑线程();
        }
    }
}