Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Crash] Fix for crash in Raid::QueuePacket #3145

Merged
merged 8 commits into from Mar 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 38 additions & 24 deletions zone/attack.cpp
Expand Up @@ -2505,8 +2505,10 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
bool ownerInGroup = false;
if ((give_exp->HasGroup() && give_exp->GetGroup()->IsGroupMember(give_exp->GetUltimateOwner()))
|| (give_exp->IsPet() && (give_exp->GetOwner()->IsClient()
|| (give_exp->GetOwner()->HasGroup() && give_exp->GetOwner()->GetGroup()->IsGroupMember(give_exp->GetOwner()->GetUltimateOwner())))))
|| (give_exp->GetOwner()->HasGroup() && give_exp->GetOwner()->GetGroup()->IsGroupMember(give_exp->GetOwner()->GetUltimateOwner()))))
) {
ownerInGroup = true;
}

give_exp = give_exp->GetUltimateOwner();

Expand All @@ -2518,20 +2520,23 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
if (give_exp && give_exp->IsTempPet() && give_exp->IsPetOwnerClient()) {
if (give_exp->IsNPC() && give_exp->CastToNPC()->GetSwarmOwner()) {
Mob* temp_owner = entity_list.GetMobID(give_exp->CastToNPC()->GetSwarmOwner());
if (temp_owner)
if (temp_owner) {
give_exp = temp_owner;
}
}
}

int PlayerCount = 0; // QueryServ Player Counting

Client *give_exp_client = nullptr;
if (give_exp && give_exp->IsClient())
if (give_exp && give_exp->IsClient()) {
give_exp_client = give_exp->CastToClient();
}

//do faction hits even if we are a merchant, so long as a player killed us
if (!IsCharmed() && give_exp_client && !RuleB(NPC, EnableMeritBasedFaction))
if (!IsCharmed() && give_exp_client && !RuleB(NPC, EnableMeritBasedFaction)) {
hate_list.DoFactionHits(GetNPCFactionID(), GetPrimaryFaction(), GetFactionAmount());
}

bool IsLdonTreasure = (GetClass() == LDON_TREASURE);

Expand Down Expand Up @@ -2559,17 +2564,22 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
}

