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

FREE ChatPlus : 1.5.5 1.5.5

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using System.Text.RegularExpressions;
using CompanionServer;
using Oxide.Core.Libraries.Covalence;
using UnityEngine;
using ConVar;
using Facepunch.Math;
namespace Oxide.Plugins {
    [Info("ChatPlus", "RustPlugin.ru - Developed by Vlad-00003", "1.5.5", ResourceId = 82)]
    public class ChatPlus : CovalencePlugin {
#region Global vars
        private ChatConfig config;
        private static ChatPlus m_Instance;
        private static Dictionary<string, MuteData> mutes = new Dictionary<string, MuteData>();
        private Dictionary<string, PlayerData> PlayersData = new Dictionary<string, PlayerData>();
        private PlayerData defaultData = new PlayerData();
        private bool GlobalMute = false;
        private bool HasExpired;
        private IPlayer ConsoleIPly;
        DynamicConfigFile mutes_File = Interface.Oxide.DataFileSystem.GetFile("ChatPlus_Mutes");
        DynamicConfigFile players_File = Interface.Oxide.DataFileSystem.GetFile("ChatPlus_Players");
        public static Dictionary<Plugin, Func<IPlayer, string>> ThirdPartyTitles = new Dictionary<Plugin, Func<IPlayer, string>>();
#endregion
#region Initialization and quiting
        void OnServerInitialized() {
            m_Instance = this;
            LoadMessages();
            LoadConfig();
            LoadData();
            config.RegisterPerms();
            timer.Repeat(10, 0, () => {
                List<string> expired = mutes.Where(m => m.Value.Expired).Select(m => m.Key).ToList();
                foreach (string userID in expired) {
                    IPlayer player = players.FindPlayerById(userID.ToString());
                    if (player == null) continue;
                    mutes.Remove(userID);
                    BroadcastChat("MUTE.EXPIRED", player.Name);
                    Log(LogType.Mute, string.Format(GetMsg("MUTE.EXPIRED"), player.Name));
                    if (!HasExpired) HasExpired = true;
                }
                if (HasExpired) {
                    SaveMutes();
                    HasExpired = false;
                }
            }
            );
        }
        void Unload() {
            OnServerSave();
        }
        void OnServerSave() {
            SaveMutes();
            players_File.WriteObject(PlayersData.Where(p => !p.Value.Equals(defaultData)).ToDictionary(p => p.Key, p => p.Value));
        }
        private void SaveMutes() {
            mutes_File.WriteObject(mutes);
        }
        void LoadData() {
            mutes = mutes_File.ReadObject<Dictionary<string, MuteData>>();
            PlayersData = players_File.ReadObject<Dictionary<string, PlayerData>>();
        }
#endregion
        private void PrintToChatMessageFake(string name, string userID, string message) {
            var prefix = config.Get(config.prefixes, "chatplus.default").Format;
            var nameColor = config.Get(config.names, "chatplus.default").Format;
            var messageColor = config.Get(config.messages, "chatplus.default").Format;
            name = string.Format(nameColor, RemoveTags(name));
            if (prefix.Length > 0) name = $"{prefix} {name}";
            message = RemoveTags(message);
            message = string.Format(messageColor, message);
            SendChat(name, message, "", userID);
        }
        private object OnPlayerOfflineChat(ulong playerId, string playerName, string message, Chat.ChatChannel channel) {
            if (GlobalMute) {
                return false;
            }
            var userId = playerId.ToString();
            var pData = GetPlayerData(userId, playerName);
            if (SpamCheck(message) != null) return false;
            if (MuteData.IsMuted(userId)) return false;
            if (config.CapsBlock) {
                message = RemoveCaps(message);
            }
            message = RemoveTags(message);
            bool mute;
            var censorMessage = CensorBadWords(message, out mute);
            if (config.BadWordsBlock & mute) {
                Mute(userId, playerName, new TimeSpan(0, 0, config.MuteBadWordsDefault), config.MuteReasonAutoMute);
            }
            var prefix = config.Get(config.prefixes, pData.Prefix).Format;
            var nameColor = config.Get(config.names, pData.NameColor).Format;
            var messageColor = config.Get(config.messages, pData.MessageColor).Format;
            var name = string.Format(nameColor, RemoveTags(playerName));
            message = string.Format(messageColor, message);
            censorMessage = string.Format(messageColor, censorMessage);
            if (prefix.Length > 0) name = $"{prefix} {name}";
            if (channel != Chat.ChatChannel.Team) {
                SendChat(name, message, censorMessage, userId);
                Log(LogType.Chat, $"{name}[{userId}]: {message}");
            }
            else {
                var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
                if (playerTeam == null) return false;
                var onlineMembers = playerTeam.GetOnlineMemberConnections();
                if (onlineMembers != null) SendChat(name, message, censorMessage, userId, onlineMembers.Select(x => x.player as BasePlayer));
                playerTeam.BroadcastTeamChat(playerId, Formatter.ToPlaintext(name), Formatter.ToPlaintext(message), "#fff");
                Log(LogType.TeamChat, $"{name}[{userId}]: {message}");
            }
            Chat.Record(new Chat.ChatEntry {
                Channel = channel, Message = Formatter.ToPlaintext(message), UserId = userId, Username = Formatter.ToPlaintext(name), Color = "#5af", Time = Epoch.Current
            }
            );
            ServerConsole.PrintColoured(ConsoleColor.DarkYellow, $"[{channel}] {Formatter.ToPlaintext(name)}({userId}) : ", ConsoleColor.DarkGreen, Formatter.ToPlaintext(message));
            return true;
        }
        object OnPlayerChat(BasePlayer player, string message, Chat.ChatChannel channel) {
            var sender = player.IPlayer;
            if (GlobalMute) {
                if (!CanMuteAll(sender)) {
                    Reply(sender, "MUTE.ALL.DISABLED");
                    return false;
                }
            }
            var pData = GetPlayerData(sender);
            if (pData.IsAdmin && channel != Chat.ChatChannel.Team) {
                Log(LogType.Chat, $"[ADMIN MODE] {sender.Name}({sender.Id}): {message}");
                bool outer;
                var cens = CensorBadWords(message, out outer);
                cens = string.Format(config.adminPrivilages.AdminFormat, cens);
                message = string.Format(config.adminPrivilages.AdminFormat, message);
                SendChat("", message, cens);
                return false;
            }
            if (pData.IsModer) {
                Log(LogType.Chat, $"[MODERATOR MODE] {sender.Name}({sender.Id}): {message}");
                bool outer;
                var cens = CensorBadWords(message, out outer);
                cens = string.Format(config.adminPrivilages.ModerFormat, cens);
                message = string.Format(config.adminPrivilages.ModerFormat, message);
                SendChat("", message, cens);
                return false;
            }
            if (SpamCheck(sender, message) != null) return false;
            if (MuteCheck(sender) != null) {
                //TODO find a way to make DiscordMesssages die
                return false;
            }
            if (config.CapsBlock) {
                message = RemoveCaps(message);
            }
            message = RemoveTags(message);
            bool mute;
            var censorMessage = CensorBadWords(message, out mute);
            if (config.BadWordsBlock & mute) {
                Mute(sender, new TimeSpan(0, 0, config.MuteBadWordsDefault), config.MuteReasonAutoMute, sender);
            }
            var prefix = config.Get(config.prefixes, pData.Prefix).Format;
            var nameColor = config.Get(config.names, pData.NameColor).Format;
            var messageColor = config.Get(config.messages, pData.MessageColor).Format;
            var name = string.Format(nameColor, RemoveTags(sender.Name));
            message = string.Format(messageColor, message);
            censorMessage = string.Format(messageColor, censorMessage);
            foreach (var thirdPartyTitle in ThirdPartyTitles) {
                try {
                    string title = thirdPartyTitle.Value(sender);
                    if (!string.IsNullOrEmpty(title)) {
                        prefix = title + " " + prefix;
                    }
                }
                catch (Exception ex) {
                    PrintError($"Error when trying to get third-party title from plugin '{thirdPartyTitle.Key.Title}'{Environment.NewLine}{ex}");
                }
            }
            Dictionary<string, object> hookDictionary = new Dictionary<string, object>() {
                ["Player"]
                = sender, ["Message"] = message, ["CensoredMessage"] = censorMessage, ["Prefixes"] = prefix
            }
            ;
            foreach (var plugin in plugins.GetAll()) {
                object result = plugin.CallHook("OnChatPlusMessage", hookDictionary);
                var dict = result as Dictionary<string, object>;
                if (dict != null) {
                    try {
                        sender = dict["Player"] as IPlayer;
                        message = dict["Message"] as string;
                        censorMessage = dict["CensoredMessage"] as string;
                        prefix = dict["Prefixes"] as string;
                    }
                    catch (Exception ex) {
                        PrintWarning($"Plugin '{plugin.Title}({plugin.Version})' failed to modify the ChatPlus message data.Error:\n{ex.Message}");
                    }
                }
                else if (result != null) return null;
            }
            if (prefix.Length > 0) name = $"{prefix} {name}";
            if (channel != Chat.ChatChannel.Team) {
                SendChat(name, message, censorMessage, sender.Id);
                Log(LogType.Chat, $"{name}[{sender.Id}]: {message}");
            }
            else {
                var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(player.userID);
                if (playerTeam == null) return false;
                var onlineMembers = playerTeam.GetOnlineMemberConnections();
                if (onlineMembers != null) SendChat(name, message, censorMessage, sender.Id, onlineMembers.Select(x => x.player as BasePlayer));
                playerTeam.BroadcastTeamChat(player.userID, Formatter.ToPlaintext(name), Formatter.ToPlaintext(message), "#fff");
                Log(LogType.TeamChat, $"{name}[{sender.Id}]: {message}");
            }
            Chat.Record(new Chat.ChatEntry {
                Channel = channel, Message = Formatter.ToPlaintext(message), UserId = sender.Id, Username = Formatter.ToPlaintext(name), Color = "#5af", Time = Epoch.Current
            }
            );
            ServerConsole.PrintColoured(ConsoleColor.DarkYellow, $"[{channel}] {Formatter.ToPlaintext(name)}({sender.Id}) : ", ConsoleColor.DarkGreen, Formatter.ToPlaintext(message));
            return true;
        }
#region Chat handling
        private string RemoveTags(string message) {
            //List<string> forbiddenTags = new List<string>{
            //    "</color>",
            //    "</size>",
            //    "<b>",
            //    "</b>",
            //    "<i>",
            //    "</i>"
            //};
            //message = Regex.Replace(message, "(<color=.+?>)", string.Empty, RegexOptions.IgnoreCase);
            //message = Regex.Replace(message, "(<size=.+?>)", string.Empty, RegexOptions.IgnoreCase);
            //foreach (string tag in forbiddenTags)
            //    message = Regex.Replace(message, tag, string.Empty, RegexOptions.IgnoreCase);
            return Formatter.ToPlaintext(message).EscapeRichText();
        }
        string RemoveCaps(string message) {
            var ss = message.Split(' ');
            for (int j = 0; j < ss.Length; j++) for (int i = 1; i < ss[j].Length; i++) {
                var sym = ss[j][i];
                if (char.IsLower(sym)) continue;
                ss[j] = ss[j].Remove(i, 1);
                ss[j] = ss[j].Insert(i, char.ToLower(sym).ToString());
            }
            return string.Join(" ", ss);
        }
        bool? MuteCheck(IPlayer sender) {
            if (MuteData.IsMuted(sender.Id)) {
                MuteData md = mutes[sender.Id];
                Reply(sender, "YOU.MUTED", md.Initiator, md.Reason, md.Remain);
                return true;
            }
            return null;
        }
        bool? SpamCheck(IPlayer sender, string message) {
            if (message.Length > 500) {
                sender.Kick(GetMsg("CHAT.TOOMUCH", sender));
                return false;
            }
            if (message.Length > 100) {
                Reply(sender, "CHAT.SPAM");
                return false;
            }
            return null;
        }
        bool? SpamCheck(string message) {
            if (message.Length > 100) return false;
            return null;
        }
        public string CensorBadWords(string input, out bool found) {
            found = false;
            string temp = input.ToLower();
            foreach (var swear in config.badWords) {
                var firstIndex = temp.IndexOf(swear.Key, StringComparison.Ordinal);
                if (firstIndex >= 0 && swear.Value.All(exception => temp.IndexOf(exception, StringComparison.Ordinal) < 0)) {
                    while (firstIndex < input.Length && input[firstIndex] != ' ') {
                        input = input.Remove(firstIndex, 1);
                        input = input.Insert(firstIndex, "*");
                        firstIndex++;
                        found = true;
                    }
                }
            }
            return input;
        }
#endregion
#region Logging
        enum LogType {
            Chat, TeamChat, Mute, Pm, ServerConsole
        }
        private void Log(LogType type, string msg) {
            var text = Formatter.ToPlaintext(msg);
            switch (type) {
                case LogType.Chat : Interface.Oxide.RootLogger.Write(Core.Logging.LogType.Info, $"[CHAT] {text}");
                return;
                case LogType.Mute : Interface.Oxide.RootLogger.Write(Core.Logging.LogType.Info, $"[MUTE] {text}");
                return;
                case LogType.Pm : Interface.Oxide.RootLogger.Write(Core.Logging.LogType.Info, $"[PM] {text}");
                return;
                case LogType.ServerConsole : Interface.Oxide.RootLogger.Write(Core.Logging.LogType.Info, $"[ServerConsole] {text}");
                return;
                case LogType.TeamChat : Interface.Oxide.RootLogger.Write(Core.Logging.LogType.Info, $"[TEAM CHAT] {text}");
                return;
            }
        }
#endregion
#region Broadcasting
        void SendChat(string name, string message, string censorMessage = "", string userId = "0", IEnumerable<BasePlayer> receivers = null) {
            name = covalence.FormatText(name);
            message = covalence.FormatText(message);
            censorMessage = covalence.FormatText(censorMessage);
            if (string.IsNullOrEmpty(censorMessage)) censorMessage = message;
            var channel = receivers == null ? 0 : 1;
            receivers = receivers ?? BasePlayer.activePlayerList;
            foreach (var player in receivers) {
                var msg = GetPlayerData(player).Censor ? censorMessage : message;
                player?.SendConsoleCommand("chat.add", channel, userId, string.IsNullOrEmpty(name) ? $"{msg}" : $"{name}: {msg}");
            }
        }
        void BroadcastChat(string langKey, params object[] args) {
            foreach (var player in BasePlayer.activePlayerList) {
                player.ChatMessage(covalence.FormatText(string.Format(GetMsg(langKey, player), args)));
            }
        }
        private void Reply(IPlayer player, string langkey, params object[] args) {
            if (player == null) return;
            var message = string.Format(GetMsg(langkey, player), args);
            message = player.IsServer ? Formatter.ToPlaintext(message) : covalence.FormatText(message);
            if (player.IsServer | player.IsConnected) player.Reply(message);
        }
#endregion
#region Sub functions
        void Mute(string targetId, string targetName, TimeSpan? time, string reason) {
            if (string.IsNullOrEmpty(reason)) reason = config.MuteReason;
            string sender = "ChatPlus";
            string log;
            if (!time.HasValue) {
                mutes[targetId] = new MuteData(sender, reason);
                BroadcastChat("USER.MUTED.REASON", sender, targetName, reason, "Unlimited");
                log = string.Format(GetMsg("USER.MUTED.LOG"), sender, targetName, "Unlimited", reason);
                Interface.CallHook("OnBetterChatMuted", targetName, null, reason);
            }
            else {
                mutes[targetId] = new MuteData(sender, reason, time.Value);
                BroadcastChat("USER.MUTED.REASON", sender, targetName, reason, MuteData.TimeToString(time.Value));
                log = string.Format(GetMsg("USER.MUTED.LOG"), sender, targetName, MuteData.TimeToString(time.Value), reason);
                Interface.CallHook("OnBetterChatTimeMuted", targetName, null, time.Value, reason);
            }
            Log(LogType.Mute, log);
            SaveMutes();
        }
        void Mute(IPlayer target, TimeSpan? time, string reason, IPlayer player) {
            if (string.IsNullOrEmpty(reason)) reason = config.MuteReason;
            string sender = target == player ? "ChatPlus" : player.IsServer ? config.ConsoleName : player.Name;
            if (config.adminPrivilages.HideAdmins.HasValue && config.adminPrivilages.HideAdmins.Value && !player.IsServer) sender = config.adminPrivilages.AdminReplace;
            string log;
            if (!time.HasValue) {
                mutes[target.Id] = new MuteData(sender, reason);
                BroadcastChat("USER.MUTED.REASON", sender, target.Name, reason, "Unlimited");
                log = string.Format(GetMsg("USER.MUTED.LOG"), sender, target.Name, "Unlimited", reason);
                Interface.CallHook("OnBetterChatMuted", target, player, reason);
            }
            else {
                mutes[target.Id] = new MuteData(sender, reason, time.Value);
                BroadcastChat("USER.MUTED.REASON", sender, target.Name, reason, MuteData.TimeToString(time.Value));
                log = string.Format(GetMsg("USER.MUTED.LOG"), sender, target.Name, MuteData.TimeToString(time.Value), reason);
                Interface.CallHook("OnBetterChatTimeMuted", target, player, time.Value, reason);
            }
            Log(LogType.Mute, log);
            SaveMutes();
        }
        private List<IPlayer> GetPlayers(string NameOrID) {
            return players.FindPlayers(NameOrID).ToList();
        }
        private void SendChatHelp(IPlayer player) {
            string msg = GetMsg("CMD.CHAT.HELP", player);
            if (CanMuteAll(player)) msg += GetMsg("CMD.MUTE.ALL.HELP", player);
            if (IsAdmin(player)) msg += GetMsg("CMD.CHAT.HELP.PERMISSION.ADMIN", player);
            if (IsModerator(player)) msg += GetMsg("CMD.CHAT.HELP.PERMISSION.MODERATOR", player);
            msg = player.IsServer ? Formatter.ToPlaintext(msg) : covalence.FormatText(msg);
            player.Message(msg);
        }
#endregion
#region Flags
        bool IsModerator(IPlayer player) => PermissionService.HasPermission(player.Id, config.adminPrivilages.ModerPermiss) || player.IsAdmin;
        //player.net.connection.authLevel >= 1;
        bool IsAdmin(IPlayer player) => PermissionService.HasPermission(player.Id, config.adminPrivilages.AdminPermiss) || player.IsAdmin;
        //player.net.connection.authLevel >= 2;
        bool CanMute(IPlayer player) => PermissionService.HasPermission(player.Id, config.adminPrivilages.MutePermiss) || player.IsAdmin;
        //player.net.connection.authLevel >= 1;
        bool CanMuteAll(IPlayer player) => PermissionService.HasPermission(player.Id, config.adminPrivilages.MuteAllPermiss) || player.IsAdmin;
        //player.net.connection.authLevel >= 2;
        bool CanAssign(IPlayer player) => PermissionService.HasPermission(player.Id, config.adminPrivilages.AssignPermiss) || player.IsAdmin;
        //player.net.connection.authLevel >= 2;
        bool CanUnMute(IPlayer player) => PermissionService.HasPermission(player.Id, config.adminPrivilages.UnMutePermiss) || player.IsAdmin;
        //player.net.connection.authLevel >= 1;
#endregion
#region Commands
        object OnServerCommand(ConsoleSystem.Arg arg) {
            if (arg?.cmd?.FullName != null && arg?.cmd?.FullName == "global.say") {
                if (!arg.HasArgs()) return false;
                string message = string.Join(" ", arg.Args);
                bool outer;
                var cens = CensorBadWords(message, out outer);
                cens = string.Format(config.ConsoleFormat, config.ConsoleName, cens);
                message = string.Format(config.ConsoleFormat, config.ConsoleName, message);
                Log(LogType.ServerConsole, message);
                SendChat("", message, cens);
                return true;
            }
            else return null;
        }
        [Command("chatplus.prefix")]
        private void cmdConsolePrefix(IPlayer player, string cmd, string[] Args) {
            if (!CanAssign(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            if (Args == null || Args.Length < 2) {
                Reply(player, "CMD.HELP.PREFIX");
                return;
            }
            var recivers = GetPlayers(Args[0]);
            if (recivers == null || recivers.Count == 0) {
                Reply(player, "PLAYER.NOT.FOUND", Args[0]);
                return;
            }
            if (recivers.Count > 1) {
                Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", recivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                return;
            }
            var target = recivers.First();
            var pdata = GetPlayerData(target);
            if (!PermissionService.HasPermission(target.Id, Args[1])) {
                Reply(player, "NO.PERMISSION.PLAYER");
                return;
            }
            pdata.Prefix = Args[1];
            Reply(player, "PREFIX.CHANGED", Args[1]);
        }
        [Command("chatplus.name")]
        private void cmdConsoleName(IPlayer player, string cmd, string[] Args) {
            if (!CanAssign(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            if (Args == null || Args.Length < 2) {
                Reply(player, "CMD.HELP.NAME");
                return;
            }
            var recivers = GetPlayers(Args[0]);
            if (recivers == null || recivers.Count == 0) {
                Reply(player, "PLAYER.NOT.FOUND", Args[0]);
                return;
            }
            if (recivers.Count > 1) {
                Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", recivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                return;
            }
            var target = recivers.First();
            var pdata = GetPlayerData(target);
            if (!PermissionService.HasPermission(target.Id, Args[1])) {
                Reply(player, "NO.PERMISSION.PLAYER");
                return;
            }
            pdata.NameColor = Args[1];
            Reply(player, "NAME.COLOR.CHANGED", Args[1]);
        }
        [Command("chatplus.message")]
        private void cmdConsoleMessage(IPlayer player, string cmd, string[] Args) {
            if (!CanAssign(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            if (Args == null || Args.Length < 2) {
                Reply(player, "CMD.HELP.MESSAGE");
                return;
            }
            var recivers = GetPlayers(Args[0]);
            if (recivers == null || recivers.Count == 0) {
                Reply(player, "PLAYER.NOT.FOUND", Args[0]);
                return;
            }
            if (recivers.Count > 1) {
                Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", recivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                return;
            }
            var target = recivers.First();
            var pdata = GetPlayerData(target);
            if (!PermissionService.HasPermission(target.Id, Args[1])) {
                Reply(player, "NO.PERMISSIO.PLAYERN");
                return;
            }
            pdata.MessageColor = Args[1];
            Reply(player, "MESSAGE.COLOR.CHANGED", Args[1]);
        }
        [Command("muteall")]
        private void cmdChatMuteAll(IPlayer player, string cmd, string[] Args) {
            if (!CanMuteAll(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            if (GlobalMute) {
                BroadcastChat("MUTE.ALL.ENABLED");
                GlobalMute = false;
                return;
            }
            BroadcastChat("MUTE.ALL.DISABLED");
            GlobalMute = true;
            return;
        }
        [Command("mutelist")]
        void cmdChatMuteList(IPlayer player, string cmd, string[] Args) {
            if (!CanMute(player) || !CanUnMute(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            string msg;
            if (mutes.Count == 0) msg = GetMsg("MUTE.LIST.NOONE");
            else {
                msg = GetMsg("MUTE.LIST.HEAD");
                foreach (var mute in mutes) {
                    msg += "\n" + string.Format(GetMsg("MUTE.LIST.BODY", player), mute.Value.Initiator, $"{players.FindPlayerById(mute.Key.ToString()).Name} ({mute.Key})", mute.Value.Reason, mute.Value.Remain);
                }
            }
            player.Reply(msg);
        }
        [Command("mute")]
        void cmdChatMute(IPlayer player, string cmd, string[] args) {
            if (!CanMute(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            if (args.Length < 1) {
                Reply(player, "CMD.MUTE.HELP");
                return;
            }
            var recivers = GetPlayers(args[0]);
            if (recivers == null || recivers.Count == 0) {
                Reply(player, "PLAYER.NOT.FOUND", args[0]);
                return;
            }
            if (recivers.Count > 1) {
                Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", recivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                return;
            }
            var mutePlayer = recivers.First();
            if (MuteData.IsMuted(mutePlayer.Id)) {
                Reply(player, "USER.ALREADY.MUTED", mutePlayer.Name, mutes[mutePlayer.Id].Reason, mutes[mutePlayer.Id].Remain);
                return;
            }
            TimeSpan time;
            if (args.Length == 1) {
                Mute(mutePlayer, null, null, player);
                return;
            }
            if (MuteData.StringToTime(args[1], out time)) {
                Mute(mutePlayer, time, string.Join(" ", args.Skip(2).ToArray()), player);
                return;
            }
            Mute(mutePlayer, null, string.Join(" ", args.Skip(1).ToArray()), player);
        }
        [Command("unmute")]
        void cmdChatUnMute(IPlayer player, string cmd, string[] args) {
            if (!CanUnMute(player)) {
                Reply(player, "NO.ACCESS");
                return;
            }
            if (args.Length == 0) {
                Reply(player, "CMD.UNMUTE.HELP");
                return;
            }
            var recivers = GetPlayers(args[0]);
            if (recivers == null || recivers.Count == 0) {
                Reply(player, "PLAYER.NOT.FOUND", args[0]);
                return;
            }
            recivers = recivers.Where(p => mutes.ContainsKey(p.Id)).ToList();
            if (recivers.Count == 0) {
                Reply(player, "PLAYER.NOT.MUTED");
                return;
            }
            if (recivers.Count > 1) {
                Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", recivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                return;
            }
            var mutePlayer = recivers.First();
            mutes.Remove(mutePlayer.Id);
            BroadcastChat("USER.UNMUTED", player.Name, mutePlayer.Name);
            string log = GetMsg("USER.UNMUTED.LOG");
            log = string.Format(log, player.Name, mutePlayer.Name);
            Log(LogType.Mute, log);
            SaveMutes();
        }
        [Command("chat")]
        void cmdChat(IPlayer player, string cmd, string[] args) {
            if (args.Length == 0) {
                SendChatHelp(player);
                return;
            }
            var playerData = GetPlayerData(player);
            switch (args[0]) {
                case "reset" : PlayersData[player.Id] = new PlayerData();
                Reply(player, "RESET.SUCCESSFULL");
                return;
                case "admin" : if (!IsAdmin(player)) {
                    Reply(player, "NO.ACCESS");
                    return;
                }
                if (playerData.IsAdmin) {
                    playerData.IsAdmin = false;
                    Reply(player, "ADMIN.DISABLE");
                    return;
                }
                playerData.IsAdmin = true;
                Reply(player, "ADMIN.ENABLE");
                return;
                case "moder" : if (!IsModerator(player)) {
                    Reply(player, "NO.ACCESS");
                    return;
                }
                if (playerData.IsModer) {
                    playerData.IsModer = false;
                    Reply(player, "MODERATOR.DISABLE");
                    return;
                }
                playerData.IsModer = true;
                Reply(player, "MODERATOR.ENABLE");
                return;
                case "censor" : if (playerData.Censor) {
                    playerData.Censor = false;
                    Reply(player, "CENSOR.DISABLED");
                    return;
                }
                playerData.Censor = true;
                Reply(player, "CENSOR.ENABLED");
                return;
                case "ignore" : if (args.Length == 2 && args[1] == "list") {
                    if (playerData.BlackList.Count == 0) {
                        Reply(player, "IGNORE.LIST.IS.EMPTY");
                        return;
                    }
                    Reply(player, "IGNORE.LIST", string.Join(", ", playerData.BlackList.Select(p => GetPlayerData(p).Name).ToArray()));
                    return;
                }
                if (args.Length < 3 || (args[1] != "add" && args[1] != "remove")) {
                    Reply(player, "CMD.CHAT.IGNORE.HELP");
                    return;
                }
                bool mode = args[1] == "add";
                var reply = 0;
                var recivers = players.FindPlayers(args[2]).ToList();
                if (!recivers.Any()) {
                    Reply(player, "PLAYER.NOT.FOUND", args[2]);
                    return;
                }
                if (recivers.Count > 1) {
                    Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", recivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                    return;
                }
                var ignorePlayer = recivers.First();
                if (mode) {
                    if (!playerData.BlackList.Contains(ignorePlayer.Id)) {
                        playerData.BlackList.Add(ignorePlayer.Id);
                        Reply(player, "USER.ADD.IGNORE.LIST", ignorePlayer.Name);
                        if (ignorePlayer.IsConnected) Reply(ignorePlayer, "YOU.ADD.IGNORE.LIST", player.Name);
                        return;
                    }
                    Reply(player, "USER.IS.IGNORE.LIST", ignorePlayer.Name);
                    return;
                }
                else {
                    if (playerData.BlackList.Contains(ignorePlayer.Id)) {
                        playerData.BlackList.Remove(ignorePlayer.Id);
                        Reply(player, "USER.REMOVE.IGNORE.LIST", ignorePlayer.Name);
                        Reply(ignorePlayer, "YOU.REMOVE.IGNORE.LIST", player.Name);
                        return;
                    }
                    Reply(player, "NOT.ON.IGNORE.LIST", ignorePlayer.Name);
                    return;
                }
                case "sound" : if (args.Length == 1 || (args[1] != "on" && args[1] != "off")) {
                    Reply(player, "CMD.CHAT.SOUND.HELP");
                    return;
                }
                bool pmSound = args[1] == "on";
                playerData.PMSound = pmSound;
                if (pmSound) {
                    Reply(player, "SOUND.ENABLED");
                    return;
                }
                else {
                    Reply(player, "SOUND.DISABLED");
                    return;
                }
                case "prefix" : var aviablePrefixes = config.prefixes.Where(p => PermissionService.HasPermission(player.Id, p.Perm) && playerData.Prefix != p.Perm || p.Perm == "chatplus.default" && playerData.Prefix != p.Perm).ToList();
                if (aviablePrefixes.Count == 0) {
                    Reply(player, "NO.AVAILABLE.PREFIXS");
                    return;
                }
                if (args.Length == 1) {
                    Reply(player, "AVAILABLE.COLORS.PREFIX", string.Join(", ", aviablePrefixes.Select(p => $"{p.Arg}({covalence.FormatText(p.Format)})").ToArray()));
                    return;
                }
                var selectedPrefix = aviablePrefixes.FirstOrDefault(p => p.Arg == args[1]);
                if (selectedPrefix == null) {
                    Reply(player, "PREFIX.NOT.FOUND", args[1]);
                    return;
                }
                playerData.Prefix = selectedPrefix.Perm;
                Reply(player, "PREFIX.CHANGED", selectedPrefix.Arg);
                return;
                case "name" : var aviableNameColors = config.names.Where(p => PermissionService.HasPermission(player.Id, p.Perm) && playerData.NameColor != p.Perm || p.Perm == "chatplus.default" && playerData.NameColor != p.Perm).ToList();
                if (aviableNameColors.Count == 0) {
                    Reply(player, "NO.AVAILABLE.COLORS");
                    return;
                }
                if (args.Length == 1) {
                    Reply(player, "AVAILABLE.COLORS.NAME", string.Join(", ", aviableNameColors.Select(p => covalence.FormatText(string.Format(p.Format, p.Arg))).ToArray()));
                    return;
                }
                var selectedNameColor = aviableNameColors.FirstOrDefault(p => p.Arg == args[1]);
                if (selectedNameColor == null) {
                    Reply(player, "COLOR.NOT.FOUND", args[1]);
                    return;
                }
                playerData.NameColor = selectedNameColor.Perm;
                Reply(player, "NAME.COLOR.CHANGED", selectedNameColor.Arg);
                return;
                case "message" : var aviableMessageColors = config.messages.Where(p => PermissionService.HasPermission(player.Id, p.Perm) && playerData.MessageColor != p.Perm || p.Perm == "chatplus.default" && playerData.MessageColor != p.Perm).ToList();
                if (aviableMessageColors.Count == 0) {
                    Reply(player, "NO.AVAILABLE.COLORS");
                    return;
                }
                if (args.Length == 1) {
                    Reply(player, "AVAILABLE.COLORS.MESSAGE", string.Join(", ", aviableMessageColors.Select(p => covalence.FormatText(string.Format(p.Format, p.Arg))).ToArray()));
                    return;
                }
                var selectedMessageColor = aviableMessageColors.FirstOrDefault(p => p.Arg == args[1]);
                if (selectedMessageColor == null) {
                    Reply(player, "COLOR.NOT.FOUND", args[1]);
                    return;
                }
                playerData.MessageColor = selectedMessageColor.Perm;
                Reply(player, "MESSAGE.COLOR.CHANGED", selectedMessageColor.Arg);
                return;
                default : SendChatHelp(player);
                return;
            }
        }
#endregion
#region Private messaging
        private bool PmAvatar() => config.PMAva.HasValue && config.PMAva.Value;
        private void RustChat(IPlayer player, string langkey, string avatar, params object[] args) {
            var msg = string.Format(GetMsg(langkey, player), args);
            player.Command("chat.add", 2, PmAvatar() ? avatar : "0", covalence.FormatText(msg));
        }
        readonly Dictionary<string, string> pmHistory = new Dictionary<string, string>();
        [Command("pm")]
        void cmdChatPM(IPlayer player, string cmd, string[] args) {
            if (args.Length < 2) {
                Reply(player, "CMD.PM.HELP");
                return;
            }
            var argList = args.ToList();
            argList.RemoveAt(0);
            string message = RemoveTags(string.Join(" ", argList.ToArray()));
            var receivers = players.Connected.Where(p => p.Name.ToLower().Contains(args[0].ToLower()) || p.Id == args[0]).ToList();
            if (receivers.Count == 0) {
                Reply(player, "PLAYER.NOT.FOUND", args[0]);
                return;
            }
            if (receivers.Count > 1) {
                Reply(player, "MULTIPLE.PLAYERS.FOUND", string.Join("\n", receivers.Select(p => $"{p.Name} ({p.Id})").ToArray()));
                return;
            }
            IPlayer receiver = receivers[0];
            if (receiver.Id == player.Id) {
                Reply(player, "PM.SELF");
                return;
            }
            var receiverName = RemoveTags(receiver.Name);
            if (GetPlayerData(receiver).BlackList.Contains(player.Id)) {
                Reply(player, "PM.YOU.ARE.BLACK.LIST", receiverName);
                return;
            }
            pmHistory[player.Id] = receiver.Id;
            pmHistory[receiver.Id] = player.Id;
            var targetName = RemoveTags(player.Name);
            if (player.IsServer) {
                ConsoleIPly = player;
                Reply(player, "PM.SENDER.FORMAT", receiverName, message);
                RustChat(receiver, "PM.RECEIVER.FORMAT", "0", config.ConsoleName, message);
            }
            else {
                RustChat(player, "PM.SENDER.FORMAT", player.Id, receiverName, message);
                RustChat(receiver, "PM.RECEIVER.FORMAT", player.Id, targetName, message);
            }
            var bply = receiver.Object as BasePlayer;
            if (GetPlayerData(receiver).PMSound) {
                Effect.server.Run(config.PrivateSoundMessagePath, bply, 0, Vector3.zero, Vector3.zero);
            }
            Log(LogType.Pm, string.Format(GetMsg("PM.LOG"), $"{targetName}({player.Id})", $"{receiverName}({receiver.Id})", message));
        }
        [Command("r")]
        void cmdChatR(IPlayer player, string cmd, string[] args) {
            if (args.Length == 0) {
                Reply(player, "CMD.R.HELP");
                return;
            }
            string message = RemoveTags(string.Join(" ", args));
            string recieverUserId;
            if (!pmHistory.TryGetValue(player.Id, out recieverUserId)) {
                Reply(player, "PM.NO.MESSAGES");
                return;
            }
            var playerName = RemoveTags(player.Name);
            if (recieverUserId == "server_console") {
                RustChat(player, "PM.SENDER.FORMAT", player.Id, config.ConsoleName, message);
                Reply(ConsoleIPly, "PM.RECEIVER.FORMAT", playerName, message);
                Log(LogType.Pm, string.Format(GetMsg("PM.LOG"), $"{playerName}({player.Id})", $"Server console", message));
                return;
            }
            var receiver = players.Connected.FirstOrDefault(p => p.Id == recieverUserId);
            if (receiver == null) {
                Reply(player, "PM.PLAYER.LEAVE");
                return;
            }
            var receiverName = RemoveTags(receiver.Name);
            if (GetPlayerData(receiver).BlackList.Contains(player.Id)) {
                Reply(player, "PM.YOU.ARE.BLACK.LIST", receiverName);
                return;
            }
            if (player.IsServer) {
                Reply(player, "PM.SENDER.FORMAT", receiverName, message);
                RustChat(receiver, "PM.RECEIVER.FORMAT", "0", config.ConsoleName, message);
            }
            else {
                RustChat(player, "PM.SENDER.FORMAT", player.Id, receiverName, message);
                RustChat(receiver, "PM.RECEIVER.FORMAT", player.Id, playerName, message);
            }
            var bply = receiver.Object as BasePlayer;
            if (GetPlayerData(receiver).PMSound) {
                Effect.server.Run(config.PrivateSoundMessagePath, bply, 0, Vector3.zero, Vector3.zero);
            }
            Log(LogType.Pm, string.Format(GetMsg("PM.LOG"), $"{playerName}({player.Id})", $"{receiverName}({receiver.Id})", message));
        }
#endregion
#region Data‌‌‍‌
        private class MuteData {
            public readonly string Initiator;
            public readonly string Reason;
            public readonly DateTime ExpireDate;
            [JsonIgnore]
            private bool Timed => ExpireDate != DateTime.MinValue;
            [JsonIgnore]
            public bool Expired => Timed && ExpireDate < DateTime.UtcNow;
            [JsonIgnore]
            public string Remain => Timed ? TimeToString(ExpireDate - DateTime.UtcNow) : "Unlimited";
            public static bool IsMuted(string userID, ulong playerid = 0) => mutes.ContainsKey(userID);
            public MuteData(string Initiator, string Reason, TimeSpan? Until = null) {
                this.ExpireDate = Until.HasValue ? DateTime.UtcNow + Until.Value : DateTime.MinValue;
                this.Reason = Reason;
                this.Initiator = Initiator;
            }
            [JsonConstructor]
            public MuteData(string Initiator, string Reason, DateTime ExpireDate) {
                this.ExpireDate = ExpireDate;
                this.Reason = Reason;
                this.Initiator = Initiator;
            }
            public static string TimeToString(TimeSpan elapsedTime) {
                int hours = elapsedTime.Hours;
                int minutes = elapsedTime.Minutes;
                int seconds = elapsedTime.Seconds;
                int days = elapsedTime.Days;
                string s = "";
                if (days > 0) s += $"{days} дн.";
                if (hours > 0) s += $"{hours} ч.";
                if (minutes > 0) s += $"{minutes} мин.";
                if (seconds > 0) s += $"{seconds} сек.";
                else s = s.TrimEnd(' ');
                return s;
            }
            public static bool StringToTime(string source, out TimeSpan time) {
                int seconds = 0, minutes = 0, hours = 0, days = 0;
                Match s = new Regex(@"(\d+?)s", RegexOptions.IgnoreCase).Match(source);
                Match m = new Regex(@"(\d+?)m", RegexOptions.IgnoreCase).Match(source);
                Match h = new Regex(@"(\d+?)h", RegexOptions.IgnoreCase).Match(source);
                Match d = new Regex(@"(\d+?)d", RegexOptions.IgnoreCase).Match(source);
                if (s.Success) seconds = Convert.ToInt32(s.Groups[1].ToString());
                if (m.Success) minutes = Convert.ToInt32(m.Groups[1].ToString());
                if (h.Success) hours = Convert.ToInt32(h.Groups[1].ToString());
                if (d.Success) days = Convert.ToInt32(d.Groups[1].ToString());
                source = source.Replace(seconds + "s", string.Empty);
                source = source.Replace(minutes + "m", string.Empty);
                source = source.Replace(hours + "h", string.Empty);
                source = source.Replace(days + "d", string.Empty);
                if (!string.IsNullOrEmpty(source) || (!s.Success && !m.Success && !h.Success && !d.Success)) {
                    time = TimeSpan.Zero;
                    return false;
                }
                time = new TimeSpan(days, hours, minutes, seconds);
                return true;
            }
        }
        public class PlayerData {
            public string Prefix = "chatplus.default";
            public string NameColor = "chatplus.default";
            public string MessageColor = "chatplus.default";
            public bool Censor = true;
            public bool PMSound = true;
            public string Name = "";
            public bool IsAdmin = false;
            public bool IsModer = false;
            public List<string> BlackList = new List<string>();
        }
        PlayerData GetPlayerData(IPlayer player) {
            var data = GetPlayerData(player.Id);
            data.Name = player.Name;
            return data;
        }
        PlayerData GetPlayerData(BasePlayer player) {
            var data = GetPlayerData(player.UserIDString);
            data.Name = player.displayName;
            return data;
        }
        PlayerData GetPlayerData(string userId) {
            PlayerData config;
            if (PlayersData.TryGetValue(userId, out config)) {
                if (config.Prefix != "chatplus.default" && !PermissionService.HasPermission(userId, config.Prefix)) config.Prefix = "chatplus.default";
                if (config.NameColor != "chatplus.default" && !PermissionService.HasPermission(userId, config.NameColor)) config.NameColor = "chatplus.default";
                if (config.MessageColor != "chatplus.default" && !PermissionService.HasPermission(userId, config.MessageColor)) config.MessageColor = "chatplus.default";
                return config;
            }
            config = new PlayerData();
            PlayersData[userId] = config;
            return config;
        }
        PlayerData GetPlayerData(string playerId, string playerName) {
            var data = GetPlayerData(playerId);
            data.Name = playerName;
            return data;
        }
#endregion
#region Localization‌‌‍‌
        private string GetMsg(string langKey) => lang.GetMessage(langKey, this);
        private string GetMsg(string langKey, BasePlayer player) => lang.GetMessage(langKey, th
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху