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

FREE BloodReport : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("BloodReport", "[LimePlugin] Chibubrik", "1.0.0")]
    public class BloodReport : RustPlugin {
#region Reference
        [PluginReference]
        private Plugin ImageLibrary, NoEscape, IQFakeActive;
#endregion
#region Vars
        private static BloodReport _ins;
        public Dictionary<ulong, PlayerSaveCheckClass> PlayerSaveCheck = new Dictionary<ulong, PlayerSaveCheckClass>();
        public class PlayerSaveCheckClass {
            public string Discord;
            public string NickName;
            public ulong ModeratorID;
            public DateTime CheckStart = DateTime.Now;
        }
        public Dictionary<ulong, bool> OpenedModeratorMenu = new Dictionary<ulong, bool>();
        public List<ReportList> LastReport = new List<ReportList>();
        public Dictionary<ulong, PlayerInfo> ReportInformation = new Dictionary<ulong, PlayerInfo>();
#endregion
#region Config
        private static Configuration _config;
        public class Configuration {
            [JsonProperty("[Discord] Вебхук для новых репортов")]
            public string DiscordWebHook;
            [JsonProperty("Пермишн модератора")]
            public string ModeratorPermission;
            [JsonProperty("Кд отправки репортов")]
            public double Cooldown;
            [JsonProperty("Количество репортов для отправки уведомления и отображения в панели")]
            public int AlertCount;
            [JsonProperty("Кастомные имена для оружия")]
            public Dictionary<string, string> CustomNames;
            [JsonProperty("Список жалоб")]
            public List<string> Reasons;
            [JsonProperty("Причина блокировки - время в днях")]
            public Dictionary<string, double> BanReasons;
            public static Configuration DefaultConfig() {
                return new Configuration {
                    DiscordWebHook = "", ModeratorPermission = "bloodreport.moderator", Cooldown = 200, AlertCount = 3, CustomNames = new Dictionary<string, string>() {
                        ["rifle.ak"]
                        = "AK-47"
                    }
                    , Reasons = new List<string>() {
                        "Читы", "3+", "Багоюз", "Другое"
                    }
                    , BanReasons = new Dictionary<string, double>() {
                        ["Использование макросов"]
                        = 3600, ["Использование читов"] = 0, ["Игнор проверки"] = 0, ["Отказ"] = 0,
                    }
                }
                ;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) LoadDefaultConfig();
                SaveConfig();
            }
            catch (Exception e) {
                Debug.LogException(e);
                PrintWarning("Creating new config file.");
                LoadDefaultConfig();
            }
        }
        protected override void LoadDefaultConfig() => _config = Configuration.DefaultConfig();
        protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Helpers
        public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
        private void SaveData() {
            Interface.Oxide.DataFileSystem.WriteObject($"{Title}/Players", ReportInformation);
            Interface.Oxide.DataFileSystem.WriteObject($"{Title}/LastReports", LastReport);
        }
        private void LoadData() {
            try {
                ReportInformation = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerInfo>>($"{Title}/Players");
                LastReport = Interface.Oxide.DataFileSystem.ReadObject<List<ReportList>>($"{Title}/LastReports");
            }
            catch (Exception e) {
                PrintError(e.ToString());
            }
            if (ReportInformation == null) ReportInformation = new Dictionary<ulong, PlayerInfo>();
            if (LastReport == null) LastReport = new List<ReportList>();
        }
        public string HexToCuiColor(string HEX, float Alpha = 100) {
            if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";
            var str = HEX.Trim('#');
            var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
            var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
            var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
            return $"{(double)r / 255} {(double)g / 255} {(double)b / 255} {Alpha / 100}";
        }
#endregion
#region [Info class]
        public class PlayerInfo {
            [JsonProperty("Количество проверок")]
            public int ChecksCount = 0;
            [JsonProperty("Количество репортов")]
            public int ReportCount = 0;
            [JsonProperty("История репортов")]
            public List<string> ReportsHistory = new List<string>();
            [JsonProperty("Выбранные к репорту")]
            public List<ulong> ReportsList = new List<ulong>();
            [JsonProperty("Список смертей")]
            public List<ulong> DeathList = new List<ulong>();
            [JsonProperty("Список убийств")]
            public List<KillsInfo> KillsList = new List<KillsInfo>();
            [JsonProperty("Статус игрока")]
            public Status PlayerStatus = Status.None;
            [JsonProperty("Должность игрока")]
            public Permission PlayerPermission = Permission.Player;
            [JsonProperty("Кд репортов")]
            public double Cooldown = 0;
            [JsonProperty("Список тиммейтов")]
            public List<ulong> Teammates = new List<ulong>();
            public enum Permission {
                Player, Moderator, Administrator
            }
            public enum Status {
                None, OnCheck, AfkCheck, ModeratorOnCheck
            }
            public PlayerInfo(BasePlayer player) {
                if (player != null) {
                    if (player.IsAdmin) {
                        PlayerPermission = Permission.Administrator;
                    }
                    else if (_ins.permission.UserHasPermission(player.UserIDString, _config.ModeratorPermission)) {
                        PlayerPermission = Permission.Moderator;
                    }
                }
            }
        }
        public class ReportList {
            [JsonProperty("Время репорта")]
            public DateTime Time;
            [JsonProperty("Стим айди зарепорченного")]
            public ulong SteamId;
        }
        public class KillsInfo {
            [JsonProperty("Ник убитого")]
            public string KilledName {
                get;
                set;
            }
            [JsonProperty("Айди убитого")]
            public ulong KilledId {
                get;
                set;
            }
            [JsonProperty("Оружие")]
            public string WeaponName {
                get;
                set;
            }
            [JsonProperty("Хитбокс")]
            public string HitBox {
                get;
                set;
            }
            [JsonProperty("Дистанция")]
            public int Distance {
                get;
                set;
            }
        }
#endregion
#region Hooks
        private void OnServerInitialized() {
            _ins = this;
            if (!permission.PermissionExists(_config.ModeratorPermission, this)) {
                permission.RegisterPermission(_config.ModeratorPermission, this);
            }
            LoadData();
            foreach (var item in BasePlayer.activePlayerList) OnPlayerConnected(item);
        }
        private void OnUserPermissionGranted(string id, string permName) {
            var player = BasePlayer.activePlayerList.FirstOrDefault(x => x.UserIDString == id);
            if (player != null && ReportInformation.ContainsKey(player.userID) && permName == _config.ModeratorPermission) {
                ReportInformation[player.userID].PlayerPermission = PlayerInfo.Permission.Moderator;
            }
        }
        private void OnUserPermissionRevoked(string id, string permName) {
            var player = BasePlayer.activePlayerList.FirstOrDefault(x => x.UserIDString == id);
            if (player != null && ReportInformation.ContainsKey(player.userID) && permName == _config.ModeratorPermission) {
                ReportInformation[player.userID].PlayerPermission = PlayerInfo.Permission.Moderator;
            }
        }
        private void Unload() {
            foreach (var item in BasePlayer.activePlayerList) {
                CuiHelper.DestroyUi(item, "CheckAlert");
            }
            foreach (var item in ReportInformation) {
                item.Value.PlayerStatus = PlayerInfo.Status.None;
            }
            PlayerSaveCheck = null;
            SaveData();
            _ins = null;
        }
        private void OnServerSave() {
            SaveData();
        }
        private void OnPlayerConnected(BasePlayer player) {
            if (player.IsReceivingSnapshot) {
                NextTick(() => OnPlayerConnected(player));
                return;
            }
            if (!ReportInformation.ContainsKey(player.userID)) ReportInformation.Add(player.userID, new PlayerInfo(player));
            if (permission.UserHasPermission(player.UserIDString, _config.ModeratorPermission) || player.IsAdmin) {
                if (!OpenedModeratorMenu.ContainsKey(player.userID)) {
                    OpenedModeratorMenu.Add(player.userID, false);
                }
            }
            if (PlayerSaveCheck.ContainsKey(player.userID)) {
                SendReply(BasePlayer.FindByID(PlayerSaveCheck[player.userID].ModeratorID), $"Игрок - {player.displayName}/{player.userID} вернулся сервер во время проверки");
                DiscordSendMessage($"Игрок - {player.displayName}/{player.userID} вернулся на сервер во время проверки");
            }
        }
        private void OnPlayerDisconnected(BasePlayer player, string reason) {
            if (permission.UserHasPermission(player.UserIDString, _config.ModeratorPermission) || player.IsAdmin) {
                if (OpenedModeratorMenu.ContainsKey(player.userID)) {
                    OpenedModeratorMenu[player.userID] = false;
                }
            }
            if (PlayerSaveCheck.ContainsKey(player.userID)) {
                SendReply(BasePlayer.FindByID(PlayerSaveCheck[player.userID].ModeratorID), $"Игрок - {player.displayName} покинул сервер во время проверки: {reason}");
                DiscordSendMessage($"Игрок - {player.displayName} покинул сервер во время проверки: {reason}");
            }
            ReportInformation[player.userID].PlayerStatus = PlayerInfo.Status.None;
        }
        object OnPlayerDeath(BasePlayer player, HitInfo info) {
            if (player == null || info == null) return null;
            var attacker = info.InitiatorPlayer;
            if (attacker == null) return null;
            if (attacker.userID == player.userID) return null;
            if (attacker != null) {
                KillsInfo killinfo = new KillsInfo {
                    Distance = (int)Vector3.Distance(player.transform.position, attacker.transform.position), HitBox = info.boneName, KilledId = player.userID, KilledName = player.displayName, WeaponName = _config.CustomNames.ContainsKey(info.Weapon.GetItem().info.shortname) ? _config.CustomNames[info.Weapon.GetItem().info.shortname] : info.Weapon.GetItem().info.displayName.english
                }
                ;
                if (ReportInformation.ContainsKey(player.userID)) {
                    ReportInformation[player.userID].DeathList.Insert(0, attacker.userID);
                }
                if (ReportInformation.ContainsKey(attacker.userID)) {
                    ReportInformation[attacker.userID].KillsList.Insert(0, killinfo);
                }
            }
            return null;
        }
#endregion
#region Methods
        void DiscordSendMessage(string key, ulong userID = 0, params object[] args) {
            if (String.IsNullOrEmpty(_config.DiscordWebHook)) return;
            List<Fields> fields = new List<Fields> {
                new Fields("ReportSystem", key, true),
            }
            ;
            FancyMessage newMessage = new FancyMessage(null, false, new FancyMessage.Embeds[1] {
                new FancyMessage.Embeds(null, 635133, fields, new Authors("ReportSystem", "https://vk.com/rustnastroika", "https://i.imgur.com/ILk3uJc.png", null), new Footer("Author: Sempai[https://vk.com/rustnastroika]", "https://i.imgur.com/ILk3uJc.png", null))
            }
            );
            Request($"{_config.DiscordWebHook}", newMessage.toJSON());
        }
#region FancyDiscord
        public class FancyMessage {
            public string content {
                get;
                set;
            }
            public bool tts {
                get;
                set;
            }
            public Embeds[] embeds {
                get;
                set;
            }
            public class Embeds {
                public string title {
                    get;
                    set;
                }
                public int color {
                    get;
                    set;
                }
                public List<Fields> fields {
                    get;
                    set;
                }
                public Footer footer {
                    get;
                    set;
                }
                public Authors author {
                    get;
                    set;
                }
                public Embeds(string title, int color, List<Fields> fields, Authors author, Footer footer) {
                    this.title = title;
                    this.color = color;
                    this.fields = fields;
                    this.author = author;
                    this.footer = footer;
                }
            }
            public FancyMessage(string content, bool tts, Embeds[] embeds) {
                this.content = content;
                this.tts = tts;
                this.embeds = embeds;
            }
            public string toJSON() => JsonConvert.SerializeObject(this);
        }
        public class Footer {
            public string text {
                get;
                set;
            }
            public string icon_url {
                get;
                set;
            }
            public string proxy_icon_url {
                get;
                set;
            }
            public Footer(string text, string icon_url, string proxy_icon_url) {
                this.text = text;
                this.icon_url = icon_url;
                this.proxy_icon_url = proxy_icon_url;
            }
        }
        public class Authors {
            public string name {
                get;
                set;
            }
            public string url {
                get;
                set;
            }
            public string icon_url {
                get;
                set;
            }
            public string proxy_icon_url {
                get;
                set;
            }
            public Authors(string name, string url, string icon_url, string proxy_icon_url) {
                this.name = name;
                this.url = url;
                this.icon_url = icon_url;
                this.proxy_icon_url = proxy_icon_url;
            }
        }
        public class Fields {
            public string name {
                get;
                set;
            }
            public string value {
                get;
                set;
            }
            public bool inline {
                get;
                set;
            }
            public Fields(string name, string value, bool inline) {
                this.name = name;
                this.value = value;
                this.inline = inline;
            }
        }
        private void Request(string url, string payload, Action<int> callback = null) {
            Dictionary<string, string> header = new Dictionary<string, string>();
            header.Add("Content-Type", "application/json");
            webrequest.Enqueue(url, payload, (code, response) => {
                if (code != 200 && code != 204) {
                    if (response != null) {
                        try {
                            JObject json = JObject.Parse(response);
                            if (code == 429) {
                                float seconds = float.Parse(Math.Ceiling((double)(int)json["retry_after"] / 1000).ToString());
                            }
                            else {
                                PrintWarning($" Discord rejected that payload! Responded with \"{json["message"].ToString()}\" Code: {code}");
                            }
                        }
                        catch {
                            PrintWarning($"Failed to get a valid response from discord! Error: \"{response}\" Code: {code}");
                        }
                    }
                    else {
                        PrintWarning($"Discord didn't respond (down?) Code: {code}");
                    }
                }
                try {
                    callback?.Invoke(code);
                }
                catch (Exception ex) {
                }
            }
            , this, RequestMethod.POST, header);
        }
