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

FREE CommandSpamBlocker : 1.0.1 1.0.1

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
using System.Linq;
using System.Text;
using Facepunch.Rust;

namespace Oxide.Plugins
{
    [Info("Command Spam Blocker", "Khan", "1.0.1")]
    [Description("Prevents spamming of chat & console commands")]
    public class CommandSpamBlocker : RustPlugin
    {
        #region Fields

        private static Configuration _config;
        private const string Chat = "chat.say";

        [Flags]
        private enum Type
        {
            All = Chat | Console,
            Chat = 1,
            Console = 2,
        }

        private static float _cd;
        private static float _cdm;
        private HashSet<string> _commands = new HashSet<string>();
        private Hash<ulong, float> _cooldowns = new Hash<ulong, float>();
        private static HashSet<ulong> _ignore;

        #endregion

        #region Config

        private class Configuration
        {
            [JsonProperty("Add commands to block ( Must be lowercased do not add the slash! / ) ( 0 = Block Both | 1 = Block Chat | 2 = Block Console )")]
            public Hash<string, Type> Commands;

            [JsonProperty("Sets the time between command usage")]
            public float CoolDownTime = 3f;

            [JsonProperty("Sets the max accumulated cooldown time limit before kicking the player if they keep trying to spam")]
            public float CoolDownTimeMax = 120.0f;

            [JsonProperty("Exclude players from being blocked ( Add their steam 64 id's to the list )", ObjectCreationHandling = ObjectCreationHandling.Auto)]
            public HashSet<ulong> Ignore;

            [JsonProperty("Message Responses")]
            public Lang Msg = new Lang();

            public string ToJson() => JsonConvert.SerializeObject(this);
            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }

        private class Lang
        {
            [JsonProperty("( Chat Icon ) Just insert a valid steam 64 ID to set")]
            public ulong ChatIcon = 0;
            public string CommandBlocked = "You are on command cooldown, try again in {0} seconds";
            public string KickReason = "Kicked for excessive command spam!";
        }

        protected override void LoadDefaultConfig() => _config = new Configuration();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<Configuration>();
                if (_config == null)
                    throw new JsonException();

                if (!_config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
                {
                    PrintWarning("Configuration appears to be outdated; Updating and saving");
                    SaveConfig();
                }
            }
            catch
            {
                PrintError($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            PrintToConsole($"Configuration changes saved to {Name}.json");
            Config.WriteObject(_config, true);
        }

        private void Init() => Unsubscribe(nameof (OnPlayerCommand));

        private void Loaded()
        {
            if (_config.Ignore.IsNullOrEmpty()) _config.Ignore = new HashSet<ulong>();
            if (_config.Commands.IsNullOrEmpty()) _config.Commands = new Hash<string, Type> { { "command", Type.All }, };
            SaveConfig();

            _ignore = _config.Ignore;

            if (!_ignore.IsNullOrEmpty())
            {
                StringBuilder sb = new StringBuilder();
                int count = 0;
                for (int i = 0; i < _config.Ignore.Count; i++)
                {
                    ulong dingus = _config.Ignore.ElementAt(i);
                    if (!dingus.IsSteamId())
                    {
                        sb.Append($"line {i} {dingus}\n");
                        count++;
                    }
                }

                PrintError($"{count} of {_config.Ignore.Count} steam ID's are not valid please double check and fix them!\n{sb}");
                sb.Clear();
            }

            _cd = _config.CoolDownTime;
            _cdm = _config.CoolDownTimeMax;

            string name = _config.Commands.First().Key;
            if (_config.Commands.Count == 1 && (name == "command" || string.IsNullOrEmpty(name))) return;

            foreach (var c in _config.Commands)
                    _commands.Add(c.Key);

            Subscribe(nameof (OnPlayerCommand));
        }

        private void Unload()
        {
            _commands.Clear();
            _ignore.Clear();
            _config = null;
        }

        #endregion

        #region Oxide

        private void OnPlayerDisconnected(BasePlayer player) => _cooldowns.Remove(player.userID.Get());
        private object OnPlayerCommand(BasePlayer player, string command, string[] args) => player == null ? null : _ignore.Contains(player.userID.Get()) ? null : CanDo(command, player);

        private object OnServerCommand(ConsoleSystem.Arg arg)
        {
            BasePlayer player = arg.Player();
            if (player != null && arg.cmd.FullName != Chat)
            {
                string command = arg.cmd.Name;
                string fullCommand = arg.cmd.FullName;

                if (!string.IsNullOrEmpty(arg.FullString.ToString()))
                {
                    command += $" {arg.FullString}";
                    fullCommand += $" {arg.FullString}";
                }

                foreach (var c in _config.Commands)
                {
                    if (c.Value != Type.Console && c.Value != Type.All) continue;

                    if ((command.StartsWith(c.Key, StringComparison.OrdinalIgnoreCase) || fullCommand.StartsWith(c.Key, StringComparison.OrdinalIgnoreCase)) && HasCommandCooldown(player))
                        return true;
                }
            }

            return null;
        }

        #endregion

        #region Helpers

        private object CanDo(string command, BasePlayer player)
        {
            foreach (string c in _commands)
            {
                if (!c.Contains(command, StringComparison.OrdinalIgnoreCase)) continue;

                command = command.ToLower();
                if ((_config.Commands[command].HasFlag(Type.Chat) || _config.Commands[command].HasFlag(Type.Console)) && HasCommandCooldown(player))
                    return true;

                break;
            }

            return null;
        }

        private bool HasCommandCooldown(BasePlayer player)
        {
            ulong user = player.userID.Get();
            float current = Time.realtimeSinceStartup;
            float cooldown;
            if (!_cooldowns.TryGetValue(user, out cooldown)) _cooldowns[user] = cooldown = current - 30f;

            if (cooldown > current)
            {
                _cooldowns[user] = cooldown += 1f;
                float remaining = cooldown - current;
                if (remaining <= _cdm) Response(player, _config.Msg.CommandBlocked, $"{remaining:0}");
                else player.Kick(_config.Msg.KickReason);
                return true;
            }

            _cooldowns[user] = current + _cd;
            return false;
        }

        private static void Response(BasePlayer player, string message, params object[] args)
        {
            if (player == null) return;
            ConsoleNetwork.SendClientCommand(player.Connection, "chat.add", 2, _config.Msg.ChatIcon, string.Format(message, args));
        }

        #endregion

    }
}

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