コード例 #1
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		public bool CheckFull(GroupMember member, SubGroup group)
		{
			if (group.IsFull)
			{
				var chr = member.Character;
				if (chr != null)
				{
					GroupHandler.SendResult(chr.Client, GroupResult.GroupIsFull);
				}
				return false;
			}
			return true;
		}
コード例 #2
0
ファイル: GroupHandler.cs プロジェクト: Stika/WCell
 public static void SendLeaderChanged(GroupMember leader)
 {
     using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_GROUP_SET_LEADER))
     {
         packet.WriteCString(leader.Name);
         leader.SubGroup.Group.SendAll(packet);
     }
 }
コード例 #3
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Checks whether the given target exists in this group and whether the given requestMember has the given privs
		/// </summary>
		public GroupResult CheckAction(GroupMember requestMember, GroupMember target, string targetName, GroupPrivs reqPrivs)
		{
			GroupResult err;
			if (target == null || (target.Group) != requestMember.Group)
			{
				// Character is offline or doesn't exist
				err = GroupResult.NotInYourParty;
			}
			else if ((reqPrivs == GroupPrivs.Leader && m_leader != requestMember) ||
				(reqPrivs == GroupPrivs.MainAsisstant && !requestMember.IsAtLeastMainAssistant) ||
				(reqPrivs == GroupPrivs.Assistant && !requestMember.IsAtLeastAssistant))
			{
				err = GroupResult.DontHavePermission;
				targetName = string.Empty;
			}
			else
			{
				return GroupResult.NoError;
			}

			var requester = requestMember.Character;
			if (requester != null)
			{
				SendResult(requester.Client, err, 0, targetName);
			}
			return err;
		}
コード例 #4
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		public bool CheckPrivs(GroupMember member, GroupPrivs reqPrivs)
		{
			//var flags = member.Flags;
			if ((reqPrivs == GroupPrivs.Leader && m_leader != member) ||
				(reqPrivs == GroupPrivs.MainAsisstant && !member.IsAtLeastMainAssistant) ||
				(reqPrivs == GroupPrivs.Assistant && !member.IsAtLeastAssistant))
			{
				var requester = member.Character;
				if (requester != null)
				{
					GroupHandler.SendResult(requester.Client, GroupResult.DontHavePermission);
				}
				return false;
			}
			return true;
		}
コード例 #5
0
ファイル: RaidGroup.cs プロジェクト: ebakkedahl/WCell
        /// <summary>
        /// Sends the response of a member to the original ready check requester.
        /// </summary>
        /// <param name="member">the responding member</param>
        /// <param name="status">their ready status</param>
        public void SendReadyCheckResponse(GroupMember member, ReadyCheckStatus status)
        {
            using (var packet = new RealmPacketOut(RealmServerOpCode.MSG_RAID_READY_CHECK_CONFIRM))
            {
                packet.Write(EntityId.GetPlayerId(member.Id));
                packet.WriteByte((byte)status);

                Character checkRequester = World.GetCharacter(m_readyCheckRequester.Id);
                if (checkRequester != null)
                    checkRequester.Client.Send(packet);
            }
        }
コード例 #6
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Sends ping to the group, except pinger
		/// </summary>
		/// <param name="pinger">The group member who pingged the minimap</param>
		/// <param name="x">x coordinate of ping</param>
		/// <param name="y">y coordinate of ping</param>
		public virtual void SendPing(GroupMember pinger, float x, float y)
		{
			using (var packet = new RealmPacketOut(RealmServerOpCode.MSG_MINIMAP_PING))
			{
				packet.Write(EntityId.GetPlayerId(pinger.Id));
				packet.WriteFloat(x);
				packet.WriteFloat(y);

				SendAll(packet, pinger);
			}
		}
コード例 #7
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Called when the given member is added
		/// </summary>
		protected virtual void OnAddMember(GroupMember member)
		{
			m_Count++;
			var chr = member.Character;
			if (chr != null)
			{
				chr.GroupMember = member;
			}

			if (m_firstMember == null)
			{
				// first member:
				m_firstMember = m_lastMember = member;
			}
			else
			{
				m_lastMember.Next = member;
				m_lastMember = member;
			}

			var handler = MemberAdded;
			if (handler != null)
			{
				handler(member);
			}
		}
コード例 #8
0
ファイル: RaidGroup.cs プロジェクト: ebakkedahl/WCell
        /// <summary>
        /// Moves a member of the raid group into another subgroup.
        /// </summary>
        /// <param name="member">the member to move</param>
        /// <param name="group">the target subgroup</param>
        /// <returns>Whether the move was successful or false if the target group was full</returns>
        public bool MoveMember(GroupMember member, SubGroup group)
        {
            if (group.IsFull)
                return false;

            var oldGroup = member.SubGroup;
            oldGroup.m_members.Remove(member);
            group.AddMember(member);
            return true;
        }
