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

FREE AutoRestart : 2.5.1 2.5.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Globalization;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("AutoRestart", "crash", "2.5.1")]
    [Description("All features are managed through an intuitive UI")]
    public class AutoRestart : RustPlugin {
#region Fields & References
        // Plugin References
        [PluginReference]
        private Plugin Economics;
        [PluginReference]
        private Plugin ServerRewards;
        // Constants
        private const string CurrentVersion = "2.5.1";
        private const int DISCORD_SUCCESS_CODE = 204;
        private const float DISCORD_ONLINE_DELAY = 300f;
        private const float RESTART_DELAY = 65f;
        private const float MINIMUM_CHECK_INTERVAL = 60f;
        private const int MINIMUM_RESTART_INTERVAL = 60;
        private const string PERMISSION_USE = "autorestart.use";
        private const string CHECKBOX_ON_SOUND = "assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab";
        private const string CHECKBOX_OFF_SOUND = "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab";
        // Configurations & Data Storage
        private ConfigData config;
        private List<int> notifiedWarningTimes = new List<int>();
        private Dictionary<string, string> _inputFieldValues = new Dictionary<string, string>();
        private Dictionary<string, string> _searchInputValues = new Dictionary<string, string>();
        private HashSet<ulong> rewardedPlayers = new HashSet<ulong>();
        private DateTime rewardStartTime = DateTime.MinValue;
        // Timers & Time Tracking
        private List<TimeSpan> restartTimes = new List<TimeSpan>();
        private List<Timer> activeTimers = new List<Timer>();
        private Timer nextRestartTimer;
        private Timer rewardLimitTimer;
        private DateTime lastRestartTime;
        private DateTime lastRestartCheck = DateTime.MinValue;
        // State Management
        private static bool hasSentDiscordOnlineNotification = false;
        private bool hasSentFinalRestartNotification = false;
        private bool isCustomRestart = false;
        private bool isCancelled = false;
        private bool isCustomUICreated = false;
        private bool isShuttingDown;
        private int customRestartTime = 0;
        // UI & Messages
        private string lastChatMessage = string.Empty;
        private string lastUIMessage = string.Empty;
#endregion
#region Configuration
        private class ConfigData {
            public string Version {
                get;
                set;
            }
            = CurrentVersion;
            public RestartConfig Restart {
                get;
                set;
            }
            = new RestartConfig();
            public PlayerRestrictionConfig PlayerRestrictions {
                get;
                set;
            }
            = new PlayerRestrictionConfig();
            public AlertConfig Alerts {
                get;
                set;
            }
            = new AlertConfig();
            public UpdateCheckConfig UpdateCheck {
                get;
                set;
            }
            = new UpdateCheckConfig();
            public UIConfig UI {
                get;
                set;
            }
            = new UIConfig();
            public DiscordConfig Discord {
                get;
                set;
            }
            = new DiscordConfig();
            public bool DisableDiscordCountdownMessages {
                get;
                set;
            }
            = false;
            public RewardsConfig Rewards {
                get;
                set;
            }
            = new RewardsConfig();
        }
        private class RestartConfig {
            public List<string> RestartTimes {
                get;
                set;
            }
            = new List<string>();
            public string AlertSound {
                get;
                set;
            }
            = "assets/prefabs/locks/keypad/effects/lock.code.lock.prefab";
            public bool UseSound {
                get;
                set;
            }
            = true;
            public bool UseChatAlerts {
                get;
                set;
            }
            = true;
            public bool SkipWipeDays {
                get;
                set;
            }
            = false;
            public List<string> WipeDays {
                get;
                set;
            }
            = new List<string>();
        }
        private class PlayerRestrictionConfig {
            public int MaxPlayersBeforeCancel {
                get;
                set;
            }
            = 10;
            public bool RestrictPlayerCount {
                get;
                set;
            }
            = false;
        }
        public class AlertConfig {
            public List<int> InGameWarningTimes {
                get;
                set;
            }
            = new List<int>();
            public List<int> DiscordWarningTimes {
                get;
                set;
            }
            = new List<int>();
        }
        private class UpdateCheckConfig {
            public bool CheckForUpdates {
                get;
                set;
            }
            = false;
            public int CheckInterval {
                get;
                set;
            }
            = 600;
        }
        private class UIConfig {
            public bool UseCustomUI {
                get;
                set;
            }
            = false;
            public bool UseRustUI {
                get;
                set;
            }
            = true;
            public CustomUISettings CustomUI {
                get;
                set;
            }
            = new CustomUISettings();
        }
        private class CustomUISettings {
            public string AnchorMin {
                get;
                set;
            }
            = "0 0.5";
            public string AnchorMax {
                get;
                set;
            }
            = "0 0.5";
            public string OffsetMin {
                get;
                set;
            }
            = "10 -45.9695";
            public string OffsetMax {
                get;
                set;
            }
            = "177.325 46.7435";
            public string CheckIcon {
                get;
                set;
            }
            = "✓";
            public string CrossIcon {
                get;
                set;
            }
            = "✗";
            public string CheckIconColor {
                get;
                set;
            }
            = "0.5568627 0.7764706 0.1843137 1";
            public string CrossIconColor {
                get;
                set;
            }
            = "0.7764706 0.5137255 0.4196078 1";
            [JsonIgnore]
            public string BackgroundColor {
                get => _backgroundColor;
                set {
                    _backgroundColor = value;
                    BackgroundColorHex = value.ToHex();
                }
            }
            private string _backgroundColor = "0.3137255 0.5843138 0.772549 0.85";
            public string BackgroundColorHex {
                get;
                private set;
            }
            = "#5094C5";
            public int TitleFontSize {
                get;
                set;
            }
            = 12;
            public int MessageFontSize {
                get;
                set;
            }
            = 10;
        }
        private class DiscordConfig {
            public string WebhookUrl {
                get;
                set;
            }
            = "https://support.discordapp.com/hc/en-us/articles/228383668-Intro-to-Webhooks";
            public string ServerName {
                get;
                set;
            }
            = "Rust Server";
            public bool DiscordNotifications {
                get;
                set;
            }
            = false;
            public bool UseFullMinuteCountdown {
                get;
                set;
            }
            = true;
        }
        private class RewardsConfig {
            public bool EnableRewards {
                get;
                set;
            }
            = false;
            public bool UseEconomics {
                get;
                set;
            }
            = false;
            public bool UseServerRewards {
                get;
                set;
            }
            = false;
            public Dictionary<string, int> ItemRewards {
                get;
                set;
            }
            = new Dictionary<string, int>();
            public double EconomicsAmount {
                get;
                set;
            }
            = 0;
            public int ServerRewardsPoints {
                get;
                set;
            }
            = 0;
            public int RewardTimeLimit {
                get;
                set;
            }
            = 300;
        }
        private class RewardsData {
            public List<ulong> RewardedPlayers {
                get;
                set;
            }
            = new List<ulong>();
            public DateTime RewardStartTime {
                get;
                set;
            }
        }
#endregion
#region Oxide Hooks
        private void Init() {
            permission.RegisterPermission(PERMISSION_USE, this);
            LoadConfigValues();
            UpdateLanguage();
            lastRestartTime = DateTime.UtcNow;
            isShuttingDown = false;
            DestroyAllUI();
            ClearAllTimers();
            LoadRewardsData();
            lastChatMessage = string.Empty;
            lastUIMessage = string.Empty;
            isCustomUICreated = false;
            notifiedWarningTimes.Clear();
            hasSentFinalRestartNotification = false;
        }
        private void OnServerInitialized() {
            try {
                timer.Once(5f, () => {
                    LogInfo("Initializing restart schedule...");
                    if (restartTimes.Count > 0) {
                        LogInfo($"Configured restart times: {string.Join(", ", restartTimes.Select(t => t.ToString(@"hh\ : mm")))}");
                        if (nextRestartTimer == null && !isCustomRestart) {
                            ScheduleNextRestartQuietly();
                        }
                    }
                    else {
                        LogInfo("No restart times configured.");
                    }
                    if (config.Discord.DiscordNotifications && !hasSentDiscordOnlineNotification) {
                        NotifyDiscordOnline();
                    }
                    if (config.Rewards.EnableRewards) {
                        rewardedPlayers.Clear();
                        timer.Once(10f, () => StartRewardPeriod());
                    }
                    timer.Every(3600f, () => {
                        if (nextRestartTimer != null) {
                            var nextRestart = DateTime.UtcNow.AddSeconds(nextRestartTimer.Repetitions);
                            LogInfo($"Periodic check - Next restart at: {nextRestart} UTC");
                        }
                        else if (restartTimes.Count > 0 && !isCustomRestart && !isCancelled) {
                            LogWarning("Periodic check - No restart scheduled! Attempting to reschedule...");
                            ScheduleNextRestartQuietly();
                        }
                    }
                    );
                }
                );
            }
            catch (Exception ex) {
                LogError($"Error in OnServerInitialized: {ex}", ex);
            }
        }
        private void ScheduleNextRestartQuietly() {
            if (isCustomRestart || isCancelled) {
                LogInfo($"Skipping restart schedule: CustomRestart={isCustomRestart}, Cancelled={isCancelled}");
                return;
            }
            if ((DateTime.UtcNow - lastRestartCheck).TotalSeconds < MINIMUM_CHECK_INTERVAL) {
                LogInfo("Skipping restart check - too soon since last check");
                return;
            }
            lastRestartCheck = DateTime.UtcNow;
            ClearAllTimers();
            if (restartTimes.Count == 0) {
                LogWarning("No restart times configured");
                return;
            }
            try {
                DateTime now = DateTime.UtcNow;
                DateTime nextRestart = FindNextRestartTime(now);
                if ((nextRestart - lastRestartTime).TotalSeconds < MINIMUM_RESTART_INTERVAL) {
                    LogWarning($"Preventing duplicate restart: Last restart at {lastRestartTime}, next scheduled for {nextRestart}");
                    nextRestart = nextRestart.AddDays(1);
                }
                TimeSpan timeUntilRestart = nextRestart - now;
                if (timeUntilRestart.TotalSeconds <= 0) {
                    LogWarning("Invalid restart time (in past), scheduling for next day");
                    nextRestart = nextRestart.AddDays(1);
                    timeUntilRestart = nextRestart - now;
                }
                int totalSeconds = (int)timeUntilRestart.TotalSeconds;
                LogInfo($"Scheduling next restart:");
                LogInfo($"Current time (UTC): {now}");
                LogInfo($"Next restart (UTC): {nextRestart}");
                LogInfo($"Time until restart: {timeUntilRestart.TotalHours:F2} hours");
                if (timeUntilRestart.TotalSeconds > 0 && CanScheduleRestart(nextRestart)) {
                    nextRestartTimer = timer.Once((float)timeUntilRestart.TotalSeconds, CheckPlayerCountAndRestart);
                    activeTimers.Add(nextRestartTimer);
                    if (config.Alerts.InGameWarningTimes != null && config.Alerts.InGameWarningTimes.Count > 0) {
                        foreach (int warningMinutes in config.Alerts.InGameWarningTimes) {
                            int warningSeconds = warningMinutes * 60;
                            if (warningSeconds < totalSeconds) {
                                Timer warningTimer = timer.Once(totalSeconds - warningSeconds, () => {
                                    if (!isCancelled) {
                                        ShowMessage(warningSeconds.ToString(), false);
                                        if (warningSeconds == 60) {
                                            customRestartTime = 60;
                                            CountdownFromMinute();
                                        }
                                    }
                                }
                                );
                                activeTimers.Add(warningTimer);
                            }
                        }
                    }
                    if (!config.Alerts.InGameWarningTimes.Contains(1)) {
                        Timer lastMinuteTimer = timer.Once(totalSeconds - 60, () => {
                            if (!isCancelled) {
                                customRestartTime = 60;
                                CountdownFromMinute();
                            }
                        }
                        );
                        activeTimers.Add(lastMinuteTimer);
                    }
                }
                else {
                    LogWarning("Invalid restart time calculated, skipping schedule");
                    timer.Once(300f, ScheduleNextRestartQuietly);
                }
            }
            catch (Exception ex) {
                LogError($"Error scheduling next restart: {ex}", ex);
                timer.Once(300f, ScheduleNextRestartQuietly);
            }
        }
        private void OnPlayerInit(BasePlayer player) {
            if (!string.IsNullOrEmpty(lastUIMessage)) {
                ShowMessage(lastUIMessage, false);
            }
        }
#endregion
#region Configuration Methods
        protected override void LoadDefaultConfig() {
            config = new ConfigData {
                Alerts = new AlertConfig {
                    InGameWarningTimes = new List<int>(), DiscordWarningTimes = new List<int>()
                }
            }
            ;
            Puts("Default config loaded without default WarningTimes.");
            SaveConfig();
        }
        private void SaveConfig() {
            Puts("Saving configuration to AutoRestart.json");
            Config.WriteObject(config, true);
            Puts("Configuration written to AutoRestart.json, please reload the plugin.");
        }
        private void LoadConfigValues() {
            if (!Config.Exists()) {
                Puts("Config does not exist, creating empty config.");
                LoadDefaultConfig();
                return;
            }
            config = Config.ReadObject<ConfigData>();
            if (config.Alerts.InGameWarningTimes == null) {
                config.Alerts.InGameWarningTimes = new List<int>();
            }
            if (config.Alerts.DiscordWarningTimes == null) {
                config.Alerts.DiscordWarningTimes = new List<int>();
            }
            if (config.Restart.WipeDays == null) {
                config.Restart.WipeDays = new List<string>();
            }
            else if (config.Restart.WipeDays.Count == 1 && config.Restart.WipeDays[0] == "Friday") {
                config.Restart.WipeDays.Clear();
            }
            if (config.Version != CurrentVersion) {
                Puts("Config version mismatch, updating config.");
                UpdateConfig();
            }
            config.UI.CustomUI.BackgroundColor = config.UI.CustomUI.BackgroundColor;
            LoadRestartTimes();
        }
        private void UpdateConfig() {
            PrintWarning("Updating configuration to the latest version.");
            config.Version = CurrentVersion;
            SaveConfig();
            PrintWarning("Configuration updated successfully.");
        }
        private void LoadRestartTimes() {
            try {
                LogInfo("Loading restart times...");
                restartTimes.Clear();
                HashSet<TimeSpan> uniqueRestartTimes = new HashSet<TimeSpan>();
                foreach (var timeString in config.Restart.RestartTimes) {
                    if (TimeSpan.TryParse(timeString, out TimeSpan restartTime)) {
                        if (restartTime.TotalHours >= 0 && restartTime.TotalHours < 24) {
                            if (uniqueRestartTimes.Add(restartTime)) {
                                restartTimes.Add(restartTime);
                                LogInfo($"Valid restart time added: {timeString}");
                            }
                            else {
                                LogWarning($"Duplicate restart time ignored: {timeString}");
                            }
                        }
                        else {
                            LogError($"Invalid time range (must be 00:00-23:59): {timeString}");
                        }
                    }
                    else {
                        LogError($"Invalid time format (use HH:mm): {timeString}");
                    }
                }
                if (restartTimes.Count == 0) {
                    LogWarning("No valid restart times configured!");
                }
                else {
                    LogInfo($"Successfully loaded {restartTimes.Count} restart time(s)");
                }
            }
            catch (Exception ex) {
                LogError("Error loading restart times", ex);
            }
        }
#endregion
#region Language Methods
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(GetDefaultMessages(), this);
        }
        private void UpdateLanguage() {
            var langFile = $"{Name}.json";
            var langPath = Path.Combine(Interface.Oxide.LangDirectory, "en", langFile);
            Dictionary<string, string> messages;
            if (File.Exists(langPath)) {
                messages = Config.ReadObject<Dictionary<string, string>>(langPath);
                var currentVersion = messages.ContainsKey("Version") ? messages["Version"] : "0.0.0";
                if (currentVersion != CurrentVersion) {
                    PrintWarning($"Updating language file from version {currentVersion} to {CurrentVersion}");
                    messages["Version"] = CurrentVersion;
                    Config.WriteObject(messages, false, langPath);
                    PrintWarning("Language file version updated while preserving existing translations.");
                }
            }
            else {
                messages = GetDefaultMessages();
            }
            lang.RegisterMessages(messages, this);
        }
        private void UpdateLanguageFile(Dictionary<string, string> messages, string langPath) {
            PrintWarning($"Updating language file from version {messages["Version"]} to {CurrentVersion}");
            var defaultMessages = GetDefaultMessages();
            bool changed = false;
            foreach (var entry in defaultMessages) {
                if (!messages.ContainsKey(entry.Key) || messages[entry.Key] != entry.Value) {
                    messages[entry.Key] = entry.Value;
                    changed = true;
                }
            }
            if (changed) {
                messages["Version"] = CurrentVersion;
                Config.WriteObject(messages, false, langPath);
                PrintWarning($"Language file updated successfully.New version: {CurrentVersion}");
            }
        }
        private Dictionary<string, string> GetDefaultMessages() {
            var messages = new Dictionary<string, string> {
                ["Version"]
                = CurrentVersion, ["ChatRestartAlert"] = "Server restart scheduled in {0}.", ["ChatRestartCanceled"] = "The server restart has been canceled.", ["ChatRestartNow"] = "RESTARTING...", ["ChatRestartCanceledTooManyPlayers"] = "Restart canceled due to too many players.", ["NoRestartScheduled"] = "No restart is currently scheduled.", ["RustUITitle"] = "SCHEDULED SERVER RESTART", ["RustUIMessage"] = "The server will restart in {0}.", ["CustomUITitle"] = "SCHEDULED SERVER RESTART", ["CustomUIMessage"] = "The server will restart in {0}.", ["NoPermission"] = "You do not have permission to use this command.", ["Usage"] = "Usage: /restart <time>[s|m|h] (e.g., 30s, 5m, 1h)", ["InvalidNumber"] = "Invalid time format.Use <number>[s|m|h] (e.g., 30s, 5m, 1h)", ["UpdateDetected"] = "A uMod update has been detected.The server will restart to apply the update.", ["DiscordRestartAlert"] = "🔄 **SERVER RESTART**\nServer will restart in {0}.", ["DiscordRestarting"] = "⚠️ **RESTARTING**\nServer is restarting now.Please wait 5 minutes for the server to be back online.", ["DiscordOnline"] = "✅ **SERVER ONLINE**\nServer is now online and ready to play!", ["TimeMinute"] = "minute", ["TimeMinutes"] = "minutes", ["TimeHour"] = "hour", ["TimeHours"] = "hours", ["TimeSecond"] = "second", ["TimeSeconds"] = "seconds", ["RewardEconomicsReceived"] = "You received ${0} from Economics reward!", ["RewardPointsReceived"] = "You received {0} RP from ServerRewards!", ["RewardItemReceived"] = "You received {0}x {1} from Item rewards!", ["RewardTimeLeft"] = "You received rewards for connecting during server restart.Rewards will be available for {0} more.", ["RewardPeriodEnded"] = "The reward period has ended."
            }
            ;
            lang.RegisterMessages(new Dictionary<string, string> {
                ["Version"]
                = CurrentVersion, ["ChatRestartAlert"] = "Перезапуск сервера запланирован через {0}.", ["ChatRestartCanceled"] = "Перезапуск сервера был отменен.", ["ChatRestartNow"] = "ПЕРЕЗАПУСК...", ["ChatRestartCanceledTooManyPlayers"] = "Перезапуск отменен из-за большого количества игроков.", ["NoRestartScheduled"] = "В настоящее время перезапуск не запланирован.", ["RustUITitle"] = "ЗАПЛАНИРОВАННЫЙ ПЕРЕЗАПУСК СЕРВЕРА", ["RustUIMessage"] = "Сервер перезапустится через {0}.", ["CustomUITitle"] = "ЗАПЛАНИРОВАННЫЙ ПЕРЕЗАПУСК СЕРВЕРА", ["CustomUIMessage"] = "Сервер перезапустится через {0}.", ["NoPermission"] = "У вас нет прав для использования этой команды.", ["Usage"] = "Использование: /restart <время>[s|m|h] (пример: 30s, 5m, 1h)", ["InvalidNumber"] = "Неверный формат времени.Используйте <число>[s|m|h] (пример: 30s, 5m, 1h)", ["UpdateDetected"] = "Обнаружено обновление uMod.Сервер будет перезапущен для применения обновления.", ["TimeMinute"] = "минута", ["TimeMinutes"] = "минут", ["TimeHour"] = "час", ["TimeHours"] = "часов", ["TimeSecond"] = "секунда", ["TimeSeconds"] = "секунд", ["RewardEconomicsReceived"] = "Вы получили ${0} от Economics!", ["RewardPointsReceived"] = "Вы получили {0} RP от ServerRewards!", ["RewardItemReceived"] = "Вы получили {0}x {1} из награды предметами!", ["RewardTimeLeft"] = "Вы получили награды за подключение во время перезапуска сервера.Награды будут доступны еще {0}.", ["RewardPeriodEnded"] = "Период получения наград закончился."
            }
            , this, "ru");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["Version"]
                = CurrentVersion, ["ChatRestartAlert"] = "Перезапуск сервера заплановано через {0}.", ["ChatRestartCanceled"] = "Перезапуск сервера було скасовано.", ["ChatRestartNow"] = "ПЕРЕЗАПУСК...", ["ChatRestartCanceledTooManyPlayers"] = "Перезапуск скасовано через велику кількість гравців.", ["NoRestartScheduled"] = "На даний момент перезапуск не заплановано.", ["RustUITitle"] = "ЗАПЛАНОВАНИЙ ПЕРЕЗАПУСК СЕРВЕРА", ["RustUIMessage"] = "Сервер перезапуститься через {0}.", ["CustomUITitle"] = "ЗАПЛАНОВАНИЙ ПЕРЕЗАПУСК СЕРВЕРА", ["CustomUIMessage"] = "Сервер перезапуститься через {0}.", ["NoPermission"] = "У вас немає прав для використання цієї команди.", ["Usage"] = "Використання: /restart <час>[s|m|h] (приклад: 30s, 5m, 1h)", ["InvalidNumber"] = "Невірний формат часу.Використовуйте <число>[s|m|h] (приклад: 30s, 5m, 1h)", ["UpdateDetected"] = "Виявлено оновлення uMod.Сервер буде перезапущено для застосування оновлення.", ["TimeMinute"] = "хвилина", ["TimeMinutes"] = "хвилин", ["TimeHour"] = "година", ["TimeHours"] = "годин", ["TimeSecond"] = "секунда", ["TimeSeconds"] = "секунд", ["RewardEconomicsReceived"] = "Ви отримали ${0} від Economics!", ["RewardPointsReceived"] = "Ви отримали {0} RP від ServerRewards!", ["RewardItemReceived"] = "Ви отримали {0}x {1} з нагороди предметами!", ["RewardTimeLeft"] = "Ви отримали нагороди за підключення під час перезапуску сервера.Нагороди будуть доступні ще {0}.", ["RewardPeriodEnded"] = "Період отримання нагород закінчився."
            }
            , this, "uk");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["Version"]
                = CurrentVersion, ["ChatRestartAlert"] = "Reinicio del servidor programado en {0}.", ["ChatRestartCanceled"] = "El reinicio del servidor ha sido cancelado.", ["ChatRestartNow"] = "REINICIANDO...", ["ChatRestartCanceledTooManyPlayers"] = "Reinicio cancelado debido a demasiados jugadores.", ["NoRestartScheduled"] = "No hay reinicio programado actualmente.", ["RustUITitle"] = "REINICIO DE SERVIDOR PROGRAMADO", ["RustUIMessage"] = "El servidor se reiniciará en {0}.", ["CustomUITitle"] = "REINICIO DE SERVIDOR PROGRAMADO", ["CustomUIMessage"] = "El servidor se reiniciará en {0}.", ["NoPermission"] = "No tienes permiso para usar este comando.", ["Usage"] = "Uso: /restart <tiempo>[s|m|h] (ejemplo: 30s, 5m, 1h)", ["InvalidNumber"] = "Formato de tiempo inválido.Usa <número>[s|m|h] (ejemplo: 30s, 5m, 1h)", ["UpdateDetected"] = "Se ha detectado una actualización de uMod.El servidor se reiniciará para aplicar la actualización.", ["TimeMinute"] = "minuto", ["TimeMinutes"] = "minutos", ["TimeHour"] = "hora", ["TimeHours"] = "horas", ["TimeSecond"] = "segundo", ["TimeSeconds"] = "segundos", ["RewardEconomicsReceived"] = "¡Has recibido ${0} de recompensa Economics!", ["RewardPointsReceived"] = "¡Has recibido {0} RP de ServerRewards!", ["RewardItemReceived"] = "¡Has recibido {0}x {1} de recompensa de objetos!", ["RewardTimeLeft"] = "Has recibido recompensas por conectarte durante el reinicio del servidor.Las recompensas estarán disponibles por {0} más.", ["RewardPeriodEnded"] = "El período de recompensas ha terminado."
            }
            , this, "es-ES");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["Version"]
                = CurrentVersion, ["ChatRestartAlert"] = "Reinício do servidor programado em {0}.", ["ChatRestartCanceled"] = "O reinício do servidor foi cancelado.", ["ChatRestartNow"] = "REINICIANDO...", ["ChatRestartCanceledTooManyPlayers"] = "Reinício cancelado devido ao excesso de jogadores.", ["NoRestartScheduled"] = "Nenhum reinício está programado no momento.", ["RustUITitle"] = "REINÍCIO DO SERVIDOR PROGRAMADO", ["RustUIMessage"] = "O servidor será reiniciado em {0}.", ["CustomUITitle"] = "REINÍCIO DO SERVIDOR PROGRAMADO", ["CustomUIMessage"] = "O servidor será reiniciado em {0}.", ["NoPermission"] = "Você não tem permissão para usar este comando.", ["Usage"] = "Uso: /restart <tempo>[s|m|h] (exemplo: 30s, 5m, 1h)", ["InvalidNumber"] = "Formato de tempo inválido.Use <número>[s|m|h] (exemplo: 30s, 5m, 1h)", ["UpdateDetected"] = "Uma atualização do uMod foi detectada.O servidor será reiniciado para aplicar a atualização.", ["TimeMinute"] = "minuto", ["TimeMinutes"] = "minutos", ["TimeHour"] = "hora", ["TimeHours"] = "horas", ["TimeSecond"] = "segundo", ["TimeSeconds"] = "segundos", ["RewardEconomicsReceived"] = "Você recebeu ${0} de recompensa Economics!", ["RewardPointsReceived"] = "Você recebeu {0} RP de ServerRewards!", ["RewardItemReceived"] = "Você recebeu {0}x {1} de recompensa de itens!", ["RewardTimeLeft"] = "Você recebeu recompensas por se conectar durante o reinício do servidor.As recompensas estarão disponíveis por mais {0}.", ["RewardPeriodEnded"] = "O período de recompensas terminou."
            }
            , this, "pt-BR");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["Version"]
                = CurrentVersion, ["ChatRestartAlert"] = "Redémarrage du serveur prévu dans {0}.", ["ChatRestartCanceled"] = "Le redémarrage du serveur a été annulé.", ["ChatRestartNow"] = "REDÉMARRAGE...", ["ChatRestartCanceledTooManyPlayers"] = "Redémarrage annulé en raison de trop de joueurs.", ["NoRestartScheduled"] = "Aucun redémarrage n'est actuellement prévu.", ["RustUITitle"] = "REDÉMARRAGE DU SERVEUR PROGRAMMÉ", ["RustUIMessage"] = "Le serveur redémarrera dans {0}.", ["CustomUITitle"] = "REDÉMARRAGE DU SERVEUR PROGRAMMÉ", ["CustomUIMessage"] = "Le serveur redémarrera dans {0}.", ["NoPermission"] = "Vous n'avez pas la permission d'utiliser cette commande.", ["Usage"] = "Utilisation: /restart <temps>[s|m|h] (exemple: 30s, 5m, 1h)", ["InvalidNumber"] = "Format de temps invalide.Utilisez <nombre>[s|m|h] (exemple: 30s, 5m, 1h)", ["UpdateDetected"] = "Une mise à jour uMod a été détectée.Le serveur va redémarrer pour appliquer la mise à jour.", ["TimeMinute"] = "minute", ["TimeMinutes"] = "minutes", ["TimeHour"] = "heure", ["TimeHours"] = "heures", ["TimeSecond"] = "seconde", ["TimeSeconds"] = "secondes", ["RewardEconomicsReceived"] = "Vous avez reçu ${0} de récompense Economics !", ["RewardPointsReceived"] = "Vous avez reçu {0} RP de ServerRewards !", ["RewardItemReceived"] = "Vous avez reçu {0}x {1} de récompense d'objets !", ["RewardTimeLeft"] = "Vous avez reçu des récompenses pour vous être connecté pendant le redémarrage du serveur.Les récompenses seront disponibles pendant encore {0}.", ["RewardPeriodEnded"] = "La période de récompenses est terminée."
            }
            , this, "fr");
            return messages;
        }
