Иконка ресурса

FREE ColouredChat : 2.2.7 2.2.7

Нет прав для скачивания
C#:
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using ConVar;
using UnityEngine;
using CompanionServer;
namespace Oxide.Plugins {
    [Info("Coloured Chat", "collect_vood", "2.2.7")]
    [Description("Allows players to change their name & message colour in chat")]
    class ColouredChat : CovalencePlugin {
        [PluginReference]
        private Plugin BetterChat, BetterChatMute, ZoneManager;
#region Constants
        private const string ColourRegex = "^#(?:[0-9a-fA-f]{3}){1,2}$";
        private const string ChatFormat = "{0}: {1}";
#endregion
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string>() {
                {
                    "NoPermission", "You don't have permission to use this command."
                }
                , {
                    "NoPermissionSetOthers", "You don't have permission to set other players {0} colours."
                }
                , {
                    "NoPermissionGradient", "You don't have permission to use {0} gradients."
                }
                , {
                    "NoPermissionRandom", "You don't have permission to use random {0} colours."
                }
                , {
                    "NoPermissionRainbow", "You don't have permission to use the rainbow colours."
                }
                , {
                    "IncorrectGradientUsage", "Incorrect usage! To use gradients please use /{0} gradient hexCode1 hexCode2 ...</color>"
                }
                , {
                    "IncorrectGradientUsageArgs", "Incorrect usage! A gradient requires at least two different valid colours!"
                }
                , {
                    "GradientChanged", "{0} gradient changed to {1}!"
                }
                , {
                    "GradientChangedFor", "{0}'s gradient {1} colour changed to {2}!"
                }
                , {
                    "IncorrectUsage", "Incorrect usage! /{0} <colour>\nFor detailed help do /{1}"
                }
                , {
                    "IncorrectSetUsage", "Incorrect set usage! /{0} set <playerIdOrName> <colourOrColourArgument>\nFor a list of colours do /colours"
                }
                , {
                    "PlayerNotFound", "Player {0} was not found."
                }
                , {
                    "InvalidCharacters", "The character '{0}' is not allowed in colours. Please remove it."
                }
                , {
                    "ColourRemoved", "{0} colour removed!"
                }
                , {
                    "ColourRemovedFor", "{0}'s {1} colour was removed!"
                }
                , {
                    "ColourChanged", "{0} colour changed to <color={1}>{1}</color>!"
                }
                , {
                    "ColourChangedFor", "{0}'s {1} colour changed to <color={2}>{2}</color>!"
                }
                , {
                    "ColoursInfo", "You can only use hexcodes, eg '<color=#ffff94>#ffff94</color>'\nTo remove your colour, use 'clear', 'reset' or 'remove'\n\nAvailable Commands: {0}\n\n{1}"
                }
                , {
                    "InvalidColour", "That colour is not valid. Do /colours for more information on valid colours."
                }
                , {
                    "RndColour", "{0} colour was randomized to <color={1}>{1}</color>"
                }
                , {
                    "RndColourFor", "{0} colour of {1} randomized to <color={2}>{2}</color>."
                }
                , {
                    "RainbowColour", "{0} colour was set to rainbow."
                }
                , {
                    "RainbowColourFor", "{0} colour of {1} set to rainbow."
                }
                , {
                    "IncorrectGroupUsage", "Incorrect group usage! /{0} group <groupName> <colourOrColourArgument>\nFor a list of colours do /colours"
                }
                ,
            }
            , this);
        }
