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

FREE NoEscape : 2.0.2 2.0.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using UnityEngine;
using Facepunch;
using Rust;

namespace Oxide.Plugins
{
    [Info("NoEscape", "rustservers.io", "2.0.2", ResourceId = 1394)]
    [Description("Prevent commands/actions while raid and/or combat is occuring")]
    class NoEscape : RustPlugin
    {
        #region Setup & Configuration

        List<string> blockTypes = new List<string>()
        {
            "remove",
            "tp",
            "bank",
            "trade",
            "recycle",
            "shop",
            "bgrade",
            "build",
            "repair",
            "upgrade",
            "vend",
            "kit",
            "assignbed",
            "craft",
            "mailbox"
        };

        // COMBAT SETTINGS
        private bool combatBlock;
        private static float combatDuration;
        private bool combatOnHitPlayer;
        private bool combatOnTakeDamage;

        // RAID BLOCK SETTINGS
        private bool raidBlock;
        private static float raidDuration;
        private float raidDistance;
        private bool blockOnDamage;
        private bool blockOnDestroy;

        // RAID-ONLY SETTINGS
        private bool ownerCheck;
        private bool blockUnowned;
        private bool blockAll;
        // IGNORES ALL OTHER CHECKS
        private bool ownerBlock;
        private bool cupboardShare;
        private bool friendShare;
        private bool clanShare;
        private bool clanCheck;
        private bool friendCheck;
        private bool raiderBlock;
        private List<string> raidDamageTypes;
        private List<string> combatDamageTypes;

        // RAID UNBLOCK SETTINGS
        private bool raidUnblockOnDeath;
        private bool raidUnblockOnWakeup;
        private bool raidUnblockOnRespawn;

        // COMBAT UNBLOCK SETTINGS
        private bool combatUnblockOnDeath;
        private bool combatUnblockOnWakeup;
        private bool combatUnblockOnRespawn;

        private float cacheTimer;

        // MESSAGES
        private bool raidBlockNotify;
        private bool combatBlockNotify;

        private bool useZoneManager;
        private bool zoneEnter;
        private bool zoneLeave;

        internal bool sendUINotification;
        internal bool sendChatNotification;
        internal bool sendGUIAnnouncementsNotification;
        internal bool sendLustyMapNotification;

        internal string GUIAnnouncementTintColor = "Red";
        internal string GUIAnnouncementTextColor = "White";

        internal string LustyMapIcon = "special";
        internal float LustyMapDuration = 150f;

        private Dictionary<string, RaidZone> zones = new Dictionary<string, RaidZone>();
        private Dictionary<string, List<string>> memberCache = new Dictionary<string, List<string>>();
        private Dictionary<string, string> clanCache = new Dictionary<string, string>();
        private Dictionary<string, List<string>> friendCache = new Dictionary<string, List<string>>();
        private Dictionary<string, DateTime> lastClanCheck = new Dictionary<string, DateTime>();
        private Dictionary<string, DateTime> lastCheck = new Dictionary<string, DateTime>();
        private Dictionary<string, DateTime> lastFriendCheck = new Dictionary<string, DateTime>();
        Dictionary<string, bool> prefabBlockCache = new Dictionary<string, bool>();

        public static NoEscape plugin;

        [PluginReference]
        Plugin Clans, Friends, ZoneManager, GUIAnnouncements, LustyMap;

        private readonly int cupboardMask = LayerMask.GetMask("Deployed");
        private readonly int blockLayer = LayerMask.GetMask("Player (Server)");
        private Dictionary<string, bool> _cachedExcludedWeapons = new Dictionary<string, bool>();

        List<string> blockedPrefabs = new List<string>()
        {
            "door",
            "window.bars",
            "floor.ladder.hatch",
            "floor.frame",
            "wall.frame",
            "shutter",
            "external"
        };

        List<string> exceptionPrefabs = new List<string>()
        {
            "ladder.wooden"
        };

        List<string> exceptionWeapons = new List<string>()
        {
            "torch"
        };

        private List<string> GetDefaultRaidDamageTypes()
        {
            return new List<DamageType>()
            {
                DamageType.Bullet,
                DamageType.Blunt,
                DamageType.Stab,
                DamageType.Slash,
                DamageType.Explosion,
                DamageType.Heat,
            }.Select(x => x.ToString()).ToList<string>();
        }

        private List<string> GetDefaultCombatDamageTypes()
        {
            return new List<DamageType>()
            {
                DamageType.Bullet,
                DamageType.Arrow,
                DamageType.Blunt,
                DamageType.Stab,
                DamageType.Slash,
                DamageType.Explosion,
                DamageType.Heat,
                DamageType.ElectricShock,
            }.Select(x => x.ToString()).ToList<string>();
        }

        static Regex _htmlRegex = new Regex("<.*?>", RegexOptions.Compiled);

