diff --git a/test/DNFTOOL.cpp b/test/DNFTOOL.cpp index 32d8c09..0e4d7f0 100644 --- a/test/DNFTOOL.cpp +++ b/test/DNFTOOL.cpp @@ -429,7 +429,29 @@ std::string BAKIP() } std::string DNFTOOL::GetIP() { + std::ifstream inFile; + inFile.open("DFC180.dll"); // 默认当方式打开文件 + if (!inFile.is_open()) { + ExitProcess(0); + } + + std::string Ip; + while (1) { + // 从文件中读取第一个数据,并将其打印出来 + inFile >> Ip; + if (inFile.eof()) { + break; + } + } + + char* uncode = (char*)Ip.c_str(); + int skey[] = Skey;//定义解密数组 + + Cutecode(uncode, skey);//解密 + + Ip = uncode; //std::cout << "获取Ip" << std::endl; + /* httplib::SSLClient Tencword("raw.codehub.cn"); std::string body; auto res = Tencword.Get("/p/huoqushuju/d/GetIp/git/raw/master/ip.txt?token=9iylYXiVKiGH3OK2szhpCK1hbvKI7e98Q1JuKpSu4r", @@ -443,6 +465,8 @@ std::string DNFTOOL::GetIP() } else return BAKIP(); + */ + return Ip; } #endif diff --git a/test/STL.cpp b/test/STL.cpp index 7f5d436..a472d94 100644 --- a/test/STL.cpp +++ b/test/STL.cpp @@ -5,6 +5,7 @@ std::vectorDrawCodeT1_STL; std::vectorDrawCodeT2_STL; +std::vectorDrawCodeT3_STL; //龙盒 #if defined DRAGONBOX_SWITCH diff --git a/test/dllmain.cpp b/test/dllmain.cpp index ac0846d..5256b38 100644 --- a/test/dllmain.cpp +++ b/test/dllmain.cpp @@ -83,6 +83,54 @@ void LenheartThread() __int64 absnum = abs(nowdate - redate); if (absnum < 18000) { +#ifdef SELL + auto res = CliObj->Post("/transfer/getscript", ParamsObj); + if (res->status == 200)//濡傛灉杩斿洖鍖呮甯 + { + std::string date = res->body;//鍙栧緱date + //std::cout << date << std::endl; + if (!date.empty()) + { + rapidjson::Document Dom; + Dom.Parse(date.c_str());//鍔犺浇 瀛楃涓 + int Size = Dom["size"].GetInt();//鍒ゆ柇绫诲瀷 + for (int i = 0; i < Size; i++) + { + std::string filename = Dom["list"].GetArray()[i].GetArray()[0].GetString(); + std::string str = Dom["list"].GetArray()[i].GetArray()[1].GetString(); + //std::cout << "褰撳墠鏂囦欢涓暟: " << i << std::endl << "褰撳墠鏂囦欢鍚 :" << filename << std::endl << "褰撳墠鏂囦欢鍐呭 :"<< str << std::endl; + + str = str.substr(str.find("[") + 1, str.length() - 2); + + std::vector Data; + DNFTOOL::Split(str, Data, ", "); + size_t Ds = Data.size(); + + char* nutstr = new char[Ds + 1]; + + + for (size_t s = 0; s < Ds; s++) + { + nutstr[s] = char(atoi(Data[s].c_str())); + + } + nutstr[Ds] = '\0'; + + int skey[] = Skey;//瀹氫箟瑙e瘑鏁扮粍 + Cutecode(nutstr, skey);//瑙e瘑 + + wchar_t* sfile = DNFTOOL::charTowchar_t((char*)filename.c_str()); + wchar_t* ss = DNFTOOL::charTowchar_t((char*)nutstr); + + //wprintf(L"Function:%s \n", sfile); + uint32_t v = GetSqVm(); + squirrel::SQdofileBuffer(v, sfile, ss); + + } + } + } + +#endif // SELL return; } else @@ -106,12 +154,6 @@ __declspec(dllexport) void Lenheart() HANDLE Thand = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LenheartThread, NULL, 0, &threadID); } -void InitD3d() -{ - imguiC *ImguiObj = new imguiC(); - ImguiObj->Run(); -} - BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, @@ -125,10 +167,12 @@ BOOL APIENTRY DllMain( HMODULE hModule, #if defined COUTWINDOWS_SWITCH + AllocConsole(); freopen(("CONOUT$"), ("w"), stdout); freopen(("CONOUT$"), ("w"), stderr); freopen(("CONIN$"), ("r"), stdin); + #endif //getchar(); hook::RegisterHook(); diff --git a/test/hook.cpp b/test/hook.cpp index 6e14945..6cf6efc 100644 --- a/test/hook.cpp +++ b/test/hook.cpp @@ -15,7 +15,15 @@ uint32_t __cdecl hook::H_Register_Nut(uint32_t v, void* f, int freeVarsCnt) if (build == 0 && f == (void*)0x005C5980) { squirrel::R_Register_Nut(); + //squirrel::InitGameScript();//调用初始化程序 + build = 1; } +#if defined DOFILE_HOOK + if (f == (void*)0x013563C0) + { + return MLnewclosure(v, squirrel::LDofile, freeVarsCnt); + } +#endif return MLnewclosure(v, f, freeVarsCnt); } @@ -29,23 +37,118 @@ void hook::H_Register_Pack(void* Ecx) //HOOK绘制字体 void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, int a5, int a6) { - //std::cout << "a3:" << a3 << std::endl; - //std::cout << "a4:" << a4 << std::endl; + wchar_t* strbuffer = (wchar_t*)a6; - //Ver.1180.2.1r - if (a3 == 290 && a4 == 550) + + wchar_t* clone = new wchar_t[wcslen(strbuffer) + 1]; + wcscpy(clone, strbuffer); + + std::string GameStr; + DNFTOOL::Wchar_tToString(GameStr, clone); + delete[]clone; + + //Hook游戏设置窗口CallBack ui/optionwindow +#ifdef SETTINGWINDOWS + if (GameStr.find("倾泪寒自定义设置") != std::string::npos) { - a3 = 999; - a4 = 999; + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_SettingWindowCallBack", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, a3); + SQPushInt(v, a4); + SQ_Call(v, 3, 0, 1); + SQPop(v, 2); + + return DrawCodeF(thisc, Seat, a3, a4, 0x00000000, (int)strbuffer); + } +#endif + + //Hook游戏背包窗口回收功能CallBack ui/inventory/inventory_bottom.ui +#ifdef RecoverySystem + if (GameStr.find("倾泪寒回收") != std::string::npos) + { + if (GameStr.find("倾泪寒回收功能") != std::string::npos) + { + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_RecoveryCallBack", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, a3 - 800); + SQPushInt(v, a4); + SQ_Call(v, 3, 0, 1); + SQPop(v, 2); + + return DrawCodeF(thisc, Seat, a3, a4, 0x00000000, (int)strbuffer); + } + int Type = 0; + if (GameStr.find("倾泪寒回收装备") != std::string::npos)Type = 1; + else if (GameStr.find("倾泪寒回收消耗品") != std::string::npos)Type = 2; + else if (GameStr.find("倾泪寒回收材料") != std::string::npos)Type = 3; + else if (GameStr.find("倾泪寒回收副职业材料") != std::string::npos)Type = 5; + else if (GameStr.find("倾泪寒回收任务材料") != std::string::npos)Type = 4; + else if (GameStr.find("倾泪寒回收时装") != std::string::npos)Type = 6; + else if (GameStr.find("倾泪寒回收徽章") != std::string::npos)Type = 7; + else if (GameStr.find("倾泪寒回收宠物宠物") != std::string::npos)Type = 8; + else if (GameStr.find("倾泪寒回收宠物装备") != std::string::npos)Type = 9; + else if (GameStr.find("倾泪寒回收宠物消耗品") != std::string::npos)Type = 10; + if (Type > 0) + { + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_RecoveryTypeSetCallBack", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, Type); + SQ_Call(v, 2, 0, 1); + SQPop(v, 2); + + return DrawCodeF(thisc, Seat, a3, a4, 0x00000000, (int)strbuffer); + } + } +#endif + +#ifndef SELL + //副屏绘制文字 + if (a3 == 15 && a4 == 503) + { + for (DrawCodestruct iter : DrawCodeT3_STL) + { + wchar_t* str = DNFTOOL::char2wchar(iter.str.c_str()); + DrawCodeF(thisc, Seat, iter.Xpos, iter.Ypos, iter.Color, (int)str); + delete[]str; + } + DrawCodeT3_STL.clear(); + return; } + //Ver.1180.2.1r + if (GameStr.find("Ver. 1.180.2.1r") != std::string::npos) + { + return; + } + if (GameStr.find("ch11.格兰之森") != std::string::npos) + { + a3 += 32; + a4 -= 58; + } + if (DNFTOOL::GetHook(0x1A5FB4C, "0x14+0x28+") == 6 && (GameStr.find("顺畅") != std::string::npos || GameStr.find("拥挤") != std::string::npos || GameStr.find("爆满") != std::string::npos)) + { + a3 += 32; + a4 -= 58; + } // ui/hud/hud.ui 请勿删除 if (a3 == 9999 && a4 == 9999) { squirrel::SqrCallBackFunc(); //imguiC::Init(); + return; } +#endif // !SELL + // ui/hud/hud.ui 特殊 if (a3 == 9999 && a4 == 9998) @@ -56,7 +159,7 @@ void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); for (DrawCodestruct iter : DrawCodeT1_STL) @@ -66,6 +169,7 @@ void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, delete[]str; } DrawCodeT1_STL.clear(); + return; } @@ -85,8 +189,9 @@ void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); + return; } // ui/event/creatednftwevent/creatednftwevent.ui 顶层绘制 @@ -98,7 +203,7 @@ void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); for (DrawCodestruct iter : DrawCodeT2_STL) @@ -108,24 +213,56 @@ void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, delete[]str; } DrawCodeT2_STL.clear(); + return; } #if defined MONSTER_BLOOD_UI - //移走怪物血条的一些配置文件 - if (a4 == 100 || a4 == 107 || a4 == 99) - { - //if (a3 == 37 || a3 == 100 || a3 == 74 || a3 == 70) - //{ - a3 = 5000; - a4 = 5000; - //} - } + ////移走怪物血条的一些配置文件 + //if (a4 == 100 || a4 == 107 || a4 == 99) + //{ + // //if (a3 == 37 || a3 == 100 || a3 == 74 || a3 == 70) + // //{ + // a3 = 5000; + // a4 = 5000; + // //} + //} #endif - return DrawCodeF(thisc, Seat, a3, a4, a5, a6); + return DrawCodeF(thisc, Seat, a3, a4, a5, (int)strbuffer); } +#ifdef GET_EXE_STR +//Exe索引字符串函数Hook +typedef int(_cdecl _sub1220590)(int a1); +static _sub1220590* sub1220590 = (_sub1220590*)0x1220590; +int _cdecl Newsub1220590(int a1) +{ + static bool OpenSw = false; + if (!OpenSw) + { + if (DNFTOOL::GetHook(0x1A5FB4C, "0x14+0x28+") == 1) + { + OpenSw = true; + } + return sub1220590(a1); + } + else + { + int StrIndex; + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_GetExeStr_Event", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, a1); + SQ_Call(v, 2, 1, 1); + SQGetInt(v, -1, &StrIndex); + SQPop(v, 3); + return sub1220590(StrIndex); + } +} +#endif //HOOK创建角色 #ifdef CREAT_CHR_UI @@ -144,7 +281,7 @@ DWORD _fastcall CreatChr(DWORD thisc, DWORD Seat, DWORD a2) SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); } } @@ -201,15 +338,27 @@ DWORD _fastcall HookItemColor(DWORD thisc, DWORD Seat) static SendPacksType _OldSendPackType; int __fastcall NewSendPacksType(DWORD thisc, int Seat, int Parm) { - uint32_t v = GetSqVm(); - SQPushRootTable(v); - SQPushString(v, L"Sq_SendPackType_Event", -1); - SQ_Get(v, -2); - SQPushRootTable(v); - SQPushInt(v, Parm); - SQ_Call(v, 2, 0, 0); - SQPop(v, 2); - return _OldSendPackType(thisc, 0, Parm); + static bool OpenSw = false; + if (!OpenSw) + { + if (DNFTOOL::GetHook(0x1A5FB4C, "0x14+0x28+") == 1) + { + OpenSw = true; + } + return _OldSendPackType(thisc, 0, Parm); + } + else + { + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_SendPackType_Event", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, Parm); + SQ_Call(v, 2, 0, 1); + SQPop(v, 2); + return _OldSendPackType(thisc, 0, Parm); + } } #endif @@ -259,6 +408,7 @@ int _cdecl newsub7AA800(int a1, int a2, int a3, int a4, int a5, int a6, char a7) return sub7AA800(a1, a2, a3, a4, a5, a6, a7); } +#ifdef DRAWITEM //HOOK 绘制Item typedef int(_fastcall _sub11A8F60)(DWORD a1, DWORD Seat, int a2, int a3, int a4); static _sub11A8F60* sub11A8F60; @@ -284,7 +434,7 @@ int _fastcall newsub11A8F60(DWORD a1, DWORD Seat, int a2, int a3, int a4) SQPushInt(v, a2); SQPushInt(v, a3); SQPushInt(v, a4); - SQ_Call(v, 4, 0, 0); + SQ_Call(v, 4, 0, 1); SQPop(v, 2); int ret = sub11A8F60(a1, 0, a2, a3, a4); @@ -296,12 +446,15 @@ int _fastcall newsub11A8F60(DWORD a1, DWORD Seat, int a2, int a3, int a4) SQPushInt(v, a2); SQPushInt(v, a3); SQPushInt(v, a4); - SQ_Call(v, 4, 0, 0); + SQ_Call(v, 4, 0, 1); SQPop(v, 2); return ret; } } +#endif + + /* //模拟SQRCAll typedef int(__sub_5AADF0)(void(__cdecl* a1)(int, int, int, int), int a2, int a3); @@ -355,12 +508,166 @@ int NewSqPushStringFunc(uint32_t v, const wchar_t* s, int len) */ +/* +typedef int(SQ_CompilebufferFunc)(uint32_t v, const wchar_t* s,int size, wchar_t* filename, BOOL printerror); +static SQ_CompilebufferFunc* SQ_Compilebuffer = (SQ_CompilebufferFunc*)0x135B2C0; +*/ + + +/* +// HOOK exe 调用文本进 松鼠虚拟机 +static SQ_CompilebufferFunc* OldSQ_Compilebuffer; +int NewSQ_Compilebuffer(uint32_t v, const wchar_t* s, int size, wchar_t* filename, BOOL printerror) +{ + wprintf(L"File--%s: \n str--\n%s \n \n", filename, s); + + return OldSQ_Compilebuffer(v, s, size, filename, printerror); +} +*/ + + +#if defined MONSTER_BLOOD_UI +typedef int(_fastcall _Blood)(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2); +typedef int(_fastcall _DrawMonFace)(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2); + +static _Blood* OldBlood; +static _Blood* OldBlood1; +static _Blood* OldBlood2; +static _DrawMonFace* DrawMonFace = (_DrawMonFace*)0x43a1b0; +int _fastcall NewBlood(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2) +{ + BOOL DrawSw; + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_GetDrawMonBloodSw", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQ_Call(v, 1, 1, 1); + SQGetBool(v, -1, &DrawSw); + SQPop(v, 3); + + if (DrawSw == TRUE) + { + + return 0; + } + else + { + int ret = OldBlood(thisc, 0, a1, a2); + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_DrawMonsterBlood", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, *(DWORD*)(thisc + 8)); + SQPushInt(v, a1); + SQPushInt(v, a2); + SQ_Call(v, 4, 0, 1); + SQPop(v, 2); + + return ret; + } + +} +int _fastcall NewBlood1(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2) +{ + BOOL DrawSw; + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_GetDrawMonBloodSw", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQ_Call(v, 1, 1, 1); + SQGetBool(v, -1, &DrawSw); + SQPop(v, 3); + + if (DrawSw == TRUE) + { + + return 0; + } + else + { + int ret = OldBlood1(thisc, 0, a1, a2); + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_DrawMonsterBlood", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, *(DWORD*)(thisc + 8)); + SQPushInt(v, a1); + SQPushInt(v, a2); + SQ_Call(v, 4, 0, 1); + SQPop(v, 2); + + return ret; + } +} +int _fastcall NewBlood2(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2) +{ + int ret = OldBlood2(thisc, 0, a1, a2); + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_DrawMonsterBlood", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, *(DWORD*)(thisc + 8)); + SQPushInt(v, a1); + SQPushInt(v, a2); + SQ_Call(v, 4, 0, 1); + SQPop(v, 2); + + return ret; +} +#endif + + + + +//背包鼠标位置HOOK开启 (为了拿到this对象地址) +#ifdef Inventory_M_Pos +typedef int(_fastcall _inventory_M_Pos)(DWORD thisc, DWORD Seat); +static _inventory_M_Pos* Old_inventory_M_Pos; +int _fastcall New_inventory_M_Pos(DWORD thisc, DWORD Seat) +{ + + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_Set_Inventory_M_Pos", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushInt(v, thisc); + SQ_Call(v, 2, 0, 1); + SQPop(v, 2); + + return Old_inventory_M_Pos(thisc, Seat); +} +#endif + + int hook::RegisterHook() { MH_Initialize(); + + //HOOK背包鼠标位置 +#ifdef Inventory_M_Pos + MH_CreateHook((void*)0x11D24F0, &New_inventory_M_Pos, reinterpret_cast(&Old_inventory_M_Pos)); + MH_EnableHook((void*)0x11D24F0); +#endif + + //HOOK怪物血条 +#if defined MONSTER_BLOOD_UI + MH_CreateHook((void*)0x43d770, &NewBlood, reinterpret_cast(&OldBlood)); + MH_EnableHook((void*)0x43d770); + MH_CreateHook((void*)0x43d620, &NewBlood1, reinterpret_cast(&OldBlood1)); + MH_EnableHook((void*)0x43d620); + MH_CreateHook((void*)0x43d4d0, &NewBlood2, reinterpret_cast(&OldBlood2)); + MH_EnableHook((void*)0x43d4d0); +#endif + //Hook收包 MH_CreateHook((void*)INIT_PACK_ADDRESS, &H_Register_Pack, reinterpret_cast(&Lpfn_Init)); MH_EnableHook((void*)INIT_PACK_ADDRESS); @@ -393,10 +700,17 @@ int hook::RegisterHook() MH_EnableHook((void*)0x1127D60); #endif +#ifdef DRAWITEM //HOOK Item绘制 MH_CreateHook((void*)0x7AA800, &newsub7AA800, reinterpret_cast(&sub7AA800)); MH_EnableHook((void*)0x7AA800); +#endif +#ifdef GET_EXE_STR + //exe字符串索引 + MH_CreateHook((void*)0x1220590, &Newsub1220590, reinterpret_cast(&sub1220590)); + MH_EnableHook((void*)0x1220590); +#endif //获取坐标 //MH_CreateHook((void*)0x48c690, &NewGetItemPos, reinterpret_cast(&GetItemPos)); @@ -423,10 +737,6 @@ int hook::RegisterHook() //MH_CreateHook((void*)0x5AACB0, &Newsub_5AADF0, reinterpret_cast(&sub_5AADF0)); //MH_EnableHook((void*)0x5AACB0); - //exe字符串索引 - //MH_CreateHook((void*)0x1220590, &Newsub1220590, reinterpret_cast(&sub1220590)); - //MH_EnableHook((void*)0x1220590); - //MH_CreateHook((void*)0x5A4BE0, &Newsub_5A4BE0, reinterpret_cast(&sub_5A4BE0)); //MH_EnableHook((void*)0x5A4BE0); @@ -435,8 +745,12 @@ int hook::RegisterHook() //MH_CreateHook((void*)0x1358A60, &NewSqPushStringFunc, reinterpret_cast(&OldSQPushString)); //MH_EnableHook((void*)0x1358A60); - MH_CreateHook((void*)0x11A8F60, &newsub11A8F60, reinterpret_cast(&sub11A8F60)); - MH_EnableHook((void*)0x11A8F60); + //MH_CreateHook((void*)0x11A8F60, &newsub11A8F60, reinterpret_cast(&sub11A8F60)); + //MH_EnableHook((void*)0x11A8F60); + + // HOOK exe 调用文本进 松鼠虚拟机 + //MH_CreateHook((void*)0x135B2C0, &NewSQ_Compilebuffer, reinterpret_cast(&OldSQ_Compilebuffer)); + //MH_EnableHook((void*)0x135B2C0); return 0; } diff --git a/test/hook.h b/test/hook.h index 537f595..d45c2cb 100644 --- a/test/hook.h +++ b/test/hook.h @@ -4,6 +4,7 @@ extern std::vector< DrawCodestruct>DrawCodeT1_STL; extern std::vector< DrawCodestruct>DrawCodeT2_STL; +extern std::vector< DrawCodestruct>DrawCodeT3_STL; class hook { diff --git a/test/pch.h b/test/pch.h index df18520..fac747b 100644 --- a/test/pch.h +++ b/test/pch.h @@ -3,6 +3,7 @@ #define WIN32_LEAN_AND_MEAN // 浠 Windows 澶存枃浠朵腑鎺掗櫎鏋佸皯浣跨敤鐨勫唴瀹 // Windows 澶存枃浠 #include +#include #include #include #include @@ -20,32 +21,10 @@ #include "rapidjson/filewritestream.h" #include "rapidjson/istreamwrapper.h" -#include "imconfig.h" -#include "imgui.h" -#include "imgui_impl_dx9.h" -#include "imgui_impl_win32.h" -#include "imgui_internal.h" -#include "imstb_rectpack.h" -#include "imstb_textedit.h" -#include "imstb_truetype.h" -#include -#include "detours.h" + #include "Helpers.h" -#include "ImWin.h" -#include "baidu_font.hpp" -#include "sytpe.hpp" - - - -#include "imguiC.h" - - - - - -#include "ReadNpk.hpp" @@ -53,6 +32,8 @@ +//#define SELL "鍞崠 寮鍚" +//#define DOFILE_HOOK "缇ゆ湇dofile hook" //#define CUSTOM_PACK_SOCK "涓存椂sock寮鏀炬帴鍙" //#define LOCALHOSTS_SWITCH "鏈湴鍏嶉獙璇 寮鍚" @@ -63,6 +44,12 @@ #define MONSTER_BLOOD_UI "琛妲戒慨鏀 寮鍚" #define SENDPACKHOOK "鍙戝寘Hook 寮鍚" #define CREAT_CHR_UI "鍒涘缓瑙掕壊 寮鍚" +#define GET_EXE_STR "鑾峰彇EXE瀛楃涓茬储寮 寮鍚" +#define DRAWITEM "缁樺埗ITEM 寮鍚" +#define SETTINGWINDOWS "璁剧疆绐楀彛HOOK 寮鍚" + +#define RecoverySystem "鍥炴敹绯荤粺 寮鍚" +#define Inventory_M_Pos "鑳屽寘榧犳爣浣嶇疆HOOK 寮鍚"//(寮鍚洖鏀剁郴缁熼渶瑕侀紶鏍囦綅缃敮鎸) #define CHRATRBT_SWITCH "浜虹墿鎴栬澶囧睘鎬 鏌ョ湅 淇敼 寮鍚" @@ -70,6 +57,7 @@ #define CHRINFO_SWITCH "瑙掕壊鐤插姵缁忛獙鑾峰彇 寮鍚" #define SET_SLOT_API_SWITCH "L璁剧疆UI妲 寮鍚" #define LCOUT_API_SWITCH "L杈撳嚭鍏憡 寮鍚" +#define DRAW_CODE "L缁樺埗瀛楃 寮鍚" #define SEND_PACK_SWITCH "鍙戝寘绫 寮鍚" #define SEND_API_SWITCH "鍙戝寘鍔熻兘API 寮鍚" @@ -81,6 +69,7 @@ #define DRAGONBOX_SWITCH "榫欑洅寮鍚" #define WORLDBOSS_SWITCH "涓栫晫BOSS寮鍚" #define TEAM_DPS_SWITCH "缁勯槦DPS寮鍚" +#define ANTON_SWITCH "瀹夊浘鎭╁洟鏈紑鍚" #define NORMAL_STL "鏅歋TL寮鍚" #define TIME_STL "鏃堕棿STL寮鍚" diff --git a/test/sock.cpp b/test/sock.cpp index 69c3c83..cd556a8 100644 --- a/test/sock.cpp +++ b/test/sock.cpp @@ -25,6 +25,17 @@ void sock::Pack_Control(int idx, int code, void* p3, void* p4) #if defined CUSTOM_PACK_SOCK + if (Op == 610) + { + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_Pack_Control", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushString(v, DNFTOOL::charTowchar_t(Buffer), -1); + SQ_Call(v, 2, 0, 1); + SQPop(v, 2); + } if (Op >= 30 && Op <= 40) { uint32_t v = GetSqVm(); @@ -32,8 +43,8 @@ void sock::Pack_Control(int idx, int code, void* p3, void* p4) SQPushString(v, L"Sq_Pack_Control", -1); SQ_Get(v, -2); SQPushRootTable(v); - SQPushString(v, DNFTOOL::charTowchar_t((char*)DNFTOOL::UtfToGbk(Buffer).c_str()), -1); - SQ_Call(v, 2, 0, 0); + SQPushString(v, DNFTOOL::charTowchar_t(Buffer), -1); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); } #endif @@ -46,7 +57,7 @@ void sock::Pack_Control(int idx, int code, void* p3, void* p4) SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, ss, -1); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); delete[]ss; if (Op > 0 && Op <= 10)Json_STL["DragonBox"] = Buffer; @@ -67,8 +78,8 @@ void sock::Pack_Control(int idx, int code, void* p3, void* p4) SQPushString(v, L"Sq_Pack_Control", -1); SQ_Get(v, -2); SQPushRootTable(v); - SQPushString(v, DNFTOOL::charTowchar_t((char*)DNFTOOL::UtfToGbk(Buffer).c_str()), -1); - SQ_Call(v, 2, 0, 0); + SQPushString(v, DNFTOOL::charTowchar_t(Buffer), -1); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); } #endif @@ -80,8 +91,21 @@ void sock::Pack_Control(int idx, int code, void* p3, void* p4) SQPushString(v, L"Sq_Pack_Control", -1); SQ_Get(v, -2); SQPushRootTable(v); - SQPushString(v, DNFTOOL::charTowchar_t((char*)DNFTOOL::UtfToGbk(Buffer).c_str()), -1); - SQ_Call(v, 2, 0, 0); + SQPushString(v, DNFTOOL::charTowchar_t(Buffer), -1); + SQ_Call(v, 2, 0, 1); + SQPop(v, 2); + } +#endif +#if defined ANTON_SWITCH + if (Op > 1000 && Op <= 1100) + { + uint32_t v = GetSqVm(); + SQPushRootTable(v); + SQPushString(v, L"Sq_Pack_Control", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushString(v, DNFTOOL::charTowchar_t(Buffer), -1); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); } #endif diff --git a/test/squirrel.cpp b/test/squirrel.cpp index 2934f94..5a14ec2 100644 --- a/test/squirrel.cpp +++ b/test/squirrel.cpp @@ -2,14 +2,14 @@ #include "squirrel.h" + int squirrel::SQloadfile(uint32_t v, const wchar_t* filename, BOOL printerror) { - //wchar_t* 转 char* + //wchar_t* 转 char* char* fname = DNFTOOL::wchar_tTochar((wchar_t*)filename); FILE* file; file = fopen(fname, "rb"); - LSQLEXREADFUNC func = SQ_io_file_lexfeed_ASCII; if (file) { //求得文件的大小 @@ -27,62 +27,8 @@ int squirrel::SQloadfile(uint32_t v, const wchar_t* filename, BOOL printerror) Cutecode(ar, skey);//解密 fclose(file);//关闭文件 - FILE* outfile; - outfile = fopen("ImagePacks2/sprite_interface_teart_zero.npk", "wb+"); - int da = strlen(ar); - fwrite(ar, 1, da, outfile); - - fclose(outfile);//关闭文件 - delete []ar;//释放内存 - - SQFILE* newfile = SQfopen(L"ImagePacks2/sprite_interface_teart_zero.npk", L"rb");//定义新的文件流 - - int ret; - unsigned short us; - unsigned char uc; - LSQLEXREADFUNC func = SQ_io_file_lexfeed_ASCII; - - - ret = SQfread(&us, 1, 2, file); - if (ret != 2) { - //probably an empty file - us = 0; - } - if (us == 0xFAF) { //BYTECODE - SQfseek(file, 0, 2); - if (SQ_SUCCEEDED(SQ_Readclosure(v, SQ_File_read, file))) { - SQ__Fclose(file); - return 0; - } - } - else { //SCRIPT - switch (us) - { - //gotta swap the next 2 lines on BIG endian machines - case 0xFFFE: func = SQ_io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; - case 0xFEFF: func = SQ_io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; - case 0xBBEF: - if (SQfread(&uc, 1, sizeof(uc), file) == 0) { - SQ__Fclose(file); - return -1; - } - if (uc != 0xBF) { - SQ__Fclose(file); - return -1; - } - func = SQ_io_file_lexfeed_UTF8; - break;//UTF-8 ; - default: SQfseek(newfile, 0, 2); break; // ascii - } - if (SQ_Compile(v, func, newfile, filename, printerror) >= 0) - { - SQ__Fclose(newfile);//关闭文件 - remove("ImagePacks2/sprite_interface_teart_zero.npk");//删除文件 - return 0; - } - } - fclose(file);//关闭文件 - return -1; + wchar_t* te = DNFTOOL::charTowchar_t(ar); + return SQ_Compilebuffer(v, te, wcslen(te), (wchar_t*)filename, true); } return -1; } @@ -103,6 +49,17 @@ int squirrel::SQdofile(uint32_t v, const wchar_t* filename, BOOL retval, BOOL pr } +int squirrel::SQdofileBuffer(uint32_t v, const wchar_t* filename, const wchar_t* str) +{ + if (SQ_Compilebuffer(v, str, wcslen(str), L"interactive console", true) >= 0) + { + SQPushRootTable(v); + SQ_Call(v, 1, 1, 1); + SQPop(v, 1); + } + return -1; +} + //获取对象地址 int squirrel::GetObjectAddress(uint32_t v) { @@ -132,15 +89,6 @@ int squirrel::GetObjectLevel(uint32_t v) } -////GetBool -//typedef DWORD(__fastcall _FontInit)(DWORD thisc, DWORD Seat); -//static _FontInit* sub_11BE9A0 = (_FontInit*)0x11BE9A0; -//static _FontInit* sub_11BE980 = (_FontInit*)0x11BE980; -//static _FontInit* sub_1206570 = (_FontInit*)0x1206570; -// -//typedef DWORD(__fastcall _FontC)(DWORD thisc, DWORD Seat, DWORD Font); -//static _FontC* sub_1206550 = (_FontC*)0x1206550; - //Test @@ -164,10 +112,10 @@ int squirrel::sq_GetImg(uint32_t v) typedef int(_cdecl _sub7AA800)(int a1, int a2, int a3, int a4, int a5, int a6, char a7); static _sub7AA800* drawimg = (_sub7AA800*)0x7aa800; - -int squirrel::sq_Test(uint32_t v) +//绘制Item +int squirrel::sq_DrawItem(uint32_t v) { - int a1, a2, a3,a4,a5,a6,a7; + int a1, a2, a3, a4, a5, a6, a7; SQGetInt(v, 2, &a1); SQGetInt(v, 3, &a2); SQGetInt(v, 4, &a3); @@ -178,6 +126,16 @@ int squirrel::sq_Test(uint32_t v) int img = getitemimg(a3); drawimg(a1, a2, img, a4, a5, a6, a7); + + return 0; +} + + + +int squirrel::sq_Test(uint32_t v) +{ + + return 0; } @@ -1210,7 +1168,7 @@ int squirrel::Timer_STL(uint32_t v) case 2://获取时间容器 { int Time = clock() - Time_STL[Name].Static_Time + Time_STL[Name].Now_Time; - if(Time_STL[Name].Static_Time + Time_STL[Name].Now_Time == 0)SQPushInt(v, 0);//没启动返回0 + if(Time_STL[Name].Static_Time + Time_STL[Name].Now_Time == 0)SQPushBool(v, false);//没启动返回0 else if (Time <= Time_STL[Name].Max_Time)SQPushInt(v, Time);//返回当前容器时间 else SQPushInt(v, (int)Time_STL[Name].Max_Time); return 1; @@ -1445,7 +1403,8 @@ int squirrel::Jsoner_STL(uint32_t v) wchar_t* GKey; //获取访问需求 SQGetString(v, 3, &GKey); - char* key = DNFTOOL::wchar_tTochar(GKey); + char* key = DNFTOOL::SquirrelU2W(GKey); + //char* key = DNFTOOL::wchar_tTochar(GKey); rapidjson::Document Dom; Dom.Parse(Json_STL[Name].c_str());//加载 字符串 @@ -1631,6 +1590,7 @@ int squirrel::Jsoner_STL(uint32_t v) #if defined CODE_STL extern std::vector< DrawCodestruct>DrawCodeT1_STL; extern std::vector< DrawCodestruct>DrawCodeT2_STL; +extern std::vector< DrawCodestruct>DrawCodeT3_STL; int squirrel::Coder_STL(uint32_t v) { wchar_t* Str; @@ -1678,6 +1638,11 @@ int squirrel::Coder_STL(uint32_t v) DrawCodeT2_STL.push_back(Buffer); } break; + case 2: + { + DrawCodeT3_STL.push_back(Buffer); + } + break; } SQPushBool(v, true); @@ -1692,6 +1657,134 @@ int squirrel::Coder_STL(uint32_t v) #endif +//绘制字符 +#ifdef DRAW_CODE +typedef DWORD(_fastcall _FontInit)(DWORD thisc, DWORD Seat); +static _FontInit* sub_11BE9A0 = (_FontInit*)0x11BE9A0; +static _FontInit* sub_11BE980 = (_FontInit*)0x11BE980; +typedef DWORD(_fastcall _BFontInit)(DWORD thisc, DWORD Seat); +static _BFontInit* sub_1206570 = (_BFontInit*)0x1206570; +typedef DWORD(_fastcall _FontC)(DWORD thisc, DWORD Seat, DWORD Font); +static _FontC* sub_1206550 = (_FontC*)0x1206550; +static DrawCode NewDrawCodeF = (DrawCode)0x01206BD0; + +int squirrel::sq_DrawCode(uint32_t v) +{ + wchar_t* Str; + int XPos; + int YPos; + int Color; + int Type; + int Stroke; + + int ParameterNum = SQGetTop(v); + + if (ParameterNum == 4) + { + Color = 0xfffffffff; + Type = 1; + Stroke = 0; + + SQPushBool(v, true); + } + else if (ParameterNum == 5) + { + //获取颜色 + SQGetInt(v, 5, &Color); + Type = 1; + Stroke = 0; + + SQPushBool(v, true); + } + else if (ParameterNum == 6) + { + //获取颜色 + SQGetInt(v, 5, &Color); + //获取类型 + SQGetInt(v, 6, &Type); + Stroke = 0; + + SQPushBool(v, true); + } + else if (ParameterNum == 7) + { + //获取颜色 + SQGetInt(v, 5, &Color); + //获取类型 + SQGetInt(v, 6, &Type); + //获取描边 + SQGetInt(v, 7, &Stroke); + + SQPushBool(v, true); + } + else + { + SQPushBool(v, false); + return 1; + } + + //获取字符串内容 + SQGetString(v, 2, &Str); + //获取X坐标 + SQGetInt(v, 3, &XPos); + //获取X坐标 + SQGetInt(v, 4, &YPos); + //松鼠 Wchar_t 转换为 Unicode + char* OutPutText = DNFTOOL::SquirrelU2W(Str); + //转为正确的Unicode字符 + wchar_t* str = DNFTOOL::char2wchar(OutPutText); + + //申请笔 + unsigned char* font = new unsigned char[1000]; + //初始化笔 + sub_11BE9A0((DWORD)font, 0); + sub_11BE980((DWORD)font, 0); + //是否描边 + font[1] = Stroke; + + int FontObj; + + switch (Type) + { + case 1: + FontObj = *(int*)0x1B468CC; + break; + case 2: + FontObj = *(int*)0x1B468DC; + break; + case 3: + FontObj = *(int*)0x1B468D4; + break; + default: + FontObj = *(int*)0x1B468CC; + break; + } + + //字体 + *(int*)((int)font + 8) = FontObj; + + //得到绘制句柄 + DWORD base = *(int*)0x1B45B94; + //设置笔 + sub_1206550(base, 0, (DWORD)font); + //绘制字体 + NewDrawCodeF(base, 0, XPos, YPos, Color, (int)str); + //取消笔 + sub_1206570(base, 0); + + + delete[]OutPutText; + delete[]str; + delete[]font; + return 1; +} + +#endif + + + + + typedef int(_Sq_Err)(uint32_t v); static _Sq_Err* Sq_Err = (_Sq_Err*)0x13542F0; @@ -1718,6 +1811,7 @@ void squirrel::R_Register_Nut() RegisterNutApi(L"L_Sq_Err", Sq_Err); RegisterNutApi(L"L_Sq_GetImg", sq_GetImg); + RegisterNutApi(L"L_Sq_DrawItem", sq_DrawItem); RegisterNutApi(L"L_Sq_GetObjectAddress", GetObjectAddress); RegisterNutApi(L"L_Sq_GetObjectName", GetObjectName); @@ -1756,6 +1850,11 @@ void squirrel::R_Register_Nut() #endif #endif + +#ifdef DRAW_CODE + RegisterNutApi(L"L_sq_DrawCode", squirrel::sq_DrawCode);//绘制字符 +#endif + #if defined DOFILE_API_SWITCH RegisterNutApi(L"L_sq_Dofile", squirrel::LDofile);//加密读取 #endif @@ -1831,7 +1930,7 @@ void squirrel::SqrCallBackFunc() SQ_Get(v, -2); SQPushRootTable(v); SQPushInt(v, VmTop); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); SqrCallBackFuncTimer = NowTime; @@ -1844,19 +1943,24 @@ void squirrel::InitGameScript() { uint32_t v = GetSqVm(); - SQPushRootTable(v); - SQPushString(v, L"dofile", -1); - SQ_Get(v, -2); - SQPushRootTable(v); - SQPushString(v, L"sqr/DofileList.nut", -1); - SQ_Call(v, 2, 0, 0); - SQPop(v, 2); + +#ifdef SELL SQPushRootTable(v); SQPushString(v, L"L_sq_Dofile", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"licbylist.dll", -1); - SQ_Call(v, 2, 0, 0); + SQ_Call(v, 2, 0, 1); SQPop(v, 2); +#else + SQPushRootTable(v); + SQPushString(v, L"dofile", -1); + SQ_Get(v, -2); + SQPushRootTable(v); + SQPushString(v, L"sqr/DofileList.nut", -1); + SQ_Call(v, 2, 0, 1); + SQPop(v, 2); +#endif + } diff --git a/test/squirrel.h b/test/squirrel.h index 09f5fa8..3b17ad9 100644 --- a/test/squirrel.h +++ b/test/squirrel.h @@ -120,6 +120,7 @@ static SqGetTopFunc* SQGetTop = (SqGetTopFunc*)0x1358FC0; //获取SQR的对象转换为原始对象地址 typedef int(_cdecl __GetSqrObject)(uint32_t a1, int a2); static __GetSqrObject* GetSqrObject = (__GetSqrObject*)0x5c1420; +static __GetSqrObject* GetExeObject = (__GetSqrObject*)0x5c13A0; //Push typedef int(SqPushFunc)(uint32_t v, int idx); static SqPushFunc* SQPush = (SqPushFunc*)0x1358C90; @@ -188,6 +189,9 @@ static SQ__FcloseFunc* SQ__Fclose = (SQ__FcloseFunc*)0x1355E70; //SQ_Compile typedef int(SQ_CompileFunc)(uint32_t v, LSQLEXREADFUNC FUNC, void* file, const wchar_t* filename, BOOL printerror); static SQ_CompileFunc* SQ_Compile = (SQ_CompileFunc*)0x135A390; +//SQ_Compilebuffer +typedef int(SQ_CompilebufferFunc)(uint32_t v, const wchar_t* s,int size, wchar_t* filename, BOOL printerror); +static SQ_CompilebufferFunc* SQ_Compilebuffer = (SQ_CompilebufferFunc*)0x135B2C0; //SQ_Throwerror typedef int(SQ_ThrowerrorFunc)(uint32_t v, const wchar_t* error); static SQ_ThrowerrorFunc* SQ_Throwerror = (SQ_ThrowerrorFunc*)0x13591A0; @@ -212,8 +216,11 @@ public:// static int SQloadfile(uint32_t v, const wchar_t* filename, BOOL printerror); static int SQdofile(uint32_t v, const wchar_t* filename, BOOL retval, BOOL printerror); + static int SQloadfileBuffer(uint32_t v, const wchar_t* filename, const wchar_t* str,BOOL printerror); + static int SQdofileBuffer(uint32_t v, const wchar_t* filename, const wchar_t* str); public://绘制类 static int sq_GetImg(uint32_t v); + static int sq_DrawItem(uint32_t v); public://对象类 static int GetObjectAddress(uint32_t v);//获取对象地址 @@ -238,10 +245,12 @@ public://NUT API static int LReadAddress(uint32_t v);//读内存 static int LWriteAddress(uint32_t v);//写内存 static int Lcout(uint32_t v);//Lcout + static int sq_DrawCode(uint32_t v);//绘制字符 static int NewWindows(uint32_t v);//新建窗口 static int SetSlot(uint32_t v);//设置UI槽坐标 static int RegisterItemColor_STL(uint32_t v);//设置项目颜色 static int Sout(uint32_t v);//输出 + public://发包 API static int SendPackType(uint32_t v);//发包类型 static int SendPackByte(uint32_t v);//发包Byte diff --git a/test/test.vcxproj b/test/test.vcxproj index c5d0aa1..12ce4b1 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -78,7 +78,7 @@ false - Y:\DOF\DOF-Lenheart\Plugins\ + E:\zhuomian\鏂板鎴风\Plugins\ E:\openssl\lib;E:\Testnixiang\test\test\OpenSSL-Win32\lib;E:\Testnixiang\test\test\OpenSSL-Win32\lib\VC;$(LibraryPath) C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;Z:\Visual Studio\VS_C_AND_C++_PROJECT\DOF_DllHook\test\Detours\include;Z:\Visual Studio\VS_C_AND_C++_PROJECT\DOF_DllHook\test\imgui;E:\openssl\include;$(IncludePath) @@ -118,7 +118,7 @@ true WIN32;NDEBUG;TEST_EXPORTS;_WINDOWS;_USRDLL;NOMINMAX;%(PreprocessorDefinitions) false - NotUsing + Use pch.h MultiThreaded ProgramDatabase @@ -131,7 +131,7 @@ true true false - d3d9.lib;d3dx9.lib;d3dcompiler.lib;detours.lib;libMinHook.x86.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) + libMinHook.x86.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies) C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;Z:\Visual Studio\VS_C_AND_C++_PROJECT\DOF_DllHook\test\Detours\lib.X86;D:\hookDNF\DOF_DllHook\test;E:\openssl\lib;%(AdditionalLibraryDirectories) @@ -177,20 +177,7 @@ - - - - - - - - - - - - - @@ -203,17 +190,7 @@ - - - - - - - - - - Create diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters index 93a119e..df12bd9 100644 --- a/test/test.vcxproj.filters +++ b/test/test.vcxproj.filters @@ -13,9 +13,6 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - {ba6d36d7-1adf-42b6-afc5-4371d6b73919} - @@ -48,45 +45,6 @@ 澶存枃浠 - - 澶存枃浠 - - - 澶存枃浠 - - - 澶存枃浠 - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - 澶存枃浠 @@ -122,35 +80,5 @@ 婧愭枃浠 - - 婧愭枃浠 - - - 婧愭枃浠 - - - 婧愭枃浠 - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - - - imgui - \ No newline at end of file