#endregion
        private void ReportPlayer(BasePlayer target, string reason) {
            ReportInformation[target.userID].ReportCount++;
            ReportInformation[target.userID].ReportsHistory.Insert(0, reason);
            LastReport.Insert(0, new ReportList() {
                SteamId = target.userID, Time = DateTime.Now
            }
            );
            if (ReportInformation[target.userID].ReportCount >= _config.AlertCount) {
                DiscordSendMessage($"Игрок - {target.displayName}/{target.userID} достиг максимальное количество репортов\nСвободный модератор вызовите на проверку!");
                foreach (var item in BasePlayer.activePlayerList.Where(x => ReportInformation[x.userID].PlayerPermission != PlayerInfo.Permission.Player)) {
                    SendReply(item, $"Игрок - {target.displayName}/{target.userID} достиг максимальное количество репортов\nСвободный модератор вызовите на проверку!");
                }
            }
        }
        public string TimeToString(double time) {
            TimeSpan elapsedTime = TimeSpan.FromSeconds(time);
            int hours = elapsedTime.Hours;
            int minutes = elapsedTime.Minutes;
            int seconds = elapsedTime.Seconds;
            int days = Mathf.FloorToInt((float)elapsedTime.TotalDays);
            string s = "";
            if (days > 0) s += $"{days} дн.";
            if (hours > 0) s += $"{hours} ч.";
            if (minutes > 0) s += $"{minutes} м.";
            if (seconds > 0) s += $"{seconds} с.";
            else s = s.TrimEnd(' ');
            return s;
        }
        public bool IsRaidBlocked(BasePlayer player) {
            if (NoEscape) return (bool)NoEscape?.Call("IsRaidBlocked", player);
            else return false;
        }
        private void SoundToast(BasePlayer player, string text, int type) {
            Effect effect = new Effect("assets/bundled/prefabs/fx/notice/item.select.fx.prefab", player, 0, new Vector3(), new Vector3());
            EffectNetwork.Send(effect, player.Connection);
            player.Command("gametip.showtoast", type, text);
        }
        private double CurrentTime() => DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
