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

FREE AntiESP : 4.5.4 4.5.4

Нет прав для скачивания
C#:
        #region Header
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using UnityEngine;
using Network;
using Facepunch;
using Oxide.Core.Plugins;
using System;

namespace Oxide.Plugins {
    [Info("AntiESP", "https://topplugin.ru / https://discord.com/invite/5DPTsRmd3G", "4.5.4")]
    [Description("Предотвращает использование ESP скрывая объекты за стенами")]
    class AntiESP : RustPlugin {
        #endregion

        #region Fields
        [PluginReference]
        private Plugin Clans, Stealth;
        private static bool isStashesHideEnabled = true;
        private static AntiESP _instance;
        private static bool _loaded = false;
        private static float _collectRate = 2f;
        private static float _updateRate = 0.03f;
        private Dictionary<ulong, HashSet<ulong>> _playersClanMates = new Dictionary<ulong, HashSet<ulong>>();
        private HashSet<BaseNetworkable> _shelves = new HashSet<BaseNetworkable>();
        private static Dictionary<ulong, Handler> _handlers = new Dictionary<ulong, Handler>();
        private static int _layerConstruction = UnityEngine.LayerMask.GetMask("Construction");
        private static int _interestedLayers = LayerMask.GetMask("Deployed", "Player (Server)");
        private static HashSet<string> _whiteListEntities = new HashSet<string>() {
            "campfire",
            "box.wooden.large",
            "woodbox_deployed",
            "lantern.deployed",
            "cupboard.tool.deployed",
            "sleepingbag_leather_deployed",
            "bed_deployed",
            "shelves",
            "lock.code",
            "lock.key",
            "repairbench_deployed",
            "locker.deployed",
            "fridge.deployed",
            "ceilinglight.deployed",
            "tunalight.deployed",
        };
        #endregion

        [ConsoleCommand("antiesp.collectrate")]
        private void AntiESPCollectRateConsoleCommand(ConsoleSystem.Arg arg) {
            if (!arg.IsAdmin) return;
            float newValue;
            if (arg.Args == null || arg.Args.Length == 0) {
                SendReply(arg, $"Использование: antiesp.collectrate 'значение в пределах 2-5'");
                return;
            }
            if (!float.TryParse(arg.Args[0], out newValue)) {
                SendReply(arg, $"Использование: antiesp.collectrate 'значение в пределах 2-5'");
                return;
            }
            if (newValue < 2 || newValue > 5) {
                SendReply(arg, $"Значение должно быть > 2 и < 5");
                return;
            }
            var old = _collectRate;
            _collectRate = newValue;
            SendReply(arg, $"Старое значение CollectRate: {old}, новое значение: {_collectRate}");
        }

        [ConsoleCommand("antiesp.updaterate")]
        private void AntiESPUpdateRateConsoleCommand(ConsoleSystem.Arg arg) {
            if (!arg.IsAdmin) return;
            float newValue;
            if (arg.Args == null || arg.Args.Length == 0) {
                SendReply(arg, $"Использование: antiesp.updaterate 'значение в пределах 0.01-0.5'");
                return;
            }
            if (!float.TryParse(arg.Args[0], out newValue)) {
                SendReply(arg, $"Использование: antiesp.updaterate 'значение в пределах 0.01-0.5'");
                return;
            }
            if (newValue < 0.01f || newValue > 0.5f) {
                SendReply(arg, $"Значение должно быть > 0.01 и < 0.5");
                return;
            }
            var old = _updateRate;
            _updateRate = newValue;
            SendReply(arg, $"Старое значение UpdateRate: {old}, новое значение: {_updateRate}");
        }

        #region Behaviours

        private class StashHandler : MonoBehaviour {
            public StashContainer Stash;
            public float nextTimeSee;
            public Dictionary<ulong, float> timeClose = new Dictionary<ulong, float>();

            private void Awake() {
                Stash = GetComponent<StashContainer>();
                if (Stash.IsHidden())
                    Hide();
            }

            public void Hide() {
                if (Stash.limitNetworking) return;
                nextTimeSee = Time.realtimeSinceStartup + 3;
                Stash.DisableNetworking();
            }

