diff --git a/common/emu_oplist.h b/common/emu_oplist.h index 869a9bd3a..f5386e9b5 100644 --- a/common/emu_oplist.h +++ b/common/emu_oplist.h @@ -129,8 +129,8 @@ N(OP_DisciplineTimer), N(OP_DisciplineUpdate), N(OP_DiscordMerchantInventory), N(OP_DoGroupLeadershipAbility), -N(OP_DuelResponse), -N(OP_DuelResponse2), +N(OP_DuelDecline), +N(OP_DuelAccept), N(OP_DumpName), N(OP_Dye), N(OP_DynamicWall), diff --git a/common/opcode_dispatch.h b/common/opcode_dispatch.h index 496dcdea3..a19cb79a3 100644 --- a/common/opcode_dispatch.h +++ b/common/opcode_dispatch.h @@ -115,8 +115,8 @@ IN(OP_GMTraining, GMTrainee_Struct); IN(OP_GMEndTraining, GMTrainEnd_Struct); IN(OP_GMTrainSkill, GMSkillChange_Struct); IN(OP_RequestDuel, Duel_Struct); -IN(OP_DuelResponse, DuelResponse_Struct); -IN(OP_DuelResponse2, Duel_Struct); +IN(OP_DuelDecline, DuelResponse_Struct); +IN(OP_DuelAccept, Duel_Struct); IN(OP_SpawnAppearance, SpawnAppearance_Struct); IN(OP_BazaarInspect, BazaarInspect_Struct); IN(OP_Death, Death_Struct); diff --git a/common/opcode_map.cpp b/common/opcode_map.cpp index 7c8fed281..c0556cf2a 100644 --- a/common/opcode_map.cpp +++ b/common/opcode_map.cpp @@ -240,8 +240,8 @@ void load_opcode_names() opcode_map[0x00a1] = "LiveOP_SaveOnZoneReq"; opcode_map[0x0185] = "LiveOP_Logout"; opcode_map[0x0298] = "LiveOP_RequestDuel"; - opcode_map[0x0a5d] = "LiveOP_DuelResponse"; - opcode_map[0x016e] = "LiveOP_DuelResponse2"; + opcode_map[0x0a5d] = "LiveOP_DuelDecline"; + opcode_map[0x016e] = "LiveOP_DuelAccept"; opcode_map[0x007c] = "LiveOP_InstillDoubt"; opcode_map[0x00ac] = "LiveOP_SafeFallSuccess"; opcode_map[0x02fb] = "LiveOP_DisciplineUpdate"; diff --git a/utils/patches/opcodes.conf b/utils/patches/opcodes.conf index 562ba3347..3f5e87b5a 100644 --- a/utils/patches/opcodes.conf +++ b/utils/patches/opcodes.conf @@ -307,8 +307,8 @@ OP_RecipeAutoCombine=0x0353 OP_TradeSkillCombine=0x0b40 OP_RequestDuel=0x0000 -OP_DuelResponse=0x0000 -OP_DuelResponse2=0x0000 #when accepted +OP_DuelDecline=0x0000 +OP_DuelAccept=0x0000 #when accepted OP_RezzComplete=0x0000 #packet wrong on this OP_RezzRequest=0x0000 #packet wrong on this diff --git a/utils/patches/patch_RoF.conf b/utils/patches/patch_RoF.conf index 93175209e..8065ca53c 100644 --- a/utils/patches/patch_RoF.conf +++ b/utils/patches/patch_RoF.conf @@ -288,8 +288,8 @@ OP_YellForHelp=0x0017 OP_LoadSpellSet=0x38b4 OP_Bandolier=0x2b6f OP_PotionBelt=0x2d1b # Was 0x4d3b -OP_DuelResponse=0x0dee -OP_DuelResponse2=0x5e04 +OP_DuelDecline=0x0dee +OP_DuelAccept=0x5e04 OP_SaveOnZoneReq=0x36b1 OP_ReadBook=0x383c OP_Dye=0x62d8 diff --git a/utils/patches/patch_RoF2.conf b/utils/patches/patch_RoF2.conf index ac69e5550..3ecb0df68 100644 --- a/utils/patches/patch_RoF2.conf +++ b/utils/patches/patch_RoF2.conf @@ -287,8 +287,8 @@ OP_YellForHelp=0x4e56 OP_LoadSpellSet=0x261d OP_Bandolier=0x7677 OP_PotionBelt=0x1a3e -OP_DuelResponse=0x6a46 -OP_DuelResponse2=0x68d3 +OP_DuelDecline=0x6a46 +OP_DuelAccept=0x68d3 OP_SaveOnZoneReq=0x600d OP_ReadBook=0x72df OP_Dye=0x23b9 diff --git a/utils/patches/patch_SoD.conf b/utils/patches/patch_SoD.conf index dd3ee0384..69f4c996b 100644 --- a/utils/patches/patch_SoD.conf +++ b/utils/patches/patch_SoD.conf @@ -281,7 +281,7 @@ OP_YellForHelp=0x6f79 # C OP_LoadSpellSet=0x7113 # C OP_Bandolier=0x441c # C OP_PotionBelt=0x5db5 # C -OP_DuelResponse=0x1ebb # C +OP_DuelDecline=0x1ebb # C OP_SaveOnZoneReq=0x6eff # C OP_ReadBook=0x2444 # C OP_Dye=0x3672 # C @@ -299,7 +299,7 @@ OP_DoGroupLeadershipAbility=0x540b # C OP_GroupLeadershipAAUpdate=0x0c33 OP_DelegateAbility=0x0322 # C OP_SetGroupTarget=0x521c # C -OP_DuelResponse2=0x52b5 # C +OP_DuelAccept=0x52b5 # C OP_Charm=0x7108 # C OP_Stun=0x2a6d # C OP_SendFindableNPCs=0x5360 diff --git a/utils/patches/patch_SoF.conf b/utils/patches/patch_SoF.conf index e6aa71168..56602d8f6 100644 --- a/utils/patches/patch_SoF.conf +++ b/utils/patches/patch_SoF.conf @@ -275,7 +275,7 @@ OP_YellForHelp=0x4F4A #Trevius 03/19/09 OP_LoadSpellSet=0x05B5 #Trevius 03/19/09 OP_Bandolier=0x3FD4 #Trevius 03/19/09 OP_PotionBelt=0x16F3 #Trevius 03/19/09 -OP_DuelResponse=0x5E59 #Derision 2009 +OP_DuelDecline=0x5E59 #Derision 2009 OP_SaveOnZoneReq=0x1103 #Trevius 03/20/09 OP_ReadBook=0x424a #Xinu 03/19/09 OP_Dye=0x3611 #Xinu 03/19/09 @@ -292,7 +292,7 @@ OP_ClearRaidNPCMarks=0x56a9 # OP_DoGroupLeadershipAbility=0x5a64 #Derision 2009 OP_DelegateAbility=0x57e3 #Derision 2009 OP_SetGroupTarget=0x1651 #Derision 2009 -OP_DuelResponse2=0x2A85 #Derision 2009 +OP_DuelAccept=0x2A85 #Derision 2009 OP_Charm=0x2F32 #Derision 2009 OP_Stun=0x55BF #Derision 2009 OP_FindPersonRequest=0x07F0 #Derision 2009 diff --git a/utils/patches/patch_Titanium.conf b/utils/patches/patch_Titanium.conf index 2c647f95c..28074dcf9 100644 --- a/utils/patches/patch_Titanium.conf +++ b/utils/patches/patch_Titanium.conf @@ -356,8 +356,8 @@ OP_RecipeAutoCombine=0x0353 OP_TradeSkillCombine=0x0b40 OP_RequestDuel=0x28e1 -OP_DuelResponse=0x3bad -OP_DuelResponse2=0x1b09 #when accepted +OP_DuelDecline=0x3bad +OP_DuelAccept=0x1b09 #when accepted OP_RezzComplete=0x4b05 OP_RezzRequest=0x1035 diff --git a/utils/patches/patch_UF.conf b/utils/patches/patch_UF.conf index 4dd97fad0..6a98e3b02 100644 --- a/utils/patches/patch_UF.conf +++ b/utils/patches/patch_UF.conf @@ -290,8 +290,8 @@ OP_YellForHelp=0x55a8 # C OP_LoadSpellSet=0x6617 # C OP_Bandolier=0x510c # C OP_PotionBelt=0x0651 # C -OP_DuelResponse=0x41a6 # C -OP_DuelResponse2=0x6d60 # C +OP_DuelDecline=0x41a6 # C +OP_DuelAccept=0x6d60 # C OP_SaveOnZoneReq=0x2913 # C OP_ReadBook=0x465e # C OP_Dye=0x2137 # C diff --git a/zone/client.h b/zone/client.h index 2ba96bd30..c6e12071e 100644 --- a/zone/client.h +++ b/zone/client.h @@ -783,9 +783,9 @@ public: void GMKill(); inline bool IsMedding() const {return medding;} - inline uint16 GetDuelTarget() const { return duel_target; } + inline uint32 GetDuelTarget() const { return duel_target; } inline bool IsDueling() const { return duelaccepted; } - inline void SetDuelTarget(uint16 set_id) { duel_target=set_id; } + inline void SetDuelTarget(uint32 set_id) { duel_target = set_id; } inline void SetDueling(bool duel) { duelaccepted = duel; } // use this one instead void MemSpell(uint16 spell_id, int slot, bool update_client = true); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 3bb32aa25..f50928479 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -194,8 +194,8 @@ void MapOpcodes() ConnectedOpcodes[OP_Disarm] = &Client::Handle_OP_Disarm; ConnectedOpcodes[OP_DisarmTraps] = &Client::Handle_OP_DisarmTraps; ConnectedOpcodes[OP_DoGroupLeadershipAbility] = &Client::Handle_OP_DoGroupLeadershipAbility; - ConnectedOpcodes[OP_DuelResponse] = &Client::Handle_OP_DuelResponse; - ConnectedOpcodes[OP_DuelResponse2] = &Client::Handle_OP_DuelResponse2; + ConnectedOpcodes[OP_DuelDecline] = &Client::Handle_OP_DuelDecline; + ConnectedOpcodes[OP_DuelAccept] = &Client::Handle_OP_DuelAccept; ConnectedOpcodes[OP_DumpName] = &Client::Handle_OP_DumpName; ConnectedOpcodes[OP_Dye] = &Client::Handle_OP_Dye; ConnectedOpcodes[OP_DzAddPlayer] = &Client::Handle_OP_DzAddPlayer; @@ -5543,37 +5543,57 @@ void Client::Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app) } } -void Client::Handle_OP_DuelResponse(const EQApplicationPacket *app) +void Client::Handle_OP_DuelDecline(const EQApplicationPacket *app) { - if (app->size != sizeof(DuelResponse_Struct)) + if (app->size != sizeof(DuelResponse_Struct)) { return; + } + DuelResponse_Struct* ds = (DuelResponse_Struct*)app->pBuffer; + if (!ds->target_id || !ds->entity_id) { + return; + } + Entity* entity = entity_list.GetID(ds->target_id); Entity* initiator = entity_list.GetID(ds->entity_id); - if (!entity->IsClient() || !initiator->IsClient()) + if (!entity->IsClient() || !initiator->IsClient()) { return; + } entity->CastToClient()->SetDuelTarget(0); entity->CastToClient()->SetDueling(false); initiator->CastToClient()->SetDuelTarget(0); initiator->CastToClient()->SetDueling(false); - if (GetID() == initiator->GetID()) + if (GetID() == initiator->GetID()) { entity->CastToClient()->MessageString(Chat::NPCQuestSay, DUEL_DECLINE, initiator->GetName()); - else + } else { initiator->CastToClient()->MessageString(Chat::NPCQuestSay, DUEL_DECLINE, entity->GetName()); + } return; } -void Client::Handle_OP_DuelResponse2(const EQApplicationPacket *app) +void Client::Handle_OP_DuelAccept(const EQApplicationPacket *app) { - if (app->size != sizeof(Duel_Struct)) + if (app->size != sizeof(Duel_Struct)) { return; + } Duel_Struct* ds = (Duel_Struct*)app->pBuffer; + if (!ds->duel_initiator || !ds->duel_target) { + return; + } + Entity* entity = entity_list.GetID(ds->duel_target); Entity* initiator = entity_list.GetID(ds->duel_initiator); + if (!entity || !initiator) { + return; + } - if (entity && initiator && entity == this && initiator->IsClient()) { + if (GetDuelTarget() != ds->duel_initiator || IsDueling()) { + return; + } + + if (entity == this && initiator->IsClient()) { auto outapp = new EQApplicationPacket(OP_RequestDuel, sizeof(Duel_Struct)); Duel_Struct* ds2 = (Duel_Struct*)outapp->pBuffer; @@ -5581,7 +5601,7 @@ void Client::Handle_OP_DuelResponse2(const EQApplicationPacket *app) ds2->duel_target = entity->GetID(); initiator->CastToClient()->QueuePacket(outapp); - outapp->SetOpcode(OP_DuelResponse2); + outapp->SetOpcode(OP_DuelAccept); ds2->duel_initiator = initiator->GetID(); initiator->CastToClient()->QueuePacket(outapp); @@ -5592,10 +5612,13 @@ void Client::Handle_OP_DuelResponse2(const EQApplicationPacket *app) SetDuelTarget(ds->duel_initiator); safe_delete(outapp); - if (IsCasting()) + if (IsCasting()) { InterruptSpell(); - if (initiator->CastToClient()->IsCasting()) + } + + if (initiator->CastToClient()->IsCasting()) { initiator->CastToClient()->InterruptSpell(); + } } return; } @@ -12455,34 +12478,54 @@ void Client::Handle_OP_Report(const EQApplicationPacket *app) void Client::Handle_OP_RequestDuel(const EQApplicationPacket *app) { - if (app->size != sizeof(Duel_Struct)) + if (app->size != sizeof(Duel_Struct)) { return; + } EQApplicationPacket* outapp = app->Copy(); Duel_Struct* ds = (Duel_Struct*)outapp->pBuffer; + if (!ds->duel_initiator || !ds->duel_target) { + return; + } + uint32 duel = ds->duel_initiator; ds->duel_initiator = ds->duel_target; ds->duel_target = duel; Entity* entity = entity_list.GetID(ds->duel_target); - if (GetID() != ds->duel_target && entity->IsClient() && (entity->CastToClient()->IsDueling() && entity->CastToClient()->GetDuelTarget() != 0)) { + + if ( + GetID() != ds->duel_target && + entity->IsClient() && + entity->CastToClient()->IsDueling() && + entity->CastToClient()->GetDuelTarget() + ) { MessageString(Chat::NPCQuestSay, DUEL_CONSIDERING, entity->GetName()); return; } + if (IsDueling()) { MessageString(Chat::NPCQuestSay, DUEL_INPROGRESS); return; } - if (GetID() != ds->duel_target && entity->IsClient() && GetDuelTarget() == 0 && !IsDueling() && !entity->CastToClient()->IsDueling() && entity->CastToClient()->GetDuelTarget() == 0) { + if ( + GetID() != ds->duel_target && + entity->IsClient() && + !GetDuelTarget() && + !IsDueling() && + !entity->CastToClient()->IsDueling() && + !entity->CastToClient()->GetDuelTarget() + ) { SetDuelTarget(ds->duel_target); entity->CastToClient()->SetDuelTarget(GetID()); ds->duel_target = ds->duel_initiator; entity->CastToClient()->FastQueuePacket(&outapp); entity->CastToClient()->SetDueling(false); SetDueling(false); - } - else + } else { safe_delete(outapp); + } + return; } diff --git a/zone/client_packet.h b/zone/client_packet.h index ce85e38c5..887372cde 100644 --- a/zone/client_packet.h +++ b/zone/client_packet.h @@ -97,8 +97,8 @@ void Handle_OP_Disarm(const EQApplicationPacket *app); void Handle_OP_DisarmTraps(const EQApplicationPacket *app); void Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app); - void Handle_OP_DuelResponse(const EQApplicationPacket *app); - void Handle_OP_DuelResponse2(const EQApplicationPacket *app); + void Handle_OP_DuelDecline(const EQApplicationPacket *app); + void Handle_OP_DuelAccept(const EQApplicationPacket *app); void Handle_OP_DumpName(const EQApplicationPacket *app); void Handle_OP_Dye(const EQApplicationPacket *app); void Handle_OP_DzAddPlayer(const EQApplicationPacket *app); diff --git a/zone/lua_packet.cpp b/zone/lua_packet.cpp index c7a039ca4..b07a7011f 100644 --- a/zone/lua_packet.cpp +++ b/zone/lua_packet.cpp @@ -582,7 +582,7 @@ luabind::scope lua_register_packet_opcodes() { luabind::value("Logout", static_cast(OP_Logout)), luabind::value("LogoutReply", static_cast(OP_LogoutReply)), luabind::value("PreLogoutReply", static_cast(OP_PreLogoutReply)), - luabind::value("DuelResponse2", static_cast(OP_DuelResponse2)), + luabind::value("DuelAccept", static_cast(OP_DuelAccept)), luabind::value("InstillDoubt", static_cast(OP_InstillDoubt)), luabind::value("SafeFallSuccess", static_cast(OP_SafeFallSuccess)), luabind::value("DisciplineUpdate", static_cast(OP_DisciplineUpdate)), @@ -659,7 +659,7 @@ luabind::scope lua_register_packet_opcodes() { luabind::value("TraderDelItem", static_cast(OP_TraderDelItem)), luabind::value("AdventureMerchantPurchase", static_cast(OP_AdventureMerchantPurchase)), luabind::value("TestBuff", static_cast(OP_TestBuff)), - luabind::value("DuelResponse", static_cast(OP_DuelResponse)), + luabind::value("DuelDecline", static_cast(OP_DuelDecline)), luabind::value("RequestDuel", static_cast(OP_RequestDuel)), luabind::value("BazaarInspect", static_cast(OP_BazaarInspect)), luabind::value("ClickDoor", static_cast(OP_ClickDoor)), diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 6e236a4cd..544b7c50b 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1753,7 +1753,7 @@ XS(XS_Client_GetDuelTarget) { Perl_croak(aTHX_ "Usage: Client::GetDuelTarget(THIS)"); // @categories Account and Character, Script Utility { Client *THIS; - uint16 RETVAL; + uint32 RETVAL; dXSTARG; VALIDATE_THIS_IS_CLIENT; RETVAL = THIS->GetDuelTarget(); @@ -1786,7 +1786,7 @@ XS(XS_Client_SetDuelTarget) { Perl_croak(aTHX_ "Usage: Client::SetDuelTarget(THIS, set_id)"); // @categories Account and Character { Client *THIS; - uint16 set_id = (uint16) SvUV(ST(1)); + uint32 set_id = (uint32) SvUV(ST(1)); VALIDATE_THIS_IS_CLIENT; THIS->SetDuelTarget(set_id); }