コード例 #9
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Add member to Group
		/// </summary>
		/// <param name="update">Indicates if this group needs to be updated after adding the 
		/// new member</param>
		/// <returns>True if the member was added successfully. False otherwise.</returns>
		public GroupMember AddMember(Character chr, bool update)
		{
			GroupMember newMember = null;

			m_syncLock.EnterWriteLock();

			try
			{
				// look for the first SubGroup with space left
				foreach (var groupUnit in m_subGroups)
				{
					if (!groupUnit.IsFull)
					{
						newMember = new GroupMember(chr, GroupMemberFlags.Normal);
						groupUnit.AddMember(newMember);
						break;
					}
				}
			}
			catch (Exception e)
			{
				LogUtil.ErrorException(e, string.Format("Could not add member {0} to group {1}", chr, this));
			}
			finally
			{
				m_syncLock.ExitWriteLock();
			}

			OnAddMember(newMember);
			if (newMember != null && update)
			{
				SendUpdate();
			}
			return newMember;
		}
コード例 #10
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Remove member from this Group
		/// </summary>
		public virtual void RemoveMember(GroupMember member)
		{
			if (Count <= MinGroupMemberCount)
			{
				Disband();
			}
			else
			{
				m_syncLock.EnterWriteLock();

				var leaderChanged = false;
				try
				{
					var next = member.Next;
					OnMemberRemoved(member);


					// fix the links in the linked list:
					if (m_firstMember == member)
					{
						// set the new FirstMember if we removed the prevous one
						m_firstMember = next;
					}
					else
					{
						// set the previous GroupMember's Next member
						var previous = m_firstMember;
						while (previous.Next != member)
						{
							previous = previous.Next;
						}

						// previous should never be null here
						previous.Next = next;
						if (member == m_lastMember)
						{
							m_lastMember = previous;
						}
					}

					//Set new Leader if we removed the previous one
					if (m_leader == member)
					{
						m_leader = GetFirstOnlineMemberUnlocked();
						leaderChanged = true;
					}

					//Set new MasterLooter if we removed the previous one
					if (m_masterLooter == member)
					{
						m_masterLooter = m_firstMember;
					}

					//Unset MainAssistant if we removed the previous one
					if (m_mainAssistant == member)
					{
						member.Flags &= ~GroupMemberFlags.MainAssistant;

						m_mainAssistant = null;
					}

					//Unset MainTank if we removed the previous one
					if (m_mainTank == member)
					{
						member.Flags &= ~GroupMemberFlags.MainTank;

						m_mainTank = null;
					}

					// Skip the member in RoundRobin
					if (m_roundRobinMember == member)
					{
						m_roundRobinMember = next;
					}
				}
				finally
				{
					m_syncLock.ExitWriteLock();
				}

				if (leaderChanged)
				{
					// make sure to call this after the lock has been released
					OnLeaderChanged(member);
				}
			}

			SendUpdate();
		}
コード例 #11
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Update the stats of the given <see cref="GroupMember"/> to all 
		/// out of range members of this group. 
		/// </summary>
		/// <remarks>Method requires Group-synchronization.</remarks>
		/// <param name="member">The <see cref="GroupMember"/> who needs to send
		/// the update</param>
		internal void UpdateOutOfRangeMembers(GroupMember member)
		{
			if (member.Character == null)
				return;

			if (member.Group != this)
				return;

			foreach (var chr in GetCharacters())
			{
				if (chr != member.Character && chr != null
					&& !chr.IsInUpdateRange(member.Character)
					&& member.Character.GroupUpdateFlags != GroupUpdateFlags.None)
				{
					GroupHandler.SendPartyMemberStats(chr.Client, member,
						member.Character.GroupUpdateFlags);
				}
			}
			member.Character.GroupUpdateFlags = GroupUpdateFlags.None;
		}
コード例 #12
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Sets the given Looting-parameters and updates the Group.
		/// </summary>
		public void SetLootMethod(LootMethod method, GroupMember masterLooter, ItemQuality lootThreshold)
		{
			m_syncLock.EnterWriteLock();
			try
			{
				LootMethod = method;
				m_masterLooter = masterLooter;
				LootThreshold = lootThreshold;
			}
			finally
			{
				m_syncLock.ExitWriteLock();
			}

			SendUpdate();
		}
コード例 #13
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Selects and returns the next online Member whose turn it is in RoundRobin.
		/// </summary>
		/// <returns>null if all members of this Group are offline.</returns>
		public GroupMember GetNextRoundRobinMember()
		{
			m_syncLock.EnterWriteLock();
			try
			{
				if (m_roundRobinMember == null)
				{
					m_roundRobinMember = m_firstMember;
				}
				else
				{
					m_roundRobinMember = m_roundRobinMember.Next;
				}
				while (m_roundRobinMember.Character == null)
				{
					m_roundRobinMember = m_roundRobinMember.Next;
					if (m_roundRobinMember == m_firstMember)
					{
						return null;
					}
				}
			}
			finally
			{
				m_syncLock.ExitWriteLock();
			}
			return m_roundRobinMember;
		}
