using Network; using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; namespace Oxide.Plugins { [Info("Suicide Cooldown", "ViolationHandler", "0.0.7")] [Description("Forces the suicide cooldown unless given bypass permissions.")] class SuicideCooldown : RustPlugin { private readonly object False = false; private Configuration config; private const string SuicideCooldownBypass = "suicidecooldown.bypass"; private void Init() { permission.RegisterPermission(SuicideCooldownBypass, this); } private void Loaded() { if (config.DefaultCooldown) return; foreach (var player in BasePlayer.activePlayerList.Where(player => player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup > 0)) { player.nextSuicideTime = UnityEngine.Time.realtimeSinceStartup + config.SuicideCooldown - (60 - (player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup)); } } private void Unload() { if (config.DefaultCooldown) return; if(config.SuicideCooldown > 60) { foreach (var player in BasePlayer.activePlayerList.Where(player => player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup > 60)) { player.nextSuicideTime = UnityEngine.Time.realtimeSinceStartup + (60 - (config.SuicideCooldown - (player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup))); } } else { foreach (var player in BasePlayer.activePlayerList.Where(player => player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup > 0)) { player.nextSuicideTime = UnityEngine.Time.realtimeSinceStartup + (60 - (config.SuicideCooldown - (player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup))); } } } protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["Dead"] = "You can't suicide while dead.", ["WaitTime"] = "You can't suicide again so quickly, wait {0} seconds." }, this); lang.RegisterMessages(new Dictionary { ["Dead"] = "Ye can't walk the plank while ye be already fish food, arr!", ["WaitTime"] = "Ye can't be takin' another plunge so swiftly, matey! Wait for {0} seconds." }, this, "en-PT"); } private class Configuration { [JsonProperty("Default Suicide Cooldown")] public bool DefaultCooldown { get; set; } = true; [JsonProperty("Suicide Cooldown")] public int SuicideCooldown { get; set; } = 60; [JsonProperty("Round the suicide cooldown to a whole number when displaying to user")] public bool RoundCooldown { get; set; } = false; [JsonProperty("Send responses to the user via F1 Console")] public bool F1Response { get; set; } = true; [JsonProperty("Send responses to the user via chat")] public bool ChatResponse { get; set; } = false; private string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } protected override void LoadDefaultConfig() => config = new Configuration(); 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)) { Puts("Configuration appears to be outdated; updating and saving."); SaveConfig(); } } catch { Puts($"Configuration file {Name}.json is invalid; using defaults"); LoadDefaultConfig(); } } protected override void SaveConfig() { Puts($"Configuration changes saved to {Name}.json"); Config.WriteObject(config, true); } // Credit to WhiteThunder for original code snippet that this started as and then eventually modified and patched <3 object OnClientCommand(Connection connection, string command) { // Fixes issues when users puts a space prior to sending kill. command = command.Trim(); // Checks if first four letters are kill as long as the message itself is only 4 letters, // Otherwise it makes sure theres a space separating the kill from any other words, otherwise it will just return null. if ((command.Length == 4 && command.Substring(0, 4) != "kill") || command.Length < 4 || ((command.Length > 4 && command.Substring(0, 4) == "kill" && command[4] != ' ') ^ (command.Length > 4 && command.Substring(0, 4) != "kill"))) { return null; } var player = connection.player as BasePlayer; if (player == null){ return null; } // Can't kill yourself while already dead, so no point to return anything. if (player.IsDead()) { player.ConsoleMessage(GetLang("Dead", player.UserIDString)); return False; } if (player.IPlayer.HasPermission(SuicideCooldownBypass)) return null; if (UnityEngine.Time.realtimeSinceStartup > player.nextSuicideTime){ NextTick(() => { if (!config.DefaultCooldown) { player.nextSuicideTime = UnityEngine.Time.realtimeSinceStartup + config.SuicideCooldown; } }); return null; } float cooldown = !config.RoundCooldown ? player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup : (int) ( player.nextSuicideTime - UnityEngine.Time.realtimeSinceStartup ); // Respond back to the player that they can't suicide yet, and their remaining time before they can suicide again. if(config.F1Response) { player.ConsoleMessage(GetLang("WaitTime", player.UserIDString, cooldown)); } if (config.ChatResponse) { player.ChatMessage(GetLang("WaitTime", player.UserIDString, cooldown)); } return False; } private string GetLang(string langKey, string playerId = null, params object[] args) { return string.Format(lang.GetMessage(langKey, this, playerId), args); } } }