/* * Copyright (C) 2012-2017 CypherCore * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using Framework.Collections; using Framework.Constants; using Framework.Database; using Game.DataStorage; using Game.Entities; using Game.Maps; using Game.Network.Packets; using System; using System.Collections.Generic; using System.Linq; namespace Game.Chat { public class Channel { public Channel(uint channelId, Team team = 0, AreaTableRecord zoneEntry = null) { _channelFlags = ChannelFlags.General; _channelId = channelId; _channelTeam = team; _zoneEntry = zoneEntry; ChatChannelsRecord channelEntry = CliDB.ChatChannelsStorage.LookupByKey(channelId); if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Trade)) // for trade channel _channelFlags |= ChannelFlags.Trade; if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly2)) // for city only channels _channelFlags |= ChannelFlags.City; if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Lfg)) // for LFG channel _channelFlags |= ChannelFlags.Lfg; else // for all other channels _channelFlags |= ChannelFlags.NotLfg; } public Channel(string name, Team team = 0) { _announceEnabled = true; _ownershipEnabled = true; _channelFlags = ChannelFlags.Custom; _channelTeam = team; _channelName = name; // If storing custom channels in the db is enabled either load or save the channel if (WorldConfig.GetBoolValue(WorldCfg.PreserveCustomChannels)) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHANNEL); stmt.AddValue(0, _channelName); stmt.AddValue(1, _channelTeam); SQLResult result = DB.Characters.Query(stmt); if (!result.IsEmpty()) //load { _channelName = result.Read(0); // re-get channel name. MySQL table collation is case insensitive _announceEnabled = result.Read(1); _ownershipEnabled = result.Read(2); _channelPassword = result.Read(3); string bannedList = result.Read(4); if (string.IsNullOrEmpty(bannedList)) { var tokens = new StringArray(bannedList, ' '); for (var i = 0; i < tokens.Length; ++i) { ObjectGuid bannedGuid = new ObjectGuid(); if (ulong.TryParse(tokens[i].Substring(0, 16), out ulong highguid) && ulong.TryParse(tokens[i].Substring(16), out ulong lowguid)) bannedGuid.SetRawValue(highguid, lowguid); if (!bannedGuid.IsEmpty()) { Log.outDebug(LogFilter.ChatSystem, "Channel({0}) loaded bannedStore guid:{1}", _channelName, bannedGuid); _bannedStore.Add(bannedGuid); } } } } else // save { stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_CHANNEL); stmt.AddValue(0, _channelName); stmt.AddValue(1, _channelTeam); DB.Characters.Execute(stmt); Log.outDebug(LogFilter.ChatSystem, "Channel({0}) saved in database", _channelName); } _persistentChannel = true; } } public static void GetChannelName(ref string channelName, uint channelId, LocaleConstant locale, AreaTableRecord zoneEntry) { if (channelId != 0) { ChatChannelsRecord channelEntry = CliDB.ChatChannelsStorage.LookupByKey(channelId); if (!channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Global)) { if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly)) channelName = string.Format(channelEntry.Name[locale].ConvertFormatSyntax(), Global.ObjectMgr.GetCypherString(CypherStrings.ChannelCity, locale)); else channelName = string.Format(channelEntry.Name[locale].ConvertFormatSyntax(), zoneEntry.AreaName[locale]); } else channelName = channelEntry.Name[locale]; } } public string GetName(LocaleConstant locale = LocaleConstant.enUS) { string result = _channelName; GetChannelName(ref result, _channelId, locale, _zoneEntry); return result; } void UpdateChannelInDB() { if (_persistentChannel) { string banlist = ""; foreach (var iter in _bannedStore) banlist += iter.GetRawValue().ToHexString() + ' '; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHANNEL); stmt.AddValue(0, _announceEnabled); stmt.AddValue(1, _ownershipEnabled); stmt.AddValue(2, _channelPassword); stmt.AddValue(3, banlist); stmt.AddValue(4, _channelName); stmt.AddValue(5, _channelTeam); DB.Characters.Execute(stmt); Log.outDebug(LogFilter.ChatSystem, "Channel({0}) updated in database", _channelName); } } void UpdateChannelUseageInDB() { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHANNEL_USAGE); stmt.AddValue(0, _channelName); stmt.AddValue(1, _channelTeam); DB.Characters.Execute(stmt); } public static void CleanOldChannelsInDB() { if (WorldConfig.GetIntValue(WorldCfg.PreserveCustomChannelDuration) > 0) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_OLD_CHANNELS); stmt.AddValue(0, WorldConfig.GetIntValue(WorldCfg.PreserveCustomChannelDuration) * Time.Day); DB.Characters.Execute(stmt); Log.outDebug(LogFilter.ChatSystem, "Cleaned out unused custom chat channels."); } } public void JoinChannel(Player player, string pass) { ObjectGuid guid = player.GetGUID(); if (IsOn(guid)) { // Do not send error message for built-in channels if (!IsConstant()) { var builder = new ChannelNameBuilder(this, new PlayerAlreadyMemberAppend(guid)); SendToOne(builder, guid); } return; } if (IsBanned(guid)) { var builder = new ChannelNameBuilder(this, new BannedAppend()); SendToOne(builder, guid); return; } if (!string.IsNullOrEmpty(_channelPassword) && pass != _channelPassword) { var builder = new ChannelNameBuilder(this, new WrongPasswordAppend()); SendToOne(builder, guid); return; } if (HasFlag(ChannelFlags.Lfg) && WorldConfig.GetBoolValue(WorldCfg.RestrictedLfgChannel) && Global.AccountMgr.IsPlayerAccount(player.GetSession().GetSecurity()) && //FIXME: Move to RBAC player.GetGroup()) { var builder = new ChannelNameBuilder(this, new NotInLFGAppend()); SendToOne(builder, guid); return; } player.JoinedChannel(this); if (_announceEnabled && !player.GetSession().HasPermission(RBACPermissions.SilentlyJoinChannel)) { var builder = new ChannelNameBuilder(this, new JoinedAppend(guid)); SendToAll(builder); } bool newChannel = _playersStore.Empty(); PlayerInfo playerInfo = new PlayerInfo(); playerInfo.SetInvisible(!player.isGMVisible()); _playersStore[guid] = playerInfo; /* ChannelNameBuilder builder = new ChannelNameBuilder(this, new YouJoinedAppend()); SendToOne(builder, guid); */ SendToOne(new ChannelNotifyJoinedBuilder(this), guid); JoinNotify(player); // Custom channel handling if (!IsConstant()) { // Update last_used timestamp in db if (!_playersStore.Empty()) UpdateChannelUseageInDB(); // If the channel has no owner yet and ownership is allowed, set the new owner. // or if the owner was a GM with .gm visible off // don't do this if the new player is, too, an invis GM, unless the channel was empty if (_ownershipEnabled && (newChannel || !playerInfo.IsInvisible()) && (_ownerGuid.IsEmpty() || _isOwnerInvisible)) { _isOwnerInvisible = playerInfo.IsInvisible(); SetOwner(guid, !newChannel && !_isOwnerInvisible); _playersStore[guid].SetModerator(true); } } } public void LeaveChannel(Player player, bool send = true) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { if (send) { var builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); } return; } player.LeftChannel(this); if (send) { /* ChannelNameBuilder builder = new ChannelNameBuilder(this, new YouLeftAppend()); SendToOne(builder, guid); */ SendToOne(new ChannelNotifyLeftBuilder(this), guid); } PlayerInfo info = _playersStore.LookupByKey(guid); bool changeowner = info.IsOwner(); _playersStore.Remove(guid); if (_announceEnabled && !player.GetSession().HasPermission(RBACPermissions.SilentlyJoinChannel)) { var builder = new ChannelNameBuilder(this, new LeftAppend(guid)); SendToAll(builder); } LeaveNotify(player); if (!IsConstant()) { // Update last_used timestamp in db UpdateChannelUseageInDB(); // If the channel owner left and there are still playersStore inside, pick a new owner // do not pick invisible gm owner unless there are only invisible gms in that channel (rare) if (changeowner && _ownershipEnabled && !_playersStore.Empty()) { ObjectGuid newowner = ObjectGuid.Empty; foreach (var key in _playersStore.Keys) { if (!_playersStore[key].IsInvisible()) { newowner = key; break; } } if (newowner.IsEmpty()) newowner = _playersStore.First().Key; _playersStore[newowner].SetModerator(true); SetOwner(newowner); // if the new owner is invisible gm, set flag to automatically choose a new owner if (_playersStore[newowner].IsInvisible()) _isOwnerInvisible = true; } } } void KickOrBan(Player player, string badname, bool ban) { ObjectGuid good = player.GetGUID(); if (!IsOn(good)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, good); return; } PlayerInfo info = _playersStore.LookupByKey(good); if (!info.IsModerator() && !player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotModeratorAppend()); SendToOne(builder, good); return; } Player bad = Global.ObjAccessor.FindPlayerByName(badname); ObjectGuid victim = bad ? bad.GetGUID() : ObjectGuid.Empty; if (victim.IsEmpty() || !IsOn(victim)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerNotFoundAppend(badname)); SendToOne(builder, good); return; } bool changeowner = _ownerGuid == victim; if (!player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator) && changeowner && good != _ownerGuid) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotOwnerAppend()); SendToOne(builder, good); return; } if (ban && !IsBanned(victim)) { _bannedStore.Add(victim); UpdateChannelInDB(); if (!player.GetSession().HasPermission(RBACPermissions.SilentlyJoinChannel)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerBannedAppend(good, victim)); SendToAll(builder); } } else if (!player.GetSession().HasPermission(RBACPermissions.SilentlyJoinChannel)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerKickedAppend(good, victim)); SendToAll(builder); } _playersStore.Remove(victim); bad.LeftChannel(this); if (changeowner && _ownershipEnabled && !_playersStore.Empty()) { info.SetModerator(true); SetOwner(good); } } public void UnBan(Player player, string badname) { ObjectGuid good = player.GetGUID(); if (!IsOn(good)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, good); return; } PlayerInfo info = _playersStore.LookupByKey(good); if (!info.IsModerator() && !player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotModeratorAppend()); SendToOne(builder, good); return; } Player bad = Global.ObjAccessor.FindPlayerByName(badname); ObjectGuid victim = bad ? bad.GetGUID() : ObjectGuid.Empty; if (victim.IsEmpty() || !IsBanned(victim)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerNotFoundAppend(badname)); SendToOne(builder, good); return; } _bannedStore.Remove(victim); ChannelNameBuilder builder1 = new ChannelNameBuilder(this, new PlayerUnbannedAppend(good, victim)); SendToAll(builder1); UpdateChannelInDB(); } public void Password(Player player, string pass) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } PlayerInfo info = _playersStore.LookupByKey(guid); if (!info.IsModerator() && !player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotModeratorAppend()); SendToOne(builder, guid); return; } _channelPassword = pass; ChannelNameBuilder builder1 = new ChannelNameBuilder(this, new PasswordChangedAppend(guid)); SendToAll(builder1); UpdateChannelInDB(); } void SetMode(Player player, string p2n, bool mod, bool set) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } PlayerInfo info = _playersStore.LookupByKey(guid); if (!info.IsModerator() && !player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotModeratorAppend()); SendToOne(builder, guid); return; } if (guid == _ownerGuid && p2n == player.GetName() && mod) return; Player newp = Global.ObjAccessor.FindPlayerByName(p2n); ObjectGuid victim = newp ? newp.GetGUID() : ObjectGuid.Empty; if (victim.IsEmpty() || !IsOn(victim) || (player.GetTeam() != newp.GetTeam() && (!player.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel) || !newp.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel)))) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerNotFoundAppend(p2n)); SendToOne(builder, guid); return; } if (_ownerGuid == victim && _ownerGuid != guid) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotOwnerAppend()); SendToOne(builder, guid); return; } if (mod) SetModerator(newp.GetGUID(), set); else SetMute(newp.GetGUID(), set); } public void SetInvisible(Player player, bool on) { var playerInfo = _playersStore.LookupByKey(player.GetGUID()); if (playerInfo == null) return; playerInfo.SetInvisible(on); // we happen to be owner too, update flag if (_ownerGuid == player.GetGUID()) _isOwnerInvisible = on; } public void SetOwner(Player player, string newname) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } if (!player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator) && guid != _ownerGuid) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotOwnerAppend()); SendToOne(builder, guid); return; } Player newp = Global.ObjAccessor.FindPlayerByName(newname); ObjectGuid victim = newp ? newp.GetGUID() : ObjectGuid.Empty; if (victim.IsEmpty() || !IsOn(victim) || (player.GetTeam() != newp.GetTeam() && (!player.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel) || !newp.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel)))) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerNotFoundAppend(newname)); SendToOne(builder, guid); return; } _playersStore[victim].SetModerator(true); SetOwner(victim); } public void SendWhoOwner(Player player) { ObjectGuid guid = player.GetGUID(); if (IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new ChannelOwnerAppend(this, _ownerGuid)); SendToOne(builder, guid); } else { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); } } public void List(Player player) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } string channelName = GetName(player.GetSession().GetSessionDbcLocale()); Log.outDebug(LogFilter.ChatSystem, "SMSG_CHANNEL_LIST {0} Channel: {1}", player.GetSession().GetPlayerInfo(), channelName); ChannelListResponse list = new ChannelListResponse(); list.Display = true; /// always true? list.Channel = channelName; list.ChannelFlags = GetFlags(); uint gmLevelInWhoList = WorldConfig.GetUIntValue(WorldCfg.GmLevelInWhoList); foreach (var pair in _playersStore) { Player member = Global.ObjAccessor.FindConnectedPlayer(pair.Key); // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all if (member && (player.GetSession().HasPermission(RBACPermissions.WhoSeeAllSecLevels) || member.GetSession().GetSecurity() <= (AccountTypes)gmLevelInWhoList) && member.IsVisibleGloballyFor(player)) { list.Members.Add(new ChannelListResponse.ChannelPlayer(pair.Key, Global.WorldMgr.GetVirtualRealmAddress(), pair.Value.GetFlags())); } } player.SendPacket(list); } public void Announce(Player player) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } PlayerInfo playerInfo = _playersStore.LookupByKey(guid); if (!playerInfo.IsModerator() && !player.GetSession().HasPermission(RBACPermissions.ChangeChannelNotModerator)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotModeratorAppend()); SendToOne(builder, guid); return; } _announceEnabled = !_announceEnabled; if (_announceEnabled) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new AnnouncementsOnAppend(guid)); SendToAll(builder); } else { ChannelNameBuilder builder = new ChannelNameBuilder(this, new AnnouncementsOffAppend(guid)); SendToAll(builder); } UpdateChannelInDB(); } public void Say(ObjectGuid guid, string what, Language lang) { if (string.IsNullOrEmpty(what)) return; // TODO: Add proper RBAC check if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionChannel)) lang = Language.Universal; if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } PlayerInfo playerInfo = _playersStore.LookupByKey(guid); if (playerInfo.IsMuted()) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new MutedAppend()); SendToOne(builder, guid); return; } SendToAll(new ChannelSayBuilder(this, lang, what, guid), !playerInfo.IsModerator() ? guid : ObjectGuid.Empty); } public void AddonSay(ObjectGuid guid, string prefix, string what) { if (what.IsEmpty()) return; if (!IsOn(guid)) { NotMemberAppend appender; ChannelNameBuilder builder = new ChannelNameBuilder(this, appender); SendToOne(builder, guid); return; } PlayerInfo playerInfo = _playersStore.LookupByKey(guid); if (playerInfo.IsMuted()) { MutedAppend appender; ChannelNameBuilder builder = new ChannelNameBuilder(this, appender); SendToOne(builder, guid); return; } SendToAllWithAddon(new ChannelWhisperBuilder(this, Language.Addon, what, prefix, guid), prefix, !playerInfo.IsModerator() ? guid : ObjectGuid.Empty); } public void Invite(Player player, string newname) { ObjectGuid guid = player.GetGUID(); if (!IsOn(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new NotMemberAppend()); SendToOne(builder, guid); return; } Player newp = Global.ObjAccessor.FindPlayerByName(newname); if (!newp || !newp.isGMVisible()) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerNotFoundAppend(newname)); SendToOne(builder, guid); return; } if (IsBanned(newp.GetGUID())) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerInviteBannedAppend(newname)); SendToOne(builder, guid); return; } if (newp.GetTeam() != player.GetTeam() && (!player.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel) || !newp.GetSession().HasPermission(RBACPermissions.TwoSideInteractionChannel))) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new InviteWrongFactionAppend()); SendToOne(builder, guid); return; } if (IsOn(newp.GetGUID())) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new PlayerAlreadyMemberAppend(newp.GetGUID())); SendToOne(builder, guid); return; } if (!newp.GetSocial().HasIgnore(guid)) { ChannelNameBuilder builder = new ChannelNameBuilder(this, new InviteAppend(guid)); SendToOne(builder, newp.GetGUID()); } ChannelNameBuilder builder1 = new ChannelNameBuilder(this, new PlayerInvitedAppend(newp.GetName())); SendToOne(builder1, guid); } public void SetOwner(ObjectGuid guid, bool exclaim = true) { if (!_ownerGuid.IsEmpty()) { // [] will re-add player after it possible removed var playerInfo = _playersStore.LookupByKey(_ownerGuid); if (playerInfo != null) playerInfo.SetOwner(false); } _ownerGuid = guid; if (!_ownerGuid.IsEmpty()) { ChannelMemberFlags oldFlag = GetPlayerFlags(_ownerGuid); var playerInfo = _playersStore.LookupByKey(_ownerGuid); if (playerInfo == null) return; playerInfo.SetModerator(true); playerInfo.SetOwner(true); ChannelNameBuilder builder = new ChannelNameBuilder(this, new ModeChangeAppend(_ownerGuid, oldFlag, GetPlayerFlags(_ownerGuid))); SendToAll(builder); if (exclaim) { ChannelNameBuilder ownerChangedBuilder = new ChannelNameBuilder(this, new OwnerChangedAppend(_ownerGuid)); SendToAll(ownerChangedBuilder); } UpdateChannelInDB(); } } public void SilenceAll(Player player, string name) { } public void UnsilenceAll(Player player, string name) { } public void DeclineInvite(Player player) { } void JoinNotify(Player player) { ObjectGuid guid = player.GetGUID(); if (IsConstant()) SendToAllButOne(new ChannelUserlistAddBuilder(this, guid), guid); else SendToAll(new ChannelUserlistUpdateBuilder(this, guid)); } void LeaveNotify(Player player) { ObjectGuid guid = player.GetGUID(); var builder = new ChannelUserlistRemoveBuilder(this, guid); if (IsConstant()) SendToAllButOne(builder, guid); else SendToAll(builder); } void SetModerator(ObjectGuid guid, bool set) { if (!IsOn(guid)) return; PlayerInfo playerInfo = _playersStore.LookupByKey(guid); if (playerInfo.IsModerator() != set) { ChannelMemberFlags oldFlag = _playersStore[guid].GetFlags(); playerInfo.SetModerator(set); ChannelNameBuilder builder = new ChannelNameBuilder(this, new ModeChangeAppend(guid, oldFlag, playerInfo.GetFlags())); SendToAll(builder); } } void SetMute(ObjectGuid guid, bool set) { if (!IsOn(guid)) return; PlayerInfo playerInfo = _playersStore.LookupByKey(guid); if (playerInfo.IsMuted() != set) { ChannelMemberFlags oldFlag = _playersStore[guid].GetFlags(); playerInfo.SetMuted(set); ChannelNameBuilder builder = new ChannelNameBuilder(this, new ModeChangeAppend(guid, oldFlag, playerInfo.GetFlags())); SendToAll(builder); } } void SendToAll(MessageBuilder builder, ObjectGuid guid = default(ObjectGuid)) { LocalizedPacketDo localizer = new LocalizedPacketDo(builder); foreach (var pair in _playersStore) { Player player = Global.ObjAccessor.FindConnectedPlayer(pair.Key); if (player) if (guid.IsEmpty() || !player.GetSocial().HasIgnore(guid)) localizer.Invoke(player); } } void SendToAllButOne(MessageBuilder builder, ObjectGuid who) { LocalizedPacketDo localizer = new LocalizedPacketDo(builder); foreach (var pair in _playersStore) { if (pair.Key != who) { Player player = Global.ObjAccessor.FindConnectedPlayer(pair.Key); if (player) localizer.Invoke(player); } } } void SendToOne(MessageBuilder builder, ObjectGuid who) { LocalizedPacketDo localizer = new LocalizedPacketDo(builder); Player player = Global.ObjAccessor.FindConnectedPlayer(who); if (player) localizer.Invoke(player); } void SendToAllWithAddon(MessageBuilder builder, string addonPrefix, ObjectGuid guid = default(ObjectGuid)) { LocalizedPacketDo localizer = new LocalizedPacketDo(builder); foreach (var pair in _playersStore) { Player player = Global.ObjAccessor.FindConnectedPlayer(pair.Key); if (player) if (player.GetSession().IsAddonRegistered(addonPrefix) && (guid.IsEmpty() || !player.GetSocial().HasIgnore(guid))) localizer.Invoke(player); } } public uint GetChannelId() { return _channelId; } public bool IsConstant() { return _channelId != 0; } public bool IsLFG() { return GetFlags().HasAnyFlag(ChannelFlags.Lfg); } bool IsAnnounce() { return _announceEnabled; } void SetAnnounce(bool nannounce) { _announceEnabled = nannounce; } string GetPassword() { return _channelPassword; } void SetPassword(string npassword) { _channelPassword = npassword; } public uint GetNumPlayers() { return (uint)_playersStore.Count; } public ChannelFlags GetFlags() { return _channelFlags; } bool HasFlag(ChannelFlags flag) { return _channelFlags.HasAnyFlag(flag); } public AreaTableRecord GetZoneEntry() { return _zoneEntry; } public void Kick(Player player, string badname) { KickOrBan(player, badname, false); } public void Ban(Player player, string badname) { KickOrBan(player, badname, true); } public void SetModerator(Player player, string newname) { SetMode(player, newname, true, true); } public void UnsetModerator(Player player, string newname) { SetMode(player, newname, true, false); } public void SetMute(Player player, string newname) { SetMode(player, newname, false, true); } public void UnsetMute(Player player, string newname) { SetMode(player, newname, false, false); } public void SetOwnership(bool ownership) { _ownershipEnabled = ownership; } bool IsOn(ObjectGuid who) { return _playersStore.ContainsKey(who); } bool IsBanned(ObjectGuid guid) { return _bannedStore.Contains(guid); } public ChannelMemberFlags GetPlayerFlags(ObjectGuid guid) { var info = _playersStore.LookupByKey(guid); return info != null ? info.GetFlags() : 0; } bool _announceEnabled; bool _ownershipEnabled; bool _persistentChannel; bool _isOwnerInvisible; ChannelFlags _channelFlags; uint _channelId; Team _channelTeam; ObjectGuid _ownerGuid; string _channelName; string _channelPassword; Dictionary _playersStore = new Dictionary(); List _bannedStore = new List(); AreaTableRecord _zoneEntry; public class PlayerInfo { public ChannelMemberFlags GetFlags() { return flags; } public bool IsInvisible() { return _invisible; } public void SetInvisible(bool on) { _invisible = on; } public bool HasFlag(ChannelMemberFlags flag) { return flags.HasAnyFlag(flag); } public void SetFlag(ChannelMemberFlags flag) { flags |= flag; } public void RemoveFlag(ChannelMemberFlags flag) { flags &= ~flag; } public bool IsOwner() { return HasFlag(ChannelMemberFlags.Owner); } public void SetOwner(bool state) { if (state) SetFlag(ChannelMemberFlags.Owner); else RemoveFlag(ChannelMemberFlags.Owner); } public bool IsModerator() { return HasFlag(ChannelMemberFlags.Moderator); } public void SetModerator(bool state) { if (state) SetFlag(ChannelMemberFlags.Moderator); else RemoveFlag(ChannelMemberFlags.Moderator); } public bool IsMuted() { return HasFlag(ChannelMemberFlags.Muted); } public void SetMuted(bool state) { if (state) SetFlag(ChannelMemberFlags.Muted); else RemoveFlag(ChannelMemberFlags.Muted); } ChannelMemberFlags flags; bool _invisible; } } }