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

FREE CombatBlock : 1.1.1 1.1.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core;
using ConVar;
using System.Text;
using UnityEngine.Networking;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core.Libraries;
using System;
using Oxide.Plugins.CombatBlockExt;
using Oxide.Core.Plugins;
using System.Collections;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Globalization;
using Time = UnityEngine.Time;
namespace Oxide.Plugins.CombatBlockExt {
    public static class ExtensionMethods {
        private static readonly Lang Lang = Interface.Oxide.GetLibrary<Lang>();
        public static string GetAdaptedMessage(this string langKey, string userID = null, params object[] args) {
            string message = Lang.GetMessage(langKey, CombatBlock.Instance, userID);
            if (args == null || args.Length == 0) {
                return message;
            }
            return new StringBuilder().AppendFormat(message, args).ToString();
        }
        public static string ToTimeFormat(this float source) {
            TimeSpan ts = TimeSpan.FromSeconds(source);
            return $"{ts.Minutes:D1}:{ts.Seconds:D2}";
        }
    }
}
namespace Oxide.Plugins {
    [Info("CombatBlock", "Mercury", "1.1.1")]
    public class CombatBlock : RustPlugin {
        private static void RunEffect(BasePlayer player, string prefab) {
            Effect effect = new Effect();
            effect.Init(Effect.Type.Generic, player.transform.position, Vector3.zero);
            effect.pooledString = prefab;
            EffectNetwork.Send(effect, player.net.connection);
        }
        private List<BasePlayer> _playerInCache = new();
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) {
                    throw new Exception();
                }
                SaveConfig();
            }
            catch {
                for (int i = 0; i < 3; i++) {
                    PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
                }
                LoadDefaultConfig();
            }
            ValidateConfig();
            SaveConfig();
        }
        private void OnRaidBlock(BasePlayer player, Vector3 position) {
            if (player != null && player.gameObject != null) {
                if (player.gameObject.TryGetComponent(out CombatPlayer combatBlocker)) combatBlocker.KillComponent(true);
            }
        }
        private void OnPlayerConnected(BasePlayer player) {
            if (player.TryGetComponent(out CombatPlayer rp)) rp.CreateUI();
        }
        private Boolean IsCombatBlock(BasePlayer player) {
            if (!_combatPlayers.ContainsKey(player)) return false;
            CombatPlayer combatP = _combatPlayers[player];
            if (combatP == null) return false;
            if (combatP.UnblockTimeLeft <= 0) return false;
            return true;
        }
        private void DrawUI_CB_Main(BasePlayer player, float timeLeft = 0f) {
            string Interface = InterfaceBuilder.GetInterface(InterfaceBuilder.CB_MAIN);
            if (Interface == null) return;
            Interface = InterfaceBuilder.TypeUi switch {
                0 => Interface.Replace("%Descriptions%", "COMBATBLOCK_UI_DESCRIPTIONS_V1".GetAdaptedMessage(player.UserIDString)), 1 => Interface.Replace("%Descriptions%", "COMBATBLOCK_UI_DESCRIPTIONS_V2".GetAdaptedMessage(player.UserIDString)), _ => Interface
            }
            ;
            Interface = Interface.Replace("%Title%", "COMBATBLOCK_UI_TITLE".GetAdaptedMessage(player.UserIDString));
            CuiHelper.DestroyUi(player, InterfaceBuilder.CB_MAIN);
            CuiHelper.AddUi(player, Interface);
            DrawUI_CB_Updated(player, timeLeft == 0 ? config.CombatBlockMain.CombatBlockDuration : timeLeft, true);
        }
        private bool IsDuel(ulong userID) {
            object playerId = ObjectCache.Get(userID);
            BasePlayer player = null;
            if (Duel != null || Duelist != null) player = BasePlayer.FindByID(userID);
            object result = EventHelper?.Call("EMAtEvent", playerId);
            if (result is bool && ((bool)result) == true) return true;
            if (Battles != null && Battles.Call<bool>("IsPlayerOnBattle", playerId)) return true;
            if (Duel != null && Duel.Call<bool>("IsPlayerOnActiveDuel", player)) return true;
            if (Duelist != null && Duelist.Call<bool>("inEvent", player)) return true;
            if (ArenaTournament != null && ArenaTournament.Call<bool>("IsOnTournament", playerId)) return true;
            return false;
        }
        private Dictionary<BasePlayer , CombatPlayer> _combatPlayers = new();
        private Boolean IsCombatBlocked(BasePlayer player) => IsCombatBlock(player);
        private static ImageUI _imageUI;
        private object canTeleport(BasePlayer player) => CanTeleport(player);
        private class CombatPlayer : FacepunchBehaviour {
            public BasePlayer player;
            private float _timeToUnblock;
            private int _combatBlockDuration;
            public float UnblockTimeLeft => _timeToUnblock - Time.realtimeSinceStartup;
            private void Awake() {
                player = gameObject.GetComponent<BasePlayer>();
                _combatBlockDuration = Instance.config.CombatBlockMain.CombatBlockDuration;
                _timeToUnblock = Time.realtimeSinceStartup + _combatBlockDuration;
                CreateUI();
                InvokeRepeating(RefreshUI, 0f, 1);
                Instance.SendChat("COMBATBLOCK_ENTER_COMBAT_INITIATOR".GetAdaptedMessage(player.UserIDString, UnblockTimeLeft.ToTimeFormat()), player);
            }
            private void OnDestroy() {
                Interface.CallHook ("OnCombatBlockStopped", player);
            }
            public void UpdateBlockTime() {
                _timeToUnblock = Time.realtimeSinceStartup + _combatBlockDuration;
            }
            public void CreateUI() {
                if (player != null) {
                    Instance.DrawUI_CB_Main(player, UnblockTimeLeft);
                }
            }
            public void KillComponent(bool isRaidBlocked = false) {
                if (player != null) CuiHelper.DestroyUi(player, InterfaceBuilder.CB_MAIN);
                if(!isRaidBlocked) Instance.SendChat("COMBATBLOCK_END_BLOCK".GetAdaptedMessage(player.UserIDString), player);
                CancelInvoke(nameof(RefreshUI));
                if (Instance._combatPlayers.ContainsKey(player)) Instance._combatPlayers.Remove(player);
                Destroy(this);
            }
            private void RefreshUI() {
                if (UnblockTimeLeft <= 0) {
                    KillComponent();
                }
                else if (player != null) {
                    Instance.DrawUI_CB_Updated(player, UnblockTimeLeft);
                }
            }
        }
        private Boolean IsCombatBlocked(String playerID) {
            if (!UInt64.TryParse(playerID, out UInt64 id)) return false;
            BasePlayer player = BasePlayer.FindByID(id);
            return player != null && IsCombatBlock(player);
        }
        private object CanRedeemKit(BasePlayer player) => CanActions(player);
        private object CanTrade(BasePlayer player) => CanActions(player, true);
        private void Unload() {
            foreach (CombatPlayer obj in _combatPlayers.Values) UnityEngine.Object.Destroy(obj);
            InterfaceBuilder.DestroyAll();
            _interface = null;
            Instance = null;
        }
        private class ImageUI {
            private readonly string _paths;
            private readonly string _printPath;
            private readonly Dictionary<string, ImageData> _images;
            private enum ImageStatus {
                NotLoaded, Loaded, Failed
            }
            public ImageUI() {
                _paths = Instance.Name + "/Images/";
                _printPath = "data/" + _paths;
                _images = new Dictionary<string, ImageData> {
                    {
                        "CB_FON0", new ImageData()
                    }
                    , {
                        "CB_FON1", new ImageData()
                    }
                    , {
                        "CB_FON2", new ImageData()
                    }
                    , {
                        "CB_VARIANT0_ICON", new ImageData()
                    }
                    , {
                        "CB_VARIANT1_ICON_FON", new ImageData()
                    }
                    , {
                        "CB_VARIANT1_ICON", new ImageData()
                    }
                    , {
                        "CB_VARIANT2_ICON", new ImageData()
                    }
                    ,
                }
                ;
            }
            private class ImageData {
                public ImageStatus Status = ImageStatus.NotLoaded;
                public string Id {
                    get;
                    set;
                }
            }
            public string GetImage(string name) {
                ImageData image;
                if (_images.TryGetValue(name, out image) && image.Status == ImageStatus.Loaded) return image.Id;
                return null;
            }
            public void DownloadImage() {
                KeyValuePair<string, ImageData>? image = null;
                foreach (KeyValuePair<string, ImageData> img in _images) {
                    if (img.Value.Status == ImageStatus.NotLoaded) {
                        image = img;
                        break;
                    }
                }
                if (image != null) {
                    ServerMgr.Instance.StartCoroutine(ProcessDownloadImage(image.Value));
                }
                else {
                    List<string> failedImages = new List<string>();
                    foreach (KeyValuePair<string, ImageData> img in _images) {
                        if (img.Value.Status == ImageStatus.Failed) {
                            failedImages.Add(img.Key);
                        }
                    }
                    if (failedImages.Count > 0) {
                        string images = string.Join(", ", failedImages);
                        Instance.PrintError(LanguageEn ? $"Failed to load the following images: {images}.Perhaps you did not upload them to the '{_printPath}' folder." : $"Не удалось загрузить следующие изображения: {images}.Возможно, вы не загрузили их в папку '{_printPath}'.");
                        Interface.Oxide.UnloadPlugin(Instance.Name);
                    }
                    else {
                        Instance.Puts(LanguageEn ? $"{_images.Count} images downloaded successfully!" : $"{_images.Count} изображений успешно загружено!");
                        Instance.Puts(LanguageEn ? "Generating the interface, please wait for approximately 5-10 seconds" : "Генерируем интерфейс, ожидайте ~5-10 секунд");
                        _interface = new InterfaceBuilder();
                        Instance.Puts(LanguageEn ? "The interface has been successfully loaded" : "Интерфейс успешно загружен!");
                    }
                }
            }
            public void UnloadImages() {
                foreach (KeyValuePair<string, ImageData> item in _images) if (item.Value.Status == ImageStatus.Loaded) if (item.Value?.Id != null) FileStorage.server.Remove(uint.Parse(item.Value.Id), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID);
                _images?.Clear();
            }
            private IEnumerator ProcessDownloadImage(KeyValuePair<string, ImageData> image) {
                string url = "file://" + Interface.Oxide.DataDirectory + "/" + _paths + image.Key + ".png";
                using UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
                yield return www.SendWebRequest();
                if (www.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError) {
                    image.Value.Status = ImageStatus.Failed;
                }
                else {
                    Texture2D tex = DownloadHandlerTexture.GetContent(www);
                    image.Value.Id = FileStorage.server.Store(tex.EncodeToPNG(), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
                    image.Value.Status = ImageStatus.Loaded;
                    UnityEngine.Object.DestroyImmediate(tex);
                }
                DownloadImage();
            }
        }
        private void OnServerInitialized() {
            permission.RegisterPermission(Name + _permIgnoreCombat, this);
            _imageUI = new ImageUI();
            _imageUI.DownloadImage();
            if(config.BlockDetect.ActivateOnNpcDamageReceived) Subscribe(nameof(OnEntityTakeDamage));
            if (config.ActionsBlocked.CanTeleport) {
                Subscribe(nameof(CanTeleport));
                Subscribe(nameof(canTeleport));
            }
            if (config.ActionsBlocked.CanTrade) {
                Subscribe(nameof(canTrade));
                Subscribe(nameof(CanTrade));
            }
            if (config.ActionsBlocked.CanUseKit) {
                Subscribe(nameof(CanRedeemKit));
            }
            if (config.CombatBlockMain.CombatBlockOnRaidBlock) {
                Subscribe(nameof(OnRaidBlock));
                Subscribe(nameof(OnRaidBlockStarted));
            }
            if (config.ActionsBlocked.BlockedCommands != null && config.ActionsBlocked.BlockedCommands.Count != 0) {
                if (config.ActionsBlocked.BlockedCommands.Count == 1 && config.ActionsBlocked.BlockedCommands[0].Equals("commandExample")) return;
                Subscribe(nameof(OnPlayerCommand));
                Subscribe(nameof(OnServerCommand));
            }
        }
        private void Init() {
            Instance = this;
            Unsubscribe(nameof(OnEntityTakeDamage));
            Unsubscribe(nameof(OnPlayerCommand));
            Unsubscribe(nameof(OnServerCommand));
            Unsubscribe(nameof(CanTeleport));
            Unsubscribe(nameof(canTeleport));
            Unsubscribe(nameof(CanRedeemKit));
            Unsubscribe(nameof(canTrade));
            Unsubscribe(nameof(CanTrade));
            Unsubscribe(nameof(OnRaidBlock));
            Unsubscribe(nameof(OnRaidBlockStarted));
        }
        private void StartCombatBlocked(BasePlayer player) {
            if (player == null) {
                Debug.LogError("StartCombatBlocked was called with a null player.");
                return;
            }
            if (permission.UserHasPermission(player.UserIDString, $"{Name}{_permIgnoreCombat}")) return;
            if (Interface.Call("CanCombatBlocked", player) != null) return;
            if (Interface.Call("CanCombatBlock", player) != null) return;
            if (player.gameObject.TryGetComponent(out CombatPlayer combatBlocker)) {
                combatBlocker.UpdateBlockTime();
            }
            else {
                try {
                    combatBlocker = player.gameObject.AddComponent<CombatPlayer>();
                    _combatPlayers.Add(player, combatBlocker);
                }
                catch (Exception ex) {
                    Debug.LogError($"Error adding CombatPlayer component: {ex.Message}");
                    return;
                }
            }
            Interface.CallHook("OnCombatBlockStarted", player);
        }
        protected override void LoadDefaultConfig() {
            config = new Configuration();
        }
        private void DrawUI_CB_Updated(BasePlayer player, float timeLeft, bool upd = false) {
            string Interface = InterfaceBuilder.GetInterface(InterfaceBuilder.CB_PROGRESS_BAR);
            if (Interface == null) return;
            double factor = InterfaceBuilder.Factor * timeLeft / config.CombatBlockMain.CombatBlockDuration;
            Interface = Interface.Replace("%left%", factor.ToString(CultureInfo.InvariantCulture));
            Interface = Interface.Replace("%TimeLeft%", "COMBATBLOCK_UI_TIMER".GetAdaptedMessage(player.UserIDString, timeLeft.ToTimeFormat()));
            if(!upd) Interface = Interface.Replace("0.222", "0");
            CuiHelper.DestroyUi(player, InterfaceBuilder.CB_PROGRESS);
            CuiHelper.DestroyUi(player, InterfaceBuilder.CB_PROGRESS_TIMER);
            CuiHelper.AddUi(player, Interface);
        }
        private object canTrade(BasePlayer player) => CanTrade(player);
        private bool IsClans(string userID, string targetID) {
            if (Clans) {
                string tagUserID = (string)Clans?.Call("GetClanOf", userID);
                string tagTargetID = (string)Clans?.Call("GetClanOf", targetID);
                if (tagUserID == null && tagTargetID == null) {
                    return false;
                }
                return tagUserID == tagTargetID;
            }
            return false;
        }
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo hitInfo) {
            if (entity.ToPlayer() == null) return;
            BasePlayer player = entity.ToPlayer();
            if (player != null && player.gameObject != null) {
                CombatPlayer combatBlocker = player.gameObject.GetComponent<CombatPlayer>();
                if (config.BlockDetect.DeactivateOnPlayerDeath && combatBlocker != null) combatBlocker.KillComponent();
            }
        }
        private class InterfaceBuilder {
            private static InterfaceBuilder _instance;
            public const string CB_MAIN = "CB_MAIN";
            public const string CB_PROGRESS_BAR = "CB_PROGRESS_BAR";
            public const string CB_PROGRESS = "CB_PROGRESS";
            public const string CB_PROGRESS_TIMER = "CB_PROGRESS_TIMER";
            public static int TypeUi;
            public static double Factor;
            private Configuration.CombatBlockUi.CombatBlockUiSettings _uiSettings;
            private static float _fade;
            private Dictionary<string, string> _interfaces;
            public InterfaceBuilder() {
                _instance = this;
                _interfaces = new Dictionary<string, string>();
                TypeUi = Instance.config.CombatBlockInterface.UiType;
                Factor = TypeUi switch {
                    0 => 142, 1 => 195, _ => 130
                }
                ;
                _uiSettings = TypeUi switch {
                    0 => Instance.config.CombatBlockInterface.InterfaceSettingsVariant0, 1 => Instance.config.CombatBlockInterface.InterfaceSettingsVariant1, 2 => Instance.config.CombatBlockInterface.InterfaceSettingsVariant2, _ => throw new ArgumentOutOfRangeException()
                }
                ;
                _fade = _uiSettings.SmoothTransition;
                switch (TypeUi) {
                    case 0 : BuildingCombatBlockMain();
                    BuildingCombatBlockUpdated();
                    break;
                    case 1 : BuildingCombatBlockMainV2();
                    BuildingCombatBlockUpdatedV2();
                    break;
                    case 2 : BuildingCombatBlockMainV3();
                    BuildingCombatBlockUpdatedV3();
                    break;
                }
            }
            private static void AddInterface(string name, string json) {
                if (_instance._interfaces.ContainsKey(name)) {
                    Instance.PrintError($"Error! Tried to add existing cui elements! -> {name}");
                    return;
                }
                _instance._interfaces.Add(name, json);
            }
            public static string GetInterface(string name) {
                string json;
                if (_instance._interfaces.TryGetValue(name, out json) == false) {
                    Instance.PrintWarning($"Warning! UI elements not found by name! -> {name}");
                }
                return json;
            }
            public static void DestroyAll() {
                foreach (BasePlayer player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, CB_MAIN);
            }
            private void BuildingCombatBlockMain() {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = "0 0 0 0", FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = $"{-179.006 + Instance.config.CombatBlockInterface.OffsetX} {-110.5 + Instance.config.CombatBlockInterface.OffsetY}", OffsetMax = $"{-0.006 + Instance.config.CombatBlockInterface.OffsetX} {-40.5 + Instance.config.CombatBlockInterface.OffsetY}"
                    }
                }
                , Instance.config.CombatBlockInterface.Layers , CB_MAIN);
                container.Add(new CuiElement {
                    Name = "CB_BACKGROUND", Parent = CB_MAIN, Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.BackgroundColor, Png = _imageUI.GetImage("CB_FON0"), FadeIn = _fade
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0", AnchorMax = "1 1"
                        }
                    }
                }
                );
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.ProgressBarBackgroundColor, FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-71.001 9.367", OffsetMax = "70.999 12.033"
                    }
                }
                , CB_MAIN, CB_PROGRESS_BAR);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-71.001 -9.637", OffsetMax = "84.101 14.717"
                    }
                    , Text = {
                        Text = "%Descriptions%", Font = "robotocondensed-regular.ttf", FontSize = 8, Align = TextAnchor.MiddleLeft, Color = _uiSettings.SecondaryTextColor, FadeIn = _fade
                    }
                }
                , CB_MAIN);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-71.001 14.717", OffsetMax = "5.043 29.111"
                    }
                    , Text = {
                        Text = "%Title%", Font = "robotocondensed-bold.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = _uiSettings.MainTextColor , FadeIn = _fade
                    }
                }
                , CB_MAIN);
                container.Add(new CuiElement {
                    Name = "CB_ICON", Parent = CB_MAIN, Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.IconColor, Png = _imageUI.GetImage("CB_VARIANT0_ICON")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "6.38 16.914", OffsetMax = "15.62 26.914"
                        }
                    }
                }
                );
                AddInterface(CB_MAIN, container.ToJson());
            }
            private void BuildingCombatBlockUpdated() {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.ProgressBarMainColor, FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -1.333", OffsetMax = "%left% 1.333"
                    }
                }
                , CB_PROGRESS_BAR, CB_PROGRESS);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-71.001 -21.162", OffsetMax = "35.499 -9.638"
                    }
                    , Text = {
                        Text = "%TimeLeft%", Font = "robotocondensed-regular.ttf", FontSize = 9, Align = TextAnchor.MiddleLeft, Color = _uiSettings.MainTextColor
                    }
                }
                , CB_MAIN, CB_PROGRESS_TIMER);
                AddInterface(CB_PROGRESS_BAR, container.ToJson());
            }
            private void BuildingCombatBlockMainV2() {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = "1 1 1 0", FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = $"{-200.01 + Instance.config.CombatBlockInterface.OffsetX} {-96 + Instance.config.CombatBlockInterface.OffsetY}", OffsetMax = $"{-0.01 + Instance.config.CombatBlockInterface.OffsetX} {-56 + Instance.config.CombatBlockInterface.OffsetY}"
                    }
                }
                , Instance.config.CombatBlockInterface.Layers, CB_MAIN);
                container.Add(new CuiElement {
                    Name = "CB_BACKGROUND", Parent = CB_MAIN, Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.BackgroundColor , Png = _imageUI.GetImage("CB_FON1"), FadeIn = _fade
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-100.001 -17", OffsetMax = "99.999 20"
                        }
                    }
                }
                );
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.ProgressBarBackgroundColor, FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-97.5 0", OffsetMax = "97.5 3.33"
                    }
                }
                , CB_MAIN, CB_PROGRESS_BAR);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-64.622 0", OffsetMax = "5.368 15.562"
                    }
                    , Text = {
                        Text = "%Title%", Font = "robotocondensed-bold.ttf", FontSize = 10, Align = TextAnchor.MiddleLeft, Color = _uiSettings.MainTextColor, FadeIn = _fade
                    }
                }
                , CB_MAIN);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-64.622 -12.76", OffsetMax = "68.698 2.76"
                    }
                    , Text = {
                        Text = "%Descriptions%", Font = "robotocondensed-regular.ttf", FontSize = 8, Align = TextAnchor.MiddleLeft, Color = _uiSettings.SecondaryTextColor, FadeIn = _fade
                    }
                }
                , CB_MAIN);
                container.Add(new CuiElement {
                    Name = "CB_ICON_FON", Parent = CB_MAIN, Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.AdditionalElementsColor, Png = _imageUI.GetImage("CB_VARIANT1_ICON_FON")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "8.199 -10", OffsetMax = "32.199 13"
                        }
                    }
                }
                );
                container.Add(new CuiElement {
                    Name = "CB_ICON", Parent = "CB_ICON_FON", Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.IconColor, Png = _imageUI.GetImage("CB_VARIANT1_ICON")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-9 -8.5", OffsetMax = "9 8.5"
                        }
                    }
                }
                );
                AddInterface(CB_MAIN, container.ToJson());
            }
            private void BuildingCombatBlockUpdatedV2() {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.ProgressBarMainColor, FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -1.665", OffsetMax = "%left% 1.665"
                    }
                }
                , CB_PROGRESS_BAR, CB_PROGRESS);
                AddInterface(CB_PROGRESS_BAR, container.ToJson());
            }
            private void BuildingCombatBlockMainV3() {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = "1 1 1 0", FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = $"{-200 + Instance.config.CombatBlockInterface.OffsetX} {-104 + Instance.config.CombatBlockInterface.OffsetY}", OffsetMax = $"{0 + Instance.config.CombatBlockInterface.OffsetX} {-48 + Instance.config.CombatBlockInterface.OffsetY}"
                    }
                }
                , Instance.config.CombatBlockInterface.Layers, CB_MAIN);
                container.Add(new CuiElement {
                    Name = "CB_BACKGROUND", Parent = CB_MAIN, Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.BackgroundColor, Png = _imageUI.GetImage("CB_FON2"), FadeIn = _fade
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0", AnchorMax = "1 1"
                        }
                    }
                }
                );
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.ProgressBarBackgroundColor, FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-46.03 9.425", OffsetMax = "83.97 12.755"
                    }
                }
                , CB_MAIN, CB_PROGRESS_BAR);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-15.954 1.549", OffsetMax = "83.97 21.851"
                    }
                    , Text = {
                        Text = "%Title%", Font = "robotocondensed-bold.ttf", FontSize = 14, Align = TextAnchor.MiddleRight, Color = _uiSettings.MainTextColor, FadeIn = _fade
                    }
                }
                , CB_MAIN);
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.AdditionalElementsColor
                    }
                    , RectTransform = {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-7.9 -25", OffsetMax = "-1.9 26"
                    }
                }
                , CB_MAIN, "CB_RIGHT_PANEL");
                container.Add(new CuiElement {
                    Name = "CB_ICON", Parent = CB_MAIN, Components = {
                        new CuiRawImageComponent {
                            Color = _uiSettings.IconColor, Png = _imageUI.GetImage("CB_VARIANT2_ICON")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "2.3 -20", OffsetMax = "42.3 20"
                        }
                    }
                }
                );
                AddInterface(CB_MAIN, container.ToJson());
            }
            private void BuildingCombatBlockUpdatedV3() {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = _uiSettings.ProgressBarMainColor, FadeIn = _fade
                    }
                    , RectTransform = {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -1.665", OffsetMax = "%left% 1.665"
                    }
                }
                , CB_PROGRESS_BAR, CB_PROGRESS);
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-46.03 -12.245", OffsetMax = "83.97 5.465"
                    }
                    , Text = {
                        Text = "%TimeLeft%", Font = "robotocondensed-regular.ttf", FontSize = 10, Align = TextAnchor.MiddleRight, Color = _uiSettings.SecondaryTextColor, FadeIn = _fade
                    }
                }
                , CB_MAIN, CB_PROGRESS_TIMER);
                AddInterface(CB_PROGRESS_BAR, container.ToJson());
            }
        }
        private void OnRaidBlockStarted(BasePlayer player) {
            if (player != null && player.gameObject != null) {
                if (player.gameObject.TryGetComponent(out CombatPlayer combatBlocker)) combatBlocker.KillComponent(true);
            }
        }
        private bool IsRaidBlocked(BasePlayer player, bool chat = false) {
            if (!config.CombatBlockMain.CombatBlockOnRaidBlock && !chat) return false;
            if (RaidBlock) return RaidBlock.Call<bool>("IsRaidBlocked", player);
            if (NoEscape) return NoEscape.Call<bool>("IsRaidBlocked", player);
            return false;
        }
        [PluginReference]
        Plugin RaidBlock, NoEscape, IQChat, Friends, Clans, Duelist, Duel, EventHelper, Battles, ArenaTournament;
        private Configuration config;
        protected override void SaveConfig() {
            Config.WriteObject(config);
        }
        private void OnPlayerAttack(BasePlayer attacker, HitInfo hitInfo) {
            if (hitInfo.HitEntity is not BasePlayer target) return;
            if (!config.BlockDetect.ActivateOnNpcAttack && target.IsNpc) return;
            if (!config.BlockDetect.ActivateOnSleeperAttack && target.IsSleeping()) return;
            if (!config.BlockDetect.ActivateOnNpcDamageReceived && attacker.IsNpc) return;
            if (!target.IsNpc && !attacker.IsNpc) if (IsFriends(attacker.userID.Get(), target.userID.Get()) || IsClans(attacker.UserIDString, target.UserIDString)) return;
            if (!IsRaidBlocked(target) && !IsDuel(target.userID.Get())) StartCombatBlocked(target);
            if (!IsRaidBlocked(attacker) && !IsDuel(attacker.userID.Get())) StartCombatBlocked(attacker);
        }
        private const string _permIgnoreCombat = ".ignore";
        private Boolean IsCombatBlocked(UInt64 playerID) {
            BasePlayer player = BasePlayer.FindByID(playerID);
            return player != null && IsCombatBlock(player);
        }
        private object OnServerCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player == null || arg.cmd.FullName == "chat.say") return null;
            String command = arg.cmd.Name;
            if (arg.Args != null && arg.Args.Length != 0) command += " " + String.Join(" ", arg.Args);
            String onlyCommand = !String.IsNullOrWhiteSpace(command) && command.Contains(" ") ? command.Substring(0, command.IndexOf(" ", StringComparison.Ordinal)) : command;
            return config.ActionsBlocked.BlockedCommands.Contains(onlyCommand.ToLower()) ? CanActions(player) : null;
        }
        private void SendChat(string message, BasePlayer player, Single timeout = 0f, Chat.ChatChannel channel = Chat.ChatChannel.Global) {
            if(IsRaidBlocked(player, true)) return;
            if (_playerInCache.Contains(player)) return;
            if (timeout != 0) {
                _playerInCache.Add(player);
                player.Invoke(() => _playerInCache.Remove(player), timeout);
            }
            Configuration.IQChat chat = config.IQChatSetting;
            if (IQChat) if (chat.UIAlertUse) IQChat?.Call("API_ALERT_PLAYER_UI", player, message);
            else IQChat?.Call("API_ALERT_PLAYER", player, message, chat.CustomPrefix, chat.CustomAvatar);
            else player.SendConsoleCommand("chat.add", channel, 0, message);
        }
        private const bool LanguageEn = false;
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["COMBATBLOCK_ACTION_BLOCKED"]
                = "You are prohibited from performing this action during a <color=#C26D33>combat-block</color>, please wait {0}", ["COMBATBLOCK_END_BLOCK"] = "Block <color=#738D45>deactivated</color>.\nFunctions unlocked", ["COMBATBLOCK_ENTER_COMBAT_INITIATOR"] = "Combat activity!\nCombat-block activated for <color=#C26D33>{0}</color>.\nSome functions are temporarily unavailable", ["COMBATBLOCK_UI_TIMER"] = "Time remaining {0}", ["COMBATBLOCK_UI_TITLE"] = "COMBAT BLOCK", ["COMBATBLOCK_UI_DESCRIPTIONS_V1"] = "Combat activity, some functions have been restricted", ["COMBATBLOCK_UI_DESCRIPTIONS_V2"] = "Some functions have been disabled",
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["COMBATBLOCK_ACTION_BLOCKED"]
                = "Вам запрещено совершать это действие во время <color=#C26D33>комбат-блока</color>, подождите {0}", ["COMBATBLOCK_END_BLOCK"] = "Блок <color=#738D45>деактивирован</color>.\nФункции разблокированы", ["COMBATBLOCK_ENTER_COMBAT_INITIATOR"] = "Боевая активность!\nАктивирован комбат-блок на <color=#C26D33>{0}</color>.\nНекоторые функции временно недоступны.", ["COMBATBLOCK_UI_TIMER"] = "Осталось {0}", ["COMBATBLOCK_UI_TITLE"] = "COMBAT BLOCK", ["COMBATBLOCK_UI_DESCRIPTIONS_V1"] = "Боевая активность, некоторые функции были ограничены", ["COMBATBLOCK_UI_DESCRIPTIONS_V2"] = "Некоторые функции были отключены",
            }
            , this, "ru");
        }
        public static CombatBlock Instance;
        private class Configuration {
            [JsonProperty(LanguageEn ? "Primary combat settings" : "Основные настройки комбат-блока")]
            public CombatBlock CombatBlockMain = new();
            public class CombatBlockActionsBlocked {
                [JsonProperty(LanguageEn ? "Disable teleportation capability (true - yes/false - no)" : "Блокировать возможность телепортироваться (true - да/false - нет)")]
                public bool CanTeleport = true;
                [JsonProperty(LanguageEn ? "Disable the use of kits (true - yes/false - no)" : "Блокировать возможность использования китов (true - да/false - нет)")]
                public bool CanUseKit = true;
                [JsonProperty(LanguageEn ? "Disable trade functionality (true - yes/false - no)" : "Блокировать возможность обмена (Trade) (true - да/false - нет)")]
                public bool CanTrade = true;
                [JsonProperty(LanguageEn ? "List of prohibited commands during active lockdown [Specify them without a slash (/)]" : "Список запрещенных команд при активной блокировки [указывайте их без слэша (/)]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
                public List<string> BlockedCommands = new List<string>() {
                    "commandExample",
                }
                ;
            }
            public class CombatBlock {
                [JsonProperty(LanguageEn ? "Disable the combat block when receiving a raid block (true - yes/false - no)" : "Отключить комбат блок при получении рейд блока (true - да/false - нет)")]
                public bool CombatBlockOnRaidBlock = true;
                [JsonProperty(LanguageEn ? "Lockout time (seconds)" : "Время блокировки (секунды)")]
                public int CombatBlockDuration = 150;
            }
            [JsonProperty(LanguageEn ? "Interface settings" : "Настройки интерфейса")]
            public CombatBlockUi CombatBlockInterface = new();
            public class IQChat {
                [JsonProperty(LanguageEn ? "IQChat : Custom prefix in the chat" : "IQChat : Кастомный префикс в чате")]
                public String CustomPrefix = "[<color=#C26D33>CombatBlock</color>]";
                [JsonProperty(LanguageEn ? "IQChat : Custom avatar in the chat (If required)" : "IQChat : Кастомный аватар в чате(Если требуется)")]
                public String CustomAvatar = "0";
                [JsonProperty(LanguageEn ? "IQChat : Use UI notifications" : "IQChat : Использовать UI уведомления")]
                public Boolean UIAlertUse = false;
            }
            [JsonProperty(LanguageEn ? "Trigger settings" : "Настройка триггеров")]
            public CombatBlockDetect BlockDetect = new();
            public class CombatBlockUi {
                [JsonProperty(LanguageEn ? "Interface variant (0, 1, 2) - example: " : "Вариант интерфейса (0, 1, 2)")]
                public int UiType = 0;
                [JsonProperty(LanguageEn ? "Interface layer: Overlay - will overlay other UI, Hud - will be overlaid by other interfaces" : "Слой интерфейса : Overlay - будет перекрывать другие UI, Hud - будет перекрываться другим интерфейсом")]
                public string Layers = "Hud";
                [JsonProperty(LanguageEn ? "Vertical padding" : "Вертикальный отступ")]
                public int OffsetY = 0;
                [JsonProperty(LanguageEn ? "Horizontal padding" : "Горизонтальный отступ")]
                public int OffsetX = 0;
                [JsonProperty(LanguageEn ? "Interface settings for variant 0" : "Настройки интерфейса для варианта 0")]
                public CombatBlockUiSettings InterfaceSettingsVariant0 = new() {
                    BackgroundColor = "0.1921569 0.1921569 0.1921569 1", IconColor = "0 0.7764706 1 1", AdditionalElementsColor = "", MainTextColor = "1 1 1 1", SecondaryTextColor = "1 1 1 0.5019608", ProgressBarMainColor = "0.3411765 0.5490196 0.9607843 1", ProgressBarBackgroundColor = "1 1 1 0.1019608", SmoothTransition = 0.222f,
                }
                ;
                [JsonProperty(LanguageEn ? "Interface settings for variant 1" : "Настройки интерфейса для варианта 1")]
                public CombatBlockUiSettings InterfaceSettingsVariant1 = new() {
                    BackgroundColor = "0.9607843 0.772549 0.7333333 0.7019608", IconColor = "1 1 1 1", AdditionalElementsColor = "0.9215686 0.3058824 0.172549 1", MainTextColor = "0.1921569 0.192081 0.1921569 1", SecondaryTextColor = "0.1320755 0.1320755 0.1320755 1", ProgressBarMainColor = "0.9215686 0.3058824 0.172549 1", ProgressBarBackgroundColor = "1 1 1 0.4117647", SmoothTransition = 0.222f
                }
                ;
                [JsonProperty(LanguageEn ? "Interface settings for variant 2" : "Настройки интерфейса для варианта 2")]
                public CombatBlockUiSettings InterfaceSettingsVariant2 = new() {
                    BackgroundColor = "0.1921569 0.1921569 0.1921569 1", IconColor = "0.9411765 0.3137255 0.286081 1", AdditionalElementsColor = "0.9568627 0.3607843 0.2627451 1", MainTextColor = "1 1 1 1", SecondaryTextColor = "1 1 1 0.5019608", ProgressBarMainColor = "1 1 1 1", ProgressBarBackgroundColor = "1 1 1 0.4117647", SmoothTransition = 0.222f
                }
                ;
                public class CombatBlockUiSettings {
                    [JsonProperty(LanguageEn ? "Background color (RGBA)" : "Цвет фона (RGBA)")]
                    public string BackgroundColor;
                    [JsonProperty(LanguageEn ? "Icon color (RGBA)" : "Цвет иконки (RGBA)")]
                    public string IconColor;
                    [JsonProperty(LanguageEn ? "Color of additional elements (RGBA)" : "Цвет дополнительных элементов (RGBA)")]
                    public string AdditionalElementsColor;
                    [JsonProperty(LanguageEn ? "Main text color (RGBA)" : "Цвет основного текста (RGBA)")]
                    public string MainTextColor;
                    [JsonProperty(LanguageEn ? "Secondary text Color (RGBA)" : "Цвет второстепенного текста (RGBA)")]
                    public string SecondaryTextColor;
                    [JsonProperty(LanguageEn ? "Main color of the progress-bar (RGBA)" : "Основной цвет прогресс-бара (RGBA)")]
                    public string ProgressBarMainColor;
                    [JsonProperty(LanguageEn ? "Background Color of the Progress Bar (RGBA)" : "Цвет фона прогресс-бара (RGBA)")]
                    public string ProgressBarBackgroundColor;
                    [JsonProperty(LanguageEn ? "Delay before the UI appears and disappears (for smooth transitions)" : "Задержка перед появлением и исчезновением UI (для плавности)")]
                    public float SmoothTransition;
                }
            }
            [JsonProperty(LanguageEn ? "Setting IQChat" : "Настройка IQChat")]
            public IQChat IQChatSetting = new IQChat();
            public class CombatBlockDetect {
                [JsonProperty(LanguageEn ? "Activate combat mode upon NPC attack (true - yes/false - no)" : "Активировать комбат-блок при атаке NPC (true - да/false - нет)")]
                public bool ActivateOnNpcAttack = true;
                [JsonProperty(LanguageEn ? "Activate combat mode upon receiving damage from NPCs (true - yes/false - no)" : "Активировать комбат-блок при получении урона от NPC (true - да/false - нет)")]
                public bool ActivateOnNpcDamageReceived = true;
                [JsonProperty(LanguageEn ? "Activate combat block when dealing damage to a sleeping player (true - yes/false - no)" : "Активировать комбат-блок при нанесении урона спящему игроку (true - да/false - нет)")]
                public bool ActivateOnSleeperAttack = false;
                [JsonProperty(LanguageEn ? "Deactivate combat mode after death (true - yes/false - no)" : "Деактивировать комбат-блок после смерти (true - да/false - нет)")]
                public bool DeactivateOnPlayerDeath = true;
            }
 
// ... [Code preview truncated due to length. Full source in attached file] ...

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