//************************************ // FileName: D:\VisualStudioSource\dnf_project\src\controller.cpp // FullName: D:\VisualStudioSource\dnf_project\src // Date: 2022/09/01 // By: Vance // Copyright (c) 2022. Vance All rights reserved //************************************ #include "controller.h" Controller::Controller() : old_IPacketDispatcher_ParamBase_dispatch_template((IPacketDispatcher_ParamBase_dispatch_template_Type*)base::IPacketDispatcher::ParamBase::dispatch_template), old_UseJewel_dispatch_sig((UseJewel_dispatch_sig_Type*)base::Dispatcher_UseJewel::dispatch_sig), old_PacketDispatcher_doDispatch((PacketDispatcher_doDispatch_Type*)base::PacketDispatcher::doDispatch) { } Controller::~Controller() { } void Controller::init() { CodeHook::WriteUChar((void*)(base::GlobalData::Init_fix_1 - 0x1), 0); //.text:085BDE9D 83 F8 0A cmp eax, 10 CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_1 + 2), 0x7E); //普通被击 //.text:085BDF30 83 F8 1E cmp eax, 30 CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_2 + 2), 0x7E); //远古被击 //.text:085BDFC3 83 F8 32 cmp eax, 50 CodeHook::WriteUChar((void*)(base::CParty::addDungeonClear_fix_3 + 2), 0x7E); //异界被击 //mhook_IPacketDispatcher_ParamBase_dispatch_template.Hook((void**)&old_IPacketDispatcher_ParamBase_dispatch_template, (void*)hook_IPacketDispatcher_ParamBase_dispatch_template); mhook_PacketDispatcher_doDispatch.Hook((void**)&old_PacketDispatcher_doDispatch, (void*)hook_PacketDispatcher_doDispatch); mhook_UseJewel_dispatch_sig.Hook((void**)&old_UseJewel_dispatch_sig, (void*)hook_UseJewel_dispatch_sig); LOG("Controller::init()"); } int Controller::hook_IPacketDispatcher_ParamBase_dispatch_template(int a1, int a2, int a3) { //[root@nimzgryilkxubzo game] # [DNF_PROJECT] Recv() class :1 id : 84 len : 21 callback : 0x81258b6 (nil)0x81258b6 0x8125a06 (nil)(nil) // [DNF_PROJECT] + 12 0x8bd8d54 : Dispatcher_ModItemAttr::dispatch_sig(CUser *,PacketBuf &) // [DNF_PROJECT] + 16 0x8bd8d58 : IPacketDispatcher::check_state(CUser *,PacketBuf &) // [DNF_PROJECT] + 20 0x8bd8d5c : Dispatcher_ModItemAttr::read(PacketBuf &,MSG_BASE &) // [DNF_PROJECT] + 24 0x8bd8d60 : Dispatcher_ModItemAttr::process(CUser *,MSG_BASE &,ParamBase &) // [DNF_PROJECT] + 28 0x8bd8d64 : IPacketDispatcher::send(CUser *,ParamBase&) // // // [DNF_PROJECT] + 12 0x8bd7dd4 : Dispatcher_Antibot::dispatch_sig // [DNF_PROJECT] + 16 0x8bd7dd8 : IPacketDispatcher::check_state(CUser *,PacketBuf &) // [DNF_PROJECT] + 20 0x8bd7ddc : Dispatcher_Antibot::read(PacketBuf &,MSG_BASE &) // [DNF_PROJECT] + 24 0x8bd7de0 : Dispatcher_Antibot::process(CUser *,MSG_BASE &,ParamBase &) // [DNF_PROJECT] + 28 0x8bd7de4 : IPacketDispatcher::send(CUser *,ParamBase&) //LOG("ParamBase_dispatch_template[ +12 :%p +16 :%p +20 :%p +24 :%p +28 :%p ]" // , *(int*)a1 + 12 // , *(int*)a1 + 16 // , *(int*)a1 + 20 // , *(int*)a1 + 24 // , *(int*)a1 + 28 //); Controller::Get()->old_IPacketDispatcher_ParamBase_dispatch_template(a1, a2, a3); } int Controller::hook_UseJewel_dispatch_sig(void* pDispatcher_UseJewel, CUser* user, PacketBuf* pBuf) { printf("getCurCharacName :%s \n", user->getCurCharacName().c_str()); printf("getCurCharacNo :%d \n", user->getCurCharacNo()); printf("get_buf_ptr :%p %p \n", pBuf->get_buf_ptr(0)); printf("get_len :%d \n", pBuf->get_len()); // printf("pBuf :%s \n", Util::ToHexString((const unsigned char*)pBuf->get_buf_ptr(0),40).c_str()); int state = user->get_state(); LOG("state :%d \n", state); //校验角色状态是否允许镶嵌 if (state != 3) return 0; int isEnableAvatarSocketAction = user->isEnableAvatarSocketAction(); if (isEnableAvatarSocketAction) user->SendCmdErrorPacket(205, (unsigned char)isEnableAvatarSocketAction); //解析packet_buf //时装所在的背包槽 int avartar_inven_slot = pBuf->get_short(); LOG("avartar_inven_slot :%d \n", avartar_inven_slot); //时装item_id int avartar_item_id = pBuf->get_int(); LOG("avartar_item_id :%d \n", avartar_item_id); //本次镶嵌徽章数量 int emblem_cnt = pBuf->get_byte(); LOG("emblem_cnt :%d \n", emblem_cnt); if (user->CheckItemLock(2, avartar_inven_slot)) { user->SendCmdErrorPacket(205, 213); return 0; } //获取时装道具 CInventory* inven = user->getCurCharacInvenW(); if (!inven) { LOG("pUser->getCurCharacInvenW : error \n"); return 0; } Inven_Item* avartar = inven->GetInvenRef(CInventory::INVENTORY_TYPE_AVARTAR, avartar_inven_slot); if (!avartar) { LOG("inven->GetInvenRef : error \n"); return 0; } //校验时装 数据是否合法 if (avartar->isEmpty() || (avartar->getKey() != avartar_item_id) || user->CheckItemLock(2, avartar_inven_slot)) { LOG("avartar->isEmpty() || avartar->getKey() || pUser->CheckItemLock() : error \n"); return 0; } //获取时装插槽数据 WongWork::CAvatarItemMgr* avartar_add_info = avartar->get_add_info(); WongWork::CAvatarItemMgr* inven_avartar_mgr = inven->GetAvatarItemMgrR(); int jewel_socket_data = inven_avartar_mgr->getJewelSocketData(avartar_add_info); if (!jewel_socket_data) { LOG("jewel_socket_data : error \n"); return 0; } LOG("jewel_socket_data :%s \n", Util::ToHexString((const unsigned char*)jewel_socket_data, 40).c_str()); if (emblem_cnt <= 3) { std::map> emblems; for (int i = 0; i < emblem_cnt; i++) { //徽章所在的背包槽 int emblem_inven_slot = pBuf->get_short(); //徽章item_id int emblem_item_id = pBuf->get_int(); //该徽章镶嵌的时装插槽id int avartar_socket_slot = pBuf->get_byte(); //获取徽章道具 Inven_Item* emblem = inven->GetInvenRef(CInventory::INVENTORY_TYPE_ITEM, emblem_inven_slot); //校验徽章及插槽数据是否合法 if (emblem->isEmpty() || (emblem->getKey() != emblem_item_id) || (avartar_socket_slot >= 3)) { LOG("emblem->isEmpty() || (emblem->getKey() : error \n"); user->SendCmdErrorPacket(205, 209); return 0; } //校验徽章是否满足时装插槽颜色要求 //获取徽章pvf数据 CDataManager* DataManager = CDataManager::G_CDataManager(); if (!DataManager) { LOG("CDataManager::G_CDataManager() : error \n"); user->SendCmdErrorPacket(205, 209); return 0; } CItem* citem = DataManager->find_item(emblem_item_id); if (!citem) { LOG("DataManager->find_item() : error \n"); user->SendCmdErrorPacket(205, 209); return 0; } //校验徽章类型 if (!citem->is_stackable() || (citem->GetItemType() != 20)) { LOG("citem->is_stackable() || (citem->GetItemType() : error \n"); user->SendCmdErrorPacket(205, 209); return 0; } //获取徽章支持的插槽 int emblem_socket_type = citem->getJewelTargetSocket(); //获取要镶嵌的时装插槽类型 int avartar_socket_type = *(short*)(jewel_socket_data + avartar_socket_slot * 6); if (!(emblem_socket_type & avartar_socket_type)) { //插槽类型不匹配 LOG("emblem_socket_type & avartar_socket_type\n"); user->SendCmdErrorPacket(205, 209); return 0; } LOG("avartar_socket_slot:%d emblem_inven_slot:%d emblem_item_id:%d\n", avartar_socket_slot, emblem_inven_slot, emblem_item_id); emblems[avartar_socket_slot] = std::make_pair(emblem_inven_slot, emblem_item_id); } LOG("数据已读取!!!\n"); for (auto& avartar_socket_slot : emblems) { //删除徽章 int emblem_inven_slot = avartar_socket_slot.second.first; inven->delete_item(CInventory::INVENTORY_TYPE_ITEM, emblem_inven_slot, 1, 8, 1); //设置时装插槽数据 int emblem_item_id = avartar_socket_slot.second.second; *(int*)(jewel_socket_data + avartar_socket_slot.first * 6 + 2) = emblem_item_id; LOG("徽章item_id=%d 已成功镶嵌进avartar_socket_slot=%d 的槽内!\n", emblem_item_id, avartar_socket_slot); } //时装插槽数据存档 DB_UpdateAvatarJewelSlot::makeRequest(user->getCurCharacNo(), avartar->get_ui_id(), (void*)jewel_socket_data); //通知客户端时装数据已更新 user->SendUpdateItemList(1, 1, avartar_inven_slot); LOG("徽章镶嵌完毕!!!"); //回包给客户端 InterfacePacketBuf* packet_guard = (InterfacePacketBuf*)PacketGuard::NewPacketGuard(); packet_guard->put_header(1, 204); packet_guard->put_int(1); packet_guard->finalize(1); user->Send((PacketGuard*)packet_guard); PacketGuard::DelPacketGuard((PacketGuard*)packet_guard); } // 08217C06 分解 return 0; } int Controller::hook_PacketDispatcher_doDispatch(PacketDispatcher* a1, CUser* user, int packet_class, int packet_id, char* packet_src, int packet_len, int a7, int a8) { int(***dispatcher)(int, CUser*, char*) = (int(***)(int, CUser*, char*))a1->get_dispatcher(packet_id); if (dispatcher) { //v32 = (**dispatcher)(dispatcher, user, v25); LOG("Recv() class:%d id:%d len:%d %p [ +00 :%p +12 :%p +16 :%p +20 :%p +24 :%p +28 :%p ]" , packet_class , packet_id , packet_len , (**dispatcher) , *(int*)dispatcher , *(int*)dispatcher + 12 , *(int*)dispatcher + 16 , *(int*)dispatcher + 20 , *(int*)dispatcher + 24 , *(int*)dispatcher + 28 ); } if (packet_id == Packet_UseEquipmentMoveItem) { int result = 0; PacketBuf* v25 = PacketBuf::NewPacketBuf(); user->setLastPacketID(packet_id); v25->bind_packet(packet_src, packet_len); LOG("Recv() class:%d id:%d len:%d packet_data :%s " , packet_class , packet_id , packet_len , Util::ToHexString((const unsigned char*)packet_src, packet_len).c_str() ); if (v25) { ENUM_PACK_RET_TYPE ret = CDispatch::Get()->UseEquipmentMoveItem(user, v25); result = (ret == PAK_ERROR) ? 1 : 0; PacketBuf::DelPacketBuf(v25); } return result; } return Controller::Get()->old_PacketDispatcher_doDispatch(a1, user, packet_class, packet_id, packet_src, packet_len, a7, a8); }