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

FREE AutomatedMessages : 2.1.0 2.1.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using ConVar;
using Newtonsoft.Json;
using System.Globalization;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using UnityEngine.UI;
using Oxide.Core.Libraries;
using Oxide.Plugins.AutomatedMessagesMethods;
/*2.1.0
 * Added "Send as game tip" option for replies + ability to preview game tip in /am.edit
 * Added "Send in chat" option (true by default)
 * Fix for inaccurate grid {hacklocation}
 * Added support for Toxic Village when using {hacklocation}
*/
namespace Oxide.Plugins {
    [Info("AutomatedMessages", "beee", "2.1.0")]
    [Description("Automated chat messages based on triggers or repeating interval.")]
    class AutomatedMessages : RustPlugin {
#region Fields
        private static AutomatedMessages _plugin;
        private PluginConfig _config;
        private List<Timer> _timers;
        public const string PREFIX_SHORT = "am";
        public const string PREFIX_LONG = "automatedmessages";
        public const string PERM_ADMIN = $"{PREFIX_LONG}.admin";
        private Dictionary<Regex, PluginConfig.ConfigAction> _autoReplyPatterns;
        [PluginReference]
        private Plugin PlaceholderAPI;
#endregion
#region Load/Unload Hooks
        private void Init() {
            UnsubscribeHooks();
        }
        void OnServerInitialized() {
            pData = PlayersData.Load();
            ProcessConfig();
            RegisterCommand(_config.ToggleCommand, nameof(TipsToggleChatCMD));
            RegisterPermissions();
            InitTimers();
            InitAutoReply();
            SubscribeHooks();
            RegisterConfigCommands();
            SetUnsetCountries();
            RegisterCommand($"{PREFIX_SHORT}.ui.texteditor", nameof(LongInputCMD));
        }
        void Loaded() {
            _plugin = this;
            _timers = new();
        }
        void Unload() {
            DestroyTimers();
            SaveData();
            foreach (var player in BasePlayer.activePlayerList) {
                CuiHelper.DestroyUi(player, uimodal);
                CuiHelper.DestroyUi(player, chatpreview);
                CuiHelper.DestroyUi(player, gametippreview);
            }
            _plugin = null;
            _timers = null;
        }
#endregion
#region Functions
        void RegisterPermissions() {
            permission.RegisterPermission(PERM_ADMIN, this);
        }
        private void InitTimers() {
            DestroyTimers();
            _timers = new();
            int count = 0;
            foreach (var message in _config.Actions.FindAll(s => s.IsEnabled() && s.Type == "Timed")) {
                Lang_Action defaultLangAction = message.CachedLangActions[_config.DefaultLang];
                if (defaultLangAction.Replies == null || defaultLangAction.Replies.Count == 0) continue;
                if (message.Interval <= 0) continue;
                Timer timer = _plugin.timer.Repeat(message.Interval * 60, 0, () => {
                    ProcessReply(message);
                }
                );
                _timers.Add(timer);
                count++;
            }
            PrintWarning($"Started {count} chat timer{((count == 1) ? "" : "s")}.");
        }
        private void InitAutoReply() {
            _autoReplyPatterns = new();
            int count = 0;
            foreach (var message in _config.Actions.FindAll(s => s.IsEnabled() && s.Type == "AutoReply")) {
                Lang_Action defaultLangAction = message.CachedLangActions[_config.DefaultLang];
                if (defaultLangAction.Replies == null || defaultLangAction.Replies.Count == 0) continue;
                if (string.IsNullOrEmpty(message.Target)) continue;
                foreach (var set in message.Target.Split('|')) {
                    string regexPattern = "";
                    foreach (var keyword in set.Split(',')) regexPattern += $"(?=.*{(keyword.StartsWith("!") ? "^!" : "")}\\b{keyword.TrimStart('!').Trim()}\\b)";
                    if (regexPattern == "") continue;
                    regexPattern = $"^{regexPattern}.*$";
                    _autoReplyPatterns.Add(new (regexPattern, RegexOptions.IgnoreCase), message);
                    count++;
                }
            }
            PrintWarning($"Cached {count} auto reply keyword pattern{((count == 1) ? "" : "s")}.");
        }
        List<string> _registeredConfigCommands;
        private void RegisterConfigCommands() {
            _registeredConfigCommands = new();
            int count = 0;
            foreach (var message in _config.Actions.FindAll(s => s.IsEnabled() && s.Type == "ChatCommand")) {
                Lang_Action defaultLangAction = message.CachedLangActions[_config.DefaultLang];
                if (defaultLangAction.Replies == null || defaultLangAction.Replies.Count == 0) continue;
                if (string.IsNullOrEmpty(message.Target)) continue;
                string command = message.Target.Replace("/", "").Trim().ToLower();
                foreach (string com in command.Split(',').Select(s => s.Trim())) {
                    if (string.IsNullOrEmpty(com)) continue;
                    RegisterCommand(com, nameof(CustomChatCMD));
                    _registeredConfigCommands.Add(com);
                    count++;
                }
            }
            PrintWarning($"Registered {count} chat command{((count == 1) ? "" : "s")}.");
        }
        private void UnregisterCachedCommands() {
            if (_registeredConfigCommands == null) return;
            Covalence library = GetLibrary<Covalence>();
            foreach (var command in _registeredConfigCommands) library.UnregisterCommand(command, this);
            _registeredConfigCommands.Clear();
        }
        private void RegisterCommand(string command, string callback, string perm = null) {
            if (!string.IsNullOrEmpty(command) && !command.Equals("null", StringComparison.OrdinalIgnoreCase)) {
                if (string.IsNullOrEmpty(perm)) AddCovalenceCommand(command, callback);
                else AddCovalenceCommand(command, callback, perm);
            }
        }
        private void SetUnsetCountries() {
            foreach (var player in BasePlayer.activePlayerList) {
                PlayerInfo pinfo;
                bool isNew = !pData.Players.TryGetValue(player.userID, out pinfo);
                if (isNew) pData.Players.Add(player.userID, pinfo = new PlayerInfo() {
                    TipsActive = true, isNew = true
                }
                );
                if (string.IsNullOrEmpty(pinfo.Country)) SetPlayerCountry(player, pinfo);
            }
        }
        private void DestroyTimers() {
            foreach (Timer timer in _timers) if (timer != null) timer.Destroy();
        }
        private void ProcessReplies(BasePlayer player, List<string> types, string target = "", bool onlySendToTeam = false) {
            if (!player.userID.IsSteamId()) return;
            PlayerInfo pinfo;
            bool isNew = !pData.Players.TryGetValue(player.userID, out pinfo);
            if (isNew) pData.Players.Add(player.userID, pinfo = new PlayerInfo() {
                TipsActive = true, isNew = true
            }
            );
            foreach (var action in _config.Actions.FindAll(s => s.IsEnabled() && types.Contains(s.Type))) {
                Lang_Action defaultLangAction = action.CachedLangActions[_config.DefaultLang];
                if (defaultLangAction.Replies == null || defaultLangAction.Replies.Count == 0) continue;
                if ((action.PlayerCanDisable && !pinfo.TipsActive) || !MessageIsEligible(action, player.UserIDString)) continue;
                bool toSend = false;
                if(AMTriggers.TryGetValue(action.Type, out AMTrigger amTrigger)) {
                    if (amTrigger.RequiresTarget) {
                        if (string.IsNullOrEmpty(target)) break;
                        switch (amTrigger.Key) {
                            case "ChatCommand" : if (action.Target.Replace("/", "").ToLower().Split(',').Any(x => x.Trim() == target)) toSend = true;
                            break;
                            default : if(action.Target == target) toSend = true;
                            break;
                        }
                    }
                    else {
                        switch (amTrigger.Key) {
                            case "NewPlayerJoined" : if (pinfo.isNew) toSend = true;
                            break;
                            case "PlayerConnected" : if (pinfo.justJoined) toSend = true;
                            break;
                            case "PlayerDead" : if (pinfo.wasDead && ((target == "" && !action.IsGlobalBroadcast) || (target == "FromEntityDeath" && action.IsGlobalBroadcast))) {
                                pinfo.wasDead = false;
                                toSend = true;
                            }
                            break;
                            default : toSend = true;
                            break;
                        }
                    }
                    if (amTrigger.UsesGenericCooldown && action.OnCooldownAll) toSend = false;
                    if (amTrigger.UsesPlayerCooldown && action.OnCooldown != null && action.OnCooldown.Contains(player.userID)) toSend = false;
                }
                if (toSend) {
                    if (action.IsGlobalBroadcast) ProcessReply(action, player, onlySendToTeam : onlySendToTeam);
                    else {
                        string playerLanguage = "";
                        Lang_Action langAction = null;
                        string reply = string.Empty;
                        if (Lang_TryGetAction(player, action.Type, action.Id, out playerLanguage, out langAction) && langAction.Replies.Count > 0) {
                            if (langAction.ReplyIndex >= langAction.Replies.Count) langAction.ReplyIndex = 0;
                            reply = langAction.Replies[langAction.ReplyIndex];
                            IncrementReplyIndex(ref langAction);
                        }
                        else {
                            langAction = action.CachedLangActions[_config.DefaultLang];
                            if (langAction.ReplyIndex >= langAction.Replies.Count) langAction.ReplyIndex = 0;
                            reply = langAction.Replies[langAction.ReplyIndex];
                            IncrementReplyIndex(ref langAction);
                        }
                        reply = FormatMessage(player, reply);
                        timer.Once(0.5f, () => {
                            SendMessage(player, reply, action.SendInChat, action.SendAsGameTip);
                        }
                        );
                    }
                    switch(action.Type) {
                        case "AutoReply" : action.RunCooldownAll(_config.AutoReplyCooldown);
                        break;
                        case "ChatCommand" : action.RunCooldownAll(_config.ChatCommandCooldown);
                        break;
                        case "EnteredZone" : action.RunCooldownPlayer(player, _config.ZoneManagerCooldown);
                        break;
                        case "LeftZone" : action.RunCooldownPlayer(player, _config.ZoneManagerCooldown);
                        break;
                        case "EnteredMonument" : action.RunCooldownPlayer(player, _config.MonumentWatcherCooldown);
                        break;
                        case "LeftMonument" : action.RunCooldownPlayer(player, _config.MonumentWatcherCooldown);
                        break;
                    }
                }
            }
            pinfo.isNew = false;
            pinfo.justJoined = false;
        }
        private void ProcessReply(PluginConfig.ConfigAction action, BasePlayer triggerOwner = null, Lang_Action defaultLangAction = null, bool onlySendToTeam = false) {
            if(defaultLangAction == null) defaultLangAction = action.CachedLangActions[_config.DefaultLang];
            if (defaultLangAction.Replies == null || defaultLangAction.Replies.Count == 0) return;
            if (triggerOwner != null && triggerOwner.IsAdmin && action.DontTriggerAdmin) return;
            List<string> incrementedLangIndex = Facepunch.Pool.Get<List<string>>();
            foreach (var player in BasePlayer.activePlayerList) {
                if(onlySendToTeam && triggerOwner.currentTeam != 0 && triggerOwner.currentTeam != player.currentTeam) continue;
                string playerLanguage = "";
                PlayerInfo pinfo;
                if (!pData.Players.TryGetValue(player.userID, out pinfo)) pData.Players.Add(player.userID, pinfo = new PlayerInfo() {
                    TipsActive = true, isNew = true
                }
                );
                if ((action.PlayerCanDisable && !pinfo.TipsActive) || !MessageIsEligible(action, player.UserIDString)) continue;
                string reply = string.Empty;
                if (Lang_TryGetAction(player, action.Type, action.Id, out playerLanguage, out Lang_Action playerlangAction) && playerlangAction.Replies.Count > 0) {
                    if (playerlangAction.ReplyIndex >= playerlangAction.Replies.Count) playerlangAction.ReplyIndex = 0;
                    reply = playerlangAction.Replies[playerlangAction.ReplyIndex];
                    if (!incrementedLangIndex.Contains(playerLanguage)) {
                        IncrementReplyIndex(ref playerlangAction);
                        incrementedLangIndex.Add(playerLanguage);
                    }
                }
                else {
                    if (defaultLangAction.ReplyIndex >= defaultLangAction.Replies.Count) defaultLangAction.ReplyIndex = 0;
                    reply = defaultLangAction.Replies[defaultLangAction.ReplyIndex];
                    if (!incrementedLangIndex.Contains(_config.DefaultLang)) {
                        IncrementReplyIndex(ref defaultLangAction);
                        incrementedLangIndex.Add(_config.DefaultLang);
                    }
                }
                reply = FormatMessage((triggerOwner == null) ? player : triggerOwner, reply);
                timer.Once(0.5f, () => {
                    SendMessage(player, reply, action.SendInChat, action.SendAsGameTip);
                }
                );
            }
            Facepunch.Pool.FreeUnmanaged<string>(ref incrementedLangIndex);
        }
        private void IncrementReplyIndex(ref Lang_Action lang_Action) {
            lang_Action.ReplyIndex++;
            if (lang_Action.ReplyIndex >= lang_Action.Replies.Count || lang_Action.ReplyIndex < 0) lang_Action.ReplyIndex = 0;
        }
        List<string> availableVariables = new List<string>() {
            "{playername}", "{playerid}", "{playercountry}", "{hacklocation}", "{wipetimeremaining}", "{online}", "{sleeping}", "{joining}"
        }
        ;
        private string FormatMessage(BasePlayer player, string message) {
            StringBuilder builder = new StringBuilder(message);
            builder.Replace("{playername}", player.displayName).Replace("{playerid}", player.UserIDString).Replace("{online}", $"{BasePlayer.activePlayerList.Count}").Replace("{sleeping}", $"{BasePlayer.sleepingPlayerList.Count}").Replace("{joining}", $"{ServerMgr.Instance.connectionQueue.Joining + ServerMgr.Instance.connectionQueue.Queued}");
            if (message.Contains("{playercountry}")) {
                PlayerInfo pinfo;
                bool found = pData.Players.TryGetValue(player.userID, out pinfo);
                if (found && !string.IsNullOrEmpty(pinfo.Country)) builder.Replace("{playercountry}", pinfo.Country);
                else builder.Replace("{playercountry}", "");
            }
            if (message.Contains("{wipetimeremaining}") && WipeTimer.serverinstance != null) {
                DateTimeOffset nowTime = DateTimeOffset.UtcNow;
                nowTime = nowTime.AddDays((double)WipeTimer.daysToAddTest);
                nowTime = nowTime.AddHours((double)WipeTimer.hoursToAddTest);
                DateTimeOffset wipeTime = WipeTimer.serverinstance.GetWipeTime(nowTime);
                TimeSpan timeSpan = wipeTime - nowTime;
                builder.Replace("{wipetimeremaining}", FormatTime(timeSpan, m : false, s : false));
            }
            if (message.Contains("{hacklocation}")) {
                PlayerInfo pinfo;
                bool found = pData.Players.TryGetValue(player.userID, out pinfo);
                if (found && !string.IsNullOrEmpty(pinfo.HackLocation)) builder.Replace("{hacklocation}", pinfo.HackLocation);
                else builder.Replace("{hacklocation}", GetGrid(player.transform.position));
            }
            if (PlaceholderAPI) {
                PlaceholderAPI?.CallHook("ProcessPlaceholders", player.IPlayer, builder);
            }
            return builder.ToString();
        }
        //Credit @Substrata
        string GetGrid(Vector3 pos) {
            float worldSize = TerrainMeta.Size.x;
            int cellCount = Mathf.FloorToInt((worldSize * 7) / 1024);
            float cellSize = worldSize / cellCount;
            int x = Mathf.FloorToInt((pos.x + (worldSize / 2)) / cellSize);
            int z = Mathf.FloorToInt((pos.z + (worldSize / 2)) / cellSize);
            char zChar = (char)('A' + (x % 26));
            string columnLabel = x < 26 ? zChar.ToString() : $"{(char)('A' + x / 26 - 1)}{zChar}";
            int row = cellCount - 1 - z;
            return $"{columnLabel}{row}";
        }
#endregion
#region Hooks
        void UnsubscribeHooks() {
            Unsubscribe(nameof(OnPlayerChat));
            Unsubscribe(nameof(OnPlayerDisconnected));
            Unsubscribe(nameof(CanHackCrate));
            Unsubscribe(nameof(OnEntityDeath));
            Unsubscribe(nameof(OnPlayerSleepEnded));
            Unsubscribe(nameof(OnUserPermissionGranted));
            Unsubscribe(nameof(OnUserPermissionRevoked));
            Unsubscribe(nameof(OnUserGroupAdded));
            Unsubscribe(nameof(OnUserGroupRemoved));
            Unsubscribe(nameof(OnEnterZone));
            Unsubscribe(nameof(OnExitZone));
            Unsubscribe(nameof(OnPlayerEnteredMonument));
            Unsubscribe(nameof(OnPlayerExitedMonument));
        }
        void SubscribeHooks() {
            foreach (var trigger in AMTriggers) {
                if (string.IsNullOrEmpty(trigger.Value.Hooks)) continue;
                if (_config.Actions.Any(s => s.Type == trigger.Key && s.IsEnabled())) foreach (string hook in trigger.Value.Hooks.Split(',')) Subscribe(hook);
            }
        }
        private void OnPlayerChat(BasePlayer player, string message, Chat.ChatChannel chatchannel) {
            if (chatchannel != Chat.ChatChannel.Global && chatchannel != Chat.ChatChannel.Team) return;
            foreach (var keywords in _autoReplyPatterns.Where(regex => regex.Key.Match(message).Success)) {
                NextTick(() => {
                    ProcessReplies(player, new List<string>() {
                        "AutoReply"
                    }
                    , (keywords.Value as PluginConfig.ConfigAction).Target, chatchannel == Chat.ChatChannel.Team && _config.BroadcastToTeamOnly);
                }
                );
            }
        }
        private void OnPlayerConnected(BasePlayer player) {
            if (!player.userID.IsSteamId()) return;
            PlayerInfo pinfo;
            if (pData.Players.TryGetValue(player.userID, out pinfo)) {
                pinfo.justJoined = true;
            }
            else {
                pData.Players.Add(player.userID, pinfo = new PlayerInfo() {
                    TipsActive = true, isNew = true, justJoined = !HasActiveNewPlayerJoinedAction
                }
                );
            }
            if (string.IsNullOrEmpty(pinfo.Country)) SetPlayerCountry(player, pinfo);
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            if (player != null) ProcessReplies(player, new List<string>() {
                "PlayerDisconnected"
            }
            );
        }
        private void CanHackCrate(BasePlayer player, HackableLockedCrate crate) {
            if (player != null && player.userID.IsSteamId()) {
                string Location = GetGrid(crate.transform.position);
                if (OnCargoShip(crate)) Location = "Cargo Ship";
                else {
                    MonumentRef monument = GetMonumentFromPosition(crate.transform.position);
                    if (monument != null) Location = $"{monument.DisplayName} ({Location})";
                }
                PlayerInfo pinfo;
                if (pData.Players.TryGetValue(player.userID, out pinfo)) {
                    pinfo.HackLocation = Location;
                }
                else {
                    pData.Players.Add(player.userID, pinfo = new PlayerInfo() {
                        TipsActive = true, HackLocation = Location
                    }
                    );
                }
                ProcessReplies(player, new List<string>() {
                    "CrateHacked"
                }
                );
            }
        }
        private void OnEntityDeath(BasePlayer player, HitInfo hitInfo) {
            if (player == null || !player.userID.IsSteamId()) return;
            PlayerInfo pinfo;
            if (pData.Players.TryGetValue(player.userID, out pinfo)) {
                pinfo.wasDead = true;
                ProcessReplies(player, new List<string>() {
                    "PlayerDead"
                }
                , "FromEntityDeath");
            }
        }
        private void OnPlayerSleepEnded(BasePlayer player) {
            if (player.IsDead() || !player.IsConnected) return;
            ProcessReplies(player, new List<string>() {
                "NewPlayerJoined", "PlayerConnected", "PlayerDead"
            }
            );
        }
        private void OnUserPermissionGranted(string id, string permName) {
            var player = BasePlayer.FindByID(Convert.ToUInt64(id));
            if (player != null) ProcessReplies(player, new List<string>() {
                "PermissionGranted"
            }
            , permName);
        }
        private void OnUserPermissionRevoked(string id, string permName) {
            var player = BasePlayer.FindByID(Convert.ToUInt64(id));
            if (player != null) ProcessReplies(player, new List<string>() {
                "PermissionRevoked"
            }
            , permName);
        }
        private void OnUserGroupAdded(string userId, string groupName) {
            var player = BasePlayer.FindByID(Convert.ToUInt64(userId));
            if (player != null) ProcessReplies(player, new List<string>() {
                "AddedToGroup"
            }
            , groupName);
        }
        private void OnUserGroupRemoved(string userId, string groupName) {
            var player = BasePlayer.FindByID(Convert.ToUInt64(userId));
            if (player != null) ProcessReplies(player, new List<string>() {
                "RemovedFromGroup"
            }
            , groupName);
        }
        private void OnEnterZone(string ZoneID, BasePlayer player) {
            if (player != null) ProcessReplies(player, new List<string>() {
                "EnteredZone"
            }
            , ZoneID);
        }
        private void OnExitZone(string ZoneID, BasePlayer player) {
            if (player != null) ProcessReplies(player, new List<string>() {
                "LeftZone"
            }
            , ZoneID);
        }
        private void OnPlayerEnteredMonument(string monumentID, BasePlayer player, string type, string oldMonumentID) {
            if (player != null) ProcessReplies(player, new List<string>() {
                "EnteredMonument"
            }
            , monumentID);
        }
        private void OnPlayerExitedMonument(string monumentID, BasePlayer player, string type, string reason, string newMonumentID) {
            if (player != null) ProcessReplies(player, new List<string>() {
                "LeftMonument"
            }
            , monumentID);
        }
#endregion
#region Commands
        private void TipsToggleChatCMD(IPlayer user, string command, string[] args) {
            var player = user.Object as BasePlayer;
            if (player == null) return;
            bool isActive = pData.ToggleTipsActive(player.userID);
            if (isActive) SendMessage(player, lang.GetMessage("toggle_enabled", this, player.UserIDString));
            else SendMessage(player, lang.GetMessage("toggle_disabled", this, player.UserIDString));
        }
        private void CustomChatCMD(IPlayer user, string command, string[] args) {
            var player = user.Object as BasePlayer;
            if (player == null) return;
            ProcessReplies(player, new List<string>() {
                "ChatCommand"
            }
            , command);
        }
#endregion
#region AMTrigger
        Dictionary<string, AMTrigger> AMTriggers;
        private class AMTrigger {
            public string Key {
                get;
                set;
            }
            public string Hooks {
                get;
                set;
            }
            public bool RequiresTarget {
                get;
                set;
            }
            public bool UsesIsGlobalBroadcast {
                get;
                set;
            }
            public bool UsesDontTriggerAdmin {
                get;
                set;
            }
            public bool UsesGenericCooldown {
                get;
                set;
            }
            public bool UsesPlayerCooldown {
                get;
                set;
            }
        }
        private void InitAMTriggers() {
            AMTriggers = new();
            AMTriggers.Add("Timed", new AMTrigger() {
                Key = "Timed", RequiresTarget = false
            }
            );
            AMTriggers.Add("ChatCommand", new AMTrigger() {
                Key = "ChatCommand", Hooks = "OnPlayerChat", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true, UsesGenericCooldown = true
            }
            );
            AMTriggers.Add("AutoReply", new AMTrigger() {
                Key = "AutoReply", Hooks = "OnPlayerChat", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true, UsesGenericCooldown = true
            }
            );
            AMTriggers.Add("NewPlayerJoined", new AMTrigger() {
                Key = "NewPlayerJoined", Hooks = "OnPlayerSleepEnded", RequiresTarget = false, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("PlayerConnected", new AMTrigger() {
                Key = "PlayerConnected", Hooks = "OnPlayerSleepEnded", RequiresTarget = false, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("PlayerDisconnected", new AMTrigger() {
                Key = "PlayerDisconnected", Hooks = "OnPlayerDisconnected", RequiresTarget = false, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("PermissionGranted", new AMTrigger() {
                Key = "PermissionGranted", Hooks = "OnUserPermissionGranted", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("PermissionRevoked", new AMTrigger() {
                Key = "PermissionRevoked", Hooks = "OnUserPermissionRevoked", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("AddedToGroup", new AMTrigger() {
                Key = "AddedToGroup", Hooks = "OnUserGroupAdded", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("RemovedFromGroup", new AMTrigger() {
                Key = "RemovedFromGroup", Hooks = "OnUserGroupRemoved", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("PlayerDead", new AMTrigger() {
                Key = "PlayerDead", Hooks = "OnEntityDeath,OnPlayerSleepEnded", RequiresTarget = false, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("CrateHacked", new AMTrigger() {
                Key = "CrateHacked", Hooks = "CanHackCrate", RequiresTarget = false, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true
            }
            );
            AMTriggers.Add("EnteredZone", new AMTrigger() {
                Key = "EnteredZone", Hooks = "OnEnterZone", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true, UsesPlayerCooldown = true
            }
            );
            AMTriggers.Add("LeftZone", new AMTrigger() {
                Key = "LeftZone", Hooks = "OnExitZone", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true, UsesPlayerCooldown = true
            }
            );
            AMTriggers.Add("EnteredMonument", new AMTrigger() {
                Key = "EnteredMonument", Hooks = "OnPlayerEnteredMonument", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true, UsesPlayerCooldown = true
            }
            );
            AMTriggers.Add("LeftMonument", new AMTrigger() {
                Key = "LeftMonument", Hooks = "OnPlayerExitedMonument", RequiresTarget = true, UsesIsGlobalBroadcast = true, UsesDontTriggerAdmin = true, UsesPlayerCooldown = true
            }
            );
        }
#endregion
#region Config
        bool HasActiveNewPlayerJoinedAction = false;
        void ProcessConfig() {
            HasActiveNewPlayerJoinedAction = _config.Actions.Any(s => s.Type == "NewPlayerJoined" && s.IsEnabled());
            Lang_CacheActions();
        }
        private class PluginConfig {
            [JsonProperty(Order = 1000)]
            public Oxide.Core.VersionNumber Version;
            [JsonProperty(Order = 1, PropertyName = "Chat Icon (Steam Id)")]
            public string IconSteamId {
                get;
                set;
            }
            [JsonProperty(Order = 2, PropertyName = "Toggle Chat Command")]
            public string ToggleCommand {
                get;
                set;
            }
            [JsonProperty(Order = 3, PropertyName = "AutoReply Cooldown (in seconds)")]
            public int AutoReplyCooldown {
                get;
                set;
            }
            [JsonProperty(Order = 4, PropertyName = "ChatCommand Cooldown (in seconds)")]
            public int ChatCommandCooldown {
                get;
                set;
            }
            [JsonProperty(Order = 5, PropertyName = "ZoneManager Cooldown (in seconds)")]
            public int ZoneManagerCooldown {
                get;
                set;
            }
            [JsonProperty(Order = 6, PropertyName = "MonumentWatcher Cooldown (in seconds)")]
            public int MonumentWatcherCooldown {
                get;
                set;
            }
            [JsonProperty(Order = 7, PropertyName = "Sample Types for Reference (Do Not Edit)")]
            public string SampleTypes {
                get;
                set;
            }
            [JsonProperty(Order = 8, PropertyName = "Replies Server Languages (Creates lang file for each in data/AutomatedMessages/lang)")]
            public List<string> ServerLangs {
                get;
                set;
            }
            [JsonProperty(Order = 9, PropertyName = "Default Server Language")]
            public string DefaultLang {
                get;
                set;
            }
            [JsonProperty(Order = 10, PropertyName = "AutoReply `Broadcast to all` option to broadcast to team only if keywords sent from team chat")]
            public bool BroadcastToTeamOnly {
                get;
                set;
            }
            [JsonProperty(Order = 11, PropertyName = "Actions")]
            public List<ConfigAction> Actions {
                get;
                set;
            }
            [JsonProperty("Chat Icon (SteamId)")]
            public ulong _ObsIconSteamId {
                get;
                set;
            }
            [JsonProperty("Messages")]
            public List<ConfigAction> _ObsMessages = null;
            public bool ShouldSerialize_ObsMessages() => _ObsMessages != null;
            internal class ConfigAction {
                [JsonProperty("Id")]
                public string Id = GenerateId();
                [JsonProperty(Order = 0, PropertyName = "Enabled")]
                public bool Enabled {
                    get;
                    set;
                }
                [JsonProperty("Type (Check Sample Types above for Reference)")]
                public string Type = "";
                [JsonProperty("Broadcast to all?")]
                public bool IsGlobalBroadcast {
                    get;
                    set;
                }
                [JsonProperty("Don't trigger for admins")]
                public bool DontTriggerAdmin {
                    get;
                    set;
                }
                [JsonProperty("Send in chat")]
                public bool SendInChat = true;
                [JsonProperty("Send as game tip")]
                public bool SendAsGameTip {
                    get;
                    set;
                }
                [JsonProperty("Interval between messages in minutes (if Type = Timed)")]
                public int Interval = 0;
                [JsonProperty("Target")]
                public string Target = "";
                [JsonProperty("Permissions")]
                public List<string> Permissions = new();
                [JsonProperty("Groups")]
                public List<string> Groups = new();
                [JsonProperty("Blacklisted Permissions")]
                public List<string> BlacklistedPerms = new();
                [JsonProperty("Blacklisted Groups")]
                public List<string> BlacklistedGroups = new();
                [JsonProperty("Player Can Disable?")]
                public bool PlayerCanDisable {
                    get;
                    set;
                }
                [JsonIgnore]
                public bool OnCooldownAll = false;
                [JsonIgnore]
                public List<ulong> OnCooldown {
                    get;
                    set;
                }
                [JsonIgnore]
                public Dictionary<string, Lang_Action> CachedLangActions {
                    get;
                    set;
                }
                [JsonProperty("Messages (Random if more than one)")]
                public List<string> _ObsMessages = null;
                [JsonProperty("Replies")]
                public List<string> _ObsReplies = null;
                public void RunCooldownAll(int cooldown) {
                    if (cooldown <= 0) return;
                    OnCooldownAll = true;
                    _plugin.timer.Once(cooldown, () => {
                        OnCooldownAll = false;
                    }
                    );
                }
                public void RunCooldownPlayer(BasePlayer player, int cooldown) {
                    OnCooldown ??= new();
                    if (cooldown <= 0 || OnCooldown.Contains(player.userID)) return;
                    OnCooldown.Add(player.userID);
                    _plugin.timer.Once(cooldown, () => {
                        OnCooldown.Remove(player.userID);
                    }
                    );
                }
                public ConfigAction Clone(bool newGuid = false) {
                    return new ConfigAction() {
                        Id = newGuid ? GenerateId() : Id, Enabled = Enabled, Type = Type, IsGlobalBroadcast = IsGlobalBroadcast, DontTriggerAdmin = DontTriggerAdmin, SendInChat = SendInChat, SendAsGameTip = SendAsGameTip, Interval = Interval, Target = Target, Permissions = new (Permissions), Groups = new (Groups), BlacklistedPerms = new (BlacklistedPerms), BlacklistedGroups = new (BlacklistedGroups), PlayerCanDisable = PlayerCanDisable, CachedLangActions = null
                    }
                    ;
                }
                public bool ShouldSerialize_ObsMessages() => _ObsMessages != null;
                public bool ShouldSerialize_ObsReplies() => _ObsReplies != null;
                public static string GenerateId() {
                    ulong timestamp = (ulong)DateTime.UtcNow.Ticks;
                    uint randomPart = (uint)UnityEngine.Random.Range(0, int.MaxValue);
                    return ((timestamp << 32) | randomPart).ToString();
                }
                public bool IsEnabled() => Enabled && (SendInChat || SendAsGameTip) ? true : false;
            }
            public bool ShouldSerialize_ObsIconSteamId() => _ObsIconSteamId != 0;
        }
        private PluginConfig GetDefaultConfig() {
            PluginConfig result = new PluginConfig {
                IconSteamId = "0", Version = Version, ToggleCommand = "tips", AutoReplyCooldown = 30, ChatCommandCooldown = 30, ZoneManagerCooldown = 0, MonumentWatcherCooldown = 15, SampleTypes = string.Join(" | ", AMTriggers.Keys), ServerLangs = new List<string>() {
                    "en", "es", "it", "ru", "zh"
                }
                , DefaultLang = lang.GetServerLanguage(), BroadcastToTeamOnly = true, Actions = new List<PluginConfig.ConfigAction>()
            }
            ;
            return result;
        }
        private void CheckForConfigUpdates() {
            bool changes = false;
            if (_config == null) {
                PluginConfig tmpDefaultConfig = GetDefaultConfig();
                _config = tmpDefaultConfig;
                changes = true;
            }
            string sampleTypes = string.Join(" | ", AMTriggers.Keys);
            if(_config.SampleTypes != sampleTypes) {
                _config.SampleTypes = sampleTypes;
                changes = true;
            }
            //1.0.8 update
            if (_config.Version == null || _config.Version < new VersionNumber(1, 0, 8)) {
                PluginConfig tmpDefaultConfig = GetDefaultConfig();
                _config.ToggleCommand = tmpDefaultConfig.ToggleCommand;
                changes = true;
            }
            //1.0.16 update
            if (_config.Version < new VersionNumber(1, 0, 16)) {
                PluginConfig tmpDefaultConfig = GetDefaultConfig();
                _config.AutoReplyCooldown = tmpDefaultConfig.AutoReplyCooldown;
                changes = true;
            }
            //2.0.0 update
            if (_config.Version < new VersionNumber(2, 0, 0)) {
                if (_config._ObsMessages != null) _config.Actions = new List<PluginConfig.ConfigAction>(_config._ObsMessages);
                else _config.Actions = new();
                _config._ObsMessages = null;
                foreach (var action in _config.Actions) {
                    if (action._ObsMessages != null) action._ObsReplies = new List<string>(action._ObsMessages);
                    else action._ObsReplies = new();
                    action._ObsMessages = null;
                }
                changes = true;
            }
            if(string.IsNullOrEmpty(_config.DefaultLang) || !AvailableLangs.ContainsKey(_config.DefaultLang)) {
                _config.DefaultLang = lang.GetServerLanguage();
                changes = true;
            }
            //2.0.6 update
            if (_config.Version < new VersionNumber(2, 0, 6)) {
                PluginConfig tmpDefaultConfig = GetDefaultConfig();
                _config.ServerLangs = _config.ServerLangs;
                _config.IconSteamId = _config._ObsIconSteamId.ToString();
                _config._ObsIconSteamId = 0;
                _config.ChatCommandCooldown = tmpDefaultConfig.ChatCommandCooldown;
                _config.ZoneManagerCooldown = tmpDefaultConfig.ZoneManagerCooldown;
                _config.MonumentWatcherCooldown = tmpDefaultConfig.MonumentWatcherCooldown;
                _config.ServerLangs = new List<string>() {
                    _config.DefaultLang
                }
                ;
                RepliesLangData = new();
                foreach (string serverLang in _config.ServerLangs) {
                    if (!AvailableLangs.ContainsKey(serverLang)) continue;
                    if (RepliesLangData.ContainsKey(serverLang)) continue;
                    Lang_Root langRoot = new();
                    foreach (var amTrigger in AMTriggers) if (!langRoot.Triggers.ContainsKey(amTrigger.Key)) {
                        langRoot.Triggers.Add(amTrigger.Key, new());
                        changes = true;
                    }
                    RepliesLangData.Add(serverLang, langRoot);
                }
                foreach (var action in _config.Actions) {
                    if (action._ObsReplies != null) {
                        foreach (var langRoot in RepliesLangData) {
                            if(langRoot.Value.Triggers.TryGetValue(action.Type, out Lang_Trigger langTrigger)) {
                                langTrigger.Actions ??= new();
                                if(langRoot.Key == _config.DefaultLang) langTrigger.Actions.Add(action.Id, new() {
                                    Replies = action._ObsReplies
                                }
                                );
                                else langTrigger.Actions.Add(action.Id, new());
                            }
                        }
                        action._ObsReplies = null;
                    }
                }
                Lang_SaveRepliesData();
                changes = true;
            }
            else Lang_LoadRepliesData();
            if (_config.ServerLangs == null || _config.ServerLangs.Count == 0) {
                _config.ServerLangs = new List<string>() {
                    lang.GetServerLanguage()
                }
                ;
                changes = true;
            }
            var langsToRemove = _config.ServerLangs.Where(s => !AvailableLangs.ContainsKey(s));
            if (langsToRemove.Length > 0) {
                PrintWarning($"Language code{(langsToRemove.Length > 1 ? "s" : "")} \"{string.Join(", ", langsToRemove)}\" {(langsToRemove.Length > 1 ? "are" : "is")} not available or not in correct code (removed from config), the following are the available options:\n{string.Join(", ", AvailableLangs.Keys)}.");
                for (int i = 0; i < langsToRemove.Length; i++) _config.ServerLangs.Remove(langsToRemove[i]);
                changes = true;
            }
            //2.0.9 update
            if (_config.Version < new VersionNumber(2, 0, 9)) {
                _config.BroadcastToTeamOnly = true;
                changes = true;
            }
            if (_config.Version != Version) changes = true;
            if (changes) {
                _config.Version = Version;
                PrintWarning("Config updated.");
                SaveConfig();
            }
        }
        protected override void LoadDefaultConfig() => _config = GetDefaultConfig();
        protected override void LoadConfig() {
            InitAMTriggers();
            base.LoadConfig();
            _config = Config.ReadObject<PluginConfig>();
            CheckForConfigUpdates();
        }
        protected override void SaveConfig() {
            Config.WriteObject(_config);
        }
#endregion
#region Data
        public PlayersData pData;
        private void OnServerSave() => timer.Once(UnityEngine.Random.Range(5f, 10f), SaveData);
        private bool wiped {
            get;
            set;
        }
        private void OnNewSave(string filename) => wiped = true;
        private void SaveData() {
            if (pData != null) pData.Save();
        }
        public class PlayersData {
            public Dictionary<ulong, PlayerInfo> Players = new();
            public static PlayersData Load() {
                var data = Interface.Oxide.DataFileSystem.ReadObject<PlayersData>($"{nameof(AutomatedMessages)}/PlayerData");
                if (data == null || _plugin.wiped) {
                    _plugin.PrintWarning("No player data found! Creating a new data file.");
                    data = new();
                    data.Save();
                }
                return data;
            }
            public void Save() {
                Interface.Oxide.DataFileSystem.WriteObject($"{nameof(AutomatedMessages)}/PlayerData", this);
            }
            public bool CheckIfNew(ulong playerid) {
                return !Players.ContainsKey(playerid);
            }
            public void EnableTips(ulong playerid, bool active) {
                PlayerInfo playerInfo;
                if (!Players.TryGetValue(playerid, out playerInfo)) Players.Add(playerid, playerInfo = new PlayerInfo() {
                    TipsActive = active, isNew = true
                }
                );
                else playerInfo.TipsActive = active;
            }
            public bool ToggleTipsActive(ulong playerid) {
                PlayerInfo playerInfo;
                if (!Players.TryGetValue(playerid, out playerInfo)) Players.Add(playerid, playerInfo = new PlayerInfo() {
                    TipsActive = true, isNew = true
                }
                );
                else playerInfo.TipsActive = !playerInfo.TipsActive;
                return playerInfo.TipsActive;
            }
            public bool IsActive(ulong playerid) {
                PlayerInfo playerInfo;
                if (!Players.TryGetValue(playerid, out playerInfo)) {
                    return true;
                }
                else {
                    return playerInfo.TipsActive;
                }
            }
        }
        public class PlayerInfo {
            public string Country = "";
            public bool TipsActive = true;
            [JsonIgnore]
            public bool wasDead = false;
            [JsonIgnore]
            public bool justJoined = false;
            [JsonIgnore]
            public bool isNew = false;
            [JsonIgnore]
            public string HackLocation = "";
        }
#endregion
#region Helpers
        private void SendMessage(BasePlayer player, string message, bool SendInChat = true, bool SendAsGameTip = false) {
            if (player == null) return;
            if (SendInChat) {
                ulong iconSteamId = 0;
                ul
// ... [Code preview truncated due to length. Full source in attached file] ...

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