Protection on group member info when updates are made
Prevents corruption in the group member pointers.. clients couldn't see each other in group lists or chat to each other depending on special conditions
This commit is contained in:
parent
ee62b2ee39
commit
5bf65b9399
6 changed files with 53 additions and 26 deletions
EQ2/source/WorldServer
|
@ -2347,23 +2347,20 @@ void Entity::RemoveSafefallSpell(LuaSpell* spell){
|
|||
((Player*)this)->SetPlayerControlFlag(4, 32, false);
|
||||
}
|
||||
|
||||
void Entity::UpdateGroupMemberInfo() {
|
||||
if (!group_member_info)
|
||||
void Entity::UpdateGroupMemberInfo(bool inGroupMgrLock, bool groupMembersLocked) {
|
||||
if (!group_member_info || group_id == 0)
|
||||
return;
|
||||
|
||||
group_member_info->class_id = GetAdventureClass();
|
||||
group_member_info->hp_max = GetTotalHP();
|
||||
group_member_info->hp_current = GetHP();
|
||||
group_member_info->level_max = GetLevel();
|
||||
group_member_info->level_current = GetLevel();
|
||||
group_member_info->name = string(GetName());
|
||||
group_member_info->power_current = GetPower();
|
||||
group_member_info->power_max = GetTotalPower();
|
||||
group_member_info->race_id = GetRace();
|
||||
if (GetZone())
|
||||
group_member_info->zone = GetZone()->GetZoneDescription();
|
||||
else
|
||||
group_member_info->zone = "Unknown";
|
||||
if(!inGroupMgrLock)
|
||||
world.GetGroupManager()->GroupLock(__FUNCTION__, __LINE__);
|
||||
|
||||
PlayerGroup* group = world.GetGroupManager()->GetGroup(group_id);
|
||||
|
||||
if (group)
|
||||
group->UpdateGroupMemberInfo(this, groupMembersLocked);
|
||||
|
||||
if(!inGroupMgrLock)
|
||||
world.GetGroupManager()->ReleaseGroupLock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
#include "WorldDatabase.h"
|
||||
|
|
|
@ -793,7 +793,7 @@ public:
|
|||
|
||||
GroupMemberInfo* GetGroupMemberInfo() { return group_member_info; }
|
||||
void SetGroupMemberInfo(GroupMemberInfo* info) { group_member_info = info; }
|
||||
void UpdateGroupMemberInfo();
|
||||
void UpdateGroupMemberInfo(bool inGroupMgrLock=false, bool groupMembersLocked=false);
|
||||
|
||||
void CustomizeAppearance(PacketStruct* packet);
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@ bool PlayerGroup::AddMember(Entity* member) {
|
|||
gmi->client = 0;
|
||||
|
||||
member->SetGroupMemberInfo(gmi);
|
||||
member->UpdateGroupMemberInfo();
|
||||
|
||||
member->group_id = gmi->group_id;
|
||||
MGroupMembers.writelock();
|
||||
m_members.push_back(gmi);
|
||||
member->UpdateGroupMemberInfo(true, true);
|
||||
MGroupMembers.releasewritelock();
|
||||
|
||||
SendGroupUpdate();
|
||||
|
@ -257,14 +257,15 @@ void PlayerGroupManager::NewGroup(Entity* leader) {
|
|||
|
||||
// Create a new group with the valid ID we got from above
|
||||
PlayerGroup* new_group = new PlayerGroup(m_nextGroupID);
|
||||
|
||||
// Add the new group to the list (need to do this first, AddMember needs ref to the PlayerGroup ptr -> UpdateGroupMemberInfo)
|
||||
m_groups[m_nextGroupID] = new_group;
|
||||
|
||||
// Add the leader to the group
|
||||
new_group->AddMember(leader);
|
||||
|
||||
leader->GetGroupMemberInfo()->leader = true;
|
||||
|
||||
// Add the new group to the list
|
||||
m_groups[m_nextGroupID] = new_group;
|
||||
|
||||
MGroups.releasewritelock(__FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
|
@ -767,4 +768,32 @@ void PlayerGroup::RemoveClientReference(Client* remove) {
|
|||
}
|
||||
}
|
||||
MGroupMembers.releasewritelock();
|
||||
}
|
||||
|
||||
void PlayerGroup::UpdateGroupMemberInfo(Entity* ent, bool groupMembersLocked) {
|
||||
Player* player = (Player*)ent;
|
||||
|
||||
if (!player || !player->GetGroupMemberInfo())
|
||||
return;
|
||||
|
||||
if(!groupMembersLocked)
|
||||
MGroupMembers.writelock();
|
||||
|
||||
GroupMemberInfo* group_member_info = player->GetGroupMemberInfo();
|
||||
player->GetGroupMemberInfo()->class_id = player->GetAdventureClass();
|
||||
group_member_info->hp_max = player->GetTotalHP();
|
||||
group_member_info->hp_current = player->GetHP();
|
||||
group_member_info->level_max = player->GetLevel();
|
||||
group_member_info->level_current = player->GetLevel();
|
||||
group_member_info->name = string(player->GetName());
|
||||
group_member_info->power_current = player->GetPower();
|
||||
group_member_info->power_max = player->GetTotalPower();
|
||||
group_member_info->race_id = player->GetRace();
|
||||
if (player->GetZone())
|
||||
group_member_info->zone = player->GetZone()->GetZoneDescription();
|
||||
else
|
||||
group_member_info->zone = "Unknown";
|
||||
|
||||
if(!groupMembersLocked)
|
||||
MGroupMembers.releasewritelock();
|
||||
}
|
|
@ -84,6 +84,7 @@ public:
|
|||
void MakeLeader(Entity* new_leader);
|
||||
|
||||
void RemoveClientReference(Client* remove);
|
||||
void UpdateGroupMemberInfo(Entity* ent, bool groupMembersLocked=false);
|
||||
|
||||
Mutex MGroupMembers; // Mutex for the group members
|
||||
private:
|
||||
|
|
|
@ -1499,7 +1499,7 @@ void World::RejoinGroup(Client* client, int32 group_id){
|
|||
info->member = client->GetPlayer();
|
||||
client->GetPlayer()->SetGroup(group);
|
||||
client->GetPlayer()->SetGroupMemberInfo(info);
|
||||
client->GetPlayer()->UpdateGroupMemberInfo();
|
||||
client->GetPlayer()->UpdateGroupMemberInfo(true, true);
|
||||
LogWrite(PLAYER__DEBUG, 0, "Player", "Identified group match for player %s to group id %u", name.c_str(), group_id);
|
||||
match = true;
|
||||
break;
|
||||
|
|
|
@ -1338,6 +1338,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
|
|||
if (!IsReadyForSpawns())
|
||||
SetReadyForSpawns(true);
|
||||
SendCharInfo();
|
||||
world.RejoinGroup(this, rejoin_group_id);
|
||||
pos_update.Start();
|
||||
quest_pos_timer.Start();
|
||||
break;
|
||||
|
@ -3513,9 +3514,6 @@ void Client::Zone(ZoneServer* new_zone, bool set_coords) {
|
|||
return;
|
||||
}
|
||||
|
||||
// block out the member info for the group
|
||||
TempRemoveGroup();
|
||||
|
||||
client_zoning = true;
|
||||
LogWrite(CCLIENT__DEBUG, 0, "Client", "%s: Setting player Resurrecting to 'true'", __FUNCTION__);
|
||||
player->SetResurrecting(true);
|
||||
|
@ -3543,6 +3541,9 @@ void Client::Zone(ZoneServer* new_zone, bool set_coords) {
|
|||
world.GetGroupManager()->SendGroupUpdate(player->GetGroupMemberInfo()->group_id, this);
|
||||
}
|
||||
|
||||
// block out the member info for the group
|
||||
TempRemoveGroup();
|
||||
|
||||
UpdateTimeStampFlag(ZONE_UPDATE_FLAG);
|
||||
|
||||
if (set_coords)
|
||||
|
@ -8703,7 +8704,6 @@ bool Client::HandleNewLogin(int32 account_id, int32 access_code)
|
|||
new_client_login = true;
|
||||
GetCurrentZone()->AddClient(this); //add to zones client list
|
||||
|
||||
world.RejoinGroup(this, rejoin_group_id);
|
||||
zone_list.AddClientToMap(player->GetName(), this);
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Add table
Reference in a new issue