コード例 #14
0
ファイル: GroupHandler.cs プロジェクト: Stika/WCell
 /// <summary>
 /// Sends the requested party member stats data to the client
 /// </summary>
 /// <param name="client">realm client</param>
 /// <param name="member">The character whose stats is going to be retrieved</param>
 /// <param name="flags">The stats to be retrieved from the <paramref name="member"/></param>
 public static void SendPartyMemberStats(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags)
 {
     SendPartyMemberStatsInternal(client, member, flags, RealmServerOpCode.SMSG_PARTY_MEMBER_STATS);
 }
コード例 #15
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Called before the given member is removed to clean up everything related to the given member
		/// </summary>
		protected void OnMemberRemoved(GroupMember member)
		{
			var chr = member.Character;
			if (chr != null && chr.IsInWorld)
			{
				if (!chr.IsInContext)
				{
					chr.ExecuteInContext(() => OnMemberRemoved(member));
					return;
				}

				var handler = MemberRemoved;
				if (handler != null)
				{
					handler(member);
				}
				m_Count--;

				//Send an empty party list to the member
				SendEmptyUpdate(chr);

				chr.GroupMember = null;

				// notify user:
				// SendGroupDestroyed(chr);
				GroupHandler.SendResult(chr.Client, GroupResult.NoError);

				//Remove the member from the subgroup
				member.SubGroup.RemoveMember(member);

				member.Character = null;

				// Teleport out of group-owned instances within 1 minute
				if (chr.Region is BaseInstance)
				{
					var instance = (BaseInstance)chr.Region;
					chr.Region.CallDelayed(GroupInstanceKickDelay, () =>
					{
						if (chr.IsInWorld && chr.Region == instance && !instance.CanEnter(chr))
						{
							// chr is still inside and not allowed
							//chr.Region.TeleportOutside(chr);
							chr.TeleportToNearestGraveyard();
						}
					});
				}
			}
			else
			{
				var handler = MemberRemoved;
				if (handler != null)
				{
					handler(member);
				}
				m_Count--;

				GroupMgr.Instance.OfflineChars.Remove(member.Id);
				member.m_subGroup = null;
			}
			member.m_nextMember = null;
		}
コード例 #16
0
ファイル: GroupHandler.cs プロジェクト: Stika/WCell
        /// <summary>
        /// Sends the requested party member stats data to the client
        /// </summary>
        /// <param name="client">realm client</param>
        /// <param name="member">The character whose stats is going to be retrieved</param>
        /// <param name="flags">The stats to be retrieved from the <paramref name="member"/></param>
        private static void SendPartyMemberStatsInternal(IPacketReceiver client, GroupMember member, GroupUpdateFlags flags,
                                                         RealmServerOpCode opcode)
        {
            using (var packet = new RealmPacketOut(opcode))
            {
                if (opcode == RealmServerOpCode.SMSG_PARTY_MEMBER_STATS_FULL)
                {
                    packet.Write((byte)0); //arena something
                }

                member.WriteIdPacked(packet);
                if (!member.IsOnline)
                {
                    packet.WriteUShort((ushort)CharacterStatus.OFFLINE);
                    client.Send(packet);
                    return;
                }
                packet.Write((uint)flags);

                var chr = member.Character;
                if (flags.HasFlag(GroupUpdateFlags.Status))
                {
                    packet.Write((ushort)chr.Status);
                }
                if (flags.HasFlag(GroupUpdateFlags.Health))
                {
                    packet.Write(chr.Health);
                }
                if (flags.HasFlag(GroupUpdateFlags.MaxHealth))
                {
                    packet.Write(chr.MaxHealth);
                }
                if (flags.HasFlag(GroupUpdateFlags.PowerType))
                {
                    packet.Write((byte)chr.PowerType);
                }
                if (flags.HasFlag(GroupUpdateFlags.Power))
                {
                    packet.Write((ushort)chr.Power);
                }
                if (flags.HasFlag(GroupUpdateFlags.MaxPower))
                {
                    packet.Write((ushort)chr.MaxPower);
                }
                if (flags.HasFlag(GroupUpdateFlags.Level))
                {
                    packet.Write((ushort)chr.Level);
                }
                if (flags.HasFlag(GroupUpdateFlags.ZoneId))
                {
                    packet.Write((ushort)(chr.Zone != null ? chr.Zone.Id : ZoneId.None));
                }
                if (flags.HasFlag(GroupUpdateFlags.Position))
                {
                    packet.Write((ushort)chr.Position.X);
                    packet.Write((ushort)chr.Position.Y);
                }
                if (flags.HasFlag(GroupUpdateFlags.Auras))
                {
                    ulong auraMask = chr.AuraUpdateMask;
                    packet.Write(auraMask);
                    Aura currAura;

                    for (byte i = 0; i < AuraHandler.MaxAuras; ++i)
                    {
                        if ((auraMask & ((ulong)1 << i)) != 0)
                        {
                            currAura = chr.Auras.GetAt(i);

                            packet.Write(currAura.Spell.Id);
                            packet.Write((byte)currAura.Flags);
                        }
                    }
                }

                NPC targetPet = chr.ActivePet;

                if (targetPet == null) //no pet
                {
                    packet.Write((byte)0); //name
                    packet.Write(0UL); //auras
                    client.Send(packet);
                    return;
                }

                if (flags.HasFlag(GroupUpdateFlags.PetGuid))
                {
                    packet.Write(targetPet.EntityId);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetName))
                {
                    packet.WriteCString(targetPet.Name);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetDisplayId))
                {
                    packet.Write((ushort)targetPet.DisplayId);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetHealth))
                {
                    packet.Write(targetPet.Health);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetMaxHealth))
                {
                    packet.Write(targetPet.MaxHealth);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetPowerType))
                {
                    packet.Write((byte)targetPet.PowerType);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetPower))
                {
                    packet.Write((ushort)targetPet.Power);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetMaxPower))
                {
                    packet.Write((ushort)targetPet.MaxPower);
                }

                if (flags.HasFlag(GroupUpdateFlags.PetAuras))
                {
                    ulong auraMask = targetPet.AuraUpdateMask;
                    packet.Write(auraMask);
                    Aura currAura;

                    for (byte i = 0; i < AuraHandler.MaxAuras; ++i)
                    {
                        if ((auraMask & ((ulong)1 << i)) != 0)
                        {
                            currAura = targetPet.Auras.GetAt(i);//chr.Auras.GetAt(i);

                            packet.Write(currAura.Spell.Id);
                            packet.Write((byte)currAura.Flags);
                        }
                    }
                }
                client.Send(packet);
            }
        }