        protected override void LoadDefaultConfig()
        {
            Config["VERSION"] = Version.ToString();

            // RAID SETTINGS
            Config["Raid", "Block", "enabled"] = true; 
            Config["Raid", "Block", "duration"] = 300f; // 5 minutes
            Config["Raid", "Block", "distance"] = 100f;
            Config["Raid", "Block", "notify"] = true;
            Config["Raid", "Block", "damageTypes"] = GetDefaultRaidDamageTypes();
            Config["Raid", "Block", "includePrefabs"] = blockedPrefabs;
            Config["Raid", "Block", "excludePrefabs"] = exceptionPrefabs;
            Config["Raid", "Block", "excludeWeapons"] = exceptionWeapons;

            Config["Raid", "BlockWhen", "damage"] = true; 
            Config["Raid", "BlockWhen", "destroy"] = true; 
            Config["Raid", "BlockWhen", "unowned"] = false; 

            Config["Raid", "BlockWho", "everyone"] = true; 
            Config["Raid", "BlockWho", "owner"] = false; 
            Config["Raid", "BlockWho", "cupboardAuthorized"] = false; 
            Config["Raid", "BlockWho", "clan"] = false; 
            Config["Raid", "BlockWho", "friends"] = false; 
            Config["Raid", "BlockWho", "raider"] = false; 

            Config["Raid", "BlockExcept", "owner"] = true; 
            Config["Raid", "BlockExcept", "friends"] = false; 
            Config["Raid", "BlockExcept", "clan"] = false; 

            Config["Raid", "Zone", "enabled"] = false; 
            Config["Raid", "Zone", "enter"] = true; 
            Config["Raid", "Zone", "leave"] = false; 

            Config["Raid", "Map", "enabled"] = false;
            Config["Raid", "Map", "icon"] = "special";
            Config["Raid", "Map", "duration"] = 150f;

            Config["Raid", "UnblockWhen", "death"] = true; 
            Config["Raid", "UnblockWhen", "wakeup"] = false; 
            Config["Raid", "UnblockWhen", "respawn"] = true; 

            // COMBAT SETTINGS
            Config["Combat", "Block", "enabled"] = false;
            Config["Combat", "Block", "duration"] = 180f; // 3 minutes
            Config["Combat", "Block", "notify"] = true;
            Config["Combat", "Block", "damageTypes"] = GetDefaultCombatDamageTypes();

            Config["Combat", "BlockWhen", "giveDamage"] = true; 
            Config["Combat", "BlockWhen", "takeDamage"] = true; 

            Config["Combat", "UnblockWhen", "death"] = true; 
            Config["Combat", "UnblockWhen", "wakeup"] = false; 
            Config["Combat", "UnblockWhen", "respawn"] = true;

            Config["Settings", "cacheMinutes"] = 1f;
            Config["Settings", "Block", "Types"] = blockTypes;

            Config["Notifications", "UI"] = true;
            Config["Notifications", "Chat"] = true;
            Config["Notifications", "GUIAnnouncements", "enabled"] = false;
            Config["Notifications", "GUIAnnouncements", "backgroundColor"] = "Red";
            Config["Notifications", "GUIAnnouncements", "textColor"] = "White";

            Config["VERSION"] = Version.ToString();
        }

        void Loaded()
        {
            LoadMessages();
        }

        void Unload()
        {
            if (useZoneManager)
                foreach (var zone in zones.ToList())
                    EraseZone(zone.Value.zoneid);

            var objects = GameObject.FindObjectsOfType(typeof(RaidBlock));
            if (objects != null)
                foreach (var gameObj in objects)
                    if (!((RaidBlock)gameObj).Active)
                        GameObject.Destroy(gameObj);

            objects = GameObject.FindObjectsOfType(typeof(CombatBlock));
            if (objects != null)
                foreach (var gameObj in objects)
                    if (!((CombatBlock)gameObj).Active)
                        GameObject.Destroy(gameObj);
        }

