using System.Collections.Generic; using Newtonsoft.Json; using UnityEngine; using Oxide.Core; using System; using Oxide.Core.Plugins; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; namespace Oxide.Plugins { [Info("STFU", "MikeHawke", "1.0.3")] [Description("Player Muting Made Simple")] class STFU : RustPlugin { [PluginReference] private Plugin DiscordMessages; public Mutedata storedData; public class Mutedata { public Dictionary MutedPlayers = new Dictionary(); } public class Mutes { public bool perm = false; public bool warned = false; public string reason = ""; public DateTime unmute; } private ConfigData configData; class ConfigData { [JsonProperty(PropertyName = "Report to Discord")] public bool rp = false; [JsonProperty(PropertyName = "Discord Webhook")] public string wh = "Discordhook."; } private bool LoadConfigVariables() { try { configData = Config.ReadObject(); } catch { return false; } SaveConfig(configData); return true; } void Init() { permission.RegisterPermission("STFU.User", this); if (!LoadConfigVariables()) { Puts("Config file issue detected. Please delete file, or check syntax and fix."); return; } } protected override void LoadDefaultConfig() { Puts("Creating new config file."); configData = new ConfigData(); SaveConfig(configData); } void SaveConfig(ConfigData config) { Config.WriteObject(config, true); } void Loaded() { JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, }; storedData = Interface.Oxide.DataFileSystem.ReadObject("STFU"); Interface.Oxide.DataFileSystem.WriteObject("STFU", storedData); checkban(); } void SaveData() { Interface.Oxide.DataFileSystem.WriteObject("STFU", storedData); } [ChatCommand("STFU")] void stfu(BasePlayer player, string cmd, string[] args) { if (!permission.UserHasPermission(player.userID.ToString(), "STFU.User")) { SendReply(player, "You do not have permission to use this command"); return; } else if (!(args?.Length == 3) || args[0] == null || args[1] == null || args[2] == null) { SendReply(player, "Incorrect Sytax... /STFU "); return; } var target = FindPlayerByName(args[0]); if (target == null) { SendReply(player, $"{args[0]} not found, are they dead? is the name right?"); return; } if (storedData.MutedPlayers.ContainsKey(target.userID)) { SendReply(player, $"{target.displayName} is already muted"); return; } if (args[1].ToLower() == "perm") { addpermmute(player, target, args[2]); return; } TimeSpan timeSpan; if (!TryParseTimeSpan(args[1], out timeSpan)) { SendReply(player, "Invalid Time Span"); return; } else { addmute(player, target, DateTime.UtcNow + timeSpan, args[2]); } } [ConsoleCommand("STFU")] void stfucon(ConsoleSystem.Arg arg) { if (!(arg.Player() == null || arg.Player()?.IsAdmin == true)) { return; } else if (!(arg.Args?.Length == 3) || arg.Args[0] == null || arg.Args[1] == null || arg.Args[2] == null) { Puts("Incorrect Sytax... STFU Target duration in mins reason"); return; } var mutereason = arg.Args[2].ToString(); var target = FindPlayerByName(arg.Args[0]); if (target == null) { Puts($"{arg.Args[0]} not found, are they dead? is the name right?"); return; } if(storedData.MutedPlayers.ContainsKey(target.userID)) { Puts($"{target.displayName} is already muted"); return; } if (arg.Args[1].ToLower() == "perm") { addpermmute(null, target, arg.Args[2]); return; } TimeSpan timeSpan; if (!TryParseTimeSpan(arg.Args[1], out timeSpan)) { Puts("Invalid Time Span"); return; } else { addmute(null, target, DateTime.UtcNow + timeSpan, arg.Args[2]); } } [ChatCommand("Unshut")] void unshut(BasePlayer player, string cmd, string[] args) { if (!permission.UserHasPermission(player.userID.ToString(), "STFU.User")) { SendReply(player, "You do not have permission to use this command"); return; } else if (!(args?.Length == 1) || args[0] == null) { SendReply(player, "Incorrect Sytax... /Unshut "); return; } var target = FindPlayerByName(args[0]); if (target == null) { SendReply(player, $"{args[0]} not found, is the name right?"); return; } if (!storedData.MutedPlayers.ContainsKey(target.userID)) { SendReply(player, $"{target.displayName} is not currently muted"); } else { unmute(target, player); } } [ConsoleCommand("Unshut")] void unshutcon(ConsoleSystem.Arg arg) { if (!(arg.Player() == null || arg.Player()?.IsAdmin == true)) { return; } else if (!(arg.Args?.Length == 1) || arg.Args[0] == null) { Puts("Incorrect Sytax... Unshut Target"); return; } var target = FindPlayerByName(arg.Args[0]); if (target == null) { Puts($"{arg.Args[0]} not found, is the name right?"); return; } if (!storedData.MutedPlayers.ContainsKey(target.userID)) { Puts($"{target.displayName} is not currently muted"); } else { unmute(target, null); } } void addpermmute(BasePlayer player, BasePlayer target, string reason) { Mutes value = new Mutes(); storedData.MutedPlayers.Add(target.userID, value); storedData.MutedPlayers[target.userID].perm = true; storedData.MutedPlayers[target.userID].reason = reason; SendReply(target, $"You have been muted indefinitely for {reason}"); PrintToChat("" + "STFU" + ": " + $"{target.displayName} has been told to STFU indefinitely... for reason {reason}"); Puts($"{target.displayName} has been muted until indefinitely for {reason}"); warn(target, player, "perm", reason); SaveData(); } void addmute(BasePlayer player, BasePlayer target, DateTime time, string reason) { Mutes value = new Mutes(); storedData.MutedPlayers.Add(target.userID, value); storedData.MutedPlayers[target.userID].unmute = time; storedData.MutedPlayers[target.userID].reason = reason; float time2 = (float)(time - DateTime.UtcNow).TotalSeconds; UpdateMute(time2, target); SendReply(target, $"You have been muted until {time} mins"); PrintToChat("" + "STFU" + ": " + $"{target.displayName} has been told to STFU until {time} mins... reason {reason}"); Puts($"{target.displayName} has been muted until {time} mins for {reason}"); var timewarn = time.ToString(); warn(target, player, timewarn, reason); SaveData(); } void unmute(BasePlayer target, BasePlayer player) { storedData.MutedPlayers.Remove(target.userID); if (Timers.ContainsKey(target.userID)) { Timers[target.userID].Destroy(); } Puts($"player {target.displayName} has been unmuted"); PrintToChat("" + "STFU" + ": " + $"{target.displayName} has been unmunted"); if (player == null) { reversewarn(target, null); ; } else { reversewarn(target, player); } SaveData(); } public Dictionary Timers = new Dictionary(); void checkban() { if (storedData.MutedPlayers.ToList().Count() == 0) return; foreach (var entry in storedData.MutedPlayers.ToList()) { if (entry.Value.perm == true) return; var target = FindPlayerByName(entry.Key.ToString()); if (target == null) return; if (entry.Value.unmute < DateTime.UtcNow) { unmute(target, null); } else { UpdateMute((float)(entry.Value.unmute - DateTime.UtcNow).TotalSeconds, target); } } } void UpdateMute(float time, BasePlayer target) { Timers[target.userID] = timer.Once(time, () => unmute(target, null)); } static BasePlayer FindPlayerByName(string name) { BasePlayer result = null; foreach (BasePlayer current in BasePlayer.activePlayerList) { if (current.displayName.Equals(name, StringComparison.OrdinalIgnoreCase) || current.UserIDString.Contains(name, CompareOptions.OrdinalIgnoreCase) || current.displayName.Contains(name, CompareOptions.OrdinalIgnoreCase)) result = current; } return result; } public class Fields { public string name { get; set; } public string value { get; set; } public bool inline { get; set; } public Fields(string name, string value, bool inline) { this.name = name; this.value = value; this.inline = inline; } } void warn(BasePlayer target, BasePlayer player, string until, string reason) { if (configData.rp == false) return; { string reporter; if (player == null) { reporter = "console"; } else { reporter = player.displayName; } List fields = new List(); string json; fields.Add(new Fields("Target", $"[{target.displayName}](https://steamcommunity.com/profiles/{target.userID})", true)); fields.Add(new Fields("Muted By", reporter, true)); fields.Add(new Fields("Muted Untill", until, true)); fields.Add(new Fields("Reson", reason, false)); json = JsonConvert.SerializeObject(fields); DiscordMessages?.Call("API_SendFancyMessage", configData.wh, "STFU", 3329330, json, null); } } void reversewarn(BasePlayer target, BasePlayer player) { if (configData.rp == false) return; { string reporter; if (player == null) { reporter = "Console Or Time Expired"; } else { reporter = player.displayName; } List fields = new List(); string json; fields.Add(new Fields("Target", $"[{target.displayName}](https://steamcommunity.com/profiles/{target.userID})", true)); fields.Add(new Fields("UnMuted by", reporter, true)); fields.Add(new Fields("Reason", "Has been unmuted", false)); json = JsonConvert.SerializeObject(fields); DiscordMessages?.Call("API_SendFancyMessage", configData.wh, "STFU", 3329330, json, null); } } [ConsoleCommand("STFUlookup")] void lookup(ConsoleSystem.Arg arg) { if (!(arg.Player() == null || arg.Player()?.IsAdmin == true)) { return; } else { foreach (var entry in storedData.MutedPlayers) { var target = FindPlayerByName(entry.Key.ToString()); var reason = entry.Value.reason; if (entry.Value.perm == true) { Puts($"{target} was given a perm mute for reason {reason}"); } else { Puts($"{target} was given a mute for reason {reason} untill {entry.Value.unmute.ToString()}"); } } } } object OnPlayerVoice(BasePlayer player, Byte[] data) { if (storedData.MutedPlayers.ContainsKey(player.userID)) { if (storedData.MutedPlayers[player.userID].warned == false || storedData.MutedPlayers[player.userID].perm == true) { SendReply(player, "You are muted.. no one can hear you"); storedData.MutedPlayers[player.userID].warned = true; timer.Once(10, () => { storedData.MutedPlayers[player.userID].warned = false; }); } return false; } else return null; } string FormatTime(TimeSpan time) => $"{(time.Days == 0 ? string.Empty : $"{time.Days} day(s)")}{(time.Days != 0 && time.Hours != 0 ? $", " : string.Empty)}{(time.Hours == 0 ? string.Empty : $"{time.Hours} hour(s)")}{(time.Hours != 0 && time.Minutes != 0 ? $", " : string.Empty)}{(time.Minutes == 0 ? string.Empty : $"{time.Minutes} minute(s)")}{(time.Minutes != 0 && time.Seconds != 0 ? $", " : string.Empty)}{(time.Seconds == 0 ? string.Empty : $"{time.Seconds} second(s)")}"; private bool TryParseTimeSpan(string source, out TimeSpan timeSpan) { int seconds = 0, minutes = 0, hours = 0, days = 0; Match s = new Regex(@"(\d+?)s", RegexOptions.IgnoreCase).Match(source); Match m = new Regex(@"(\d+?)m", RegexOptions.IgnoreCase).Match(source); Match h = new Regex(@"(\d+?)h", RegexOptions.IgnoreCase).Match(source); Match d = new Regex(@"(\d+?)d", RegexOptions.IgnoreCase).Match(source); if (s.Success) seconds = Convert.ToInt32(s.Groups[1].ToString()); if (m.Success) minutes = Convert.ToInt32(m.Groups[1].ToString()); if (h.Success) hours = Convert.ToInt32(h.Groups[1].ToString()); if (d.Success) days = Convert.ToInt32(d.Groups[1].ToString()); source = source.Replace($"{seconds}s", string.Empty); source = source.Replace($"{minutes}m", string.Empty); source = source.Replace($"{hours}h", string.Empty); source = source.Replace($"{days}d", string.Empty); if (!string.IsNullOrEmpty(source) || (!s.Success && !m.Success && !h.Success && !d.Success)) { timeSpan = default(TimeSpan); return false; } timeSpan = new TimeSpan(days, hours, minutes, seconds); return true; } } }