            private void Update() {
                foreach (var player in BasePlayer.activePlayerList) {
                    if (Stash.limitNetworking) {
                        if (Stash.PlayerInRange(player)) {
                            if (nextTimeSee - Time.realtimeSinceStartup < 0) {
                                float time;
                                if (!timeClose.TryGetValue(player.userID, out time)) {
                                    timeClose[player.userID] = 0;
                                } else {
                                    timeClose[player.userID] += Time.deltaTime;
                                }
                                if (time > 1) {
                                    Show();
                                    timeClose.Remove(player.userID);
                                }
                            }
                        } else {
                            if (timeClose.ContainsKey(player.userID)) {
                                timeClose[player.userID] -= Time.deltaTime;
                                if (timeClose[player.userID] < 0) {
                                    timeClose.Remove(player.userID);
                                }
                            }
                        }
                    }
                }
            }

            private void Show() {
                Stash.SetFlag(BaseEntity.Flags.Disabled, false, false, true);
                Stash.limitNetworking = false;
                Stash.SetHidden(false);
            }

            public void Destroy() {
                Stash.SetFlag(BaseEntity.Flags.Disabled, false, false, true);
                Stash.limitNetworking = false;
                UnityEngine.GameObject.Destroy(this);
            }
        }

        class Handler : MonoBehaviour {
            public BasePlayer player;
            private List<BaseNetworkable> deleteShelves = new List<BaseNetworkable>();
            private Dictionary<uint, float> lastEntityWrite = new Dictionary<uint, float>();
            private HashSet<BaseEntity> entityList = new HashSet<BaseEntity>();
            private Vector3 playerPreviousPosition;
            private float lastTick = Time.realtimeSinceStartup;
            private float lastEntityCollect = Time.realtimeSinceStartup;
            private float lastSleepersCollect = Time.realtimeSinceStartup;
            private float lastClanMatesCollect;
            private float uniqUpdateRateModifier = UnityEngine.Random.Range(-(_collectRate / 20), _collectRate / 20);
            private int currentEntityPosition = 0;
            private bool isCollectingEntities = false;
            private bool isCollectingSleepers = false;

            private void Awake() {
                player = GetComponent<BasePlayer>();
                _handlers[player.userID] = this;
                GetClanMates();
            }

            private void LateUpdate() {
                if (player.IsSleeping()) return;
                if (player.transform.position == playerPreviousPosition || (player.transform.position - playerPreviousPosition).sqrMagnitude < 0.00001f)
                if (Time.realtimeSinceStartup - lastTick < _updateRate) return;
                lastTick = Time.realtimeSinceStartup;
                if (Time.realtimeSinceStartup - lastEntityCollect > UpdateRate) {
                    entityList.Clear();
                    GetEntities();
                    lastEntityCollect = Time.realtimeSinceStartup;
                }
                if (Time.realtimeSinceStartup - lastSleepersCollect > UpdateRate + 10) {
                    if (!isCollectingSleepers) {
                        StartCoroutine(CheckSleepers());
                        lastSleepersCollect = Time.realtimeSinceStartup;
                    }
                }
                if (entityList.Count == 0) return;
                if (entityList.Count - 1 < currentEntityPosition) {
                    currentEntityPosition = 0;
                    return;
                }
                var target = entityList.ElementAtOrDefault(currentEntityPosition);
                if (target == null || target.IsDestroyed) {
                    entityList.Remove(target);
                    goto NEXT;
                }
                if (NeedCheck(target.net.ID)) {
                    GetClanMates();
                    if (target.OwnerID == player.userID || IsClanMates(target.OwnerID) || player.IsAdmin)
                        Show(target);
                    else {
                        if (target is BasePlayer) {
                            if (TryLineCast(player.eyes.position, target.transform.position))
                                Show(target);
                        } else if (IsObjectVisible(target.WorldSpaceBounds().ToBounds().center))
                            Show(target);
                    }
                }
                playerPreviousPosition = player.transform.position;
                NEXT:
                if (entityList.Count >= currentEntityPosition + 1)
                    currentEntityPosition++;
                else
                    currentEntityPosition = 0;
            }

