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

FREE NoEscapeSimpleStatus : 1.2.0 1.2.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using UnityEngine;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
using System.Collections.Generic;
using Newtonsoft.Json;
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;

namespace Oxide.Plugins
{
    [Info("NoEscapeSimpleStatus", "Nogard", "1.2.0")]
    [Description("Detects when a player enters or leaves raid or combat lock")]
    internal class NoEscapeSimpleStatus : RustPlugin
    {
        #region Fields

        private readonly HashSet<BasePlayer> _combatBlockedPlayers = new();
        private readonly HashSet<BasePlayer> _raidBlockedPlayers = new();
        private readonly Dictionary<BasePlayer, float> _statusTimers = new();
        private readonly Dictionary<ulong, PlayerStatusMonitor> _playerMonitors = new();

        private ConfigFile _config;

        [PluginReference] private Plugin NoEscape, SimpleStatus, ImageLibrary;

        #endregion


        #region Classes

        public class ConfigFile
        {
            [JsonProperty(PropertyName = "General")]
            public GeneralSettings General { get; set; }

            [JsonProperty(PropertyName = "Blockages")]
            public BlockageSettings Blockages { get; set; }

            public class GeneralSettings
            {
                [JsonProperty(PropertyName = "Only with permission")]
                public bool OnlyWithPermission { get; set; }

                [JsonProperty(PropertyName = "Permissions")]
                public Dictionary<PermissionType, string> Permissions { get; set; }
            }

            public class BlockageSettings
            {
                public BlockageConfig Combat { get; set; }
                public BlockageConfig Raid { get; set; }
            }

            public class BlockageConfig
            {
                [JsonProperty(PropertyName = "Enabled")]
                public bool Enabled { get; set; }

                [JsonProperty(PropertyName = "Duration set in NoEscape plugin settings")]
                public int Duration { get; set; }

                [JsonProperty(PropertyName = "Simple Status Settings")]
                public SimpleStatusConfig SimpleStatus { get; set; }
            }

            public class SimpleStatusConfig
            {
                [JsonProperty(PropertyName = "Title")]
                public string Title { get; set; }

                [JsonProperty(PropertyName = "Title Color (RGB Hexadecimal format)")]
                public string TitleColor { get; set; }

                [JsonProperty(PropertyName = "Text Color (RGB Hexadecimal format)")]
                public string TextColor { get; set; }

                [JsonProperty(PropertyName = "Background Color (RGB Hexadecimal format)")]
                public string BackgroundColor { get; set; }

                [JsonProperty(PropertyName = "Icon URL")]
                public string IconURL { get; set; }

                [JsonProperty(PropertyName = "Icon Color (RGB Hexadecimal format)")]
                public string IconColor { get; set; }
            }

            public enum PermissionType
            {
                Combat,
                Raid
            }

            public static ConfigFile DefaultConfig()
            {
                return new ConfigFile()
                {
                    General = new GeneralSettings()
                    {
                        OnlyWithPermission = false,
                        Permissions = new Dictionary<PermissionType, string>
                        {
                            { PermissionType.Combat, "noescapesimplestatus.combat" },
                            { PermissionType.Raid, "noescapesimplestatus.raid" }
                        }
                    },
                    Blockages = new BlockageSettings()
                    {
                        Combat = new BlockageConfig()
                        {
                            Enabled = true,
                            Duration = 180,
                            SimpleStatus = new SimpleStatusConfig()
                            {
                                Title = "Combat",
                                TitleColor = "#E9C6C1",
                                TextColor = "#E9C6C1",
                                BackgroundColor = "#C53D28",
                                IconURL = "https://i.postimg.cc/65SyPLf2/espada.png",
                                IconColor = "#E9C6C1",
                            }
                        },
                        Raid = new BlockageConfig()
                        {
                            Enabled = true,
                            Duration = 300,
                            SimpleStatus = new SimpleStatusConfig()
                            {
                                Title = "Raid",
                                TitleColor = "#419CDC",
                                TextColor = "#419CDC",
                                BackgroundColor = "#164163",
                                IconURL = "https://i.postimg.cc/dVNXK3Sx/explosion.png",
                                IconColor = "#419CDC",
                            }
                        }
                    }
                };
            }
        }

        public class PlayerStatusMonitor : MonoBehaviour
        {
            private BasePlayer _player;
            private NoEscapeSimpleStatus _plugin;
            private float _combatCheckTime;
            private float _raidCheckTime;
            private const float CHECK_INTERVAL = 0.5f;

            public void Initialize(NoEscapeSimpleStatus plugin, BasePlayer player)
            {
                _plugin = plugin;
                _player = player;
                _combatCheckTime = 0f;
                _raidCheckTime = 0f;
            }

