using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; /* v1.3.3 * Added pages to the commands list, set in the config. */ /* v1.3.0 * Added time remaining on wipe command and supporting config option. * Cleanup. */ /* v1.2.1 * Cleanup. */ /* v1.2.0 * Efficiency improvements. */ namespace Oxide.Plugins { [Info("BasicInfo", "Gt403cyl2", "1.3.3")] [Description("Displays server info such as discord, rules, population, ect.")] internal class BasicInfo : RustPlugin { #region Fields private StringBuilder sb = new StringBuilder(); #endregion Fields #region config private ConfigData configData; private class ConfigData : BaseConfig { [JsonProperty(PropertyName = "Next Wipe Scheduled (YYYY-MM-DD HH:mm:ss):")] public DateTime WipeSchedule = new DateTime(2025, 7, 31, 8, 0, 0); [JsonProperty(PropertyName = "Rules Prefix:")] public string ChatPrefixRules = "Server Rules: "; [JsonProperty(PropertyName = "Discord Prefix:")] public string ChatPrefixDiscord = "Discord Address: "; [JsonProperty(PropertyName = "Website Prefix:")] public string ChatPrefixWebsite = "Website Address: "; [JsonProperty(PropertyName = "Population Prefix:")] public string ChatPrefixPop = "Population: "; [JsonProperty(PropertyName = "Server Commands Prefix:")] public string ChatPrefixComs = "Server Commands: "; [JsonProperty("Change Commands")] public Commands Commands = new Commands(); [JsonProperty(PropertyName = "Rules list:")] public string[] rulesList = new string[] { "1. Have respect for all members of this server.", "2. No racism of any sort.", "3. Strictly no spamming chat of any sorts.", "4. No cheating, including ESP, Scripting, Aimbot ect.", "5. Bans can be appealed in Discord." }; [JsonProperty(PropertyName = "Server Commands:")] public string[] comList = new string[] { "/shop - Opens shop.", "/bandit - Teleport to bandit.", "/outpost - Teleport to Outpost.", "/rules - Displays server rules.", "/commands - Displays server chat commands", "/discord - Displays Discord invite address.", "/website - Displays server website.", "/pop - Current server population", "/untilwipe - Displays next wipe details." }; [JsonProperty(PropertyName = "Discord Address:")] public string discadd = "Come Join our Discord at: https://discord.gg/HTaaNghRRp"; [JsonProperty(PropertyName = "Website Address:")] public string websadd = "Checkout our Website at: "; } private class BaseConfig { public string ToJson() => JsonConvert.SerializeObject(this); public Dictionary ToDictionary() => JsonConvert.DeserializeObject>(ToJson()); } private class Commands { [JsonProperty(PropertyName = "Commands list:")] public string comcom = "commands"; [JsonProperty(PropertyName = "Amount of commands per page:")] public int PageSize = 15; [JsonProperty(PropertyName = "Rules:")] public string rulescom = "rules"; [JsonProperty(PropertyName = "Discord:")] public string disccom = "discord"; [JsonProperty(PropertyName = "Website:")] public string webscom = "website"; [JsonProperty(PropertyName = "Population:")] public string popCommand = "pop"; [JsonProperty(PropertyName = "Wipe:")] public string untilWipe = "untilwipe"; } protected override void LoadDefaultConfig() => configData = new ConfigData(); protected override void LoadConfig() { base.LoadConfig(); try { configData = Config.ReadObject(); if (!configData.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys)) { PrintWarning($"{Name} Configuration appears to be outdated; updating and saving"); SaveConfig(); } } catch (FileNotFoundException) { PrintWarning($"No {Name} configuration file found, creating default"); LoadDefaultConfig(); SaveConfig(); } catch (JsonReaderException) { PrintError($"{Name} Configuration file contains invalid JSON, creating default"); } } protected override void SaveConfig() { PrintWarning($"Configuration changes saved to {Name}.json"); Config.WriteObject(configData, true); } private void Unload() { if (!string.IsNullOrEmpty(sb.ToString())) { sb.Clear(); } } private void Init() { cmd.AddChatCommand(configData.Commands.rulescom, this, Rules); cmd.AddChatCommand(configData.Commands.comcom, this, CommandsL); cmd.AddChatCommand(configData.Commands.disccom, this, Discord); cmd.AddChatCommand(configData.Commands.webscom, this, Website); cmd.AddChatCommand(configData.Commands.popCommand, this, CommandPop); cmd.AddChatCommand(configData.Commands.untilWipe, this, UntilWipe); } #endregion config #region commands private void Rules(BasePlayer player, string command, string[] args) { foreach (var rul in configData.rulesList) { if (!string.IsNullOrEmpty(rul)) { sb.AppendLine(rul); } } SendReply(player, $"{configData.ChatPrefixRules}\n{sb}"); sb.Clear(); } private void CommandsL(BasePlayer player, string command, string[] args) { int currentPage = 1; if (args.Length > 0) { int page; if (int.TryParse(args[0], out page)) { currentPage = Math.Max(page, 1); } } int pageSize = configData.Commands.PageSize; int startIndex = (currentPage - 1) * pageSize; int endIndex = Math.Min(startIndex + pageSize, configData.comList.Length); sb.AppendLine(configData.ChatPrefixComs + " - Page " + currentPage + ":"); for (int i = startIndex; i < endIndex; i++) { if (!string.IsNullOrEmpty(configData.comList[i])) { sb.AppendLine(configData.comList[i]); } } int totalPages = (int)Math.Ceiling((double)configData.comList.Length / pageSize); sb.AppendLine("Page " + currentPage + " of " + totalPages); if (currentPage < totalPages) { sb.AppendLine("Type /commands " + (currentPage + 1) + " to view the next page."); } SendReply(player, sb.ToString()); sb.Clear(); } private void Discord(BasePlayer player, string command, string[] args) { if (string.IsNullOrEmpty(configData.discadd) || configData.discadd == "Come Join our Discord at: https://discord.gg/HTaaNghRRp") return; SendReply(player, $"{configData.ChatPrefixDiscord}\n{configData.discadd}"); } private void Website(BasePlayer player, string command, string[] args) { if (string.IsNullOrEmpty(configData.websadd) || configData.websadd == "Checkout our Website at: ") return; SendReply(player, $"{configData.ChatPrefixWebsite}\n{configData.websadd}"); } private void CommandPop(BasePlayer player, string command, string[] args) { int pCount = BasePlayer.activePlayerList.Count; int psCount = BasePlayer.sleepingPlayerList.Count; int pJoin = ServerMgr.Instance.connectionQueue.Joining; int pQueued = ServerMgr.Instance.connectionQueue.Queued; string onlineMessage = $"{lang.GetMessage("ReportOnline", this)}{pCount}"; string sleepingMessage = $"{lang.GetMessage("ReportSleeping", this)}{psCount}"; string joiningMessage = $"{lang.GetMessage("ReportJoining", this)}{pJoin}"; string queuedMessage = $"{lang.GetMessage("ReportQueued", this)}{pQueued}"; if (pJoin == 0 && pQueued == 0) { SendReply(player, $"{configData.ChatPrefixPop}\n{onlineMessage}\n{sleepingMessage}"); } else if (pJoin != 0 && pQueued == 0) { SendReply(player, $"{configData.ChatPrefixPop}\n{onlineMessage}\n{sleepingMessage}\n{joiningMessage}"); } else if (pJoin == 0 && pQueued != 0) { SendReply(player, $"{configData.ChatPrefixPop}\n{onlineMessage}\n{sleepingMessage}\n{queuedMessage}"); } else { SendReply(player, $"{configData.ChatPrefixPop}\n{onlineMessage}\n{sleepingMessage}\n{joiningMessage}\n{queuedMessage}"); } } private void UntilWipe(BasePlayer player, string command, string[] args) { DateTime wipeDateTimeUtc = configData.WipeSchedule.ToUniversalTime(); DateTime currentDateTimeUtc = DateTime.UtcNow; TimeSpan serverTimeZoneOffset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow); DateTime currentDateTimePlayerTime = currentDateTimeUtc.Add(serverTimeZoneOffset); TimeSpan timeRemaining = wipeDateTimeUtc.Subtract(currentDateTimePlayerTime); int remainingDays = timeRemaining.Days; int remainingHours = timeRemaining.Hours; int remainingMinutes = timeRemaining.Minutes; string response = $"The next wipe is scheduled for {wipeDateTimeUtc:yyyy-MM-dd HH:mm:ss} (UTC).\nTime remaining: {remainingDays} days, {remainingHours} hours, {remainingMinutes} minutes"; SendReply(player, response); } #endregion commands #region Lang protected override void LoadDefaultMessages() { lang.RegisterMessages(new Dictionary { ["ReportOnline"] = $"Players Online: ", ["ReportSleeping"] = $"Players Sleeping: ", ["ReportJoining"] = $"Players Joining: ", ["ReportQueued"] = $"Players Queued: " }, this); } #endregion Lang } }