From d68f52bdc399df4fe70a69200beb2d80fc56d4e8 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Thu, 1 Feb 2024 10:10:38 -0500 Subject: [PATCH] Core/Chat: Corrected chat channel flag implementations Port From (https://github.com/TrinityCore/TrinityCore/commit/d2baaac9ec9c0b0839d5868d9666aa0901031b28) --- Source/Framework/Constants/ChatConst.cs | 18 ++--------- Source/Framework/Constants/CliDBConst.cs | 33 ++++++++++++++++++++ Source/Game/Chat/Channels/Channel.cs | 16 +++++----- Source/Game/Chat/Channels/ChannelManager.cs | 31 +++++++++--------- Source/Game/DataStorage/Structs/C_Records.cs | 7 +++-- Source/Game/Entities/Player/Player.Map.cs | 12 +++++-- Source/Game/Entities/Player/Player.cs | 21 ++++++++----- Source/Game/Handlers/ChatHandler.cs | 4 +++ 8 files changed, 91 insertions(+), 51 deletions(-) diff --git a/Source/Framework/Constants/ChatConst.cs b/Source/Framework/Constants/ChatConst.cs index bf172af6e..b4cce4f2d 100644 --- a/Source/Framework/Constants/ChatConst.cs +++ b/Source/Framework/Constants/ChatConst.cs @@ -1,6 +1,8 @@ // Copyright (c) CypherCore All rights reserved. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. +using System; + namespace Framework.Constants { public enum ChatNotify @@ -65,22 +67,6 @@ namespace Framework.Constants // LookingForGroup 0x50 = 0x40 | 0x10 } - public enum ChannelDBCFlags - { - None = 0x00000, - Initial = 0x00001, // General, Trade, Localdefense, Lfg - ZoneDep = 0x00002, // General, Trade, Localdefense, Guildrecruitment - Global = 0x00004, // Worlddefense - Trade = 0x00008, // Trade, Lfg - CityOnly = 0x00010, // Trade, Guildrecruitment, Lfg - CityOnly2 = 0x00020, // Trade, Guildrecruitment, Lfg - Defense = 0x10000, // Localdefense, Worlddefense - GuildReq = 0x20000, // Guildrecruitment - Lfg = 0x40000, // Lfg - Unk1 = 0x80000, // General - NoClientJoin = 0x200000 - } - public enum ChannelMemberFlags { None = 0x00, diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index 7157c15c1..8a6b5c29a 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -1079,6 +1079,7 @@ namespace Framework.Constants Factional = 0x40 } + [Flags] public enum CfgCategoriesCharsets { Any = 0x00, @@ -1089,12 +1090,44 @@ namespace Framework.Constants Chinese = 0x10 } + [Flags] public enum CfgCategoriesFlags { None = 0x0, Tournament = 0x1 } + [Flags] + public enum ChatChannelFlags + { + None = 0x00, + AutoJoin = 0x01, + ZoneBased = 0x02, + ReadOnly = 0x04, + AllowItemLinks = 0x08, + OnlyInCities = 0x10, + LinkedChannel = 0x20, + ZoneAttackAlerts = 0x10000, + GuildRecruitment = 0x20000, + LookingForGroup = 0x40000, + GlobalForTournament = 0x80000, + DisableRaidIcons = 0x100000, + Regional = 0x200000 + } + + public enum ChatChannelRuleset + { + None = 0, + Mentor = 1, + Disabled = 2, + ChromieTimeCataclysm = 3, + ChromieTimeBuringCrusade = 4, + ChromieTimeWrath = 5, + ChromieTimeMists = 6, + ChromieTimeWoD = 7, + ChromieTimeLegion = 8, + } + [Flags] public enum ChrRacesFlag { diff --git a/Source/Game/Chat/Channels/Channel.cs b/Source/Game/Chat/Channels/Channel.cs index 3183f8d35..439a56fec 100644 --- a/Source/Game/Chat/Channels/Channel.cs +++ b/Source/Game/Chat/Channels/Channel.cs @@ -25,13 +25,13 @@ namespace Game.Chat _zoneEntry = zoneEntry; ChatChannelsRecord channelEntry = CliDB.ChatChannelsStorage.LookupByKey(channelId); - if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Trade)) // for trade channel + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.AllowItemLinks)) // for trade channel _channelFlags |= ChannelFlags.Trade; - if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly2)) // for city only channels + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.LinkedChannel)) // for city only channels _channelFlags |= ChannelFlags.City; - if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Lfg)) // for LFG channel + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.LookingForGroup)) // for LFG channel _channelFlags |= ChannelFlags.Lfg; else // for all other channels _channelFlags |= ChannelFlags.NotLfg; @@ -66,12 +66,12 @@ namespace Game.Chat if (channelId != 0) { ChatChannelsRecord channelEntry = CliDB.ChatChannelsStorage.LookupByKey(channelId); - if (!channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Global)) + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.ZoneBased)) { - 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]); + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.LinkedChannel)) + zoneEntry = ChannelManager.SpecialLinkedArea; + + channelName = string.Format(channelEntry.Name[locale].ConvertFormatSyntax(), zoneEntry?.AreaName[locale]); } else channelName = channelEntry.Name[locale]; diff --git a/Source/Game/Chat/Channels/ChannelManager.cs b/Source/Game/Chat/Channels/ChannelManager.cs index adcd2b96e..175249092 100644 --- a/Source/Game/Chat/Channels/ChannelManager.cs +++ b/Source/Game/Chat/Channels/ChannelManager.cs @@ -13,6 +13,8 @@ namespace Game.Chat { public class ChannelManager { + public static AreaTableRecord SpecialLinkedArea { get; private set; } + public ChannelManager(Team team) { _team = team; @@ -21,6 +23,9 @@ namespace Game.Chat public static void LoadFromDB() { + SpecialLinkedArea = CliDB.AreaTableStorage.LookupByKey(3459); + Cypher.Assert(SpecialLinkedArea.GetFlags().HasFlag(AreaFlags.LinkedChatSpecialArea)); + if (!WorldConfig.GetBoolValue(WorldCfg.PreserveCustomChannels)) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 custom chat channels. Custom channel saving is disabled."); @@ -212,25 +217,19 @@ namespace Game.Chat ObjectGuid CreateBuiltinChannelGuid(uint channelId, AreaTableRecord zoneEntry = null) { - ChatChannelsRecord channelEntry = CliDB.ChatChannelsStorage.LookupByKey(channelId); - uint zoneId = zoneEntry != null ? zoneEntry.Id : 0; - if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Global | ChannelDBCFlags.CityOnly)) - zoneId = 0; + uint zoneId = 0; + if (zoneEntry != null && channelEntry.GetFlags().HasFlag(ChatChannelFlags.ZoneBased) && !channelEntry.GetFlags().HasFlag(ChatChannelFlags.LinkedChannel)) + zoneId = zoneEntry.Id; - ulong high = 0; - high |= (ulong)HighGuid.ChatChannel << 58; - high |= (ulong)Global.WorldMgr.GetRealmId().Index << 42; - high |= 1ul << 25; // built-in - if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly2)) - high |= 1ul << 24; // trade + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.GlobalForTournament)) + { + var category = CliDB.CfgCategoriesStorage.LookupByKey(Global.WorldMgr.GetRealm().Timezone); + if (category != null && category.GetFlags().HasFlag(CfgCategoriesFlags.Tournament)) + zoneId = 0; + } - high |= (ulong)(zoneId) << 10; - high |= (ulong)(_team == Team.Alliance ? 3 : 5) << 4; - - ObjectGuid channelGuid = new(); - channelGuid.SetRawValue(high, channelId); - return channelGuid; + return ObjectGuid.Create(HighGuid.ChatChannel, true, channelEntry.GetFlags().HasFlag(ChatChannelFlags.LinkedChannel), (ushort)zoneId, (byte)(_team == Team.Alliance ? 3 : 5), channelId); } Dictionary _customChannels = new(); diff --git a/Source/Game/DataStorage/Structs/C_Records.cs b/Source/Game/DataStorage/Structs/C_Records.cs index b6ebb0547..5dc29f68d 100644 --- a/Source/Game/DataStorage/Structs/C_Records.cs +++ b/Source/Game/DataStorage/Structs/C_Records.cs @@ -20,7 +20,7 @@ namespace Game.DataStorage public CfgCategoriesCharsets GetExistingCharsetMask() { return (CfgCategoriesCharsets)ExistingCharsetMask; } public CfgCategoriesFlags GetFlags() { return (CfgCategoriesFlags)Flags; } } - + public sealed class Cfg_RegionsRecord { public uint Id; @@ -75,9 +75,12 @@ namespace Game.DataStorage public uint Id; public LocalizedString Name; public string Shortcut; - public ChannelDBCFlags Flags; + public int Flags; public sbyte FactionGroup; public int Ruleset; + + public ChatChannelFlags GetFlags() { return (ChatChannelFlags)Flags; } + public ChatChannelRuleset GetRuleset() { return (ChatChannelRuleset)Ruleset; } } public sealed class ChrClassUIDisplayRecord diff --git a/Source/Game/Entities/Player/Player.Map.cs b/Source/Game/Entities/Player/Player.Map.cs index d29dc89f4..4ce98c0ac 100644 --- a/Source/Game/Entities/Player/Player.Map.cs +++ b/Source/Game/Entities/Player/Player.Map.cs @@ -93,8 +93,10 @@ namespace Game.Entities { // FFA_PVP flags are area and not zone id dependent // so apply them accordingly + uint oldArea = m_areaUpdateId; m_areaUpdateId = newArea; + AreaTableRecord oldAreaEntry = CliDB.AreaTableStorage.LookupByKey(oldArea); AreaTableRecord area = CliDB.AreaTableStorage.LookupByKey(newArea); bool oldFFAPvPArea = pvpInfo.IsInFFAPvPArea; pvpInfo.IsInFFAPvPArea = area != null && area.GetFlags().HasFlag(AreaFlags.FreeForAllPvP); @@ -135,6 +137,10 @@ namespace Game.Entities UpdateCriteria(CriteriaType.EnterTopLevelArea, newArea); UpdateMountCapability(); + + if ((oldAreaEntry != null && oldAreaEntry.GetFlags2().HasFlag(AreaFlags2.UseSubzoneForChatChannel)) + || (area != null && area.GetFlags2().HasFlag(AreaFlags2.UseSubzoneForChatChannel))) + UpdateLocalChannels(newArea); } public void UpdateZone(uint newZone, uint newArea) @@ -201,7 +207,9 @@ namespace Game.Entities AutoUnequipOffhandIfNeed(); // recent client version not send leave/join channel packets for built-in local channels - UpdateLocalChannels(newZone); + var newAreaEntry = CliDB.AreaTableStorage.LookupByKey(newArea); + if (newAreaEntry == null || !newAreaEntry.GetFlags2().HasFlag(AreaFlags2.UseSubzoneForChatChannel)) + UpdateLocalChannels(newZone); UpdateZoneDependentAuras(newZone); @@ -612,7 +620,7 @@ namespace Game.Entities return (instanceLock.GetData().CompletedEncountersMask & (1u << dungeonEncounter.Bit)) != 0; } - + public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, LiquidData newLiquidData) { // process liquid auras using generic unit code diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 06bf82987..5cba0add7 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -2988,28 +2988,34 @@ namespace Game.Entities public bool CanJoinConstantChannelInZone(ChatChannelsRecord channel, AreaTableRecord zone) { - if (channel.Flags.HasAnyFlag(ChannelDBCFlags.ZoneDep) && zone.GetFlags().HasFlag(AreaFlags.NoChatChannels)) + if (channel.GetFlags().HasFlag(ChatChannelFlags.ZoneBased) && zone.GetFlags().HasFlag(AreaFlags.NoChatChannels)) return false; - if (channel.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly) && !zone.GetFlags().HasFlag(AreaFlags.AllowTradeChannel)) + if (channel.GetFlags().HasFlag(ChatChannelFlags.OnlyInCities) && !zone.GetFlags().HasFlag(AreaFlags.AllowTradeChannel)) return false; - if (channel.Flags.HasAnyFlag(ChannelDBCFlags.GuildReq) && GetGuildId() != 0) + if (channel.GetFlags().HasFlag(ChatChannelFlags.GuildRecruitment) && GetGuildId() != 0) return false; - if (channel.Flags.HasAnyFlag(ChannelDBCFlags.NoClientJoin)) + if (channel.GetRuleset() == ChatChannelRuleset.Disabled) + return false; + + if (channel.GetFlags().HasFlag(ChatChannelFlags.Regional)) return false; return true; } + public void JoinedChannel(Channel c) { m_channels.Add(c); } + public void LeftChannel(Channel c) { m_channels.Remove(c); } + public void CleanupChannels() { while (!m_channels.Empty()) @@ -3026,6 +3032,7 @@ namespace Game.Entities } Log.outDebug(LogFilter.ChatSystem, "Player {0}: channels cleaned up!", GetName()); } + void UpdateLocalChannels(uint newZone) { if (GetSession().PlayerLoading() && !IsBeingTeleportedFar()) @@ -3041,7 +3048,7 @@ namespace Game.Entities foreach (var channelEntry in CliDB.ChatChannelsStorage.Values) { - if (!channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Initial)) + if (!channelEntry.GetFlags().HasFlag(ChatChannelFlags.AutoJoin)) continue; Channel usedChannel = null; @@ -3060,9 +3067,9 @@ namespace Game.Entities if (CanJoinConstantChannelInZone(channelEntry, current_zone)) { - if (!channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.Global)) + if (!channelEntry.GetFlags().HasFlag(ChatChannelFlags.ZoneBased)) { - if (channelEntry.Flags.HasAnyFlag(ChannelDBCFlags.CityOnly) && usedChannel != null) + if (channelEntry.GetFlags().HasFlag(ChatChannelFlags.LinkedChannel) && usedChannel != null) continue; // Already on the channel, as city channel names are not changing joinChannel = cMgr.GetSystemChannel(channelEntry.Id, current_zone); diff --git a/Source/Game/Handlers/ChatHandler.cs b/Source/Game/Handlers/ChatHandler.cs index 99ef6fb4a..459409abf 100644 --- a/Source/Game/Handlers/ChatHandler.cs +++ b/Source/Game/Handlers/ChatHandler.cs @@ -334,6 +334,10 @@ namespace Game Channel chn = !channelGuid.IsEmpty() ? ChannelManager.GetChannelForPlayerByGuid(channelGuid, sender) : ChannelManager.GetChannelForPlayerByNamePart(target, sender); if (chn != null) { + var chatChannel = CliDB.ChatChannelsStorage.LookupByKey(chn.GetChannelId()); + if (chatChannel != null && chatChannel.GetFlags().HasFlag(ChatChannelFlags.ReadOnly)) + return; + Global.ScriptMgr.OnPlayerChat(GetPlayer(), type, lang, msg, chn); chn.Say(GetPlayer().GetGUID(), msg, lang); }