            void Update()
            {
                if (_player == null || _plugin == null || _plugin.NoEscape == null)
                {
                    Destroy(this);
                    return;
                }

                float time = Time.time;

                if (time >= _combatCheckTime)
                {
                    _plugin.HandleBlockState(_player, "combat", _plugin._combatBlockedPlayers, "IsCombatBlocked", ConfigFile.PermissionType.Combat);
                    _combatCheckTime = time + CHECK_INTERVAL;
                }

                if (time >= _raidCheckTime)
                {
                    _plugin.HandleBlockState(_player, "raid", _plugin._raidBlockedPlayers, "IsRaidBlocked", ConfigFile.PermissionType.Raid);
                    _raidCheckTime = time + CHECK_INTERVAL;
                }
            }

            void OnDestroy()
            {
                if (_plugin != null && _player != null)
                {
                    _plugin._combatBlockedPlayers.Remove(_player);
                    _plugin._raidBlockedPlayers.Remove(_player);
                    _plugin._statusTimers.Remove(_player);

                    if (_plugin._playerMonitors.ContainsKey(_player.userID))
                    {
                        _plugin._playerMonitors.Remove(_player.userID);
                    }

                    if (_plugin.SimpleStatus != null)
                    {
                        _plugin.SimpleStatus.Call("SetStatus", _player.UserIDString, "combat", 0);
                        _plugin.SimpleStatus.Call("SetStatus", _player.UserIDString, "raid", 0);
                    }
                }
            }
        }

        #endregion


