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

FREE HarmonyLogManager : 1.0.1 1.0.1

Нет прав для скачивания
C#:
using Newtonsoft.Json;
using System;
using System.IO;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using HarmonyLib;

namespace Oxide.Plugins
{
    [Info("HarmonyLogManager", "ZEODE", "1.0.1")]
    [Description("Manages Harmony logging and log rotation")]
    public class HarmonyLogManager : CovalencePlugin
    {
        #region Configuration
        private ConfigData config;

        public class ConfigData
        {
            [JsonProperty(PropertyName = "Disable Global Verbose Harmony Logging")]
            public bool DisableHarmonyLogging { get; set; } = false;
            [JsonProperty(PropertyName = "Enable Log Rotation")]
            public bool EnableLogRotation { get; set; } = true;
            [JsonProperty(PropertyName = "Log Rotation Mode (daily, hourly, size)")]
            public string RotationMode { get; set; } = "daily"; // "daily", "hourly", "size"

            [JsonProperty(PropertyName = "Daily Mode Options")]
            public DailyRotation Daily { get; set; }

            [JsonProperty(PropertyName = "Hourly Mode Options")]
            public HourlyRotation Hourly { get; set; }

            [JsonProperty(PropertyName = "Size Mode Options")]
            public SizeRotation Size { get; set; }

            [JsonProperty(PropertyName = "Log File Options")]
            public LogFileOptions File { get; set; }

            public VersionNumber Version { get; set; }
        }

        public class DailyRotation
        {
            [JsonProperty(PropertyName = "Daily Log Rotation Time as HH:MM:SS Format")]
            public string DailyRotationTime { get; set; } = "23:59:59"; // HH:MM:SS format
        }

        public class HourlyRotation
        {
            [JsonProperty(PropertyName = "Log Rotation Every HH Hours")]
            public int RotationHours { get; set; } = 24;
        }

        public class SizeRotation
        {
            [JsonProperty(PropertyName = "Max Log File Size (MB)")]
            public int MaxFileSizeMB { get; set; } = 50;
            [JsonProperty(PropertyName = "Log File Size Checking Interval (seconds)")]
            public float FileSizeCheckInterval { get; set; } = 300f;
        }

        public class LogFileOptions
        {
            [JsonProperty(PropertyName = "Path to Harmony Log File (default = harmony_log.txt)")]
            public string HarmonyLogFile { get; set; } = "harmony_log.txt";
            [JsonProperty(PropertyName = "Path to Store Old Log Files (default = oxide/logs/Harmony/")]
            public string StoredLogPath { get; set; } = "oxide/logs/Harmony/";
            [JsonProperty(PropertyName = "Max Stored Log Files (Oldest Deleted First)")]
            public int MaxBackupFiles { get; set; } = 30;
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<ConfigData>();

                if (config == null)
                {
                    LoadDefaultConfig();
                }
                else if (config.Version < Version)
                {
                    UpdateConfigValues();
                }
            }
            catch (Exception ex)
            {
                if (ex is JsonSerializationException || ex is NullReferenceException || ex is JsonReaderException)
                {
                    Puts($"Exception Type: {ex.GetType()}");
                    Puts($"INFO: {ex}");
                    return;
                }
                throw;
            }
        }

        protected override void LoadDefaultConfig()
        {
            Puts("Configuration file missing or corrupt, creating default config file.");
            config = GetDefaultConfig();
            SaveConfig();
        }

        private ConfigData GetDefaultConfig()
        {
            return new ConfigData
            {
                Daily = new DailyRotation(),
                Hourly = new HourlyRotation(),
                Size = new SizeRotation(),
                File = new LogFileOptions(),
                Version = Version
            };
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(config, true);
        }

        private void UpdateConfigValues()
        {
            ConfigData defaultConfig = GetDefaultConfig();

            Puts("Config update detected! Updating config file...");

            if (config.Version < new VersionNumber(1, 0, 0))
            {
                config = defaultConfig;
            }
            config.Version = Version;
            SaveConfig();
            Puts("Config update complete!");
        }