            private IEnumerator CheckSleepers() {
                isCollectingSleepers = true;
                for (int i = BasePlayer.sleepingPlayerList.Count - 1; i >= 0; i--) {
                    if (i > BasePlayer.sleepingPlayerList.Count - 1) break;
                    var sleeper = BasePlayer.sleepingPlayerList[i];
                    if (sleeper == null || sleeper.IsDestroyed) continue;
                    if (Vector3.Distance(sleeper.transform.position, player.transform.position) < 100)
                        if (!IsPlayerInvisible(sleeper.userID) && TryLineCast(player.eyes.position, sleeper.transform.position))
                            Show(sleeper);
                    if (i % 1 == 0)
                        yield return null;
                }
                isCollectingSleepers = false;
            }
            
            private void GetShelves() {
                foreach (var shelve in _instance._shelves) {
                    if (shelve == null || shelve.IsDestroyed) {
                        deleteShelves.Add(shelve);
                        continue;
                    }
                    if ((player.transform.position - shelve.transform.position).sqrMagnitude <= 50)
                        entityList.Add(shelve as BaseEntity);
                }
                _instance._shelves.ExceptWith(deleteShelves);
                deleteShelves.Clear();
            }

            private void GetEntities() {
                GetShelves();
                List<Collider> list2 = Pool.GetList<Collider>();
                Vis.Colliders(player.transform.position, 50, list2, _interestedLayers, QueryTriggerInteraction.Ignore);
                for (int i = 0; i < list2.Count; i++) {
                    var e = list2[i].gameObject.ToBaseEntity();
                    if ((e != null && !e.IsDestroyed) && IsInterestedEntity(e))
                        entityList.Add(e);
                }
                Pool.FreeList(ref list2);
            }

            private void GetClanMates() {
                if (Time.realtimeSinceStartup - lastClanMatesCollect > UpdateRate + 180) {
                    lastClanMatesCollect = Time.realtimeSinceStartup;
                    var list = new List<ulong>();
                    var teamMates = GetTeamMates();
                    var clanMembers = GetClanMembers();
                    if (teamMates != null)
                        list.AddRange(teamMates);
                    if (clanMembers != null)
                        list.AddRange(clanMembers);
                    if (list.Count > 0) {
                        if (!_instance._playersClanMates.ContainsKey(player.userID))
                            _instance._playersClanMates[player.userID] = new HashSet<ulong>();
                        _instance._playersClanMates[player.userID].Clear();
                        _instance._playersClanMates[player.userID].UnionWith(list);
                    } else
                        _instance._playersClanMates.Remove(player.userID);
                }
            }

            private List<ulong> GetClanMembers() {
                var clanMates = (List<ulong>)_instance.Clans?.Call("GetClanMembersByPlayer", player.userID);
                if (clanMates != null)
                    return clanMates;
                return null;
            }

            private List<ulong> GetTeamMates() {
                if (player.currentTeam != 0) {
                    var team = RelationshipManager.ServerInstance.FindTeam(player.currentTeam);
                    if (team != null)
                        return team.members;
                }
                return null;
            }

            private bool IsClanMates(ulong targetID) {
                HashSet<ulong> list;
                if (_instance._playersClanMates.TryGetValue(player.userID, out list)) {
                    return list.Contains(targetID);
                }
                return false;
            }

            private bool NeedCheck(uint entityID) {
                float value;
                if (lastEntityWrite.TryGetValue(entityID, out value))
                    if (Time.realtimeSinceStartup - value < 20) return false;
                return true;
            }

            private bool TryLineCast(Vector3 start, Vector3 target, float plusPlayer = 0) {
                start.y += plusPlayer;
                return !Physics.Linecast(start, target, _layerConstruction);
            }

            private bool IsObjectVisible(Vector3 target) {
                if (TryLineCast(player.eyes.position, target)) return true;
                if (Vector3.Distance(player.transform.position, target) > 25) return false;
                if (TryLineCast(player.transform.position, target, 0.5f)) return true;
                if (TryLineCast(player.transform.position, target, 0.25f)) return true;
                if (TryLineCast(player.transform.position, target, 1f)) return true;
                return false;
            }

            public void Show(BaseEntity entity) {
                if (!_loaded) return;
                _instance.Write(player, entity);
                entityList.Remove(entity);
                lastEntityWrite[entity.net.ID] = Time.realtimeSinceStartup;
                foreach (var e in entity.children)
                    _instance.Write(player, e);
            }

            private float UpdateRate => uniqUpdateRateModifier + _collectRate;