        #region Hooks
        protected override void LoadDefaultConfig() => _config = ConfigFile.DefaultConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<ConfigFile>() ?? ConfigFile.DefaultConfig();
            }
            catch (Exception ex)
            {
                PrintError($"Configuration error: {ex.Message}");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(_config, true);

        void Init()
        {
            foreach (var permissionEntry in _config.General.Permissions.Values)
                permission.RegisterPermission(permissionEntry, this);

            _combatBlockedPlayers.Clear();
            _raidBlockedPlayers.Clear();
            _statusTimers.Clear();
            _playerMonitors.Clear();
        }

        void OnServerInitialized()
        {
            if (!VerifyDependencies())
                return;

            InitializeImages();
            OnSimpleStatusReady();
            InitializeExistingPlayers();
        }

        private void OnServerSave() => SaveConfig();

        void OnPlayerConnected(BasePlayer player)
        {
            NextTick(() => AttachMonitorToPlayer(player));
        }

        void OnPlayerDisconnected(BasePlayer player)
        {
            if (player == null)
                return;

            if (_playerMonitors.TryGetValue(player.userID, out PlayerStatusMonitor monitor))
            {
                if (monitor != null)
                {
                    UnityEngine.Object.Destroy(monitor.gameObject);
                }
                _playerMonitors.Remove(player.userID);
            }

            _combatBlockedPlayers.Remove(player);
            _raidBlockedPlayers.Remove(player);
            _statusTimers.Remove(player);
        }

        void Unload()
        {
            foreach (var monitor in _playerMonitors.Values)
            {
                if (monitor != null)
                {
                    UnityEngine.Object.Destroy(monitor.gameObject);
                }
            }

            _playerMonitors.Clear();
            _combatBlockedPlayers.Clear();
            _raidBlockedPlayers.Clear();
            _statusTimers.Clear();
        }
        #endregion


        #region Helper Methods

        private int GetNoEscapeTimeRemaining(BasePlayer player, string blockType)
        {
            object result = NoEscape.Call("GetRemainingBlockTime", player, blockType);
            return result is float ? (int)Math.Ceiling((float)result) : 0;
        }

        private void HandleBlockState(BasePlayer player, string statusKey, HashSet<BasePlayer> blockedPlayers, string noEscapeMethod, ConfigFile.PermissionType permissionType)
        {
            if (player == null || NoEscape == null || SimpleStatus == null)
                return;

            bool isBlocked = (bool)NoEscape.Call(noEscapeMethod, player);
            bool wasBlocked = blockedPlayers.Contains(player);
            ConfigFile.BlockageConfig settings = statusKey == "raid" ? _config.Blockages.Raid : _config.Blockages.Combat;

            if (isBlocked && settings.Enabled)
            {
                if (_config.General.OnlyWithPermission && !permission.UserHasPermission(player.UserIDString, _config.General.Permissions[permissionType]))
                    return;

                int noEscapeTimeRemaining = GetNoEscapeTimeRemaining(player, statusKey);

                if (!wasBlocked)
                {
                    blockedPlayers.Add(player);
                    _statusTimers[player] = noEscapeTimeRemaining;
                    SimpleStatus.Call("SetStatus", player.UserIDString, statusKey, noEscapeTimeRemaining, false);
                    Interface.CallHook($"OnPlayerEnter{char.ToUpper(statusKey[0]) + statusKey.Substring(1)}Block", player);
                }
                else if (!_statusTimers.ContainsKey(player) || Math.Abs(_statusTimers[player] - noEscapeTimeRemaining) > 1f)
                {
                    _statusTimers[player] = noEscapeTimeRemaining;
                    SimpleStatus.Call("SetStatus", player.UserIDString, statusKey, noEscapeTimeRemaining, false);
                }
            }
            else if (!isBlocked && wasBlocked)
            {
                blockedPlayers.Remove(player);
                if (_statusTimers.ContainsKey(player))
                {
                    _statusTimers.Remove(player);
                }
                SimpleStatus.Call("SetStatus", player.UserIDString, statusKey, 0);
                Interface.CallHook($"OnPlayerExit{char.ToUpper(statusKey[0]) + statusKey.Substring(1)}Block", player);
            }
        }

        private void OnSimpleStatusReady()
        {
            SimpleStatus.CallHook("CreateStatus", this, "raid", new Dictionary<string, object>
            {
                ["color"] = ConvertHexToRgba(_config.Blockages.Raid.SimpleStatus.BackgroundColor),
                ["title"] = _config.Blockages.Raid.SimpleStatus.Title,
                ["titleColor"] = ConvertHexToRgba(_config.Blockages.Raid.SimpleStatus.TitleColor),
                ["text"] = null,
                ["textColor"] = ConvertHexToRgba(_config.Blockages.Raid.SimpleStatus.TextColor),
                ["icon"] = "raid",
                ["iconColor"] = ConvertHexToRgba(_config.Blockages.Raid.SimpleStatus.IconColor),
            });

            SimpleStatus.CallHook("CreateStatus", this, "combat", new Dictionary<string, object>
            {
                ["color"] = ConvertHexToRgba(_config.Blockages.Combat.SimpleStatus.BackgroundColor),
                ["title"] = _config.Blockages.Combat.SimpleStatus.Title,
                ["titleColor"] = ConvertHexToRgba(_config.Blockages.Combat.SimpleStatus.TitleColor),
                ["text"] = null,
                ["textColor"] = ConvertHexToRgba(_config.Blockages.Combat.SimpleStatus.TextColor),
                ["icon"] = "combat",
                ["iconColor"] = ConvertHexToRgba(_config.Blockages.Combat.SimpleStatus.IconColor),
            });
        }

        private string ConvertHexToRgba(string hex)
        {
            if (string.IsNullOrWhiteSpace(hex))
                return "Invalid Input";

            if (hex.StartsWith("#"))
                hex = hex.Substring(1);

            if (hex.Length != 6 && hex.Length != 8)
                return "Invalid Input";

            int red = 0;
            int green = 0;
            int blue = 0;

            bool parsed = int.TryParse(hex.Substring(0, 2), NumberStyles.HexNumber, null, out red) &&
                          int.TryParse(hex.Substring(2, 2), NumberStyles.HexNumber, null, out green) &&
                          int.TryParse(hex.Substring(4, 2), NumberStyles.HexNumber, null, out blue);

            float alpha = 1.0f;

            if (hex.Length == 8)
            {
                parsed &= int.TryParse(hex.Substring(6, 2), NumberStyles.HexNumber, null, out int alphaInt);
                alpha = alphaInt / 255f;
            }

            if (!parsed)
                return "Invalid Input";

            return $"{(red / 255f):0.00} {(green / 255f):0.00} {(blue / 255f):0.00} {alpha:0.00}";
        }

        private void InitializeImages()
        {
            try
            {
                ImageLibrary.Call("AddImage", _config.Blockages.Raid.SimpleStatus.IconURL, "raid", 0UL);
                ImageLibrary.Call("AddImage", _config.Blockages.Combat.SimpleStatus.IconURL, "combat", 0UL);
            }
            catch (Exception ex)
            {
                PrintError($"Error initializing images: {ex.Message}");
            }
        }

        private bool VerifyDependencies()
        {
            if (!NoEscape)
            {
                PrintError("NoEscape plugin not found or not loaded!");
                return false;
            }

            if (!SimpleStatus)
            {
                PrintError("SimpleStatus plugin not found or not loaded!");
                return false;
            }

            if (!ImageLibrary)
            {
                PrintError("ImageLibrary plugin not found or not loaded!");
                return false;
            }

            return true;
        }

        private void AttachMonitorToPlayer(BasePlayer player)
        {
            if (player == null || player.IsDestroyed || !player.IsConnected)
                return;

            try
            {
                if (_playerMonitors.ContainsKey(player.userID))
                    return;

                GameObject monitorObj = new GameObject("StatusMonitor");
                monitorObj.transform.SetParent(player.transform);

                PlayerStatusMonitor monitor = monitorObj.AddComponent<PlayerStatusMonitor>();
                monitor.Initialize(this, player);

                _playerMonitors[player.userID] = monitor;
            }
            catch (Exception ex)
            {
                PrintError($"Error attaching monitor to player {player.displayName}: {ex.Message}");
            }
        }

        private void InitializeExistingPlayers()
        {
            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                if (player.IsConnected)
                {
                    AttachMonitorToPlayer(player);
                }
            }
        }

        #endregion
    }
}

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