/* Send the EVENT_KILLED_MERIT event for all raid members */
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client
Client *c = kr->members[i].member;
for (const auto& m : kr->members) {
if (m.is_bot) {
continue;
}

if (m.member && m.member->IsClient()) { // If Group Member is Client
Client *c = m.member;

c->RecordKilledNPCEvent(this);
if (parse->HasQuestSub(GetNPCTypeID(), EVENT_KILLED_MERIT)) {
parse->EventNPC(EVENT_KILLED_MERIT, this, c, "killed", 0);
}

if (RuleB(NPC, EnableMeritBasedFaction))
if (RuleB(NPC, EnableMeritBasedFaction)) {
c->SetFactionLevel(c->CharacterID(), GetNPCFactionID(), c->GetBaseClass(), c->GetBaseRace(), c->GetDeity());
}

PlayerCount++;
}
Expand All @@ -2586,9 +2596,13 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
QS->s1.NPCID = GetNPCTypeID();
QS->s1.ZoneID = GetZoneID();
QS->s1.Type = 2; // Raid Fight
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client
Client *c = kr->members[i].member;
for (const auto& m : kr->members) {
if (m.is_bot) {
continue;
}

if (m.member && m.member->IsClient()) { // If Group Member is Client
Client *c = m.member;
QS->Chars[PlayerCount].char_id = c->CharacterID();
PlayerCount++;
}
Expand Down Expand Up @@ -2742,34 +2756,34 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
Raid* r = entity_list.GetRaidByClient(killer->CastToClient());
if (r) {
int i = 0;
for (int x = 0; x < MAX_RAID_MEMBERS; x++) {
for (const auto& m : r->members) {
if (m.is_bot) {
continue;
}
Aeadoin marked this conversation as resolved.
Show resolved Hide resolved

switch (r->GetLootType()) {
case 0:
case 1:
if (r->members[x].member && r->members[x].is_raid_leader) {
corpse->AllowPlayerLoot(r->members[x].member, i);
if (m.member && m.is_raid_leader) {
corpse->AllowPlayerLoot(m.member, i);
i++;
}
break;
case 2:
if (r->members[x].member && r->members[x].is_raid_leader) {
corpse->AllowPlayerLoot(r->members[x].member, i);
i++;
}
else if (r->members[x].member && r->members[x].is_group_leader) {
corpse->AllowPlayerLoot(r->members[x].member, i);
if (m.member && (m.is_raid_leader || m.is_group_leader)) {
corpse->AllowPlayerLoot(m.member, i);
i++;
}
break;
case 3:
if (r->members[x].member && r->members[x].is_looter) {
corpse->AllowPlayerLoot(r->members[x].member, i);
if (m.member && m.is_looter) {
corpse->AllowPlayerLoot(m.member, i);
i++;
}
break;
case 4:
if (r->members[x].member) {
corpse->AllowPlayerLoot(r->members[x].member, i);
if (m.member) {
corpse->AllowPlayerLoot(m.member, i);
i++;
}
break;
Expand Down
16 changes: 9 additions & 7 deletions zone/bot.cpp
Expand Up @@ -9105,16 +9105,18 @@ std::vector<Mob*> Bot::GetApplySpellList(
auto* r = GetRaid();
auto group_id = r->GetGroup(GetCleanName());
if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
for (auto i = 0; i < MAX_RAID_MEMBERS; i++) {
auto* m = r->members[i].member;
if (m && m->IsClient() && (!is_raid_group_only || r->GetGroup(m) == group_id)) {
l.push_back(m);
for (const auto& m : r->members) {
if (m.is_bot) {
continue;
}
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
l.push_back(m.member);

if (allow_pets && m->HasPet()) {
l.push_back(m->GetPet());
if (allow_pets && m.member->HasPet()) {
l.push_back(m.member->GetPet());
}

const auto& sbl = entity_list.GetBotListByCharacterID(m->CharacterID());
const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID());
for (const auto& b : sbl) {
l.push_back(b);
}
Expand Down
82 changes: 35 additions & 47 deletions zone/client.cpp
Expand Up @@ -798,24 +798,21 @@ bool Client::SendAllPackets() {
}

void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CONN_STATUS required_state, eqFilterType filter) {
if(filter!=FilterNone){
//this is incomplete... no support for FilterShowGroupOnly or FilterShowSelfOnly
if(GetFilter(filter) == FilterHide)
return; //Client has this filter on, no need to send packet
if (filter != FilterNone && GetFilter(filter) == FilterHide) {
return;
}
if(client_state != CLIENT_CONNECTED && required_state == CLIENT_CONNECTED){

if (client_state != CLIENT_CONNECTED && required_state == CLIENT_CONNECTED) {
AddPacket(app, ack_req);
return;
}

// if the program doesnt care about the status or if the status isnt what we requested
if (required_state != CLIENT_CONNECTINGALL && client_state != required_state)
{
if (required_state != CLIENT_CONNECTINGALL && client_state != required_state) {
// todo: save packets for later use
AddPacket(app, ack_req);
}
else if (eqs)
{
else if (eqs) {
eqs->QueuePacket(app, ack_req);
}
}
Expand Down Expand Up @@ -4143,42 +4140,32 @@ void Client::UpdateLFP() {

bool Client::GroupFollow(Client* inviter) {

if (inviter)
{
if (inviter) {
isgrouped = true;
Raid* raid = entity_list.GetRaidByClient(inviter);
Raid* iraid = entity_list.GetRaidByClient(this);

//inviter has a raid don't do group stuff instead do raid stuff!
if (raid)
{
if (raid) {
// Suspend the merc while in a raid (maybe a rule could be added for this)
if (GetMerc())
if (GetMerc()) {
GetMerc()->Suspend();
}

uint32 groupToUse = 0xFFFFFFFF;
for (int x = 0; x < MAX_RAID_MEMBERS; x++)
{
if (raid->members[x].member)
{
//this assumes the inviter is in the zone
if (raid->members[x].member == inviter){
groupToUse = raid->members[x].group_number;
break;
}
for (const auto& m : raid->members) {
if (m.member && m.member == inviter) {
groupToUse = m.group_number;
break;
}
}
if (iraid == raid)
{
if (iraid == raid) {
//both in same raid
uint32 ngid = raid->GetGroup(inviter->GetName());
if (raid->GroupCount(ngid) < 6)
{
if (raid->GroupCount(ngid) < 6) {
raid->MoveMember(GetName(), ngid);
raid->SendGroupDisband(this);
//raid->SendRaidGroupAdd(GetName(), ngid);
//raid->SendGroupUpdate(this);
raid->GroupUpdate(ngid); //break
raid->GroupUpdate(ngid);
}
return false;
}
Expand Down Expand Up @@ -8866,16 +8853,15 @@ void Client::ProcessAggroMeter()
if (m_aggrometer.set_pct(AggroMeter::AT_Secondary, has_aggro ? cur_tar->GetHateRatio(this, secondary) : secondary ? 100 : 0))
add_entry(AggroMeter::AT_Secondary);

// fuuuuuuuuuuuuuuuuuuuuuuuucckkkkkkkkkkkkkkk raids
if (IsRaidGrouped()) {
auto raid = GetRaid();
if (raid) {
auto gid = raid->GetGroup(this);
if (gid < 12) {
if (gid < MAX_RAID_GROUPS) {
int at_id = AggroMeter::AT_Group1;
for (int i = 0; i < MAX_RAID_MEMBERS; ++i) {
if (raid->members[i].member && raid->members[i].member != this && raid->members[i].group_number == gid) {
if (m_aggrometer.set_pct(static_cast<AggroMeter::AggroTypes>(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), raid->members[i].member)))
for (const auto& m : raid->members) {
if (m.member && m.member != this && m.group_number == gid) {
if (m_aggrometer.set_pct(static_cast<AggroMeter::AggroTypes>(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), m.member)))
add_entry(static_cast<AggroMeter::AggroTypes>(at_id));
at_id++;
if (at_id > AggroMeter::AT_Group5)
Expand Down Expand Up @@ -10956,11 +10942,14 @@ std::vector<Client *> Client::GetPartyMembers()
std::vector<Client *> clients_to_update = {};

// raid
Raid *raid = entity_list.GetRaidByClient(this);
if (raid) {
for (auto &e : raid->members) {
if (e.member && e.member->IsClient()) {
clients_to_update.push_back(e.member->CastToClient());
if (const auto raid = entity_list.GetRaidByClient(this)) {
for (auto &m : raid->members) {
if (m.is_bot) {
continue;
}

if (m.member && m.member->IsClient()) {
clients_to_update.push_back(m.member->CastToClient());
}
}
}
Expand Down Expand Up @@ -11747,17 +11736,16 @@ std::vector<Mob*> Client::GetApplySpellList(
auto* r = GetRaid();
auto group_id = r->GetGroup(this);
if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) {
for (auto i = 0; i < MAX_RAID_MEMBERS; i++) {
auto* m = r->members[i].member;
if (m && m->IsClient() && (!is_raid_group_only || r->GetGroup(m) == group_id)) {
l.push_back(m);
for (const auto& m : r->members) {
if (m.member && m.member->IsClient() && (!is_raid_group_only || r->GetGroup(m.member) == group_id)) {
l.push_back(m.member);

if (allow_pets && m->HasPet()) {
l.push_back(m->GetPet());
if (allow_pets && m.member->HasPet()) {
l.push_back(m.member->GetPet());
}

if (allow_bots) {
const auto& sbl = entity_list.GetBotListByCharacterID(m->CharacterID());
const auto& sbl = entity_list.GetBotListByCharacterID(m.member->CharacterID());
for (const auto& b : sbl) {
l.push_back(b);
}
Expand Down
2 changes: 1 addition & 1 deletion zone/client_packet.cpp
Expand Up @@ -12183,7 +12183,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
uint32 i = raid->GetPlayerIndex(raid_command_packet->leader_name);
raid->SetNewRaidLeader(i);
raid->HandleBotGroupDisband(c_to_disband->CharacterID());
raid->HandleOfflineBots(c_to_disband->CharacterID());
raid->HandleOfflineBots(c_to_disband->CharacterID());
raid->RemoveMember(raid_command_packet->leader_name);
raid->SendGroupDisband(c_to_disband);
raid->GroupUpdate(group);
Expand Down
10 changes: 7 additions & 3 deletions zone/questmgr.cpp
Expand Up @@ -448,9 +448,13 @@ void QuestManager::ZoneRaid(const char *zone_name) {
initiator->MoveZone(zone_name);
} else {
auto client_raid = initiator->GetRaid();
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
for (const auto& m : client_raid->members) {
if (m.is_bot) {
continue;
}
Aeadoin marked this conversation as resolved.
Show resolved Hide resolved

if (m.member && m.member->IsClient()) {
auto raid_member = m.member->CastToClient();
raid_member->MoveZone(zone_name);
}
}
Expand Down