using Newtonsoft.Json; using Oxide.Core.Plugins; using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; namespace Oxide.Plugins { [Info("BagMonitor", "Reheight", "1.1.0")] [Description("Impose limitations on and monitor beds and sleeping bags.")] class BagMonitor : RustPlugin { #region Plugin References [PluginReference] Plugin DiscordMessages; #endregion #region Configuration PluginConfiguration _config; private void Init() { _config = Config.ReadObject(); } protected override void LoadDefaultConfig() => _config = GetDefaultConfig(); protected override void LoadConfig() { base.LoadConfig(); try { _config = Config.ReadObject(); if (_config == null) { throw new JsonException(); } if (!_config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) { PrintWarning($"Plugin Configuration file {Name}.json updated."); SaveConfig(); } } catch { LoadDefaultConfig(); PrintError("Config file contains an error and has been replaced with the default file."); } } protected override void SaveConfig() => Config.WriteObject(_config, true); class ChatSettings { [JsonProperty(PropertyName = "Prefix", Order = 1)] public string Prefix { get; set; } } class LeetConversion { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } [JsonProperty(PropertyName = "Leet Table", Order = 2)] public Dictionary LeetTable { get; set; } } class DiscordWebhook { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } [JsonProperty(PropertyName = "Webhook URL", Order = 2)] public string WebhookURL { get; set; } [JsonProperty(PropertyName = "Embed Color", Order = 3)] public string EmbedHEX { get; set; } } class ConsoleLogging { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } } class Logging { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } [JsonProperty(PropertyName = "Discord", Order = 2)] public DiscordWebhook DiscordWebhook; [JsonProperty(PropertyName = "Console", Order = 3)] public ConsoleLogging ConsoleLogging; } class BlacklistingTerms { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } [JsonProperty(PropertyName = "Blacklisted Terms", Order = 2)] public string[] BlacklistedTermsList { get; set; } } class BlacklistingREGEX { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } [JsonProperty(PropertyName = "Blacklisted REGEXs", Order = 2)] public string[] BlacklistedREGEXList { get; set; } } class Blacklisting { [JsonProperty(PropertyName = "Enabled", Order = 1)] public bool Enabled { get; set; } [JsonProperty(PropertyName = "Blacklist Terms (Simple)", Order = 2)] public BlacklistingTerms BlacklistingTerms; [JsonProperty(PropertyName = "Blacklist REGEX (Advanced)", Order = 3)] public BlacklistingREGEX BlacklistingREGEX; [JsonProperty(PropertyName = "Leet Conversion (Advanced)", Order = 4)] public LeetConversion LeetConversion; [JsonProperty(PropertyName = "Logging", Order = 5)] public Logging BlacklistingLogging; } class PluginConfiguration { [JsonProperty(PropertyName = "Chat", Order = 1)] public ChatSettings ChatSettings { get; set; } [JsonProperty(PropertyName = "Logging", Order = 2)] public Logging LoggingSystem { get; set; } [JsonProperty(PropertyName = "Blacklisting", Order = 3)] public Blacklisting BlacklistingSystem { get; set; } public string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } private PluginConfiguration GetDefaultConfig() { return new PluginConfiguration { ChatSettings = new ChatSettings { Prefix = "BagMonitor:" }, LoggingSystem = new Logging { Enabled = false, DiscordWebhook = new DiscordWebhook { Enabled = false, WebhookURL = "URL HERE", EmbedHEX = "#FFCC00" }, ConsoleLogging = new ConsoleLogging { Enabled = false } }, BlacklistingSystem = new Blacklisting { Enabled = false, BlacklistingTerms = new BlacklistingTerms { Enabled = false, BlacklistedTermsList = new string[] { "term1", "term2", "term3" } }, BlacklistingREGEX = new BlacklistingREGEX { Enabled = false, BlacklistedREGEXList = new string[] { "REGEX1", "REGEX2", "REGEX3" } }, LeetConversion = new LeetConversion { Enabled = false, LeetTable = new Dictionary() { {"}{", "h"}, {"|-|", "h"}, {"]-[", "h"}, {"/-/", "h"}, {"|{", "k"}, {"/\\/\\", "m"}, {"|\\|", "n"}, {"/\\/", "n"}, {"()", "o"}, {"[]", "o"}, {"vv", "w"}, {"\\/\\/", "w"}, {"><", "x"}, {"2", "z"}, {"4", "a"}, {"@", "a"}, {"8", "b"}, {"ß", "b"}, {"(", "c"}, {"<", "c"}, {"{", "c"}, {"3", "e"}, {"€", "e"}, {"6", "g"}, {"9", "g"}, {"&", "g"}, {"#", "h"}, {"$", "s"}, {"7", "t"}, {"|", "l"}, {"1", "i"}, {"!", "i"}, {"0", "o"} } }, BlacklistingLogging = new Logging { Enabled = false, DiscordWebhook = new DiscordWebhook { Enabled = false, WebhookURL = "URL HERE", EmbedHEX = "#FFCC00" }, ConsoleLogging = new ConsoleLogging { Enabled = false } } } }; } #endregion Configuration #region Language protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["NameNotAllowed"] = "You cannot use that in bag names!" }, this); } private string Lang(string key, string pid, params object[] args) => _config.ChatSettings.Prefix + " " + String.Format(lang.GetMessage(key, this, pid), args); private string LangNoPFX(string key, string pid, params object[] args) => String.Format(lang.GetMessage(key, this, pid), args); #endregion Language #region Rust Methods object CanRenameBed(BasePlayer player, SleepingBag bed, string bedName) { #region Variables string PlayerName = GetPlayerName(player.userID); string OwnerName = GetPlayerName(bed.OwnerID); string DeployerName = GetPlayerName(bed.deployerUserID); #endregion Variables #region Collection/Storage List DetectedInputs = Facepunch.Pool.GetList(); #endregion #region Blacklisting if (_config.BlacklistingSystem.Enabled) { string bedNameLeet = TranslateLeet(bedName); if (_config.BlacklistingSystem.BlacklistingTerms.Enabled) { string[] bedNameArr = bedName.Split(' '); foreach (string str in bedNameArr) { if (_config.BlacklistingSystem.BlacklistingTerms.BlacklistedTermsList.Contains(str, StringComparer.OrdinalIgnoreCase)) { DetectedInputs.Add(str); } } if (_config.BlacklistingSystem.LeetConversion.Enabled) { string[] leetConvertedBedNameArr = bedNameLeet.Split(' '); foreach (string str in leetConvertedBedNameArr) { if (_config.BlacklistingSystem.BlacklistingTerms.BlacklistedTermsList.Contains(str, StringComparer.OrdinalIgnoreCase)) { DetectedInputs.Add(str); } } } } if (_config.BlacklistingSystem.BlacklistingREGEX.Enabled) { foreach (string entry in _config.BlacklistingSystem.BlacklistingREGEX.BlacklistedREGEXList) { Regex REGEX = new Regex($@"{entry}"); if (REGEX.IsMatch(bedName)) DetectedInputs.Add(entry); if (_config.BlacklistingSystem.LeetConversion.Enabled && REGEX.IsMatch(bedNameLeet)) DetectedInputs.Add(entry); } } if (DetectedInputs.Count() > 0) { if (_config.BlacklistingSystem.BlacklistingLogging.Enabled) { object fields = new[] { new { name = "Player", value = $"[{PlayerName} (Steam)](https://www.steamcommunity.com/profiles/{player.UserIDString}) | [{PlayerName} (BM)](https://www.battlemetrics.com/rcon/players?filter%5Bsearch%5D={player.UserIDString})", inline = false }, new { name = "Bag Owner", value = $"[{OwnerName} (Steam)](https://www.steamcommunity.com/profiles/{bed.OwnerID}) | [{OwnerName} (BM)](https://www.battlemetrics.com/rcon/players?filter%5Bsearch%5D={bed.OwnerID})", inline = false }, new { name = "Bag Deployer", value = $"[{DeployerName} (Steam)](https://www.steamcommunity.com/profiles/{bed.deployerUserID}) | [{DeployerName} (BM)](https://www.battlemetrics.com/rcon/players?filter%5Bsearch%5D={bed.deployerUserID})", inline = false }, new { name = "Logged Name", value = $"```{bedName}```", inline = false } }; SendDiscordWebhook(_config.BlacklistingSystem.BlacklistingLogging.DiscordWebhook.WebhookURL, fields, "Bag Name Prevented", _config.BlacklistingSystem.BlacklistingLogging.DiscordWebhook.EmbedHEX); } if (_config.BlacklistingSystem.BlacklistingLogging.ConsoleLogging.Enabled) { Puts($"{player.displayName} ({player.UserIDString}) was prevented from attempting to rename a bag that belongs to {GetPlayerName(bed.OwnerID)} ({bed.OwnerID}) to: {bedName}"); } player.ChatMessage(Lang("NameNotAllowed", player.UserIDString)); Facepunch.Pool.FreeList(ref DetectedInputs); return true; } else Facepunch.Pool.FreeList(ref DetectedInputs); } #endregion Blacklisting #region Logging if (_config.LoggingSystem.Enabled) { if (_config.LoggingSystem.DiscordWebhook.Enabled) { object fields = new[] { new { name = "Player", value = $"[{PlayerName} (Steam)](https://www.steamcommunity.com/profiles/{player.UserIDString}) | [{PlayerName} (BM)](https://www.battlemetrics.com/rcon/players?filter%5Bsearch%5D={player.UserIDString})", inline = false }, new { name = "Bag Owner", value = $"[{OwnerName} (Steam)](https://www.steamcommunity.com/profiles/{bed.OwnerID}) | [{OwnerName} (BM)](https://www.battlemetrics.com/rcon/players?filter%5Bsearch%5D={bed.OwnerID})", inline = false }, new { name = "Bag Deployer", value = $"[{DeployerName} (Steam)](https://www.steamcommunity.com/profiles/{bed.deployerUserID}) | [{DeployerName} (BM)](https://www.battlemetrics.com/rcon/players?filter%5Bsearch%5D={bed.deployerUserID})", inline = false }, new { name = "Logged Name", value = $"```{bedName}```", inline = false } }; SendDiscordWebhook(_config.LoggingSystem.DiscordWebhook.WebhookURL, fields, "Bag Name Change", _config.LoggingSystem.DiscordWebhook.EmbedHEX); } if(_config.LoggingSystem.Enabled) { Puts($"{player.displayName} ({player.UserIDString}) has renamed a bag that belongs to {GetPlayerName(bed.OwnerID)} ({bed.OwnerID}) to: {bedName}"); } } #endregion Logging return null; } #endregion #region Helpers private string GetPlayerName(ulong playerID) { var player = covalence.Players.FindPlayerById(playerID.ToString()); if (player != null) return player.Name; return playerID + " (Unknown Player)"; } void SendDiscordWebhook(string URL, object fields, string title, string ColorHEX) { if (DiscordMessages == null) { PrintWarning("You do not have DiscordMessages installed, so we cannot send Discord Webhooks!"); return; } int colorInt = int.Parse(ColorHEX.Replace("#", ""), System.Globalization.NumberStyles.HexNumber); string json = JsonConvert.SerializeObject(fields); DiscordMessages.Call("API_SendFancyMessage", URL, title, colorInt, json); } private string TranslateLeet(string original) { string translated = original; foreach (var leet in _config.BlacklistingSystem.LeetConversion.LeetTable) translated = translated.Replace(leet.Key, leet.Value); return translated; } #endregion } }