            public void Destroy(bool remove = true) {
                if (remove)
                    _handlers.Remove(player.userID);
                GameObject.Destroy(this);
            }
        }
        #endregion

        #region Helpers

        private static bool IsPlayerInvisible(ulong userID) {
            var isPlayerInvisible = _instance.Stealth?.Call("IsPlayerInvisible", userID);
            if (isPlayerInvisible == null) return false;
            return (bool)isPlayerInvisible;
        }

        private void OnClanRemoveMember(string clanName, ulong userID) {
            _playersClanMates.Remove(userID);
            CommunityEntity.ServerInstance.StartCoroutine(RemoveFromClanMatesCoroutine(userID));
        }

        private IEnumerator RemoveFromClanMatesCoroutine(ulong userID) {
            foreach (var list in _playersClanMates.Values.ToList()) {
                for (int i = list.Count - 1; i >= 0; i--) {
                    if (list.ElementAt(i) == userID)
                        list.Remove(userID);
                    yield return null;
                }
            }
        }

        private void WriteForAll(BasePlayer player, BaseNetworkable entity, bool shoudInvalidate = false) {
            if (shoudInvalidate && (player == null || player.net.connection == null || entity == null || entity.IsDestroyed)) return;
            Write(player, entity, !shoudInvalidate);
            WriteForMates(player, entity, !shoudInvalidate);
        }

        private void WriteForMates(BasePlayer player, BaseNetworkable entity, bool shoudInvalidate = false) {
            HashSet<ulong> list;
            if (_playersClanMates.TryGetValue(player.userID, out list)) {
                foreach (var mate in list) {
                    var playerMate = BasePlayer.FindByID(mate);
                    if (playerMate != null && playerMate.IsConnected && Vector3.Distance(entity.transform.position, playerMate.transform.position) < 100)
                        Write(playerMate, entity, shoudInvalidate);
                }
            }
        }

        private void Write(BasePlayer player, BaseNetworkable entity, bool shoudInvalidate = false) {
            if (shoudInvalidate && (player == null || player.net.connection == null || entity == null || entity.IsDestroyed)) return;
            if (Net.sv.write.Start()) {
                Connection conn = player.net.connection;
                conn.validate.entityUpdates = conn.validate.entityUpdates + 1u;
                BaseNetworkable.SaveInfo saveInfo = new BaseNetworkable.SaveInfo {
                    forConnection = player.net.connection,
                    forDisk = false
                };
                Net.sv.write.PacketID(Message.Type.Entities);
                Net.sv.write.UInt32(player.net.connection.validate.entityUpdates);
                entity.ToStreamForNetwork(Net.sv.write, saveInfo);
                Net.sv.write.Send(new SendInfo(player.net.connection));
            }
        }

        private static bool IsInterestedEntity(BaseNetworkable entity) {
            if (entity is BaseLock) {
                var parent = (entity as BaseEntity).GetParentEntity();
                if (parent != null && !(parent is StorageContainer)) return false;
            }
            if ( _whiteListEntities.Contains(entity.ShortPrefabName)) return true;
            var bp = entity as BasePlayer;
            if (bp != null && !bp.IsConnected && !IsPlayerInvisible(bp.userID)) return true;
            return false;
        }

        private IEnumerator HideAllEntities(bool hide) {
            string operation = hide ? "скрытие" : "показ";
            PrintWarning($"Начинаем {operation} объектов...");
            int i = 0;
            int all = 0;
            foreach (var entity in BaseNetworkable.serverEntities.ToList()) {
                if (entity == null || entity.IsDestroyed) continue;

                var npc = entity as BasePlayer;
                if (npc != null && !npc.userID.IsSteamId()) {
                    continue;
                }

                if (isStashesHideEnabled && hide) {
                    if (entity is StashContainer) {
                        GetStashHandler(entity as BaseEntity);
                        continue;
                    }
                }
                if (hide == true && entity is Door)
                    foreach (var e in entity.children)
                        e.limitNetworking = false;
                if (IsInterestedEntity(entity)) {
                    i++;
                    if (i % 1000 == 0)
                        PrintWarning($"Обработано {i} объектов...");
                    entity.limitNetworking = hide;
                    var group = Net.sv.visibility.GetGroup(entity.transform.position);
                    entity.net.SwitchGroup(group);
                    if (hide && entity.ShortPrefabName == "shelves")
                        _shelves.Add(entity);
                }
                all++;
                if (all % 500 == 0)
                yield return null;
            }
            PrintWarning($"Обработка {i} объектов завершена.");
            if (hide)
                _loaded = true;
        }