#endregion
#region Config
        private Configuration config;
        private class Configuration {
            //General
            [JsonProperty(PropertyName = "Player Inactivity Data Removal (days)")]
            public int inactivityRemovalTime = 7;
            [JsonProperty(PropertyName = "Block messages of muted players (requires BetterChatMute)")]
            public bool blockChatMute = true;
            [JsonProperty(PropertyName = "Rainbow Colours")]
            public string[] rainbowColours = {
                "#ff0000", "#ffa500", "#ffff94", "#008000", "#0000ff", "#4b0082", "#ee82ee"
            }
            ;
            [JsonProperty(PropertyName = "Blocked Characters")]
            public string[] blockedValues = {
                "{", "}", "size"
            }
            ;
            //Name
            [JsonProperty(PropertyName = "Name colour command")]
            public string nameColourCommand = "colour";
            [JsonProperty(PropertyName = "Name colours command (Help)")]
            public string nameColoursCommand = "colours";
            [JsonProperty(PropertyName = "Name show colour permission")]
            public string namePermShow = "colouredchat.name.show";
            [JsonProperty(PropertyName = "Name use permission")]
            public string namePermUse = "colouredchat.name.use";
            [JsonProperty(PropertyName = "Name use gradient permission")]
            public string namePermGradient = "colouredchat.name.gradient";
            [JsonProperty(PropertyName = "Name default rainbow name permission")]
            public string namePermRainbow = "colouredchat.name.rainbow";
            [JsonProperty(PropertyName = "Name bypass restrictions permission")]
            public string namePermBypass = "colouredchat.name.bypass";
            [JsonProperty(PropertyName = "Name set others colour permission")]
            public string namePermSetOthers = "colouredchat.name.setothers";
            [JsonProperty(PropertyName = "Name get random colour permission")]
            public string namePermRandomColour = "colouredchat.name.random";
            [JsonProperty(PropertyName = "Name use blacklist")]
            public bool nameUseBlacklist = true;
            [JsonProperty(PropertyName = "Name blocked colour hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> nameBlockColoursHex = new List<string> {
                {
                    "#000000"
                }
            }
            ;
            [JsonProperty(PropertyName = "Name blocked colours range hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ColourRange> nameBlacklistedRangeColoursHex = new List<ColourRange> {
                {
                    new ColourRange("#000000", "#000000")
                }
            }
            ;
            [JsonProperty(PropertyName = "Name use whitelist")]
            public bool nameUseWhitelist = false;
            [JsonProperty(PropertyName = "Name whitelisted colours hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> nameWhitelistedColoursHex = new List<string> {
                {
                    "#000000"
                }
            }
            ;
            [JsonProperty(PropertyName = "Name whitelisted colour range hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ColourRange> nameWhitelistedRangeColoursHex = new List<ColourRange> {
                {
                    new ColourRange("#000000", "#FFFFFF")
                }
            }
            ;
            //Message
            [JsonProperty(PropertyName = "Message colour command")]
            public string messageColourCommand = "mcolour";
            [JsonProperty(PropertyName = "Message colours command (Help)")]
            public string messageColoursCommand = "mcolours";
            [JsonProperty(PropertyName = "Message show colour permission")]
            public string messagePermShow = "colouredchat.message.show";
            [JsonProperty(PropertyName = "Message use permission")]
            public string messagePermUse = "colouredchat.message.use";
            [JsonProperty(PropertyName = "Message use gradient permission")]
            public string messagePermGradient = "colouredchat.message.gradient";
            [JsonProperty(PropertyName = "Message default rainbow name permission")]
            public string messagePermRainbow = "colouredchat.message.rainbow";
            [JsonProperty(PropertyName = "Message bypass restrictions permission")]
            public string messagePermBypass = "colouredchat.message.bypass";
            [JsonProperty(PropertyName = "Message set others colour permission")]
            public string messagePermSetOthers = "colouredchat.message.setothers";
            [JsonProperty(PropertyName = "Message get random colour permission")]
            public string messagePermRandomColour = "colouredchat.message.random";
            [JsonProperty(PropertyName = "Message use blacklist")]
            public bool messageUseBlacklist = true;
            [JsonProperty(PropertyName = "Message blocked colours hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> messageBlockColoursHex = new List<string> {
                {
                    "#000000"
                }
            }
            ;
            [JsonProperty(PropertyName = "Message blocked colour range hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ColourRange> messageBlacklistedRangeColoursHex = new List<ColourRange> {
                {
                    new ColourRange("#000000", "#000000")
                }
            }
            ;
            [JsonProperty(PropertyName = "Message use whitelist")]
            public bool messageUseWhitelist = false;
            [JsonProperty(PropertyName = "Message whitelisted colours hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> messageWhitelistedColoursHex = new List<string> {
                {
                    "#000000"
                }
            }
            ;
            [JsonProperty(PropertyName = "Message whitelisted colour range hex", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ColourRange> messageWhitelistedRangeColoursHex = new List<ColourRange> {
                {
                    new ColourRange("#000000", "#FFFFFF")
                }
            }
            ;
        }
        protected override void LoadDefaultConfig() {
            PrintWarning("Creating a new configuration file");
            config = new Configuration();
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            config = Config.ReadObject<Configuration>();
            SaveConfig();
        }
        protected override void SaveConfig() => Config.WriteObject(config);
#region Colour Range Class
        public class ColourRange {
            [JsonProperty(PropertyName = "From")]
            public string _from;
            [JsonProperty(PropertyName = "To")]
            public string _to;
            public ColourRange(string from, string to) {
                _from = from;
                _to = to;
            }
        }
#endregion
#endregion
#region Data
        private Dictionary<string, CachePlayerData> cachedData = new Dictionary<string, CachePlayerData>();
        private StoredData storedData;
        private Dictionary<string, PlayerData> allColourData => storedData.AllColourData;
        private class StoredData {
            public Dictionary<string, PlayerData> AllColourData {
                get;
                private set;
            }
            = new Dictionary<string, PlayerData>();
        }
        private class PlayerData {
            [JsonProperty("Name Colour")]
            public string NameColour = string.Empty;
            [JsonProperty("Name Gradient Args")]
            public string[] NameGradientArgs = null;
            [JsonProperty("Message Colour")]
            public string MessageColour = string.Empty;
            [JsonProperty("Message Gradient Args")]
            public string[] MessageGradientArgs = null;
            [JsonProperty("Last active")]
            public long LastActive = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            public PlayerData() {
            }
            public PlayerData(string nameColour = "", string[] nameGradientArgs = null, string messageColour = "", string[] messageGradientArgs = null) {
                NameColour = nameColour;
                NameGradientArgs = nameGradientArgs;
                MessageColour = messageColour;
                MessageGradientArgs = messageGradientArgs;
            }
            public PlayerData(bool isGroup) {
                LastActive = 0;
            }
        }
        private class CachePlayerData {
            public string NameColourGradient;
            public string PrimaryGroup;
            public CachePlayerData(string nameColourGradient = "", string primaryGroup = "") {
                NameColourGradient = nameColourGradient;
                PrimaryGroup = primaryGroup;
            }
        }
        private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);
        private void OnServerSave() {
            ClearUpData();
            SaveData();
        }
        private void Unload() => SaveData();
        private void ChangeNameColour(string key, string colour, string[] colourArgs) {
            var playerData = new PlayerData(colour, colourArgs);
            if (!allColourData.ContainsKey(key)) allColourData.Add(key, playerData);
            allColourData[key].NameColour = colour;
            allColourData[key].NameGradientArgs = colourArgs;
        }
        private void ChangeMessageColour(string key, string colour, string[] colourArgs) {
            var playerData = new PlayerData(string.Empty, null, colour, colourArgs);
            if (!allColourData.ContainsKey(key)) allColourData.Add(key, playerData);
            allColourData[key].MessageColour = colour;
            allColourData[key].MessageGradientArgs = colourArgs;
        }
#endregion
#region Hooks
        private void Init() {
            if (config.messageUseBlacklist && config.messageUseWhitelist || config.nameUseBlacklist && config.nameUseWhitelist) PrintWarning("You are using both black/- and whitelist! This might cause issues.");
            permission.RegisterPermission(config.namePermShow, this);
            permission.RegisterPermission(config.messagePermShow, this);
            permission.RegisterPermission(config.namePermRainbow, this);
            permission.RegisterPermission(config.messagePermRainbow, this);
            permission.RegisterPermission(config.namePermGradient, this);
            permission.RegisterPermission(config.messagePermGradient, this);
            permission.RegisterPermission(config.namePermUse, this);
            permission.RegisterPermission(config.messagePermUse, this);
            permission.RegisterPermission(config.namePermBypass, this);
            permission.RegisterPermission(config.messagePermBypass, this);
            permission.RegisterPermission(config.namePermSetOthers, this);
            permission.RegisterPermission(config.messagePermSetOthers, this);
            permission.RegisterPermission(config.namePermRandomColour, this);
            permission.RegisterPermission(config.messagePermRandomColour, this);
            AddCovalenceCommand(config.nameColourCommand, nameof(cmdNameColour));
            AddCovalenceCommand(config.nameColoursCommand, nameof(cmdNameColours));
            AddCovalenceCommand(config.messageColourCommand, nameof(cmdMessageColour));
            AddCovalenceCommand(config.messageColoursCommand, nameof(cmdMessageColours));
            storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
            ClearUpData();
        }
        private void OnUserConnected(IPlayer player) {
            if (!allColourData.ContainsKey(player.Id)) return;
            allColourData[player.Id].LastActive = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        }
        private void OnUserDisconnected(IPlayer player) {
            if (!allColourData.ContainsKey(player.Id)) return;
            allColourData[player.Id].LastActive = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        }
        private void OnUserNameUpdated(string id, string oldName, string newName) => ClearCache(id);
        private void OnUserGroupAdded(string id, string groupName) => ClearCache(id);
        private void OnUserGroupRemoved(string id, string groupName) => ClearCache(id);
        private void OnGroupDeleted(string name) => ClearCache();
        private void OnGroupPermissionGranted(string name, string perm) => ClearCache();
        private void OnGroupPermissionRevoked(string name, string perm) => ClearCache();
        private object OnPlayerChat(BasePlayer player, string message, Chat.ChatChannel channel) {
            if (BetterChatIns()) return null;
            if (config.blockChatMute && BetterChatMuteIns()) if (BetterChatMute.Call<bool>("API_IsMuted", player.IPlayer)) return null;
            if (player == null) return null;
            if (ZoneManagerIns() && ZoneManager.Call<bool>("PlayerHasFlag", player, "nochat")) return false;
            if (Chat.serverlog) {
                object[] objArray = new object[] {
                    ConsoleColor.DarkYellow, null, null, null
                }
                ;
                objArray[1] = string.Concat(new object[] {
                    "[", channel, "] ", player.displayName.EscapeRichText(), ": "
                }
                );
                objArray[2] = ConsoleColor.DarkGreen;
                objArray[3] = message;
                ServerConsole.PrintColoured(objArray);
            }
            var colouredChatMessage = FromMessage(player.IPlayer, channel, message);
            var colouredChatMessageDict = colouredChatMessage.ToDictionary();
#region API
            foreach (Plugin plugin in plugins.GetAll()) {
                object obj = plugin.CallHook("OnColouredChat", colouredChatMessageDict);
                if (obj is Dictionary<string, object>) {
                    try {
                        colouredChatMessageDict = obj as Dictionary<string, object>;
                    }
                    catch (Exception e) {
                        PrintError($"Failed to load modified OnColouredChat hook data from plugin '{plugin.Title} ({plugin.Version})':{Environment.NewLine}{e}");
                        continue;
                    }
                }
                else if (obj != null) return obj;
            }
            colouredChatMessage = ColouredChatMessage.FromDictionary(colouredChatMessageDict);
#endregion
            SendMessage(colouredChatMessage);
            return true;
        }
        private Dictionary<string, object> OnBetterChat(Dictionary<string, object> dict) {
            if (dict != null) {
                IPlayer player = dict["Player"] as IPlayer;
                var colouredChatMessage = FromMessage(player, (Chat.ChatChannel)dict["ChatChannel"], dict["Message"].ToString());
#region API
                var colouredChatMessageDict = colouredChatMessage.ToDictionary();
                foreach (Plugin plugin in plugins.GetAll()) {
                    object obj = plugin.CallHook("OnColouredChat", colouredChatMessageDict);
                    if (obj is Dictionary<string, object>) {
                        try {
                            colouredChatMessageDict = obj as Dictionary<string, object>;
                        }
                        catch (Exception e) {
                            PrintError($"Failed to load modified OnColouredChat hook data from plugin '{plugin.Title} ({plugin.Version})':{Environment.NewLine}{e}");
                            continue;
                        }
                    }
                    else if (obj != null) {
                        if (obj is bool) {
                            dict["CancelOption"] = 2;
                        }
                    }
                }
                colouredChatMessage = ColouredChatMessage.FromDictionary(colouredChatMessageDict);
#endregion
                if (!string.IsNullOrEmpty(colouredChatMessage.Name)) dict["Username"] = colouredChatMessage.Name;
                if (!string.IsNullOrEmpty(colouredChatMessage.Colour)) {
                    ((Dictionary<string, object>)dict["UsernameSettings"])["Color"] = colouredChatMessage.Colour;
                }
                dict["Message"] = colouredChatMessage.Message;
            }
            return dict;
        }
#endregion
#region Commands
        void cmdNameColour(IPlayer player, string cmd, string[] args) => ProcessColourCommand(player, cmd, args);
        void cmdNameColours(IPlayer player, string cmd, string[] args) => ProcessColoursCommand(player, cmd, args);
        void cmdMessageColour(IPlayer player, string cmd, string[] args) => ProcessColourCommand(player, cmd, args, true);
        void cmdMessageColours(IPlayer player, string cmd, string[] args) => ProcessColoursCommand(player, cmd, args, true);
#endregion
#region Helpers
        private bool BetterChatIns() => (BetterChat != null && BetterChat.IsLoaded);
        private bool BetterChatMuteIns() => (BetterChatMute != null && BetterChatMute.IsLoaded);
        private bool ZoneManagerIns() => (ZoneManager != null && ZoneManager.IsLoaded);
        private bool IsValidColour(string input) => Regex.Match(input, ColourRegex).Success;
        private string GetMessage(string key, IPlayer player, params string[] args) => String.Format(lang.GetMessage(key, this, player.Id), args);
        //Name
        private bool HasNameShowPerm(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermShow));
        private bool HasNamePerm(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermUse));
        private bool HasNameRainbow(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermRainbow));
        private bool CanNameGradient(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermGradient));
        private bool CanNameBypass(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermBypass));
        private bool CanNameSetOthers(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermSetOthers));
        private bool CanNameRandomColour(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.namePermRandomColour));
        //Message
        private bool HasMessageShowPerm(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermShow));
        private bool HasMessagePerm(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermUse));
        private bool HasMessageRainbow(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermRainbow));
        private bool CanMessageGradient(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermGradient));
        private bool CanMessageBypass(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermBypass));
        private bool CanMessageSetOthers(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermSetOthers));
        private bool CanMessageRandomColour(IPlayer player) => (player.IsAdmin || permission.UserHasPermission(player.Id, config.messagePermRandomColour));
        private bool IsValidName(string input, IPlayer iPlayer = null) {
            if (iPlayer != null && CanNameBypass(iPlayer)) return true;
            if (config.nameUseBlacklist) {
                bool inRange = false;
                foreach (var colourRange in config.nameBlacklistedRangeColoursHex) {
                    inRange = IsInHexRange(input, colourRange._from, colourRange._to);
                    if (inRange) break;
                }
                return !config.nameBlockColoursHex.Any(x => (input == x)) && !inRange;
            }
            else if (config.nameUseWhitelist) {
                bool inRange = false;
                foreach (var colourRange in config.nameWhitelistedRangeColoursHex) {
                    inRange = IsInHexRange(input, colourRange._from, colourRange._to);
                    if (!inRange) break;
                }
                return config.nameWhitelistedColoursHex.Any(x => (input == x)) || inRange;
            }
            return true;
        }
        private bool IsValidMessage(string input, IPlayer iPlayer = null) {
            if (iPlayer != null && CanMessageBypass(iPlayer)) return true;
            if (config.messageUseBlacklist) {
                bool inRange = false;
                foreach (var colourRange in config.messageBlacklistedRangeColoursHex) {
                    inRange = IsInHexRange(input, colourRange._from, colourRange._to);
                    if (inRange) break;
                }
                return !config.messageBlockColoursHex.Any(x => (input == x)) && !inRange;
            }
            else if (config.messageUseWhitelist) {
                bool inRange = false;
                foreach (var colourRange in config.messageWhitelistedRangeColoursHex) {
                    inRange = IsInHexRange(input, colourRange._from, colourRange._to);
                    if (!inRange) break;
                }
                return config.messageWhitelistedColoursHex.Any(x => (input == x)) || inRange;
            }
            return true;
        }
        private void SendMessage(ColouredChatMessage colouredChatMessage, List<BasePlayer> players = null) {
            var player = colouredChatMessage.Player.Object as BasePlayer;
            string formattedMsg = string.Format("{0}[{1}]", new string[] {
                player?.displayName?.EscapeRichText() ?? string.Empty, player?.UserIDString ?? string.Empty
            }
            );
            string chatMessage = colouredChatMessage.GetChatOutput();
            var receivers = new ListHashSet<BasePlayer>();
            if (players != null) {
                foreach (var ply in players) {
                    ply.SendConsoleCommand("chat.add2", (int)colouredChatMessage.ChatChannel, player.userID, colouredChatMessage.Message, colouredChatMessage.Name, colouredChatMessage.Colour);
                }
                DebugEx.Log(string.Concat("[PRIVATE CHAT] ", formattedMsg, " : ", colouredChatMessage.Message), StackTraceLogType.None);
            }
            else if (colouredChatMessage.ChatChannel == Chat.ChatChannel.Global) {
                receivers = BasePlayer.activePlayerList;
                DebugEx.Log(string.Concat("[CHAT] ", formattedMsg, " : ", colouredChatMessage.Message), StackTraceLogType.None);
            }
            else if (colouredChatMessage.ChatChannel == Chat.ChatChannel.Team) {
                if (player?.Team == null) return;
                player.Team.BroadcastTeamChat(player.userID, player.displayName, colouredChatMessage.Message, colouredChatMessage.Colour);
                foreach (ulong memberId in player.Team.members) {
                    BasePlayer member;
                    if ((member = RelationshipManager.FindByID(memberId)) != null) receivers.Add(member);
                }
                DebugEx.Log(string.Concat("[TEAM CHAT] ", formattedMsg, " : ", colouredChatMessage.Message), StackTraceLogType.None);
            }
            foreach (var receiver in receivers) receiver.SendConsoleCommand("chat.add", new object[] {
                (int)colouredChatMessage.ChatChannel, player.userID, chatMessage
            }
            );
            Chat.ChatEntry chatentry = new Chat.ChatEntry {
                Channel = colouredChatMessage.ChatChannel, Message = colouredChatMessage.Message, UserId = player.UserIDString, Username = player.displayName, Color = colouredChatMessage.Colour, Time = Facepunch.Math.Epoch.Current
            }
            ;
            Facepunch.RCon.Broadcast(Facepunch.RCon.LogType.Chat, chatentry);
        }
        private void ProcessColourCommand(IPlayer player, string cmd, string[] args, bool isMessage = false) {
            if (args.Length < 1) {
                player.Reply(GetMessage("IncorrectUsage", player, isMessage ? config.messageColourCommand : config.nameColourCommand, isMessage ? config.messageColoursCommand : config.nameColoursCommand));
                return;
            }
            string colLower = string.Empty;
            if (args[0] == "set") {
                if ((!isMessage && !CanNameSetOthers(player)) || (isMessage && !CanMessageSetOthers(player))) {
                    player.Reply(GetMessage("NoPermissionSetOthers", player, isMessage ? "message" : "name"));
                    return;
                }
                if (args.Length < 3) {
                    player.Reply(GetMessage("IncorrectSetUsage", player, isMessage ? config.messageColourCommand : config.nameColourCommand));
                    return;
                }
                IPlayer target = covalence.Players.FindPlayer(args[1]);
                if (target == null) {
                    player.Reply(GetMessage("PlayerNotFound", player, args[1]));
                    return;
                }
                colLower = args[2].ToLower();
                ProcessColour(player, target, colLower, args.Skip(2).ToArray(), isMessage);
            }
            else if (args[0] == "group") {
                if (!player.IsAdmin) {
                    player.Reply(GetMessage("NoPermission", player));
                    return;
                }
                if (args.Length < 3) {
                    player.Reply(GetMessage("IncorrectGroupUsage", player, isMessage ? config.messageColourCommand : config.nameColourCommand));
                    return;
                }
                if (!permission.GroupExists(args[1])) permission.CreateGroup(args[1], string.Empty, 0);
                colLower = args[2].ToLower();
                ProcessColour(player, player, colLower, args.Skip(3).ToArray(), isMessage, args[1]);
            }
            else {
                if ((!isMessage && !HasNamePerm(player)) || (isMessage && !HasMessagePerm(player))) {
                    player.Reply(GetMessage("NoPermission", player));
                    return;
                }
                if (args.Length < 1) {
                    player.Reply(GetMessage("IncorrectUsage", player, isMessage ? config.messageColourCommand : config.nameColourCommand));
                    return;
                }
                colLower = args[0].ToLower();
                ProcessColour(player, player, colLower, args.Skip(1).ToArray(), isMessage);
            }
        }
        private void ProcessColoursCommand(IPlayer player, string cmd, string[] args, bool isMessage = false) {
            if ((!isMessage && !HasNamePerm(player)) || (isMessage && !HasMessagePerm(player))) {
                player.Reply(GetMessage("NoPermission", player));
                return;
            }
            string availableCommands = string.Empty;
            if (isMessage) {
                availableCommands += $"\n/{config.messageColourCommand} <color=#ff6666>#ff6666</color>";
                if (CanMessageRandomColour(player)) availableCommands += $"\n/{config.messageColourCommand} random";
                if (CanMessageGradient(player)) availableCommands += $"\n/{config.messageColourCommand} gradient <color=#ff6666>#ff6666</color> <color=#ff6666>#ff6666</color>" + $"\n/{config.messageColourCommand} gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color> <color=#90ee90>#90ee90</color>";
                if (CanMessageSetOthers(player)) availableCommands += $"\n/{config.messageColourCommand} set <color=#a8a8a8>playerIdOrName</color> <color=#ff6666>#ff6666</color>" + $"\n/{config.messageColourCommand} set <color=#a8a8a8>playerIdOrName</color> gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color>";
                if (player.IsAdmin) availableCommands += $"\n/{config.messageColourCommand} group <color=#a8a8a8>groupName</color> <color=#ff6666>#ff6666</color>" + $"\n/{config.messageColourCommand} group <color=#a8a8a8>groupName</color> gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color>";
            }
            else {
                availableCommands += $"\n/{config.nameColourCommand} <color=#ff6666>#ff6666</color>";
                if (CanNameRandomColour(player)) availableCommands += $"\n/{config.nameColourCommand} random";
                if (CanNameGradient(player)) availableCommands += $"\n/{config.nameColourCommand} gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color>" + $"\n/{config.nameColourCommand} gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color> <color=#90ee90>#90ee90</color>";
                if (CanNameSetOthers(player)) availableCommands += $"\n/{config.nameColourCommand} set <color=#a8a8a8>playerIdOrName</color> <color=#ff6666>#ff6666</color>" + $"\n/{config.nameColourCommand} set <color=#a8a8a8>playerIdOrName</color> gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color>";
                if (player.IsAdmin) availableCommands += $"\n/{config.nameColourCommand} group <color=#a8a8a8>groupName</color> <color=#ff6666>#ff6666</color>" + $"\n/{config.nameColourCommand} group <color=#a8a8a8>groupName</color> gradient <color=#ff6666>#ff6666</color> <color=#ffff94>#ffff94</color>";
            }
            string additionalInfo = string.Empty;
            if (isMessage && config.messageUseWhitelist) {
                additionalInfo += "Whitelisted Colours:\n";
                foreach (string colour in config.messageWhitelistedColoursHex) {
                    additionalInfo += "- <color=" + colour + ">" + colour + "</color>\n";
                }
                foreach (var colourRange in config.messageWhitelistedRangeColoursHex) {
                    additionalInfo += "- From <color=" + colourRange._from + ">" + colourRange._from + "</color> to <color=" + colourRange._to + ">" + colourRange._to + "</color>\n";
                }
            }
            else if (isMessage && config.messageUseBlacklist) {
                additionalInfo += "Blacklisted Colours:\n";
                foreach (string colour in config.messageBlockColoursHex) {
                    additionalInfo += "- <color=" + colour + ">" + colour + "</color>\n";
                }
                foreach (var colourRange in config.messageBlacklistedRangeColoursHex) {
                    additionalInfo += "- From <color=" + colourRange._from + ">" + colourRange._from + "</color> to <color=" + colourRange._to + ">" + colourRange._to + "</color>\n";
                }
            }
            else if (!isMessage && config.nameUseWhitelist) {
                additionalInfo += "Whitelisted Colours:\n";
                foreach (string colour in config.nameWhitelistedColoursHex) {
                    additionalInfo += "- <color=" + colour + ">" + colour + "</color>\n";
                }
                foreach (var colourRange in config.nameWhitelistedRangeColoursHex) {
                    additionalInfo += "- From <color=" + colourRange._from + ">" + colourRange._from + "</color> to <color=" + colourRange._to + ">" + colourRange._to + "</color>\n";
                }
            }
            else if (!isMessage && config.nameUseBlacklist) {
                additionalInfo += "Blacklisted Colours:\n";
                foreach (string colour in config.nameBlockColoursHex) {
                    additionalInfo += "- <color=" + colour + ">" + colour + "</color>\n";
                }
                foreach (var colourRange in config.nameBlacklistedRangeColoursHex) {
                    additionalInfo += "- From <color=" + colourRange._from + ">" + colourRange._from + "</color> to <color=" + colourRange._to + ">" + colourRange._to + "</color>\n";
                }
            }
            player.Reply(GetMessage("ColoursInfo", player, availableCommands, additionalInfo));
        }
        private string ProcessColourMessage(string message, string colour) => $"<color={colour}>" + message + "</color>";
        private void ProcessColour(IPlayer player, IPlayer target, string colLower, string[] colours, bool isMessage = false, string groupName = "") {
            bool isGroup = false;
            if (!string.IsNullOrEmpty(groupName)) isGroup = true;
            bool isCalledOnto = false;
            if (player != target && !isGroup) isCalledOnto = true;
            string key = isGroup ? groupName : target.Id;
            if (!isGroup && !allColourData.ContainsKey(target.Id)) allColourData.Add(target.Id, new PlayerData());
            else if (isGroup && !allColourData.ContainsKey(groupName)) allColourData.Add(groupName, new PlayerData(true));
            if (colLower == "gradient") {
                if ((!isMessage && !CanNameGradient(player)) || (isMessage && !CanMessageGradient(player))) {
                    player.Reply(GetMessage("NoPermissionGradient", player, isMessage ? "message" : "name"));
                    return;
                }
                colours = colours.Where(col => isMessage ? IsValidMessage(col, player) : IsValidName(col, player) && IsValidColour(col) && (IsInvalidCharacter(col) == null ? true : false)).ToArray();
                if (colours.Length < 2) {
                    player.Reply(GetMessage("IncorrectGradientUsageArgs", player, isMessage ? config.messageColourCommand : config.nameColourCommand));
                    return;
                }
                string gradientName = ProcessGradient(isMessage ? "Example Message" : target.Name, colours, isMessage, player);
                if (gradientName.Equals(string.Empty)) {
                    player.Reply(GetMessage("IncorrectGradientUsage", player, isMessage ? config.messageColourCommand : config.nameColourCommand));
                    return;
                }
                if (isMessage) {
                    allColourData[key].MessageColour = string.Empty;
                    allColourData[key].MessageGradientArgs = colours;
                }
                else {
                    allColourData[key].NameColour = string.Empty;
                    allColourData[key].NameGradientArgs = colours;
                    if (!isGroup) {
                        if (!cachedData.ContainsKey(key)) cachedData.Add(key, new CachePlayerData(gradientName, GetPrimaryUserGroup(player.Id)));
                        else cachedData[key].NameColourGradient = gradientName;
                    }
                }
                if (isGroup) ClearCache();
                if (target.IsConnected) target.Reply(GetMessage("GradientChanged", target, GetCorrectLang(isGroup, isMessage, key), gradientName));
                if (isCalledOnto) player.Reply(GetMessage("GradientChangedFor", player, target.Name, isMessage ? "message" : "name", gradientName));
                return;
            }
            if (colLower == "reset" || colLower == "clear" || colLower == "remove") {
                if (isMessage) {
                    allColourData[key].MessageColour = string.Empty;
                    allColourData[key].MessageGradientArgs = null;
                }
                else {
                    allColourData[key].NameColour = string.Empty;
                    allColourData[key].NameGradientArgs = null;
                    if (cachedData.ContainsKey(key)) cachedData.Remove(key);
                }
                if (string.IsNullOrEmpty(allColourData[key].NameColour) && allColourData[key].NameGradientArgs == null && string.IsNullOrEmpty(allColourData[key].MessageColour) && allColourData[key].MessageGradientArgs == null) allColourData.Remove(key);
                if (isGroup) ClearCache();
                if (target.IsConnected) target.Reply(GetMessage("ColourRemoved", target, GetCorrectLang(isGroup, isMessage, key)));
                if (isCalledOnto) player.Reply(GetMessage("ColourRemovedFor", player, target.Name, isMessage ? "message" : "name"));
                return;
            }
            if (colLower == "random") {
                if (!isMessage && !CanNameRandomColour(player) || isMessage && !CanMessageRandomColour(player)) {
                    player.Reply(GetMessage("NoPermissionRandom", player, isMessage ? "message" : "name"));
                    return;
                }
                colLower = GetRndColour();
                if (isMessage) ChangeMessageColour(key, colLower, null);
                else ChangeNameColour(key, colLower, null);
                if (isGroup) ClearCache();
                if (target.IsConnected) target.Reply(GetMessage("RndColour", target, GetCorrectLang(isGroup, isMessage, key), colLower));
                if (isCalledOnto) player.Reply(GetMessage("RndColourFor", player, isMessage ? "Message" : "Name", target.Name, colLower));
                return;
            }
            if (colLower == "rainbow") {
                if (isMessage && !HasMessageRainbow(player) || !HasNameRainbow(player)) {
                    player.Reply(GetMessage("NoPermissionRainbow", player));
                    return;
                }
                if (isMessage) ChangeMessageColour(key, string.Empty, config.rainbowColours);
                else ChangeNameColour(key, string.Empty, config.rainbowColours);
                if (isGroup) ClearCache();
                if (target.IsConnected) target.Reply(GetMessage("RainbowColour", target, GetCorrectLang(isGroup, isMessage, key)));
                if (isCalledOnto) player.Reply(GetMessage("RainbowColourFor", player, isMessage ? "Message" : "Name", target.Name));
                return;
            }
            string invalidChar;
            if ((invalidChar = IsInvalidCharacter(colLower)) != null) {
                player.Reply(GetMessage("InvalidCharacters", player, invalidChar));
                return;
            }
            if (!IsValidColour(colLower)) {
                player.Reply(GetMessage("InvalidColour", player));
                return;
            }
            if (isMessage ? !IsValidMessage(colLower, player) : !IsValidName(colLower, player)) {
                player.Reply(GetMessage("InvalidColour", player));
                return;
            }
            if (isMessage) ChangeMessageColour(key, colLower, null);
            else ChangeNameColour(key, colLower, null);
            if (isCalledOnto) player.Reply(GetMessage("ColourChangedFor", player, target.Name, isMessage ? "message" : "name", colLower));
            else if (isGroup && target.IsConnected) target.Reply(GetMessage("ColourChangedFor", player, key, isMessage ? "message" : "name", colLower));
            else if (target.IsConnected) target.Reply(GetMessage("ColourChanged", target, isMessage ? "Message" : "Name", colLower));
            if (isGroup) ClearCache();
        }
        private string ProcessGradient(string name, string[] colourArgs, bool isMessage = false, IPlayer iPlayer = null) {
            var chars = name.ToCharArray();
            string gradientName = string.Empty;
            var colours = new List<Color>();
            Color startColour;
            Color endColour;
            int gradientsSteps = chars.Length / (colourArgs.Length - 1);
            if (gradientsSteps <= 1) {
                for (int i = 0; i < chars.Length; i++) {
                    if (i > colourArgs.Length - 1) ColorUtility.TryParseHtmlString(colourArgs[colourArgs.Length - 1], out startColour);
                    else ColorUtility.TryParseHtmlString(colourArgs[i], out startColour);
                    colours.Add(startColour);
                }
            }
            else {
                int gradientIterations = chars.Length / gradientsSteps;
                for (int i = 0; i < gradientIterations; i++) {
                    if (colours.Count >= chars.Length) continue;
                    if (i > colourArgs.Length - 1) ColorUtility.TryParseHtmlString(colourArgs[colourArgs.Length - 1], out startColour);
                    else ColorUtility.TryParseHtmlString(colourArgs[i], out startColour);
                    if (i >= colourArgs.Length - 1) endColour = startColour;
                    else ColorUtility.TryParseHtmlString(colourArgs[i + 1], out endColour);
                    foreach (var c in GetGradients(startColour, endColour, gradientsSteps)) colours.Add(c);
                }
                if (colours.Count < chars.Length) {
                    ColorUtility.TryParseHtmlString(colourArgs[colourArgs.Length - 1], out endColour);
                    while (colours.Count < chars.Length) colours.Add(endColour);
                }
            }
            for (int i = 0; i < colours.Count; i++) {
                gradientName += $"<color=#{ColorUtility.ToHtmlStringRGB(colours[i])}>{chars[i]}</color>";
            }
            return gradientName;
        }
        private List<Color> GetGradients(Color start, Color end, int steps) {
            var colours = new List<Color>();
            float stepR = ((end.r - start.r) / (steps - 1));
            float stepG = ((end.g - start.g) / (steps - 1));
            float stepB = ((end.b - start.b) / (steps - 1));
            for (int i = 0; i < steps; i++) {
                colours.Add(new Color(start.r + (stepR * i), start.g + (stepG * i), start.b + (stepB * i)));
            }
            return colours;
        }
        private string GetRndColour() => String.Format("#{0:X6}", new System.Random().Next(0x1000000));
        private string IsInvalidCharacter(string input) => (config.blockedValues.Where(x => input.Contains(x)).FirstOrDefault()) ?? null;
        private void ClearUpData() {
            if (config.inactivityRemovalTime == 0) return;
            var copy = new Dictionary<string, PlayerData>(allColourData);
            foreach (var colData in copy) {
                if (colData.Value.LastActive == 0) continue;
                if (colData.Value.LastActive + (config.inactivityRemovalTime * 86400) < DateTimeOffset.UtcNow.ToUnixTimeSeconds()) allColourData.Remove(colData.Key);
            }
        }
        private void ClearCache() {
            var cachedCopy = new Dictionary<string, CachePlayerData>(cachedData);
            foreach (var cache in cachedCopy) cachedData.Remove(cache.Key);
        }
        private void ClearCache(string Id) {
            if (cachedData.ContainsKey(Id)) cachedData.Remove(Id);
        }
 
// ... [Code preview truncated due to length. Full source in attached file] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху