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

FREE RealtimeWipeInfo : 2.1.5 2.1.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Reference: Facepunch.Sqlite

using System;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Realtime Wipe Info", "Ryan", "2.1.5")]
    class RealtimeWipeInfo : RustPlugin
    {
        #region Declaration

        // Plugin references
        [PluginReference] private Plugin BetterChat;

        // Datetimes
        private DateTime CachedWipeTime;
        private DateTime Epoch = new DateTime(1970, 1, 1);

        // Permissions
        private const string BypassPerm = "realtimewipeinfo.chatbypass";

        // Timers
        private Timer DescriptionTimer;
        private Timer TitleTimer;

        // Configuration and data
        private static ConfigFile CFile;
        private static DataFile DFile;

        // Instance
        private static RealtimeWipeInfo Instance;

        // Other variables
        private bool NewConfig;

        #endregion

        #region Configuration

        private class ConfigFile
        {
            [JsonProperty("Description Settings")]
            public DescriptionSettings Description;

            [JsonProperty("Title Settings")]
            public TitleSettings Title;

            [JsonProperty("Phrase Settings")]
            public PhraseSettings Phrase;

            [JsonProperty("Connect Message Settings")]
            public ConnectSettings Connect;

            [JsonProperty("Command Settings")]
            public CommandSettings Command;

            [JsonProperty("Blueprint settings")]
            public BlueprintSettings Blueprint;

            public static ConfigFile DefaultConfig()
            {
                return new ConfigFile()
                {
                    Description = new DescriptionSettings
                    {
                        Enabled = false,
                        Description = "Your description here.Put {0} where you want plugin info to go",
                        UseTime = true,
                        Date = new Date
                        {
                            Enabled = true,
                            Format = "dddd d/M"
                        },
                        Refresh = 120
                    },
                    Title = new TitleSettings
                    {
                        Enabled = false,
                        Title = "Your title here.Put {0} where you want plugin info to go",
                        UseTime = true,
                        Date = new Date
                        {
                            Enabled = true,
                            Format = "d/M"
                        },
                        Refresh = 60
                    },
                    Phrase = new PhraseSettings
                    {
                        Enabled = false,
                        Phrases = new Dictionary<string, PhraseItem>
                        {
                            ["wipe"] = new PhraseItem(true, true),
                            ["wipe?"] = new PhraseItem(true, false),
                            ["wiped"] = new PhraseItem(false, true),
                            ["wiped?"] = new PhraseItem(false, false)
                        },
                        UseTime = true,
                        Date = new Date
                        {
                            Enabled = true,
                            Format = "d/M"
                        },
                        Schedule = new ScheduleSettings
                        {
                            Enabled = true,
                            Schedule = 7,
                            Format = "dddd d/M"
                        }
                    },
                    Connect = new ConnectSettings
                    {
                        Enabled = false
                    },
                    Command = new CommandSettings()
                    {
                        Enabled = true,
                        Command = "wipe"
                    },
                    Blueprint = new BlueprintSettings()
                };
            }
        }

        #region Config Classes

        private class DescriptionSettings
        {
            [JsonProperty("Enable Description")]
            public bool Enabled;

            [JsonProperty("Full Server Description")]
            public string Description;

            [JsonProperty("Include Seed & Map Size")]
            public bool SeedSize;

            [JsonProperty("Enable Use Of Time")]
            public bool UseTime;

            public Date Date;

            [JsonProperty("Refresh Interval")]
            public float Refresh;
        }

        private class TitleSettings
        {
            [JsonProperty("Enable Title")]
            public bool Enabled;

            [JsonProperty("Full Server Hostname")]
            public string Title;

            [JsonProperty("Enable Use Of Time")]
            public bool UseTime;

            public Date Date;

            [JsonProperty("Refresh Interval")]
            public float Refresh;
        }

        private class PhraseSettings
        {
            [JsonProperty("Enable Phrases")]
            public bool Enabled;

            public Dictionary<string, PhraseItem> Phrases;

            [JsonProperty("Enable Use Of Time")]
            public bool UseTime;

            public Date Date;

            [JsonProperty("Schedule Settings")]
            public ScheduleSettings Schedule;
        }

        private class ConnectSettings
        {
            [JsonProperty("Enable Connect Messages")]
            public bool Enabled;
        }

        private class CommandSettings
        {
            public bool Enabled;
            public string Command;
        }

        private class Date
        {
            [JsonProperty("Enable Use Of Date")]
            public bool Enabled;

            [JsonProperty("Date format")]
            public string Format;
        }

        private class ScheduleSettings
        {
            [JsonProperty("Enable Wipe Schedule Messages")]
            public bool Enabled;

            [JsonProperty("Wipe Schedule In Days")]
            public int Schedule;

            [JsonProperty("Date Format")]
            public string Format;
        }

        private class PhraseItem
        {
            [JsonProperty("Send Reply")]
            public bool Message;

            [JsonProperty("Block Message")]
            public bool Block;

            public PhraseItem(bool message, bool block)
            {
                Message = message;
                Block = block;
            }
        }

        private class BlueprintSettings
        {
            [JsonProperty("Enable blueprint wipe tracking")]
            public bool Enabled;

            [JsonProperty("Add BP wipe to description")]
            public bool UseDescription;

            [JsonProperty("Use BP chat reply")]
            public bool UseChat;

            public BlueprintSettings()
            {
                Enabled = true;
                UseDescription = true;
                UseChat = true;
            }
        }

        #endregion

        protected override void LoadDefaultConfig()
        {
            PrintWarning($"All values are disabled by default, set them up at oxide/config/{Name}.json!");
            NewConfig = true;
            CFile = ConfigFile.DefaultConfig();
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                CFile = Config.ReadObject<ConfigFile>();
                if (CFile == null)
                {
                    Regenerate();
                    return;
                }
                if (CFile.Blueprint == null)
                {
                    CFile.Blueprint = new BlueprintSettings();
                    SaveConfig();
                }
            }
            catch { Regenerate(); }
        }

        protected override void SaveConfig() => Config.WriteObject(CFile);

        private void Regenerate()
        {
            PrintWarning($"Configuration file at 'oxide/config/{Name}.json' seems to be corrupt! Regenerating...");
            CFile = ConfigFile.DefaultConfig();
            SaveConfig();
        }

        #endregion

        #region Lang

        private struct Msg
        {
            public const string TitleDay = "TitleDay";
            public const string TitleDays = "TitleDays";
            public const string TitleHour = "TitleHour";
            public const string TitleHours = "TitleHours";
            public const string TitleMinutes = "TitleMinutes";
            public const string DescLastWipe = "DescLastWipe";
            public const string DescNextWipe = "DescNextWipe";
            public const string DescSeedSize = "DescSeedSize";
            public const string MsgTime = "MsgTime";
            public const string MsgDate = "MsgDate";
            public const string MsgDateTime = "MsgDateTime";
            public const string MsgNextWipe = "MsgNextWipe";
            public const string DescBpWipe = "DescBpWipe";
            public const string DescMsgBpWipe = "DescMsgBpWipe";
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Msg.TitleDay] = "{0} day ago",
                [Msg.TitleDays] = "{0} days ago",
                [Msg.TitleHour] = "{0} hour ago",
                [Msg.TitleHours] = "{0} hrs ago",
                [Msg.TitleMinutes] = "{0} mins ago",
                [Msg.DescLastWipe] = "The last wipe was on {0}",
                [Msg.DescNextWipe] = "The next wipe will be on {0} ({1} day wipe schedule)",
                [Msg.DescSeedSize] = "The map size is {0} and the seed is {1}",
                [Msg.MsgTime] = "The last wipe was {0} ago",
                [Msg.MsgDate] = "The last wipe was on {0}",
                [Msg.MsgDateTime] = "The last wipe was on {0} ({1} ago)",
                [Msg.MsgNextWipe] = "The next wipe will be on <color=orange>{0}</color> (<color=orange>{1}</color> day wipe schedule)",
                ["DayFormat"] = "<color=orange>{0}</color> day and <color=orange>{1}</color> hours",
                ["DaysFormat"] = "<color=orange>{0}</color> days and <color=orange>{1}</color> hours",
                ["HourFormat"] = "<color=orange>{0}</color> hour and <color=orange>{1}</color> minutes",
                ["HoursFormat"] = "<color=orange>{0}</color> hours and <color=orange>{1}</color> minutes",
                ["MinFormat"] = "<color=orange>{0}</color> minute and <color=orange>{1}</color> seconds",
                ["MinsFormat"] = "<color=orange>{0}</color> minutes and <color=orange>{1}</color> seconds",
                ["SecsFormat"] = "<color=orange>{0}</color> seconds",
                [Msg.DescBpWipe] = "(BP wiped {0})",
                [Msg.DescMsgBpWipe] = "(Blueprints wiped <color=orange>{0}</color>)"
            }, this);
        }

        #endregion

        #region Data

        private class DataFile
        {
            public string Hostname;
            public string Description;
            public DateTime BlueprintWipe;

            public DataFile()
            {
                Hostname = "";
                Description = "";
                BlueprintWipe = DateTime.MinValue;
            }

            public DataFile(string hostname, string description)
            {
                Hostname = hostname;
                Description = description;
            }
        }

        #endregion

        #region Methods

        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);

        private string GetFormattedTime(double time)
        {
            TimeSpan timeSpan = TimeSpan.FromSeconds(time);
            if (timeSpan.TotalSeconds < 1) return null;

            if (Math.Floor(timeSpan.TotalDays) >= 1)
                return string.Format(timeSpan.Days > 1 ? Lang("DaysFormat", null, timeSpan.Days, timeSpan.Hours) : Lang("DayFormat", null, timeSpan.Days, timeSpan.Hours));
            if (Math.Floor(timeSpan.TotalMinutes) >= 60)
                return string.Format(timeSpan.Hours > 1 ? Lang("HoursFormat", null, timeSpan.Hours, timeSpan.Minutes) : Lang("HourFormat", null, timeSpan.Hours, timeSpan.Minutes));
            if (Math.Floor(timeSpan.TotalSeconds) >= 60)
                return string.Format(timeSpan.Minutes > 1 ? Lang("MinsFormat", null, timeSpan.Minutes, timeSpan.Seconds) : Lang("MinFormat", null, timeSpan.Minutes, timeSpan.Seconds));
            return Lang("SecsFormat", null, timeSpan.Seconds);
        }

        #region Title Methods

        private void ApplyTitle(string title) => ConVar.Server.hostname = string.Format(CFile.Title.Title, title);

        private void StartTitleRefresh()
        {
            ApplyTitle(GetFormattedTitle());
            timer.Every(CFile.Title.Refresh, () =>
            {
                ApplyTitle(GetFormattedTitle());
            });
        }

        private string GetFormattedTitleTime()
        {
            TimeSpan timeSpan = TimeSpan.FromSeconds((DateTime.UtcNow.ToLocalTime() - CachedWipeTime).TotalSeconds);
            if (timeSpan.TotalSeconds < 1) return null;

            if (Math.Floor(timeSpan.TotalDays) >= 1)
                return string.Format(timeSpan.Days > 1 ? Lang(Msg.TitleDays, null, timeSpan.Days) : Lang(Msg.TitleDay, null, timeSpan.Days));
            if (Math.Floor(timeSpan.TotalMinutes) >= 60)
                return string.Format(timeSpan.Hours > 1 ? Lang(Msg.TitleHours, null, timeSpan.Hours) : Lang(Msg.TitleHour, null, timeSpan.Hours));
            return Lang(Msg.TitleMinutes, null, timeSpan.Minutes);
        }

        private string GetFormattedTitle()
        {
            if (CFile.Title.UseTime && !CFile.Title.Date.Enabled)
            {
                return GetFormattedTitleTime();
            }
            if (CFile.Title.Date.Enabled && !CFile.Title.UseTime)
            {
                return CachedWipeTime.ToString(CFile.Title.Date.Format);
            }
            if (CFile.Title.Date.Enabled && CFile.Title.UseTime)
            {
                return CachedWipeTime.ToString(CFile.Title.Date.Format) + " " + GetFormattedTitleTime();
            }
            return string.Empty;
        }

        #endregion

        #region Description Methods

        private void ApplyDescription(string description) => ConVar.Server.description = description;

        private void StartDescriptionRefresh()
        {
            ApplyDescription(GetFormattedDescription());
            timer.Every(CFile.Description.Refresh, () =>
            {
                ApplyDescription(GetFormattedDescription());
            });
        }

        private string GetFormattedDescription()
        {
            var output = "";
            if (CFile.Phrase.Schedule.Enabled)
            {
                output = string.Format(Lang(Msg.DescLastWipe, null, CachedWipeTime.ToString(CFile.Description.Date.Format)) + "\n" +
                    Lang(Msg.DescNextWipe, null, CachedWipeTime.AddDays(CFile.Phrase.Schedule.Schedule).ToString(CFile.Description.Date.Format), CFile.Phrase.Schedule.Schedule));
            }
            else
            {
                output = Lang(Msg.DescLastWipe, null, CachedWipeTime.ToString(CFile.Description.Date.Format));
            }
            if (CFile.Description.SeedSize)
            {
                output += "\n" + Lang(Msg.DescSeedSize, null, ConVar.Server.worldsize, ConVar.Server.seed);
            }
            if (CFile.Blueprint.Enabled)
            {
                output += " " + Lang(Msg.DescBpWipe, null, DFile.BlueprintWipe.ToLocalTime().ToString(CFile.Description.Date.Format));
            }
            return string.Format(CFile.Description.Description, output);
        }

        #endregion

        #region Phrase Methods

        private object ChatMessageResult(BasePlayer player, string input, bool reply)
        {
            if (!CFile.Phrase.Enabled) return null;
            foreach (var phrase in CFile.Phrase.Phrases)
            {
                if (input.ToLower().Contains(phrase.Key.ToLower()))
                {
                    if (phrase.Value.Message && reply)
                    {
                        PrintToChat(player, GetFormattedMessage(player));
                    }
                    if (phrase.Value.Block)
                    {
                        return false;
                    }
                    return null;
                }
            }
            return null;
        }

        private string GetFormattedMessageTime() => GetFormattedTime((DateTime.UtcNow.ToLocalTime() - CachedWipeTime).TotalSeconds);

        private string GetFormattedMessage(BasePlayer player)
        {
            var addition = string.Empty;
            if (CFile.Blueprint.Enabled) addition = " " + Lang(Msg.DescMsgBpWipe, player.UserIDString, DFile.BlueprintWipe.ToLocalTime().ToString(CFile.Phrase.Date.Format));
            if (CFile.Phrase.UseTime && !CFile.Phrase.Date.Enabled)
            {
                var output = Lang(Msg.MsgTime, player.UserIDString, GetFormattedMessageTime());
                if (CFile.Phrase.Schedule.Enabled)
                    output += "\n" + Lang(Msg.MsgNextWipe, player.UserIDString, CachedWipeTime.AddDays(CFile.Phrase.Schedule.Schedule).ToString(CFile.Phrase.Schedule.Format),
                                  CFile.Phrase.Schedule.Schedule);
                return output + addition;
            }
            if (CFile.Phrase.Date.Enabled && !CFile.Phrase.UseTime)
            {
                var output = Lang(Msg.MsgDate, player.UserIDString, CachedWipeTime.ToString(CFile.Phrase.Date.Format));
                if (CFile.Phrase.Schedule.Enabled)
                {
                    output += Lang(Msg.MsgNextWipe, player.UserIDString, CachedWipeTime.AddDays(CFile.Phrase.Schedule.Schedule).ToString(CFile.Phrase.Schedule.Format),
                        CFile.Phrase.Schedule.Schedule);
                }
                return output + addition;
            }
            if (CFile.Phrase.Date.Enabled && CFile.Phrase.UseTime)
            {
                var output = Lang(Msg.MsgDateTime, player.UserIDString, CachedWipeTime.ToString(CFile.Phrase.Date.Format), GetFormattedMessageTime());
                if (CFile.Phrase.Schedule.Enabled)
                {
                    output += "\n" + Lang(Msg.MsgNextWipe, player.UserIDString, CachedWipeTime.AddDays(CFile.Phrase.Schedule.Schedule).ToString(CFile.Phrase.Schedule.Format),
                                  CFile.Phrase.Schedule.Schedule);
                }
                return output + addition;
            }
            return null;
        }

        #endregion

        private void OnBpsWiped()
        {
            PrintWarning("Blueprint wipe detected!");
            Interface.Oxide.CallHook("OnUsersCleared");
            Interface.Oxide.DataFileSystem.WriteObject(Name, DFile);
        }

        #endregion

        #region Hooks

        private void Init()
        {
            DFile = Interface.Oxide.DataFileSystem.ReadObject<DataFile>(Name);
            permission.RegisterPermission(BypassPerm, this);
            cmd.AddChatCommand(CFile.Command.Command, this, WipeCommand);
            Instance = this;
            if (CFile.Phrase.Enabled && BetterChat && BetterChat.Version < new VersionNumber(5, 0, 6))
            {
                PrintWarning($"This plugin is only compatible with BetterChat version 5.0.6 or greater!");
                Unsubscribe("OnBetterChat");
            }
            if (NewConfig)
            {
                PrintWarning("Saved your current hostname and description to apply at a later date if needed");
                DFile = new DataFile(ConVar.Server.hostname, ConVar.Server.description);
                Interface.Oxide.DataFileSystem.WriteObject(Name, DFile);
            }
        }

        private void OnServerInitialized()
        {
            CachedWipeTime = SaveRestore.SaveCreatedTime.ToLocalTime();
            if (CFile.Blueprint.Enabled)
            {
                var blueprints = UserPersistance.blueprints;
                var playerCount = blueprints?.QueryInt("SELECT COUNT(*) FROM data");
                if (playerCount != null && playerCount == 0)
                {
                    DFile.BlueprintWipe = DateTime.UtcNow;
                    OnBpsWiped();
                }
                if (DFile.BlueprintWipe == null || DFile.BlueprintWipe == DateTime.MinValue)
                {
                    DFile.BlueprintWipe = SaveRestore.SaveCreatedTime;
                    OnBpsWiped();
                }
            }
            if (!CFile.Phrase.Enabled)
            {
                Unsubscribe("OnPlayerChat");
                Unsubscribe("OnBetterChat");
            }
            if (!CFile.Connect.Enabled)
            {
                Unsubscribe("OnPlayerInit");
            }
            if (CFile.Description.Enabled)
            {
                if (CFile.Description.UseTime)
                    StartDescriptionRefresh();
                else
                    ApplyDescription(GetFormattedDescription());
            }
            if (CFile.Title.Enabled)
            {
                if (CFile.Title.UseTime)
                    StartTitleRefresh();
                else
                    ApplyTitle(GetFormattedTitle());
            }
        }

        private void Unload()
        {
            TitleTimer?.Destroy();
            DescriptionTimer?.Destroy();
            if (!ConVar.Admin.ServerInfo().Restarting)
            {
                PrintWarning($"Setting servers hostname and description to the originally stored ones in oxide/data/{Name}.json");
                if(CFile.Title.Enabled) ConVar.Server.hostname = DFile.Hostname;
                if(CFile.Description.Enabled) ConVar.Server.description = DFile.Description;
            }
        }

        private void OnPlayerInit(BasePlayer player)
        {
            timer.Once(3, () =>
            {
                PrintToChat(player, GetFormattedMessage(player));
            });
        }

        private object OnPlayerChat(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (!permission.UserHasPermission(player.UserIDString, BypassPerm) && !player.IsAdmin)
            {
                return ChatMessageResult(player, arg.FullString, true);
            }
            return null;
        }

        private object OnBetterChat(Dictionary<string, object> data)
        {
            var player = (IPlayer)data["Player"];
            if (!player.HasPermission(BypassPerm) && !player.IsAdmin)
            {
                return ChatMessageResult((BasePlayer)player.Object, data["Text"].ToString(), false);
            }
            return null;
        }

        #endregion

        #region Commands

        private void WipeCommand(BasePlayer player, string command, string[] args)
        {
            PrintToChat(player, GetFormattedMessage(player));
        }

        #endregion
    }
}

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