[Bug Fix] Remove possible Duel exploit. (#1911)

* [Duels] Cleanup duel response/request logic.

* Fixes and function name cleanup.

* Patch file name changes.
This commit is contained in:
Kinglykrab
2022-01-02 22:06:31 -05:00
committed by GitHub
parent 9815f50efa
commit 645251992d
15 changed files with 89 additions and 46 deletions
+61 -18
View File
@@ -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;
}