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

FREE AdminRadar : 5.4.2 5.4.2

Нет прав для скачивания
C#:
//#define DEBUG
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust.Ai.Gen2;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using static Oxide.Plugins.AdminRadarExtensionMethods.ExtensionMethods;
namespace Oxide.Plugins {
    [Info("Admin Radar", "nivex", "5.4.2")]
    [Description("Radar tool for Admins and Developers.")]
    internal class AdminRadar : RustPlugin {
        [PluginReference]
        Plugin Clans, Backpacks;
        [Flags]
        public enum DrawFlags {
            None = 0, Arrow = 1 << 1, Box = 1 << 2, Text = 1 << 3,
        }
        public enum EntityType {
            Active, Airdrop, Bag, Backpack, Boat, Bradley, Car, CargoPlane, CargoShip, CCTV, CH47, Box, Col, TC, TCArrow, Dead, Drop, Limit, Loot, Heli, Mini, MLRS, Npc, Ore, Horse, RHIB, Sleeper, Stash, Trap, Turret
        }
        private List<string> _tags = new() {
            "ore", "cluster", "1", "2", "3", "4", "5", "6", "_", ".", "-", "deployed", "wooden", "large", "pile", "prefab", "collectable", "loot", "small"
        }
        ;
        private List<EntityType> _errorTypes = new();
        private List<Radar> _radars = new();
        private List<BaseEntity> _spawnedEntities = new();
        private List<ClanInfo> _clans = new();
        private Dictionary<NetworkableId, Vector3> _despawnedEntities = new();
        private Dictionary<NetworkableId, BaseEntity> _allEntities = new();
        private Dictionary<string, float> _cooldowns = new();
        private Dictionary<ulong, string> _teamColors = new();
        private Dictionary<string, string> _clanColors = new();
        private Array _allEntityTypes = Enum.GetValues(typeof(EntityType));
        private CoroutineTimer _coroutineTimer = new(1.0f);
        private Coroutine _clanCo;
        private Stack<Coroutine> _coroutines = new();
        private StoredData data = new();
        private bool _isPopulatingCache;
        private bool isUnloading;
        private Cache cache;
        private class StoredData {
            public Dictionary<ulong, UiOffsets> Offsets = new();
            public Dictionary<string, int> EntityTextSize = new();
            public Dictionary<string, int> EntityNameSize = new();
            public Dictionary<string, int> PlayerTextSize = new();
            public Dictionary<string, int> PlayerNameSize = new();
            public List<string> Extended = new();
            public Dictionary<string, List<string>> Filters = new();
            public List<string> Hidden = new();
            public List<string> OnlineBoxes = new();
            public List<string> Visions = new();
            public List<string> Active = new();
            public StoredData() {
            }
            public void Init() {
                Offsets ??= new();
                EntityTextSize ??= new();
                EntityNameSize ??= new();
                PlayerTextSize ??= new();
                PlayerNameSize ??= new();
                Extended ??= new();
                Filters ??= new();
                Hidden ??= new();
                OnlineBoxes ??= new();
                Visions ??= new();
                Active ??= new();
            }
        }
        private class Cache {
            public Cache(AdminRadar instance) {
                config = instance.config;
                this.instance = instance;
            }
            public Configuration config;
            public AdminRadar instance;
            internal EntityType entityType;
            public Dictionary<NetworkableId, EntityInfo> Airdrops = new();
            public Dictionary<NetworkableId, EntityInfo> Animals = new();
            public Dictionary<NetworkableId, EntityInfo> Backpacks = new();
            public Dictionary<NetworkableId, EntityInfo> Bags = new();
            public Dictionary<NetworkableId, EntityInfo> Boats = new();
            public Dictionary<NetworkableId, EntityInfo> BradleyAPCs = new();
            public Dictionary<NetworkableId, EntityInfo> CargoPlanes = new();
            public Dictionary<NetworkableId, EntityInfo> CargoShips = new();
            public Dictionary<NetworkableId, EntityInfo> Cars = new();
            public Dictionary<NetworkableId, EntityInfo> CCTV = new();
            public Dictionary<NetworkableId, EntityInfo> CH47 = new();
            public Dictionary<NetworkableId, EntityInfo> Cupboards = new();
            public Dictionary<NetworkableId, EntityInfo> Collectibles = new();
            public Dictionary<NetworkableId, EntityInfo> Containers = new();
            public Dictionary<NetworkableId, EntityInfo> Corpses = new();
            public Dictionary<NetworkableId, EntityInfo> Drops = new();
            public Dictionary<NetworkableId, EntityInfo> Helicopters = new();
            public Dictionary<NetworkableId, EntityInfo> MiniCopter = new();
            public Dictionary<NetworkableId, EntityInfo> MLRS = new();
            public Dictionary<NetworkableId, EntityInfo> NPC = new();
            public Dictionary<NetworkableId, EntityInfo> Ores = new();
            public Dictionary<NetworkableId, EntityInfo> RHIB = new();
            public Dictionary<NetworkableId, EntityInfo> RidableHorse = new();
            public Dictionary<NetworkableId, EntityInfo> Turrets = new();
            public Dictionary<NetworkableId, EntityInfo> Traps = new();
            public bool Add(BaseEntity entity) {
                if (entity.IsKilled()) {
                    return false;
                }
                if (IsDrop(entity)) {
                    Add_Internal<BaseEntity, EntityInfo>(Drops, entity, EntityType.Drop);
                }
                if (entity is BasePlayer player) {
                    Interface.Oxide.NextTick(() => {
                        if (player.IsKilled()) {
                            return;
                        }
                        if (player.userID.IsSteamId()) {
                            instance._radars.ForEach(radar => {
                                if (radar.GetBool(EntityType.Active)) {
                                    radar.TryCacheOnlinePlayer(player);
                                }
                            }
                            );
                        }
                        else if (config.Core.NPC && !NPC.TryGetValue(entity.net.ID, out var ei)) {
                            NPC[entity.net.ID] = ei = new(player, EntityType.Npc, config.Distance.Get);
                            instance.TryCacheByType(EntityType.Npc, ei);
                        }
                    }
                    );
                    return false;
                }
                if (config.Core.Dead && entity is PlayerCorpse corpse) {
                    Interface.Oxide.NextTick(() => {
                        if (!corpse.IsKilled() && corpse.playerSteamID.IsSteamId() && !Corpses.TryGetValue(entity.net.ID, out var ei)) {
                            Corpses[entity.net.ID] = ei = new(entity, EntityType.Dead, config.Distance.Get);
                            ei.name = corpse.parentEnt?.ToString() ?? corpse.playerSteamID.ToString();
                            instance.TryCacheByType(EntityType.Dead, ei);
                        }
                    }
                    );
                    return false;
                }
                if ((config.Additional.Traps || config.GUI.Traps) && IsTrap(entity) && Add_Internal<BaseEntity, EntityInfo>(Traps, entity, EntityType.Trap)) {
                    return true;
                }
                if (config.Additional.RH && Add_Internal<RidableHorse, EntityInfo>(RidableHorse, entity, EntityType.Horse)) {
                    return true;
                }
                if (config.Core.NPC && Add_Internal<TravellingVendor, EntityInfo>(NPC, entity, EntityType.Npc)) {
                    return true;
                }
                if (config.Core.Animals && Add_Internal<BaseNpc, EntityInfo>(Animals, entity, EntityType.Npc)) {
                    return true;
                }
                if (config.Core.Animals && Add_Internal<BaseNPC2, EntityInfo>(Animals, entity, EntityType.Npc)) {
                    return true;
                }
                if (config.Core.Animals && Add_Internal<WildlifeHazard, EntityInfo>(Animals, entity, EntityType.Npc)) {
                    return true;
                }
                if (config.Core.Animals && Add_Internal<SimpleShark, EntityInfo>(Animals, entity, EntityType.Npc)) {
                    return true;
                }
                if (config.Core.Loot && entity is TrainCarUnloadable tcu && Add_Internal<StorageContainer, EntityInfo>(Containers, tcu.GetStorageContainer(), EntityType.Loot)) {
                    return true;
                }
                if ((config.Core.Loot || config.Core.Box || config.Core.Stash) && entity is StorageContainer && TryGetContainerType(entity, out entityType) && Add_Internal<StorageContainer, EntityInfo>(Containers, entity, entityType)) {
                    return true;
                }
                if (config.Core.Col && entity is CollectibleEntity && Add_Internal<CollectibleEntity, EntityInfo>(Collectibles, entity, EntityType.Col)) {
                    return true;
                }
                if (config.Core.Ore && entity is OreResourceEntity && Add_Internal<OreResourceEntity, EntityInfo>(Ores, entity, EntityType.Ore)) {
                    return true;
                }
                if ((config.Additional.Cars || config.GUI.Cars) && (Add_Internal<BasicCar, EntityInfo>(Cars, entity, EntityType.Car) || Add_Internal<ModularCar, EntityInfo>(Cars, entity, EntityType.Car) || Add_Internal<Bike, EntityInfo>(Cars, entity, EntityType.Car))) {
                    return true;
                }
                if ((config.Additional.CP || config.GUI.CP) && entity.prefabID == 2383782438 && Add_Internal<BaseEntity, EntityInfo>(CargoPlanes, entity, EntityType.CargoPlane)) {
                    return true;
                }
                if (config.Core.Bags && Add_Internal<SleepingBag, EntityInfo>(Bags, entity, EntityType.Bag)) {
                    return true;
                }
                if (config.Core.TC && Add_Internal<BuildingPrivlidge, EntityInfo>(Cupboards, entity, EntityType.TC)) {
                    return true;
                }
                if ((config.Additional.CCTV || config.GUI.CCTV) && (Add_Internal<CCTV_RC, EntityInfo>(CCTV, entity, EntityType.CCTV) || Add_Internal<Drone, EntityInfo>(CCTV, entity, EntityType.CCTV))) {
                    return true;
                }
                if (config.Core.Airdrop && Add_Internal<SupplyDrop, EntityInfo>(Airdrops, entity, EntityType.Airdrop)) {
                    return true;
                }
                if (config.Core.Loot && Add_Internal<DroppedItemContainer, EntityInfo>(Backpacks, entity, EntityType.Backpack)) {
                    return true;
                }
                if (config.Core.Loot && entity is WorldItem wi && wi.item != null && wi.item.IsBackpack() && Add_Internal<WorldItem, EntityInfo>(Backpacks, entity, EntityType.Backpack)) {
                    return true;
                }
                if ((config.Additional.Heli || config.GUI.Heli) && Add_Internal<PatrolHelicopter, EntityInfo>(Helicopters, entity, EntityType.Heli)) {
                    return true;
                }
                if ((config.Additional.Bradley || config.GUI.Bradley) && (Add_Internal<BradleyAPC, EntityInfo>(BradleyAPCs, entity, EntityType.Bradley))) {
                    return true;
                }
                if ((config.Additional.RHIB || config.GUI.RHIB) && Add_Internal<RHIB, EntityInfo>(RHIB, entity, EntityType.RHIB)) {
                    return true;
                }
                if ((config.Additional.Boats || config.GUI.Boats) && Add_Internal<BaseBoat, EntityInfo>(Boats, entity, EntityType.Boat)) {
                    return true;
                }
                if ((config.Additional.MC || config.GUI.MC) && (Add_Internal<Minicopter, EntityInfo>(MiniCopter, entity, EntityType.Mini) || Add_Internal<AttackHelicopter, EntityInfo>(MiniCopter, entity, EntityType.Mini))) {
                    return true;
                }
                if ((config.Additional.CH47 || config.GUI.CH47) && Add_Internal<CH47Helicopter, EntityInfo>(CH47, entity, EntityType.CH47)) {
                    return true;
                }
                if ((config.Additional.CS || config.GUI.CS) && Add_Internal<CargoShip, EntityInfo>(CargoShips, entity, EntityType.CargoShip)) {
                    return true;
                }
                if (config.Core.Turrets && Add_Internal<AutoTurret, EntityInfo>(Turrets, entity, EntityType.Turret)) {
                    return true;
                }
                if ((config.Additional.MLRS || config.GUI.MLRS) && Add_Internal<MLRSRocket, EntityInfo>(MLRS, entity, EntityType.MLRS)) {
                    return true;
                }
                return false;
            }
            private bool TryGetContainerType(BaseEntity entity, out EntityType type) {
                if (entity is LockedByEntCrate || IsLoot(entity)) {
                    type = EntityType.Loot;
                    return true;
                }
                if (entity is StashContainer) {
                    type = EntityType.Stash;
                    return true;
                }
                if (IsBox(entity)) {
                    type = EntityType.Box;
                    return true;
                }
                type = (EntityType)0;
                return false;
            }
            public bool Remove(NetworkableId nid, Vector3 entityPos) {
                instance._radars.ForEach(radar => radar.RemoveByNetworkId(nid));
                if (Remove_Internal(Airdrops, nid)) return true;
                if (Remove_Internal(Animals, nid)) return true;
                if (Remove_Internal(Backpacks, nid)) return true;
                if (Remove_Internal(Bags, nid)) return true;
                if (Remove_Internal(Boats, nid)) return true;
                if (Remove_Internal(BradleyAPCs, nid)) return true;
                if (Remove_Internal(CargoPlanes, nid)) return true;
                if (Remove_Internal(CargoShips, nid)) return true;
                if (Remove_Internal(Cars, nid)) return true;
                if (Remove_Internal(CCTV, nid)) return true;
                if (Remove_Internal(CH47, nid)) return true;
                if (Remove_Internal(Collectibles, nid)) return true;
                if (Remove_Internal(Containers, nid)) return true;
                if (Remove_Internal(Corpses, nid)) return true;
                if (Remove_Internal(Cupboards, nid)) return true;
                if (Remove_Internal(Helicopters, nid)) return true;
                if (Remove_Internal(MiniCopter, nid)) return true;
                if (Remove_Internal(MLRS, nid)) return true;
                if (Remove_Internal(NPC, nid)) return true;
                if (Remove_Internal(Ores, nid)) return true;
                if (Remove_Internal(RHIB, nid)) return true;
                if (Remove_Internal(RidableHorse, nid)) return true;
                if (Remove_Internal(Traps, nid)) return true;
                if (Remove_Internal(Turrets, nid)) return true;
                return false;
            }
            private bool Add_Internal<TLookFor, TTargetType>(Dictionary<NetworkableId, EntityInfo> cachedList, BaseEntity entity, EntityType type) {
                if (entity is TLookFor && !entity.IsKilled() && !cachedList.TryGetValue(entity.net.ID, out var ei)) {
                    cachedList[entity.net.ID] = ei = new(entity, type, config.Distance.Get, instance.StripTags);
                    instance.TryCacheByType(type, ei);
                    return true;
                }
                return false;
            }
            private bool Remove_Internal<TType, TKeyType>(Dictionary<TKeyType, TType> cachedList, TKeyType key) {
                return cachedList.Remove(key);
            }
            public void Print() {
                StringBuilder sb = StringBuilderCache.Acquire();
                sb.AppendLine();
                sb.AppendLine($"{nameof(Airdrops)}: {Airdrops.Count}");
                sb.AppendLine($"{nameof(Animals)}: {Animals.Count}");
                sb.AppendLine($"{nameof(Backpacks)}: {Backpacks.Count}");
                sb.AppendLine($"{nameof(Bags)}: {Bags.Count}");
                sb.AppendLine($"{nameof(Boats)}: {Boats.Count}");
                sb.AppendLine($"{nameof(BradleyAPCs)}: {BradleyAPCs.Count}");
                sb.AppendLine($"{nameof(CargoPlanes)}: {CargoPlanes.Count}");
                sb.AppendLine($"{nameof(CargoShips)}: {CargoShips.Count}");
                sb.AppendLine($"{nameof(Cars)}: {Cars.Count}");
                sb.AppendLine($"{nameof(CCTV)}: {CCTV.Count}");
                sb.AppendLine($"{nameof(CH47)}: {CH47.Count}");
                sb.AppendLine($"{nameof(Collectibles)}: {Collectibles.Count}");
                sb.AppendLine($"{nameof(Containers)}: {Containers.Count}");
                sb.AppendLine($"{nameof(Corpses)}: {Corpses.Count}");
                sb.AppendLine($"{nameof(Cupboards)}: {Cupboards.Count}");
                sb.AppendLine($"{nameof(Helicopters)}: {Helicopters.Count}");
                sb.AppendLine($"{nameof(MiniCopter)}: {MiniCopter.Count}");
                sb.AppendLine($"{nameof(MLRS)}: {MLRS.Count}");
                sb.AppendLine($"{nameof(NPC)}: {NPC.Count}");
                sb.AppendLine($"{nameof(Ores)}: {Ores.Count}");
                sb.AppendLine($"{nameof(RHIB)}: {RHIB.Count}");
                sb.AppendLine($"{nameof(RidableHorse)}: {RidableHorse.Count}");
                sb.AppendLine($"{nameof(Traps)}: {Traps.Count}");
                sb.AppendLine($"{nameof(Turrets)}: {Turrets.Count}");
                Puts(StringBuilderCache.GetStringAndRelease(sb));
            }
            public bool IsDrop(BaseEntity entity) {
                if (entity is DroppedItem || entity is Landmine || entity is BearTrap || entity is DroppedItemContainer || entity is RFTimedExplosive) {
                    return !config.Settings.DropExceptions.Exists(entity.ShortPrefabName.Contains);
                }
                return false;
            }
            public bool IsTrap(BaseNetworkable entity) {
                return entity is BaseTrap || config.Options.AdditionalTraps.Exists(entity.ShortPrefabName.Contains);
            }
            public bool IsLoot(BaseNetworkable entity) {
                if (config.Core.Loot) {
                    if (entity is WorldItem wi) {
                        return wi.item != null && wi.item.IsBackpack();
                    }
                    return entity is TrainCarUnloadable || entity.ShortPrefabName == "campfire" || entity.ShortPrefabName.Contains("loot", CompareOptions.IgnoreCase) || entity.ShortPrefabName.Contains("crate_", CompareOptions.IgnoreCase) || entity.ShortPrefabName.Contains("trash", CompareOptions.IgnoreCase) || entity.ShortPrefabName.Contains("hackable", CompareOptions.IgnoreCase) || entity.ShortPrefabName.Contains("oil", CompareOptions.IgnoreCase) || entity.ShortPrefabName.Contains("vehicle_parts") || entity.ShortPrefabName.Contains("foodbox") || entity.ShortPrefabName == "krieg_storage_horizontal" || entity.ShortPrefabName == "krieg_storage_vertical";
                }
                return false;
            }
            public bool IsBox(BaseNetworkable entity) {
                if (config.Core.Box) {
                    return config.Options.AdditionalBoxes.Exists(entity.ShortPrefabName.Contains);
                }
                return false;
            }
        }
        private class CoroutineTimer {
            private Stopwatch stopwatch = new();
            private float _maxDurationMs;
            private bool _isRunning;
            //public bool ForceStop;
            public double Elapsed => stopwatch.Elapsed.TotalMilliseconds;
            public CoroutineTimer(float maxDurationMs) {
                _maxDurationMs = maxDurationMs;
            }
            public void Stop() {
                stopwatch.Stop();
                _isRunning = false;
            }
            public void Start() {
                stopwatch.Start();
                _isRunning = true;
            }
            public bool ShouldYield() {
                _isRunning = stopwatch.Elapsed.TotalMilliseconds < _maxDurationMs;
                if (!_isRunning) {
#if DEBUG
                    double milliseconds = Elapsed;
                    if (stopwatch.Elapsed.TotalMilliseconds > 2f * _maxDurationMs) {
                        Interface.Oxide.LogInfo($"[AdminRadar] Time slice took {Elapsed} when it should be around {_maxDurationMs}");
                    }
#endif
                }
                return !_isRunning;
            }
            public void ResetIfYielded() {
                if (_isRunning) return;
                stopwatch.Restart();
                _isRunning = true;
            }
        }
        internal static class StringBuilderCache {
            public static StringBuilder Acquire(string text = "") {
                StringBuilder builder = Pool.Get<StringBuilder>();
                if (string.IsNullOrEmpty(text)) return builder;
                return builder.Append(text);
            }
            public static string GetStringAndRelease(StringBuilder sb) {
                string result = sb.ToString();
                Pool.FreeUnmanaged(ref sb);
                return result;
            }
        }
        public class EntityInfo {
            public BuildingPrivlidge priv;
            public BaseEntity entity;
            public BasePlayer owner;
            public EntityType type;
            public Color color;
            public Vector3 _from;
            public Vector3 to;
            public Vector3 offset;
            public string name;
            public object info;
            public float dist;
            public float nextonlinecheck;
            public float sqrdist;
            public float size = 0.5f;
            public Transform t;
            public Network.Visibility.Group group => entity?.net?.group;
            public Vector3 from => (t == null ? _from : _from = t.position) + offset;
            public bool Moving => type == EntityType.Airdrop || type == EntityType.Bradley || type == EntityType.CargoPlane || type == EntityType.Heli;
            public bool OutOfRange(Vector3 position) {
                if (entity == null || (from - position).sqrMagnitude > sqrdist) {
                    info = null;
                    return true;
                }
                return false;
            }
            public BasePlayer ToPlayer() {
                if (owner == null && Time.time > nextonlinecheck) {
                    nextonlinecheck = Time.time + 30f;
                    owner = BasePlayer.FindAwakeOrSleeping(entity.OwnerID.ToString());
                }
                return owner;
            }
            public EntityInfo() {
            }
            public EntityInfo(BaseEntity entity, EntityType type, Func<EntityType, BaseEntity, float> getDistance, Func<string, string> stripTags = null) {
                if (stripTags != null) {
                    name = stripTags(entity.ShortPrefabName);
                }
                if (getDistance != null) {
                    dist = getDistance(type, entity);
                    sqrdist = dist * dist;
                }
                if (type == EntityType.TC) {
                    priv = entity as BuildingPrivlidge;
                }
                this.type = type;
                this.entity = entity;
                t = entity.transform;
                _from = t.position;
            }
        }
        private class Radar : FacepunchBehaviour {
            private string abbr(string s) {
                if (string.IsNullOrEmpty(s) || s.Length > 256) return s;
                Span<char> buf = stackalloc char[s.Length];
                int n = 0;
                for (int i = 0; i < s.Length; i++) {
                    char c = s[i];
                    if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) buf[n++] = c;
                }
                return new string(buf.Slice(0, n));
            }
            public class DataObject : Pool.IPooled {
                public EntityInfo ei;
                public Action action;
                public DrawFlags flags;
                public bool disabled;
                public DataObject() {
                }
                public bool HasFlag(DrawFlags flag) {
                    return ((flags & flag) == flag);
                }
                public void SetEnabled(Network.Visibility.Group group, Vector3 to, float max) {
                    if (ei == null) {
                        disabled = true;
                    }
                    else if (!ei.Moving) {
                        disabled = ei.group != group && (ei.from - to).sqrMagnitude > Mathf.Max(max * max, ei.sqrdist);
                    }
                }
                public bool IsOfType(EntityType type) {
                    if (type != EntityType.Loot) {
                        return ei.type == type;
                    }
                    return ei.type == EntityType.Loot || ei.type == EntityType.Backpack;
                }
                public void Reset() {
                    ei = null;
                    action = null;
                    disabled = false;
                    flags = DrawFlags.None;
                }
                public void EnterPool() {
                    Reset();
                }
                public void LeavePool() {
                    Reset();
                }
            }
            internal class DistantPlayer : Pool.IPooled {
                public Vector3 pos;
                public bool alive;
                public DistantPlayer() {
                }
                public void Reset() {
                    pos = default;
                    alive = false;
                }
                public void EnterPool() {
                    Reset();
                }
                public void LeavePool() {
                    Reset();
                }
            }
            internal bool setSource = true, canGetExistingBackpacks = true, isEnabled = true, canBypassOverride, hasPermAllowed, isAdmin, showHT, showAll, Extended;
            internal int entityNameSize, entityTextSize, playerNameSize, playerTextSize, inactiveSeconds, activatedSeconds, checks;
            internal float currDistance, invokeTime, maxDistance;
            internal string username, userid;
            internal RaycastHit hit;
            internal EntityType currType;
            internal Vector3 position;
            internal BaseEntity source;
            internal BasePlayer player;
            internal AdminRadar instance;
            internal Network.Visibility.Group group;
            internal ItemContainer _backpackItemContainer;
            internal Coroutine _radarCo, _updateCo, _groupCo;
            internal List<ulong> exclude = Pool.Get<List<ulong>>();
            internal List<NetworkableId> removeByNetworkId = Pool.Get<List<NetworkableId>>();
            internal List<EntityType> entityTypes = Pool.Get<List<EntityType>>();
            internal List<DistantPlayer> distant = Pool.Get<List<DistantPlayer>>();
            internal List<EntityType> removeByEntityType = Pool.Get<List<EntityType>>();
            internal Dictionary<NetworkableId, DataObject> data = Pool.Get<Dictionary<NetworkableId, DataObject>>();
            internal Dictionary<EntityType, Action> filters = Pool.Get<Dictionary<EntityType, Action>>();
            internal Dictionary<ulong, ItemContainer> backpacks = Pool.Get<Dictionary<ulong, ItemContainer>>();
            internal Cache Cache => instance.cache;
            internal Configuration config => instance.config;
            internal float delay => invokeTime + 0.05f;
            internal float Distance(Vector3 a) {
                float sqrMagnitude = (a - position).sqrMagnitude;
                return Mathf.Ceil(Mathf.Sqrt(sqrMagnitude));
            }
            public Vector3 limitUp;
            public Vector3 halfUp = new(0f, 0.5f);
            public Vector3 twoHalfUp = new(0f, 2.5f);
            public Vector3 twoUp = new(0f, 2f);
            public Vector3 fiveUp = new(0f, 5f);
            private void Awake() {
                source = player = GetComponent<BasePlayer>();
                isAdmin = player.IsAdmin;
                userid = player.UserIDString;
                username = player.displayName;
                position = player.transform.position;
                exclude.Add(player.userID);
            }
            private void OnDestroy() {
                isEnabled = false;
                Interface.CallHook("OnRadarDeactivated", player, username, userid, position);
                if (config.Settings.Cooldown > 0f) {
                    instance._cooldowns[userid] = Time.realtimeSinceStartup + config.Settings.Cooldown;
                }
                if (config.Settings.ShowToggle) {
                    instance.Message(player, "Deactivated");
                }
                if (instance._radars.Remove(this) && instance._radars.Count == 0 && !instance.isUnloading) {
                    instance.Unsubscribe(nameof(OnPlayerRespawned));
                }
                instance._voices.Remove(userid);
                instance.DestroyUI(player);
                ResetToPool();
                StopAll();
            }
            private void ResetToPool() {
                for (int i = distant.Count - 1; i >= 0; i--) {
                    var obj = distant[i];
                    if (obj != null) {
                        Pool.Free(ref obj);
                    }
                    distant[i] = null;
                }
                for (int i = data.Count - 1; i >= 0; i--) {
                    var obj = data.ElementAt(i);
                    if (obj.Value != null) {
                        var value = obj.Value;
                        value.Reset();
                        Pool.Free(ref value);
                    }
                }
                data.ResetToPool();
                exclude.ResetToPool();
                distant.ResetToPool();
                filters.ResetToPool();
                backpacks.ResetToPool();
                entityTypes.ResetToPool();
                removeByNetworkId.ResetToPool();
                removeByEntityType.ResetToPool();
            }
            public bool Add(EntityType type) {
                if (type == EntityType.Loot && !entityTypes.Contains(EntityType.Backpack)) {
                    entityTypes.Add(EntityType.Backpack);
                }
                if (!entityTypes.Contains(type)) {
                    entityTypes.Add(type);
                    return true;
                }
                return false;
            }
            public void Init(AdminRadar instance) {
                this.instance = instance;
                this.limitUp = new(0f, config.Limit.Height);
                this.instance._radars.Add(this);
                canBypassOverride = CanBypassOverride(userid);
                hasPermAllowed = HasPermission(userid, "adminradar.allowed");
                Extended = instance.data.Extended.Contains(userid);
                InvokeRepeating(Activity, 0f, 1f);
                Interface.CallHook("OnRadarActivated", player, username, userid, position);
                if (instance._radars.Count == 1) {
                    instance.Subscribe(nameof(OnPlayerRespawned));
                }
            }
            public void StopAll() {
                if (_radarCo != null) {
                    StopCoroutine(_radarCo);
                    _radarCo = null;
                }
                if (_updateCo != null) {
                    StopCoroutine(_updateCo);
                    _updateCo = null;
                }
                if (_groupCo != null) {
                    StopCoroutine(_groupCo);
                    _groupCo = null;
                }
                try {
                    CancelInvoke(Activity);
                }
                catch {
                }
                try {
                    RemoveAdminFlag();
                }
                catch {
                }
            }
            public bool GetBool(EntityType type) {
                return entityTypes.Contains(type);
            }
            private void Activity() {
                inactiveSeconds = position == player.transform.position ? inactiveSeconds + 1 : 0;
                position = source.transform.position;
                if (source != player) {
                    inactiveSeconds = 0;
                    return;
                }
                if (config.Settings.DeactivateSeconds > 0 && ++activatedSeconds >= config.Settings.DeactivateSeconds) {
                    isEnabled = false;
                    Destroy(this);
                }
                if (config.Settings.InactiveSeconds > 0 && inactiveSeconds >= config.Settings.InactiveSeconds) {
                    isEnabled = false;
                    Destroy(this);
                }
            }
            private class Idle {
                public BasePlayer player;
                public Vector3 lastPosition;
                public float lastMovementTime;
            }
            private Dictionary<ulong, Idle> _idle = new();
            private double GetIdleTime(BasePlayer target) {
                Vector3 currPosition = target.transform.position;
                if (!_idle.TryGetValue(target.userID, out var idle)) {
                    _idle[target.userID] = idle = new();
                    idle.lastPosition = currPosition;
                    idle.lastMovementTime = Time.time;
                    idle.player = target;
                    return 0;
                }
                if (idle.lastPosition != currPosition) {
                    idle.lastPosition = currPosition;
                    idle.lastMovementTime = Time.time;
                    return 0;
                }
                double time = Math.Round((Time.time - idle.lastMovementTime) / 60.0, config.Settings.IdleRoundDigits);
                return time > 0 ? time : 0;
            }
            private void RemoveIdleTime() {
                if (_idle.Count > 0) {
                    foreach (var pair in _idle) {
                        if (pair.Value.player == null || !pair.Value.player.IsConnected) {
                            _idle.Remove(pair.Key);
                            break;
                        }
                    }
                }
            }
            private void SetupFilter(EntityType type, Action action) {
                if (entityTypes.Contains(type)) {
                    if (_radarCo != null) {
                        action();
                    }
                    filters[type] = action;
                }
                else if (filters.Remove(type)) {
                    RemoveByEntityType(type);
                }
            }
            public void SetupFilters(bool barebones) {
                if (_updateCo != null) {
                    StopCoroutine(_updateCo);
                }
                SetupFilter(EntityType.Active, ShowActive);
                SetupFilter(EntityType.Sleeper, ShowSleepers);
                if (!barebones) {
                    SetupFilters();
                }
                if (_radarCo == null) {
                    CheckNetworkGroupChange();
                    _radarCo = StartCoroutine(DoRadarRoutine());
                }
                if (_groupCo == null && config.Limit.Enabled) {
                    _groupCo = StartCoroutine(DoGroupLimitRoutine());
                }
                DoRemoves();
            }
            private void SetupFilters() {
                SetupFilter(EntityType.TC, ShowTC);
                SetupFilter(EntityType.Bag, ShowBags);
                SetupFilter(EntityType.Box, ShowBox);
                SetupFilter(EntityType.Ore, ShowOre);
                SetupFilter(EntityType.Npc, ShowNPC);
                SetupFilter(EntityType.CCTV, ShowCCTV);
                SetupFilter(EntityType.Dead, ShowDead);
                SetupFilter(EntityType.Drop, ShowDrops);
                SetupFilter(EntityType.Heli, ShowHeli);
                SetupFilter(EntityType.Loot, ShowLoot);
                SetupFilter(EntityType.Stash, ShowStash);
                SetupFilter(EntityType.Turret, ShowTurrets);
                SetupFilter(EntityType.Bradley, ShowBradley);
                SetupFilter(EntityType.Col, ShowCollectibles);
                SetupFilter(EntityType.Airdrop, ShowAirdrops);
                SetupFilter(EntityType.Car, () => ShowEntity(EntityType.Car, Cache.Cars));
                SetupFilter(EntityType.CH47, () => ShowEntity(EntityType.CH47, Cache.CH47));
                SetupFilter(EntityType.MLRS, () => ShowEntity(EntityType.MLRS, Cache.MLRS));
                SetupFilter(EntityType.RHIB, () => ShowEntity(EntityType.RHIB, Cache.RHIB));
                SetupFilter(EntityType.Boat, () => ShowEntity(EntityType.Boat, Cache.Boats));
                SetupFilter(EntityType.Trap, () => ShowEntity(EntityType.Trap, Cache.Traps));
                SetupFilter(EntityType.Mini, () => ShowEntity(EntityType.Mini, Cache.MiniCopter));
                SetupFilter(EntityType.Horse, () => ShowEntity(EntityType.Horse, Cache.RidableHorse));
                SetupFilter(EntityType.CargoShip, () => ShowEntity(EntityType.CargoShip, Cache.CargoShips));
                SetupFilter(EntityType.CargoPlane, () => ShowEntity(EntityType.CargoPlane, Cache.CargoPlanes));
            }
            private IEnumerator DoGroupLimitRoutine() {
                while (isEnabled) {
                    ShowGroupLimits();
                    yield return CoroutineEx.waitForSeconds(invokeTime);
                }
            }
            private IEnumerator DoUpdateRoutine() {
                SetEnabledDataObjects();
                foreach (var filter in filters) {
                    filter.Value();
                    if (checks >= 100) {
                        checks = 0;
                        yield return CoroutineEx.waitForFixedUpdate;
                    }
                }
            }
            private IEnumerator DoRadarRoutine() {
                while (isEnabled) {
                    if (player == null || !player.IsConnected || instance.isUnloading) {
                        isEnabled = false;
                        Destroy(this);
                        yield break;
                    }
                    if (!SetSource()) {
                        yield return CoroutineEx.waitForSeconds(0.1f);
                        continue;
                    }
                    DoRemoves();
                    SetAdminFlag();
                    DirectDrawAll();
                    RemoveAdminFlag();
                    CheckNetworkGroupChange();
                    checks = 0;
                    yield return CoroutineEx.waitForSeconds(invokeTime);
                }
            }
            private void DoRemoves() {
                if (data.Count != 0) {
                    foreach (var pair in data) {
                        if (pair.Value.ei == null || !pair.Value.ei.entity.IsValid()) {
                            removeByNetworkId.Add(pair.Key);
                            pair.Value.disabled = true;
                        }
                    }
                }
                if (removeByEntityType.Count != 0) {
                    foreach (var type in removeByEntityType) {
                        RemoveByEntityType(type);
                        entityTypes.Remove(type);
                        filters.Remove(type);
                    }
                    removeByEntityType.Clear();
                }
                if (removeByNetworkId.Count != 0) {
                    foreach (var nid in removeByNetworkId) {
                        RemoveByNetworkId(nid);
                    }
                    removeByNetworkId.Clear();
                }
            }
            private void CheckNetworkGroupChange() {
                if (group == player.net.group) {
                    return;
                }
                group = player.net.group;
                if (_updateCo != null) {
                    StopCoroutine(_updateCo);
                }
                if (filters.ContainsKey(EntityType.Npc)) {
                    RemoveByEntityType(EntityType.Npc);
                    DoRemoves();
                }
                _updateCo = StartCoroutine(DoUpdateRoutine());
            }
            public void SetEnabledDataObjects() {
                foreach (var pair in data) {
                    pair.Value.SetEnabled(group, position, maxDistance);
                }
            }
            public void RemoveByEntityType(EntityType type) {
                foreach (var pair in data) {
                    if (pair.Value.IsOfType(type)) {
                        removeByNetworkId.Add(pair.Key);
                        pair.Value.disabled = true;
                    }
                }
            }
            public void RemoveByNetworkId(NetworkableId nid) {
                if (data.Remove(nid, out var obj)) {
                    if (obj != null) {
                        Pool.Free(ref obj);
                    }
                }
            }
            public void TryCacheByType(EntityType type, EntityInfo ei) {
                try {
                    if (!entityTypes.Contains(type) || !ei.entity.IsValid()) {
                        return;
                    }
                    switch (type) {
                        case EntityType.Airdrop : {
                            CacheAirdrop(ei);
                            break;
                        }
                        case EntityType.Backpack : {
                            CacheBackpack(ei);
                            break;
                        }
                        case EntityType.Bag : {
                            CacheSleepingBag(ei);
                            break;
                        }
                        case EntityType.Box : {
                            CacheContainer(ei);
                            break;
                        }
                        case EntityType.Bradley : {
                            CacheBradley(ei);
                            break;
                        }
                        case EntityType.CCTV : {
                            CacheCCTV(ei);
                            break;
                        }
                        case EntityType.Col : {
                            CacheCol(ei);
                            break;
                        }
                        case EntityType.Dead : {
                            CacheDead(ei);
                            break;
                        }
                        case EntityType.Heli : {
                            CacheHeli(ei);
                            break;
                        }
                        case EntityType.Loot : {
                            CacheLoot(ei);
                            break;
                        }
                        case EntityType.Npc : {
                            CacheNpc(ei);
                            break;
                        }
                        case EntityType.Ore : {
                            CacheOre(ei);
                            break;
                        }
                        case EntityType.Stash : {
                            CacheStash(ei);
                            break;
                        }
                        case EntityType.TC : {
                            CacheTC(ei);
                            break;
                        }
                        case EntityType.Turret : {
                            CacheTurret(ei);
                            break;
                        }
                        default : {
                            CacheEntity(ei, type);
                            break;
                        }
                    }
                }
                catch (Exception ex) {
                    currType = type;
                    HandleException(ex);
                }
            }
            private DataObject cobj;
            private DrawFlags cflag;
            private void DirectDrawAll() {
                float delay = this.delay;
                foreach (var pair in data) {
                    cobj = pair.Value;
                    if (cobj == null || cobj.ei == null || cobj.disabled) {
                        continue;
                    }
                    if (cobj.ei.type == EntityType.Ore && OreWhitelist.Count > 0 && !IsOreWhitelisted(cobj.ei)) {
                        continue;
                    }
                    cflag = DrawFlags.Arrow;
                    if (cobj.HasFlag(DrawFlags.Arrow)) {
                        player.SendConsoleCommand("ddraw.arrow", delay, cobj.ei.color, cobj.ei.from, cobj.ei.to, cobj.ei.size);
                    }
                    cflag = DrawFlags.Box;
                    if (cobj.HasFlag(DrawFlags.Box)) {
                        player.SendConsoleCommand("ddraw.box", delay, cobj.ei.color, cobj.ei.from, cobj.ei.size);
                    }
                    cflag = DrawFlags.Text;
                    if (cobj.HasFlag(DrawFlags.Text)) {
                        try {
                            cobj.action();
                        }
                        catch (Exception ex) {
                            HandleException(pair.Key, ex);
                            continue;
                        }
                        if (cobj.ei.info == null) {
                            continue;
                        }
                        player.SendConsoleCommand("ddraw.text", delay, cobj.ei.color, cobj.ei.from, cobj.ei.info);
                    }
                }
            }
            private void DrawVisionArrow(BasePlayer target, float dist) {
                if (dist <= 150f && instance.data.Visions.Contains(userid) && Physics.Raycast(target.eyes.HeadRay(), out hit, Mathf.Infinity)) {
                    DrawArrow(Color.red, target.eyes.position + new Vector3(0f, 0.115f, 0f), hit.point, 0.15f, true);
                }
            }
            private void DrawArrow(Color color, Vector3 from, Vector3 to, float size, bool @override = false) {
                if (config.Methods.A
// ... [Code preview truncated due to length. Full source in attached file] ...

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