コード例 #17
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		private void OnLeaderChanged(GroupMember oldLeader)
		{
			// if everyone is offline, the Group has no leader
			if (m_leader != null)
			{
				GroupHandler.SendLeaderChanged(m_leader);
			}

			var evt = LeaderChanged;
			if (evt != null)
			{
				evt(oldLeader, m_leader);
			}
		}
コード例 #18
0
ファイル: RaidGroup.cs プロジェクト: ebakkedahl/WCell
        /// <summary>
        /// Sends a ready check request to the members of the raid group.
        /// </summary>
        /// <param name="member">the member who requested the check</param>
        public void SendReadyCheckRequest(GroupMember member)
        {
            m_readyCheckRequester = member;

            using (var packet = new RealmPacketOut(RealmServerOpCode.MSG_RAID_READY_CHECK))
            {
                packet.Write(EntityId.GetPlayerId(member.Id));

                SendAll(packet, member);
            }
        }
コード例 #19
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		protected Group(Character leader, byte maxGroupUnits)
		{
			// m_syncLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
			m_syncLock = new ReaderWriterLockSlim();
			m_subGroups = new SubGroup[maxGroupUnits];

			for (byte i = 0; i < maxGroupUnits; i++)
			{
				m_subGroups[i] = new SubGroup(this, i);
			}

			m_targetIcons = new EntityId[TargetIconCount];
			for (int i = 0; i < m_targetIcons.Length; i++)
				m_targetIcons[i] = EntityId.Zero;

			m_lootMethod = LootMethod.GroupLoot;
			m_lootThreshold = ItemQuality.Uncommon;
			m_DungeonDifficulty = 0;

			var member = AddMember(leader, false);
			Leader = member;
			m_masterLooter = null;
			// update will follow when the 2nd guy joins
		}
コード例 #20
0
ファイル: RaidGroup.cs プロジェクト: ebakkedahl/WCell
 /// <summary>
 /// Creates a raid group with the given character as the leader.
 /// </summary>
 /// <param name="leader">the character to be the leader</param>
 public RaidGroup(Character leader)
     : base(leader, MaxSubGroupCount)
 {
     m_readyCheckRequester = null;
 }
コード例 #21
0
ファイル: Group.cs プロジェクト: ray2006/WCell
		/// <summary>
		/// Send a packet to each group member except one specified
		/// </summary>
		/// <param name="packet">Realm Packet</param>
		/// <param name="ignored">Member that won't receive the message</param>
		protected virtual void SendAll(RealmPacketOut packet, GroupMember ignored)
		{
			foreach (var groupUnit in m_subGroups)
			{
				groupUnit.Send(packet, ignored);
			}
		}