#endregion
#region Commands
        private void ReportUI(BasePlayer player) {
            if (player == null) return;
            if (PlayerSaveCheck != null) {
                foreach (var kvp in PlayerSaveCheck) {
                    if (kvp.Value.ModeratorID == player.userID) {
                        ModeratorCheckInfo(player, kvp.Key);
                        return;
                    }
                }
            }
            ReportsUI(player);
        }
        [ConsoleCommand("reports")]
        void ConsoleReport(ConsoleSystem.Arg args) {
            BasePlayer player = args.Player();
            if (player != null && args.HasArgs(1)) {
                if (args.Args[0] == "back") {
                    ReportsBack(player);
                }
                if (args.Args[0] == "help") {
                    ShowUIInforamtion(player);
                }
                if (args.Args[0] == "stopcheck") {
                    if (permission.UserHasPermission(player.UserIDString, _config.ModeratorPermission) || player.IsAdmin) {
                        if (args.Args.Length > 1) StopCheck(player, Convert.ToUInt64(args.Args[1]));
                    }
                }
                if (args.Args[0] == "trychecklast") {
                    if (args.Args.Length > 1) {
                        string target = args.Args[1];
                        TryCheckLast(player, target);
                    }
                }
                if (args.Args[0] == "trycheck") {
                    if (args.Args.Length > 1) {
                        string target = args.Args[1];
                        TryCheck(player, target);
                    }
                }
                if (args.Args[0] == "add") {
                    if (args.Args.Length > 1) AddTargetHandler(player, Convert.ToUInt64(args.Args[1]));
                }
                if (args.Args[0] == "remove") {
                    if (args.Args.Length > 1) RemoveTargetHandler(player, Convert.ToUInt64(args.Args[1]));
                }
                if (args.Args[0] == "closemenu") {
                    if (OpenedModeratorMenu.ContainsKey(player.userID)) OpenedModeratorMenu[player.userID] = false;
                    LoadedPlayers(player);
                }
                if (args.Args[0] == "sendcheck") {
                    if (args.Args.Length > 1) SendCheck(player, Convert.ToUInt64(args.Args[1]));
                }
                if (args.Args[0] == "cancelcheck") {
                    LoadedPlayersModerator(player);
                }
                if (args.Args[0] == "verdict") {
                    if (permission.UserHasPermission(player.UserIDString, _config.ModeratorPermission) || player.IsAdmin) {
                        if (args.Args.Length > 2) StopCheckVerdict(player, Convert.ToUInt64(args.Args[1]), Convert.ToInt32(args.Args[2]));
                    }
                }
                if (args.Args[0] == "moderation") {
                    OpenModerationMenu(player);
                }
                if (args.Args[0] == "send") {
                    SendReportHandler(player, args.Args[1]);
                }
                if (args.Args[0] == "search") {
                    if (args.Args.Length > 1) {
                        string name = args.Args[1];
                        LoadedPlayers(player, name);
                    }
                }
                if (args.Args[0] == "page") {
                    LoadedPlayers(player, "", int.Parse(args.Args[1]));
                }
            }
        }
        [ChatCommand("discord")]
        private void SendDiscord(BasePlayer Suspect, string command, string[] args) {
            if (!PlayerSaveCheck.ContainsKey(Suspect.userID)) {
                return;
            }
            string Discord = "";
            foreach (var arg in args) Discord += " " + arg;
            PlayerSaveCheck[Suspect.userID].Discord = Discord;
            BasePlayer Moderator = BasePlayer.FindByID(PlayerSaveCheck[Suspect.userID].ModeratorID);
            if (Discord != "") {
                var container = new CuiElementContainer();
                CuiHelper.DestroyUi(Moderator, "DiscordImage");
                CuiHelper.DestroyUi(Moderator, "DiscordText");
                container.Add(new CuiElement {
                    Name = "DiscordText", Parent = "DiscordPanel", Components = {
                        new CuiTextComponent {
                            Text = $"{PlayerSaveCheck[Suspect.userID].Discord}", Font = "robotocondensed-bold.ttf", FontSize = 7, Align = TextAnchor.MiddleCenter, Color = "1 1 1 0.6"
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0", AnchorMax = "1 1"
                        }
                    }
                }
                );
                DiscordSendMessage($"Игрок {Suspect.displayName}/{Suspect.userID} предоставил дискорд для проверки: {Discord}");
                CuiHelper.AddUi(Moderator, container);
            }
        }
        private void StopCheck(BasePlayer moderator, ulong target) {
            ReportInformation[target].ChecksCount++;
            ReportInformation[target].PlayerStatus = PlayerInfo.Status.None;
            PlayerSaveCheck.Remove(target);
            var targetPlayer = BasePlayer.FindByID(target) ?? BasePlayer.FindAwakeOrSleeping(target.ToString());
            CuiHelper.DestroyUi(targetPlayer, "CheckAlert");
            CuiHelper.DestroyUi(targetPlayer, "CheckTarget");
            ReportInformation[moderator.userID].PlayerStatus = PlayerInfo.Status.None;
            ReportInformation[target].ReportCount = 0;
            ReportInformation[target].ReportsHistory.Clear();
            LastReport.Remove(LastReport.FirstOrDefault(x => x.SteamId == target));
            ReportsUI(moderator);
            DiscordSendMessage($"Модератор - {moderator.displayName}/{moderator.userID} завершил проверку игрока - {targetPlayer.displayName}/{target}\nВердикт:Чист");
        }
        private void StopCheckVerdict(BasePlayer moderator, ulong target, int index) {
            ReportInformation[target].ChecksCount++;
            ReportInformation[target].PlayerStatus = PlayerInfo.Status.None;
            PlayerSaveCheck.Remove(target);
            var targetPlayer = BasePlayer.FindByID(target) ?? BasePlayer.FindAwakeOrSleeping(target.ToString());
            CuiHelper.DestroyUi(targetPlayer, "CheckAlert");
            CuiHelper.DestroyUi(targetPlayer, "CheckTarget");
            ReportInformation[moderator.userID].PlayerStatus = PlayerInfo.Status.None;
            ReportInformation[target].ReportCount = 0;
            ReportInformation[target].ReportsHistory.Clear();
            rust.RunClientCommand(moderator, $"ban {target} {_config.BanReasons.ElementAt(index).Value}d {_config.BanReasons.ElementAt(index).Key}");
            LastReport.Remove(LastReport.FirstOrDefault(x => x.SteamId == target));
            ReportsUI(moderator);
            DiscordSendMessage($"Модератор - {moderator.displayName}/{moderator.userID} завершил проверку игрока - {targetPlayer.displayName}/{target}\nВердикт:{_config.BanReasons.ElementAt(index).Key}");
        }
        private void SendCheck(BasePlayer moderator, ulong target) {
            if (permission.UserHasPermission(moderator.UserIDString, _config.ModeratorPermission) || moderator.IsAdmin) {
                if (ReportInformation[moderator.userID].PlayerStatus != PlayerInfo.Status.None) {
                    SoundToast(moderator, "У вас уже имеется активная проверка", 1);
                    LoadedPlayersModerator(moderator);
                    return;
                }
                if (ReportInformation[target].PlayerStatus != PlayerInfo.Status.None) {
                    SoundToast(moderator, "Игрок уже проверяется", 1);
                    LoadedPlayersModerator(moderator);
                    return;
                }
                if (IsRaidBlocked(BasePlayer.FindByID(target))) {
                    SoundToast(moderator, "Игрок находится в рейдблоке", 1);
                    LoadedPlayersModerator(moderator);
                    return;
                }
                ReportInformation[target].PlayerStatus = PlayerInfo.Status.AfkCheck;
                LoadedPlayersModerator(moderator);
                Metods_AFK(moderator, target);
            }
        }
        public Dictionary<ulong, GenericPosition> AFKPositionTry = new Dictionary<ulong, GenericPosition>();
        public Dictionary<ulong, int> AFKCheckedTry = new Dictionary<ulong, int>();
        void Metods_AFK(BasePlayer Moderator, ulong SuspectID) {
            IPlayer Suspect = covalence.Players.FindPlayerById(SuspectID.ToString());
            if (!AFKCheckedTry.ContainsKey(SuspectID)) AFKCheckedTry.Add(SuspectID, 0);
            else AFKCheckedTry[SuspectID] = 0;
            StartAFKCheck(Moderator, Suspect);
        }
        public void StartAFKCheck(BasePlayer Moderator, IPlayer Suspect) {
            SoundToast(Moderator, "Проверка на афк - началась", 0);
            ulong SuspectID = ulong.Parse(Suspect.Id);
            var Position = Suspect.Position();
            if (!AFKPositionTry.ContainsKey(SuspectID)) AFKPositionTry.Add(SuspectID, Position);
            int Try = 1;
            double seconds = 0;
            timer.Repeat(5f, 5, () => {
                Position = Suspect.Position();
                if (AFKPositionTry[SuspectID] != Position) {
                    AFKCheckedTry[SuspectID]++;
                }
                AFKPositionTry[SuspectID] = Position;
                Try++;
            }
            );
            timer.Repeat(1f, 30, () => {
                if (OpenedModeratorMenu[Moderator.userID]) DrawAfkCheck(Moderator, seconds);
                seconds++;
            }
            );
            timer.Once(30f, () => {
                if (AFKCheckedTry[SuspectID] < 3) {
                    SoundToast(Moderator, "Игрок - афк, проверка отменяется", 1);
                    ReportInformation[SuspectID].PlayerStatus = PlayerInfo.Status.None;
                    LoadedPlayersModerator(Moderator);
                    CuiHelper.DestroyUi(Moderator, "AfkCheck");
                }
                else {
                    BasePlayer SuspectOnline = BasePlayer.FindByID(ulong.Parse(Suspect.Id));
                    ReportInformation[SuspectID].PlayerStatus = PlayerInfo.Status.OnCheck;
                    ReportInformation[Moderator.userID].PlayerStatus = PlayerInfo.Status.None;
                    if (SuspectOnline == null || !SuspectOnline.IsConnected) {
                        SoundToast(Moderator, $"Игрок - {Suspect.Name} покинул сервер во время скрытой проверки на АФК!\nПроверка была снята автоматически", 1);
                        DiscordSendMessage($"Игрок - {Suspect.Name} покинул сервер во время скрытой проверки на АФК!\nПроверка была снята автоматически", 1);
                        if (PlayerSaveCheck.ContainsKey(SuspectID)) PlayerSaveCheck.Remove(SuspectID);
                        return;
                    }
                    if (!PlayerSaveCheck.ContainsKey(SuspectOnline.userID)) {
                        PlayerSaveCheck.Add(SuspectID, new PlayerSaveCheckClass {
                            Discord = string.Empty, NickName = Suspect.Name, ModeratorID = Moderator.userID,
                        }
                        );
                    }
                    else {
                        PlayerSaveCheck.Remove(SuspectOnline.userID);
                        PlayerSaveCheck.Add(SuspectID, new PlayerSaveCheckClass {
                            Discord = string.Empty, NickName = Suspect.Name, ModeratorID = Moderator.userID,
                        }
                        );
                    }
                    CuiHelper.DestroyUi(Moderator, "AfkCheck");
                    CuiHelper.DestroyUi(Moderator, "ModeratorPanel");
                    ModeratorCheckInfo(Moderator, SuspectID);
                    UI_AlertSendPlayer(SuspectOnline);
                    DiscordSendMessage($"Модератор {Moderator.displayName}/{Moderator.userID} вызвал на проверку игрока - {SuspectOnline.displayName}/{SuspectOnline.userID}");
                }
                if (AFKCheckedTry.ContainsKey(SuspectID)) AFKCheckedTry.Remove(SuspectID);
            }
            );
        }
        void UI_AlertSendPlayer(BasePlayer Suspect) {
            CuiElementContainer container = new CuiElementContainer();
            CuiHelper.DestroyUi(Suspect, "CheckAlert");
            container.Add(new CuiPanel {
                CursorEnabled = false, RectTransform = {
                    AnchorMin = "0 0.75", AnchorMax = "1 0.9", OffsetMax = "0 0"
                }
                , Image = {
                    Color = "0 0 0 0.9"
                }
                ,
            }
            , "Overlay", "CheckAlert");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = $"<b><size=20>{Suspect.displayName.ToUpper()}, ВАС ВЫЗВАЛИ НА ПРОВЕРКУ</size></b>\nПредоставте свой дискорд или скайп для проверки.\nВведите команду /discord\nЕсли Вы покинете сервер, Вы будете забанены на проекте.\nУ вас есть 5 минут!", Color = "1 1 1 0.5", Align = TextAnchor.MiddleCenter, FontSize = 14, Font = "robotocondensed-regular.ttf"
                }
            }
            , "CheckAlert");
            CuiHelper.AddUi(Suspect, container);
        }
        private void DrawAfkCheck(BasePlayer moderator, double seconds) {
            var container = new CuiElementContainer();
            CuiHelper.DestroyUi(moderator, "AfkCheck");
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = "0 1.015", AnchorMax = "1 1.08"
                }
                , Image = {
                    Color = HexToCuiColor("#84b4dd", 25)
                }
            }
            , "ModeratorPanel", "AfkCheck");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = $"Проверка на АФК, осталось {30 - seconds}с", Color = HexToCuiColor("#84b4dd", 100), Align = TextAnchor.MiddleCenter, FontSize = 12, Font = "robotocondensed-regular.ttf"
                }
            }
            , "AfkCheck");
            CuiHelper.AddUi(moderator, container);
        }
        private void ModeratorCheckInfo(BasePlayer moderator, ulong target) {
            CuiHelper.DestroyUi(moderator, "ModeratorPanel");
            CuiHelper.DestroyUi(moderator, "CheckTarget");
            var container = new CuiElementContainer();
            var targetPlayer = BasePlayer.FindByID(target) ?? BasePlayer.FindAwakeOrSleeping(target.ToString());
            container.Add(new CuiPanel {
                CursorEnabled = true, RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
                }
                , Image = {
                    Color = "0 0 0 0"
                }
            }
            , "Menu_Block", "CheckTarget");
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = "0 0.94", AnchorMax = "0.94 1"
                }
                , Image = {
                    Color = HexToCuiColor("#84b4dd", 25)
                }
                ,
            }
            , "CheckTarget", "Title");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = $"Игрок двигался, удачной проверки!", Color = HexToCuiColor("#84b4dd", 100), Align = TextAnchor.MiddleCenter, FontSize = 12, Font = "robotocondensed-regular.ttf"
                }
            }
            , "Title");
            container.Add(new CuiButton {
                RectTransform = {
                    AnchorMin = "0.95 0.94", AnchorMax = "1 1"
                }
                , Button = {
                    Color = HexToCuiColor("#e0947a", 25), Command = "reports closemenu"
                }
                , Text = {
                    Text = "✕", Color = HexToCuiColor("#e0947a", 100), Align = TextAnchor.MiddleCenter, FontSize = 14, Font = "robotocondensed-regular.ttf"
                }
                ,
            }
            , "CheckTarget");
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = "0 0.87", AnchorMax = "0.65 0.93"
                }
                , Image = {
                    Color = HexToCuiColor("#e0947a", 25)
                }
                ,
            }
            , "CheckTarget", "SuspectTitle");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = "Подозреваемый", Color = HexToCuiColor("#e0947a", 100), Align = TextAnchor.MiddleCenter, FontSize = 12, Font = "robotocondensed-regular.ttf"
                }
            }
            , "SuspectTitle");
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = "0.66 0.87", AnchorMax = "1 0.93"
                }
                , Image = {
                    Color = HexToCuiColor("#e0947a", 25)
                }
                ,
            }
            , "CheckTarget", "LastKills");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = "Последние убийства", Color = HexToCuiColor("#e0947a", 100), Align = TextAnchor.MiddleCenter, FontSize = 12, Font = "robotocondensed-regular.ttf"
                }
            }
            , "LastKills");
            container.Add(new CuiPanel {
                Image = {
                    Color = "1 1 1 0.04", Material = "assets/content/ui/uibackgroundblur.mat"
                }
                , RectTransform = {
                    AnchorMin = "0 0.78", AnchorMax = "0.65 0.86"
                }
            }
            , "CheckTarget", "SuspectPanel");
            container.Add(new CuiElement {
                Name = "Avatar", Parent = "SuspectPanel", Components = {
                    new CuiRawImageComponent {
                        Color = "1 1 1 1", Png = GetImage(target.ToString(), 0)
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.015 0.15", AnchorMax = "0.09 0.85"
                    }
                }
            }
            );
            var name = targetPlayer.displayName.Length > 20 ? targetPlayer.displayName.Substring(0, 20) + "..." : targetPlayer.displayName;
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0.11 0.33", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = name, Color = HexToCuiColor("#cec5bb", 100), Align = TextAnchor.MiddleLeft, FontSize = 12, Font = "robotocondensed-regular.ttf"
                }
            }
            , "SuspectPanel");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0.11 0", AnchorMax = "1 0.67", OffsetMax = "0 0"
                }
                , Text = {
                    Text = $"{target}", Color = HexToCuiColor("#7f7d7d", 100), Align = TextAnchor.MiddleLeft, FontSize = 8, Font = "robotocondensed-regular.ttf"
                }
            }
            , "SuspectPanel");
            container.Add(new CuiPanel {
                Image = {
                    Color = "0 0 0 0"
                }
                , RectTransform = {
                    AnchorMin = "0.66 0.4", AnchorMax = "1 0.86"
                }
            }
            , "CheckTarget", "KillsPanel");
            float width = 0.99f, height = 0.14f, startxBox = 0f, startyBox = 0.994f - height, xmin = startxBox, ymin = startyBox;
            foreach (var i in Enumerable.Range(0, 6)) {
                var item = ReportInformation[target].KillsList.ElementAtOrDefault(i);
                if (item != null) {
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = $"{xmin} {ymin}", AnchorMax = $"{xmin + width} {ymin + height * 1}"
                        }
                        , Image = {
                            Color = "1 1 1 0.04", Material = "assets/content/ui/uibackgroundblur.mat"
                        }
                    }
                    , "KillsPanel", "CheckPlayer");
                    xmin += width + 0.02f;
                    if (xmin + width >= 0) {
                        xmin = startxBox;
                        ymin -= height + 0.03f;
                    }
                    var killedname = item.KilledName.Length > 15 ? item.KilledName.Substring(0, 15) + "..." : item.KilledName;
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0.02 0.35", AnchorMax = "1 1", OffsetMax = "0 0"
                        }
                        , Text = {
                            Text = killedname, Color = HexToCuiColor("#cec5bb", 100), Align = TextAnchor.MiddleLeft, FontSize = 10, Font = "robotocondensed-regular.ttf"
                        }
                    }
                    , "CheckPlayer");
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0.02 0", AnchorMax = "1 0.6", OffsetMax = "0 0"
                        }
                        , Text = {
                            Text = $"<color=#84b4dd>{item.WeaponName}</color> - <color=#e0947a>{item.HitBox}</color>", Color = HexToCuiColor("#7f7d7d", 100), Align = TextAnchor.MiddleLeft, FontSize = 8, Font = "robotocondensed-regular.ttf"
                        }
                    }
                    , "CheckPlayer");
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "0.96 1", OffsetMax = "0 0"
                        }
                        , Text = {
                            Text = $"{item.Distance}м", Color = HexToCuiColor("#7f7d7d", 100), Align = TextAnchor.MiddleRight, FontSize = 10, Font = "robotocondensed-regular.ttf"
                        }
                    }
                    , "CheckPlayer");
                }
            }
            container.Add(new CuiButton {
                RectTransform = {
                    AnchorMin = "0.66 0.33", AnchorMax = "0.998 0.388"
                }
                , Button = {
                    Color = HexToCuiColor("#bbc47e", 25), Command = $"reports stopcheck {target}"
                }
                , Text = {
                    Text = "Стоп", Font = "robotocondensed-regular.ttf", FontSize = 12, Align = TextAnchor.MiddleCenter, Color = HexToCuiColor("#bbc47e", 100)
                }
                ,
            }
            , "CheckTarget", "StopBTN");
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = "0 0.7", AnchorMax = "0.65 0.765"
                }
                , Image = {
                    Color = HexToCuiColor("#84b4dd", 25)
                }
                ,
            }
            , "CheckTarget", "TeamTittle");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
                }
                , Text = {
                    Text = "Тимейты подозреваемого", Color = HexToCuiColor("#84b4dd", 100), Align = TextAnchor.MiddleCenter, FontSize = 12, Font = "robotocondensed-regular.ttf"
                }
            }
            , "TeamTittle");
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = "0 0.4", AnchorMax = "0.65 0.688"
                }
                , Image = {
                    Color = $"0 0 0 0"
                }
            }
            , "CheckTarget", "TeamPanel");
            var Team = targetPlayer.Team == null ? ReportInformation[target].Teammates : targetPlayer.Team.members;
            float width1 = 0.996f, height1 = 0.3f, startxBox1 = 0f, startyBox1 = 0.994f - height1, xmin1 = startxBox1, ymin1 = startyBox1;
            foreach (var j in Enumerable.Range(0, 3)) {
                var item = Team.Where(x => x != target).ElementAtOrDefault(j);
                if (item != 0) {
                    container.Add(new CuiPanel {
                        RectTransform = {
                            AnchorMin = $"{xmin1} {ymin1}", AnchorMax = $"{xmin1 + width1} {ymin1 + height1 * 1}"
                        }
                        , Image = {
                            Color = "1 1 1 0.04", Material = "assets/content/ui/uibackgroundblur.mat"
                        }
                    }
                    , "TeamPanel", "TeamMate");
                    xmin1 += width1 + 0.02f;
                    if (xmin1 + width1 >= 0) {
                        xmin1 = startxBox1;
                        ymin1 -= height1 + 0.045f;
                    }
                    container.Add(new CuiElement {
                        Name = "Avatar", Parent = "TeamMate", Components = {
                            new CuiRawImageComponent {
                                Color = "1 1 1 1", Png = GetImage(item.ToString(), 0)
                            }
                            , new CuiRectTransformComponent {
                                AnchorMin = "0.015 0.15", AnchorMax = "0.1 0.85"
                            }
                        }
                    }
                    );
                    var mate = covalence.Players.FindPlayerById(item.ToString());
                    container.Add(new CuiLabel {
                        RectTransform = {
                            AnchorMin = "0.12 0.35", AnchorMax = "1 1", OffsetMax = "0 0"
                        }
                        , Text = {
                            Text = mate.Name, Color = HexToCuiColor("#cec5bb", 100), Align = TextAnchor.MiddleLeft, FontSize = 12, Font = "robotocondensed-regular.ttf"
                        }
                    }
                    , "TeamMate");
                    container.Add(new
// ... [Code preview truncated due to length. Full source in attached file] ...

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