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

FREE BanSystem : 0.4.29 0.4.29

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Libraries;
using UnityEngine;
// ReSharper disable UnusedMember.Local
// ReSharper disable UnusedMember.Global
namespace Oxide.Plugins {
    [Info("Ban System", "Bombardir, Moscow.OVH", "0.4.29")]
    [Description("Ban System")]
    public class BanSystem : RustPlugin {
        private static readonly string SyncPermission = "bansystem.sync";
        private static readonly string KickPermission = "bansystem.kick";
        private static readonly string BanPermission = "bansystem.ban";
        private static readonly string StrikePermission = "bansystem.strike";
        private static readonly string UnbanPermission = "bansystem.unban";
        private readonly Core.Libraries.Plugins _plugins = GetLibrary<Core.Libraries.Plugins>();
        private readonly Permission _permission = GetLibrary<Permission>();
        private readonly Lang _lang = GetLibrary<Lang>();
        private readonly Covalence _covalence = GetLibrary<Covalence>();
        private ExConfig _exConfig;
        private WebApi _webApi;
        private GameObject _mainObject;
        private BansData _bansData;
        private static BanSystem _plugin;
        private bool _initialized = false;
        protected override void LoadDefaultConfig() {
        }
        // Совместимость с.cs плагинами, создание пустого файла конфигурации.public override void HandleRemovedFromManager(PluginManager manager)
        {
            if (_mainObject != null) {
                UnityEngine.Object.Destroy(_mainObject);
            }
            base.HandleRemovedFromManager(manager);
        }
        private static readonly Regex RegexStringTime = new Regex(@"(\d+)([dhms])", RegexOptions.Compiled);
        private static bool ConvertToSeconds(string time, out uint seconds) {
            seconds = 0;
            if (time == "0" || string.IsNullOrEmpty(time)) {
                return true;
            }
            MatchCollection matches = RegexStringTime.Matches(time);
            if (matches.Count == 0) {
                return false;
            }
            for (var i = 0; i < matches.Count; i++) {
                Match match = matches[i];
                switch (match.Groups[2].Value) {
                    case "d" : {
                        seconds += uint.Parse(match.Groups[1].Value) * 24 * 60 * 60;
                        break;
                    }
                    case "h" : {
                        seconds += uint.Parse(match.Groups[1].Value) * 60 * 60;
                        break;
                    }
                    case "m" : {
                        seconds += uint.Parse(match.Groups[1].Value) * 60;
                        break;
                    }
                    case "s" : {
                        seconds += uint.Parse(match.Groups[1].Value);
                        break;
                    }
                }
            }
            return true;
        }
        private static string GetNiceTime(ulong seconds, string day, string hour, string min, string sec) {
            TimeSpan span = TimeSpan.FromSeconds(seconds).Duration();
            string formatted = string.Empty;
            if (span.Days > 0) {
                formatted += span.Days + day;
            }
            if (span.Hours > 0) {
                formatted += span.Hours + hour;
            }
            if (span.Minutes > 0) {
                formatted += span.Minutes + min;
            }
            if (span.Seconds > 0) {
                formatted += span.Seconds + sec;
            }
            if (string.IsNullOrEmpty(formatted)) {
                formatted = "0 сек";
            }
            return formatted;
        }
        private void LogAdmin(string action, ulong steamId, string playerName, string playerSteam) {
            string initiatorStr;
            if (steamId == 0) {
                initiatorStr = "через консоль";
            }
            else {
                string steamStr = steamId.ToString();
                string adminName = _covalence.Players.FindPlayerById(steamId.ToString())?.Name;
                initiatorStr = "администратором " + (string.IsNullOrEmpty(adminName) ? steamStr : $"{adminName} ({steamStr})");
            }
            string log = $"[{DateTime.Now.ToString(CultureInfo.InvariantCulture)}] Игрок {playerName} ({playerSteam}) {action} {initiatorStr}\n";
            Log.Debug(log);
            Log.File(log, "actions");
        }
        private void SyncStandartBans(string fileName, bool doMove) {
            string filePath = ConVar.Server.GetServerFolder("cfg") + "/" + fileName;
            if (!File.Exists(filePath)) {
                if (!doMove) {
                    Log.Debug("Нет банов для синхронизации");
                }
                return;
            }
            string fileText = File.ReadAllText(filePath);
            if (string.IsNullOrEmpty(fileText)) {
                if (!doMove) {
                    Log.Debug("Нет банов для синхронизации");
                }
                return;
            }
            var banRegex = new Regex("banid\\s+(\\d+)\\s+\"[^\"]*\"\\s+\"([^\"]*)\"", RegexOptions.Compiled);
            List<string> bans = fileText.Split('\n').ToList();
            for (int i = bans.Count - 1; i >= 0; i--) {
                Match match = banRegex.Match(bans[i]);
                if (!match.Success) {
                    continue;
                }
                string reason = match.Groups[2].Value;
                if (reason == "VAC" || reason == "EAC" || reason == "GAMEBAN") {
                    if (doMove) {
                        bans.RemoveAt(i);
                    }
                    continue;
                }
                ulong steam = ulong.Parse(match.Groups[1].Value);
                _bansData.AddBan(steam, reason, 0, 0, "0.0.0.0", 0, 0);
            }
            if (doMove) {
                try {
                    string backupFilePath = filePath + ".backup";
                    if (!File.Exists(backupFilePath)) {
                        File.WriteAllLines(backupFilePath, bans.ToArray());
                    }
                    else {
                        List<string> backupLines = File.ReadAllLines(backupFilePath).ToList();
                        foreach (string newLine in bans) {
                            if (backupLines.Contains(newLine)) {
                                continue;
                            }
                            backupLines.Add(newLine);
                        }
                        File.WriteAllLines(backupFilePath, backupLines.ToArray());
                    }
                    File.Delete(filePath);
                }
                catch {
                    // ignored
                }
            }
            Log.Debug($"Баны из файла {fileName} синхронизированы локально, идет синхронизация с сайтом");
            SyncBanList(_bansData.noSyncBans, (success) => {
                Log.Debug(success ? "Баны успешно синхронизированы" : "Во время синхронизации банов произошла ошибка, синхронизация будет повторена позже");
            }
            );
        }
        public static string FormatString(int str, string first, string second, string third) {
            string formatted = str + " ";
            if (str > 100) {
                str = str % 100;
            }
            if (str > 9 && str < 21) {
                formatted += third;
            }
            else {
                switch (str % 10) {
                    case 1 : formatted += first;
                    break;
                    case 2 : case 3 : case 4 : formatted += second;
                    break;
                    default : formatted += third;
                    break;
                }
            }
            return formatted;
        }
        [HookMethod("Init")]
        private void Init() {
            _plugin = this;
            try {
                _bansData = Interface.Oxide.DataFileSystem.ReadObject<BansData>("BanSystem");
            }
            catch {
                // ignored
            }
            if (_bansData == null) {
                _bansData = new BansData();
            }
            _exConfig = ExConfig.Parse(this);
            _permission.RegisterPermission(BanPermission, this);
            _permission.RegisterPermission(KickPermission, this);
            _permission.RegisterPermission(SyncPermission, this);
            _permission.RegisterPermission(UnbanPermission, this);
            _permission.RegisterPermission(StrikePermission, this);
            foreach (string hookName in Hooks.Keys) {
                if (hookName == nameof(OnServerInitialized) || hookName == nameof(OnPluginLoaded)) {
                    continue;
                }
                Unsubscribe(hookName);
            }
        }
        private string GetLangMessage(string key, string userId) => _lang.GetMessage(key, this, userId);
        private string GetLangMessage(string key, BasePlayer player) => GetLangMessage(key, player.UserIDString);
        [HookMethod("OnPluginLoaded")]
        private void OnPluginLoaded(Plugin plugin) {
            if (plugin.Name == "RustStore" && _initialized) {
                PostInitialize();
            }
        }
        private void PostInitialize() {
            if (_mainObject != null) return;
            _initialized = true;
            Plugin store = _plugins.Find("RustStore");
            if (store == null || !store.IsLoaded) {
                Log.Warning("Не найден обязательный плагин RustStore, ожидается его загрузка.");
                return;
            }
            Log.Debug("Синхронизация с магазином...");
            string storeId;
            string serverId;
            string serverKey;
            try {
                storeId = store.Config.Get<string>("номер магазина");
                serverId = store.Config.Get<string>("номер сервера");
                serverKey = store.Config.Get<string>("ключ сервера");
            }
            catch {
                Log.Error("Ошибка в данных для авторизации (конфиг RustStore).");
                Interface.Oxide.UnloadPlugin("BanSystem");
                return;
            }
            _mainObject = new GameObject("BanSystem" + Version);
            _webApi = new WebApi(_mainObject.AddComponent<WWWRequests>(), storeId, serverId, serverKey);
            _webApi.PostRequest(_webApi.InitData, (r, c) => {
                ConsoleSystem.Run(ConsoleSystem.Option.Unrestricted, "server.writecfg");
                ///SyncStandartBans("bans.cfg", true);
            }
            );
            var comLib = GetLibrary<Command>();
            comLib.AddConsoleCommand("bs.ban", this, BanConsoleCmd);
            comLib.AddConsoleCommand("bs.unban", this, UnbanConsoleCmd);
            comLib.AddConsoleCommand("bs.sync", this, SyncConsoleCmd);
            comLib.AddConsoleCommand("bs.kick", this, KickConsoleCmd);
            comLib.AddConsoleCommand("bs.strike", this, StrikeConsoleCmd);
            comLib.AddChatCommand("kick", this, KickChatCmd);
            comLib.AddChatCommand("ban", this, BanChatCmd);
            comLib.AddChatCommand("unban", this, UnbanChatCmd);
            comLib.AddChatCommand("strike", this, StrikeChatCmd);
            foreach (string hookName in Hooks.Keys) {
                Subscribe(hookName);
            }
        }
        [HookMethod("OnServerInitialized")]
        private void OnServerInitialized() {
            Interface.Oxide.NextTick(PostInitialize);
        }
        private void SyncBanList(IEnumerable<BansData.SyncBanData> syncList, Action<bool> onSync = null) {
            BansData.SyncBanData[] syncCopy = syncList.ToArray();
            if (syncCopy.Length == 0) {
                return;
            }
            _webApi.AddBanListData["data"] = JsonConvert.SerializeObject(syncCopy);
            _webApi.PostRequest(_webApi.AddBanListData, (success, res) => {
                if (!success) {
                    onSync?.Invoke(false);
                    return;
                }
                foreach (BansData.SyncBanData sync in syncCopy) {
                    _bansData.SyncBan(sync.steamID, 0, false);
                    ServerUsers.Remove(sync.steamID);
                }
                _bansData.Save();
                onSync?.Invoke(true);
            }
            );
        }
        [HookMethod("OnServerSave")]
        private void OnServerSave() {
            SyncBanList(_bansData.noSyncBans);
        }
        private void KickConnectionBan(Connection connection, string reason) {
            string steam = connection.userid.ToString();
            string rejectMessage = string.IsNullOrEmpty(reason) ? GetLangMessage("BAN.MESSAGE", steam) : GetLangMessage("BAN.MESSAGE.REASON", steam).Replace("{reason}", reason);
            ConnectionAuth.Reject(connection, rejectMessage);
        }
        [HookMethod("OnPlayerConnected")]
        private void OnPlayerConnected(BasePlayer player) {
            Connection connection = player.Connection;
            if (connection == null) {
                return;
            }
            ulong steam = connection.userid;
            ulong owner = connection.ownerid;
            if (owner == steam) {
                owner = 0;
            }
            BansData.SyncBanData noSynced = _bansData.noSyncBans.FirstOrDefault(p => p.steamID == steam || p.familyShare == steam || owner > 0 && (p.familyShare == owner || p.steamID == owner));
            if (noSynced != default(BansData.SyncBanData)) {
                KickConnectionBan(connection, noSynced.reason);
                return;
            }
            _webApi.CheckBanData["steamID"] = steam.ToString();
            _webApi.CheckBanData["familyShare"] = owner.ToString();
            _webApi.CheckBanData["ip"] = connection.ipaddress?.Remove(connection.ipaddress.Length - 6, 6) ?? string.Empty;
            _webApi.PostRequest(_webApi.CheckBanData, (success, resp) => {
                bool isLocalBanned = _bansData.IsPlayerBanned(steam);
                if (!success) {
                    if (isLocalBanned) {
                        KickConnectionBan(connection, string.Empty);
                    }
                    return;
                }
                if (resp.message != "banned") {
                    if (isLocalBanned) {
                        _bansData.RemoveBan(steam);
                    }
                    return;
                }
                if (!isLocalBanned) {
                    _bansData.SyncBan(steam, 0);
                }
                KickConnectionBan(connection, resp.data.ToString());
            }
            );
        }
        private bool FindPlayer(string pattern, out ulong steamId, out string name) {
            if (ulong.TryParse(pattern, out steamId) && steamId > 76561190000000000 && steamId < 76561199999999999) {
                name = _covalence.Players.FindPlayerById(steamId.ToString())?.Name ?? string.Empty;
                return true;
            }
            List<BasePlayer> players = BasePlayer.activePlayerList.Where(pl => !pl.IsSleeping() && pl.displayName.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) != -1).ToList();
            players.AddRange(BasePlayer.sleepingPlayerList.Where(pl => pl.displayName.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) != -1));
            if (players.Count == 0) {
                name = "Игрок с таким именем не найден";
                return false;
            }
            if (players.Count > 1) {
                name = $"Найдены совпадения по имени: {string.Join(" ", players.Select(p => p.displayName).ToArray())}";
                return false;
            }
            steamId = players[0].userID;
            name = players[0].displayName;
            return true;
        }
        private string KickPlayer(ulong initiator, string pattern, string reason) {
            if (reason == "-") {
                reason = string.Empty;
            }
            List<BasePlayer> players = BasePlayer.activePlayerList.Where(pl => pl.displayName.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) != -1).ToList();
            if (players.Count == 0) {
                return "Игрок с таким именем не найден";
            }
            if (players.Count > 1) {
                return $"Найдены совпадения по имени: {string.Join(" ", players.Select(p => p.displayName).ToArray())}";
            }
            BasePlayer ply = players[0];
            string name = ply.displayName;
            string steamStr = ply.UserIDString;
            Interface.Oxide.CallHook("OnBanSystemKick", ply, initiator);
            LogAdmin("был кикнут", initiator, name, steamStr);
            if (_exConfig.showGlobalKickMessage) {
                foreach (BasePlayer brodPlayer in BasePlayer.activePlayerList) {
                    brodPlayer.ChatMessage(GetLangMessage(string.IsNullOrEmpty(reason) ? "KICK.BROADCAST" : "KICK.BROADCAST.REASON", brodPlayer).Replace("{reason}", reason).Replace("{name}", name).Replace("{steamID}", steamStr));
                }
            }
            ply.Kick(reason);
            return $"Игрок {name} {steamStr} кикнут с сервера.";
        }
        private void BanPlayer(string player, string reason, string banTimeStr, ulong bannedBy, int single, Action<string> onMessage) {
            uint banTime;
            if (!ConvertToSeconds(banTimeStr, out banTime)) {
                onMessage("Ошибка в формате времени");
                return;
            }
            ulong steam;
            string name;
            if (!FindPlayer(player, out steam, out name)) {
                onMessage(name);
                return;
            }
            if (!string.IsNullOrEmpty(name)) {
                name += " ";
            }
            BanPlayer(name, steam, reason, banTime, bannedBy, single, onMessage);
        }
        private void BanPlayer(string name, ulong steam, string reason, uint banTime, ulong bannedBy, int single, Action<string> onMessage) {
            if (reason == "-") {
                reason = string.Empty;
            }
            string steamStr = steam.ToString();
            ulong owner = 0;
            string banTimeString = banTime == 0 ? "навсегда" : $"на {GetNiceTime(banTime, "д.", "ч.", "мин.", "сек.")}";
            var ip = "0.0.0.0";
            Connection con = BasePlayer.FindByID(steam)?.net?.connection;
            if (con != null) {
                ip = con.ipaddress;
                ip = ip.Remove(ip.IndexOf(':'));
                owner = con.ownerid;
                if (owner == steam) {
                    owner = 0;
                }
                KickConnectionBan(con, reason);
                if (owner > 0) {
                    Connection ownerCon = BasePlayer.FindByID(owner)?.net?.connection;
                    if (ownerCon != null) {
                        KickConnectionBan(ownerCon, "Family Share Ban");
                    }
                }
            }
            bool isBannedAlready = _bansData.IsPlayerBanned(steam);
            if (!isBannedAlready) {
                _bansData.AddBan(steam, reason, banTime, bannedBy, ip, owner, single);
            }
            if (_exConfig.showGlobalBanMessage && (con != null || _exConfig.showGlobalBanMessageOffline && !isBannedAlready)) {
                foreach (BasePlayer brodPlayer in BasePlayer.activePlayerList) {
                    brodPlayer.ChatMessage(banTime == 0 ? GetLangMessage(string.IsNullOrEmpty(reason) ? "BAN.BROADCAST.FOREVER" : "BAN.BROADCAST.FOREVER.REASON", brodPlayer).Replace("{reason}", reason).Replace("{name}", name).Replace("{steamID}", steamStr) : GetLangMessage(string.IsNullOrEmpty(reason) ? "BAN.BROADCAST" : "BAN.BROADCAST.REASON", brodPlayer).Replace("{reason}", reason).Replace("{name}", name).Replace("{steamID}", steamStr).Replace("{time}", GetNiceTime(banTime, GetLangMessage("DAY_SHORT", brodPlayer), GetLangMessage("HOUR_SHORT", brodPlayer), GetLangMessage("MIN_SHORT", brodPlayer), GetLangMessage("SEC_SHORT", brodPlayer))));
                }
            }
            _webApi.AddBanData["steamID"] = steam.ToString();
            _webApi.AddBanData["reason"] = reason;
            _webApi.AddBanData["banTime"] = banTime.ToString();
            _webApi.AddBanData["bannedBy"] = bannedBy.ToString();
            _webApi.AddBanData["ip"] = ip;
            _webApi.AddBanData["familyShare"] = owner.ToString();
            _webApi.AddBanData["singleBan"] = single.ToString();
            _webApi.PostRequest(_webApi.AddBanData, (success, res) => {
                if (!success) {
                    if (isBannedAlready) {
                        onMessage($"Игрок {name}{steam} уже забанен");
                    }
                    else {
                        Interface.Oxide.CallHook("OnBanSystemBan", steam, owner, reason, banTime, bannedBy, single);
                        LogAdmin($"был забанен {banTimeString}", bannedBy, name, steamStr);
                        onMessage($"Игрок {name}{steam} успешно забанен {banTimeString} локально, но при синхронизации произошла ошибка, бан будет синхронизирован с сайтом позже");
                    }
                    return;
                }
                _bansData.SyncBan(steam, owner);
                if (res.message == "userAlreadyBanned") {
                    onMessage($"Игрок {name}{steam} уже забанен");
                    return;
                }
                Interface.Oxide.CallHook("OnBanSystemBan", steam, owner, reason, banTime, bannedBy, single);
                LogAdmin($"был забанен {banTimeString}" , bannedBy, name, steamStr);
                onMessage($"Игрок {name}{steam} успешно забанен {banTimeString}");
            }
            );
        }
        private void StrikePlayer(string player, string reason, ulong initiator, Action<string> onMessage) {
            if (reason == "-") {
                reason = string.Empty;
            }
            ulong steamId;
            string name;
            if (!FindPlayer(player, out steamId, out name)) {
                onMessage(name);
                return;
            }
            if (!string.IsNullOrEmpty(name)) {
                name += " ";
            }
            List<string> strikes = _bansData.GiveStrike(steamId, reason).strikes;
            BasePlayer ply = BasePlayer.FindByID(steamId);
            if (ply != null && ply.IsConnected) {
                ply.ChatMessage(GetLangMessage(string.IsNullOrEmpty(reason) ? "STRIKE.MESSAGE" : "STRIKE.MESSAGE.REASON", ply).Replace("{reason}", reason).Replace("{strikeCount}", strikes.Count.ToString()).Replace("{banStrikeCount}", _exConfig.strikeBanCount.ToString()));
            }
            string steamStr = steamId.ToString();
            Interface.Oxide.CallHook("OnBanSystemStrike", steamId, reason, initiator);
            LogAdmin("был страйкнут", initiator, name, steamStr);
            if (_exConfig.showGlobalStrikeMessage) {
                string cntStr = strikes.Count.ToString();
                string maxCntStr = _exConfig.strikeBanCount.ToString();
                foreach (BasePlayer brodPlayer in BasePlayer.activePlayerList) {
                    brodPlayer.ChatMessage(GetLangMessage(string.IsNullOrEmpty(reason) ? "STRIKE.BROADCAST" : "STRIKE.BROADCAST.REASON", brodPlayer).Replace("{reason}", reason).Replace("{name}", name).Replace("{steamID}", steamStr).Replace("{strikeCount}", cntStr).Replace("{banStrikeCount}", maxCntStr));
                }
            }
            if (strikes.Count < _exConfig.strikeBanCount) {
                onMessage($"Игрок {name}{steamId} получил страйк.");
                return;
            }
            uint banTime;
            if (!ConvertToSeconds(_exConfig.strikeBanTime, out banTime)) {
                onMessage("Ошибка в формате времени");
                return;
            }
            string[] nonEmptyStrikes = strikes.Where(s => !string.IsNullOrEmpty(s)).ToArray();
            BanPlayer(name, steamId, GetLangMessage(nonEmptyStrikes.Length == 0 ? "BAN.STRIKE.FORMAT" : "BAN.STRIKE.FORMAT.REASON", steamId.ToString()).Replace("{STRIKES}", string.Join(", ", nonEmptyStrikes)), banTime, initiator, _exConfig.syncStrikeBans ? 0 : 1, onMessage);
        }
        private void UnbanPlayer(string player, ulong initiator, Action<string> onMessage) {
            ulong steamId;
            string name;
            if (!FindPlayer(player, out steamId, out name)) {
                onMessage(name);
                return;
            }
            if (!string.IsNullOrEmpty(name)) {
                name += " ";
            }
            _webApi.RemoveBanData["steamID"] = steamId.ToString();
            _webApi.RemoveBanData["bannedBy"] = initiator.ToString();
            _webApi.PostRequest(_webApi.RemoveBanData, (success, res) => {
                if (!success) {
                    onMessage("Что-то пошло не так в процессе разбана, попробуйте позже");
                    return;
                }
                _bansData.RemoveBan(steamId);
                ServerUsers.User serverUser = ServerUsers.Get(steamId);
                if (serverUser != null && serverUser.group == ServerUsers.UserGroup.Banned) {
                    ServerUsers.Remove(steamId);
                    ConsoleSystem.Run(ConsoleSystem.Option.Unrestricted, "server.writecfg");
                }
                else if (res.message == "userNotBanned") {
                    onMessage($"Игрок {name}{steamId} не был забанен");
                    return;
                }
                string steamStr = steamId.ToString();
                LogAdmin("был разбанен", initiator, name, steamStr);
                Interface.Oxide.CallHook("OnBanSystemUnban", steamId, initiator);
                onMessage($"Игрок {name}{steamId} успешно разбанен");
                if (!_exConfig.showGlobalUnbanMessage) {
                    return;
                }
                foreach (BasePlayer brodPlayer in BasePlayer.activePlayerList) {
                    brodPlayer.ChatMessage(GetLangMessage("UNBAN.BROADCAST", brodPlayer).Replace("{name}", name).Replace("{steamID}", steamStr));
                }
            }
            );
        }
        private void KickChatCmd(BasePlayer player, string command, string[] args) {
            if (player.net.connection.authLevel < 2 && !_permission.UserHasPermission(player.UserIDString, KickPermission)) {
                player.ChatMessage("Недостаточно прав");
                return;
            }
            if (args.Length == 0) {
                player.ChatMessage("Синтаксис: /kick {имя/стим} {причина}");
                return;
            }
            player.ChatMessage(KickPlayer(player.userID, args[0], args.Length > 1 ? args[1] : _exConfig.defaultKickReason));
        }
        private void StrikeChatCmd(BasePlayer player, string command, string[] args) {
            if (args.Length > 0 && args[0] == "info") {
                List<string> strikes = _bansData.GetStrikeData(player.userID)?.strikes;
                if (strikes == null) {
                    player.ChatMessage(GetLangMessage("STRIKE.INFO.EMPTY", player));
                    return;
                }
                string[] nonEmptyStrikes = strikes.Where(s => !string.IsNullOrEmpty(s)).ToArray();
                player.ChatMessage(GetLangMessage(nonEmptyStrikes.Length == 0 ? "STRIKE.INFO" : "STRIKE.INFO.REASON", player).Replace("{strikeCount}", strikes.Count.ToString()).Replace("{banStrikeCount}", _exConfig.strikeBanCount.ToString()).Replace("{STRIKES}", string.Join(", ", nonEmptyStrikes)));
                return;
            }
            if (player.net.connection.authLevel < 2 && !_permission.UserHasPermission(player.UserIDString, StrikePermission)) {
                player.ChatMessage("Недостаточно прав");
                return;
            }
            if (args.Length == 0) {
                player.ChatMessage("Синтаксис: /strike {имя/стим} {причина}");
                return;
            }
            StrikePlayer(args[0], args.Length > 1 ? args[1] : _exConfig.defaultStrikeReason, player.userID, player.ChatMessage);
        }
        private void BanChatCmd(BasePlayer player, string command, string[] args) {
            if (player.net.connection.authLevel < 2 && !_permission.UserHasPermission(player.UserIDString, BanPermission)) {
                player.ChatMessage("Недостаточно прав");
                return;
            }
            if (args.Length == 0) {
                player.ChatMessage("Синтаксис: /ban {имя/стим} {причина} {время}, /ban single {имя/стим} {причина} {время}");
                return;
            }
            int single = args[0] == "single" ? 1 : 0;
            if (single == 1 && args.Length == 1) {
                player.ChatMessage("Синтаксис: /ban {имя/стим} {причина} {время}, /ban single {имя/стим} {причина} {время}");
                return;
            }
            string banTime = _exConfig.defaultTime;
            string reason = _exConfig.defaultBanReason;
            if (args.Length >= 2 + single) {
                reason = args[1 + single];
                if (args.Length >= 3 + single) {
                    banTime = args[2 + single];
                }
            }
            BanPlayer(args[0 + single], reason, banTime, player.userID, single, player.ChatMessage);
        }
        private void UnbanChatCmd(BasePlayer player, string command, string[] args) {
            if (player.net.connection.authLevel < 2 && !_permission.UserHasPermission(player.UserIDString, UnbanPermission)) {
                player.ChatMessage("Недостаточно прав");
                return;
            }
            if (args.Length == 0) {
                player.ChatMessage("Синтаксис: /unban {имя/стим}");
                return;
            }
            UnbanPlayer(args[0], player.userID, player.ChatMessage);
        }
        private bool BanConsoleCmd(ConsoleSystem.Arg arg) {
            var bannedBy = 0UL;
            if (arg.Connection != null) {
                if (arg.Connection.authLevel < 2 && !_permission.UserHasPermission(arg.Connection.userid.ToString(), BanPermission)) {
                    return false;
                }
                bannedBy = arg.Connection.userid;
            }
            string name = arg.GetString(0);
            if (string.IsNullOrEmpty(name)) {
                arg.ReplyWith("Синтаксис: bs.ban {имя/стим} {причина} {время}, bs.ban single {имя/стим} {причина} {время}");
                return false;
            }
            int single = name == "single" ? 1 : 0;
            if (string.IsNullOrEmpty(arg.GetString(0 + single))) {
                arg.ReplyWith("Синтаксис: bs.ban {имя/стим} {причина} {время}, bs.ban single {имя/стим} {причина} {время}");
                return false;
            }
            BanPlayer(arg.GetString(0 + single), arg.GetString(1 + single, _exConfig.defaultBanReason), arg.GetString(2 + single, _exConfig.defaultTime), bannedBy, single, Log.Debug);
            return true;
        }
        private bool KickConsoleCmd(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2 && !_permission.UserHasPermission(arg.Connection.userid.ToString(), KickPermission)) {
                return false;
            }
            string name = arg.GetString(0);
            if (string.IsNullOrEmpty(name)) {
                arg.ReplyWith("Синтаксис: bs.kick {имя/стим} {причина}");
                return false;
            }
            ulong initiator = 0;
            if (arg.Connection != null) {
                initiator = arg.Connection.userid;
            }
            arg.ReplyWith(KickPlayer(initiator, name, arg.GetString(1, _exConfig.defaultKickReason)));
            return true;
        }
        private bool StrikeConsoleCmd(ConsoleSystem.Arg arg) {
            var strikedBy = 0UL;
            if (arg.Connection != null) {
                if (arg.Connection.authLevel < 2 && !_permission.UserHasPermission(arg.Connection.userid.ToString(), StrikePermission)) {
                    return false;
                }
                strikedBy = arg.Connection.userid;
            }
            string name = arg.GetString(0);
            if (string.IsNullOrEmpty(name)) {
                arg.ReplyWith("Синтаксис: bs.strike {имя/стим} {причина}");
                return false;
            }
            StrikePlayer(name, arg.GetString(1, _exConfig.defaultKickReason), strikedBy, Log.Debug);
            return true;
        }
        private bool SyncConsoleCmd(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2 && !_permission.UserHasPermission(arg.Connection.userid.ToString(), SyncPermission)) {
                return false;
            }
            ///SyncStandartBans("bans.cfg.backup", false);
            return true;
        }
        private bool UnbanConsoleCmd(ConsoleSystem.Arg arg) {
            var unbannedBy = 0UL;
            if (arg.Connection != null) {
                if (arg.Connection.authLevel < 2 && !_permission.UserHasPermission(arg.Connection.userid.ToString(), UnbanPermission)) {
                    return false;
                }
                unbannedBy = arg.Connection.userid;
            }
            string name = arg.GetString(0);
            if (string.IsNullOrEmpty(name)) {
                arg.ReplyWith("Синтаксис: bs.unban {имя/стим}");
                return false;
            }
            UnbanPlayer(name, unbannedBy, Log.Debug);
            return true;
        }
        [HookMethod("OnServerCommand")]
        private object OnServerCommand(ConsoleSystem.Arg arg) {
            string command = arg.cmd?.Name;
            if (command == null) {
                return null;
            }
            switch (command) {
                case "ban" : BanConsoleCmd(arg);
                return true;
                case "banid" : if (arg.Args.Length == 2) {
                    arg.Args = new[] {
                        arg.Args[0]
                    }
                    ;
                }
                else if (arg.Args.Length >= 3) {
                    arg.Args = new[] {
                        arg.Args[0], arg.Args[2]
                    }
                    ;
                }
                BanConsoleCmd(arg);
                return true;
                case "unban" : UnbanConsoleCmd(arg);
                return true;
                default : return null;
            }
        }
        public class WWWRequests : MonoBehaviour {
            private readonly HashSet<WWW> activeRequests = new HashSet<WWW>();
            public void Request(string url, Dictionary<string, string> data = null, Action<string, string> onRequestComplete = null) {
                StartCoroutine(WaitForRequest(url, data, onRequestComplete));
            }
            private IEnumerator WaitForRequest(string url, Dictionary<string, string> data = null, Action<string, string> onRequestComplete = null) {
                WWW www;
                if (data != null) {
                    var form = new WWWForm();
                    foreach (KeyValuePair<string, string> pair in data) {
                        form.AddField(pair.Key, pair.Value);
                    }
                    www = new WWW(url, form.data);
                }
                else {
                    www = new WWW(url);
                }
                www.threadPriority = ThreadPriority.High;
                activeRequests.Add(www);
                yield return www;
                onRequestComplete?.Invoke(www.text, www.error);
                activeRequests.Remove(www);
            }
            private void OnDestroy() {
                foreach (WWW www in activeRequests) {
                    try {
                        www.Dispose();
                    }
                    catch {
                    }
                }
            }
        }
        public class WebApi {
            public class JsonResponse {
                public string message = "empty";
                public string status = "empty";
                public JToken data;
                public JsonResponse() {
                }
                public bool IsSuccess() => status == "success";
            }
            private readonly WWWRequests _requests;
            private const string BaseUrl = "https://store-api.moscow.ovh/index.php";
            public readonly Dictionary<string, string> InitData = new Dictionary<string, string>() {
                ["modules"]
                = "servers", ["action"] = "checkAuth"
            }
            ;
            public readonly Dictionary<string, string> CheckBanData = new Dictionary<string, string>() {
                ["modules"]
                = "banlist", ["action"] = "checkUserBan", ["steamID"] = "0", ["familyShare"] = "0", ["ip"] = "0.0.0.0"
            }
            ;
            public readonly Dictionary<string, string> AddBanData = new Dictionary<string, string>() {
                ["modules"]
                = "banlist", ["action"] = "addBan", ["steamID"] = "0", ["reason"] = "", ["banTime"] = "0", ["bannedBy"] = "0", ["ip"] = "0.0.0.0", ["familyShare"] = "0", ["singleBan"] = "0"
            }
            ;
            public readonly Dictionary<string, string> AddBanListData = new Dictionary<string, string>() {
                ["modules"]
                = "banlist", ["action"] = "importBans", ["data"] = ""
            }
            ;
            public readonly Dictionary<string, string> RemoveBanData = new Dictionary<string, string>() {
                ["modules"]
                = "banlist", ["action"] = "removeBan", ["steamID"] = "0", ["bannedBy"] = "0"  //["ip"] = "0"
            }
            ;
            public WebApi(WWWRequests www, string storeId, string serverId, string serverKey) {
                _requests = www;
                InitData["storeID"] = storeId;
                InitData["serverID"] = serverId;
                InitData["serverKey"] = serverKey;
                CheckBanData["storeID"] = storeId;
                CheckBanData["serverID"] = serverId;
                CheckBanData["serverKey"] = serverKey;
                AddBanData["storeID"] = storeId;
                AddBanData["serverID"] = serverId;
                AddBanData["serverKey"] = serverKey;
                AddBanListData["storeID"] = storeId;
                AddBanListData["serverID"] = serverId;
                AddBanListData["serverKey"] = serverKey;
                RemoveBanData["storeID"] = storeId;
                RemoveBanData["serverID"] = serverId;
                RemoveBanData["serverKey"] = serverKey;
            }
            public void PostRequest(Dictionary<string, string> data, Action<bool, JsonResponse> response = null) {
                _requests.Request(BaseUrl, data, (res, error) => {
                    if (!string.IsNullOrEmpty(error) || string.IsNullOrEmpty(res)) {
                        Log.File($"Request error: {error}", "errors");
                        response?.Invoke(false, new JsonResponse() {
                            status = "RequestError", message = error
                        }
                        );
                        return;
                    }
                    JsonResponse converted = null;
                    try {
                        var settings = new JsonSerializerSettings {
                            StringEscapeHandling = StringEscapeHandling.EscapeHtml
                        }
                        ;
                        converted = JsonConvert.DeserializeObject<JsonResponse>(res, settings);
                    }
                    catch {
                        // ignored
                    }
                    if (converted == null) {
                        Log.File($"JsonError: {res}", "errors");
                        response?.Invoke(false, new JsonResponse() {
                            status = "JsonError", message = res
                        }
                        );
                        return;
                    }
                    if (!converted.IsSuccess()) {
                        switch (converted.message) {
                            case "unload" : Log.Debug("Плагин отключен в настройках магазина.");
                            Interface.Oxide.UnloadPlugin("BanSystem");
                            return;
                            case "invalidStoreAuth" : case "invalidServerAuth" : Log.Error("Ошибка авторизации.");
                            Interface.Oxide.UnloadPlugin("BanSystem");
                            return;
                        }
                        response?.Invoke(false, converted);
                        return;
                    }
                    response?.Invoke(true, converted);
                }
                );
            }
        }
        public static class Log {
            public static void File(string text, string title = "info") {
                text = $"[{DateTime.Now:HH:mm:ss}] {text}";
                _plugin.LogToFile($"{title}-{DateTime.Now:yyyy-MM-dd}.txt", text, _plugin);
            }
            public static void Debug(string format) {
                UnityEngine.Debug.Log($"[BanSystem] {format}");
            }
            public static void Error(string format, params object[] args) {
                UnityEngine.Debug.LogError($"[BanSystem] {string.Format(format, args)}");
            }
            public static void Warning(string format, params object[] args) {
                UnityEngine.Debug.LogWarning($"[BanSystem] {string.Format(format, args)}");
            }
        }
        public class ExConfig {
            private readonly Dictionary<string, string> _messages = new Dictionary<string, string>() {
                ["BAN.MESSAGE"]
                = "Вы забанены на этом сервере", ["BAN.MESSAGE.REASON"] = "Вы забанены на этом сервере, причина: {reason}", ["BAN.STRIKE.FORMAT"] = "Страйк бан", ["BAN.STRIKE.FORMAT.REASON"] = "Страйк бан: {STRIKES}", ["BAN.BROADCAST"] = "Игрок {name} ({steamID}) был забанен на {time}.", ["BAN.BROADCAST.REASON"] = "Игрок {name} ({steamID}) был забанен на {time}.\nПричина: {reason}", ["BAN.BROADCAST.FOREVER"] = "Игрок {name} ({steamID}) был забанен навсегда.", ["BAN.BROADCAST.FOREVER.REASON"] = "Игрок {name} ({steamID}) был забанен навсегда.\nПричина: {reason}", ["STRIKE.INFO"] = "Вы получили {strikeCount}/{banStrikeCount} страйков.", ["STRIKE.INFO.EMPTY"] = "Вы не получали страйков.", ["STRIKE.INFO.REASON"] = "Вы получили {strikeCount}/{banStrikeCount} страйков, причины: {STRIKES}", ["STRIKE.MESSAGE"] = "Вы получили страйк, всего страйков {strikeCount}/{banStrikeCount}", ["STRIKE.MESSAGE.REASON"] = "Вы получили страйк, причина: {reason}, всего страйков {strikeCount}/{banStrikeCount}", ["STRIKE.BROADCAST"] = "Игрок {name} ({steamID}) получил страйк.\nВсего страйков игрока {strikeCount}/{banStrikeCount}", ["STRIKE.BROADCAST.REASON"] = "Игрок {name} ({steamID}) получил страйк.\nПричина: {reason}.\nВсего страйков игрока {strikeCount}/{banStrikeCount}", ["KICK.BROADCAST"] = "Игрок {name} ({steamID}) был кикнут.", ["KICK.BROADCAST.REASON"] = "Игрок {name} ({steamID}) был кикнут.\nПричина: {reason}", ["UNBAN.BROADCAST"] = "Игрок {name} ({steamID}) был разбанен.", ["DAY_SHORT"] = "д ", ["HOUR_SHORT"] = "ч ", ["MIN_SHORT"] = "мин ", ["SEC_SHORT"] = "сек "
            }
            ;
            [JsonProperty("Время бана по умолчанию")]
            public string defaultTime = "0";
            [JsonProperty("Причина бана по умолчанию")]
            public string defaultBanReason = "";
            [JsonProperty("Причина кика по умолчанию")]
            public string defaultKickReason = "";
            [JsonProperty("Причина страйка по умолчанию")]
            public string defaultStrikeReason = "";
            [JsonProperty("Время бана за страйки")]
            public string strikeBanTime = "1d";
            [JsonProperty("Количество страйков для бана")]
            public ushort strikeBanCount = 3;
            [JsonProperty("Синхронизировать баны за страйки с другими серверами")]
            public bool syncStrikeBans = false;
            [JsonProperty("Оповещение о бане")]
            public bool showGlobalBanMessage = true;
            [JsonProperty("Оповещение о бане игрока, который не находится на сервере")]
            public bool showGlobalBanMessageOffline = false;
            [JsonProperty("Оповещение о разбане")]
            public bool showGlobalUnbanMessage = false;
            [JsonProperty("Оповещение о кике")]
            public bool showGlobalKickMessage = true;
            [JsonProperty("Оповещение о страйке")]
            public bool showGlobalStrikeMessage = true;
            private CSPlugin _pluginOwner;
            private void Initialize() {
                CSPlugin.GetLibrary<Lang>().RegisterMessages(_messages, _pluginOwner);
            }
            public static ExConfig Parse(RustPlugin plugin) {
                DynamicConfigFile pluginConfig = plugin.Config;
                ExConfig output = null;
                // Parsing config
                try {
                    output = pluginConfig.ReadObject<ExConfig>();
                }
                catch {
                    // ignored
                }
                if (output == null) {
                    pluginConfig.Save($"{pluginConfig.Filename}.jsonError");
                    Log.Debug("Lol");
                    output = new ExConfig();
                    Log.Error("Файл конфигурации \"{0}\" содержит ошибку и был заменен на стандартный.\n" + "Ошибочный файл конфигурации сохранен под названием \"{0}.jsonError\"", GetFileName(pluginConfig.Filename));
                }
                pluginConfig.WriteObject(output);
                output._pluginOwner = plugin;
                output.Initialize();
                return output;
            }
        }
        public class BansData {
            public HashSet<StrikeData> strikes = new HashSet<StrikeData>();
            public HashSet<SyncBanData> noSyncBans = new HashSet<SyncBanData>();
            public HashSet<ulong> bans = new HashSet<ulong>();
            public class SyncBanData {
                public ulong steamID;
                public ulong familyShare;
                public ulong bannedBy;
                public string reason;
                public string ip;
                public uint banTime;
                public int singleBan;
                public SyncBanData() {
                }
            }
            public class StrikeData {
                public ulong steamID;
      
// ... [Code preview truncated due to length. Full source in attached file] ...

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