#endregion
#region Command Handlers
        [ChatCommand("crestart")]
        private void CmdCRestart(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) {
                player.ChatMessage(GetLang("NoPermission", player.UserIDString));
                return;
            }
            if (args == null || args.Length == 0) {
                ShowCRestartUI(player);
                return;
            }
            switch (args[0].ToLower()) {
                case "rewards" : ShowRewardsUI(player);
                break;
                case "help" : ShowCommandHelp(player);
                break;
                default : ShowCRestartUI(player);
                break;
            }
        }
        private void ShowCommandHelp(BasePlayer player) {
            var sb = new StringBuilder();
            sb.AppendLine("Available CRestart Commands:");
            sb.AppendLine("/crestart - Opens the main configuration UI");
            sb.AppendLine("/crestart rewards - Opens the rewards configuration UI");
            sb.AppendLine("/crestart help - Shows this help message");
            player.ChatMessage(sb.ToString());
        }
        [ChatCommand("restart")]
        private void CommandRestart(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) {
                player.ChatMessage(GetLang("NoPermission", player.UserIDString));
                return;
            }
            if (args == null || args.Length < 1) {
                player.ChatMessage(GetLang("Usage", player.UserIDString));
                return;
            }
            int seconds = ParseTimeWithUnit(args[0]);
            if (seconds <= 0) {
                player.ChatMessage(GetLang("InvalidNumber", player.UserIDString));
                return;
            }
            LogInfo($"Restart command received: Input='{args[0]}', Converted to {seconds} seconds");
            StartCustomRestart(seconds);
        }
        [ChatCommand("restartstop")]
        private void ChatRestartStopCommand(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) {
                SendReply(player, GetLang("NoPermission", player.UserIDString));
                return;
            }
            bool hasActiveRestart = nextRestartTimer != null || activeTimers.Count > 0 || isCustomRestart;
            if (hasActiveRestart) {
                CancelRestart();
            }
            else {
                SendReply(player, GetLang("NoRestartScheduled", player.UserIDString));
            }
        }
        [ConsoleCommand("restart")]
        private void ConsoleRestart(ConsoleSystem.Arg arg) {
            if (!arg.IsServerside && !arg.IsAdmin) {
                Puts("You don't have permission to use this command.");
                return;
            }
            if (arg.Args == null || arg.Args.Length < 1) {
                Puts("Usage: restart <time>[s|m|h] (e.g., 30s, 5m, 1h)");
                return;
            }
            int seconds = ParseTimeWithUnit(arg.Args[0]);
            if (seconds <= 0) {
                Puts("Invalid time format.Use <number>[s|m|h] (e.g., 30s, 5m, 1h)");
                return;
            }
            StartCustomRestart(seconds);
            Puts($"Initiated a custom restart in {seconds} seconds.");
        }
        [ConsoleCommand("restartstop")]
        private void ConsoleRestartStopCommand(ConsoleSystem.Arg arg) {
            if (arg.IsServerside || arg.IsAdmin) {
                if (isCustomRestart || nextRestartTimer != null) {
                    CancelRestart();
                }
                else {
                    Puts("No restart is currently scheduled.");
                }
            }
            else {
                Puts("You don't have permission to use this command.");
            }
        }
        [ConsoleCommand("restart.list")]
        private void CmdListNextRestarts(ConsoleSystem.Arg arg) {
            if (!arg.IsAdmin) return;
            var sb = new StringBuilder();
            sb.AppendLine("Upcoming Restarts (UTC):");
            if (config.Restart.SkipWipeDays && config.Restart.WipeDays != null && config.Restart.WipeDays.Count > 0) {
                sb.AppendLine("Skipped Wipe Days:");
                foreach (var day in config.Restart.WipeDays) {
                    sb.AppendLine($"- {day}");
                }
                sb.AppendLine();
            }
            DateTime now = DateTime.UtcNow;
            var upcomingRestarts = new List<DateTime>();
            foreach (var time in restartTimes) {
                var todayTime = now.Date.Add(time);
                if (todayTime > now) {
                    if (!ShouldSkipRestart(todayTime)) {
                        upcomingRestarts.Add(todayTime);
                    }
                }
            }
            foreach (var time in restartTimes) {
                var tomorrowTime = now.Date.AddDays(1).Add(time);
                if (!ShouldSkipRestart(tomorrowTime)) {
                    upcomingRestarts.Add(tomorrowTime);
                }
            }
            if (upcomingRestarts.Count == 0) {
                sb.AppendLine("No upcoming restarts found.");
            }
            else {
                foreach (var restart in upcomingRestarts.OrderBy(x => x).Take(5)) {
                    var timeUntil = restart - now;
                    string timeUntilString = FormatTimeUntil(timeUntil);
                    sb.AppendLine($"- {restart:yyyy-MM-dd HH:mm:ss} (in {timeUntilString})");
                }
            }
            Puts(sb.ToString());
        }
        private string FormatTimeUntil(TimeSpan timeSpan) {
            if (timeSpan.TotalMinutes < 1) {
                return "less than a minute";
            }
            else if (timeSpan.TotalHours < 1) {
                return $"{(int)timeSpan.TotalMinutes} minute{(timeSpan.Minutes == 1 ? "" : "s")}";
            }
            else if (timeSpan.TotalHours < 24) {
                int hours = (int)timeSpan.TotalHours;
                int minutes = timeSpan.Minutes;
                if (minutes == 0) return $"{hours} hour{(hours == 1 ? "" : "s")}";
                else return $"{hours} hour{(hours == 1 ? "" : "s")} {minutes} minute{(minutes == 1 ? "" : "s")}";
            }
            else {
                int days = (int)timeSpan.TotalDays;
                int hours = timeSpan.Hours;
                if (hours == 0) return $"{days} day{(days == 1 ? "" : "s")}";
                else return $"{days} day{(days == 1 ? "" : "s")} {hours} hour{(hours == 1 ? "" : "s")}";
            }
        }
        private bool ShouldSkipRestart(DateTime restartTime) {
            if (!config.Restart.SkipWipeDays || config.Restart.WipeDays == null || config.Restart.WipeDays.Count == 0) return false;
            string dayName = restartTime.DayOfWeek.ToString();
            return config.Restart.WipeDays.Contains(dayName, StringComparer.OrdinalIgnoreCase);
        }
        [ConsoleCommand("crestart.toggle")]
        private void CmdToggleSetting(ConsoleSystem.Arg arg) {
            var player = arg.Player();
            if (player == null || !permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) return;
            var setting = arg.GetString(0);
            bool newValue = !GetConfigValue(setting);
            SetConfigValue(setting, newValue);
            string soundEffect = newValue ? CHECKBOX_ON_SOUND : CHECKBOX_OFF_SOUND;
            Effect.server.Run(soundEffect, player.transform.position);
            Puts($"Toggled setting: {setting} to {newValue}");
            SaveConfig();
            ShowCRestartUI(player);
        }
        [ConsoleCommand("crestart.input")]
        private void CmdInputSetting(ConsoleSystem.Arg arg) {
            var player = arg.Player();
            if (player == null || !permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) return;
            if (arg.Args == null || arg.Args.Length < 2) {
                PrintError("Insufficient arguments provided for crestart.input command.");
                return;
            }
            string setting = arg.Args[0];
            string value = string.Join(" ", arg.Args.Skip(1).ToArray());
            Puts($"Received input for setting: {setting}, with value: {value}");
            string key = $"{player.UserIDString}_{setting}";
            _inputFieldValues[key] = value;
            if (string.IsNullOrEmpty(value)) {
                Puts($"Error: No value provided for setting {setting}");
                return;
            }
            switch (setting) {
                case "InGameWarningTimes" : try {
                    var newInGameWarningTimes = value.Split(',').Select(s => int.Parse(s.Trim())).Where(i => i > 0).Distinct().OrderByDescending(x => x).ToList();
                    config.Alerts.InGameWarningTimes = newInGameWarningTimes;
                    Puts($"Updated InGameWarningTimes: {string.Join(", ", config.Alerts.InGameWarningTimes)}");
                }
                catch (FormatException) {
                    PrintError($"Invalid format for InGameWarningTimes: {value}");
                }
                break;
                case "DiscordWarningTimes" : try {
                    var newDiscordWarningTimes = value.Split(',').Select(s => int.Parse(s.Trim())).Where(i => i > 0).Distinct().OrderByDescending(x => x).ToList();
                    config.Alerts.DiscordWarningTimes = newDiscordWarningTimes;
                    Puts($"Updated DiscordWarningTimes: {string.Join(", ", config.Alerts.DiscordWarningTimes)}");
                }
                catch (FormatException) {
                    PrintError($"Invalid format for DiscordWarningTimes: {value}");
                }
                break;
                case "RestartTimes" : try {
                    var newRestartTimes = value.Split(',').Select(s => s.Trim()).ToList();
                    config.Restart.RestartTimes = newRestartTimes;
                    LoadRestartTimes();
                    Puts($"Updated RestartTimes: {string.Join(", ", config.Restart.RestartTimes)}");
                }
                catch (Exception ex) {
                    PrintError($"Error updating RestartTimes: {ex.Message}");
                }
                break;
                case "AlertSound" : config.Restart.AlertSound = value;
                Puts($"Updated AlertSound: {value}");
                break;
                case "MaxPlayersBeforeCancel" : if (int.TryParse(value, out int maxPlayers)) {
                    config.PlayerRestrictions.MaxPlayersBeforeCancel = maxPlayers;
                    Puts($"Updated MaxPlayersBeforeCancel: {maxPlayers}");
                }
                else {
                    PrintError($"Invalid MaxPlayersBeforeCancel value: {value}");
                }
                break;
                case "CheckInterval" : if (int.TryParse(value, out int interval)) {
                    config.UpdateCheck.CheckInterval = interval;
                    Puts($"Updated CheckInterval: {interval}");
                }
                else {
                    PrintError($"Invalid CheckInterval value: {value}");
                }
                break;
                case "WebhookUrl" : config.Discord.WebhookUrl = value;
                Puts($"Updated WebhookUrl: {value}");
                break;
                case "ServerName" : config.Discord.ServerName = value;
                Puts($"Updated ServerName: {value}");
                break;
                case "WipeDays" : try {
                    var newWipeDays = value.Split(',').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).Select(s => char.ToUpper(s[0]) + s.Substring(1).ToLower()).Where(day => Enum.TryParse<DayOfWeek>(day, out _)).ToList();
                    if (newWipeDays.Any()) {
                        config.Restart.WipeDays = newWipeDays;
                        Puts($"Updated WipeDays: {string.Join(", ", newWipeDays)}");
                        string inputKey = $"{player.UserIDString}_WipeDays";
                        _inputFieldValues[inputKey] = string.Join(", ", newWipeDays);
                        ShowCRestartUI(player);
                    }
                    else {
                        PrintError($"No valid days found in input: {value}");
                    }
                }
                catch (Exception ex) {
                    PrintError($"Error updating WipeDays: {ex.Message}");
                }
                break;
                default : Puts($"Setting '{setting}' is not recognized.");
                return;
            }
            SaveConfig();
            LoadConfigValues();
            UpdateCRestartUI(player);
        }
        [ConsoleCommand("crestart.submit")]
        private void CmdSubmitSetting(ConsoleSystem.Arg arg) {
            var player = arg.Player();
            if (player == null || !permission.UserHasPermission(player.UserIDString, PERMISSION_USE)) return;
            var setting = arg.GetString(0);
            var value = arg.GetString(1, "");
            if (string.IsNullOrEmpty(value)) {
                Puts($"Error: No value provided for setting {setting}");
                return;
            }
            UpdateConfigValue(setting, value);
            SaveConfig();
            Puts($"Config updated: {setting} = {value}");
            CuiHelper.DestroyUi(player, "InputFieldsPanel");
            CuiHelper.DestroyUi(player, "ScrollContainer");
            CuiHelper.DestroyUi(player, "ScrollContainer.View");
            CuiHelper.DestroyUi(player, "ScrollContainer.View.Content");
            ShowCRestartUI(player);
        }
        private void UpdateConfigValue(string setting, string value) {
            switch (setting) {
                case "InGameWarningTimes" : try {
                    var newInGameWarningTimes = value.Split(',').Select(s => int.Parse(s.Trim())).Where(i => i > 0).Distinct().OrderByDescending(x => x).ToList();
                    config.Alerts.InGameWarningTimes = newInGameWarningTimes;
                    Puts($"Updated InGameWarningTimes: {string.Join(", ", config.Alerts.InGameWarningTimes)}");
                }
                catch (FormatException) {
                    PrintError($"Invalid format for InGameWarningTimes: {value}");
                }
                break;
                case "DiscordWarningTimes" : try {
                    var newDiscordWarningTimes = value.Split(',').Select(s => int.Parse(s.Trim())).Where(i =>
// ... [Code preview truncated due to length. Full source in attached file] ...

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