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

FREE IQBanSystem : 1.12.22 1.12.22

Нет прав для скачивания
C#:
using Newtonsoft.Json.Linq;
using Rust;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Oxide.Core;
using ConVar;
using Oxide.Core.Libraries.Covalence;
using System.Text;
using System.Linq;
using Oxide.Core.Database;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries;
using System;
using Object = System.Object;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("IQBanSystem", "Mercury", "1.12.22")]
    [Description("IQBanSystem")]
    public class IQBanSystem : RustPlugin {
        private Dictionary<UInt64, Double> GetTeamsBannedPlayer(UInt64 bannedPlayer) {
            Dictionary<UInt64, Double> playerTeamMemory = new Dictionary<UInt64, Double>();
            if (teamLocalMemory.TryGetValue(bannedPlayer, out Dictionary<UInt64, TeamLocalMemory> teamsPlayers)) {
                foreach (KeyValuePair<UInt64, TeamLocalMemory> teammate in teamsPlayers) {
                    Double duration = (teammate.Value.lastRemoved == 0 ? CurrentTime : teammate.Value.lastRemoved) - teammate.Value.firstJoin;
                    playerTeamMemory.Add(teammate.Key, duration);
                    // PrintToChat(teammate.Key.ToString() + " " + teammate.Value.firstJoin + " " + teammate.Value.lastRemoved);
                }
            }
            //PrintToChat(playerTeamMemory.Count.ToString());
            return playerTeamMemory;
        }
        private List<Int32> appIds = new() {
            252490, 480
        }
        ;
        private void InserOrUpdateDatabase(String idOrIP, TypeAction typeBanned, IPlayer mbPlayer = null) {
            if (sqlConnection == null) return;
            PlayerInfo playerInfo = PlayerInfo.Get(idOrIP, typeBanned);
            if (playerInfo == null) return;
            String ipAddress = typeBanned == TypeAction.BannedIP ? idOrIP : mbPlayer?.Address ?? "None";
            String userID = typeBanned == TypeAction.BannedSteamID ? idOrIP : mbPlayer?.Id ?? "None";
            String jsonNameHistory = JsonConvert.SerializeObject(playerInfo.nameHistory, Formatting.None);
            String jsonIpHistory = JsonConvert.SerializeObject(playerInfo.ipHistory, Formatting.None);
            String jsonSteamHistory = JsonConvert.SerializeObject(playerInfo.steamIdHistory, Formatting.None);
            String sqlQueryUpdate = SQL_Query_UpdateUser(typeBanned);
            Sql updateCommand = Oxide.Core.Database.Sql.Builder.Append(sqlQueryUpdate, userID, ipAddress, playerInfo.permanent, playerInfo.timeUnbanned, playerInfo.reason, playerInfo.serverName, playerInfo.serverAdress, playerInfo.owner, jsonNameHistory, jsonIpHistory, jsonSteamHistory);
            sqlLibrary.Update(updateCommand, sqlConnection, rowsAffected => {
                if (rowsAffected <= 0) {
                    String sqlQueryInsert = SQL_Query_InsertUser();
                    Sql insertCommand = Oxide.Core.Database.Sql.Builder.Append(sqlQueryInsert, userID, ipAddress, playerInfo.permanent, playerInfo.timeUnbanned, playerInfo.reason, playerInfo.serverName, playerInfo.serverAdress, playerInfo.owner, jsonNameHistory, jsonIpHistory, jsonSteamHistory);
                    sqlLibrary.Insert(insertCommand, sqlConnection, rowsAffecteds => {
                        Puts(LanguageEn ? $"New user added to the database: {userID}/{ipAddress}" : $"В базу данных добавлен новый пользователь : {userID}/{ipAddress}");
                    }
                    );
                }
                else Puts(LanguageEn ? $"User data updated in the database: {userID}/{ipAddress}" : $"В базе данных обновлены данные о пользователе : {userID}/{ipAddress}");
            }
            );
        }
        void ReadData() {
            ipListGods = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<List<String>>("IQSystem/IQBanSystem/ListGodIps");
            teamLocalMemory = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Dictionary<UInt64, Dictionary<UInt64, TeamLocalMemory>>>("IQSystem/IQBanSystem/TeamsMemory");
            Puts(LanguageEn ? $"Database initialized with {ipListGods.Count} VPN-verified IPs" : $"Инициализирована база данных {ipListGods.Count} проверенных на VPN IP");
        }
        [ConsoleCommand("ban")]
        private void ConsoleBanCommand(ConsoleSystem.Arg arg) => BanCommand(arg.Player(), arg.Args);
        private class TeamLocalMemory {
            public Double firstJoin;
            public Double lastRemoved;
        }
        void HandlerProxyCheckIo(Int32 code, String response, String adress) {
            ProcessCheckVPN processChecked = ipListChecked[adress];
            if (code != 200 || string.IsNullOrEmpty(response)) {
                ResponseError("ProxyCheckIO", $"{code}");
                processChecked.isCompleteProxyCheck = true;
                return;
            }
            JObject jsonResponse;
            try {
                jsonResponse = JObject.Parse(response);
            }
            catch (JsonReaderException e) {
                ResponseError("ProxyCheckIO", e.Message);
                processChecked.isCompleteProxyCheck = true;
                return;
            }
            String status = jsonResponse["status"]?.ToString();
            if (!status.Equals("ok")) {
                String message = jsonResponse["message"]?.ToString();
                ResponseError("ProxyCheckIO", $"{status} : {message}");
                processChecked.isCompleteProxyCheck = true;
                return;
            }
            foreach (JProperty ipInfoProperty in jsonResponse.Properties()) {
                if (ipInfoProperty.Name.Equals("status", StringComparison.OrdinalIgnoreCase)) continue;
                JToken ipInfo = ipInfoProperty.Value;
                if (ipInfo["proxy"] != null && ipInfo["type"] != null) {
                    String proxy = ipInfo["proxy"].ToString();
                    String type = ipInfo["type"].ToString();
                    if (proxy.Equals("yes", StringComparison.OrdinalIgnoreCase) || type.Equals("VPN", StringComparison.OrdinalIgnoreCase)) {
                        //PrintError("DETECT ");
                        processChecked.detectedVpn++;
                    }
                }
            }
            processChecked.isCompleteProxyCheck = true;
        }
        private void SendInfo(BasePlayer player, String message) {
            if (player != null) SendChat(message, player);
            else Puts(message);
        }
        private void IsAvailabilityConnection(IPlayer player) {
            if (player == null) return;
            if (permission.UserHasPermission(player.Id, permissionIgnoreBan)) return;
            String ipAddress = player.Address;
            if (config.mysqlConnected.useMySQL) {
                GetUserData(player, ipAddress);
                return;
            }
            String userID = player.Id;
            PlayerInfo playerDataSteam = PlayerInfo.Get(userID, TypeAction.BannedSteamID);
            PlayerInfo playerDataIps = PlayerInfo.Get(ipAddress, TypeAction.BannedIP);
            if (playerDataSteam == null && playerDataIps == null) return;
            ProcessBanData(player, playerDataSteam, TypeAction.BannedSteamID, userID, ipAddress);
            ProcessBanData(player, playerDataIps, TypeAction.BannedIP, userID, ipAddress);
        }
        void OnTeamDisbanded(RelationshipManager.PlayerTeam team) {
            foreach (UInt64 teamMember in team.members) LeaveTeamPlayer(teamMember);
        }
        private class ProcessCheckVPN {
            public Boolean isCompleteProxyCheck;
            public Int32 detectedVpn;
            public Boolean isCompleteVpnApi;
            public Boolean isCompleteIPHub;
        }
        private readonly Dictionary<String, ProcessCheckVPN> ipListChecked = new Dictionary<String, ProcessCheckVPN>();
        private const String VendingPrefab = "assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab";
        [ChatCommand("ban")]
        private void ChatBanCommand(BasePlayer ownerCommand, String cmd, String[] arg) => BanCommand(ownerCommand, arg);
        private enum TypeAction {
            BannedIP, BannedSteamID,
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
            }
            catch {
                PrintWarning(LanguageEn ? $"Error reading #54327 configuration 'oxide/config/{Name}', creating a new configuration!!" : $"Ошибка чтения #54327 конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
                LoadDefaultConfig();
            }
            NextTick(SaveConfig);
        }
        private List<String> ipListGods = new List<String>();
        private void ProcessStorageContainer(BaseEntity entityPlayer, Action<StorageContainer> action) {
            if (entityPlayer is not StorageContainer) return;
            StorageContainer storage = entityPlayer as StorageContainer;
            if (storage.inventory != null && storage.inventory.itemList.Count != 0) action(storage);
        }
        private String IsAvailabilityPreConnection(IPlayer player, String id, String ip) {
            if (permission.UserHasPermission(id, permissionIgnoreBan)) return null;
            if (config.mysqlConnected.useMySQL) return null;
            PlayerInfo playerDataSteam = PlayerInfo.Get(id, TypeAction.BannedSteamID);
            PlayerInfo playerDataIps = PlayerInfo.Get(ip, TypeAction.BannedIP);
            if (playerDataSteam == null && playerDataIps == null) return null;
            String bannedReasonID = ProcessBanData(player, playerDataSteam, TypeAction.BannedSteamID, id, ip);
            String bannedReasonIP = ProcessBanData(player, playerDataIps, TypeAction.BannedIP, id, ip);
            if (!String.IsNullOrEmpty(bannedReasonID)) return bannedReasonID;
            if (!String.IsNullOrEmpty(bannedReasonIP)) return bannedReasonIP;
            return null;
        }
        private String SQL_Query_GetUserData() => $"SELECT `steamid`, `ipAdress`, `permanent`, `timeUnbanned`, `reason`, `serverName`, `serverAdress`, `owner`, `nameHistory`, `ipHistory`, `steamIdHistory` FROM {config.mysqlConnected.dbTableName} WHERE `steamid` = @0 OR `ipAdress` = @1";
        public String FormatTime(Double Second, String UserID = null) {
            TimeSpan time = TimeSpan.FromSeconds(Second);
            String Result = String.Empty;
            String Days = GetLang("TITLE_FORMAT_DAYS", UserID);
            String Hourse = GetLang("TITLE_FORMAT_HOURSE", UserID);
            String Minutes = GetLang("TITLE_FORMAT_MINUTES", UserID);
            String Seconds = GetLang("TITLE_FORMAT_SECONDS", UserID);
            if (time.Seconds != 0) Result = $"{Format(time.Seconds, Seconds, Seconds, Seconds)}";
            if (time.Minutes != 0) Result = $"{Format(time.Minutes, Minutes, Minutes, Minutes)}";
            if (time.Hours != 0) Result = $"{Format(time.Hours, Hourse, Hourse, Hourse)}";
            if (time.Days != 0) Result = $"{Format(time.Days, Days, Days, Days)}";
            return Result;
        }
        private static StringBuilder sb = new StringBuilder();
        void OnPlayerConnected(BasePlayer player) {
            if (config.generalSetting.discordSetting.alertBanned.teamsAlert.saveInfoTeams || config.generalSetting.additionalSetting.useAlertBlockTeam || config.bannedSetting.teamBannedSetting.useBlockTeam) PullOutTeamsInfo(player);
            Configuration.BannedSetting.DestroyedAfterBannedSetting configDestroyed = config.bannedSetting.destroyedAfterBannedSetting;
            Boolean isMarkerUse = configDestroyed.mapMarkerDestroyedObjectSetting.useMapMarkerDestroyedObjectPlayer && config.generalSetting.additionalSetting.useAlertAllPlayers && configDestroyed.useAlertGridHomes && configDestroyed.useDestroyObjects;
            if (isMarkerUse) {
                foreach (MarkerRepository markerRepository in mapMarkers) {
                    if(!markerRepository.vending.IsDestroyed) markerRepository.vending.SendNetworkUpdate();
                    if(!markerRepository.marker.IsDestroyed) markerRepository.marker.SendNetworkUpdate();
                }
            }
        }
        private const String permissionIgnoreBan = "iqbansystem.ignoreban";
        private void SetTirifyUnBan(String steamIdString, String reason = "") {
            if (!TirifyGamePluginRust) return;
            if (!config.bannedSetting.tirifyBannedReplace) return;
            TirifyGamePluginRust.Call("SetTirifyUnBan", steamIdString, reason);
            Puts(LanguageEn ? $"The player's hardware has been unblocked {steamIdString} (Tirify)" : $"Выдана разблокировка по железу игроку {steamIdString} (Tirify)");
        }
        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 MarkerUpdate() {
            for (Int32 i = 0; i < mapMarkers.Count; i++) {
                MarkerRepository marker = mapMarkers[i];
                TimeSpan timeSpan = DateTime.Now - marker.timeSetMarker;
                Double totalSeconds = timeSpan.TotalSeconds;
                if (!TryParseTimeSpan(config.bannedSetting.destroyedAfterBannedSetting.mapMarkerDestroyedObjectSetting.markerLifeTime, out Double markerUpdate)) {
                    PrintError(LanguageEn ? "Incorrect marker update time format. The marker has been deleted." : "Некорректный формат времени обновления маркера. Маркер был удален.");
                    if(!marker.vending.IsDestroyed) marker.vending.Kill();
                    if(!marker.marker.IsDestroyed) marker.marker.Kill();
                    mapMarkers.Remove(marker);
                }
                if(totalSeconds < markerUpdate) continue;
                if(!marker.vending.IsDestroyed) marker.vending.Kill();
                if(!marker.marker.IsDestroyed) marker.marker.Kill();
                mapMarkers.Remove(marker);
            }
        }
        private String SQL_Query_DeletedDatabase(TypeAction typeUnBanned) => $"DELETE FROM `{config.mysqlConnected.dbTableName}` WHERE " + $"{(typeUnBanned == TypeAction.BannedSteamID ? "`steamid` = @0" : "`ipAdress` = @0")}";
        private void ResponseError(String nameService, String message) => PrintWarning(LanguageEn ? $"[{nameService}] The service is temporarily unavailable or your key is incorrect, it returned a negative code, the request was not sent.\nInformation (Code or messages from the service): {message}" : $"[{nameService}] Сервис временно недоступен или ваш ключ некорректен, он вернул отрицательный код, запрос не был отправлен.\nИнформация (Код или сообщения от сервиса) : : {message}");
        private Boolean TryParseTimeSpan(String source, out Double timeSpan) {
            Int32 seconds = 0, minutes = 0, hours = 0, days = 0;
            MatchCollection matches = Regex.Matches(source, @"(\d+)([smhd])", RegexOptions.IgnoreCase);
            foreach (Match match in matches) {
                Int32 value = int.Parse(match.Groups[1].Value);
                Char unit = match.Groups[2].Value.ToLower()[0];
                switch (unit) {
                    case 's' : seconds += value;
                    break;
                    case 'm' : minutes += value;
                    break;
                    case 'h' : hours += value;
                    break;
                    case 'd' : days += value;
                    break;
                }
            }
            source = Regex.Replace(source, @"(\d+)[smhd]", String.Empty, RegexOptions.IgnoreCase);
            if (!String.IsNullOrEmpty(source) || (seconds == 0 && minutes == 0 && hours == 0 && days == 0)) {
                timeSpan = 0;
                return false;
            }
            timeSpan = new TimeSpan(days, hours, minutes, seconds).TotalSeconds;
            return true;
        }
        private void OnServerShutdown() => Unload();
        object OnTeamLeave(RelationshipManager.PlayerTeam team, BasePlayer player) {
            LeaveTeamPlayer(player.userID);
            return null;
        }
        private class Configuration {
            [JsonProperty(LanguageEn ? "Server data configuration" : "Настройка данных сервера")]
            public GeneralSetting generalSetting = new GeneralSetting();
            [JsonProperty(LanguageEn ? "Setting up MySQL connection" : "Настройка подключения MySQL")]
            public MySQLSetting mysqlConnected = new MySQLSetting();
            [JsonProperty(LanguageEn ? "Setting up interaction with Steam" : "Настройка взаимодействия со Steam")]
            public SteamSetting steamSetting = new SteamSetting();
            [JsonProperty(LanguageEn ? "Setting up VPN protection" : "Настройка защиты от VPN")]
            public VPNSetting vpnSetting = new VPNSetting();
            [JsonProperty(LanguageEn ? "Setting up the blocking system" : "Настройка системы блокировки")]
            public BannedSetting bannedSetting = new BannedSetting();
            internal class GeneralSetting {
                [JsonProperty(LanguageEn ? "Server name" : "Название сервера")]
                public String serverName;
                [JsonProperty(LanguageEn ? "IP:PORT server" : "IP:Port сервера")]
                public String serverAdress;
                [JsonProperty(LanguageEn ? "Additional configuration" : "Дополнительная настройка")]
                public AdditionalSetting additionalSetting = new AdditionalSetting();
                [JsonProperty(LanguageEn ? "Setting IQChat" : "Настройка IQChat")]
                public IQChatSetting iqchatSetting = new IQChatSetting();
                [JsonProperty(LanguageEn ? "Setting Discord" : "Настройка Discord")]
                public DiscordSetting discordSetting = new DiscordSetting();
                internal class AdditionalSetting {
                    [JsonProperty(LanguageEn ? "Sound effect for all players to notify when a player is blocked ('Notify all players' should be enabled) (leave it blank - if you don't need it)" : "Звуковой эффект для всех игроков для уведомления о блокировке игрока (должно быть включено 'Уведомлять всех игроков') (оставьте пустым - если вам не нужно это)")]
                    public String effectAlertAllPlayers;
                    [JsonProperty(LanguageEn ? "Notify all players when a player is blocked" : "Уведомлять всех игроков о блокировке игрока")]
                    public Boolean useAlertAllPlayers;
                    [JsonProperty(LanguageEn ? "Notify all players about player's kick" : "Уведомлять всех игроков о кике игрока")]
                    public Boolean useAlertKickPlayer;
                    [JsonProperty(LanguageEn ? "Add information about blocked teammates to the blocking notification" : "Добавлять в уведомление о блокировке - информацию о заблокированных тиммейтах")]
                    public Boolean useAlertBlockTeam;
                }
                internal class IQChatSetting {
                    [JsonProperty(LanguageEn ? "IQChat: Chat Prefix" : "IQChat : Префикс в чате")]
                    public String customPrefix;
                    [JsonProperty(LanguageEn ? "IQChat: Chat Avatar (Use Steam64ID)" : "IQChat : Аватарка в чате (Используйте Steam64ID)")]
                    public String customAvatar;
                }
                internal class DiscordSetting {
                    [JsonProperty(LanguageEn ? "Discord notification setting for player ban" : "Настройка уведомления в Discord о блокировке игрока")]
                    public AlertBanned alertBanned = new AlertBanned();
                    internal class AlertBanned {
                        [JsonProperty(LanguageEn ? "Webhooks: For banned notifications" : "Webhooks : Для уведомлений о блокировке")]
                        public String webHookBanned;
                        [JsonProperty(LanguageEn ? "Include home information of the banned player in the notification" : "Добавлять в уведомление дома где прописан заблокированный игрок")]
                        public Boolean cupboardAuthInfo;
                        [JsonProperty(LanguageEn ? "Additional notification setting for players who played with the banned player" : "Настройка дополнительного уведомления о тех с кем играл заблокированный")]
                        public TeamsAlert teamsAlert = new TeamsAlert();
                        internal class TeamsAlert {
                            [JsonProperty(LanguageEn ? "Include players who played with the banned player in the notification" : "Добавлять в уведомление игроков с которыми играл забаненный")]
                            public Boolean saveInfoTeams;
                            [JsonProperty(LanguageEn ? "Time spent together with the banned player to be included in the notification (Format: 1s/1m/1h/1d)" : "Сколько времени должны провести вместе забаненный с игроком для его отображения в уведомлении (В формате 1s/1m/1h/1d)")]
                            public String formatTimePlaying;
                        }
                    }
                    [JsonProperty(LanguageEn ? "Webhooks : For unbanned notifications" : "Webhooks : Для уведомлений о разблокировке")]
                    public String webHookUnBanned;
                    [JsonProperty(LanguageEn ? "Webhooks : For kicked notifications" : "Webhooks : Для уведомлений о киках")]
                    public String webHookKicked;
                    [JsonProperty(LanguageEn ? "Webhooks : For notifications about a blocked player's login attempt" : "Webhooks : Для уведомлений о попытке входа заблокированного игрока")]
                    public String webHookConnectedBanned;
                    [JsonProperty(LanguageEn ? "Link to the image in Discord" : "Ссылка на изображение в Discord")]
                    public String imageLink;
                }
            }
            internal class SteamSetting {
                [JsonProperty(LanguageEn ? "Please provide the Steam API Key for the operation of these functions (Obtain it here - https://steamcommunity.com/dev/apikey)" : "Укажите SteamApiKey для работы данных функций (Взять тут - https://steamcommunity.com/dev/apikey)")]
                public String steamApiKey;
                [JsonProperty(LanguageEn ? "The minimum amount of time since Steam account registration for logging into the server. Format: 1m/1h/1d (leave empty if you don't need this function)" : "Минимальное количество времени с регистрации аккаунта Steam для входа на сервер. Формат 1m/1h/1d (оставьте пустым - если вам не нужна эта функция)")]
                public String minSteamRegisterTime;
                [JsonProperty(LanguageEn ? "The minimum amount of playtime in RUST required for logging into the server. Format: 1m/1h/1d (leave empty if you don't need this function)" : "Минимальное количество отыгранного времени в RUST для входа на сервер. Формат 1m/1h/1d (оставьте пустым - если вам не нужна эта функция)")]
                public String minPlayGameTime;
            }
            internal class MySQLSetting {
                [JsonProperty(LanguageEn ? "Use MySQL database (true - yes/false - no)" : "Использовать базу-данных MySQL (true - да/false - нет)")]
                public Boolean useMySQL;
                [JsonProperty(LanguageEn ? "Host (IP-Address)" : "Хост (IP-Address)")]
                public String dbIP;
                [JsonProperty(LanguageEn ? "Port (default 3306)" : "Порт (стандартно 3306)")]
                public String dbPort;
                [JsonProperty(LanguageEn ? "Database name" : "Имя базы данных")]
                public String dbName;
                [JsonProperty(LanguageEn ? "Username" : "Имя пользователя")]
                public String dbUser;
                [JsonProperty(LanguageEn ? "Password" : "Пароль")]
                public String dbPassword;
                [JsonProperty(LanguageEn ? "Table name" : "Название таблицы")]
                public String dbTableName;
            }
            internal class VPNSetting {
                [JsonProperty(LanguageEn ? "Saving 'Good IPs' to avoid reusing requests on the player" : "Сохранять `Хорошие IP`, чтобы не тратить запросы повторно на игрока")]
                public Boolean useSaveGodIps;
                [JsonProperty(LanguageEn ? "The number of detects for kicking a player for VPN (if you use more than 1 service for VPN checking)" : "Количество детектов для кика игрока за VPN (Если вы испольузете более 1 сервиса на проверку VPN)")]
                public Int32 countDetectedToKickInVPN;
                [JsonProperty(LanguageEn ? "Token https://iphub.info/" : "Токен от https://iphub.info/")]
                public String iPHubToken;
                [JsonProperty(LanguageEn ? "Token https://proxycheck.io/" : "Токен от https://proxycheck.io/")]
                public String proxyCheckIo;
                [JsonProperty(LanguageEn ? "Token https://vpnapi.io/" : "Токен от https://vpnapi.io/")]
                public String vpnApiIoToken;
                [JsonProperty(LanguageEn ? "IP Whitelist for ignoring VPN" : "Белый список IP для игнорирования VPN")]
                public List<String> vpnWhiteList = new List<String>();
            }
            internal class BannedSetting {
                [JsonProperty(LanguageEn ? "TirifyGamePluginRust : Block the player by hardware using Tirify if the lock is issued forever (true - yes/false - no)" : "TirifyGamePluginRust : Блокировать игрока по железу с помощью Tirify если блокировка выдана навсегда (true - да/false - нет)")]
                public Boolean tirifyBannedReplace;
                [JsonProperty(LanguageEn ? "Kill player after being banned on the server" : "Убивать игрока после блокировки на сервере")]
                public Boolean useKilledPlayer;
                [JsonProperty(LanguageEn ? "Setting for banning teammates for playing with the offender" : "Настройка блокировки тиммейтов за игру с нарушителем")]
                public TeamBannedSetting teamBannedSetting = new TeamBannedSetting();
                [JsonProperty(LanguageEn ? "Setting for destroying player's objects after being banned" : "Настройка уничтожения объектов игрока после блокировки")]
                public DestroyedAfterBannedSetting destroyedAfterBannedSetting = new DestroyedAfterBannedSetting();
                internal class TeamBannedSetting {
                    [JsonProperty(LanguageEn ? "Specify the time played with the offender for issuing a ban. Format 1s/1m/1h/1d" : "Укажите время игры с нарушителем для выдачи блокировки. Формат 1s/1m/1h/1d")]
                    public String timeDeteckGamingTeamMemory;
                    [JsonProperty(LanguageEn ? "Ban teammates of the banned player" : "Блокировать тиммейтов заблокированного игрока")]
                    public Boolean useBlockTeam;
                    [JsonProperty(LanguageEn ? "Specify the ban time for teammates for playing with the offender. Format 1s/1m/1h/1d (Leave empty for issuing a permanent ban)" : "Укажите время блокировки тиммейтов за игру с нарушителем. Формат 1s/1m/1h/1d (Оставьте пустым - для выдачи блокировки навсегда)")]
                    public String timeBlockTeam;
                }
                internal class DestroyedAfterBannedSetting {
                    [JsonProperty(LanguageEn ? "Use the function to delete player's objects after being banned" : "Использовать функцию удаления объектов игрока после блокировки")]
                    public Boolean useDestroyObjects;
                    [JsonProperty(LanguageEn ? "Type of object destruction: 0 - All objects, 1 - All objects and dropping items from containers on the ground, 2 - Only locks, 3 - Only boxes, 4 - Only boxes with dropping items from them" : "Тип уничтожения объектов : 0 - Все объекты, 1 - Все объекты и выбрасывание предметов из контейнеров на пол, 2 - Только замки, 3 - Только ящики, 4 - Только ящики с выбрасыванием предметов из них")]
                    public TypeDestroy typeDestroyed;
                    [JsonProperty(LanguageEn ? "Notify in chat about squares of destroyed player's objects" : "Уведомлять в чате о квадратах разрушенных объектах игрока")]
                    public Boolean useAlertGridHomes;
                    [JsonProperty(LanguageEn ? "Setting for displaying markers on the G-Map" : "Настройка отображения маркеров на G-Map")]
                    public MapMarkerDestroyedObject mapMarkerDestroyedObjectSetting = new();
                    internal class MapMarkerDestroyedObject {
                        [JsonProperty(LanguageEn ? "Display points with destroyed objects on the map" : "Отображать на карте точки с разрушенными объектами")]
                        public Boolean useMapMarkerDestroyedObjectPlayer;
                        [JsonProperty(LanguageEn ? "Main marker color" : "Основной цвет маркера")]
                        public String mainColorMarker;
                        [JsonProperty(LanguageEn ? "Outline marker color" : "Цвет обводки маркера")]
                        public String additionalColorMarker;
                        [JsonProperty(LanguageEn ? "Marker radius on the map" : "Радиус маркера на карте")]
                        public Single radiusMarker;
                        [JsonProperty(LanguageEn ? "How long the marker will be displayed. Format 1s/1m/1h/1d" : "Сколько будет отображаться маркер. Формат 1s/1m/1h/1d")]
                        public String markerLifeTime;
                    }
                }
            }
            public static Configuration GetNewConfiguration() {
                return new Configuration {
                    generalSetting = new GeneralSetting {
                        serverName = "MY SERVER", serverAdress = "127.0.0.1", additionalSetting = new GeneralSetting.AdditionalSetting {
                            effectAlertAllPlayers = "assets/bundled/prefabs/fx/item_unlock.prefab", useAlertAllPlayers = true, useAlertKickPlayer = false, useAlertBlockTeam = false,
                        }
                        , iqchatSetting = new GeneralSetting.IQChatSetting {
                            customPrefix = "<color=#1F6BA0>[IQBanSystem]</color>", customAvatar = "0"
                        }
                        , discordSetting = new GeneralSetting.DiscordSetting {
                            alertBanned = new GeneralSetting.DiscordSetting.AlertBanned {
                                webHookBanned = String.Empty, cupboardAuthInfo = false, teamsAlert = new GeneralSetting.DiscordSetting.AlertBanned.TeamsAlert {
                                    saveInfoTeams = false, formatTimePlaying = "12h",
                                }
                            }
                            , webHookUnBanned = String.Empty, webHookKicked = String.Empty, webHookConnectedBanned = String.Empty, imageLink = "https://i.postimg.cc/MGLfp4dR/IQBan-System.png",
                        }
                        ,
                    }
                    , mysqlConnected = new MySQLSetting {
                        useMySQL = false, dbIP = "", dbPort = "3306", dbName = "", dbUser = "", dbPassword = "", dbTableName = "IQBanSystem_Db"
                    }
                    , steamSetting = new SteamSetting {
                        steamApiKey = "", minSteamRegisterTime = "14d", minPlayGameTime = "3d",
                    }
                    , vpnSetting = new VPNSetting {
                        useSaveGodIps = true, countDetectedToKickInVPN = 1, iPHubToken = "", proxyCheckIo = "", vpnApiIoToken = "", vpnWhiteList = new List<String> {
                            "127.0.0.1"
                        }
                    }
                    , bannedSetting = new BannedSetting {
                        tirifyBannedReplace = false, useKilledPlayer = true, teamBannedSetting = new BannedSetting.TeamBannedSetting {
                            useBlockTeam = false, timeDeteckGamingTeamMemory = "3h", timeBlockTeam = "7d"
                        }
                        , destroyedAfterBannedSetting = new BannedSetting.DestroyedAfterBannedSetting {
                            useDestroyObjects = false, typeDestroyed = TypeDestroy.AllObjects, useAlertGridHomes = false, mapMarkerDestroyedObjectSetting = new BannedSetting.DestroyedAfterBannedSetting.MapMarkerDestroyedObject {
                                useMapMarkerDestroyedObjectPlayer = false, mainColorMarker = "#CD412B", additionalColorMarker = "#1E2020", radiusMarker = 0.25f, markerLifeTime = "10m",
                            }
                        }
                        ,
                    }
                }
                ;
            }
        }
        private static Configuration config = new Configuration();
        private enum TypeAlertDiscord {
            Banned, Unbanned, Kicked, ConnectionBanned
        }
        private String SQL_Query_InsertUser() {
            return $"INSERT INTO {config.mysqlConnected.dbTableName} " + "(`steamid`, `ipAdress`, `permanent`, `timeUnbanned`, `reason`, `serverName`, `serverAdress`, `owner`, `nameHistory`, `ipHistory`, `steamIdHistory`) " + "VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10)";
        }
        private const String patternIP = @"^\b(?:\d{1,3}\.){3}\d{1,3}\b$";
        private void BanIp(String IpAdress, IPlayer iPlayer = null, String reason = default, Double banTime = 0, BasePlayer ownerCommand = null, Boolean skipTeam = false) {
            String displayName = iPlayer?.Name ?? String.Empty;
            String idPlayer = iPlayer?.Id ?? String.Empty;
            BanUserOrIp(idPlayer, displayName, IpAdress, reason, banTime, TypeAction.BannedIP, ownerCommand, skipTeam);
        }
        private List<String> DestroyObjectBanned(IPlayer bannedPlayer, String bannedDisplayName) {
            Vector3 lastObjectPos = Vector3.zero;
            List<String> homeCords = new ();
            List<BaseEntity> entitesPlayer = Facepunch.Pool.Get<List<BaseEntity>>();
            Configuration.BannedSetting.DestroyedAfterBannedSetting configDestroyed = config.bannedSetting.destroyedAfterBannedSetting;
            Func<BaseNetworkable, Boolean> baseFilter = e => e != null && e is BaseEntity && (e as BaseEntity).OwnerID == UInt64.Parse(bannedPlayer.Id);
            Func<BaseNetworkable, Boolean> filter = baseFilter;
            baseFilter = configDestroyed.typeDestroyed switch {
                TypeDestroy.OnlyLocks => e => filter(e) && e is BaseLock, TypeDestroy.OnlyStorageAndDropInStorage or TypeDestroy.OnlyStorage => e => filter(e) && e is StorageContainer, _ => baseFilter
            }
            ;
            Boolean isBuildingAccess = false;
            foreach (BaseEntity entityPlayer in BaseNetworkable.serverEntities.entityList.Get().Values.Where(baseFilter).OrderByDescending(x => x is StorageContainer)) {
                if (entityPlayer.IsDestroyed) continue;
                if (!isBuildingAccess) {
                    BuildingPrivlidge buildingPrivilage = entityPlayer.GetBuildingPrivilege();
                    if (buildingPrivilage == null) continue;
                    isBuildingAccess = true;
                }
                switch (configDestroyed.typeDestroyed) {
                    case TypeDestroy.AllObjectsAndDropInStorage or TypeDestroy.OnlyStorageAndDropInStorage : ProcessStorageContainer(entityPlayer, storage => {
                        storage.DropItems();
                    }
                    );
                    break;
                    case TypeDestroy.AllObjects or TypeDestroy.OnlyStorage : ProcessStorageContainer(entityPlayer, storage => {
                        storage.inventory.Clear();
                    }
                    );
                    break;
                }
                if (config.generalSetting.additionalSetting.useAlertAllPlayers && configDestroyed.useAlertGridHomes) {
                    if (lastObjectPos != Vector3.zero) if (Vector3.Distance(lastObjectPos, entityPlayer.transform.position) >= 100) {
                        String cordHomeOnMap = MapHelper.PositionToString(entityPlayer.transform.position);
                        if (!homeCords.Contains(cordHomeOnMap)) {
                            homeCords.Add(cordHomeOnMap);
                            CreateMapMarker(entityPlayer.transform.position, bannedDisplayName);
                        }
                        lastObjectPos = entityPlayer.transform.position;
                        continue;
                    }
                    lastObjectPos = entityPlayer.transform.position;
                    if (homeCords.Count == 0) {
                        homeCords.Add(MapHelper.PositionToString(entityPlayer.transform.position));
                        CreateMapMarker(entityPlayer.transform.position, bannedDisplayName);
                    }
                }
                entityPlayer.Kill();
            }
            Facepunch.Pool.FreeUnmanaged(ref entitesPlayer);
            return homeCords;
        }
        private void Request(String url, String payload, Action<Int32> 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) {
                                Single seconds = Single.Parse(Math.Ceiling((Double)(Int32)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, timeout : 10f);
        }
        private String GetKickReason(PlayerInfo playerData, String userID) {
            if (!string.IsNullOrWhiteSpace(playerData.reason)) {
                return playerData.permanent ? GetLang("BANNED_ALERT_PERMANENT", userID, playerData.reason) : GetLang("BANNED_ALERT_TIME", userID, playerData.reason, FormatTime(playerData.GetUnbanTime, userID));
            }
            else {
                return playerData.permanent ? GetLang("BANNED_DEFAULT_REASON_PERMANENT", userID) : GetLang("BANNED_DEFAULT_REASON", userID, FormatTime(playerData.GetUnbanTime, userID));
            }
        }
        private String ProcessBanData(IPlayer player, PlayerInfo playerData, TypeAction typeAction, String userID, String ipAddress) {
            if (playerData == null) return String.Empty;
            playerData.UpdateHistory(TypeHistoryInfo.Name, player?.Name ?? "Unknown");
            playerData.UpdateHistory(TypeHistoryInfo.IP, ipAddress);
            playerData.UpdateHistory(TypeHistoryInfo.SteamID, userID);
            if (playerData.IsBanned()) {
                String kickReason = GetKickReason(playerData, userID);
                player?.Kick(kickReason);
                if (!String.IsNullOrWhiteSpace(config.generalSetting.discordSetting.webHookConnectedBanned)) {
                    List<Fields> fieldsKick = new List<Fields> {
                        new Fields(LanguageEn ? "Player" : "Игрок", $"{player?.Name ?? "Unknown"}({userID})", false), new Fields("IP", ipAddress, false), new Fields(LanguageEn ? "Banned reason" : "Причина блокировки", playerData.reason, false), new Fields(LanguageEn ? "Unban time" : "Время разблокировки", playerData.permanent ? (LanguageEn ? "never" : "никогда") : FormatTime(playerData.GetUnbanTime), false),
                    }
                    ;
                    SendDiscord(fieldsKick, TypeAlertDiscord.ConnectionBanned, config.generalSetting.discordSetting.webHookConnectedBanned);
                }
                return kickReason;
            }
            else {
                PlayerInfo.Remove(userID, typeAction);
                return String.Empty;
            }
        }
        object OnTeamAcceptInvite(RelationshipManager.PlayerTeam team, BasePlayer player) {
            TeamAdded(team);
            return null;
        }
        private void CheckSteamController(IPlayer player) {
            if (player == null) return;
            if (String.IsNullOrWhiteSpace(config.steamSetting.steamApiKey)) return;
            webrequest.Enqueue($"https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key={config.steamSetting.steamApiKey}&steamids={player.Id}", String.Empty, (code, response) => HandlerSteam(player, code, response), this, timeout : 10f);
        }
        private Dictionary<UInt64, Dictionary<UInt64, TeamLocalMemory>> teamLocalMemory = new();
        /// <summary>
        /// Returned unbanTime. -1 = permanent
        /// </summary>
        /// <param name="idOrIP"></param>
        /// <returns></returns>
        private Double GetUnbanTime(String idOrIP) {
            TypeAction typeAction = TypeAction.BannedSteamID;
            if (IsIpAdress(idOrIP)) typeAction = TypeAction.BannedIP;
            PlayerInfo pInfo = PlayerInfo.Get(idOrIP, typeAction);
            if (pInfo == null) return 0;
            if (pInfo.permanent) return -1;
            return pInfo.GetUnbanTime;
        }
        private Boolean IsOpenMySQL() => config.mysqlConnected.useMySQL && sqlConnection != null;
        private void CreateMapMarker(Vector3 position, String namePlayer) {
            Configuration.BannedSetting.DestroyedAfterBannedSetting configDestroyed = config.bannedSetting.destroyedAfterBannedSetting;
            if (!configDestroyed.mapMarkerDestroyedObjectSetting.useMapMarkerDestroyedObjectPlayer) return;
            VendingMachineMapMarker vending = GameManager.server.CreateEntity(VendingPrefab, position, Quaternion.identity, true) as VendingMachineMapMarker;
            vending.markerShopName = namePlayer;
            vending.enableSaving = false;
            vending.EnableGlobalBroadcast(true);
            vending.Spawn();
            MapMarkerGenericRadius genericMarker = GameManager.server.CreateEntity(GenericPrefab, new Vector3(), Quaternion.identity, true) as MapMarkerGenericRadius;
            ColorUtility.TryParseHtmlString(configDestroyed.mapMarkerDestroyedObjectSetting.mainColorMarker, out Color color1);
            ColorUtility.TryParseHtmlString(configDestroyed.mapMarkerDestroyedObjectSetting.additionalColorMarker, out Color color2);
            genericMarker.color1 = color1;
            genericMarker.color2 = color2;
            genericMarker.radius = configDestroyed.mapMarkerDestroyedObjectSetting.radiusMarker;
            genericMarker.alpha = 1f;
            genericMarker.SetParent(vending);
            genericMarker.Spawn();
            genericMarker.SendUpdate();
            genericMarker.EnableGlobalBroadcast(true);
            MarkerRepository markerInfo = new MarkerRepository() {
                vending = vending, marker = genericMarker, timeSetMarker = DateTime.Now
            }
            ;
            mapMarkers.Add(markerInfo);
        }
        private void LoadDataFiles(TypeAction type) {
            String[] players = PlayerInfo.GetFiles(type);
            foreach (String player in players) PlayerInfo.Load(player, type);
            String Message = type == TypeAction.BannedSteamID ? (LanguageEn ? $"Database initialized with {players.Length} banned players" : $"Инициализирована база данных {players.Length} забаненных игроков") : (LanguageEn ? $"Database initialized with {players.Length} banned IPs" : $"Инициализирована база данных {players.Length} забаненных IP-адресов");
            Puts(Message);
        }
        private void RustApp_OnPaidAnnounceBan(String steamID, List<String> targets, String reason) {
            if (!UInt64.TryParse(steamID, out UInt64 userID)) return;
            IPlayer iPlayer = GetIPlayer(steamID);
            BanUser(userID, iPlayer, reason : reason);
        }
        private Boolean IsIpAdress(String mbIP) => Regex.IsMatch(mbIP, patternIP);
        private void Init() {
            _ = this;
            if (config.mysqlConnected.useMySQL) {
                SQL_OpenConnection();
                Unsubscribe(nameof(CanUserLogin));
            }
            else {
                LoadDataFiles(TypeAction.BannedIP);
                LoadDataFiles(TypeAction.BannedSteamID);
                foreach (BasePlayer player in BasePlayer.activePlayerList) OnPlayerConnected(player);
            }
            if(config.vpnSetting.useSaveGodIps) ReadData();
            if (!config.generalSetting.discordSetting.alertBanned.teamsAlert.saveInfoTeams && !config.generalSetting.additionalSetting.useAlertBlockTeam && !config.bannedSetting.teamBannedSetting.useBlockTeam) {
                Unsubscribe(nameof(OnTeamCreated));
                Unsubscribe(nameof(OnTeamDisbanded));
                Unsubscribe(nameof(OnTeamKick));
                Unsubscribe(nameof(OnTeamLeave));
                Unsubscribe(nameof(OnTeamAcceptInvite));
            }
        }
        void WriteData() {
            Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQBanSystem/ListGodIps", ipListGods);
            Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQBanSystem/TeamsMemory", teamLocalMemory);
        }
        private const Boolean LanguageEn = false;
        private void BanCommand(BasePlayer ownerCommand, String[] arg) {
            if (ownerCommand != null) if (!permission.UserHasPermission(ownerCommand.UserIDString, permissionsBan)) return;
            if (arg == null) {

// ... [Code preview truncated due to length. Full source in attached file] ...

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