        private StashHandler GetStashHandler(BaseEntity entity) {
            var handler = entity.GetComponent<StashHandler>() ?? entity.gameObject.AddComponent<StashHandler>();
            return handler;
        }

        #endregion

        #region Oxide

        private void Loaded() {
            _instance = this;
            if (!isStashesHideEnabled) {
                Unsubscribe("CanHideStash");
            }
        }

        private void CanHideStash(BasePlayer player, StashContainer stash) {
            timer.Once(1, () => {
                if (stash != null && !stash.IsDestroyed)
                    GetStashHandler(stash).Hide();
            });
        }

        private void OnServerInitialized() {
            CommunityEntity.ServerInstance.StartCoroutine(HideAllEntities(true));
            foreach (var player in BasePlayer.activePlayerList)
                OnPlayerConnected(player);
        }

        private void OnEntitySpawned(BaseNetworkable entity) {
            if (!IsInterestedEntity(entity)) return;
            var npc = entity as BasePlayer;
            if (npc != null && !npc.userID.IsSteamId()) {
                return;
            }
            entity.limitNetworking = true;
            var group = Net.sv.visibility.GetGroup(entity.transform.position);
            entity.net.SwitchGroup(group);
            var baseEntity = entity as BaseEntity;
            if (baseEntity.OwnerID == 0) return;
            if (entity.ShortPrefabName == "shelves")
                _shelves.Add(entity);
            var player = BasePlayer.FindByID(baseEntity.OwnerID);
            player.GetComponent<Handler>()?.Show(baseEntity);
            WriteForMates(player, baseEntity, true);
        }

        private void OnEntityTakeDamage(BaseNetworkable entity, HitInfo info) {
            if (entity == null || entity.IsDestroyed) return;
            var player = info.InitiatorPlayer;
            if (player == null) return;
            if (!IsInterestedEntity(entity)) return;
            NextTick(() => WriteForAll(player, entity, true));
        }

        private void OnPlayerConnected(BasePlayer player) {
            if (!IsPlayerInvisible(player.userID))
                player.limitNetworking = false;
            if (player.GetComponent<Handler>() != null)
                GameObject.Destroy(player.GetComponent<Handler>());
            player.gameObject.AddComponent<Handler>();
        }

        private void OnPlayerDisconnected(BasePlayer player) {
            player.GetComponent<Handler>().Destroy();
            player.limitNetworking = true;
        }

        private void Unload() {
            foreach (var player in BasePlayer.activePlayerList)
                player.GetComponent<Handler>()?.Destroy(false);
            CommunityEntity.ServerInstance.StartCoroutine(HideAllEntities(false));
            if (isStashesHideEnabled) {
                var stashes = GameObject.FindObjectsOfType<StashContainer>();
                foreach (var s in stashes) {
                    s.GetComponent<StashHandler>()?.Destroy();
                }
            }
        }

        private void OnCupboardAuthorize(BuildingPrivlidge privilege, BasePlayer player) => NextTick(() => WriteForAll(player, privilege, true));

        private void OnCupboardDeauthorize(BuildingPrivlidge privilege, BasePlayer player) => NextTick(() => WriteForAll(player, privilege, true));

        private void OnCupboardClearList(BuildingPrivlidge privilege, BasePlayer player) => NextTick(() => WriteForAll(player, privilege, true));

        private void OnCodeEntered(CodeLock codeLock, BasePlayer player, string code) => NextTick(() => WriteForAll(player, codeLock, true));

        private void OnOvenToggle(BaseOven oven, BasePlayer player) => NextTick(() => WriteForAll(player, oven, true));

        private void CanLock(BasePlayer player, BaseLock baseLock) => NextTick(() => WriteForAll(player, baseLock, true));

        private void CanUnlock(BasePlayer player, BaseLock baseLock) => NextTick(() => WriteForAll(player, baseLock, true));

        private void CanChangeCode(BasePlayer player, CodeLock codeLock, string newCode, bool isGuestCode) => NextTick(() => WriteForAll(player, codeLock, true));
        
        #endregion

        #region Footer
    }
}
#endregion

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