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

FREE AntiCheat : 1.2.7 1.2.7

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using ox = Oxide.Core;
using Oxide.Core.Plugins;
using System.Linq;
using UnityEngine;
using System.Data;
using Oxide.Core;
using Rust;
using ru = Oxide.Game.Rust;
using Oxide.Plugins;
using Oxide.Core.Configuration;
using System.Globalization;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
namespace Oxide.Plugins {
    [Info("AntiCheat", "RustPlugin.ru", "1.2.7")]
    class AntiCheat : RustPlugin {
        public static ox.Libraries.Permission perm => ox.Interface.Oxide.GetLibrary<ox.Libraries.Permission>("Permission");
        private static HashSet<PlayerData> LoadedPlayerData = new HashSet<PlayerData>();
        [PluginReference]
        Plugin Duel;
        [PluginReference]
        Plugin CarCommander;
        static List<BasePlayer> adminList = new List<BasePlayer>();
#region Data
        class PlayerData {
            public string SteamID;
        }
#endregion
        //////// Конфиг-начало
        protected override void LoadDefaultConfig() {
            Config.Clear();
            Config["Количество детектов для автоматического бана за макрос:"] = 10;
            Config["Включить проверку на Speedhack?"] = true;
            Config["Включить проверку Flyhack?"] = true;
            Config["Процент попадания в голову для автоматического бана за AIM"] = 35f;
            Config["Количество попаданий для автоматического бана за AIM, если процент попадания больше зазначеного в конфиге:"] = 40;
            Config["[Топ-Игроков] Цвет Панели"] = "0.0 0.0 0.0 0.8";
            Config["[Топ-Игроков] Включить?"] = true;
            Config["[Топ-Игроков] Время Между Сообщениями"] = 300f;
            Config["[Топ-Игроков] Цвет Оповещаний"] = "#FF6347";
            SaveConfig();
        }
        ///Топ-Игроков
        [HookMethod("OnServerSave")]
        private void OnServerSave() {
            Saved();
        }
        [HookMethod("Saved")]
        private void Saved() {
            Interface.Oxide.DataFileSystem.WriteObject("TopData", Tops);
        }
        private bool IsNPC(BasePlayer player) {
            if (player == null) return false;
            //BotSpawn
            if (player is NPCPlayer) return true;
            //HumanNPC
            if (!(player.userID >= 76560000000000000L || player.userID <= 0L)) return true;
            return false;
        }
        [ChatCommand("rank")]
        void TurboRankCommand(BasePlayer player, string command) {
            var TopPlayer = (from x in Tops where x.UID == player.UserIDString select x).OrderByDescending(x => x.РакетВыпущено + x.ВзрывчатокИспользовано);
            player.ChatMessage($"<size=15>Статистика игрока <color=#ffa500>{player.displayName}</color></size>");
            foreach (var top in TopPlayer) {
                rust.SendChatMessage(player, $"<size=14><color=#ffffff>Убийств игроков: <color=#ffa500>{top.УбийствPVP}</color> | Смертей: <color=#ffa500>{top.Смертей}</color></color></size>", null, "0");
                rust.SendChatMessage(player, $"<size=14><color=#ffffff>Ракет выпущено: <color=#ffa500>{top.РакетВыпущено}</color> | Взрывчаток использовано: <color=#ffa500>{top.ВзрывчатокИспользовано}</color></color></size>", null, "0");
                rust.SendChatMessage(player, $"<size=14><color=#ffffff>Ресурсов собрано: <color=#ffa500>{top.РесурсовСобрано}</color> | Животных убито: <color=#ffa500>{top.УбийствЖивотных}</color></color></size>", null, "0");
                rust.SendChatMessage(player, $"<size=14><color=#ffffff>Пуль выпущено: <color=#ffa500>{top.ПульВыпущено}</color> | Стрел выпущено: <color=#ffa500>{top.СтрелВыпущено}</color></color></size>", null, "0");
                rust.SendChatMessage(player, $"<size=14><color=#ffffff>Предметов скрафчено: <color=#ffa500>{top.ПредметовСкрафчено}</color> | Вертолетов сбито: <color=#ffa500>{top.ВертолётовУничтожено}</color></color></size>", null, "0");
                rust.SendChatMessage(player, $"<size=14><color=#ffffff>NPC убито: <color=#ffa500>{top.NPCУбито}</color> | Танков уничтожено: <color=#ffa500>{top.ТанковУничтожено}</color></color></size>", null, "0");
            }
            return;
        }
        [ChatCommand("top")]
        void TurboTopCommand(BasePlayer player, string command, string[] args) {
            if (args.Length == 1) {
                int n = 0;
                // Очистка статистики игроков
                if (args[0] == "reset") {
                    if (!player.IsAdmin) {
                        rust.SendChatMessage(player, $"<size=14><color=#FFA500>Ты кто такой? Давай досвиданье!</color></size>", null, "0");
                        return;
                    }
                    var TopPlayer = (from x in Tops select x);
                    foreach (var top in TopPlayer) {
                        top.РакетВыпущено = 0;
                        top.УбийствPVP = 0;
                        top.ВзрывчатокИспользовано = 0;
                        top.УбийствЖивотных = 0;
                        top.ПульВыпущено = 0;
                        top.СтрелВыпущено = 0;
                        top.Смертей = 0;
                        top.РесурсовСобрано = 0;
                        top.ВертолётовУничтожено = 0;
                        top.NPCУбито = 0;
                        Saved();
                    }
                    rust.SendChatMessage(player, $"<size=14><color=#FFA500>Статистика игроков обнулена!</color></size>", null, "0");
                    return;
                }
                if (args[0] == "farm") {
                    bool prov = false;
                    player.ChatMessage("<size=14><color=#FF6347>[СТАТИСТИКА]</color> ТОП Фармеров</size>");
                    var TopPlayer = (from x in Tops select x).OrderByDescending(x => x.РесурсовСобрано);
                    foreach (var top in TopPlayer) {
                        n++;
                        if (n <= 5) {
                            rust.SendChatMessage(player, $"<size=14><color=#FFA500>{n}.</color> <color=#FF8C00>{top.Ник}</color> ({top.РесурсовСобрано})</size>", null, top.UID);
                            if (top.UID == player.UserIDString) {
                                prov = true;
                            }
                        }
                    }
                    if (!prov) {
                        player.ChatMessage("...");
                        int i = 0;
                        foreach (var top in TopPlayer) {
                            i++;
                            if (top.UID == player.UserIDString) {
                                rust.SendChatMessage(player, $"<size=14><color=#FFA500>{i}.</color> <color=#FF8C00>{top.Ник}</color> ({top.РесурсовСобрано})</size>", null, player.UserIDString);
                            }
                        }
                    }
                    return;
                }
                if (args[0] == "pvp") {
                    bool prov = false;
                    player.ChatMessage("<size=14><color=#FF6347>[СТАТИСТИКА]</color> ТОП Убийств PVP</size>");
                    var TopPlayer = (from x in Tops select x).OrderByDescending(x => x.УбийствPVP);
                    foreach (var top in TopPlayer) {
                        n++;
                        if (n <= 5) {
                            rust.SendChatMessage(player, $"<size=14><color=#FFA500>{n}.</color> <color=#FF8C00>{top.Ник}</color> ({top.УбийствPVP})</size>", null, top.UID);
                            if (top.UID == player.UserIDString) {
                                prov = true;
                            }
                        }
                    }
                    if (!prov) {
                        player.ChatMessage("<size=14>...</size>");
                        int i = 0;
                        foreach (var top in TopPlayer) {
                            i++;
                            if (top.UID == player.UserIDString) {
                                rust.SendChatMessage(player, $"<size=14><color=#FFA500>{i}.</color> <color=#FF8C00>{top.Ник}</color> ({top.УбийствPVP})</size>", null, player.UserIDString);
                            }
                        }
                    }
                    return;
                }
                if (args[0] == "raid") {
                    bool prov = false;
                    player.ChatMessage("<size=14><color=#FF6347>[СТАТИСТИКА]</color> ТОП Рейдеров</size>");
                    var TopPlayer = (from x in Tops select x).OrderByDescending(x => x.РакетВыпущено + x.ВзрывчатокИспользовано);
                    foreach (var top in TopPlayer) {
                        n++;
                        if (n <= 5) {
                            rust.SendChatMessage(player, $"<size=14><color=#FFA500>{n}.</color> <color=#FF8C00>{top.Ник}</color> ({top.РакетВыпущено + top.ВзрывчатокИспользовано})</size>", null, top.UID);
                            if (top.UID == player.UserIDString) {
                                prov = true;
                            }
                        }
                    }
                    if (!prov) {
                        player.ChatMessage("<size=14>...</size>");
                        int i = 0;
                        foreach (var top in TopPlayer) {
                            i++;
                            if (top.UID == player.UserIDString) {
                                rust.SendChatMessage(player, $"<size=14><color=#FFA500>{i}.</color> <color=#FF8C00>{top.Ник}</color> ({top.РакетВыпущено + top.ВзрывчатокИспользовано})</size>", null, player.UserIDString);
                            }
                        }
                    }
                    return;
                }
            }
            else {
                CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo() {
                    connection = player.net.connection
                }
                , null, "DestroyUI", new Facepunch.ObjectList("Панелька", null, null, null, null));
                CuiElementContainer elements = CreatePanel("0");
                CuiHelper.AddUi(player, elements);
            }
        }
        // GUI панелька
        [ConsoleCommand("top.show")]
        private void TopShowOpenCmd2(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if ((bool)Config["[Топ-Игроков] Включить?"] == false) return;
            if (player == null) return;
            CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo() {
                connection = player.net.connection
            }
            , null, "DestroyUI", new Facepunch.ObjectList("Панелька", null, null, null, null));
            string number = arg.Args[0];
            CuiElementContainer elements = CreatePanel(number);
            CuiHelper.AddUi(player, elements);
            return;
        }
        CuiElementContainer CreatePanel(string number) {
            string cvet = Convert.ToString(Config["[Топ-Игроков] Цвет Панели"]);
            var elements = new CuiElementContainer();
            var panel = elements.Add(new CuiPanel {
                Image = {
                    Color = "0 0 0 0.75"
                }
                , RectTransform = {
                    AnchorMin = "0.2 0.13", AnchorMax = "0.8 0.95"
                }
                , CursorEnabled = true
            }
            , "Hud", "Панелька");
            elements.Add(new CuiPanel {
                Image = {
                    Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0 0.81", AnchorMax = "1 1"
                }
                ,
            }
            , panel);
            elements.Add(new CuiLabel {
                Text = {
                    Text = "<color=#ffa500>TOP 10 ИГРОКОВ</color>", FontSize = 30, Align = TextAnchor.MiddleCenter
                }
                , RectTransform = {
                    AnchorMin = "0 0.89", AnchorMax = "1 1"
                }
                ,
            }
            , panel);
            elements.Add(new CuiButton {
                Button = {
                    Command = "top.exit", Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0.9 0.90", AnchorMax = "1 1"
                }
                , Text = {
                    Text = "<color=#ffa500>X</color>", FontSize = 18, Align = TextAnchor.MiddleCenter
                }
            }
            , panel);
            elements.Add(new CuiPanel {
                Image = {
                    Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0 0.81", AnchorMax = "0.298 0.8899999"
                }
                ,
            }
            , panel);
            elements.Add(new CuiLabel {
                Text = {
                    Text = "<color=#ffa500>Игрок</color>", FontSize = 20, Align = TextAnchor.MiddleCenter
                }
                , RectTransform = {
                    AnchorMin = "0 0.81", AnchorMax = "0.29 0.8899999"
                }
                ,
            }
            , panel);
            elements.Add(new CuiButton {
                Text = {
                    Text = "<color=#ffa500>Убийства</color>", FontSize = 15, Align = TextAnchor.MiddleCenter
                }
                , Button = {
                    Command = "top.show 1", Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0.30 0.81", AnchorMax = "0.454 0.8899999"
                }
            }
            , panel);
            elements.Add(new CuiButton {
                Text = {
                    Text = "<color=#ffa500>Смертей</color>", FontSize = 15, Align = TextAnchor.MiddleCenter
                }
                , Button = {
                    Command = "top.show 2", Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0.455 0.81", AnchorMax = "0.578 0.8899999"
                }
            }
            , panel);
            elements.Add(new CuiButton {
                Text = {
                    Text = "<color=#ffa500>Животные</color>", FontSize = 15, Align = TextAnchor.MiddleCenter
                }
                , Button = {
                    Command = "top.show 3", Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0.58 0.81", AnchorMax = "0.678 0.8899999"
                }
            }
            , panel);
            elements.Add(new CuiButton {
                Text = {
                    Text = "<color=#ffa500>Взрывов</color>", FontSize = 15, Align = TextAnchor.MiddleCenter
                }
                , Button = {
                    Command = "top.show 4", Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0.68 0.81", AnchorMax = "0.859 0.8899999"
                }
            }
            , panel);
            elements.Add(new CuiButton {
                Text = {
                    Text = "<color=#ffa500>Ресурсы</color>", FontSize = 15, Align = TextAnchor.MiddleCenter
                }
                , Button = {
                    Command = "top.show 5", Color = $"{cvet}"
                }
                , RectTransform = {
                    AnchorMin = "0.86 0.81", AnchorMax = "1 0.8899999"
                }
            }
            , panel);
            string polosa = "0 0 0 0.9";
            int n = 0;
            var TopPlayer = (from x in Tops select x).OrderByDescending(x => x.УбийствPVP).Take(10);
            if (number == "2") {
                TopPlayer = (from x in Tops select x).OrderByDescending(x => x.Смертей).Take(10);
            }
            else if (number == "3") {
                TopPlayer = (from x in Tops select x).OrderByDescending(x => x.УбийствЖивотных).Take(10);
            }
            else if (number == "4") {
                TopPlayer = (from x in Tops select x).OrderByDescending(x => x.РакетВыпущено + x.ВзрывчатокИспользовано).Take(10);
            }
            else if (number == "5") {
                TopPlayer = (from x in Tops select x).OrderByDescending(x => x.РесурсовСобрано).Take(10);
            }
            else {
                TopPlayer = (from x in Tops select x).OrderByDescending(x => x.УбийствPVP).Take(10);
            }
            foreach (var top in TopPlayer) {
                if (n % 2 == 0) {
                    polosa = "0 0 0 0.7";
                }
                else {
                    polosa = "1 1 1 0.05";
                }
                elements.Add(new CuiPanel {
                    Image = {
                        Color = polosa
                    }
                    , RectTransform = {
                        AnchorMin = $"0 {0.72 - (n * 0.08)}", AnchorMax = $"1 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                elements.Add(new CuiLabel {
                    Text = {
                        Text = Convert.ToString(top.Ник), FontSize = 15, Align = TextAnchor.MiddleCenter
                    }
                    , RectTransform = {
                        AnchorMin = $"0 {0.72 - (n * 0.08)}", AnchorMax = $"0.29 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                elements.Add(new CuiLabel {
                    Text = {
                        Text = Convert.ToString(top.УбийствPVP), FontSize = 15, Align = TextAnchor.MiddleCenter
                    }
                    , RectTransform = {
                        AnchorMin = $"0.3 {0.72 - (n * 0.08)}", AnchorMax = $"0.454 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                elements.Add(new CuiLabel {
                    Text = {
                        Text = Convert.ToString(top.Смертей), FontSize = 15, Align = TextAnchor.MiddleCenter
                    }
                    , RectTransform = {
                        AnchorMin = $"0.455 {0.72 - (n * 0.08)}", AnchorMax = $"0.578 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                elements.Add(new CuiLabel {
                    Text = {
                        Text = Convert.ToString(top.УбийствЖивотных), FontSize = 15, Align = TextAnchor.MiddleCenter
                    }
                    , RectTransform = {
                        AnchorMin = $"0.58 {0.72 - (n * 0.08)}", AnchorMax = $"0.678 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                elements.Add(new CuiLabel {
                    Text = {
                        Text = $"{ Convert.ToString(top.ВзрывчатокИспользовано + top.РакетВыпущено)}", FontSize = 15, Align = TextAnchor.MiddleCenter
                    }
                    , RectTransform = {
                        AnchorMin = $"0.68 {0.72 - (n * 0.08)}", AnchorMax = $"0.85 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                elements.Add(new CuiLabel {
                    Text = {
                        Text = Convert.ToString(top.РесурсовСобрано), FontSize = 15, Align = TextAnchor.MiddleCenter
                    }
                    , RectTransform = {
                        AnchorMin = $"0.86 {0.72 - (n * 0.08)}", AnchorMax = $"0.99 {0.8 - (n * 0.08)}"
                    }
                    ,
                }
                , panel);
                n++;
            }
            return elements;
        }
        // Выход с панельки
        [ConsoleCommand("top.exit")]
        private void MagazineOpenCmd2(ConsoleSystem.Arg arg) {
            if ((bool)Config["[Топ-Игроков] Включить?"] == false) return;
            if (arg.Player() == null) return;
            BasePlayer player = arg.Player();
            CommunityEntity.ServerInstance.ClientRPCEx(new Network.SendInfo() {
                connection = player.net.connection
            }
            , null, "DestroyUI", new Facepunch.ObjectList("Панелька", null, null, null, null));
        }
        private Dictionary<uint, string> LastHeliHit = new Dictionary<uint, string>();
        void OnEntityDeath(BaseCombatEntity victim, HitInfo info, BaseCombatEntity entity) {
            if (entity == null || info == null) return;
            if (victim == null) return;
            if (entity?.net?.ID == null) return;
            BasePlayer victimBP = victim.ToPlayer();
            BasePlayer initiator = info.InitiatorPlayer;
            if (entity is BaseHelicopter && info.Initiator is BasePlayer) LastHeliHit[entity.net.ID] = info.InitiatorPlayer.UserIDString;
            if (victimBP != null && !IsNPC(victimBP)) {
                string death = victimBP.UserIDString;
                TopData con = (from x in Tops where x.UID == death select x).FirstOrDefault();
                //Считаем смерти
                con.Смертей += 1;
                Saved();
            }
            if (initiator == null) {
                //Считаем количество сбитых "Гвинтокрилів"
                if (victim is BaseHelicopter) {
                    if (LastHeliHit.ContainsKey(victim.net.ID)) {
                        TopData data = Tops.Where(p => p.UID == LastHeliHit[victim.net.ID]).FirstOrDefault();
                        data.ВертолётовУничтожено += 1;
                        LastHeliHit.Remove(victim.net.ID);
                    }
                }
                return;
            }
            if (initiator != null && !IsNPC(initiator)) {
                string killer = initiator.UserIDString;
                TopData con2 = (from x in Tops where x.UID == killer select x).FirstOrDefault();
                //NPC
                if (IsNPC(victimBP)) {
                    con2.NPCУбито++;
                }
                //Считаем убийства животных
                if (victim is BaseAnimalNPC) {
                    con2.УбийствЖивотных += 1;
                }
                if (victim is BradleyAPC) {
                    con2.ТанковУничтожено++;
                }
                //Считаем убийства игроков
                if (victimBP != null && victimBP != initiator) {
                    con2.УбийствPVP += 1;
                }
                Saved();
            }
            return;
        }
        //Считаем взрывчатку
        void OnExplosiveThrown(BasePlayer player, BaseEntity entity) {
            TopData con = (from x in Tops where x.UID == Convert.ToString(player.userID) select x).FirstOrDefault();
            con.ВзрывчатокИспользовано += 1;
            Saved();
        }
        //Считаем ракеты
        void OnRocketLaunched(BasePlayer player, BaseEntity entity) {
            TopData con = (from x in Tops where x.UID == Convert.ToString(player.userID) select x).FirstOrDefault();
            con.РакетВыпущено += 1;
            Saved();
        }
        private void OnCollectiblePickup(Item item, BasePlayer player) {
            DoGather(player, item.amount);
        }
        void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
            if (entity == null || !(entity is BasePlayer) || item == null || dispenser == null) return;
            if (entity.ToPlayer() is BasePlayer) DoGather(entity.ToPlayer(), item.amount);
        }
        //Подсчитываем количество собраных ресурсов
        private void DoGather(BasePlayer player, int item) {
            if (player == null) return;
            TopData con = (from x in Tops where x.UID == Convert.ToString(player.userID) select x).FirstOrDefault();
            con.РесурсовСобрано += item;
            Saved();
            return;
        }
        private void CreateInfo(BasePlayer player) {
            if ((bool)Config["[Топ-Игроков] Включить?"] == false) return;
            if (player == null) return;
            Tops.Add(new TopData((string)player.displayName, player.UserIDString, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
            Saved();
        }
        //////// Конфиг-конец
        [ConsoleCommand("ban.user")]
        private void cmdBan(ConsoleSystem.Arg arg) {
            if (arg.Player() != null && !arg.Player().IsAdmin) {
                return;
            }
            if (arg.Args == null || arg.Args.Length < 2) {
                arg.ReplyWith("Неверный синтаксис! Используйте ban.user <SteamID> <Причина>");
                return;
            }
            BasePlayer target = null;
            foreach (var player in BasePlayer.activePlayerList) {
                if (player.UserIDString == arg.Args[0]) {
                    target = player;
                    ConsoleNetwork.BroadcastToAllClients("chat.add", new object[] {
                        0, $"<color=#FF4500>[Анти-чит]</color> <color=#FF6347>{player.displayName}({player.UserIDString})</color> забанен! Причина: {arg.Args[1]}!"
                    }
                    );
                }
            }
            LoadedPlayerData.Add(new PlayerData {
                SteamID = arg.Args[0],
            }
            );
            SaveData();
            if (target != null && target.IsConnected) Kick(target, "VAC BAN");
            arg.ReplyWith($"{arg.Args[0]} забанен");
        }
        [HookMethod("UnbanCommand")]
        private void UnbanCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null && !arg.Player().IsAdmin) {
                return;
            }
            if (arg.Args == null || arg.Args.Length != 1) {
                arg.ReplyWith("Неверный синтаксис! Используйте unban.user <SteamID>");
                return;
            }
            LoadedPlayerData.RemoveWhere(p => p.SteamID == arg.Args[0]);
            arg.ReplyWith($"{arg.Args[0]} разбанен");
            SaveData();
        }
        private object CanUserLogin(string name, string id) => !LoadedPlayerData.Any(p => p.SteamID == id);
        //////// Бан колонка
        public List<BasePlayer> Players => BasePlayer.activePlayerList;
        public BasePlayer FindById(ulong id) {
            foreach (var player in Players) {
                if (!id.Equals(player.userID)) continue;
                return player;
            }
            return null;
        }
        public bool IsConnected(BasePlayer player) => BasePlayer.activePlayerList.Contains(player);
        public void Kick(BasePlayer player, string reason = "") => player.Kick(reason);
        public bool IsBanned(ulong id) => ServerUsers.Is(id, ServerUsers.UserGroup.Banned);
        public void Ban(ulong id, string reason = "") {
            if (IsBanned(id)) return;
            var player = FindById(id);
            ServerUsers.Set(id, ServerUsers.UserGroup.Banned, player?.displayName ?? "Unknown", reason);
            ServerUsers.Save();
            if (player != null && IsConnected(player)) Kick(player, reason);
        }
        private readonly Dictionary<ulong, AimLockData> aimlock = new Dictionary<ulong, AimLockData>();
        public class AimLockData {
            public int Ticks = 1;
            public string Body = "";
        }
        [HookMethod("OnEntityTakeDamage")]
        private void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info, BaseCombatEntity victim, BasePlayer player) {
            // Собираем инфу для начала
            if (entity is BasePlayer && info.Initiator is BasePlayer) {
                if (victim == null) return;
                if (entity?.net?.ID == null) return;
                var distance = info.Initiator.Distance(entity.transform.position);
                if (entity is BaseHelicopter && info.Initiator is BasePlayer) LastHeliHit[entity.net.ID] = info.InitiatorPlayer.UserIDString;
                if (distance > 10) {
                    BasePlayer ent = entity.ToPlayer();
                    BasePlayer init = info.Initiator.ToPlayer();
                    AimLockData bodylock;
                    if (!aimlock.TryGetValue(init.userID, out bodylock)) {
                        aimlock.Add(init.userID, bodylock = new AimLockData());
                    }
                    var _bodyPart = entity?.skeletonProperties?.FindBone(info.HitBone)?.name?.english ?? "";
                    if (bodylock.Body == _bodyPart && _bodyPart != "lower spine") {
                        bodylock.Ticks++;
                    }
                    else {
                        bodylock.Ticks = 1;
                    }
                    if (bodylock.Ticks > 2) {
                        ConVar.Server.Log("oxide/logs/AntiCheat.txt", $"(АимЛок) {init.displayName}({init.UserIDString})| обнаружений {bodylock.Ticks} |  {bodylock?.Body ?? ""} | {distance} м.");
                        bodylock.Ticks = 1;
                    }
                    bodylock.Body = _bodyPart;
                    AimData con = (from x in Aim where x.SteamId == init.UserIDString select x).FirstOrDefault();
                    con.Попаданий += 1;
                    if (info.isHeadshot) {
                        con.Голова += 1;
                    }
                    double aim = Math.Floor((con.Голова * 1f / con.Попаданий * 1f) * 100);
                    TopData play = (from x in Tops where x.UID == init.UserIDString select x).FirstOrDefault();
                    if (play.Смертей == 0) play.Смертей = 1;
                    double kdr = Math.Round(play.УбийствPVP * 1f / play.Смертей * 1f, 2);
                    if (con.Попаданий > 20 && aim > 50) {
                        SendDetection(player, string.Format("<color=green>[Античит детект]</color> " + "(<color=red>AimHack</color>) " + player.displayName + "забанен! Процент попаданий в голову слишком большой {aim}% (AimHack)!"));
                        Debug.LogWarning($"[Анти-чит] {init.displayName}({init.UserIDString}) забанен! Причина: AimHack!");
                        Ban(init.userID, "[Анти-чит] AimHack");
                        ConVar.Server.Log("oxide/logs/AntiCheat.txt", $"{init.displayName}({init.UserIDString}) забанен! Процент попаданий в голову слишком большой {aim}% (AimHack)!");
                    }
                    if (con.Попаданий > 80 && aim < 7 && kdr > 2) {
                        SendDetection(player, string.Format("<color=green>[Античит детект]</color> " + "(<color=red>AimLock</color>) " + player.displayName + "забанен! Соотношение попаданий в голову {aim}% и КДР аномальные (AimLock)!"));
                        Debug.LogWarning($"[Анти-чит] {init.displayName}({init.UserIDString}) забанен! Причина: AimLock!");
                        Ban(init.userID, "[Анти-чит] AimLock");
                        ConVar.Server.Log("oxide/logs/AntiCheat.txt", $"{init.displayName}({init.UserIDString}) забанен! Соотношение попаданий в голову {aim}% и КДР аномальные (AimLock)!");
                    }
                }
            }
        }
#region Console Commands
        [HookMethod("AimCheck")]
        private void AimCheck(ConsoleSystem.Arg arg) {
            if (arg.Player() != null && !arg.Player().IsAdmin) {
                return;
            }
            if (arg.Args.Length == 1) {
                var check = (from x in Aim where x.SteamId == arg.Args[0] select x).Count();
                if (check > 0) {
                    AimData con = (from x in Aim where x.SteamId == arg.Args[0] select x).FirstOrDefault();
                    double aim = Math.Floor((con.Голова * 1f / con.Попаданий * 1f) * 100);
                    arg.ReplyWith($"[Анти-чит] {con.Игрок}: Aim: {aim}% при {con.Попаданий} попаданиях (с растояния 10 метров и выше)");
                }
                else {
                    arg.ReplyWith("Игрока не найдено!");
                }
            }
            return;
        }
        [HookMethod("AimCheckServer")]
        private void AimCheckServer(ConsoleSystem.Arg arg) {
            if (arg.Player() != null && !arg.Player().IsAdmin) {
                return;
            }
            double popa = 0;
            double head = 0;
            var Top = (from x in Aim select x);
            foreach (var top in Top) {
                popa = popa + top.Попаданий;
                head = head + top.Голова;
            }
            arg.ReplyWith($"[Анти-чит]: В голову попадают в {Math.Floor((head * 1f / popa * 1f) * 100f)}% случаев (с растояния 10 метров и выше)");
            return;
        }
        [HookMethod("CheckServer")]
        private void CheckServer(ConsoleSystem.Arg arg) {
            if (arg.Player() != null && !arg.Player().IsAdmin) {
                return;
            }
            int i = 0;
            double procent = 0;
            string players = "";
            double popa = 0;
            double head = 0;
            string aimdesc = "";
            var Top = (from x in Aim select x);
            foreach (var top in Top) {
                popa = popa + top.Попаданий;
                head = head + top.Голова;
            }
            double aimserver = Math.Floor((head * 1f / popa * 1f) * 100f);
            players = "----------------------------------Игроки---------------------------------- \n";
            foreach (var player in BasePlayer.activePlayerList) {
                TopData play = (from x in Tops where x.UID == player.UserIDString select x).FirstOrDefault();
                if (play.Смертей == 0) play.Смертей = 1;
                AimData aim = (from x in Aim where x.SteamId == play.UID select x).FirstOrDefault();
                if (aim.Попаданий == 0) aim.Попаданий = 1;
                double aimprocent = Math.Floor((aim.Голова * 1f / aim.Попаданий * 1f) * 100f);
                double kdr = Math.Round(play.УбийствPVP * 1f / play.Смертей * 1f, 2);
                double razn = aimserver - aimprocent;
                if (aim.Попаданий < 30 || play.УбийствPVP < 10) {
                    aimdesc = "Новый игрок";
                }
                else if (razn > -5 && razn > 5 && kdr < 2) {
                    aimdesc = "Простой игрок";
                }
                else if (razn > -5 && razn > 5 && kdr < 3) {
                    aimdesc = "Подозрительный игрок";
                }
                else if (razn > -5 && razn > 5 && kdr >= 3) {
                    aimdesc = "Очень подозрительный игрок";
                }
                else if (razn > -5 && razn < -8 && kdr < 2) {
                    aimdesc = "Игрок с хорошей точностью в голову";
                }
                else if (razn > -5 && razn < -8 && kdr < 3) {
                    aimdesc = "Скилловый игрок";
                }
                else if (razn > -5 && razn < -8 && kdr < 4) {
                    aimdesc = "Подозрительный игрок";
                }
                if (razn > -5 && razn < -8 && kdr >= 4) {
                    aimdesc = "Читер";
                }
                else if (razn > 5 && razn < 8 && kdr < 1) {
                    aimdesc = "Игрок со слабым скиллом";
                }
                else if (razn > 5 && razn < 8 && kdr < 2) {
                    aimdesc = "Подозрительный игрок";
                }
                else if (razn > 5 && razn < 8 && kdr < 3) {
                    aimdesc = "Очень подозрительный игрок";
                }
                if (razn > 5 && razn < 8 && kdr >= 4) {
                    aimdesc = "Читер";
                }
                i++;
                players = players + $"{i}.{play.Ник} ({play.UID}) | aim: {aimprocent}% | kdr {kdr} | {aimdesc} \n";
            }
            arg.ReplyWith(players + "-------------------------------------------------------------------------------");
        }
#endregion
        [HookMethod("OnPlayerInit")]
        private void OnPlayerInit(BasePlayer player) {
            if (player == null) return;
            var check = (from x in Tops where x.UID == player.UserIDString select x).Count();
            if (check == 0) CreateInfo(player);
            TopData con = (from x in Tops where x.UID == Convert.ToString(player.userID) select x).FirstOrDefault();
            if (player.displayName != con.Ник) con.Ник = player.displayName;
            Saved();
            new PluginTimers(this).Once(2f, () => CheckSpeed(player));
            new PluginTimers(this).Once(2f, () => AimPlayer(player));
            if (isAdmin(player)) {
                if (!adminList.Contains(player)) adminList.Add(player);
            }
        }
        bool isAdmin(BasePlayer player ) {
            if (player.net.connection.authLevel > 0) return true;
            return permission.UserHasPermission(player.userID.ToString(), "anticheat.admin");
        }
        private void AimPlayer(BasePlayer player) {
            if (player == null) return;
            var check = (from x in Aim where x.SteamId == player.UserIDString select x).Count();
            if (check == 0) {
                Aim.Add(new AimData(player.displayName, player.UserIDString, 0, 0));
                SaveData();
            }
        }
        [HookMethod("CheckSpeed")]
        private void CheckSpeed(BasePlayer player) {
            if (player == null) return;
            if (player.net?.connection?.authLevel >= 2) return;
            if (perm.UserHasPermission(player.UserIDString, "anticheat.admin")) return;
            BaseMountable mount = player.GetMounted();
            if (mount == null) return;
            var position = player.transform.position;
            int n = 0;
            int f = 0;
            if (Duel && (bool)Duel?.CallHook("IsDuelPlayer", player)) return;
            new PluginTimers(this).Repeat(2f, 0, () => {
                if (player == null) return;
                if (!player.IsConnected) return;
                //ФлайХак
                if (player.IsFlying && (bool)Config["Включить проверку Flyhack?"] && !player.IsSwimming() && !player.IsDead() && !player.IsSleeping() && !player.IsWounded()) {
                    f++;
                    if (f >= 2) {
                        Kick(player, "[Анти-чит] FlyHack");
                        SendDetection(player, string.Format("<color=green>[Античит детект]</color> " + "(<color=red>FLY</color>) " + player.displayName + " кикнут! Слишком долго находился в воздухе!"));
                        Debug.LogWarning($"[Анти-чит] {player.displayName}({player.UserIDString}) кикнут! Причина: FlyHack!");
                        LogToFile("log", $"(ФлайХак) {player.displayName}({player.UserIDString}) кикнут! Слишком долго находился в воздухе!", this, false);
                    }
                }
                else {
                    f = 0;
                }
                var distance = player.Distance(position);
                position = player.transform.position;
                // Спидхак
                if (distance > 11) {
                    if (n >= 2) {
                        if (player.IsOnGround() && (bool)Config["Включить проверку на Speedhack?"]) {
                            Kick(player, "[Анти-чит] SpeedHack");
                            SendDetection(player, string.Format("<color=green>[Античит детект]</color> " + "(<color=red>SPEEDHACK</color>) " + player.displayName + "кикнут! Двигался со скоростью выше нормы!"));
                            Debug.LogWarning($"[Анти-чит] {player.displayName}({player.UserIDString}) кикнут! Причина: SpeedHack!");
                            LogToFile("log", $"(СпидХак) {player.displayName}({player.UserIDString}) кикнут! Двигался со скоростью выше нормы!", this, false);
                        }
                        SaveData();
                    }
                    n++;
                }
                else {
                    n = 0;
                }
            }
            );
        }
        ////////////////////////////////////////////////////////////
        // Static Fields
        ////////////////////////////////////////////////////////////
        static int bulletmask;
        static DamageTypeList emptyDamage = new DamageTypeList();
        static Vector3 VectorDown = new Vector3(0f, -1f, 0f);
        static Hash<BasePlayer, float> lastWallhack = new Hash<BasePlayer, float>();
        static RaycastHit cachedRaycasthit;
        [HookMethod("WallhackKillCheck")]
        private void WallhackKillCheck(BasePlayer player, BasePlayer attacker, HitInfo hitInfo) {
            if (Physics.Linecast(attacker.eyes.position, hitInfo.HitPositionWorld, out cachedRaycasthit, bulletmask)) {
                BuildingBlock block = cachedRaycasthit.collider.GetComponentInParent<BuildingBlock>();
                if (block != null) {
                    if (block.blockDefinition.hierachyName == "wall.window") return;
                    CancelDamage(hitInfo);
                    if (Time.realtimeSinceStartup - lastWallhack[attacker] > 0.5f) {
                        lastWallhack[attacker] = Time.realtimeSinceStartup;
                        Debug.LogWarning($"WallhackAttack обнаружен у {player.displayName}");
                        SendDetection(player, string.Format("<color=green>[Античит детект]</color> " + "(<color=red>WallhackAttack</color>) " + player.displayName + "нанес урон через препятствие."));
                        LogToFile("log", $"((WallhackAttack) {player.displayName}({player.UserIDString}) нанес урон через препятствие.", this, false);
                    }
                }
            }
        }
        private void CancelDamage(HitInfo hitinfo) {
            hitinfo.damageTypes = emptyDamage;
            hitinfo.HitEntity = null;
        }
        private readonly Dictionary<ulong, NoRecoilData> data = new Dictionary<ulong, NoRecoilData>();
        private readonly Dictionary<ulong, Timer> detections = new Dictionary<ulong, Timer>();
        private readonly int detectionDiscardSeconds = 300;
        private readonly int violationProbability = 30;
        private readonly int maximumViolations = 30;
        private readonly Dictionary<string, int> probabilityModifiers = new Dictionary<string, int>() {
            {
                "weapon.mod.muzzleboost", -5
            }
            , {
                "weapon.mod.silencer", 5
            }
            , {
                "weapon.mod.holosight", 5
            }
            , {
                "crouching", 8
            }
            , {
                "aiming", 5
            }
        }
        ;
        private readonly List<string> blacklistedAttachments = new List<string>() {
            "weapon.mod.muzzlebreak", "weapon.mod.lasersight", "weapon.mod.small.scope"
        }
        ;
        public class NoRecoilData {
            public int Ticks = 0;
            public int Count;
            public int Violations;
        }
        static void SendDetection(BasePlayer player, string msg) {
            if (perm.UserHasPermission(player.UserIDString, "anticheat.send")) {
                player.SendConsoleCommand("chat.add", new object[] {
                    0, msg
                }
                );
            }
            Interface.GetMod().LogWarning(msg);
        }
        void OnItemCraftFinished(ItemCraftTask task, Item item) {
            if (task.owner is BasePlayer) {
                TopData con = (from x in Tops where x.UID == Convert.ToString(task.owner.userID) select x).FirstOrDefault();
                con.ПредметовСкрафчено += 1;
                Saved();
            }
        }
        [HookMethod("OnWeaponFired")]
        private void OnWeaponFired(BaseProjectile projectile, BasePlayer player, ItemModProjectile mod, ProjectileShoot projectileShoot) {
            if ((bool)Config["[Топ-Игроков] Включить?"]) {
                TopData con = (from x in Tops where x.UID == Convert.ToString(player.userID) select x).FirstOrDefault();
                if (projectile.primaryMagazine.ammoType.itemid == -420273765 || projectile.primaryMagazine.ammoType.itemid == -1280058093) {
                    con.СтрелВыпущено += 1;
                }
                else {
                    con.ПульВыпущено += 1;
                }
            }
            var item = player.GetActiveItem();
            if (!(item.info.shortname == "rifle.ak" || item.info.shortname == "lmg.m249")) return;
            if (item.contents.itemList.Any(x => blacklistedAttachments.Contains(x.info.shortname))) return;
            NoRecoilData info;
            if (!data.TryGetValue(player.userID, out info)) data.Add(player.userID, info = new NoRecoilData());
            UnityEngine.Vector3 eyesDirection = player.eyes.HeadForward();
            if (eyesDirection.y < -0.80) return;
            info.Ticks++;
            int probModifier = 0;
            foreach (Item attachment in item.contents.itemList) if (probabilityModifiers.ContainsKey(attachment.info.shortname)) probModifier += probabilityModifiers[attachment.info.shortname];
            if (player.modelState.aiming && probabilityModifiers.ContainsKey("aiming")) probModifier += probabilityModifiers["aiming"];
            if (player.IsDucked() && probabilityModifiers.ContainsKey("crouching")) probModifier += probabilityModifiers["crouching"];
            Timer detectionTimer;
            if (detections.TryGetValue(player.userID, out detectionTimer)) detectionTimer.Reset(detectionDiscardSeconds);
            else detections.Add(player.userID, timer.Once(detectionDiscardSeconds, delegate () {
                if (info.Violations > 0) info.Violations--;
            }
            ));
            timer.Once(.5f, () => {
                ProcessRecoil(projectile, player, mod, projectileShoot, info, probModifier, eyesDirection);
            }
            );
        }
        [HookMethod("ProcessRecoil")]
        private void ProcessRecoil(BaseProjectile projectile, BasePlayer player, ItemModProjectile mod, ProjectileShoot projectileShoot, NoRecoilData info, int probModifier, UnityEngine.Vector3 eyesDirection) {
            var nextEyesDirection = player.eyes.HeadForward();
            if (Math.Abs(nextEyesDirection.y - eyesDirection.y) <.009 && nextEyesDirection.y <.8) info.Count++;
            if (info.Ticks <= 10) return;
            var prob = 101 * info.Count / info.Ticks;
            var item = player.GetActiveItem();
            if (prob > ((101 - violationProbability) + probModifier)) {
                if (prob > 10) prob = 101;
                info.Violations++;
                Debug.LogWarning("(Макрос) " + player.displayName + ": вероятность " + string.Format("{0}", prob) + "% | обнаружений " + info.Violations.ToString() + ".");
                SendDetection(player, string.Format("<color=green>[Античит детект]</color> " + "(<color=red>NoRecoil</color>) " + "У игрока " + player.displayName + " обнаружен NoRecoil " + ",вероятность " + string.Format("{0}", prob) + "% | обнаружений " + info.Violations.ToString() ));
                LogToFile("log", $"(Макрос) " + player.displayName + ": вероятность " + string.Format("{0}", prob) + "% | обнаружений " + info.Violations.ToString() + "
// ... [Code preview truncated due to length. Full source in attached file] ...

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