Set group info to null in various places

When the group is disbanded, set the leader to null.

When setting a new raid leader, make sure we have a new raid leader. If we don't, avoid a crash and disband the raid. It's better than zones falling apart, and will resolve itself on the next VerifyRaid call.

If a member zones, set the leader pointer to nullptr. This fixes an issue where the leader pointer is freed later (MemberZoned normally cleans up the Client object), but referenced by other entities, allowing the leader to be used in the same server process tick, post-cleanup - as the leader won't exist.
This commit is contained in:
E Spause 2020-07-19 02:34:59 -04:00
parent 42781036a8
commit 147916ce2e
2 changed files with 16 additions and 0 deletions

View File

@ -498,6 +498,9 @@ void Group::SendEndurancePacketFrom(Mob* member)
//if the group was in the zone already
bool Group::UpdatePlayer(Mob* update){
if (!update)
return false;
bool updateSuccess = false;
VerifyGroup();
@ -1009,6 +1012,7 @@ void Group::DisbandGroup(bool joinraid) {
Leader->UpdateLFP();
}
SetLeader(nullptr);
safe_delete(outapp);
}

View File

@ -279,6 +279,8 @@ void Raid::SetRaidLeader(const char *wasLead, const char *name)
Client *c = entity_list.GetClientByName(name);
if(c)
SetLeader(c);
else
SetLeader(nullptr); //sanity check, should never get hit but we want to prefer to NOT crash if we do VerifyRaid and leader never gets set there (raid without a leader?)
LearnMembers();
VerifyRaid();
@ -1549,6 +1551,11 @@ void Raid::VerifyRaid()
SetLeader(members[x].member);
strn0cpy(leadername, members[x].membername, 64);
}
else
{
//should never happen, but maybe it is?
SetLeader(nullptr);
}
}
}
}
@ -1558,6 +1565,11 @@ void Raid::MemberZoned(Client *c)
if(!c)
return;
if (leader == c)
{
leader = nullptr;
}
// Raid::GetGroup() goes over the members as well, this way we go over once
uint32 gid = RAID_GROUPLESS;
for(int x = 0; x < MAX_RAID_MEMBERS; x++)