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

FREE Arkan : 1.0.18 1.0.18

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using ProtoBuf;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using System.Globalization;
using Newtonsoft.Json;
using UnityEngine;
using System.Text.RegularExpressions;
namespace Oxide.Plugins {
    [Info("Arkan", "Antidote", "1.0.18")]
    [Description("Player shot analysis tool for Admins")]
    class Arkan : RustPlugin {
        [PluginReference]
        private Plugin DiscordMessages;
#region Fields
        private const string permName = "arkan.allowed";
        private const string permNRDrawViolation = "arkan.nr.draw";
        private const string permAIMDrawViolation = "arkan.aim.draw";
        private const string permIRDrawViolation = "arkan.ir.draw";
        private const string permNRReportChat = "arkan.nr.reportchat";
        private const string permNRReportConsole = "arkan.nr.reportconsole";
        private const string permAIMReportChat = "arkan.aim.reportchat";
        private const string permAIMReportConsole = "arkan.aim.reportconsole";
        private const string permIRReportChat = "arkan.ir.reportchat";
        private const string permIRReportConsole = "arkan.ir.reportconsole";
        private const string permNRWhitelist = "arkan.nrwhitelist";
        private const string permNRBlacklist = "arkan.nrblacklist";
        private const string permAIMWhitelist = "arkan.aimwhitelist";
        private const string permAIMBlacklist = "arkan.aimblacklist";
        private const string permIRWhitelist = "arkan.irwhitelist";
        private const string permIRBlacklist = "arkan.irblacklist";
        private Dictionary<ulong, PlayerFiredProjectlesData> PlayersFiredProjectlesData = new Dictionary<ulong, PlayerFiredProjectlesData>();
        private PlayersViolationsData PlayersViolations = new PlayersViolationsData();
        private PlayersViolationsData tmpPlayersViolations = new PlayersViolationsData();
        private string serverTimeStamp;
        private bool isAttackShow = false;
        //for development purposes only
        private AdminConfig RconLog = new AdminConfig();
        private readonly int world_defaultLayer = LayerMask.GetMask("World", "Default");
        private readonly int world_terrainLayer = LayerMask.GetMask("World", "Terrain");
        private readonly int terrainLayer = LayerMask.GetMask("Terrain");
        private readonly string stringNullValueWarning = "Error: value is null";
        private Dictionary<BasePlayer, AdminConfig> AdminsConfig = new Dictionary<BasePlayer, AdminConfig>();
        private static Configuration _config;
        private class Configuration {
            public float NRProcessTimer = 4f;
            public float EPSILON = 0.005f;
            public float projectileTrajectoryForgiveness = 0.3f;
            public float hitDistanceForgiveness = 0.25f;
            public float minDistanceAIMCheck = 10.0f;
            public float inRockCheckDistance = 200f;
            public bool isDetectAIM = true;
            public bool isDetectNR = true;
            public bool isDetectIR = true;
            public bool debugMessages = true;
            public bool autoSave = true;
            public bool isCheckAIMOnTargetNPC = true;
            public float drawTime = 60f;
            public float NRViolationAngle = 0.3f;
            public float NRViolationScreenDistance = 5f;
            public float playerEyesPositionToProjectileInitialPositionDistanceForgiveness = 10f;
            [JsonProperty(PropertyName = "The maximum allowed value for the physics.steps parameter")]
            public float minPhysicsStepsAllowed = 40f;
            [JsonProperty(PropertyName = "Check players only on the blacklist")]
            public bool checkBlacklist = false;
            [JsonProperty(PropertyName = "Notify when a player has a high value of the physics.steps parameter")]
            public bool notifyPhysicsStepsWarning = false;
            [JsonProperty(PropertyName = "Enable Discord No Recoil Notifications")]
            public bool DiscordNRReportEnabled = false;
            [JsonProperty(PropertyName = "Enable Discord AIMBOT Notifications")]
            public bool DiscordAIMReportEnabled = false;
            [JsonProperty(PropertyName = "Enable Discord In Rock Notifications")]
            public bool DiscordIRReportEnabled = false;
            [JsonProperty(PropertyName = "Discord No Recoil Webhook URL")]
            public string DiscordNRWebhookURL = "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
            [JsonProperty(PropertyName = "Discord AIMBOT Webhook URL")]
            public string DiscordAIMWebhookURL = "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
            [JsonProperty(PropertyName = "Discord In Rock Webhook URL")]
            public string DiscordIRWebhookURL = "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
            [JsonProperty(PropertyName = "AIMBodyParts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> AIMBodyParts = new List<string>() {
                "head", "chest"
            }
            ;
            [JsonProperty(PropertyName = "IRBodyParts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> IRBodyParts = new List<string>() {
                "body", "pelvis", "left knee", "left foot", "left toe", "groin", "hip", "right knee", "right foot", "right toe", "lower spine", "stomach", "chest", "left shoulder", "left arm", "left forearm", "left hand", "left ring finger", "left thumb", "left wrist", "neck", "head", "jaw", "left eye", "right eye", "right shoulder", "right arm", "right forearm", "right hand", "right ring finger", "right thumb", "right wrist"
            }
            ;
            [JsonProperty(PropertyName = "weaponsConfig")]
            public Dictionary<string, WeaponConfig> weaponsConfig = new Dictionary<string, WeaponConfig>() {
                {
                    "rifle.ak", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.09375f, weaponMaxTimeShotsInterval = 0.15625f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
                , {
                    "lmg.m249", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.09375f, weaponMaxTimeShotsInterval = 0.15625f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
                , {
                    "pistol.nailgun", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.09375f, weaponMaxTimeShotsInterval = 0.15625f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
                , {
                    "smg.2", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.09375f, weaponMaxTimeShotsInterval = 0.125f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
                , {
                    "smg.thompson", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.09375f, weaponMaxTimeShotsInterval = 0.15625f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
                , {
                    "smg.mp5", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.0625f, weaponMaxTimeShotsInterval = 0.125f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
                , {
                    "bow.hunting", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                ,  //    {"bow.compound", new WeaponConfig() {NRDetectEnabled = false, AIMDetectEnabled = true}},
                {
                    "crossbow", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "rifle.bolt", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "rifle.l96", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "rifle.m39", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "rifle.semiauto", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "pistol.m92", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "pistol.python", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "pistol.revolver", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "pistol.semiauto", new WeaponConfig() {
                        NRDetectEnabled = false, AIMDetectEnabled = true
                    }
                }
                , {
                    "rifle.lr300", new WeaponConfig() {
                        NRDetectEnabled = true, AIMDetectEnabled = true, weaponMinTimeShotsInterval = 0.09375f, weaponMaxTimeShotsInterval = 0.15625f, NRMinShotsCountToCheck = 5, NRViolationProbability = 70f
                    }
                }
            }
            ;
        }
        private class WeaponConfig {
            public bool NRDetectEnabled;
            public bool AIMDetectEnabled;
            public float weaponMinTimeShotsInterval;
            public float weaponMaxTimeShotsInterval;
            public int NRMinShotsCountToCheck;
            public float NRViolationProbability;
        }
        private class ViolationsLog {
            public ulong steamID;
            public int NoRecoilViolation;
            public int AIMViolation;
            public int InRockViolation;
        }
        private class AdminConfig {
            public ViolationsLog violationsLog = new ViolationsLog();
        }
        private class PlayersViolationsData {
            public int seed;
            public int mapSize;
            public string serverTimeStamp;
            public DateTime lastSaveTime;
            public DateTime lastChangeTime;
            public Dictionary<ulong, PlayerViolationsData> Players = new Dictionary<ulong, PlayerViolationsData>();
        }
        private class PlayerFiredProjectlesData {
            public ulong PlayerID;
            public string PlayerName;
            public float lastFiredTime;
            public float physicsSteps = 32f;
            public SortedDictionary<int, FiredProjectile> firedProjectiles = new SortedDictionary<int, FiredProjectile>();
            public SortedDictionary<uint, MeleeThrown> melees = new SortedDictionary<uint, MeleeThrown>();
            public bool isChecked;
        }
        private class PlayerViolationsData {
            public ulong PlayerID;
            public string PlayerName;
            public SortedDictionary<string, NoRecoilViolationData> noRecoilViolations = new SortedDictionary<string, NoRecoilViolationData>();
            public SortedDictionary<string, AIMViolationData> AIMViolations = new SortedDictionary<string, AIMViolationData>();
            public SortedDictionary<string, InRockViolationsData> inRockViolations = new SortedDictionary<string, InRockViolationsData>();
        }
        private class HitData {
            public ProjectileRicochet hitData;
            public Vector3 startProjectilePosition;
            public Vector3 startProjectileVelocity;
            public Vector3 hitPositionWorld;
            public Vector3 hitPointStart;
            public Vector3 hitPointEnd;
            public bool isHitPointNearProjectileTrajectoryLastSegmentEndPoint = true;
            public bool isHitPointOnProjectileTrajectory = true;
            public bool isProjectileStartPointAtEndReverseProjectileTrajectory = true;
            public bool isHitPointNearProjectilePlane = true;
            public bool isLastSegmentOnProjectileTrajectoryPlane = true;
            public float distanceFromHitPointToProjectilePlane = 0f;
            public int side;
            public Vector3 pointProjectedOnLastSegmentLine;
            public float travelDistance = 0f;
            public float delta = 1f;
            public Vector3 lastSegmentPointStart;
            public Vector3 lastSegmentPointEnd;
            public Vector3 reverseLastSegmentPointStart;
            public Vector3 reverseLastSegmentPointEnd;
        }
        private class AIMViolationData {
            public int projectileID;
            public int violationID;
            public DateTime firedTime;
            public Vector3 startProjectilePosition;
            public Vector3 startProjectileVelocity;
            public string hitInfoInitiatorPlayerName;
            public string hitInfoInitiatorPlayerUserID;
            public string hitInfoHitEntityPlayerName;
            public string hitInfoHitEntityPlayerUserID;
            public string hitInfoBoneName;
            public Vector3 hitInfoHitPositionWorld;
            public float hitInfoProjectileDistance;
            public Vector3 hitInfoPointStart;
            public Vector3 hitInfoPointEnd;
            public float hitInfoProjectilePrefabGravityModifier;
            public float hitInfoProjectilePrefabDrag;
            public string weaponShortName;
            public string ammoShortName;
            public string bodyPart;
            public float damage;
            public bool isEqualFiredProjectileData = true;
            public bool isPlayerPositionToProjectileStartPositionDistanceViolation = false;
            public float distanceDifferenceViolation = 0f;
            public float calculatedTravelDistance;
            public bool isAttackerMount = false;
            public bool isTargetMount = false;
            public string attackerMountParentName;
            public string targetMountParentName;
            public float firedProjectileFiredTime;
            public float firedProjectileTravelTime;
            public Vector3 firedProjectilePosition;
            public Vector3 firedProjectileVelocity;
            public Vector3 firedProjectileInitialPosition;
            public Vector3 firedProjectileInitialVelocity;
            public Vector3 playerEyesLookAt;
            public Vector3 playerEyesPosition;
            public bool hasFiredProjectile = false;
            public List<HitData> hitsData = new List<HitData>();
            public float gravityModifier;
            public float drag;
            public float forgivenessModifier = 1f;
            public float physicsSteps = 32f;
            public List<string> attachments = new List<string>();
        }
        private class NoRecoilViolationData {
            public int ShotsCnt;
            public int NRViolationsCnt;
            public float violationProbability;
            public bool isMounted;
            public Vector3 mountParentPosition;
            public Vector4 mountParentRotation;
            public List<string> attachments = new List<string>();
            public string ammoShortName;
            public string weaponShortName;
            public Dictionary<int, SuspiciousProjectileData> suspiciousNoRecoilShots = new Dictionary<int, SuspiciousProjectileData>();
        }
        private class InRockViolationsData {
            public DateTime dateTime;
            public Dictionary<int, InRockViolationData> inRockViolationsData = new Dictionary<int, InRockViolationData>();
        }
        private class InRockViolationData {
            public DateTime dateTime;
            public float physicsSteps;
            public float targetHitDistance;
            public string targetName;
            public string targetID;
            public float targetDamage;
            public string targetBodyPart;
            public Vector3 targetHitPosition;
            public Vector3 rockHitPosition;
            public FiredProjectile firedProjectile;
            public int projectileID;
            public float drag;
            public float gravityModifier;
        }
        private struct SuspiciousProjectileData {
            public DateTime timeStamp;
            public int projectile1ID;
            public int projectile2ID;
            public float timeInterval;
            public Vector3 projectile1Position;
            public Vector3 projectile2Position;
            public Vector3 projectile1Velocity;
            public Vector3 projectile2Velocity;
            public Vector3 closestPointLine1;
            public Vector3 closestPointLine2;
            public Vector3 prevIntersectionPoint;
            public float recoilAngle;
            public float recoilScreenDistance;
            public bool isNoRecoil;
            public bool isShootedInMotion;
        }
        private class FiredShotsData {
            public string ammoShortName;
            public string weaponShortName;
            public List<string> attachments = new List<string>();
            public SortedDictionary<int, FiredProjectile> firedShots = new SortedDictionary<int, FiredProjectile>();
        }
        private class FiredProjectile {
            public DateTime firedTime;
            public Vector3 projectileVelocity;
            public Vector3 projectilePosition;
            public Vector3 playerEyesLookAt;
            public Vector3 playerEyesPosition;
            public bool isChecked;
            public string ammoShortName;
            public string weaponShortName;
            public uint weaponUID;
            public bool isMounted;
            public string mountParentName;
            public Vector3 mountParentPosition;
            public Vector4 mountParentRotation;
            public List<ProjectileRicochet> hitsData = new List<ProjectileRicochet>();
            public List<string> attachments = new List<string>();
            public float NRProbabilityModifier = 1f;
        }
        private struct MeleeThrown {
            public DateTime firedTime;
            public Vector3 position;
            public Vector3 playerEyesLookAt;
            public Vector3 playerEyesPosition;
            public float projectileVelocity;
            public float drag;
            public float gravityModifier;
            public string meleeShortName;
            public uint meleeUID;
            public bool isMounted;
            public string mountParentName;
            public Vector3 mountParentPosition;
            public Vector4 mountParentRotation;
        }
        private struct ProjectileRicochet {
            public int projectileID;
            public Vector3 hitPosition;
            public Vector3 inVelocity;
            public Vector3 outVelocity;
        }
        private class TrajectorySegment {
            public Vector3 pointStart;
            public Vector3 pointEnd;
        }
        public class EmbedFieldList {
            public string name {
                get;
                set;
            }
            public string value {
                get;
                set;
            }
            public bool inline {
                get;
                set;
            }
        }
#endregion Fields
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["PlayerAIMViolation"]
                = "<color=red><color=green>Arkan:</color> Player <color=yellow>{0}/{1}</color> has possibly AIMBOT violation <color=yellow>#{2}</color>.Target <color=yellow>{3}/{4}</color></color>", ["PlayerAIMViolationCon"] = "Player {0}/{1} has possibly AIMBOT violation #{2}.Target {3}/{4}", ["PlayerIRViolation"] = "<color=red><color=green>Arkan:</color> Player <color=yellow>{0}/{1}</color> has In Rock violation <color=yellow>#{2}</color>.Shots count <color=yellow>{3}</color></color>", ["PlayerIRViolationCon"] = "<color=green>Arkan:</color> Player {0}/{1} has In Rock violation #{2}.Shots count <color=yellow>{3}</color></color>", ["InitPlgText1"] = "Arkan Init: map seed: {0}, map size: {1}, server timestamp: {2}", ["AIMText1"] = "AIMBOT probable violation\n", ["AIMText2"] = "HitPoint is located before line ProjectileTrajectoryLastSegment", ["AIMText3"] = "HitPoint is located behind line ProjectileTrajectoryLastSegment", ["AIMText4"] = "AIMBOT Violation: HitPoint is not located within line ProjectileTrajectoryLastSegment.\nBut HitPoint is located near the plane ProjectilePlane at a distance {0}.{1}, distance to {2} {3}", ["AIMText6"] = "AIMBOT Violation: ProjectileTrajectoryFirstSegments does not match calculated by FiredProjectile data: pointStart = {0} pointEnd = {1}, by HitInfo data: pointStart = {2} pointEnd = {3}\n", ["AIMText7"] = "AIMBOT Violation: HitPoint is not near the plane ProjectilePlane at a distance {0}\n", ["AIMText8"] = "AIMBOT Violation: ProjectileTrajectoryLastSegments does not match calculated by FiredProjectile data: pointStart = {0}, by HitInfo data: pointStart = {1} pointEnd = {2}\n", ["ClearVD"] = "<color=red><color=green>Arkan:</color> Violations data cleared</color>", ["SaveVD1"] = "<color=red><color=green>Arkan:</color> Violation data saved in file <color=yellow>{0}</color></color>", ["LoadVD1"] = "<color=red><color=green>Arkan:</color> File <color=yellow>{0}</color> exist, saved data loaded</color>", ["LoadVD2"] = "Saved data map seed:{0} doesn't match map seed:{1}", ["LoadVD3"] = "Saved data map size:{0} doesn't match map size:{1}", ["LoadVD4"] = "<color=red><color=green>Arkan:</color> File <color=yellow>{0}</color> doesn't exist</color>", ["LogText6"] = "     Distance difference {0}\n", ["LogText7"] = "____Trajectory #{0} check data____", ["LogText8"] = "____Trajectory #{0} data log end____", ["VDataLog"] = "Violation data log", ["ErrorText1"] = "Projectile data collect error: player {0}, missing projectileShoot data", ["ErrorText2"] = "AIMBOT check error: attacker {0}, target {1}, missing ProjectileID: {2}", ["ShowLog1v1.0.13"] = "<size=14><color=orange><color=green>Arkan</color> by Antidote</color></size>\n" + "Commands in chat:\n" + "<color=orange>/arkan</color> - Show all No Recoil/AIMBOT/In Rock violations\n" + "<color=orange>/arkannr</color> - Show all No Recoil violations\n" + "<color=orange>/arkannr SteamID/NAME</color> - Teleport to player's first/next No Recoil violation position\n" + "<color=orange>/arkannr SteamID/NAME 0/num</color> - Teleport to player's first/specific No Recoil violation position\n" + "<color=orange>/arkanaim</color> - Show all AIMBOT violations\n" + "<color=orange>/arkanaim SteamID/NAME</color> - Teleport to player's first/next AIMBOT violation position\n" + "<color=orange>/arkanaim SteamID/NAME 0/num</color> - Teleport to player's first/specific AIMBOT violation position\n" + "<color=orange>/arkanir</color> - Show all In Rock violations\n" + "<color=orange>/arkanir SteamID/NAME</color> - Teleport to player's first/next In Rock violation position\n" + "<color=orange>/arkanir SteamID/NAME 0/num</color> - Teleport to player's first/specific In Rock violation position\n" + "<color=orange>/arkansave, /arkansave filename</color> - Saves all violations to datafile\n" + "<color=orange>/arkanload, /arkanload filename</color> - Loads violations from datafile\n\n", ["ShowLog2"] = "<size=14><color=orange>Players violations list:</color>\n<color=red>", ["ShowLog3"] = "<size=14><color=orange>Players violations list empty", ["ShowInfo"] = "<size=14><color=orange><color=green>Arkan</color> by Antidote</color></size>\n" + "Arkan commands info: <color=orange>/arkaninfo</color>\n\n", ["ShowNRLog2"] = "<size=14><color=orange>Players No Recoil violations list:</color>\n<color=red>", ["ShowNRLog3"] = "<size=14><color=orange>Players No Recoil violations list empty", ["ShowIRLog2"] = "<size=14><color=orange>Players In Rock violations list:</color>\n<color=red>", ["ShowIRLog3"] = "<size=14><color=orange>Players In Rock violations list empty", ["ShowAIMLog2"] = "<size=14><color=orange>Players AIMBOT violations list:</color>\n<color=red>", ["ShowAIMLog3"] = "<size=14><color=orange>Players AIMBOT violations list empty", ["DrawIRVD1"] = "Player <color=yellow>{0}</color>\nIn Rock violation <color=gray>#{1}</color>\nEntity <color=gray>{2}</color>", ["DrawNRVD1"] = "Player <color=yellow>{0}</color>\nAmmo <color=gray>{1}</color>\nWeapon <color=gray>{2}</color>\nShots count <color=gray>{3}</color>\nViolation probability <color=gray>{4}</color>", ["DrawAIMVD3"] = "Target <color=yellow>{0}</color>\nBody part <color=gray>{1}</color>\nDamage <color=gray>{2}</color>", ["DrawAIMVD4"] = "Attacker <color=yellow>{0}</color>\nProjectileID <color=gray>{1}</color>\nAmmo <color=gray>{2}</color>\nWeapon <color=gray>{3}</color>\nDistance <color=gray>{4}</color>", ["DrawAIMVD5"] = "Attacker <color=yellow>{0}</color>, violation <color=gray>#{1}</color>\nPlayer position: <color=gray>{2}</color>\nProjectile start position: <color=gray>{3}</color>\nDistance: <color=gray>{4}</color>", ["ShowD1"] = "Clear current violation number", ["ShowD2"] = "Error.There is no such player in the logs", ["ShowD3"] = "Player {0} has no more positive detections", ["NoMoreViolations"] = "<color=red>Player <color=yellow>{0}</color> has no more positive detections</color>", ["ShowNRD1"] = "Error.Player {0} has no No Recoil violation", ["ShowNRD2"] = "No Recoil violations count: <color=yellow>{0}</color>\n", ["ShowNRD3"] = "Current No Recoil violation number: <color=yellow>{0}</color>", ["ShowIRD1"] = "Error.Player {0} has no In Rock violation", ["ShowIRD2"] = "In Rock violations count: <color=yellow>{0}</color>\n", ["ShowIRD3"] = "Current In Rock violation number: <color=yellow>{0}</color>", ["Player"] = "<color=green>Arkan:</color> <color=red>Player <color=yellow>{0}</color>\n", ["ShowAIMD1"] = "Error.Player {0} has no AIMBOT violation", ["ShowAIMD2"] = "AIMBOT violations count: <color=yellow>{0}</color>\n", ["ShowAIMD3"] = "Current AIMBOT violation number: <color=yellow>{0}</color></color>", ["ClosestPoint"] = "Closest point 1: {0} Closest point 2: {1}, prev {2}", ["StandingShooting"] = "Standing shooting position", ["ShootingOnMove"] = "Shooting on the move", ["FireTimeInterval"] = "Fire time interval {0}", ["ProjectileID"] = "Projectile ID: {0}", ["PlayerTxt"] = "Player", ["Probability"] = "Probability", ["ShotsCount"] = "Shots count", ["AttachmentsCount"] = "Attachments count", ["Attachment"] = "Attachment", ["Weapon"] = "Weapon", ["Ammo"] = "Ammo", ["NoAttachments"] = "No attachments", ["Attacker"] = "Attacker", ["Target"] = "Target", ["HitPart"] = "Hit part", ["RecoilAngle"] = "Recoil angle: {0}", ["Distance"] = "Distance", ["Damage"] = "Damage", ["NRDetection"] = "No Recoil probable violation", ["IRDetection"] = "In Rock violation", ["DistanceToFirstPoint"] = "Distance to first point: {0}", ["ScreenCoords"] = "Screen coords point1: {0}, coords point2: {1}", ["NRViolationNum"] = "NR violation #", ["AIMViolationNum"] = "AIMBOT violation #", ["IRViolationNum"] = "IR violation #", ["AIMDetection"] = "AIMBOT probable violation", ["DateTime"] = "Date/Time", ["MountedOn"] = "Attacker mounted on {0}", ["RicochetsCount"] = "Ricochets count", ["DistanceBetweenTwoPoints"] = "Distance between two points: {0}", ["HighPhysicsStepsDetection"] = "Detected high value of the physics.steps parameter", ["PhysicsStepsChangeWarning"] = "Player {0} probably changed the value of the physics.steps parameter to ~{1}({2}).The default value for physics.steps is 32.\nChanging the value of this parameter to a higher value allows the player to gain advantages over normal game play (allows jumping higher).", ["Description"] = "Description", ["DiscordWarning2"] = "Error: Discord reports enabled but plugin DiscordMessages not loaded!", ["DiscordWarningNR"] = "Error: Discord No Recoil reports enabled but webhook for No Recoil violation is not configured!", ["DiscordWarningAIM"] = "Error: Discord AIMBOT reports enabled but webhook for AIMBOT violation is not configured!", ["DiscordWarningIR"] = "Error: Discord In Rock reports enabled but webhook for In Rock violation is not configured!", ["PlayerNRViolation"] = "<size=14><color=red><color=green>Arkan:</color> Player <color=yellow>{0}/{1}</color> has possibly No Recoil violation <color=yellow>#{2}</color>\ntotal shots cnt: <color=yellow>{3}</color> | shots with low recoil cnt: <color=yellow>{4}</color>\nprobability: <color=yellow>{5}%</color></color></size>", ["PlayerNRViolationCon"] = "Arkan: Player {0}/{1} has possibly No Recoil violation #{2}\ntotal shots cnt: {3} | shots with low recoil cnt: {4}\nprobability: {5}",
            }
            , this, "en");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["PlayerAIMViolation"]
                = "<color=red><color=green>Arkan:</color> У игрока <color=yellow>{0}/{1}</color> обнаружено возможное нарушение AIM <color=yellow>#{2}</color>.Жертва <color=yellow>{3}/{4}</color></color>", ["PlayerAIMViolationCon"] = "У игрока {0}/{1} обнаружено возможное нарушение AIM #{2}.Жертва {3}/{4}", ["PlayerIRViolation"] = "<color=red><color=green>Arkan:</color> У игрока <color=yellow>{0}/{1}</color> обнаружено нарушение In Rock <color=yellow>#{2}</color>.Количество выстрелов <color=yellow>{3}</color></color>", ["PlayerIRViolationCon"] = "<color=green>Arkan:</color> У игрока {0}/{1} обнаружено нарушение In Rock #{2}.Количество выстрелов <color=yellow>{3}</color></color>", ["InitPlgText1"] = "Arkan Init: сид карты: {0}, размер карты: {1}, timestamp сервера: {2}", ["AIMText1"] = "Вероятное нарушение AIMBOT\n", ["AIMText2"] = "HitPoint расположен перед сегментом траектории ProjectileTrajectoryLastSegment", ["AIMText3"] = "HitPoint расположен за сегментом траектории ProjectileTrajectoryLastSegment", ["AIMText4"] = "AIMBOT Нарушение: HitPoint расположен вне сегмента траектории ProjectileTrajectoryLastSegment.\nНо HitPoint расположен недалеко от плоскости ProjectilePlane на расстоянии {0}.{1}, дистанция к {2} {3}", ["AIMText6"] = "AIMBOT Нарушение: ProjectileTrajectoryFirstSegments не соответствует рассчитанным данным FiredProjectile: pointStart = {0} pointEnd = {1}, по данным HitInfo: pointStart = {2} pointEnd = {3}\n", ["AIMText7"] = "AIMBOT Нарушение: HitPoint расположен слишком далеко от плоскости ProjectilePlane на расстоянии {0}\n", ["AIMText8"] = "AIMBOT Нарушение: ProjectileTrajectoryLastSegments не соответствует рассчитанным данным FiredProjectile: pointStart = {0}, по данным HitInfo: pointStart = {1} pointEnd = {2}\n", ["ClearVD"] = "<color=red><color=green>Arkan:</color> Данные нарушений очищены</color>", ["SaveVD1"] = "<color=red><color=green>Arkan:</color> Данные нарушений сохранены в файл <color=yellow>{0}</color></color>", ["LoadVD1"] = "<color=red><color=green>Arkan:</color> Файл <color=yellow>{0}</color> существует, сохранненые в нем данные загружены</color>", ["LoadVD2"] = "В загружаемом лог-файле сид карты:{0} не соответствует сиду карты на сервере:{1}", ["LoadVD3"] = "В загружаемом лог-файле размер карты:{0} не соответствует размеру карты на сервере:{1}", ["LoadVD4"] = "<color=red><color=green>Arkan:</color> Файл <color=yellow>{0}</color> не существует</color>", ["LogText6"] = "     Разница расстояния {0}\n", ["LogText7"] = "____Данные проверки траектории #{0}____", ["LogText8"] = "____Конец данных лога проверки траектории #{0}____", ["VDataLog"] = "Лог данных нарушения", ["ErrorText1"] = "Ошибка при сборе данных снаряда: игрок {0}, отсутствуют данные projectileShoot", ["ErrorText2"] = "Ошибка при проверке AIMBOT: атакующий {0}, жертва {1}, пропущен ProjectileID: {2}", ["ShowLog1v1.0.13"] = "<size=14><color=orange><color=green>Arkan</color> by Antidote</color></size>\n" + "Команды в чат:\n" + "<color=orange>/arkan</color> - Показывает список всех No Recoil/AIMBOT/In Rock нарушений\n" + "<color=orange>/arkannr</color> - Показывает список всех No Recoil нарушений\n" + "<color=orange>/arkannr SteamID/NAME</color> - Телепортирует на первую/следующую позицию нарушения No Recoil игрока\n" + "<color=orange>/arkannr SteamID/NAME 0/num</color> - Телепортирует на первую/определенную позицию нарушения No Recoil игрока\n" + "<color=orange>/arkanaim</color> - Показывает список всех AIMBOT нарушений\n" + "<color=orange>/arkanaim SteamID/NAME</color> - Телепортирует на первую/следующую позицию нарушения AIMBOT игрока\n" + "<color=orange>/arkanaim SteamID/NAME 0/num</color> - Телепортирует на первую/определенную позицию нарушения AIMBOT игрока\n" + "<color=orange>/arkanir</color> - Показывает список всех In Rock нарушений\n" + "<color=orange>/arkanir SteamID/NAME</color> - Телепортирует на первую/следующую позицию нарушения In Rock игрока\n" + "<color=orange>/arkanir SteamID/NAME 0/num</color> - Телепортирует на первую/определенную позицию нарушения No Recoil игрока\n" + "<color=orange>/arkansave, /arkansave filename</color> - Сохраняет все данные нарушений в файл\n" + "<color=orange>/arkanload, /arkanload filename</color> - Загружает сохраненные данные нарушений из файла\n\n", ["ShowLog2"] = "<size=14><color=orange>Список нарушений игроков:</color>\n<color=red>", ["ShowLog3"] = "<size=14><color=orange>Список нарушений игрока пуст", ["ShowInfo"] = "<size=14><color=orange><color=green>Arkan</color> by Antidote</color></size>\n" + "Инфо по командам Arkan: <color=orange>/arkaninfo</color>\n\n", ["ShowNRLog2"] = "<size=14><color=orange>Список нарушений No Recoil игроков:</color>\n<color=red>", ["ShowNRLog3"] = "<size=14><color=orange>Список нарушений No Recoil игрока пуст", ["ShowIRLog2"] = "<size=14><color=orange>Список нарушений In Rock игроков:</color>\n<color=red>", ["ShowIRLog3"] = "<size=14><color=orange>Список нарушений In Rock игрока пуст", ["ShowAIMLog2"] = "<size=14><color=orange>Список нарушений AIMBOT игроков:</color>\n<color=red>", ["ShowAIMLog3"] = "<size=14><color=orange>Список нарушений AIMBOT игрока пуст", ["DrawIRVD1"] = "Игрок <color=yellow>{0}</color>\nIn Rock нарушение <color=gray>#{1}</color>\nОбъект <color=gray>{2}</color>", ["DrawNRVD1"] = "Игрок <color=yellow>{0}</color>\nАммо <color=gray>{1}</color>\nОружие <color=gray>{2}</color>\nКоличество выстрелов <color=gray>{3}</color>\nВероятность нарушения <color=gray>{4}</color>", ["DrawAIMVD3"] = "Жертва <color=yellow>{0}</color>\nЧасть тела <color=gray>{1}</color>\nПовреждение <color=gray>{2}</color>", ["DrawAIMVD4"] = "Атакующий <color=yellow>{0}</color>\nProjectileID <color=gray>{1}</color>\nАммо <color=gray>{2}</color>\nОружие <color=gray>{3}</color>\nРасстояние <color=gray>{4}</color>", ["DrawAIMVD5"] = "Атакующий <color=yellow>{0}</color>, нарушение <color=gray>#{1}</color>\nПозиция игрока: <color=gray>{2}</color>\nТочка старта снаряда: <color=gray>{3}</color>\nРасстояние: <color=gray>{4}</color>", ["ShowD1"] = "Номер текущего нарушения сброшен", ["ShowD2"] = "Ошибка.Такого игрока нет в логах", ["ShowD3"] = "У игрока {0} нет больше нарушений", ["NoMoreViolations"] = "<color=red>У игрока <color=yellow>{0}</color> нет больше нарушений</color>", ["ShowNRD1"] = "Ошибка.У игрока {0} нет нарушения No Recoil", ["ShowNRD2"] = "Количество нарушений No Recoil: <color=yellow>{0}</color>\n", ["ShowNRD3"] = "Номер текущего нарушения No Recoil: <color=yellow>{0}</color>", ["ShowIRD1"] = "Ошибка.У игрока {0} нет нарушения In Rock", ["ShowIRD2"] = "Количество нарушений In Rock: <color=yellow>{0}</color>\n", ["ShowIRD3"] = "Номер текущего нарушения In Rock: <color=yellow>{0}</color>", ["Player"] = "<color=green>Arkan:</color> <color=red>Игрок <color=yellow>{0}</color>\n", ["ShowAIMD1"] = "Ошибка.У игрока {0} нет нарушения AIMBOT", ["ShowAIMD2"] = "Количество нарушений AIMBOT: <color=yellow>{0}</color>\n", ["ShowAIMD3"] = "Номер текущего нарушения AIMBOT: <color=yellow>{0}</color></color>", ["ClosestPoint"] = "Ближайшая точка 1: {0} Ближайшая точка 2: {1}, Предыдущая ближайшая точка {2}", ["StandingShooting"] = "Стрельба из положения стоя", ["ShootingOnMove"] = "Стрельба в движении", ["FireTimeInterval"] = "Интервал между выстрелами {0}", ["ProjectileID"] = "ID снаряда: {0}", ["PlayerTxt"] = "Игрок", ["Probability"] = "Вероятность", ["ShotsCount"] = "Количество выстрелов", ["Weapon"] = "Оружие", ["Ammo"] = "Боеприпас", ["AttachmentsCount"] = "Количество навески", ["Attachment"] = "Навеска", ["NoAttachments"] = "Нет навески", ["Attacker"] = "Атакующий", ["Target"] = "Жертва", ["HitPart"] = "Место попадания", ["RecoilAngle"] = "Угол отдачи: {0}", ["Distance"] = "Расстояние", ["Damage"] = "Урон", ["NRDetection"] = "Вероятное нарушение No Recoil", ["IRDetection"] = "Нарушение In Rock", ["DistanceToFirstPoint"] = "Расстояние до первой точки: {0}", ["ScreenCoords"] = "Экранные координаты точки point1: {0}, экранные координаты точки point2: {1}", ["NRViolationNum"] = "Нарушение NR #", ["AIMViolationNum"] = "Нарушение AIMBOT #", ["IRViolationNum"] = "Нарушение IR #", ["AIMDetection"] = "Вероятное нарушение AIMBOT", ["DateTime"] = "Дата/Время", ["MountedOn"] = "Атакующий состыкован с {0}", ["RicochetsCount"] = "Количество рикошетов", ["DistanceBetweenTwoPoints"] = "Расстояние между двумя точками: {0}", ["HighPhysicsStepsDetection"] = "Обнаружено высокое значение параметра physics.steps", ["PhysicsStepsChangeWarning"] = "Игрок {0} вероятно изменил значение параметра physics.steps на ~{1}({2}).Значение по умолчанию для physics.steps 32.\nИзменение значения этого параметра на более высокое значение позволяет игроку получить преимущества по сравнению с обычной игрой (позволяет прыгать выше).", ["Description"] = "Описание", ["DiscordWarning2"] = "Ошибка: Отправка отчетов в дискорд включена, только плагин DiscordMessages не загружен!", ["DiscordWarningNR"] = "Ошибка: Отправка отчетов No Recoil в дискорд включена, только webhook дискорда для нарушения No Recoil не настроен!", ["DiscordWarningAIM"] = "Ошибка: Отправка отчетов AIMBOT в дискорд включена, только webhook дискорда для нарушения AIMBOT не настроен!", ["DiscordWarningIR"] = "Ошибка: Отправка отчетов In Rock в дискорд включена, только webhook дискорда для нарушения In Rock не настроен!", ["PlayerNRViolation"] = "<size=14><color=red><color=green>Arkan:</color> У игрока <color=yellow>{0}/{1}</color> обнаружено возможное нарушение No Recoil <color=yellow>#{2}</color>\nобщее количество выстрелов: <color=yellow>{3}</color> | количество выстрелов с низкой отдачей: <color=yellow>{4}</color>\nвероятность: <color=yellow>{5}%</color></color></size>", ["PlayerNRViolationCon"] = "У игрока {0}/{1} обнаружено возможное нарушение No Recoil #{2}\nобщее количество выстрелов: {3} | количество выстрелов с низкой отдачей: {4}\nвероятность: {5}",
            }
            , this, "ru");
        }
#endregion Localization
#region Initialization & Loading
        private void Init() {
            //LoadVariables();
            LoadConfig();
            Unsubscribe(nameof(OnPlayerAttack));
            Unsubscribe(nameof(OnMeleeThrown));
            Unsubscribe(nameof(OnProjectileRicochet));
            Unsubscribe(nameof(OnWeaponFired));
            Unsubscribe(nameof(OnEntityTakeDamage));
            Unsubscribe(nameof(OnItemPickup));
            if (_config.DiscordNRWebhookURL == "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks" && _config.DiscordNRReportEnabled) {
                PrintWarning(Lang("DiscordWarningNR", null));
                _config.DiscordNRReportEnabled = false;
            }
            if (_config.DiscordAIMWebhookURL == "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks" && _config.DiscordAIMReportEnabled) {
                PrintWarning(Lang("DiscordWarningAIM", null));
                _config.DiscordAIMReportEnabled = false;
            }
            if (_config.DiscordIRWebhookURL == "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks" && _config.DiscordIRReportEnabled) {
                PrintWarning(Lang("DiscordWarningIR", null));
                _config.DiscordIRReportEnabled = false;
            }
        }
        private void OnServerInitialized() {
            if (_config.isDetectNR) Subscribe(nameof(OnWeaponFired));
            if (_config.isDetectAIM) {
                Subscribe(nameof(OnPlayerAttack));
                Subscribe(nameof(OnMeleeThrown));
                Subscribe(nameof(OnProjectileRicochet));
                Subscribe(nameof(OnWeaponFired));
                Subscribe(nameof(OnEntityTakeDamage));
                Subscribe(nameof(OnItemPickup));
            }
            DateTime currentDate = DateTime.Now.AddSeconds(-UnityEngine.Time.realtimeSinceStartup);
            serverTimeStamp = currentDate.Year + "." + currentDate.Month + "." + currentDate.Day + "." + currentDate.Hour + "." + currentDate.Minute;
            PlayersViolations.seed = ConVar.Server.seed;
            PlayersViolations.mapSize = ConVar.Server.worldsize;
            PlayersViolations.serverTimeStamp = serverTimeStamp;
            LoadViolationsData(null, null, null);
            Puts(Lang("InitPlgText1", null, PlayersViolations.seed, PlayersViolations.mapSize, PlayersViolations.serverTimeStamp));
            foreach (var _player in BasePlayer.activePlayerList.Where(x => x.IsAdmin && permission.UserHasPermission(x.UserIDString, permName))) AdminLogInit(_player);
            if ((_config.DiscordNRReportEnabled || _config.DiscordAIMReportEnabled || _config.DiscordIRReportEnabled) && DiscordMessages == null) PrintWarning(Lang("DiscordWarning2", null));
        }
        void OnPlayerConnected(BasePlayer player) {
            if (player != null) {
                if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, permName)) return;
                AdminLogInit(player);
            }
        }
#endregion Initialization & Loading
#region Helpers
        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
        public string RemoveFormatting(string source) => source.Contains(">") ? Regex.Replace(source, "<.*?>", string.Empty) : source;
#endregion Helpers
#region Oxide Hooks
        private void Unload() {
            if (PlayersViolations.lastChangeTime > PlayersViolations.lastSaveTime) SaveViolationsData(null, null, null);
            PlayersFiredProjectlesData.Clear();
            AdminsConfig.Clear();
            _config.weaponsConfig.Clear();
            _config.AIMBodyParts.Clear();
            _config.IRBodyParts.Clear();
            _config = null;
        }
        private void Loaded() {
            permission.RegisterPermission(permName, this);
            permission.RegisterPermission(permNRDrawViolation, this);
            permission.RegisterPermission(permAIMDrawViolation, this);
            permission.RegisterPermission(permIRDrawViolation, this);
            permission.RegisterPermission(permNRReportChat, this);
            permission.RegisterPermission(permNRReportConsole, this);
            permission.RegisterPermission(permAIMReportChat, this);
            permission.RegisterPermission(permAIMReportConsole, this);
            permission.RegisterPermission(permIRReportChat, this);
            permission.RegisterPermission(permIRReportConsole, this);
            permission.RegisterPermission(permNRWhitelist, this);
            permission.RegisterPermission(permNRBlacklist, this);
            permission.RegisterPermission(permAIMWhitelist, this);
            permission.RegisterPermission(permAIMBlacklist, this);
            permission.RegisterPermission(permIRWhitelist, this);
            permission.RegisterPermission(permIRBlacklist, this);
            LoadViolationsData(null, null, null);
        }
        private void OnServerSave() {
            if (_config.autoSave && PlayersViolations.lastChangeTime > PlayersViolations.lastSaveTime) SaveViolationsData(null, null, null);
        }
        private void OnPlayerAttack(BasePlayer attacker, HitInfo info) {
            if (attacker == null || info.Weapon == null) return;
            if (_config.checkBlacklist) {
                if (!(permission.UserHasPermission(attacker.UserIDString, permNRBlacklist) || permission.UserHasPermission(attacker.UserIDString, permAIMBlacklist))) return;
            }
            else if (permission.UserHasPermission(attacker.UserIDString, permNRWhitelist) || permission.UserHasPermission(attacker.UserIDString, permAIMWhitelist)) return;
            if (PlayersFiredProjectlesData.ContainsKey(attacker.userID)) {
                if (PlayersFiredProjectlesData[attacker.userID].firedProjectiles.ContainsKey(info.ProjectileID)) {
                    PlayersFiredProjectlesData[attacker.userID].firedProjectiles[info.ProjectileID].hitsData.Add(new ProjectileRicochet());
                    ProjectileRicochet pr;
                    pr.projectileID = info.ProjectileID;
                    pr.hitPosition = info.HitPositionWorld;
                    pr.inVelocity = (info.PointEnd - info.PointStart) * PlayersFiredProjectlesData[attacker.userID].physicsSteps;
                    pr.outVelocity = info.ProjectileVelocity;
                    PlayersFiredProjectlesData[attacker.userID].firedProjectiles[info.ProjectileID].hitsData[PlayersFiredProjectlesData[attacker.userID].firedProjectiles[info.ProjectileID].hitsData.Count - 1] = pr;
                }
            }
            //for development purposes only
            if (isAttackShow) {
                BaseMelee component = info.Weapon.GetComponent<BaseMelee>();
                FiredProjectile fp;
                if (component == null) {
                    foreach (var _player in BasePlayer.activePlayerList.Where(x => x.IsAdmin && permission.UserHasPermission(x.UserIDString, permName))) foreach (KeyValuePair<ulong, PlayerFiredProjectlesData> list in PlayersFiredProjectlesData) if (PlayersFiredProjectlesData[list.Key].firedProjectiles.TryGetValue(info.ProjectileID, out fp)) DrawProjectileTrajectory2(_player, _config.drawTime, fp, info, Color.blue, PlayersFiredProjectlesData[list.Key].physicsSteps);
                }
            }
        }
        private void OnMeleeThrown(BasePlayer player, Item item) {
            if (player == null || item == null) return;
            if (_config.checkBlacklist) {
                if (!(permission.UserHasPermission(player.UserIDString, permNRBlacklist) || permission.UserHasPermission(player.UserIDString, permAIMBlacklist))) return;
            }
            else if (permission.UserHasPermission(player.UserIDString, permNRWhitelist) || permission.UserHasPermission(player.UserIDString, permAIMWhite
// ... [Code preview truncated due to length. Full source in attached file] ...

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