        #endregion

        #region Fields
        private Timer rotationTimer;
        private string harmonyLogPath;
        #endregion

        #region Initialization
        void Init()
        {
            LoadConfig();
        }

        private void OnServerInitialized()
        {
            harmonyLogPath = config.File.HarmonyLogFile;

            NextTick(() => PrintWarning($"INFO: HarmonyLogManager loading, stand by..."));
            // Wait until any other plugins that might alter the Harmony.DEBUG flag to load before altering the flag
            timer.Once(5f, () =>
            {
                ConfigureHarmonyLogging();
                
                if (config.EnableLogRotation)
                {
                    SetupLogRotation();
                }
                
                PrintWarning($"INFO: HarmonyLogManager loaded - Logging: {(config.DisableHarmonyLogging ? "Disabled" : "Enabled")}, Rotation: {(config.EnableLogRotation ? "Enabled" : "Disabled")}");
            });
        }

        void Unload()
        {
            rotationTimer?.Destroy();
            Harmony.DEBUG = true;
        }
        #endregion

        #region Harmony Configuration
        private void ConfigureHarmonyLogging()
        {
            if (config.DisableHarmonyLogging)
            {
                Harmony.DEBUG = false;
                PrintWarning("INFO: Harmony verbose logging disabled globally");
            }
            else
            {
                Harmony.DEBUG = true;
                PrintWarning("INFO: Harmony verbose logging enabled globally");
            }
        }
        #endregion

        #region Log Rotation
        private void SetupLogRotation()
        {
            float intervalSeconds = 0;
            
            switch (config.RotationMode.ToLower())
            {
                case "hourly":
                    intervalSeconds = config.Hourly.RotationHours * 3600f;
                    break;
                case "size":
                    intervalSeconds = config.Size.FileSizeCheckInterval;
                    break;
                case "daily":
                default:
                    intervalSeconds = CalculateSecondsUntilDailyRotation();
                    break;
            }

            if (intervalSeconds > 0)
            {
                rotationTimer = timer.Every(intervalSeconds, () => {
                    CheckAndRotateLog();
                    
                    // For daily rotation, recalculate next interval
                    if (config.RotationMode.ToLower() == "daily")
                    {
                        rotationTimer?.Destroy();
                        SetupLogRotation();
                    }
                });
                
                if (config.RotationMode.ToLower() == "daily")
                {
                    PrintWarning($"INFO: Log rotation scheduled at {config.Daily.DailyRotationTime} daily");
                }
                else
                {
                    PrintWarning($"INFO: Log rotation scheduled every {intervalSeconds} seconds");
                }
            }
        }

        private float CalculateSecondsUntilDailyRotation()
        {
            try
            {
                var timeParts = config.Daily.DailyRotationTime.Split(':');
                int hours = int.Parse(timeParts[0]);
                int minutes = timeParts.Length > 1 ? int.Parse(timeParts[1]) : 0;
                int seconds = 0;
                
                var now = DateTime.Now;
                var targetTime = new DateTime(now.Year, now.Month, now.Day, hours, minutes, seconds);
                
                // If target time has passed today, schedule for tomorrow
                if (targetTime <= now)
                {
                    targetTime = targetTime.AddDays(1);
                }
                
                return (float)(targetTime - now).TotalSeconds;
            }
            catch
            {
                PrintWarning("INFO: Invalid daily rotation time format, using 24 hours");
                return 86400f; // Default to 24 hours
            }
        }

