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

FREE SpeedHackDetector : 0.0.0 0.0.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//  ######
//  #     #
//  #     #
//  ######
//  #   #
//  #    #
//  #     #
//
//  #     #
//  #     #
//  #     #
//  #     #
//  #     #
//  #     #
//   #####
//
//   #####
//  #     #
//  #
//   #####
//        #
//  #     #
//   #####
//
//  #######
//     #
//     #
//     #
//     #
//     #
//     #
//
//   ####  #####    ##   #####  ######   ####
//  #      #    #  #  #  #    # #    #  #    #
//   ####  #    # #    # #    # #    #  #    #
//       # #    # ###### #####  ######  #    #
//  #    # #    # #    # #      #   #   #    #  Creator
//   ####  #####  #    # #      #    #   ####
//  Плагин создан специально для RustWin 2.0 x1000000 Упрощает работу модератору! не детектит стим игроков!
using UnityEngine;
using System;
using System.Linq;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Oxide.Plugins {
    [Info("SpeedHackDetector", "sdapro", "0.0.0")]
    public class SpeedHackDetector : RustPlugin {
        private const float MAX_LEFT_SPEED = 4.7f;
        private const float MAX_RIGHT_SPEED = 4.7f;
        private const float MAX_BACK_SPEED = 4.7f;
        private const float MAX_BACK_LEFT_SPEED = 4.7f;
        private const float MAX_BACK_RIGHT_SPEED = 4.7f;
        private const float CHECK_INTERVAL = 0.1f;
        private const string PERMISSION_ADMIN = "speedhackdetector.admin";
        // Это право дает показ модеру или админу что тип ебаный флеш
        private const string STEAM_API_KEY = "API Ключик из стима";
        private const int MIN_STEAM_LEVEL = 0;
        private const int MIN_STEAM_DAYS = 10;
        [PluginReference]
        private Plugin MultiFighting;
        [PluginReference]
        private Plugin NTeleportation;
        private class PlayerData {
            public Vector3 LastPosition;
            public Vector3 LastSafePosition;
            public float LastCheck;
            public bool WasViolated;
            public float JoinTime;
            public bool IsChecked;
            public float TotalPlayTime {
                get;
                set;
            }
            public float LastSessionUpdate {
                get;
                set;
            }
            public float LastYRotation;
            public float FreezeEndTime;
            public bool IsFrozen;
            public float LastDismountTime;
            public float LastRespawnTime;
        }
        private Dictionary<ulong, PlayerData> _playerData = new Dictionary<ulong, PlayerData>();
        void Init() {
            permission.RegisterPermission(PERMISSION_ADMIN, this);
        }
        private bool IsSteam(string id) {
            if (MultiFighting == null) return true;
            BasePlayer player = BasePlayer.Find(id);
            if (player == null) return false;
            object obj = MultiFighting.CallHook("IsSteam", player.Connection);
            return obj is bool ? (bool)obj : false;
        }
        void OnPlayerConnected(BasePlayer player) {
            if (!_playerData.ContainsKey(player.userID)) {
                _playerData[player.userID] = new PlayerData {
                    LastPosition = player.transform.position, LastSafePosition = player.transform.position, LastCheck = Time.time, WasViolated = false, JoinTime = Time.time, IsChecked = false, TotalPlayTime = 0f, LastSessionUpdate = Time.time, LastYRotation = player.eyes.rotation.eulerAngles.y, FreezeEndTime = 0f, IsFrozen = false, LastDismountTime = 0f, LastRespawnTime = 0f
                }
                ;
                timer.Once(2f, () => CheckAccount(player));
            }
        }
        void OnServerInitialized() {
            timer.Once(5f, () => {
                foreach (var player in BasePlayer.activePlayerList) {
                    if (!IsSteam(player.UserIDString)) {
                        CheckAccount(player);
                    }
                }
            }
            );
        }
        private void CheckAccount(BasePlayer player) {
            if (player == null || !player.IsConnected) return;
            if (IsSteam(player.UserIDString)) return;
            webrequest.Enqueue($"https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key={STEAM_API_KEY}&steamids={player.UserIDString}", null, (code, response) => {
                if (code != 200) return;
                var json = JsonConvert.DeserializeObject<JObject>(response);
                var players = json["response"]["players"].ToList();
                if (players.Count == 0) return;
                var profile = players[0];
                var createdTime = profile["timecreated"]?.Value<long>() ?? 0;
                var communityVisibilityState = profile["communityvisibilitystate"]?.Value<int>() ?? 1;
                bool isPrivate = communityVisibilityState != 3;
                webrequest.Enqueue($"https://api.steampowered.com/IPlayerService/GetSteamLevel/v1/?key={STEAM_API_KEY}&steamid={player.UserIDString}", null, (levelCode, levelResponse) => {
                    if (levelCode != 200) return;
                    var levelJson = JsonConvert.DeserializeObject<JObject>(levelResponse);
                    var steamLevel = levelJson["response"]["player_level"]?.Value<int>() ?? 0;
                    if (createdTime > 0) {
                        var creationDate = DateTimeOffset.FromUnixTimeSeconds(createdTime).UtcDateTime;
                        var accountAge = DateTime.UtcNow - creationDate;
                        var daysOld = (int)accountAge.TotalDays;
                        string message = $"\n<color=#ff0000>Обнаружен пиратский аккаунт!</color>\n" + $"Имя: <color=#00ffff>{player.displayName}</color>\n" + $"SteamID: <color=#00ffff>{player.UserIDString}</color>\n" + $"Профиль: {(isPrivate ? "<color=#ff0000>Приватный</color>" : "<color=#00ff00>Публичный</color>")}\n" + $"Уровень Steam: <color=#00ffff>{steamLevel}</color>\n" + $"Возраст аккаунта: <color=#00ffff>{daysOld} дней</color>";
                        if (isPrivate) {
                            message += "\n<color=#ff0000>Игрок будет кикнут за приватный профиль</color>";
                            timer.Once(0.5f, () => player.Kick("Ваш профиль Steam не может быть приватным на этом сервере"));
                        }
                        else if (steamLevel < MIN_STEAM_LEVEL) {
                            message += "\n<color=#ff0000>Игрок будет кикнут за низкий уровень Steam</color>";
                            timer.Once(0.5f, () => player.Kick($"Требуется минимум {MIN_STEAM_LEVEL} уровень Steam"));
                        }
                        else if (daysOld < MIN_STEAM_DAYS) {
                            message += "\n<color=#ff0000>Игрок будет кикнут за новый аккаунт</color>";
                            timer.Once(0.5f, () => player.Kick($"Ваш аккаунт слишком новый.Требуется аккаунт старше {MIN_STEAM_DAYS} дней"));
                        }
                        foreach (var admin in BasePlayer.activePlayerList.Where(p => permission.UserHasPermission(p.UserIDString, PERMISSION_ADMIN))) {
                            admin.ChatMessage(message);
                            admin.Command("note.play", "assets/prefabs/misc/summer_dlc/boom_box/effects/boombox-deploy.prefab");
                        }
                    }
                }
                , this );
            }
            , this );
        }
        void OnPlayerTick(BasePlayer player) {
            if (player == null || !player.IsConnected || player.IsSleeping() || player.IsSpectating() || player.isMounted || !player.IsOnGround() || player.IsFlying || player.IsSwimming() || player.modelState.onLadder) return;
            if (IsSteam(player.UserIDString)) return;
            if (NTeleportation != null) {
                object isTeleporting = NTeleportation.Call("IsTeleporting", player);
                if (isTeleporting is bool && (bool)isTeleporting) {
                    return;
                }
            }
            if (_playerData.TryGetValue(player.userID, out var playerData) && Time.time - playerData.LastRespawnTime < 5f) {
                playerData.LastPosition = player.transform.position;
                playerData.LastCheck = Time.time;
                return;
            }
            bool isOnMovingPlatform = false;
            RaycastHit hit;
            if (Physics.Raycast(player.transform.position + Vector3.up * 0.1f, Vector3.down, out hit, 0.3f)) {
                BaseEntity entity = hit.GetEntity();
                if (entity != null) {
                    BaseEntity currentEntity = entity;
                    while (currentEntity != null) {
                        if (currentEntity.ShortPrefabName.Contains("cargo") || currentEntity.ShortPrefabName.Contains("heli") || currentEntity.ShortPrefabName.Contains("car") || currentEntity.ShortPrefabName.Contains("boat") || currentEntity is HotAirBalloon) {
                            isOnMovingPlatform = true;
                            break;
                        }
                        currentEntity = currentEntity.GetParentEntity();
                    }
                }
            }
            if (!_playerData.ContainsKey(player.userID)) {
                _playerData[player.userID] = new PlayerData {
                    LastPosition = player.transform.position, LastSafePosition = player.transform.position, LastCheck = Time.time, WasViolated = false, JoinTime = Time.time, IsChecked = false, TotalPlayTime = 0f, LastSessionUpdate = Time.time, LastYRotation = player.eyes.rotation.eulerAngles.y, FreezeEndTime = 0f, IsFrozen = false, LastDismountTime = 0f, LastRespawnTime = 0f
                }
                ;
                return;
            }
            var data = _playerData[player.userID];
            float deltaTime = Time.time - data.LastCheck;
            if (isOnMovingPlatform) {
                data.LastPosition = player.transform.position;
                data.LastCheck = Time.time;
                return;
            }
            bool isOnPrefab = false;
            if (Physics.Raycast(player.transform.position + Vector3.up * 0.1f, Vector3.down, out hit, 0.3f, LayerMask.GetMask("Construction", "Deployable"))) {
                isOnPrefab = true;
            }
            if (Time.time - data.LastDismountTime < 3f) {
                data.LastPosition = player.transform.position;
                data.LastCheck = Time.time;
                return;
            }
            if (deltaTime < CHECK_INTERVAL) return;
            Vector3 movement = (player.transform.position - data.LastPosition) / deltaTime;
            movement.y = 0;
            Vector3 forward = player.eyes.BodyForward();
            forward.y = 0;
            forward.Normalize();
            Vector3 right = Vector3.Cross(Vector3.up, forward);
            float forwardSpeed = Vector3.Dot(movement, forward);
            float rightSpeed = Vector3.Dot(movement, right);
            float currentYRotation = player.eyes.rotation.eulerAngles.y;
            float rotationSpeed = Mathf.Abs(Mathf.DeltaAngle(currentYRotation, data.LastYRotation)) / deltaTime;
            data.LastYRotation = currentYRotation;
            float rotationSpeedBonus = rotationSpeed > 100f ? 3f : 0f;
            float prefabSpeedBonus = isOnPrefab ? 2f : 0f;
            float adjustedMaxSpeed = MAX_LEFT_SPEED + rotationSpeedBonus + prefabSpeedBonus;
            float adjustedMaxBackSpeed = MAX_BACK_SPEED + rotationSpeedBonus + prefabSpeedBonus;
            bool isViolating = false;
            string violationType = "";
            float violationSpeed = 0f;
            float maxAllowedSpeed = 0f;
            if (forwardSpeed > 0) {
                data.LastPosition = player.transform.position;
                data.LastCheck = Time.time;
                return;
            }
            if (forwardSpeed < 0) {
                float backSpeed = Mathf.Abs(forwardSpeed);
                if (backSpeed > adjustedMaxBackSpeed) {
                    isViolating = true;
                    violationType = "назад";
                    violationSpeed = backSpeed;
                    maxAllowedSpeed = adjustedMaxBackSpeed;
                }
            }
            if (!isViolating && Mathf.Abs(rightSpeed) > adjustedMaxSpeed) {
                isViolating = true;
                violationType = rightSpeed > 0 ? "вправо" : "влево";
                violationSpeed = Mathf.Abs(rightSpeed);
                maxAllowedSpeed = adjustedMaxSpeed;
            }
            if (data.WasViolated) {
                data.WasViolated = false;
                data.LastPosition = player.transform.position;
                data.LastCheck = Time.time;
                return;
            }
            if (isViolating && !data.IsFrozen) {
                UpdateSessionTime(player, data);
                TimeSpan sessionTime = TimeSpan.FromSeconds(player.Connection.GetSecondsConnected());
                string accountType = IsSteam(player.UserIDString) ? "<color=#00ff00>STEAM</color>" : "<color=#ff0000>ПИРАТ</color>";
                string message = $"\n<color=#ff0000>Обнаружен SpeedHack!</color>\n" + $"Игрок: <color=#00ffff>{player.displayName}</color>\n" + $"Тип аккаунта: {accountType}\n" + $"Текущая сессия: {sessionTime.Hours}ч {sessionTime.Minutes}м {sessionTime.Seconds}с\n" + $"Всего на сервере: {FormatTimeSpan(data.TotalPlayTime)}\n" + $"Тип движения: <color=#ff0000>{violationType}</color>\n" + $"Скорость: <color=#ff0000>{violationSpeed:F1} м/с</color>\n" + $"Макс.допустимая: <color=#00ff00>{maxAllowedSpeed:F1} м/с</color>";
                foreach (var admin in BasePlayer.activePlayerList.Where(p => permission.UserHasPermission(p.UserIDString, PERMISSION_ADMIN))) {
                    admin.ChatMessage(message);
                    admin.Command("note.play", "assets/prefabs/misc/summer_dlc/boom_box/effects/boombox-deploy.prefab");
                }
                // //Фризить игрока!
                //data.IsFrozen = true;
                // data.FreezeEndTime = Time.time + 1f;
                data.WasViolated = true;
                //player.ClientRPCPlayer(null, player, "ForcePositionTo", player.transform.position);
                //player.SendNetworkUpdate();
            }
            //Фризить игрока!
            // else if (data.IsFrozen)
            // {
            //    if (Time.time >= data.FreezeEndTime)
            //    {
            //        data.IsFrozen = false;
            //      data.WasViolated = false;
            //  }
            //   else
            //   {
            // Продолжаем удерживать игрока на месте
            //       player.ClientRPCPlayer(null, player, "ForcePositionTo", player.transform.position);
            //   }
            // }
            if (!data.IsFrozen) {
                data.LastSafePosition = player.transform.position;
                data.LastPosition = player.transform.position;
            }
            data.LastCheck = Time.time;
        }
        [ChatCommand("checkspeed")]
        private void CmdCheckSpeed(BasePlayer player, string command, string[] args) {
            if (!_playerData.ContainsKey(player.userID)) return;
            var data = _playerData[player.userID];
            float deltaTime = Time.time - data.LastCheck;
            Vector3 movement = (player.transform.position - data.LastPosition) / deltaTime;
            movement.y = 0;
            Vector3 forward = player.eyes.BodyForward();
            forward.y = 0;
            forward.Normalize();
            Vector3 right = Vector3.Cross(Vector3.up, forward);
            float forwardSpeed = Vector3.Dot(movement, forward);
            float rightSpeed = Vector3.Dot(movement, right);
            string direction;
            if (forwardSpeed > 0.1f) direction = "вперед";
            else if (forwardSpeed < -0.1f) direction = "назад";
            else if (Mathf.Abs(rightSpeed) > 0.1f) direction = rightSpeed > 0 ? "вправо" : "влево";
            else direction = "стоит";
            player.ChatMessage($"Скорость:\n" + $"Вперед/Назад: {forwardSpeed:F1} м/с\n" + $"Вправо/Влево: {rightSpeed:F1} м/с\n" + $"Направление: {direction}\n" + $"Макс.скорость назад: {MAX_BACK_SPEED:F1} м/с\n" + $"Макс.скорость в стороны: {MAX_LEFT_SPEED:F1} м/с");
        }
        void OnPlayerDisconnected(BasePlayer player) {
            if (_playerData.ContainsKey(player.userID)) {
                var data = _playerData[player.userID];
                data.TotalPlayTime += (float)TimeSpan.FromSeconds(player.Connection.GetSecondsConnected()).TotalSeconds;
                _playerData.Remove(player.userID);
            }
        }
        private string FormatTimeSpan(float seconds) {
            TimeSpan time = TimeSpan.FromSeconds(seconds);
            if (time.Days > 0) return $"{time.Days}д {time.Hours}ч {time.Minutes}м";
            if (time.Hours > 0) return $"{time.Hours}ч {time.Minutes}м";
            return $"{time.Minutes}м {time.Seconds}с";
        }
        private void UpdateSessionTime(BasePlayer player, PlayerData data) {
            if (player == null || !player.IsConnected) return;
            float currentTime = Time.realtimeSinceStartup;
            if (currentTime - data.LastSessionUpdate < 60f) return;
            data.TotalPlayTime += (float)TimeSpan.FromSeconds(player.Connection.GetSecondsConnected()).TotalSeconds;
            data.LastSessionUpdate = currentTime;
        }
        void OnEntityDismounted(BaseMountable mountable, BasePlayer player) {
            if (player == null || !_playerData.ContainsKey(player.userID)) return;
            var data = _playerData[player.userID];
            data.LastDismountTime = Time.time;
        }
        void OnPlayerRespawned(BasePlayer player) {
            if (player == null || !_playerData.ContainsKey(player.userID)) return;
            var data = _playerData[player.userID];
            data.LastRespawnTime = Time.time;
            data.LastPosition = player.transform.position;
            data.LastSafePosition = player.transform.position;
        }
    }
}

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