        void LoadMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
                {
                    { "Raid Blocked Message", "You may not do that while raid blocked ({time})" },
                    { "Combat Blocked Message", "You may do that while a in combat ({time})" },
                    { "Raid Block Complete", "You are no longer raid blocked." },
                    { "Combat Block Complete", "You are no longer combat blocked." },
                    { "Raid Block Notifier", "You are raid blocked for {time}" },
                    { "Combat Block Notifier", "You are combat blocked for {time}" },
                    { "Combat Block UI Message", "COMBAT BLOCK" },
                    { "Raid Block UI Message", "RAID BLOCK" },
                    { "Unit Seconds", "second(s)" },
                    { "Unit Minutes", "minute(s)" },
                    { "Prefix", string.Empty }
                }, this);
        }

        void CheckConfig()
        {
            if (Config["VERSION"] == null)
            {
                // FOR COMPATIBILITY WITH INITIAL VERSIONS WITHOUT VERSIONED CONFIG
                ReloadConfig();
            }
            else if (GetConfig<string>("VERSION", string.Empty) != Version.ToString())
            {
                // ADDS NEW, IF ANY, CONFIGURATION OPTIONS
                ReloadConfig();
            }
        }

        protected void ReloadConfig()
        {
            Config["VERSION"] = Version.ToString();

            // NEW CONFIGURATION OPTIONS HERE
            // END NEW CONFIGURATION OPTIONS

            PrintToConsole("Upgrading configuration file");
            SaveConfig();
        }

        void OnServerInitialized()
        {
            NoEscape.plugin = this;

            permission.RegisterPermission("noescape.disable", this);

            blockTypes = GetConfig("Settings", "Block", "Types", blockTypes);

            foreach (string command in blockTypes)
            {
                permission.RegisterPermission("noescape.raid." + command + "block", this);
                permission.RegisterPermission("noescape.combat." + command + "block", this);
            }

            CheckConfig();

            // RAID SETTINGS
            raidBlock = GetConfig("Raid", "Block", "enabled", true);
            raidDuration = GetConfig("Raid", "Block", "duration", 300f);
            raidDistance = GetConfig("Raid", "Block", "distance", 100f);
            raidBlockNotify = GetConfig("Raid", "Block", "notify", true);
            raidDamageTypes = GetConfig("Raid", "Block", "damageTypes", GetDefaultRaidDamageTypes());
            blockedPrefabs = GetConfig("Raid", "Block", "includePrefabs", blockedPrefabs);
            exceptionPrefabs = GetConfig("Raid", "Block", "excludePrefabs", exceptionPrefabs);
            exceptionWeapons = GetConfig("Raid", "Block", "excludeWeapons", exceptionWeapons);

            blockOnDamage = GetConfig("Raid", "BlockWhen", "damage", true);
            blockOnDestroy = GetConfig("Raid", "BlockWhen", "destroy", true);
            blockUnowned = GetConfig("Raid", "BlockWhen", "unowned", false);

            blockAll = GetConfig("Raid", "BlockWho", "everyone", true);
            ownerBlock = GetConfig("Raid", "BlockWho", "owner", false);
            friendShare = GetConfig("Raid", "BlockWho", "friends", false);
            clanShare = GetConfig("Raid", "BlockWho", "clan", false);
            cupboardShare = GetConfig("Raid", "BlockWho", "cupboardAuthorized", false);
            raiderBlock = GetConfig("Raid", "BlockWho", "raider", false);

            ownerCheck = GetConfig("Raid", "BlockExcept", "owner", true);
            friendCheck = GetConfig("Raid", "BlockExcept", "friends", false);
            clanCheck = GetConfig("Raid", "BlockExcept", "clan", false);

            useZoneManager = GetConfig("Raid", "Zone", "enabled", false);
            zoneEnter = GetConfig("Raid", "Zone", "enter", true);
            zoneLeave = GetConfig("Raid", "Zone", "leave", false);

            sendLustyMapNotification = GetConfig("Raid", "Map", "enabled", false);
            LustyMapIcon = GetConfig("Raid", "Map", "icon", "special");
            LustyMapDuration = GetConfig("Raid", "Map", "duration", 150f);

            raidUnblockOnDeath = GetConfig("Raid", "UnblockWhen", "death", true);
            raidUnblockOnWakeup = GetConfig("Raid", "UnblockWhen", "wakeup", false);
            raidUnblockOnRespawn = GetConfig("Raid", "UnblockWhen", "respawn", true);

            // COMBAT SETTINGS
            combatBlock = GetConfig("Combat", "Block", "enabled", false);
            combatDuration = GetConfig("Combat", "Block", "duration", 180f);
            combatBlockNotify = GetConfig("Combat", "Block", "notify", true);
            combatDamageTypes = GetConfig("Combat", "Block", "damageTypes", GetDefaultCombatDamageTypes());

            combatOnHitPlayer = GetConfig("Combat", "BlockWhen", "giveDamage", true);
            combatOnTakeDamage = GetConfig("Combat", "BlockWhen", "takeDamage", true);

            combatUnblockOnDeath = GetConfig("Combat", "UnblockWhen", "death", true);
            combatUnblockOnWakeup = GetConfig("Combat", "UnblockWhen", "wakeup", false);
            combatUnblockOnRespawn = GetConfig("Combat", "UnblockWhen", "respawn", true);

            cacheTimer = GetConfig("Settings", "cacheMinutes", 1f);

            sendUINotification = GetConfig("Notifications", "UI", true);
            sendChatNotification = GetConfig("Notifications", "Chat", true);

            sendGUIAnnouncementsNotification = GetConfig("Notifications", "GUIAnnouncements", "enabled", false);
            GUIAnnouncementTintColor = GetConfig("Notifications", "GUIAnnouncements", "backgroundColor", "Red");
            GUIAnnouncementTextColor = GetConfig("Notifications", "GUIAnnouncements", "textColor", "White");

            if ((clanShare || clanCheck) && !Clans)
            {
                clanShare = false;
                clanCheck = false;
                PrintWarning("Clans not found! All clan options disabled.Cannot use clan options without this plugin.http://oxidemod.org/plugins/clans.2087");
            }

            if (friendShare && !Friends)
            {
                friendShare = false;
                friendCheck = false;
                PrintWarning("Friends not found! All friend options disabled.Cannot use friend options without this plugin.http://oxidemod.org/plugins/friends-api.686");
            }

            if (useZoneManager && !ZoneManager)
            {
                useZoneManager = false;
                PrintWarning("ZoneManager not found! All zone options disabled.Cannot use zone options without this plugin.http://oxidemod.org/plugins/zones-manager.739");
            }

            if (sendGUIAnnouncementsNotification && !GUIAnnouncements)
            {
                sendGUIAnnouncementsNotification = false;
                PrintWarning("GUIAnnouncements not found! GUI announcement option disabled.Cannot use gui announcement integration without this plugin.http://oxidemod.org/plugins/gui-announcements.1222");
            }

            if (sendLustyMapNotification && !LustyMap)
            {
                sendLustyMapNotification = false;
                PrintWarning("LustyMap not found! LustyMap notification option disabled.Cannot use LustyMap integration without this plugin.http://oxidemod.org/plugins/lustymap.1333");
            }

            if (sendLustyMapNotification && LustyMap && LustyMapDuration <= 0)
            {
                PrintWarning("LustyMap icon duration is zero, no icon will be displayed");
            }

            UnsubscribeHooks();
        }

        void UnsubscribeHooks()
        {
            if (!blockOnDestroy && !raidUnblockOnDeath && !combatUnblockOnDeath)
                Unsubscribe("OnEntityDeath");

            if (!raidUnblockOnWakeup && !combatUnblockOnWakeup)
                Unsubscribe("OnPlayerSleepEnded");

            if (!combatOnTakeDamage && !combatOnHitPlayer)
                Unsubscribe("OnPlayerAttack");

            if (!blockOnDamage)
                Unsubscribe("OnEntityTakeDamage");

            if (!blockTypes.Contains("repair"))
                Unsubscribe("OnStructureRepair");

            if (!blockTypes.Contains("upgrade"))
                Unsubscribe("OnStructureUpgrade");

            if (!blockTypes.Contains("mailbox"))
                Unsubscribe("CanUseMailbox");

            if (!blockTypes.Contains("vend"))
                Unsubscribe("CanUseVending");

            if (!blockTypes.Contains("build"))
                Unsubscribe("CanBuild");

            if (!blockTypes.Contains("assignbed"))
                Unsubscribe("CanAssignBed");

            if (!blockTypes.Contains("craft"))
                Unsubscribe("CanCraft");
        }

        #endregion

        #region Classes

        public class RaidZone
        {
            public string zoneid;
            public Vector3 position;
            public Timer timer;

            public RaidZone(string zoneid, Vector3 position)
            {
                this.zoneid = zoneid;
                this.position = position;
            }

            public float Distance(RaidZone zone)
            {
                return Vector3.Distance(position, zone.position);
            }

            public float Distance(Vector3 pos)
            {
                return Vector3.Distance(position, pos);
            }

            public RaidZone ResetTimer()
            {
                if (timer is Timer && !timer.Destroyed)
                    timer.Destroy();

                return this;
            }
        }

        public abstract class BlockBehavior : MonoBehaviour
        {
            protected BasePlayer player;
            public DateTime lastBlock = DateTime.MinValue;
            public DateTime lastNotification = DateTime.MinValue;
            internal DateTime lastUINotification = DateTime.MinValue;
            internal Timer timer;
            internal Action notifyCallback;
            internal string iconUID;

            internal abstract float Duration { get; }

            internal abstract CuiRectTransformComponent NotificationWindow { get; }

            internal abstract string notifyMessage { get; }

            internal string BlockName
            {
                get
                {
                    return GetType().Name;
                }
            }

            public bool Active
            {
                get
                {
                    if (lastBlock > DateTime.MinValue)
                    {
                        TimeSpan ts = DateTime.Now - lastBlock;
                        if (ts.TotalSeconds < Duration)
                        {
                            return true;
                        }
                    }

                    GameObject.Destroy(this);

                    return false;
                }
            }

            void Awake()
            {
                player = GetComponent<BasePlayer>();
            }

            void Destroy()
            {
                Stop();
            }

            void Update()
            {
                if (!plugin.sendUINotification)
                    return;
                bool send = false;
                if (lastUINotification == DateTime.MinValue)
                {
                    lastUINotification = DateTime.Now;
                    send = true;
                }
                else
                {
                    TimeSpan ts = DateTime.Now - lastUINotification;
                    if (ts.TotalSeconds > 2)
                    {
                        send = true;
                    }
                    else
                    {
                        send = false;
                    }
                }

                if (player is BasePlayer && player.IsConnected)
                {
                    if (!Active)
                    {
                        CuiHelper.DestroyUi(player, "BlockMsg" + BlockName);
                    }

                    if (send && Active)
                    {
                        lastUINotification = DateTime.Now;
                        SendGUI();
                    }
                }
            }

            public void Stop()
            {
                if (notifyCallback is Action)
                    notifyCallback.Invoke();

                if (timer is Timer && !timer.Destroyed)
                    timer.Destroy();

                if (plugin.sendUINotification && player is BasePlayer && player.IsConnected)
                    CuiHelper.DestroyUi(player, "BlockMsg" + BlockName);

                GameObject.Destroy(this);
            }

            public void Notify(Action callback)
            {
                if (plugin.sendUINotification)
                    SendGUI();
                
                notifyCallback = callback;
                if (timer is Timer && !timer.Destroyed)
                    timer.Destroy();

                timer = plugin.timer.In(Duration, callback);
            }

            private string FormatTime(TimeSpan ts)
            {
                if (ts.Days > 0)
                    return string.Format("{0}D, {1}H", ts.Days, ts.Hours);

                if (ts.Hours > 0)
                    return string.Format("{0}H {1}M", ts.Hours, ts.Minutes);

                return string.Format("{0}M {1}S", ts.Minutes, ts.Seconds);
            }

            void SendGUI()
            {
                TimeSpan ts = lastBlock.AddSeconds(Duration) - DateTime.Now;

                string countDown = FormatTime(ts);
                CuiHelper.DestroyUi(player, "BlockMsg" + BlockName);
                var elements = new CuiElementContainer();
                var BlockMsg = elements.Add(new CuiPanel
                    {
                        Image =
                        {
                            Color = "0.95 0 0.02 0.67"
                        },
                        RectTransform =
                        {
                            AnchorMax = NotificationWindow.AnchorMax,
                            AnchorMin = NotificationWindow.AnchorMin
                        }
                    }, "Hud", "BlockMsg" + BlockName);
                elements.Add(new CuiElement
                    {
                        Parent = BlockMsg,
                        Components =
                        {
                            new CuiRawImageComponent
                            {
                                Sprite = "assets/icons/explosion.png",
                                Color = "0.95 0 0.02 0.67"
                            },
                            new CuiRectTransformComponent
                            {
                                AnchorMin = "0 0",
                                AnchorMax = "0.13 1"
                            }
                        }
                    });
                elements.Add(new CuiLabel
                    {
                        RectTransform =
                        {
                            AnchorMin = "0.15 0",
                            AnchorMax = "0.82 1"
                        },
                        Text =
                        {
                            Text = notifyMessage,
                            FontSize = 11,
                            Align = TextAnchor.MiddleLeft,
                        }
                    }, BlockMsg);
                elements.Add(new CuiElement
                    {
                        Name = "TimerPanel",
                        Parent = BlockMsg,
                        Components =
                        {
                            new CuiImageComponent
                            {
                                Color = "0 0 0 0.64",
                                ImageType = UnityEngine.UI.Image.Type.Filled
                            },
                            new CuiRectTransformComponent
                            {
                                AnchorMin = "0.73 0",
                                AnchorMax = "1 1"
                            }
                        }
                    });
                elements.Add(new CuiLabel
                    {
                        RectTransform =
                        {
                            AnchorMin = "0 0",
                            AnchorMax = "1 1"
                        },
                        Text =
                        {
                            Text = countDown,
                            FontSize = 12,
                            Align = TextAnchor.MiddleCenter,
                        }
                    }, "TimerPanel");
                CuiHelper.AddUi(player, elements);
            }

            
        }

        public class CombatBlock : BlockBehavior
        {
            internal override float Duration
            {
                get
                {
                    return combatDuration;
                }
            }

            internal override string notifyMessage
            {
                get { return NoEscape.GetMsg("Combat Block UI Message", player); }
            }

            private CuiRectTransformComponent _notificationWindow = null;

            internal override CuiRectTransformComponent NotificationWindow
            {
                get
                {
                    if (_notificationWindow != null)
                    {
                        return _notificationWindow;
                    }
                    return _notificationWindow = new CuiRectTransformComponent()
                    {
                        AnchorMin = "0.87 0.35",
                        AnchorMax = "0.99 0.38"
                    };
                }
            }
        }

        public class RaidBlock : BlockBehavior
        {
            internal override float Duration
            {
                get
                {
                    return raidDuration;
                }
            }

            internal override string notifyMessage
            {
                get { return NoEscape.GetMsg("Raid Block UI Message", player); }
            }

            private CuiRectTransformComponent _notificationWindow = null;

            internal override CuiRectTransformComponent NotificationWindow
            {
                get
                {
                    if (_notificationWindow != null)
                    {
                        return _notificationWindow;
                    }
                    return _notificationWindow = new CuiRectTransformComponent()
                    {
                        AnchorMin = "0.87 0.39",
                        AnchorMax = "0.99 0.42"
                    };
                }
            }
        }

        #endregion

        #region Oxide Hooks

        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
        {
            if (!blockOnDamage || !raidBlock)
                return;
            if (hitInfo == null || hitInfo.WeaponPrefab == null || hitInfo.Initiator == null || !IsEntityBlocked(entity) || hitInfo.Initiator.transform == null || hitInfo.Initiator.transform.position == null)
                return;
            if (!IsRaidDamage(hitInfo.damageTypes.GetMajorityDamageType()))
                return;
            if (IsExcludedWeapon(hitInfo.WeaponPrefab.ShortPrefabName))
                return;

            StructureAttack(entity, hitInfo.Initiator, hitInfo.WeaponPrefab.ShortPrefabName, hitInfo.HitPositionWorld);
        }

        void OnPlayerAttack(BasePlayer attacker, HitInfo hitInfo)
        {
            if (!combatBlock || !(hitInfo.HitEntity is BasePlayer))
                return;
            if (!IsCombatDamage(hitInfo.damageTypes.GetMajorityDamageType()))
                return;

            BasePlayer target = hitInfo.HitEntity as BasePlayer;

            if (combatOnTakeDamage)
                StartCombatBlocking(target);

            if (combatOnHitPlayer)
                StartCombatBlocking(attacker);
        }

        private void OnEntityDeath(BaseCombatEntity entity, HitInfo hitInfo)
        {
            if (blockOnDestroy && raidBlock)
            {
                if (hitInfo == null || hitInfo.WeaponPrefab == null || hitInfo.Initiator == null || !IsRaidDamage(hitInfo.damageTypes.GetMajorityDamageType()) || !IsEntityBlocked(entity))
                    return;

                StructureAttack(entity, hitInfo.Initiator, hitInfo.WeaponPrefab.ShortPrefabName, hitInfo.HitPositionWorld);
            }

            if (entity.ToPlayer() == null)
                return;
            var player = entity.ToPlayer();
            RaidBlock raidBlocker;
            if (raidBlock && raidUnblockOnDeath && TryGetBlocker<RaidBlock>(player, out raidBlocker))
            {
                timer.In(0.3f, delegate()
                    {
                        raidBlocker.Stop();
                    });
            }

            CombatBlock combatBlocker;
            if (combatBlock && combatUnblockOnDeath && TryGetBlocker<CombatBlock>(player, out combatBlocker))
            {
                timer.In(0.3f, delegate()
                    {
                        combatBlocker.Stop();
                    });
            }
        }

        void OnPlayerSleepEnded(BasePlayer player)
        {
            RaidBlock raidBlocker;
            if (raidBlock && raidUnblockOnWakeup && TryGetBlocker<RaidBlock>(player, out raidBlocker))
            {
                timer.In(0.3f, delegate()
                    {
                        raidBlocker.Stop();
                    });
            }

            CombatBlock combatBlocker;
            if (combatBlock && combatUnblockOnWakeup && TryGetBlocker<CombatBlock>(player, out combatBlocker))
            {
                timer.In(0.3f, delegate()
                    {
                        combatBlocker.Stop();
                    });
            }
        }

        void OnPlayerRespawned(BasePlayer player)
        {
            if (raidBlock && raidUnblockOnRespawn && IsRaidBlocked(player))
            {
                timer.In(0.3f, delegate()
                    {
                        StopBlocking(player);
                    });
            }

            if (combatBlock && combatUnblockOnRespawn && IsCombatBlocked(player))
            {
                timer.In(0.3f, delegate()
                    {
                        StopBlocking(player);
                    });
            }
        }

        #endregion

        #region Block Handling

        void StructureAttack(BaseEntity targetEntity, BaseEntity sourceEntity, string weapon, Vector3 hitPosition)
        {
            BasePlayer source = null;

            if (sourceEntity.ToPlayer() is BasePlayer)
                source = sourceEntity.ToPlayer();
            else
            {
                ulong ownerID = sourceEntity.OwnerID;
                if (ownerID.IsSteamId())
                    source = BasePlayer.FindByID(ownerID);
                else
                    return;
            }

            if (source == null)
                return;

            List<string> sourceMembers = null;

            if (targetEntity.OwnerID.IsSteamId() || (blockUnowned && !targetEntity.OwnerID.IsSteamId()))
            {
                if (clanCheck || friendCheck)
                    sourceMembers = getFriends(source.UserIDString);

                if (blockAll)
                {
                    BlockAll(source, targetEntity.transform.position, sourceMembers);
                }
                else
                {
                    if (ownerBlock)
                        OwnerBlock(source, sourceEntity, targetEntity.OwnerID, targetEntity.transform.position, sourceMembers);

                    if (raiderBlock)
                        RaiderBlock(source, targetEntity.OwnerID, targetEntity.transform.position, sourceMembers);
                }
            }
        }

        void BlockAll(BasePlayer source, Vector3 position, List<string> sourceMembers = null)
        {
            StartRaidBlocking(source, position);
            var nearbyTargets = Pool.GetList<BasePlayer>();
            Vis.Entities<BasePlayer>(position, raidDistance, nearbyTargets, blockLayer);
            if (nearbyTargets.Count > 0)
            {
                RaidBlock blocker;
                foreach (BasePlayer nearbyTarget in nearbyTargets)
                {
                    if (TryGetBlocker<RaidBlock>(nearbyTarget, out blocker) && blocker.Active)
                    {
                        StartRaidBlocking(nearbyTarget, position);
                    }
                    else if (ShouldBlockEscape(nearbyTarget.userID, source.userID, sourceMembers))
                    {
                        StartRaidBlocking(nearbyTarget, position);
                    }
                }
            }

            Pool.FreeList<BasePlayer>(ref nearbyTargets);
        }

        void OwnerBlock(BasePlayer source, BaseEntity sourceEntity, ulong target, Vector3 position, List<string> sourceMembers = null)
        {
            if (!ShouldBlockEscape(target, source.userID, sourceMembers))
                return;
            
            var targetMembers = new List<string>();

            if (clanShare || friendShare)
                targetMembers = getFriends(target.ToString());

            var nearbyTargets = Pool.GetList<BasePlayer>();
            Vis.Entities<BasePlayer>(position, raidDistance, nearbyTargets, blockLayer);
            if (cupboardShare)
                sourceMembers = CupboardShare(target.ToString(), position, sourceEntity, sourceMembers);

            if (nearbyTargets.Count > 0)
                foreach (BasePlayer nearbyTarget in nearbyTargets)
                    if (nearbyTarget.userID == target || (targetMembers != null && targetMembers.Contains(nearbyTarget.UserIDString)))
                        StartRaidBlocking(nearbyTarget, position);

            Pool.FreeList<BasePlayer>(ref nearbyTargets);
        }

        List<string> CupboardShare(string owner, Vector3 position, BaseEntity sourceEntity, List<string> sourceMembers = null)
        {
            var nearbyCupboards = Pool.GetList<BuildingPrivlidge>();
            Vis.Entities<BuildingPrivlidge>(position, raidDistance, nearbyCupboards, cupboardMask);
            if (sourceMembers == null)
                sourceMembers = new List<string>();

            List<string> cupboardMembers = new List<string>();

            var sourcePlayer = sourceEntity as BasePlayer;

            if (sourcePlayer != null)
            {
                foreach (var cup in nearbyCupboards)
                {
                    if (cup.IsAuthed(sourcePlayer))
                    {
                        bool ownerOrFriend = false;

                        if (owner == cup.OwnerID.ToString())
                            ownerOrFriend = true;

                        foreach (var member in sourceMembers)
                        {
                            if (member == cup.OwnerID.ToString())
                                ownerOrFriend = true;
                        }

                        if (ownerOrFriend)
                            foreach (var proto in cup.authorizedPlayers)
                                if (!sourceMembers.Contains(proto.userid.ToString()))
                                    cupboardMembers.Add(proto.userid.ToString());
                    }
                }
            }

            sourceMembers.AddRange(cupboardMembers);
            Pool.FreeList<BuildingPrivlidge>(ref nearbyCupboards);

            return sourceMembers;
        }

        void RaiderBlock(BasePlayer source, ulong target, Vector3 position, List<string> sourceMembers = null)
        {
            if (!ShouldBlockEscape(target, source.userID, sourceMembers))
                return;

            var targetMembers = new List<string>();

            if ((clanShare || friendShare) && sourceMembers == null)
                sourceMembers = getFriends(source.UserIDString);

            var nearbyTargets = Pool.GetList<BasePlayer>();
            Vis.Entities<BasePlayer>(position, raidDistance, nearbyTargets, blockLayer);
            if (nearbyTargets.Count > 0)
                foreach (BasePlayer nearbyTarget in nearbyTargets)
                    if (nearbyTarget == source || (sourceMembers != null && sourceMembers.Contains(nearbyTarget.UserIDString)))
                        StartRaidBlocking(nearbyTarget, position);

            Pool.FreeList<BasePlayer>(ref nearbyTargets);
        }

        #endregion

        #region API

        bool IsBlocked(string target)
        {
            var player = BasePlayer.Find(target);
            if (player is BasePlayer)
            {
                return IsBlocked(player);
            }

            return false;
        }

        bool IsBlocked(BasePlayer target)
        {
            if (IsBlocked<RaidBlock>(target) || IsBlocked<CombatBlock>(target))
                return true;

            return false;
        }

        public bool IsBlocked<T>(BasePlayer target) where T : BlockBehavior
        {
            T behavior;
            if (TryGetBlocker<T>(target, out behavior) && behavior.Active)
                return true;

            return false;
        }

        bool IsRaidBlocked(BasePlayer target)
        {
            return IsBlocked<RaidBlock>(target);
        }

        bool IsCombatBlocked(BasePlayer target)
        {
            return IsBlocked<CombatBlock>(target);
        }

        bool IsEscapeBlocked(string target)
        {
            var player = BasePlayer.Find(target);
            if (player is BasePlayer)
            {
                return IsBlocked(player);
            }

            return false;
        }

        bool IsRaidBlocked(string target)
        {
            var player = BasePlayer.Find(target);
            if (player is BasePlayer)
            {
                return IsBlocked<RaidBlock>(player);
            }

            return false;
        }

        bool IsCombatBlocked(string target)
        {
            var player = BasePlayer.Find(target);
            if (player is BasePlayer)
            {
                return IsBlocked<CombatBlock>(player);
            }

            return false;
        }

        bool ShouldBlockEscape(ulong target, ulong source, List<string> sourceMembers = null)
        {
            if (target == source)
            {
                if ((ownerBlock || raiderBlock) && (!ownerCheck))
                    return true;

                return false;
            }

            if (sourceMembers is List<string> && sourceMembers.Count > 0 && sourceMembers.Contains(target.ToString()))
                return false;

            return true;
        }

        //[ChatCommand("bblocked")]
        //void cmdBBlocked(BasePlayer player, string command, string[] args)
        //{
        //    StartCombatBlocking(player);
        //    StartRaidBlocking(player);
        //}

        void StartRaidBlocking(BasePlayer target, bool createZone = true)
        {
            StartRaidBlocking(target, target.transform.position, createZone);
        }

        void StartRaidBlocking(BasePlayer target, Vector3 position, bool createZone = true)
        {
            if (HasPerm(target.UserIDString, "disable"))
            {
                return;
            }
            if (position == null)
            {
                position = target.transform.position;
            }
            if (target.gameObject == null)
                return;
            var raidBlocker = target.gameObject.GetComponent<RaidBlock>();
            if (raidBlocker == null)
            {
                raidBlocker = target.gameObject.AddComponent<RaidBlock>();
            }

            raidBlocker.lastBlock = DateTime.Now;

            if (raidBlockNotify)
                SendBlockMessage(target, raidBlocker, "Raid Block Notifier", "Raid Block Complete");

            if (useZoneManager && createZone && (zoneEnter || zoneLeave))
                CreateRaidZone(position);
        }

        void StartCombatBlocking(BasePlayer target)
        {
            if (HasPerm(target.UserIDString, "disable"))
            {
                return;
            }
            if (target.gameObject == null)
                return;
            var combatBlocker = target.gameObject.GetComponent<CombatBlock>();
            if (combatBlocker == null)
            {
                combatBlocker = target.gameObject.AddComponent<CombatBlock>();
            }

            combatBlocker.lastBlock = DateTime.Now;

            if (combatBlockNotify)
                SendBlockMessage(target, combatBlocker, "Combat Block Notifier", "Combat Block Complete");
        }

        void StopBlocking(BasePlayer target)
        {
            if (IsRaidBlocked(target))
                StopBlocking<RaidBlock>(target);
            if (IsCombatBlocked(target))
                StopBlocking<CombatBlock>(target);
        }

        public void StopBlocking<T>(BasePlayer target) where T : BlockBehavior
        {
            if (target.gameObject == null)
                return;
            var block = target.gameObject.GetComponent<T>();
            if (block is BlockBehavior)
                block.Stop();
        }

        void ClearRaidBlockingS(string target)
        {
            StopRaidBlocking(target);
        }

        void StopRaidBlocking(string target)
        {
            var player = BasePlayer.Find(target);
            if (player is BasePlayer && IsRaidBlocked(player))
                StopBlocking<RaidBlock>(player);
        }

        void StopCombatBlocking(string target)
        {
            var player = BasePlayer.Find(target);
            if (player is BasePlayer && IsRaidBlocked(player))
                StopBlocking<CombatBlock>(player);
        }

        void ClearCombatBlocking(string target)
        {
            StopCombatBlocking(target);
        }

        #endregion

        #region Zone Handling

        void EraseZone(string zoneid)
        {
            ZoneManager.CallHook("EraseZone", zoneid);
            zones.Remove(zoneid);
        }

        void ResetZoneTimer(RaidZone zone)
        {
            zone.ResetTimer().timer = timer.In(raidDuration, delegate()
                {
                    EraseZone(zone.zoneid);
                });
        }

        void CreateRaidZone(Vector3 position)
        {
            var zoneid = position.ToString();

            RaidZone zone;
            if (zones.TryGetValue(zoneid, out zone))
            {
                ResetZoneTimer(zone);
                return;
            }
            else
            {
                foreach (var nearbyZone in zones)
                {
                    if (nearbyZone.Value.Distance(position) < (raidDistance / 2))
                    {
                        ResetZoneTimer(nearbyZone.Value);
                        return;
                    }
                }
            }

            ZoneManager.CallHook("CreateOrUpdateZone", zoneid, new string[]
                {
                    "radius",
                    raidDistance.ToString()
                }, position);

            zones.Add(zoneid, zone = new RaidZone(zoneid, position));

            ResetZoneTimer(zone);
        }

        [HookMethod("OnEnterZone")]
        void OnEnterZone(string zoneid, BasePlayer player)
        {
            if (!zoneEnter)
                return;
            if (!zones.ContainsKey(zoneid))
                return;

            StartRaidBlocking(player, player.transform.position, false);
        }

        [HookMethod("OnExitZone")]
        void OnExitZone(string zoneid, BasePlayer player)
        {
            if (!zoneLeave)
                return;
            if (!zones.ContainsKey(zoneid))
                return;

            if (IsRaidBlocked(player))
            {
                StopBlocking<RaidBlock>(player);
            }
        }

        #endregion

        #region Friend/Clan Integration

        public List<string> getFriends(string player)
        {
            var players = new List<string>();
            if (player == null)
                return players;

            if (friendShare || friendCheck)
            {
                var friendList = getFriendList(player);
                if (friendList != null)
                    players.AddRange(friendList);
            }

            if (clanShare || clanCheck)
            {
                var members = getClanMembers(player);
                if (members != null)
                    players.AddRange(members);
            }
            return players;
        }

        public List<string> getFriendList(string player)
        {
            object friends_obj = null;
            DateTime lastFriendCheckPlayer;
            var players = new List<string>();

            if (lastFriendCheck.TryGetValue(player, out lastFriendCheckPlayer))
            {
                if ((DateTime.Now - lastFriendCheckPlayer).TotalMinutes <= cacheTimer && friendCache.TryGetValue(player, out players))
                {
                    return players;
                }
                else
                {
                    friends_obj = Friends?.CallHook("IsFriendOfS", player);
                    lastFriendCheck[player] = DateTime.Now;
                }
            }
            else
            {
                friends_obj = Friends?.CallHook("IsFriendOfS", player);
                lastFriendCheck.Add(player, DateTime.Now);
            }

            if (friends_obj == null)
                return players;

            string[] friends = friends_obj as string[];
            
            foreach (string fid in friends)
                players.Add(fid);

            if (friendCache.ContainsKey(player))
                friendCache[player] = players;
            else
                friendCache.Add(player, players);

            return players;
        }

        public List<string> getClanMembers(string player)
        {
            string tag = null;
            DateTime lastClanCheckPlayer;
            string lastClanCached;
            if (lastClanCheck.TryGetValue(player, out lastClanCheckPlayer) && clanCache.TryGetValue(player, out lastClanCached))
            {
                if ((DateTime.Now - lastClanCheckPlayer).TotalMinutes <= cacheTimer)
       
// ... [Code preview truncated due to length. Full source in attached file] ...

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