Core/Groups: Fixes groups staying linked with players.

This commit is contained in:
Hondacrx
2025-09-02 22:43:56 -04:00
parent 6531cd9dc1
commit 3d23a9f162
34 changed files with 385 additions and 402 deletions
@@ -1,12 +1,28 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved. // Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
namespace Framework.Collections namespace Framework.Collections
{ {
public class LinkedListElement public class LinkedListElement
{ {
internal LinkedListElement INext; internal LinkedListElement INext
internal LinkedListElement IPrev; {
get;
set
{
field = value;
}
}
internal LinkedListElement IPrev
{
get;
set
{
field = value;
}
}
public LinkedListElement() public LinkedListElement()
{ {
@@ -52,32 +68,31 @@ namespace Framework.Collections
public class LinkedListHead public class LinkedListHead
{ {
LinkedListElement _iFirst = new(); LinkedListElement iHeader = new();
LinkedListElement _iLast = new();
uint _iSize; uint _iSize;
public LinkedListHead() public LinkedListHead()
{ {
_iSize = 0; _iSize = 0;
// create empty list
_iFirst.INext = _iLast; // create empty list
_iLast.IPrev = _iFirst; iHeader.INext = new();
iHeader.IPrev = new();
} }
public bool IsEmpty() { return (!_iFirst.INext.IsInList()); } public bool IsEmpty() { return iHeader.INext == iHeader; }
public LinkedListElement GetFirstElement() { return (IsEmpty() ? null : _iFirst.INext); } public LinkedListElement GetFirstElement() { return (IsEmpty() ? null : iHeader.INext); }
public LinkedListElement GetLastElement() { return (IsEmpty() ? null : _iLast.IPrev); } public LinkedListElement GetLastElement() { return (IsEmpty() ? null : iHeader); }
public void InsertFirst(LinkedListElement pElem) public void InsertFirst(LinkedListElement pElem)
{ {
_iFirst.InsertAfter(pElem); iHeader.InsertBefore(pElem);
} }
public void InsertLast(LinkedListElement pElem) public void InsertLast(LinkedListElement pElem)
{ {
_iLast.InsertBefore(pElem); iHeader.InsertBefore(pElem);
} }
public uint GetSize() public uint GetSize()
+49 -13
View File
@@ -1,11 +1,14 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved. // Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Collections; using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Framework.Dynamic namespace Framework.Dynamic
{ {
public class Reference<TO, FROM> : LinkedListElement where TO : class where FROM : class public class Reference<TO, FROM> where TO : class where FROM : class
{ {
TO _RefTo; TO _RefTo;
FROM _RefFrom; FROM _RefFrom;
@@ -21,7 +24,8 @@ namespace Framework.Dynamic
public Reference() public Reference()
{ {
_RefTo = null; _RefFrom = null; _RefTo = null;
_RefFrom = null;
} }
// Create new link // Create new link
@@ -43,7 +47,6 @@ namespace Framework.Dynamic
public void Unlink() public void Unlink()
{ {
TargetObjectDestroyLink(); TargetObjectDestroyLink();
Delink();
_RefTo = null; _RefTo = null;
_RefFrom = null; _RefFrom = null;
} }
@@ -53,7 +56,6 @@ namespace Framework.Dynamic
public void Invalidate() // the iRefFrom MUST remain!! public void Invalidate() // the iRefFrom MUST remain!!
{ {
SourceObjectDestroyLink(); SourceObjectDestroyLink();
Delink();
_RefTo = null; _RefTo = null;
} }
@@ -62,26 +64,60 @@ namespace Framework.Dynamic
return _RefTo != null; return _RefTo != null;
} }
public Reference<TO, FROM> Next() { return ((Reference<TO, FROM>)GetNextElement()); }
public Reference<TO, FROM> Prev() { return ((Reference<TO, FROM>)GetPrevElement()); }
public TO GetTarget() { return _RefTo; } public TO GetTarget() { return _RefTo; }
public FROM GetSource() { return _RefFrom; } public FROM GetSource() { return _RefFrom; }
} }
public class RefManager<TO, FROM> : LinkedListHead where TO : class where FROM : class public class RefManager<ReferenceType> : IEnumerable where ReferenceType : class, new()
{ {
LinkedList<ReferenceType> linkedList = new LinkedList<ReferenceType>();
~RefManager() { ClearReferences(); } ~RefManager() { ClearReferences(); }
public Reference<TO, FROM> GetFirst() { return (Reference<TO, FROM>)base.GetFirstElement(); } public void InsertFirst(ReferenceType pElem)
public Reference<TO, FROM> GetLast() { return (Reference<TO, FROM>)base.GetLastElement(); } {
linkedList.AddFirst(pElem);
}
public void InsertLast(ReferenceType pElem)
{
linkedList.AddLast(pElem);
}
public ReferenceType Find(Func<ReferenceType, bool> func)
{
return linkedList.FirstOrDefault(func);
}
public void Remove(Func<ReferenceType, bool> func)
{
linkedList.Remove(Find(func));
}
public int GetSize()
{
return linkedList.Count;
}
public ReferenceType GetFirst() { return linkedList.First?.Value; }
public ReferenceType GetLast() { return linkedList.Last?.Value; }
public IEnumerator<ReferenceType> GetEnumerator()
{
return linkedList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void ClearReferences() public void ClearReferences()
{ {
Reference<TO, FROM> refe; ReferenceType refe;
while ((refe = GetFirst()) != null) while ((refe = GetFirst()) != null)
refe.Invalidate(); linkedList.Remove(refe);
} }
} }
} }
+3 -3
View File
@@ -592,10 +592,10 @@ namespace Game.AI
_allySet.Add(me.GetGUID()); _allySet.Add(me.GetGUID());
if (group != null) // add group if (group != null) // add group
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player target = refe.GetSource(); Player target = groupRef.GetSource();
if (target == null || !target.IsInMap(owner) || !group.SameSubGroup(owner.ToPlayer(), target)) if (!target.IsInMap(owner) || !group.SameSubGroup(owner.ToPlayer(), target))
continue; continue;
if (target.GetGUID() == owner.GetGUID()) if (target.GetGUID() == owner.GetGUID())
@@ -83,10 +83,9 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = groupRef.GetSource(); Player member = groupRef.GetSource();
if (member != null)
if (member.IsInMap(player)) if (member.IsInMap(player))
member.FailQuest(_escortQuest.Id); member.FailQuest(_escortQuest.Id);
} }
@@ -150,10 +149,9 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = groupRef.GetSource(); Player member = groupRef.GetSource();
if (member != null)
if (me.IsWithinDistInMap(member, GetMaxPlayerDistance())) if (me.IsWithinDistInMap(member, GetMaxPlayerDistance()))
return true; return true;
} }
@@ -52,10 +52,9 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = groupRef.GetSource(); Player member = groupRef.GetSource();
if (member != null)
if (member.IsInMap(player)) if (member.IsInMap(player))
member.FailQuest(_questForFollow); member.FailQuest(_questForFollow);
} }
@@ -109,12 +108,9 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null && (maxRangeExceeded || questAbandoned); groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = groupRef.GetSource(); Player member = groupRef.GetSource();
if (member == null)
continue;
if (maxRangeExceeded && me.IsWithinDistInMap(member, 100.0f)) if (maxRangeExceeded && me.IsWithinDistInMap(member, 100.0f))
maxRangeExceeded = false; maxRangeExceeded = false;
@@ -253,10 +249,10 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = groupRef.GetSource(); Player member = groupRef.GetSource();
if (member != null && me.IsWithinDistInMap(member, 100.0f) && member.IsAlive()) if (me.IsWithinDistInMap(member, 100.0f) && member.IsAlive())
{ {
Log.outDebug(LogFilter.Scripts, $"FollowerAI::GetLeaderForFollower: GetLeader changed and returned new leader. ({me.GetGUID()})"); Log.outDebug(LogFilter.Scripts, $"FollowerAI::GetLeaderForFollower: GetLeader changed and returned new leader. ({me.GetGUID()})");
_leaderGUID = member.GetGUID(); _leaderGUID = member.GetGUID();
+2 -2
View File
@@ -227,7 +227,7 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player groupGuy = groupRef.GetSource(); Player groupGuy = groupRef.GetSource();
if (!groupGuy.IsInMap(player)) if (!groupGuy.IsInMap(player))
@@ -333,7 +333,7 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player groupGuy = groupRef.GetSource(); Player groupGuy = groupRef.GetSource();
if (groupGuy.IsInMap(player) && me.GetDistance(groupGuy) <= checkDist) if (groupGuy.IsInMap(player) && me.GetDistance(groupGuy) <= checkDist)
+1 -2
View File
@@ -2889,10 +2889,9 @@ namespace Game.AI
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference groupRef = group.GetFirstMember(); groupRef != null; groupRef = groupRef.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = groupRef.GetSource(); Player member = groupRef.GetSource();
if (member != null)
if (member.IsInMap(player)) if (member.IsInMap(player))
targets.Add(member); targets.Add(member);
} }
@@ -985,10 +985,9 @@ namespace Game.Achievements
Group group = referencePlayer.GetGroup(); Group group = referencePlayer.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player groupMember = refe.GetSource(); Player groupMember = groupRef.GetSource();
if (groupMember != null)
if (groupMember.GetGuildId() == _owner.GetId()) if (groupMember.GetGuildId() == _owner.GetId())
ca.CompletingPlayers.Add(groupMember.GetGUID()); ca.CompletingPlayers.Add(groupMember.GetGUID());
} }
+13 -12
View File
@@ -9,6 +9,7 @@ using Game.BattleGrounds;
using Game.DataStorage; using Game.DataStorage;
using Game.Entities; using Game.Entities;
using Game.Garrisons; using Game.Garrisons;
using Game.Groups;
using Game.Maps; using Game.Maps;
using Game.Miscellaneous; using Game.Miscellaneous;
using Game.Networking; using Game.Networking;
@@ -1725,8 +1726,8 @@ namespace Game.Achievements
var group = referencePlayer.GetGroup(); var group = referencePlayer.GetGroup();
if (group != null) if (group != null)
{ {
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRefe in group.GetMembers())
if (itr.GetSource().GetGuildId() == referencePlayer.GetGuildId()) if (groupRefe.GetSource().GetGuildId() == referencePlayer.GetGuildId())
++guildMemberCount; ++guildMemberCount;
} }
@@ -2739,8 +2740,8 @@ namespace Game.Achievements
var group = referencePlayer.GetGroup(); var group = referencePlayer.GetGroup();
if (group != null) if (group != null)
{ {
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (itr.GetSource() != referencePlayer && referencePlayer.m_playerData.VirtualPlayerRealm == itr.GetSource().m_playerData.VirtualPlayerRealm) if (groupRef.GetSource() != referencePlayer && referencePlayer.m_playerData.VirtualPlayerRealm == groupRef.GetSource().m_playerData.VirtualPlayerRealm)
++memberCount; ++memberCount;
} }
@@ -2845,8 +2846,8 @@ namespace Game.Achievements
if (group != null) if (group != null)
{ {
uint membersWithAchievement = 0; uint membersWithAchievement = 0;
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (itr.GetSource().HasAchieved((uint)secondaryAsset)) if (groupRef.GetSource().HasAchieved((uint)secondaryAsset))
++membersWithAchievement; ++membersWithAchievement;
if (membersWithAchievement > reqValue) if (membersWithAchievement > reqValue)
@@ -3283,8 +3284,8 @@ namespace Game.Achievements
if (group == null) if (group == null)
return false; return false;
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (itr.GetSource().GetSession().GetRecruiterId() == referencePlayer.GetSession().GetAccountId()) if (groupRef.GetSource().GetSession().GetRecruiterId() == referencePlayer.GetSession().GetAccountId())
return true; return true;
return false; return false;
@@ -3295,8 +3296,8 @@ namespace Game.Achievements
if (group == null) if (group == null)
return false; return false;
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (itr.GetSource().GetSession().GetAccountId() == referencePlayer.GetSession().GetRecruiterId()) if (groupRef.GetSource().GetSession().GetAccountId() == referencePlayer.GetSession().GetRecruiterId())
return true; return true;
return false; return false;
@@ -3430,8 +3431,8 @@ namespace Game.Achievements
var group = referencePlayer.GetGroup(); var group = referencePlayer.GetGroup();
if (group != null) if (group != null)
{ {
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (!itr.GetSource().HasAchieved(reqValue)) if (!groupRef.GetSource().HasAchieved(reqValue))
return false; return false;
} }
else if (!referencePlayer.HasAchieved(reqValue)) else if (!referencePlayer.HasAchieved(reqValue))
@@ -82,12 +82,9 @@ namespace Game.BattleGrounds
//add players from group to ginfo //add players from group to ginfo
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
if (member == null)
continue; // this should never happen
PlayerQueueInfo pl_info = new(); PlayerQueueInfo pl_info = new();
pl_info.LastOnlineTime = lastOnlineTime; pl_info.LastOnlineTime = lastOnlineTime;
pl_info.GroupInfo = ginfo; pl_info.GroupInfo = ginfo;
+9 -20
View File
@@ -106,11 +106,9 @@ namespace Game.Chat
if (groupTarget == null) if (groupTarget == null)
return false; return false;
for (GroupReference it = groupTarget.GetFirstMember(); it != null; it = it.Next()) foreach (GroupReference groupRef in groupTarget.GetMembers())
{
target = it.GetSource();
if (target != null)
{ {
target = groupRef.GetSource();
uint oldlevel = target.GetLevel(); uint oldlevel = target.GetLevel();
if (level != oldlevel) if (level != oldlevel)
@@ -128,7 +126,6 @@ namespace Game.Chat
target.SendSysMessage(CypherStrings.YoursLevelDown, handler.GetNameLink(), level); target.SendSysMessage(CypherStrings.YoursLevelDown, handler.GetNameLink(), level);
} }
} }
}
return true; return true;
} }
@@ -248,12 +245,8 @@ namespace Game.Chat
if (groupTarget == null) if (groupTarget == null)
return false; return false;
for (GroupReference it = groupTarget.GetFirstMember(); it != null; it = it.Next()) foreach (GroupReference groupRef in groupTarget.GetMembers())
{ groupRef.GetSource().DurabilityRepairAll(false, 0, false);
Player target = it.GetSource();
if (target != null)
target.DurabilityRepairAll(false, 0, false);
}
return true; return true;
} }
@@ -270,16 +263,13 @@ namespace Game.Chat
if (groupTarget == null) if (groupTarget == null)
return false; return false;
for (GroupReference it = groupTarget.GetFirstMember(); it != null; it = it.Next()) foreach (GroupReference groupRef in groupTarget.GetMembers())
{
Player target = it.GetSource();
if (target != null)
{ {
Player target = groupRef.GetSource();
target.ResurrectPlayer(target.GetSession().HasPermission(RBACPermissions.ResurrectWithFullHps) ? 1.0f : 0.5f); target.ResurrectPlayer(target.GetSession().HasPermission(RBACPermissions.ResurrectWithFullHps) ? 1.0f : 0.5f);
target.SpawnCorpseBones(); target.SpawnCorpseBones();
target.SaveToDB(); target.SaveToDB();
} }
}
return true; return true;
} }
@@ -326,11 +316,10 @@ namespace Game.Chat
} }
} }
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == gmPlayer || player.GetSession() == null)
if (player == null || player == gmPlayer || player.GetSession() == null)
continue; continue;
// check online security // check online security
+4 -6
View File
@@ -127,18 +127,16 @@ namespace Game.Chat
string nameLink = handler.GetNameLink(target); string nameLink = handler.GetNameLink(target);
Group grp = target.GetGroup(); Group group = target.GetGroup();
if (grp == null) if (group == null)
{ {
handler.SendSysMessage(CypherStrings.NotInGroup, nameLink); handler.SendSysMessage(CypherStrings.NotInGroup, nameLink);
return false; return false;
} }
for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == null || player.GetSession() == null)
continue;
// check online security // check online security
if (handler.HasLowerSecurity(player, ObjectGuid.Empty)) if (handler.HasLowerSecurity(player, ObjectGuid.Empty))
+10 -13
View File
@@ -397,11 +397,9 @@ namespace Game.DungeonFinding
else else
{ {
byte memberCount = 0; byte memberCount = 0;
for (GroupReference refe = grp.GetFirstMember(); refe != null && joinData.result == LfgJoinResult.Ok; refe = refe.Next()) foreach (GroupReference groupRef in grp.GetMembers())
{
Player groupPlayer = refe.GetSource();
if (groupPlayer != null)
{ {
Player groupPlayer = groupRef.GetSource();
if (!groupPlayer.GetSession().HasPermission(RBACPermissions.JoinDungeonFinder)) if (!groupPlayer.GetSession().HasPermission(RBACPermissions.JoinDungeonFinder))
joinData.result = LfgJoinResult.NoLfgObject; joinData.result = LfgJoinResult.NoLfgObject;
if (groupPlayer.HasAura(SharedConst.LFGSpellDungeonDeserter)) if (groupPlayer.HasAura(SharedConst.LFGSpellDungeonDeserter))
@@ -417,7 +415,9 @@ namespace Game.DungeonFinding
} }
++memberCount; ++memberCount;
players.Add(groupPlayer.GetGUID()); players.Add(groupPlayer.GetGUID());
}
if (joinData.result != LfgJoinResult.Ok)
break;
} }
if (joinData.result == LfgJoinResult.Ok && memberCount != grp.GetMembersCount()) if (joinData.result == LfgJoinResult.Ok && memberCount != grp.GetMembersCount())
@@ -521,11 +521,9 @@ namespace Game.DungeonFinding
SetState(gguid, LfgState.Rolecheck); SetState(gguid, LfgState.Rolecheck);
// Send update to player // Send update to player
LfgUpdateData updateData = new(LfgUpdateType.JoinQueue, dungeons); LfgUpdateData updateData = new(LfgUpdateType.JoinQueue, dungeons);
for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in grp.GetMembers())
{
Player plrg = refe.GetSource();
if (plrg != null)
{ {
Player plrg = groupRef.GetSource();
ObjectGuid pguid = plrg.GetGUID(); ObjectGuid pguid = plrg.GetGUID();
plrg.GetSession().SendLfgUpdateStatus(updateData, true); plrg.GetSession().SendLfgUpdateStatus(updateData, true);
SetState(pguid, LfgState.Rolecheck); SetState(pguid, LfgState.Rolecheck);
@@ -537,7 +535,6 @@ namespace Game.DungeonFinding
debugNames += ", "; debugNames += ", ";
debugNames += plrg.GetName(); debugNames += plrg.GetName();
} }
}
// Update leader role // Update leader role
UpdateRoleCheck(gguid, guid, roles); UpdateRoleCheck(gguid, guid, roles);
} }
@@ -1303,10 +1300,10 @@ namespace Game.DungeonFinding
if (!fromOpcode) if (!fromOpcode)
{ {
// Select a player inside to be teleported to // Select a player inside to be teleported to
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player plrg = refe.GetSource(); Player plrg = groupRef.GetSource();
if (plrg != null && plrg != player && plrg.GetMapId() == dungeon.map) if (plrg != player && plrg.GetMapId() == dungeon.map)
{ {
mapid = plrg.GetMapId(); mapid = plrg.GetMapId();
x = plrg.GetPositionX(); x = plrg.GetPositionX();
+6 -6
View File
@@ -1178,10 +1178,10 @@ namespace Game.Entities
foreach (Group partyToForceIntoCombat in partiesToForceIntoCombat) foreach (Group partyToForceIntoCombat in partiesToForceIntoCombat)
{ {
for (GroupReference refe = partyToForceIntoCombat.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in partyToForceIntoCombat.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == null || !player.IsInWorld || player.GetMap() != GetMap() || player.IsGameMaster()) if (!player.IsInWorld || player.GetMap() != GetMap() || player.IsGameMaster())
continue; continue;
EngageWithTarget(player); EngageWithTarget(player);
@@ -1334,9 +1334,9 @@ namespace Game.Entities
{ {
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
for (var itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (GetMap().IsRaid() || group.SameSubGroup(player, itr.GetSource())) if (GetMap().IsRaid() || group.SameSubGroup(player, groupRef.GetSource()))
m_tapList.Add(itr.GetSource().GetGUID()); m_tapList.Add(groupRef.GetSource().GetGUID());
} }
if (m_tapList.Count >= SharedConst.CreatureTappersSoftCap) if (m_tapList.Count >= SharedConst.CreatureTappersSoftCap)
@@ -1966,10 +1966,9 @@ namespace Game.Entities
Group group = player.GetGroup(); Group group = player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
if (member != null)
if (member.IsAtGroupRewardDistance(this)) if (member.IsAtGroupRewardDistance(this))
member.KillCreditGO(info.entry, GetGUID()); member.KillCreditGO(info.entry, GetGUID());
} }
@@ -3763,6 +3763,11 @@ namespace Game.Entities
public void SetLocationInstanceId(uint _instanceId) { instanceId = _instanceId; } public void SetLocationInstanceId(uint _instanceId) { instanceId = _instanceId; }
public override string ToString()
{
return GetName();
}
#region Fields #region Fields
public TypeMask ObjectTypeMask { get; set; } public TypeMask ObjectTypeMask { get; set; }
protected TypeId ObjectTypeId { get; set; } protected TypeId ObjectTypeId { get; set; }
+4 -10
View File
@@ -104,11 +104,9 @@ namespace Game.Entities
if (group != null) if (group != null)
{ {
// 2. In case when player is in group, initialize variables necessary for group calculations: // 2. In case when player is in group, initialize variables necessary for group calculations:
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{
Player member = refe.GetSource();
if (member != null)
{ {
Player member = groupRef.GetSource();
if (killer == member || (member.IsAtGroupRewardDistance(_victim) && member.IsAlive())) if (killer == member || (member.IsAtGroupRewardDistance(_victim) && member.IsAlive()))
{ {
uint lvl = member.GetLevel(); uint lvl = member.GetLevel();
@@ -126,7 +124,6 @@ namespace Game.Entities
_maxNotGrayMember = member; _maxNotGrayMember = member;
} }
} }
}
// 2.5. _isFullXP - flag identifying that for all group members victim is not gray, // 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
// so 100% XP will be rewarded (50% otherwise). // so 100% XP will be rewarded (50% otherwise).
_isFullXP = _maxNotGrayMember != null && (_maxLevel == _maxNotGrayMember.GetLevel()); _isFullXP = _maxNotGrayMember != null && (_maxLevel == _maxNotGrayMember.GetLevel());
@@ -254,11 +251,9 @@ namespace Game.Entities
_groupRate = Formulas.XPInGroupRate(_count, isRaid); _groupRate = Formulas.XPInGroupRate(_count, isRaid);
} }
// 3.1.3. Reward each group member (even dead or corpse) within reward distance. // 3.1.3. Reward each group member (even dead or corpse) within reward distance.
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{
Player member = refe.GetSource();
if (member != null)
{ {
Player member = groupRef.GetSource();
// Killer may not be at reward distance, check directly // Killer may not be at reward distance, check directly
if (killer == member || member.IsAtGroupRewardDistance(_victim)) if (killer == member || member.IsAtGroupRewardDistance(_victim))
_RewardPlayer(member, isDungeon); _RewardPlayer(member, isDungeon);
@@ -268,4 +263,3 @@ namespace Game.Entities
} }
} }
} }
}
+2 -5
View File
@@ -40,12 +40,9 @@ namespace Game.Entities
Group group = GetGroup(); Group group = GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == null)
continue;
if (!player.IsAtGroupRewardDistance(pRewardSource)) if (!player.IsAtGroupRewardDistance(pRewardSource))
continue; // member (alive or dead) or his corpse at req. distance continue; // member (alive or dead) or his corpse at req. distance
+14 -14
View File
@@ -18,14 +18,14 @@ namespace Game.Entities
List<Player> nearMembers = new(); List<Player> nearMembers = new();
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player Target = refe.GetSource(); Player target = groupRef.GetSource();
// IsHostileTo check duel and controlled by enemy // IsHostileTo check duel and controlled by enemy
if (Target != null && Target != this && IsWithinDistInMap(Target, radius) && if (target != this && IsWithinDistInMap(target, radius) &&
!Target.HasInvisibilityAura() && !IsHostileTo(Target)) !target.HasInvisibilityAura() && !IsHostileTo(target))
nearMembers.Add(Target); nearMembers.Add(target);
} }
if (nearMembers.Empty()) if (nearMembers.Empty())
@@ -37,13 +37,13 @@ namespace Game.Entities
public PartyResult CanUninviteFromGroup(ObjectGuid guidMember, byte? partyIndex) public PartyResult CanUninviteFromGroup(ObjectGuid guidMember, byte? partyIndex)
{ {
Group grp = GetGroup(partyIndex); Group group = GetGroup(partyIndex);
if (grp == null) if (group == null)
return PartyResult.NotInGroup; return PartyResult.NotInGroup;
if (grp.IsLFGGroup()) if (group.IsLFGGroup())
{ {
ObjectGuid gguid = grp.GetGUID(); ObjectGuid gguid = group.GetGUID();
if (Global.LFGMgr.GetKicksLeft(gguid) == 0) if (Global.LFGMgr.GetKicksLeft(gguid) == 0)
return PartyResult.PartyLfgBootLimit; return PartyResult.PartyLfgBootLimit;
@@ -51,7 +51,7 @@ namespace Game.Entities
if (Global.LFGMgr.IsVoteKickActive(gguid)) if (Global.LFGMgr.IsVoteKickActive(gguid))
return PartyResult.PartyLfgBootInProgress; return PartyResult.PartyLfgBootInProgress;
if (grp.GetMembersCount() <= SharedConst.LFGKickVotesNeeded) if (group.GetMembersCount() <= SharedConst.LFGKickVotesNeeded)
return PartyResult.PartyLfgBootTooFewPlayers; return PartyResult.PartyLfgBootTooFewPlayers;
if (state == LfgState.FinishedDungeon) if (state == LfgState.FinishedDungeon)
@@ -62,8 +62,8 @@ namespace Game.Entities
return PartyResult.PartyLfgBootLootRolls; return PartyResult.PartyLfgBootLootRolls;
// @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer. // @todo Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
if (refe.GetSource() != null && refe.GetSource().IsInMap(this) && refe.GetSource().IsInCombat()) if (groupRef.GetSource().IsInMap(this) && groupRef.GetSource().IsInCombat())
return PartyResult.PartyLfgBootInCombat; return PartyResult.PartyLfgBootInCombat;
/* Missing support for these types /* Missing support for these types
@@ -73,13 +73,13 @@ namespace Game.Entities
} }
else else
{ {
if (!grp.IsLeader(GetGUID()) && !grp.IsAssistant(GetGUID())) if (!group.IsLeader(GetGUID()) && !group.IsAssistant(GetGUID()))
return PartyResult.NotLeader; return PartyResult.NotLeader;
if (InBattleground()) if (InBattleground())
return PartyResult.InviteRestricted; return PartyResult.InviteRestricted;
if (grp.IsLeader(guidMember)) if (group.IsLeader(guidMember))
return PartyResult.NotLeader; return PartyResult.NotLeader;
} }
+3 -4
View File
@@ -2442,12 +2442,11 @@ namespace Game.Entities
var group = GetGroup(); var group = GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
// for any leave or dead (with not released body) group member at appropriate distance // for any leave or dead (with not released body) group member at appropriate distance
if (player != null && player.IsAtGroupRewardDistance(pEventObject) && player.GetCorpse() == null) if (player.IsAtGroupRewardDistance(pEventObject) && player.GetCorpse() == null)
player.AreaExploredOrEventHappens(questId); player.AreaExploredOrEventHappens(questId);
} }
} }
+5 -5
View File
@@ -147,6 +147,9 @@ namespace Game.Entities
WorldMgr.DecreasePlayerCount(); WorldMgr.DecreasePlayerCount();
m_group.Dispose();
m_originalGroup.Dispose();
base.Dispose(); base.Dispose();
} }
@@ -7531,12 +7534,9 @@ namespace Game.Entities
Group group = GetGroup(); Group group = GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == null)
continue;
if (!player.IsAtRecruitAFriendDistance(this)) if (!player.IsAtRecruitAFriendDistance(this))
continue; // member (alive or dead) or his corpse at req. distance continue; // member (alive or dead) or his corpse at req. distance
+3 -3
View File
@@ -123,10 +123,10 @@ namespace Game.Entities
Group group = owner.GetGroup(); Group group = owner.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player target = refe.GetSource(); Player target = groupRef.GetSource();
if (target != null && target.IsInMap(owner) && group.SameSubGroup(owner, target)) if (target.IsInMap(owner) && group.SameSubGroup(owner, target))
target.RemoveAurasDueToSpell(GetSpell(), GetGUID()); target.RemoveAurasDueToSpell(GetSpell(), GetGUID());
} }
} }
+2 -5
View File
@@ -3382,11 +3382,9 @@ namespace Game.Entities
List<Unit> nearMembers = new(); List<Unit> nearMembers = new();
// reserve place for players and pets because resizing vector every unit push is unefficient (vector is reallocated then) // reserve place for players and pets because resizing vector every unit push is unefficient (vector is reallocated then)
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{
Player target = refe.GetSource();
if (target != null)
{ {
Player target = groupRef.GetSource();
// IsHostileTo check duel and controlled by enemy // IsHostileTo check duel and controlled by enemy
if (target != this && IsWithinDistInMap(target, radius) && target.IsAlive() && !IsHostileTo(target)) if (target != this && IsWithinDistInMap(target, radius) && target.IsAlive() && !IsHostileTo(target))
nearMembers.Add(target); nearMembers.Add(target);
@@ -3397,7 +3395,6 @@ namespace Game.Entities
if (pet != this && IsWithinDistInMap(pet, radius) && pet.IsAlive() && !IsHostileTo(pet)) if (pet != this && IsWithinDistInMap(pet, radius) && pet.IsAlive() && !IsHostileTo(pet))
nearMembers.Add(pet); nearMembers.Add(pet);
} }
}
if (nearMembers.Empty()) if (nearMembers.Empty())
return null; return null;
+36 -59
View File
@@ -487,14 +487,12 @@ namespace Game.Groups
UpdateObject groupDataPacket; UpdateObject groupDataPacket;
// Broadcast group members' fields to player // Broadcast group members' fields to player
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
if (refe.GetSource() == player) Player existingMember = groupRef.GetSource();
if (existingMember == player)
continue; continue;
Player existingMember = refe.GetSource();
if (existingMember != null)
{
if (player.HaveAtClient(existingMember)) if (player.HaveAtClient(existingMember))
existingMember.BuildValuesUpdateBlockForPlayerWithFlag(groupData, UpdateFieldFlag.PartyMember, player); existingMember.BuildValuesUpdateBlockForPlayerWithFlag(groupData, UpdateFieldFlag.PartyMember, player);
@@ -510,7 +508,6 @@ namespace Game.Groups
} }
} }
} }
}
if (groupData.HasData()) if (groupData.HasData())
{ {
@@ -531,11 +528,9 @@ namespace Game.Groups
Player player = Global.ObjAccessor.FindConnectedPlayer(guid); Player player = Global.ObjAccessor.FindConnectedPlayer(guid);
if (player != null) if (player != null)
{ {
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{
Player groupMember = refe.GetSource();
if (groupMember != null)
{ {
Player groupMember = groupRef.GetSource();
if (groupMember.GetGUID() == guid) if (groupMember.GetGUID() == guid)
continue; continue;
@@ -543,7 +538,6 @@ namespace Game.Groups
player.RemoveAllGroupBuffsFromCaster(groupMember.GetGUID()); player.RemoveAllGroupBuffsFromCaster(groupMember.GetGUID());
} }
} }
}
// LFG group vote kick handled in scripts // LFG group vote kick handled in scripts
if (IsLFGGroup() && method == RemoveMethod.Kick) if (IsLFGGroup() && method == RemoveMethod.Kick)
@@ -925,37 +919,36 @@ namespace Game.Groups
PartyMemberFullState packet = new(); PartyMemberFullState packet = new();
packet.Initialize(player); packet.Initialize(player);
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
if (member != null && member != player && (!member.IsInMap(player) || !member.IsWithinDist(player, member.GetSightRange(), false))) if (member != player && (!member.IsInMap(player) || !member.IsWithinDist(player, member.GetSightRange(), false)))
member.SendPacket(packet); member.SendPacket(packet);
} }
} }
public void BroadcastAddonMessagePacket(ServerPacket packet, string prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = default) public void BroadcastAddonMessagePacket(ServerPacket packet, string prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = default)
{ {
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == null || (!ignore.IsEmpty() && player.GetGUID() == ignore) || (ignorePlayersInBGRaid && player.GetGroup() != this)) if ((!ignore.IsEmpty() && player.GetGUID() == ignore) || (ignorePlayersInBGRaid && player.GetGroup() != this))
continue; continue;
if ((group == -1 || refe.GetSubGroup() == group)) if (player.GetSession().IsAddonRegistered(prefix) && (group == -1 || groupRef.GetSubGroup() == group))
if (player.GetSession().IsAddonRegistered(prefix))
player.SendPacket(packet); player.SendPacket(packet);
} }
} }
public void BroadcastPacket(ServerPacket packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = default) public void BroadcastPacket(ServerPacket packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = default)
{ {
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == null || (!ignore.IsEmpty() && player.GetGUID() == ignore) || (ignorePlayersInBGRaid && player.GetGroup() != this)) if ((!ignore.IsEmpty() && player.GetGUID() == ignore) || (ignorePlayersInBGRaid && player.GetGroup() != this))
continue; continue;
if (player.GetSession() != null && (group == -1 || refe.GetSubGroup() == group)) if (group == -1 || groupRef.GetSubGroup() == group)
player.SendPacket(packet); player.SendPacket(packet);
} }
} }
@@ -1183,11 +1176,12 @@ namespace Game.Groups
return GroupJoinBattlegroundResult.None; // ERR_GROUP_JOIN_Battleground_TOO_MANY handled on client side return GroupJoinBattlegroundResult.None; // ERR_GROUP_JOIN_Battleground_TOO_MANY handled on client side
// get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.) // get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.)
Player reference = GetFirstMember().GetSource(); var membersRefe = GetMembers().GetFirst();
// no reference found, can't join this way // no reference found, can't join this way
if (reference == null) if (membersRefe == null)
return GroupJoinBattlegroundResult.BattlegroundJoinFailed; return GroupJoinBattlegroundResult.BattlegroundJoinFailed;
Player reference = membersRefe.GetSource();
PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel((uint)bgOrTemplate.MapIDs[0], reference.GetLevel()); PvpDifficultyRecord bracketEntry = Global.DB2Mgr.GetBattlegroundBracketByLevel((uint)bgOrTemplate.MapIDs[0], reference.GetLevel());
if (bracketEntry == null) if (bracketEntry == null)
return GroupJoinBattlegroundResult.BattlegroundJoinFailed; return GroupJoinBattlegroundResult.BattlegroundJoinFailed;
@@ -1198,9 +1192,9 @@ namespace Game.Groups
// check every member of the group to be able to join // check every member of the group to be able to join
memberscount = 0; memberscount = 0;
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next(), ++memberscount) foreach (GroupReference groupRef in GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
// offline member? don't let join // offline member? don't let join
if (member == null) if (member == null)
return GroupJoinBattlegroundResult.BattlegroundJoinFailed; return GroupJoinBattlegroundResult.BattlegroundJoinFailed;
@@ -1243,6 +1237,8 @@ namespace Game.Groups
return GroupJoinBattlegroundResult.BattlegroundJoinFailed; return GroupJoinBattlegroundResult.BattlegroundJoinFailed;
if (isMercenary != (member.HasAura(BattlegroundConst.SpellMercenaryContractHorde) || member.HasAura(BattlegroundConst.SpellMercenaryContractAlliance))) if (isMercenary != (member.HasAura(BattlegroundConst.SpellMercenaryContractHorde) || member.HasAura(BattlegroundConst.SpellMercenaryContractAlliance)))
return GroupJoinBattlegroundResult.BattlegroundJoinMercenary; return GroupJoinBattlegroundResult.BattlegroundJoinMercenary;
memberscount++;
} }
errorGuid = ObjectGuid.Empty; errorGuid = ObjectGuid.Empty;
@@ -1267,12 +1263,9 @@ namespace Game.Groups
DB.Characters.Execute(stmt); DB.Characters.Execute(stmt);
} }
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player.GetSession() == null)
continue;
player.SetDungeonDifficultyID(difficulty); player.SetDungeonDifficultyID(difficulty);
player.SendDungeonDifficulty(); player.SendDungeonDifficulty();
} }
@@ -1291,12 +1284,9 @@ namespace Game.Groups
DB.Characters.Execute(stmt); DB.Characters.Execute(stmt);
} }
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player.GetSession() == null)
continue;
player.SetRaidDifficultyID(difficulty); player.SetRaidDifficultyID(difficulty);
player.SendRaidDifficulty(false); player.SendRaidDifficulty(false);
} }
@@ -1315,12 +1305,9 @@ namespace Game.Groups
DB.Characters.Execute(stmt); DB.Characters.Execute(stmt);
} }
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player.GetSession() == null)
continue;
player.SetLegacyRaidDifficultyID(difficulty); player.SetLegacyRaidDifficultyID(difficulty);
player.SendRaidDifficulty(true); player.SendRaidDifficulty(true);
} }
@@ -1348,9 +1335,9 @@ namespace Game.Groups
public void ResetInstances(InstanceResetMethod method, Player notifyPlayer) public void ResetInstances(InstanceResetMethod method, Player notifyPlayer)
{ {
for (GroupInstanceReference refe = m_ownedInstancesMgr.GetFirst(); refe != null; refe = refe.Next()) foreach (GroupInstanceReference groupInstanceRef in m_ownedInstancesMgr)
{ {
InstanceMap map = refe.GetSource(); InstanceMap map = groupInstanceRef.GetSource();
switch (map.Reset(method)) switch (map.Reset(method))
{ {
case InstanceResetResult.Success: case InstanceResetResult.Success:
@@ -1795,19 +1782,9 @@ namespace Game.Groups
m_memberMgr.InsertFirst(pRef); m_memberMgr.InsertFirst(pRef);
} }
void DelinkMember(ObjectGuid guid) public void DelinkMember(ObjectGuid guid)
{ {
GroupReference refe = m_memberMgr.GetFirst(); m_memberMgr.Remove(p => p.GetSource().GetGUID() == guid);
while (refe != null)
{
GroupReference nextRef = refe.Next();
if (refe.GetSource().GetGUID() == guid)
{
refe.Unlink();
break;
}
refe = nextRef;
}
} }
void _initRaidSubGroupsCounter() void _initRaidSubGroupsCounter()
@@ -1915,7 +1892,7 @@ namespace Game.Groups
public uint GetDbStoreId() { return m_dbStoreId; } public uint GetDbStoreId() { return m_dbStoreId; }
public List<MemberSlot> GetMemberSlots() { return m_memberSlots; } public List<MemberSlot> GetMemberSlots() { return m_memberSlots; }
public GroupReference GetFirstMember() { return (GroupReference)m_memberMgr.GetFirst(); } public GroupRefManager GetMembers() { return m_memberMgr; }
public uint GetMembersCount() { return (uint)m_memberSlots.Count; } public uint GetMembersCount() { return (uint)m_memberSlots.Count; }
public uint GetInviteeCount() { return (uint)m_invitees.Count; } public uint GetInviteeCount() { return (uint)m_invitees.Count; }
public GroupFlags GetGroupFlags() { return m_groupFlags; } public GroupFlags GetGroupFlags() { return m_groupFlags; }
@@ -1924,8 +1901,8 @@ namespace Game.Groups
public void BroadcastWorker(Action<Player> worker) public void BroadcastWorker(Action<Player> worker)
{ {
for (GroupReference refe = GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in GetMembers())
worker(refe.GetSource()); worker(groupRef.GetSource());
} }
public ObjectGuid GetRecentInstanceOwner(uint mapId) public ObjectGuid GetRecentInstanceOwner(uint mapId)
+2 -7
View File
@@ -8,9 +8,7 @@ namespace Game.Groups
{ {
public class GroupInstanceReference : Reference<Group, InstanceMap> public class GroupInstanceReference : Reference<Group, InstanceMap>
{ {
~GroupInstanceReference() { Unlink(); } public void Dispose() { Unlink(); }
public new GroupInstanceReference Next() { return (GroupInstanceReference)base.Next(); }
public override void TargetObjectBuildLink() public override void TargetObjectBuildLink()
{ {
@@ -18,8 +16,5 @@ namespace Game.Groups
} }
} }
class GroupInstanceRefManager : RefManager<Group, InstanceMap> class GroupInstanceRefManager : RefManager<GroupInstanceReference> { }
{
public new GroupInstanceReference GetFirst() { return (GroupInstanceReference)base.GetFirst(); }
}
} }
+6 -6
View File
@@ -13,14 +13,17 @@ namespace Game.Groups
iSubGroup = 0; iSubGroup = 0;
} }
~GroupReference() { Unlink(); } public void Dispose() { Unlink(); }
public override void TargetObjectBuildLink() public override void TargetObjectBuildLink()
{ {
GetTarget().LinkMember(this); GetTarget().LinkMember(this);
} }
public new GroupReference Next() { return (GroupReference)base.Next(); } public override void TargetObjectDestroyLink()
{
GetTarget()?.DelinkMember(GetSource().GetGUID());
}
public byte GetSubGroup() { return iSubGroup; } public byte GetSubGroup() { return iSubGroup; }
@@ -29,8 +32,5 @@ namespace Game.Groups
byte iSubGroup; byte iSubGroup;
} }
public class GroupRefManager : RefManager<Group, Player> public class GroupRefManager : RefManager<GroupReference> { }
{
public new GroupReference GetFirst() { return (GroupReference)base.GetFirst(); }
}
} }
+16 -22
View File
@@ -86,7 +86,7 @@ namespace Game
GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None; GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult.None;
Group grp = _player.GetGroup(); Group group = _player.GetGroup();
Team getQueueTeam() Team getQueueTeam()
{ {
@@ -105,7 +105,7 @@ namespace Game
BattlefieldStatusFailed battlefieldStatusFailed; BattlefieldStatusFailed battlefieldStatusFailed;
// check queue conditions // check queue conditions
if (grp == null) if (group == null)
{ {
if (GetPlayer().IsUsingLfg()) if (GetPlayer().IsUsingLfg())
{ {
@@ -177,12 +177,12 @@ namespace Game
} }
else else
{ {
if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) if (group.GetLeaderGUID() != GetPlayer().GetGUID())
return; return;
ObjectGuid errorGuid; ObjectGuid errorGuid;
err = grp.CanJoinBattlegroundQueue(bgTemplate, bgQueueTypeId, 0, bgTemplate.GetMaxPlayersPerTeam(), false, 0, out errorGuid); err = group.CanJoinBattlegroundQueue(bgTemplate, bgQueueTypeId, 0, bgTemplate.GetMaxPlayersPerTeam(), false, 0, out errorGuid);
isPremade = (grp.GetMembersCount() >= bgTemplate.GetMinPlayersPerTeam()); isPremade = (group.GetMembersCount() >= bgTemplate.GetMinPlayersPerTeam());
BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId); BattlegroundQueue bgQueue = Global.BattlegroundMgr.GetBattlegroundQueue(bgQueueTypeId);
GroupQueueInfo ginfo = null; GroupQueueInfo ginfo = null;
@@ -191,16 +191,13 @@ namespace Game
if (err == 0) if (err == 0)
{ {
Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:"); Log.outDebug(LogFilter.Battleground, "Battleground: the following players are joining as group:");
ginfo = bgQueue.AddGroup(GetPlayer(), grp, getQueueTeam(), bracketEntry, isPremade, 0, 0); ginfo = bgQueue.AddGroup(GetPlayer(), group, getQueueTeam(), bracketEntry, isPremade, 0, 0);
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId());
} }
for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
if (member == null)
continue; // this should never happen
if (err != 0) if (err != 0)
{ {
BattlefieldStatusFailed battlefieldStatus; BattlefieldStatusFailed battlefieldStatus;
@@ -510,11 +507,11 @@ namespace Game
if (bracketEntry == null) if (bracketEntry == null)
return; return;
Group grp = GetPlayer().GetGroup(); Group group = GetPlayer().GetGroup();
// no group found, error // no group found, error
if (grp == null) if (group == null)
return; return;
if (grp.GetLeaderGUID() != GetPlayer().GetGUID()) if (group.GetLeaderGUID() != GetPlayer().GetGUID())
return; return;
uint ateamId = GetPlayer().GetArenaTeamId(packet.TeamSizeIndex); uint ateamId = GetPlayer().GetArenaTeamId(packet.TeamSizeIndex);
@@ -525,7 +522,7 @@ namespace Game
// get the team rating for queuing // get the team rating for queuing
uint arenaRating = at.GetRating(); uint arenaRating = at.GetRating();
uint matchmakerRating = at.GetAverageMMR(grp); uint matchmakerRating = at.GetAverageMMR(group);
// the arenateam id must match for everyone in the group // the arenateam id must match for everyone in the group
if (arenaRating <= 0) if (arenaRating <= 0)
@@ -537,21 +534,18 @@ namespace Game
GroupQueueInfo ginfo = null; GroupQueueInfo ginfo = null;
ObjectGuid errorGuid; ObjectGuid errorGuid;
var err = grp.CanJoinBattlegroundQueue(bgTemplate, bgQueueTypeId, (uint)arenatype, (uint)arenatype, true, packet.TeamSizeIndex, out errorGuid); var err = group.CanJoinBattlegroundQueue(bgTemplate, bgQueueTypeId, (uint)arenatype, (uint)arenatype, true, packet.TeamSizeIndex, out errorGuid);
if (err == 0) if (err == 0)
{ {
Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype); Log.outDebug(LogFilter.Battleground, "Battleground: arena team id {0}, leader {1} queued with matchmaker rating {2} for type {3}", GetPlayer().GetArenaTeamId(packet.TeamSizeIndex), GetPlayer().GetName(), matchmakerRating, arenatype);
ginfo = bgQueue.AddGroup(GetPlayer(), grp, _player.GetTeam(), bracketEntry, false, arenaRating, matchmakerRating, ateamId); ginfo = bgQueue.AddGroup(GetPlayer(), group, _player.GetTeam(), bracketEntry, false, arenaRating, matchmakerRating, ateamId);
avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId()); avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry.GetBracketId());
} }
for (GroupReference refe = grp.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
if (member == null)
continue;
if (err != 0) if (err != 0)
{ {
BattlefieldStatusFailed battlefieldStatus; BattlefieldStatusFailed battlefieldStatus;
+5 -5
View File
@@ -158,7 +158,7 @@ namespace Game
if (group == null) if (group == null)
return; return;
if (packet.PartyIndex != 0 && group.GetGroupCategory() != (GroupCategory)packet.PartyIndex) if (packet.PartyIndex.HasValue && group.GetGroupCategory() != (GroupCategory)packet.PartyIndex)
return; return;
if (packet.Accept) if (packet.Accept)
@@ -702,9 +702,9 @@ namespace Game
broadcastPingUnit.SpellOverrideNameID = pingUnit.SpellOverrideNameID; broadcastPingUnit.SpellOverrideNameID = pingUnit.SpellOverrideNameID;
broadcastPingUnit.Write(); broadcastPingUnit.Write();
for (GroupReference itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = itr.GetSource(); Player member = groupRef.GetSource();
if (_player == member || !_player.IsInMap(member)) if (_player == member || !_player.IsInMap(member))
continue; continue;
@@ -732,9 +732,9 @@ namespace Game
broadcastPingWorldPoint.PingDuration = pingWorldPoint.PingDuration; broadcastPingWorldPoint.PingDuration = pingWorldPoint.PingDuration;
broadcastPingWorldPoint.Write(); broadcastPingWorldPoint.Write();
for (GroupReference itr = group.GetFirstMember(); itr != null; itr = itr.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = itr.GetSource(); Player member = groupRef.GetSource();
if (_player == member || !_player.IsInMap(member)) if (_player == member || !_player.IsInMap(member))
continue; continue;
+2 -5
View File
@@ -205,12 +205,9 @@ namespace Game
LfgPartyInfo lfgPartyInfo = new(); LfgPartyInfo lfgPartyInfo = new();
// Get the Locked dungeons of the other party members // Get the Locked dungeons of the other party members
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player plrg = refe.GetSource(); Player plrg = groupRef.GetSource();
if (plrg == null)
continue;
ObjectGuid pguid = plrg.GetGUID(); ObjectGuid pguid = plrg.GetGUID();
if (pguid == guid) if (pguid == guid)
continue; continue;
+2 -5
View File
@@ -99,12 +99,9 @@ namespace Game
Group group = player.GetGroup(); Group group = player.GetGroup();
List<Player> playersNear = new(); List<Player> playersNear = new();
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player member = refe.GetSource(); Player member = groupRef.GetSource();
if (member == null)
continue;
if (!loot.HasAllowedLooter(member.GetGUID())) if (!loot.HasAllowedLooter(member.GetGUID()))
continue; continue;
+6 -8
View File
@@ -126,11 +126,10 @@ namespace Game
var group = _player.GetGroup(); var group = _player.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();
if (player == _player || !player.IsInMap(_player)) // not self and in same map
if (player == null || player == _player || !player.IsInMap(_player)) // not self and in same map
continue; continue;
if (player.CanTakeQuest(quest, true)) if (player.CanTakeQuest(quest, true))
@@ -551,11 +550,10 @@ namespace Game
return; return;
} }
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player receiver = refe.GetSource(); Player receiver = groupRef.GetSource();
if (receiver == sender)
if (receiver == null || receiver == sender)
continue; continue;
if (!receiver.GetPlayerSharingQuest().IsEmpty()) if (!receiver.GetPlayerSharingQuest().IsEmpty())
+2 -3
View File
@@ -936,10 +936,9 @@ namespace Game.Loots
if (loot_type == LootType.Corpse) if (loot_type == LootType.Corpse)
roundRobinPlayer = lootOwner.GetGUID(); roundRobinPlayer = lootOwner.GetGUID();
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player player = refe.GetSource(); Player player = groupRef.GetSource();// should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
if (player != null) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter
if (player.IsAtGroupRewardDistance(lootOwner)) if (player.IsAtGroupRewardDistance(lootOwner))
FillNotNormalLootFor(player); FillNotNormalLootFor(player);
} }
+18 -5
View File
@@ -3,7 +3,6 @@
using Framework.Constants; using Framework.Constants;
using Framework.Database; using Framework.Database;
using Framework.Dynamic;
using Game.BattleGrounds; using Game.BattleGrounds;
using Game.Collision; using Game.Collision;
using Game.DataStorage; using Game.DataStorage;
@@ -15,7 +14,6 @@ using Game.Scenarios;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
@@ -62,7 +60,7 @@ namespace Game.Maps
_worldStateValues = Global.WorldStateMgr.GetInitialWorldStatesForMap(this); _worldStateValues = Global.WorldStateMgr.GetInitialWorldStatesForMap(this);
} }
public void Dispose() public virtual void Dispose()
{ {
// Delete all waiting spawns // Delete all waiting spawns
// This doesn't delete from database. // This doesn't delete from database.
@@ -389,7 +387,6 @@ namespace Game.Maps
} }
} }
public void AddInfiniteAOIVignette(VignetteData vignette) public void AddInfiniteAOIVignette(VignetteData vignette)
{ {
_infiniteAOIVignettes.Add(vignette); _infiniteAOIVignettes.Add(vignette);
@@ -4905,10 +4902,14 @@ namespace Game.Maps
} }
} }
~InstanceMap() public override void Dispose()
{ {
if (i_instanceLock != null) if (i_instanceLock != null)
i_instanceLock.SetInUse(false); i_instanceLock.SetInUse(false);
i_owningGroupRef.Dispose();
base.Dispose();
} }
public override void InitVisibilityDistance() public override void InitVisibilityDistance()
@@ -5339,6 +5340,18 @@ namespace Game.Maps
InitVisibilityDistance(); InitVisibilityDistance();
} }
public override void Dispose()
{
if (m_bg != null)
{
//unlink to prevent crash, always unlink all pointer reference before destruction
m_bg.SetBgMap(null);
m_bg.Dispose();
}
base.Dispose();
}
public override void InitVisibilityDistance() public override void InitVisibilityDistance()
{ {
m_VisibleDistance = IsBattleArena() ? Global.WorldMgr.GetMaxVisibleDistanceInArenas() : Global.WorldMgr.GetMaxVisibleDistanceInBG(); m_VisibleDistance = IsBattleArena() ? Global.WorldMgr.GetMaxVisibleDistanceInArenas() : Global.WorldMgr.GetMaxVisibleDistanceInBG();
+2 -5
View File
@@ -61,12 +61,9 @@ namespace Game.PvP
Group group = killer.GetGroup(); Group group = killer.GetGroup();
if (group != null) if (group != null)
{ {
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next()) foreach (GroupReference groupRef in group.GetMembers())
{ {
Player groupGuy = refe.GetSource(); Player groupGuy = groupRef.GetSource();
if (groupGuy == null)
continue;
// skip if too far away // skip if too far away
if (!groupGuy.IsAtGroupRewardDistance(killed)) if (!groupGuy.IsAtGroupRewardDistance(killed))