#include "pch.h" #include "hook.h" //注册nut uint32_t __cdecl hook::H_Register_Nut(uint32_t v, void* f, int freeVarsCnt) { /* wchar_t* funcName = nullptr; SQGetString(v, -1 - freeVarsCnt, &funcName); //std::wcout << funcName << std::endl; wprintf(L"Function:%s Num:%d Address: 0x%p\n", funcName, freeVarsCnt,f); */ static int build = 0; 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); } //注册收包 void hook::H_Register_Pack(void* Ecx) { Lpfn_Init(Ecx); sock::R_Register_Pack(); } //HOOK绘制字体 void _fastcall hook::H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, int a5, int a6) { wchar_t* strbuffer = (wchar_t*)a6; 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) { 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) { uint32_t v = GetSqVm(); SQPushRootTable(v); SQPushString(v, L"Sq_DrawMainMaxLayerCustomUI", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); SQ_Call(v, 2, 0, 1); SQPop(v, 2); for (DrawCodestruct iter : DrawCodeT1_STL) { wchar_t* str = DNFTOOL::char2wchar(iter.str.c_str()); DrawCodeF(thisc, Seat, iter.Xpos, iter.Ypos, iter.Color, (int)str); delete[]str; } DrawCodeT1_STL.clear(); return; } // ui/selectcharacter/selectcharacterover.ui 选角色 if (a3 == 9999 && a4 == 9489) { static bool Init = false; if (!Init) { squirrel::InitGameScript();//调用初始化程序 Init = true; } uint32_t v = GetSqVm(); SQPushRootTable(v); SQPushString(v, L"Sq_SelectCharacter", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); SQ_Call(v, 2, 0, 1); SQPop(v, 2); return; } // ui/event/creatednftwevent/creatednftwevent.ui 顶层绘制 if (a3 == 8888 && a4 == 8884) { uint32_t v = GetSqVm(); SQPushRootTable(v); SQPushString(v, L"Sq_DrawMainTopLayerCustomUI", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); SQ_Call(v, 2, 0, 1); SQPop(v, 2); for (DrawCodestruct iter : DrawCodeT2_STL) { wchar_t* str = DNFTOOL::char2wchar(iter.str.c_str()); DrawCodeF(thisc, Seat, iter.Xpos, iter.Ypos, iter.Color, (int)str); 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; // //} //} #endif 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 typedef DWORD(_fastcall _OldCreatChr)(DWORD thisc, DWORD Seat, DWORD a3); static _OldCreatChr* OldCreatChr; DWORD _fastcall CreatChr(DWORD thisc, DWORD Seat, DWORD a2) { //std::cout << "a2:" << a2 << std::endl; if (*(int*)0x1A5FE1C == 1) { if (*(int*)a2 == 25481068) { uint32_t v = GetSqVm(); SQPushRootTable(v); SQPushString(v, L"Sq_CreatChr", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushString(v, L"Lenheart", -1); SQ_Call(v, 2, 0, 1); SQPop(v, 2); } } return OldCreatChr(thisc, 0, a2); } #endif // CREAT_CHR_UI //HOOK Item颜色 #ifdef ITEMRARITY extern std::map< int,int>ItemColorMap; typedef DWORD(_cdecl _OldHookEquNameColor)(int rarity); static _OldHookEquNameColor* OldHookEquNameColor; DWORD _cdecl HookEquNameColor(int rarity) { DWORD OldColor = OldHookEquNameColor(rarity); switch (rarity) { case 6: return 0xFF0055FF; case 7: return 0xFF9314FF; case 8: return 0xFF1CBC0C; case 9: return 0xFFACFF08; } return OldColor; } typedef DWORD(_fastcall _OldHookItemColor)(DWORD thisc, DWORD Seat); static _OldHookItemColor* OldHookItemColor; DWORD _fastcall HookItemColor(DWORD thisc, DWORD Seat) { int ItemCode = *(int*)(thisc + 0x1C); if (ItemColorMap.count(ItemCode) == 1) { return ItemColorMap[ItemCode]; } //不在注册项目颜色map里就执行原颜色获取 int Rarity = *(int*)(thisc + 0xF4); int color = HookEquNameColor(Rarity); return color; } #endif //HOOK 发包类型 #ifdef SENDPACKHOOK static SendPacksType _OldSendPackType; int __fastcall NewSendPacksType(DWORD thisc, int Seat, int 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 /* //HOOK 获取ITEM 坐标 typedef int(_fastcall __GetItemPos)(DWORD thisc, DWORD Seat); static __GetItemPos* GetItemPos; int __fastcall NewGetItemPos(DWORD thisc, int Seat) { int PosX = *(int*)(thisc + 0x14); int PosY = *(int*)(thisc + 0x18); return PosX; } */ /* //Img 绘制函数 typedef int(_fastcall __sub_11A97E0)(DWORD a1, DWORD Seat, int a2, int a3,DWORD a4, int a5,int a6,int a7 ,int a8,float a9, float a10); static __sub_11A97E0* sub_11A97E0; int _fastcall Newsub_11A97E0(DWORD a1, DWORD Seat, int a2, int a3, DWORD a4, int a5, int a6, int a7, int a8, float a9, float a10) { //std::cout << "a1: " << a1 << std::endl; //std::cout << "a2: " << a2 << std::endl; //std::cout << "a3: " << a3 << std::endl; //std::cout << "a4: " << a4 << std::endl; //std::cout << "a5: " << a5 << std::endl; //std::cout << "a6: " << a6 << std::endl; //std::cout << "a7: " << a7 << std::endl; //std::cout << "a8: " << a8 << std::endl; //std::cout << "a9: " << a9 << std::endl; //std::cout << "a10: " << a10 << std::endl; static DWORD st = a4; return sub_11A97E0(a1, 0, a2, a3, st, a5, a6, a7, a8, a9, a10); } */ //HOOK 绘制stackable typedef int(_cdecl _sub7AA800)(int a1, int a2, int a3 , int a4, int a5 , int a6,char a7); static _sub7AA800* sub7AA800; 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; int _fastcall newsub11A8F60(DWORD a1, DWORD Seat, int a2, int a3, int a4) { static bool OpenSw = false; if (!OpenSw) { //std::cout << DNFTOOL::GetHook(0x1A5FB4C, "0x14+0x28+") << std::endl; if (DNFTOOL::GetHook(0x1A5FB4C, "0x14+0x28+") == 1) { OpenSw = true; } return sub11A8F60(a1, 0, a2, a3, a4); } else { uint32_t v = GetSqVm(); SQPushRootTable(v); SQPushString(v, L"Sq_DrawItemBack", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushInt(v, a2); SQPushInt(v, a3); SQPushInt(v, a4); SQ_Call(v, 4, 0, 1); SQPop(v, 2); int ret = sub11A8F60(a1, 0, a2, a3, a4); SQPushRootTable(v); SQPushString(v, L"Sq_DrawItemFront", -1); SQ_Get(v, -2); SQPushRootTable(v); SQPushInt(v, a2); SQPushInt(v, a3); SQPushInt(v, a4); 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); static __sub_5AADF0* sub_5AADF0; int Newsub_5AADF0(void(__cdecl* a1)(int, int, int, int), int a2, int a3) { std::cout << "drawani: " << a1 << std::endl; //std::cout << "TestDrawSkill" << std::endl; //std::cout << "DrawSkillAddr:" << a1 << std::endl; return sub_5AADF0(a1, a2, a3); } */ /* //大部分IMG数字的调用函数 typedef int(_fastcall __sub_11B2390)(DWORD a1, DWORD Seat, int a2, int a3, int a4, int a5, DWORD* a6); static __sub_11B2390* sub_11B2390; int _fastcall Newsub_11B2390(DWORD a1, DWORD Seat, int a2, int a3, int a4, int a5, DWORD* a6) { //std::cout << "a2: " << a2 << std::endl; //std::cout << "a3: " << a3 << std::endl; //std::cout << "a4: " << a4 << std::endl; //std::cout << "a5: " << a5 << std::endl; a2 = 100; a3 = 100; return sub_11B2390(a1, 0, a2, a3, a4, a5, a6); } */ /* //push string std::map< std::wstring, int>BQS; static SqPushStringFunc* OldSQPushString; int NewSqPushStringFunc(uint32_t v, const wchar_t* s, int len) { std::wstring a = s; if (BQS.count(a) != 1) { wprintf(L"Name:%s Len:%d\n", s, len); BQS[a] = 1; } //std::wcout << funcName << std::endl; return OldSQPushString(v, s, 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); //HookNut函数注册 MH_CreateHook((void*)INIT_NUT_ADDRESS, &H_Register_Nut, reinterpret_cast(&MLnewclosure)); MH_EnableHook((void*)INIT_NUT_ADDRESS); //Hook绘制字符 MH_CreateHook((void*)INIT_NUT_DRAWCODE, &H_Register_DrawCode, reinterpret_cast(&DrawCodeF)); MH_EnableHook((void*)INIT_NUT_DRAWCODE); #ifdef CREAT_CHR_UI MH_CreateHook((void*)0x10f3050, &CreatChr, reinterpret_cast(&OldCreatChr)); MH_EnableHook((void*)0x10f3050); #endif // CREAT_CHR_UI #ifdef ITEMRARITY //HOOK获取绘制颜色 MH_CreateHook((void*)0x7AB080, &HookItemColor, reinterpret_cast(&OldHookItemColor)); MH_EnableHook((void*)0x7AB080); //HOOK根据品级得到颜色 MH_CreateHook((void*)0x7AAD00, &HookEquNameColor, reinterpret_cast(&OldHookEquNameColor)); MH_EnableHook((void*)0x7AAD00); #endif #ifdef SENDPACKHOOK //HOOK发包类型 MH_CreateHook((void*)0x1127D60, &NewSendPacksType, reinterpret_cast(&_OldSendPackType)); 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)); //MH_EnableHook((void*)0x48c690); //nut调用绘制技能的函数 //MH_CreateHook((void*)0x5DCDA0, &Newsub_5DCDA0, reinterpret_cast(&sub_5DCDA0)); //MH_EnableHook((void*)0x5DCDA0); //绘制技能图标的函数 //MH_CreateHook((void*)0x5A4BE0, &Newsub_5A4BE0, reinterpret_cast(&sub_5A4BE0)); //MH_EnableHook((void*)0x5A4BE0); //img绘制的函数 //MH_CreateHook((void*)0x11A97E0, &Newsub_11A97E0, reinterpret_cast(&sub_11A97E0)); //MH_EnableHook((void*)0x11A97E0); //大部分IMG数字的调用函数 //MH_CreateHook((void*)0x11B2390, &Newsub_11B2390, reinterpret_cast(&sub_11B2390)); //MH_EnableHook((void*)0x11B2390); //模拟Sqrcall //MH_CreateHook((void*)0x5AACB0, &Newsub_5AADF0, reinterpret_cast(&sub_5AADF0)); //MH_EnableHook((void*)0x5AACB0); //MH_CreateHook((void*)0x5A4BE0, &Newsub_5A4BE0, reinterpret_cast(&sub_5A4BE0)); //MH_EnableHook((void*)0x5A4BE0); //MH_CreateHook((void*)0x1358A60, &NewSqPushStringFunc, reinterpret_cast(&OldSQPushString)); //MH_EnableHook((void*)0x1358A60); //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; }