        private void CheckAndRotateLog()
        {
            if (!File.Exists(harmonyLogPath))
                return;

            bool shouldRotate = false;
            string reason = "";

            if (config.RotationMode.ToLower() == "size" || config.Size.MaxFileSizeMB > 0)
            {
                var fileInfo = new FileInfo(harmonyLogPath);
                if (fileInfo.Length > config.Size.MaxFileSizeMB * 1024 * 1024)
                {
                    shouldRotate = true;
                    reason = $"size ({fileInfo.Length / (1024 * 1024)}MB > {config.Size.MaxFileSizeMB}MB)";
                }
            }

            // For time-based rotation, always rotate when called
            if (config.RotationMode.ToLower() != "size")
            {
                shouldRotate = true;
                reason = $"time-based ({config.RotationMode})";
            }

            if (shouldRotate)
            {
                RotateLogFile(reason);
            }
        }

        private void RotateLogFile(string reason)
        {
            try
            {
                string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
                string backupPath = Path.Combine(config.File.StoredLogPath, $"harmony_log_{timestamp}.txt");
                
                Directory.CreateDirectory(config.File.StoredLogPath);

                File.Move(harmonyLogPath, backupPath);

                File.Create(harmonyLogPath).Close();
                
                PrintWarning($"INFO: Rotated harmony log due to {reason} -> {Path.GetFileName(backupPath)}");
                
                CleanupOldBackups();
            }
            catch (Exception ex)
            {
                PrintError($"INFO: Failed to rotate log file: {ex.Message}");
            }
        }

        private void CleanupOldBackups()
        {
            try
            {
                var logDir = new DirectoryInfo(config.File.StoredLogPath);
                var backupFiles = logDir.GetFiles("harmony_log_*.txt");
                
                if (backupFiles.Length > config.File.MaxBackupFiles)
                {
                    Array.Sort(backupFiles, (x, y) => x.CreationTime.CompareTo(y.CreationTime));
                    
                    int filesToDelete = backupFiles.Length - config.File.MaxBackupFiles;
                    for (int i = 0; i < filesToDelete; i++)
                    {
                        backupFiles[i].Delete();
                        PrintWarning($"INFO: Deleted old backup: {backupFiles[i].Name}");
                    }
                }
            }
            catch (Exception ex)
            {
                PrintError($"INFO: Failed to cleanup old backups: {ex.Message}");
            }
        }
        #endregion

        #region Commands
        [Command("harmonylog.rotate")]
        private void RotateLogCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin && !player.IsServer)
            {
                player.Reply("INFO: You need to be an admin to use this command");
                return;
            }

            RotateLogFile("manual command");
            player.Reply("INFO: Harmony log rotated manually");
        }

        [Command("harmonylog.status")]
        private void StatusCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin && !player.IsServer)
            {
                player.Reply("INFO: You need to be an admin to use this command");
                return;
            }

            string status = $"Verbose Harmony Logging: {Harmony.DEBUG}\n";
            status += $"Log Rotation: {(config.EnableLogRotation ? "Enabled" : "Disabled")}\n";
            status += $"Rotation Mode: {config.RotationMode}\n";
            status += $"Max File Size: {config.Size.MaxFileSizeMB}MB\n";
            status += $"Max Backup Files: {config.File.MaxBackupFiles}\n";
            
            if (File.Exists(harmonyLogPath))
            {
                var fileInfo = new FileInfo(harmonyLogPath);
                status += $"Current Log Size: {fileInfo.Length / (1024 * 1024)}MB\n";
                status += $"Last Modified: {fileInfo.LastWriteTime}";
            }
            else
            {
                status += "Current Log: Not found";
            }

            player.Reply(status);
        }

        [Command("harmonylog.reload")]
        private void ReloadCommand(IPlayer player, string command, string[] args)
        {
            if (!player.IsAdmin && !player.IsServer)
            {
                player.Reply("INFO: You need to be an admin to use this command");
                return;
            }

            LoadConfig();
            ConfigureHarmonyLogging();
            
            rotationTimer?.Destroy();
            if (config.EnableLogRotation)
            {
                SetupLogRotation();
            }

            player.Reply("INFO: HarmonyLogManager configuration reloaded");
        }
        #endregion
    }
}

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