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

FREE ServerArmour : 2.83.7 2.83.7

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using ConVar;
using Facepunch;
using Facepunch.Extend;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Libraries;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using WebSocketSharp;
using Application = UnityEngine.Application;
using Time = Oxide.Core.Libraries.Time;
#pragma warning disable 8600
#pragma warning disable 8601
namespace Oxide.Plugins {
    [Info("Server Armour", "Pho3niX90", "2.83.7")]
    [Description("Protect your server! Auto ban known hackers, scripters and griefer accounts, and notify server owners of threats.")]
    class ServerArmour : CovalencePlugin {
#if CARBON
        bool isCarbon = true;
#else
        bool isCarbon = false;
#endif
#region Variables
        string api_hostname = "https://serverarmour.com";
        //
        Dictionary<string, ISAPlayer> _playerData = new Dictionary<string, ISAPlayer>();
        private Time _time = GetLibrary<Time>();
        private double cacheLifetime = 1;
        // minutes
        private SAConfig config;
        string specifier = "G";
        CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
        //StringComparison defaultCompare = StringComparison.InvariantCultureIgnoreCase;
        const string DATE_FORMAT = "yyyy/MM/dd HH:mm";
        const string DATE_FORMAT2 = "yyyy-MM-dd HH:mm:ss";
        const string DATE_FORMAT_BAN = "yyyy-MM-ddTHH:mm:ss.fffZ";
        Regex logRegex = new Regex(@"(^assets.*prefab).*?position (.*) on");
        Regex logRegexNull = new Regex(@"(.*) changed its network group to null");
        bool debug = false;
        bool apiConnected = false;
        bool serverStarted = false;
        int serverId;
        private Dictionary<string, string> headers;
        string adminIds = "";
        Timer updateTimer;
        // related to auto updating
        Dictionary<string, byte[]> fileBackups = new Dictionary<string, byte[]>();
        List<string> ignoredPlugins = new List<string>();
#endregion
#region Libraries
        private readonly Game.Rust.Libraries.Player Player = Interface.Oxide.GetLibrary<Game.Rust.Libraries.Player>();
#endregion
#region Permissions
        const string PermissionToBan = "serverarmour.ban";
        const string PermissionToUnBan = "serverarmour.unban";
        const string PermissionAdminWebsite = "serverarmour.website.admin";
        const string PermissionWhitelistRecentVacKick = "serverarmour.whitelist.recentvac";
        const string PermissionWhitelistBadIPKick = "serverarmour.whitelist.badip";
        const string PermissionWhitelistVacCeilingKick = "serverarmour.whitelist.vacceiling";
        const string PermissionWhitelistServerCeilingKick = "serverarmour.whitelist.banceiling";
        const string PermissionWhitelistGameBanCeilingKick = "serverarmour.whitelist.gamebanceiling";
        const string PermissionWhitelistTotalBanCeiling = "serverarmour.whitelist.totalbanceiling";
        const string PermissionWhitelistSteamProfile = "serverarmour.whitelist.steamprofile";
        const string PermissionWhitelistFamilyShare = "serverarmour.whitelist.familyshare";
        const string PermissionWhitelistTwitterBan = "serverarmour.whitelist.twitterban";
        const string PermissionWhitelistAllowCountry = "serverarmour.whitelist.allowcountry";
        const string PermissionWhitelistAllowHighPing = "serverarmour.whitelist.allowhighping";
        const string DISCORD_INTRO_URL = "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
        /**
         * Plugin Name, Download Url
         */
        Dictionary<string, string> requiredPlugins = new Dictionary<string, string> {
            {
                "DiscordApi", "https://serverarmour.com/api/v1/shop/product/379a27d9-d245-43c9-ad8f-332efa8a25e6/download"
            }
            , {
                "CombatLogInfo", "https://serverarmour.com/api/v1/shop/product/4195c37c-8eb5-47f6-8908-45aaa06df59c/download"
            }
        }
        ;
        // int serverId = 0;
#endregion
#region Plugins
#pragma warning disable 0649
        [PluginReference]
        Plugin DiscordApi, DiscordMessages, BetterChat, Ember, Clans, AdminToggle, CombatLogInfo, ServerArmourUpdater;
#pragma warning restore 0649
        void DiscordSend(string steamId, string name, EmbedFieldList report, int color = 39423, bool isBan = false) {
            string webHook;
            if (isBan) {
                if (config.DiscordBanWebhookURL.IsNullOrEmpty() || config.DiscordBanWebhookURL.Equals(DISCORD_INTRO_URL)) {
                    Puts("Discord webhook not setup.");
                    return;
                }
                webHook = config.DiscordBanWebhookURL;
            }
            else {
                if (config.DiscordWebhookURL.IsNullOrEmpty() || config.DiscordWebhookURL.Equals(DISCORD_INTRO_URL)) {
                    Puts("Discord webhook not setup.");
                    return;
                }
                webHook = config.DiscordWebhookURL;
            }
            List<EmbedFieldList> fields = new List<EmbedFieldList>();
            if (config.DiscordQuickConnect) {
                fields.Add(new EmbedFieldList() {
                    name = server.Name, value = $"[steam://connect/{config.ServerIp}:{server.Port}](steam://connect/{config.ServerIp}:{server.Port})", inline = true
                }
                );
            }
            fields.Add(new EmbedFieldList() {
                name = "Steam Profile", value = $"[{name}\n{steamId}](https://steamcommunity.com/profiles/{steamId})", inline = !config.DiscordQuickConnect
            }
            );
            fields.Add(new EmbedFieldList() {
                name = "Server Armour Profile ", value = $"[{name}\n{steamId}](https://serverarmour.com/profile/{steamId})", inline = !config.DiscordQuickConnect
            }
            );
            fields.Add(report);
            var fieldsObject = fields.Cast<object>().ToArray();
            string json = JsonConvert.SerializeObject(fieldsObject);
            if (DiscordApi != null && DiscordApi.IsLoaded) {
                DiscordApi?.Call("API_SendEmbeddedMessage", webHook, "Server Armour Report: ", color, json);
            }
            else if (DiscordMessages != null && DiscordMessages.IsLoaded) {
                DiscordMessages?.Call("API_SendFancyMessage", webHook, "Server Armour Report: ", color, json);
            }
            else {
                LogWarning("No discord API plugin loaded, will not publish to hook!");
            }
        }
        void CheckPing(IPlayer player) {
            // fix: https://discord.com/channels/751155344532570223/751155561776808158/1160293816104914974
            if (player == null || !player.IsConnected) return;
            try {
                if (!HasPerm(player.Id, PermissionWhitelistAllowHighPing) && (config.AutoKickMaxPing > 0 && config.AutoKickMaxPing < player.Ping)) {
                    KickPlayer(player.Id, GetMsg("Your Ping is too High", new Dictionary<string, string> {
                        ["ping"]
                        = player.Ping.ToString(), ["maxPing"] = config.AutoKickMaxPing.ToString()
                    }
                    ), "C");
                }
            }
            catch (Exception ex) {
            }
        }
#endregion
#region Hooks
        void OnServerSave() {
            if (config.AutoKickMaxPing > 0) foreach (var player in players.Connected) timer.Once(5f, () => CheckPing(player));
        }
        void OnServerInitialized(bool first) {
            LoadData();
            if (first) {
                //quick fix to ignore bans on server restart.(rust rebanning.)
                Unsubscribe(nameof(OnUserBanned));
                timer.Once(60, () => {
                    Subscribe(nameof(OnUserBanned));
                    serverStarted = true;
                }
                );
            }
            else {
                serverStarted = true;
            }
            // CheckOnlineUsers();
            // CheckLocalBans();
            string ServerGPort = ConVar.Server.port.ToString();
            string ServerQPort = ConVar.Server.queryport > 0 ? ConVar.Server.queryport.ToString() : ServerGPort;
            string ServerRPort = RCon.Port.ToString();
            Puts($"Server Ports are, Game Port: {ServerGPort} | Query Port:{ServerQPort} | RCON Port: {ServerRPort}");
            RegPerm(PermissionToBan);
            RegPerm(PermissionToUnBan);
            RegPerm(PermissionAdminWebsite);
            RegPerm(PermissionWhitelistBadIPKick);
            RegPerm(PermissionWhitelistRecentVacKick);
            RegPerm(PermissionWhitelistServerCeilingKick);
            RegPerm(PermissionWhitelistVacCeilingKick);
            RegPerm(PermissionWhitelistGameBanCeilingKick);
            RegPerm(PermissionWhitelistTotalBanCeiling);
            RegPerm(PermissionWhitelistSteamProfile);
            RegPerm(PermissionWhitelistFamilyShare);
            RegPerm(PermissionWhitelistTwitterBan);
            RegPerm(PermissionWhitelistAllowCountry);
            RegPerm(PermissionWhitelistAllowHighPing);
            RegisterTag();
            string framework = this.isCarbon ? "Carbon" : "Oxide";
            headers = new Dictionary<string, string> {
                {
                    "server-key", config.ServerApiKey
                }
                , {
                    "Accept", "application/json"
                }
                , {
                    "Content-Type", "application/x-www-form-urlencoded"
                }
                , {
                    "User-Agent", $"Server Armour/{this.Version} <{framework}>"
                }
            }
            ;
            string[] _admins = permission.GetUsersInGroup("admin");
            if (config.OwnerSteamId != null && config.OwnerSteamId.Length > 0 && !_admins.Contains(config.OwnerSteamId)) {
                var adminsList = new List<string>();
                adminsList.AddRange(_admins);
                adminsList.AddRange(config.OwnerSteamId.Split(','));
                var extraAdmins = permission.GetPermissionUsers(PermissionAdminWebsite);
                if (extraAdmins != null && extraAdmins.Length > 0) {
                    adminsList.AddRange(extraAdmins);
                }
                int e = 0;
                foreach (string extraAdminsGroups in permission.GetPermissionGroups(PermissionAdminWebsite)) {
                    foreach (string extraAdmin in permission.GetUsersInGroup(extraAdminsGroups)) {
                        if (!adminsList.Contains(extraAdmin)) {
                            adminsList.Add(extraAdmin);
                            e++;
                        }
                    }
                }
                _admins = adminsList.Distinct().ToArray();
            }
            for (int i = 0, n = _admins.Length; i < n; i++) {
                adminIds += $"{_admins[i].Substring(0, 17)}" + (i < _admins.Length - 1 ? "," : string.Empty);
            }
            CheckServerConnection();
            Application.logMessageReceived += HandleLog;
            if (ServerArmourUpdater != null && ServerArmourUpdater.IsLoaded) {
                foreach (var item in plugins.GetAll()) {
                    if (item.Filename == null || item.Filename.Length == 0) continue;
                    if (requiredPlugins.ContainsKey(item.Name)) requiredPlugins.Remove(item.Name);
                }
                Puts($"Needed plugins = {requiredPlugins.Count}");
                foreach (var plugin in requiredPlugins) {
                    ServerArmourUpdater?.Call("QueueDownload", plugin.Key, plugin.Value, "Server Armour");
                }
            }
        }
        void CheckServerConnection() {
            string body = ServerGetString();
            DoRequest("check_server", body, (code, response) => {
                JObject obj = null;
                try {
                    obj = JObject.Parse(response);
                }
                catch (Exception) {
                    LogWarning($"Response issue: ({code}) {response}");
                    timer.Once(15, CheckServerConnection);
                    return;
                }
                if (obj != null) {
                    var msg = obj["message"].ToString();
                    try {
                        this.serverId = int.Parse(obj["serverId"].ToString());
                    }
                    catch (Exception) {
                    }
                    Puts(msg);
                    if (msg.Equals("connected")) {
                        apiConnected = true;
                        Puts($"Connected to SA API | Server ID = {this.serverId}");
                        ServerStatusUpdate();
                        updateTimer = timer.Every(60, ServerStatusUpdate);
                    }
                    else {
                        Puts($"ServerApiKey = {config.ServerApiKey}");
                        var errMsg = "Server Armour has not initialized.Is your apikey correct? Get it from https://serverarmour.com/my-servers or join discord for support https://discord.gg/jxvRaPR";
                        LogError(errMsg);
                        timer.Once(500, () => LogError(errMsg));
                        return;
                    }
                    Puts("Server Armour has initialized.");
                }
                else {
                    timer.Once(5, CheckServerConnection);
                    return;
                }
            }
            );
        }
        void Unload() {
            _playerData?.Clear();
            _playerData = null;
            Application.logMessageReceived -= HandleLog;
            if (updateTimer != null && !updateTimer.Destroyed) updateTimer.Destroy();
        }
        void OnUserConnected(IPlayer iPlayer) {
            this.DoConnectionChecks(iPlayer);
        }
        void DoConnectionChecks(IPlayer player, string type = "C") {
            if (!apiConnected) {
                LogError("User not checked.Server armour is not loaded.");
            }
            else {
                //lets check the userid first.if (config.AutoKick_KickWeirdSteam64 && !player.Id.IsSteamId())
                {
                    KickPlayer(player.Id, GetMsg("Strange Steam64ID"), type);
                    return;
                }
                GetPlayerBans(player);
                try {
                    var connectedSeconds = GetConnectedSeconds(player);
                    if (connectedSeconds < 600) timer.Once(120, () => {
                        DoConnectionChecks(player);
                    }
                    );
                    if (config.ShowProtectedMsg && connectedSeconds < 60) SendReplyWithIcon(player, GetMsg("Protected MSG"));
                }
                catch (Exception) {
                }
            }
        }
        int GetConnectedSeconds(IPlayer player) {
            return BasePlayer.FindByID(ulong.Parse(player.Id))?.secondsConnected ?? int.MaxValue;
        }
        int GetConnectedSeconds(ISAPlayer player) {
            return BasePlayer.FindByID(ulong.Parse(player.steamid))?.secondsConnected ?? int.MaxValue;
        }
        void OnUserDisconnected(IPlayer player) {
            if (apiConnected) {
                try {
                    _playerData = _playerData?.Where(pair => MinutesAgo((uint)pair.Value.cacheTimestamp) < cacheLifetime) ?.ToDictionary(pair => pair.Key, pair => pair.Value);
                }
                catch (Exception) {
                }
            }
        }
        void OnPluginLoaded(Plugin plugin) {
            if (plugin.Title == "BetterChat") RegisterTag();
        }
        /**
         * To detect publisher bans
         */
        void OnPlayerKicked(BasePlayer player, string reason) {
            if (reason.Contains("PublisherBanned")) {
                DoRequest($"player/eacban", $"reason={reason}&steamId={player.UserIDString}&username={player.displayName}&serverId={this.serverId}", (code, response) => {
                }
                , RequestMethod.POST);
            }
        }
        void OnUserUnbanned(string name, string id, string ipAddress) {
            DoPardon(id);
        }
        void OnUserBanned(string name, string id, string ipAddress, string reason) {
            //this is to make sure that if an app like battlemetrics for example, bans a player, we catch it.if (config.IgnoreCheatDetected && reason.StartsWith("Cheat Detected"))
            {
                return;
            }
            try {
                if (AdminToggle != null && AdminToggle.Call<bool>("IsAdmin", id)) {
                    return;
                }
            }
            catch (Exception) {
            }
            timer.Once(10f, () => {
                //lets make sure first it wasn't us.if (!IsPlayerCached(id) && (IsPlayerCached(id) && !ContainsMyBan(id)))
                {
                    // LogDebug($"Player wasn't banned via Server Armour, now adding to DB with a default lengh ban of 100yrs {name} ({id}) at {ipAddress} was banned: {reason}");
                    IPlayer bPlayer = players.FindPlayerById(id);
                    if (bPlayer != null) {
                        if ((bPlayer.IsAdmin && config.IgnoreAdmins)) return;
                        // LogDebug("Before AddBan");
                        AddBan(new ISABan {
                            steamid = ulong.Parse(bPlayer.Id), serverName = server.Name, serverIp = config.ServerIp, reason = reason, created = DateTime.Now.ToString(DATE_FORMAT), banUntil = DateTime.Now.AddYears(100).ToString(DATE_FORMAT)
                        }
                        , false);
                    }
                }
            }
            );
        }
        void OnPlayerReported(BasePlayer reporter, string targetName, string targetId, string subject, string message, string type) {
            if (!serverStarted) return;
            string messageClean = Uri.EscapeDataString(message);
            string subjectClean = Uri.EscapeDataString(subject);
            DoRequest($"player/{reporter.UserIDString}/addf7", $"target={targetId}&subject={subjectClean}&message={messageClean}", (c, s) => {
            }
            );
        }
#endregion
#region Checks
        void GetPlayerRiskScore(ulong steamId) {
            GetJson($"player/{steamId}/risk", (c, s) => {
                if (c < 300) {
                    double riskscore = 0;
                    double.TryParse(s.GetValue("score").ToString(), out riskscore);
                    // TODO check the risk
                }
            }
            );
        }
#endregion
#region API_Hooks
#endregion
#region WebRequests
        void GetPlayerBans(IPlayer player) {
            if (player == null || player.Id == null) return;
            KickIfBanned(GetPlayerCache(player?.Id));
            WebCheckPlayer(player.Id, player.Address, player.IsConnected);
            timer.Once(10f, () => CheckPing(player));
        }
        void GetPlayerBans(string playerId, string playerName) {
            KickIfBanned(GetPlayerCache(playerId));
            WebCheckPlayer(playerId, "0.0.0.0", true);
        }
        void WebCheckPlayer(string id, string address, bool connected) {
            if (!serverStarted) return;
            DoRequest($"player/{id}?bans=true&linked={config.AutoKick_ActiveBans.ToString().ToLowerInvariant()}", $"ipAddress={address}", (code, response) => {
                // LogDebug("Getting player from API");
                ISAPlayer isaPlayer = null;
                try {
                    isaPlayer = JsonConvert.DeserializeObject<ISAPlayer>(response);
                }
                catch (Exception) {
                    timer.Once(30, () => WebCheckPlayer(id, address, connected));
                    return;
                }
                if (isaPlayer == null) {
                    return;
                }
                isaPlayer.cacheTimestamp = _time.GetUnixTimestamp();
                isaPlayer.lastConnected = _time.GetUnixTimestamp();
                // add cache for player
                // LogDebug("Checking cache");
                if (!IsPlayerCached(isaPlayer.steamid)) {
                    AddPlayerCached(isaPlayer);
                }
                else {
                    UpdatePlayerData(isaPlayer);
                }
                // lets check bans first
                try {
                    KickIfBanned(isaPlayer);
                }
                catch (Exception ane) {
                    Puts("An ArgumentNullException occured.Please notify the developer along with the below information: ");
                    Puts(response);
                    Puts(ane.StackTrace);
                }
                //script vars
                string pSteamId = isaPlayer.steamid ?? id;
                //string lSteamId = GetFamilyShare(isaPlayer.steamid);
                //
                LogDebug("Check for a twitter/eac game ban");
                if (config.AutoKick_KickTwitterGameBanned && !HasPerm(pSteamId, PermissionWhitelistTwitterBan) && isaPlayer.eacBans.Count > 0) {
                    KickPlayer(isaPlayer?.steamid, $"https://twitter.com/rusthackreport/status/{isaPlayer.eacBans[isaPlayer.eacBans.Count - 1].id}", "C");
                }
                LogDebug($"Check for a recent vac: DissallowVacBanDays = {config?.DissallowVacBanDays}, steamDaysSinceLastBan = {isaPlayer?.steamDaysSinceLastBan}, steamNumberOfVACBans = {isaPlayer?.steamNumberOfVACBans}, steamDaysSinceLastBan = {isaPlayer?.steamDaysSinceLastBan}, whitelisted = {HasPerm(pSteamId, PermissionWhitelistRecentVacKick)}");
                bool pRecentVac = (isaPlayer.steamNumberOfVACBans > 0 || isaPlayer.steamDaysSinceLastBan > 0) && isaPlayer.steamDaysSinceLastBan < config.DissallowVacBanDays;
                //check main player
                //bool lRecentVac = (isaPlayer.lender?.steamNumberOfVACBans > 0 || isaPlayer.lender?.steamDaysSinceLastBan > 0)
                //&& isaPlayer.lender?.steamDaysSinceLastBan < config.DissallowVacBanDays; //check the lender player
                if (config.AutoKickOn && !HasPerm(pSteamId, PermissionWhitelistRecentVacKick) && pRecentVac) {
                    int vacLast = isaPlayer.steamDaysSinceLastBan;
                    int until = config.DissallowVacBanDays - vacLast;
                    Interface.CallHook("OnSARecentVacKick", vacLast, until);
                    string msg = GetMsg(pRecentVac ? "Reason: VAC Ban Too Fresh" : "Reason: VAC Ban Too Fresh - Lender", new Dictionary<string, string> {
                        ["daysago"]
                        = vacLast.ToString(), ["daysto"] = until.ToString()
                    }
                    );
                    KickPlayer(isaPlayer?.steamid, msg, "C");
                }
                LogDebug("Check for too many vac bans");
                if (!HasPerm(pSteamId, PermissionWhitelistVacCeilingKick) && HasReachedVacCeiling(isaPlayer)) {
                    Interface.CallHook("OnSATooManyVacKick", pSteamId, isaPlayer?.steamNumberOfVACBans);
                    KickPlayer(isaPlayer?.steamid, GetMsg("VAC Ceiling Kick"), "C");
                }
                LogDebug("Check for too many game bans");
                if (!HasPerm(pSteamId, PermissionWhitelistGameBanCeilingKick) && HasReachedGameBanCeiling(isaPlayer)) {
                    Interface.CallHook("OnSATooManyGameBansKick", pSteamId, isaPlayer.steamNumberOfGameBans);
                    KickPlayer(isaPlayer?.steamid, GetMsg("Too Many Previous Game Bans"), "C");
                }
                // LogDebug("Check for players with too many server bans");
                //if (!HasPerm(pSteamId, PermissionWhitelistServerCeilingKick) && HasReachedServerCeiling(isaPlayer))
                //{
                //    Interface.CallHook("OnSATooManyServerBans", pSteamId, config.AutoKickCeiling, ServerBanCount(isaPlayer) + ServerBanCount(isaPlayer.lender));
                //    KickPlayer(isaPlayer?.steamid, GetMsg("Too Many Previous Bans"), "C");
                //}
                //if (!HasPerm(PermissionWhitelistTotalBanCeiling, pSteamId) && HasReachedTotalBanCeiling(isaPlayer))
                //{
                //    Interface.CallHook("OnSATooManyBans", pSteamId, config.AutoKickCeiling, TotalBans(isaPlayer.lender));
                //    KickPlayer(isaPlayer?.steamid, GetMsg("Too Many Previous Bans"), "C");
                //}
                LogDebug("Check for players with a private profile");
                if (!HasPerm(pSteamId, PermissionWhitelistSteamProfile) && config.AutoKick_KickPrivateProfile && isaPlayer.communityvisibilitystate != 3) {
                    Interface.CallHook("OnSAProfilePrivate", pSteamId, isaPlayer.communityvisibilitystate);
                    KickPlayer(isaPlayer?.steamid, GetMsg("Profile Private"), "C");
                }
                LogDebug("Check for a hidden steam level");
                if (!HasPerm(pSteamId, PermissionWhitelistSteamProfile) && isaPlayer.steamlevel == -1 && config.AutoKick_KickHiddenLevel) {
                    Interface.CallHook("OnSASteamLevelHidden", pSteamId);
                    KickPlayer(isaPlayer?.steamid, GetMsg("Steam Level Hidden"), "C");
                }
                LogDebug($"Player {isaPlayer.steamid} is at steam level {isaPlayer.steamlevel}");
                if (!HasPerm(pSteamId, PermissionWhitelistSteamProfile) && isaPlayer.steamlevel < config.AutoKick_MinSteamProfileLevel && isaPlayer.steamlevel >= 0) {
                    Interface.CallHook("OnSAProfileLevelLow", pSteamId, config.AutoKick_MinSteamProfileLevel, isaPlayer.steamlevel);
                    KickPlayer(isaPlayer?.steamid, GetMsg("Profile Low Level", new Dictionary<string, string> {
                        ["level"]
                        = config.AutoKick_MinSteamProfileLevel.ToString()
                    }
                    ), "C");
                }
                LogDebug($"IP/CACHE| ID:{id} ADD:{address} COUNTRY: {isaPlayer.ipInfo.isocode} RATING:{isaPlayer?.ipInfo?.rating} AGE: {isaPlayer.ipInfo?.lastcheck}");
                if (config.AutoKickOn && config.AutoKick_BadIp && !HasPerm(id, PermissionWhitelistBadIPKick) && config.AutoKick_BadIp) {
                    if (IsBadIp(isaPlayer)) {
                        if (isaPlayer.ipInfo?.proxy == "yes") KickPlayer(id, GetMsg("Reason: Proxy IP"), "C");
                        else KickPlayer(id, GetMsg("Reason: Bad IP"), "C");
                        Interface.CallHook("OnSAVPNKick", id, isaPlayer?.ipInfo?.rating);
                    }
                }
                if (!HasPerm(id, PermissionWhitelistAllowCountry) && !config.AutoKickLimitCountry.IsNullOrEmpty()) {
                    var playerIso = isaPlayer.ipInfo?.isocode?.Trim();
                    var countriesAllowed = config.AutoKickLimitCountry.Split(',');
                    if (playerIso != null && playerIso != "" && !countriesAllowed.Contains(playerIso)) KickPlayer(id, GetMsg("Country Not Allowed", new Dictionary<string, string> {
                        ["country"]
                        = playerIso, ["country2"] = config.AutoKickLimitCountry.ToString()
                    }
                    ), "C");
                }
                GetPlayerReport(isaPlayer, connected);
            }
            , RequestMethod.POST, 5);
        }
        void KickIfBanned(ISAPlayer isaPlayer) {
            if (isaPlayer == null) return;
            IPlayer iPlayer = covalence.Players.FindPlayer(isaPlayer.steamid);
            if (iPlayer != null && iPlayer.IsAdmin && config.IgnoreAdmins) return;
            try {
                if (AdminToggle != null && AdminToggle.Call<bool>("IsAdmin", iPlayer.Id) && config.IgnoreAdmins) return;
            }
            catch (Exception) {
            }
            ISABan ban = IsBanned(isaPlayer?.steamid);
            if (ban != null) {
                if (!ban.steamid.ToString().Equals(isaPlayer.steamid)) {
                    KickPlayer(isaPlayer?.steamid, $"Linked: {ban.steamid}, {ban.reason}", "U");
                }
                else {
                    KickPlayer(isaPlayer?.steamid, ban.reason, "U");
                }
            }
        }
        void AddBan(ISABan thisBan, bool doNative = true) {
            if (!serverStarted) return;
            if (thisBan == null) {
                // LogDebug($"This ban is null");
                return;
            }
            string reason = Uri.EscapeDataString(thisBan.reason);
            try {
                DoRequest($"player/{thisBan.steamid}/addban", $"reason={reason}&dateTime={thisBan.created}&banUntil={thisBan.banUntil}&createdBySteamId={thisBan.bannedBy}", (code, response) => {
                    // ISABan thisBan = new ISABan { serverName = server.Name, date = dateTime, reason = banreason, serverIp = thisServerIp, banUntil = dateBanUntil };
                    // LogDebug("Check cache");
                    if (IsPlayerCached(thisBan.steamid.ToString())) {
                        // LogDebug($"{thisBan.steamid} has ban cached, now updating.");
                        AddPlayerData(thisBan.steamid.ToString(), thisBan);
                    }
                    else {
                        // LogDebug($"{thisBan.steamid} had no ban data cached, now creating.");
                        ISAPlayer newPlayer = new ISAPlayer((ulong)thisBan.steamid);
                        // LogDebug("Player cache object created");
                        newPlayer.bans.Add(thisBan);
                        // LogDebug("After adding");
                        AddPlayerCached(newPlayer);
                    }
                }
                , RequestMethod.POST, 60);
            }
            catch (Exception) {
                return;
            }
        }
#endregion
#region Commands
        [Command("sa.apply_key")]
        void ApplyKey(IPlayer player, string command, string[] args) {
            var key = args[0].ToString();
            if (!player.IsServer) {
                return;
            }
            this.config.ServerApiKey = key;
            SaveConfig();
        }
        [Command("sa.clb", "getreport")]
        void SCmdCheckLocalBans(IPlayer player, string command, string[] args) {
            CheckLocalBans();
        }
        [Command("unban", "playerunban", "sa.unban"), Permission(PermissionToUnBan)]
        void SCmdUnban(IPlayer player, string command, string[] args) {
            if (args == null || (args.Length > 2 || args.Length < 1)) {
                SendReplyWithIcon(player, GetMsg("UnBan Syntax"));
                return;
            }
            var reason = args.Length > 1 ? args[1] : "";
            SaUnban(args[0], player, reason);
        }
        void SilentBan(ulong steamId, TimeSpan timeSpan, string reason, IPlayer enforcer = null) {
            Unsubscribe(nameof(OnUserBanned));
            var username = covalence.Players.FindPlayerById(steamId.ToString())?.Name ?? "";
            NativeBan(steamId, reason, Convert.ToInt64(timeSpan.TotalSeconds), username, enforcer);
            Subscribe(nameof(OnUserBanned));
        }
        void SilentBan(ulong steamId, int timeSpan, string reason, IPlayer enforcer = null) {
            Unsubscribe(nameof(OnUserBanned));
            var username = covalence.Players.FindPlayerById(steamId.ToString())?.Name ?? "";
            NativeBan(steamId, reason, -1, username, enforcer);
            Subscribe(nameof(OnUserBanned));
        }
        void SilentUnban(string playerId, IPlayer admin) {
            Unsubscribe(nameof(OnUserUnbanned));
            NativeUnban(playerId, admin);
            Subscribe(nameof(OnUserUnbanned));
        }
        void NativeBan(ulong playerId, string reason, long duration = -1, string playerUsername = "unnamed", IPlayer player = null) {
            if (!playerId.IsSteamId()) {
                if (serverStarted) player?.Reply(string.Concat("This doesn't appear to be a 64bit steamid: ", playerId));
                return;
            }
            ServerUsers.User user = ServerUsers.Get(playerId);
            if (user != null && user.@group == ServerUsers.UserGroup.Banned) {
                if (serverStarted) player?.Reply(string.Concat("User ", playerId, " is already banned"));
                return;
            }
            string str3 = "";
            BasePlayer basePlayer = BasePlayer.FindByID(playerId);
            string durationSuffix = (duration > (long)0 ? string.Concat(" for ", duration.FormatSecondsLong()) : "");
            if (basePlayer != null && basePlayer.IsConnected) {
                playerUsername = basePlayer.displayName;
                if (basePlayer.IsConnected && basePlayer.net.connection.ownerid != 0 && basePlayer.net.connection.ownerid != basePlayer.net.connection.userid) {
                    str3 = string.Concat(str3, string.Format(" and also banned ownerid {0}", basePlayer.net.connection.ownerid));
                    ServerUsers.Set(basePlayer.net.connection.ownerid, ServerUsers.UserGroup.Banned, basePlayer.displayName, reason, duration);
                }
                Chat.Broadcast(string.Concat(new string[] {
                    "Kickbanning ", basePlayer.displayName, durationSuffix, " (", reason, ")"
                }
                ), "SERVER", "#eee", (ulong)0);
                //Net.sv.Kick(basePlayer.net.connection, string.Concat("Banned", str, ": ", str2), false);
            }
            ServerUsers.Set(playerId, ServerUsers.UserGroup.Banned, playerUsername, reason, duration == -1 ? -1 : (long)(DateTime.Now.AddSeconds(duration) - Epoch).TotalSeconds);
            if (serverStarted) player?.Reply(string.Format("Banned User{0}: {1} - \"{2}\" for \"{3}\"{4}", new object[] {
                durationSuffix, playerId, playerUsername, reason, str3
            }
            ));
        }
        bool NativeUnban(string playerId, IPlayer admin = null) {
            ulong playerIdLong = 0;
            if (!ulong.TryParse(playerId, out playerIdLong)) {
                var msg = string.Format("This doesn't appear to be a 64bit steamid: {0}", playerId);
                if (admin == null) {
                    Puts(msg);
                }
                else {
                    admin.Reply(msg);
                }
                return false;
            }
            ServerUsers.User user = ServerUsers.Get(playerIdLong);
            if (user == null || user.@group != ServerUsers.UserGroup.Banned) {
                admin?.Reply(string.Format("User {0} isn't banned", playerId));
                return false;
            }
            ServerUsers.Remove(playerIdLong);
            admin?.Reply($"Unbanned User: {playerId}");
            return true;
        }
        void SaUnban(string playerId, IPlayer admin = null, string reason = "") {
            IPlayer iPlayer = players.FindPlayer(playerId);
            SilentUnban(playerId, admin);
            ulong playerIdLong = 0;
            ulong.TryParse(playerId, out playerIdLong);
            if (playerIdLong == 0 && iPlayer == null) {
                GetMsg("Player Not Found", new Dictionary<string, string> {
                    ["player"]
                    = playerId
                }
                );
                return;
            }
            Puts($"Player {iPlayer?.Name} ({playerId}) was unbanned by {admin?.Name} ({admin?.Id})");
            // Add ember support.if (Ember != null)
            {
                Ember?.Call("Unban", playerId, Player.FindById(admin?.Id));
            }
            //
            if (serverStarted) {
                DoPardon(playerId, iPlayer, admin);
            }
            string msgClean;
            if (reason.IsNullOrEmpty()) {
                msgClean = GetMsg("Player Now Unbanned Clean - NoReason", new Dictionary<string, string> {
                    ["player"]
                    = iPlayer?.Name ?? playerId
                }
                );
            }
            else {
                msgClean = GetMsg("Player Now Unbanned Clean - Reason", new Dictionary<string, string> {
                    ["player"]
                    = iPlayer?.Name ?? playerId, ["reason"] = reason
                }
                );
            }
            if (config.DiscordBanReport) {
                DiscordSend(playerId, iPlayer?.Name ?? playerId, new EmbedFieldList() {
                    name = "Player Unbanned", value = msgClean, inline = true
                }
                , 3066993, true);
            }
        }
        void DoPardon(string playerId, IPlayer iPlayer = null, IPlayer admin = null) {
            RemoveBans(playerId);
            DoRequest($"player/ban/pardon/{playerId}", $"pardonedBy={admin?.Id ?? admin.Name}", (code, response) => {
                if (config.RconBroadcast) RCon.Broadcast(RCon.LogType.Chat, new Chat.ChatEntry {
                    Message = $"Player was unbanned by {admin.Name} ({admin?.Id})", UserId = playerId, Username = iPlayer?.Name ?? "", Time = Facepunch.Math.Epoch.Current
                }
                );
                if (admin != null && config.RconBroadcast) {
                    RCon.Broadcast(RCon.LogType.Chat, new Chat.ChatEntry {
                        Message = $"Player {iPlayer?.Name} ({playerId}) was unbanned", UserId = admin?.Id, Username = admin?.Name ?? "", Time = Facepunch.Math.Epoch.Current
                    }
                    );
                }
                if (admin != null && !admin.IsServer) {
                    SendReplyWithIcon(admin, $"Player {iPlayer?.Name} ({playerId}) was unbanned");
                }
            }
            , RequestMethod.POST, 30, 5);
        }
        //banid 76561198007433923 "Pho3niX90" "Some reason" 1953394942
        [Command("banid"), Permission(PermissionToBan)]
        void SCmdBanId(IPlayer player, string command, string[] args) {
            var argString = string.Join(" ", args);
            var matches = new Regex(@"([7]\d{16}).*?(\d{9,12}|-1)$").Match(argString);
            var mG = matches.Groups;
            // [0] steam64id [1] username [2] reason [3] length
            if (args.Length > 0) {
                var playerId = args[0];
                var reason = "No reason provided.";
                var lengthInt = 0;
                var length = "-1";
                if (mG.Count == 3) {
                    if (int.TryParse(mG[2].Value, out lengthInt)) length = lengthInt == -1 || lengthInt > 1848030000 ? length : lengthInt.ToString();
                }
                if (args.Length >= 3) {
                    reason = args[2].ToString() == length ? args[1] : args[2];
                }
                API_BanPlayer(player, playerId, reason, length, true);
            }
        }
        [Command("ban", "playerban", "sa.ban"), Permission(PermissionToBan)]
        void SCmdBan(IPlayer player, string command, string[] args) {
            int argsLength = args == null ? 0 : args.Length;
            if (argsLength >= 0 && argsLength < 2) {
                SendReplyWithIcon(player, GetMsg("Ban Syntax"));
                return;
            }
            var playerId = args[0]?.ToString()?.Trim();
            var fPlayer = players.FindPlayer(playerId);
            if (playerId.Length != 17 && !playerId.StartsWith("7656")) {
                // LogDebug("Length = " + playerId.Length + ", StartsWith = " + playerId.StartsWith("7656"));
                if (fPlayer == null) {
                    //Puts("Player not found, or not in servers cache.");
                    SendReplyWithIcon(player, "Player not found, or not in servers cache.");
                    return;
                }
                playerId = fPlayer.Id;
            }
            /***
             * Length 2: player, reason
             * Length 3: player, reason, time
             * Length 4: playerSteamId, reason, time, ignoreSearch
             ***/
            if (args == null || (argsLength > 4)) {
                SendReplyWithIcon(player, GetMsg("Ban Syntax"));
                return;
            }
            var reason = argsLength < 2 ? "No reason provided." : args[1];
            var length = args.Length > 2 ? args[2].ToUpper() : "100Y";
            var ignoreSearch = false;
            if (args.Length > 3) bool.TryParse(args[3], out ignoreSearch);
            try {
                API_BanPlayer(player, playerId, reason, length, ignoreSearch);
            }
            catch (Exception e) {
                Puts(e.Message);
                SendReplyWithIcon(player, GetMsg("Ban Syntax"));
            }
        }
        [Command("clanban"), Permission(PermissionToBan)]
        void SCmdClanBan(IPlayer player, string command, string[] args) {
            int argsLength = args == null ? 0 : args.Length;
            /***
             * Length 2: player, reason
             * Length 3: player, reason, time
             * Length 4: playerSteamId, reason, time, ignoreSearch
             ***/
            if (args == null || (argsLength < 2 || argsLength > 4)) {
                SendReplyWithIcon(player, GetMsg("Ban Syntax"));
                return;
            }
            var playerId = args[0];
            var reason = args[1];
            var length = args.Length > 2 ? args[2] : "100y";
            var ignoreSearch = false;
            var errMsg = "";
            IPlayer iPlayer = null;
            IEnumerable<IPlayer> playersFound = players.FindPlayers(playerId);
            int playersFoundCount = playersFound.Count();
            switch (playersFoundCount) {
                case 0 : errMsg = GetMsg("Player Not Found", new Dictionary<string, string> {
                    ["player"]
                    = playerId
                }
                );
                break;
                case 1 : iPlayer = players.FindPlayer(playerId);
                break;
                default : List<string> playersFoundNames = new List<string>();
                for (int i = 0; i < playersFoundCount; i++) playersFoundNames.Add(playersFound.ElementAt(i).Name);
                string playersFoundNamesString = String.Join(", ", playersFoundNames.ToArray());
                errMsg = GetMsg("Multiple Players Found", new Dictionary<string, string> {
                    ["players"]
                    = playersFoundNamesString
                }
                );
                break;
            }
            if ((!ignoreSearch && iPlayer == null) || !errMsg.Equals("")) {
                SendReplyWithIcon(player, errMsg);
                return;
            }
            ulong playerIdU = ulong.Parse(iPlayer.Id);
            List<ulong> teamMembers = new List<ulong>();
            if (config.ClanBanTeams) {
                teamMembers = GetTeamMembers(playerIdU);
            }
            if (Clans != null && Clans.IsLoaded) {
                var clanMembers = GetClan(playerId);
                if (clanMembers != null && clanMembers.Count() > 0) {
                    teamMembers.AddRange(clanMembers);
                }
            }
            teamMembers = teamMembers.Distinct().ToList();
            teamMembers?.Remove(ulong.Parse(playerId));
            bool.TryParse(args[3], out ignoreSearch);
            API_BanPlayer(player, playerId, reason, length, ignoreSearch);
            if (teamMembers.Count() > 0) {
                var clanBanReason = config.ClanBanPrefix.Replace("{reason}", reason).Replace("{playerId}", playerId);
                foreach (var member in teamMembers) {
                    API_BanPlayer(player, member.ToString(), clanBanReason, length, ignoreSearch);
                }
            }
        }
        [Command("sa.cp")]
        void SCmdCheckPlayer(IPlayer player, string command, string[] args) {
            string playerArg = (args.Length == 0) ? player.Id : args[0];
            IPlayer playerToCheck = players.FindPlayer(playerArg.Trim());
            if (playerToCheck == null) {
                SendReplyWithIcon(player, GetMsg("Player Not Found", new Dictionary<string, string> {
                    ["player"]
                    = playerArg
                }
                ));
                return;
            }
            GetPlayerReport(playerToCheck, player);
        }
#endregion
#region VPN/Proxy
#endregion
#region Ban System
        string BanMinutes(DateTime ban) {
            return ((int)Math.Round((ban - DateTime.UtcNow).TotalMinutes)).ToString();
        }
        DateTime BanUntil(string banLength) {
            int digit = 10;
            string del = "y";
            if (!banLength.ToLower().Equals("permanent")) {
                int.TryParse(new string(banLength.Where(char.IsDigit).ToArray()), out digit);
                del = new string(banLength.Where(char.IsLetter).ToArray());
            }
            if (digit <= 0) {
                digit = 100;
            }
            DateTime now = DateTime.UtcNow;
            /*
             * Fix for bans.cfg going blank.* Issue: When server restarts, the bans.cfg is empty.The reason is that facepunch stores the bans in this file, verbatim, and rebans everyone when the server is restart (bans are kept in memory).Once the server restarted, SA couldn't convert the unix timestamp to a length, and errored out, causing the file to go blank on next save (since there are no bans in memory).*/
            DateTime dateBanUntil;
            if (banLength.Length >= 10) {
                //already epoch?
                long lBanLength;
                if (long.TryParse(banLength, out lBanLength)) {
                    return ConvertUnixToDateTime(lBanLength);
                }
            }
            switch (del.ToUpper()) {
                case "S" : dateBanUntil = now.AddSeconds(digit);
                break;
                case "MI" : dateBanUntil = now.AddMinutes(digit);
                break;
                case "H" : dateBanUntil = now.AddHours(digit);
                break;
                case "D" : dateBanUntil = now.AddDays(digit);
                break;
                case "W" : dateBanUntil = now.AddDays(digit * 7);
                break;
                case "M" : dateBanUntil = now.AddMonths(digit);
                break;
                case "Y" : dateBanUntil = now.AddYears(Math.Min(2030 - DateTime.Now.Year, digit));
                break;
                default : dateBanUntil = now.AddDays(digit);
                break;
            }
            return dateBanUntil;
        }
        string BanFor(string banLength) {
            int digit = int.Parse(new string(banLength.Where(char.IsDigit).ToArray()));
            string del = new string(banLength.Where(char.IsLetter).ToArray());
            // DateTime now = DateTime.Now;
            //str
// ... [Code preview truncated due to length. Full source in attached file] ...

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