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

FREE PerformanceMonitor : 1.2.5 1.2.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

// TODO: Make this plugin actually useful.namespace Oxide.Plugins
{
    [Info("Performance Monitor", "Orange", "1.2.5")]
    [Description("Tool for collecting information about server performance")]
    public class PerformanceMonitor : RustPlugin
    {
        #region Vars

        private const string commandString = "monitor.createreport";
        private const string commandString2 = "monitor.report";
        private PerformanceDump currentReport;

        #endregion

        #region Oxide Hooks

        private void Init()
        {

            cmd.AddConsoleCommand(commandString, this, nameof(cmdCompleteNow));
            cmd.AddConsoleCommand(commandString2, this, nameof(cmdCompleteNow));
        }

        private void OnServerInitialized()
        {
            if (config.checkTime > 0)
            {
                timer.Every(config.checkTime, CreateReport);
            }
        }

        #endregion

        #region Commands

        private void cmdCompleteNow(ConsoleSystem.Arg arg)
        {
            if (arg.IsAdmin == false)
            {
                return;
            }

            CreateReport();
        }

        #endregion

        #region Core

        private void CreateReport()
        {
            ServerMgr.Instance.StartCoroutine(CreateActualReport());
        }

        private IEnumerator CreateActualReport()
        {
            if (currentReport != null)
            {
                yield break;
            }
            else
            {
                currentReport = new PerformanceDump();
            }

            var sw = new Stopwatch();
            sw.Start();

            CompletePluginsReport();
            ServerMgr.Instance.StartCoroutine(CompleteEntitiesReport());

            while (!currentReport.entities.completed && config.runEntitiesReport)
            {
                Puts($"Report status: {currentReport.statusBar}% [{currentReport.entitiesChecked}/{currentReport.entitiesTotal}]");
                yield return new WaitForEndOfFrame();
            }

            if (!config.runPluginsReportAverage)
            {
                SaveReport(currentReport);
                currentReport = null;
                sw.Stop();
                Puts($"Performance report was completed in {sw.Elapsed.Seconds + (sw.Elapsed.Milliseconds / 1000.0)} seconds.");
            }
            else
            {
                timer.Once(32 * 3, () =>
                {
                    SaveReport(currentReport);
                    currentReport = null;
                    sw.Stop();
                    Puts($"Performance report was completed in {sw.Elapsed.Seconds + (32 * 3) + (sw.Elapsed.Milliseconds / 1000.0)} seconds.");
                });
            }
        }
        
        private void CompletePluginsReport()
        {
            var list = new List<string>();

            if (config.runPluginsReport == false)
            {
                return;
            }
            // Make this use time as the determining factor, Do so by creating a new variable called 'pastTime'
            // This holds the last called time, if its larger, it puts it below that, otherwise above
            double pastTime = 0.0;
            foreach (var plugin in plugins.GetAll().OrderByDescending(x => x.TotalHookTime))
            {
                var name = plugin.Name;
                if (name == Name || plugin.IsCorePlugin || config.excludedPlugins.Contains(name))
                {
                    continue;
                }

                var version = plugin.Version;
                double time = plugin.TotalHookTime;
                var info = $"{name} ({version}), Total Hook Time = {time}";
                if(pastTime != 0.0 && pastTime> time){
                    list.Add(info);
                }else{
                    if(list.Count>2){
                        list.Insert(list.Count-2, info);
                    }else if(list.Count>1){
                        list.Insert(list.Count-1, info);
                    }else{
                        list.Add(info);
                    }
                }
                pastTime = time;
            }
            currentReport.plugins = list.ToArray();
            
            
            // Average Load Time for Plugins:
            if (!config.runPluginsReportAverage) return;
            var averageTime = new Dictionary<string, List<double>>();
            Puts($"Checking Average Time: Please Wait...");
            timer.Repeat(30f, 3, () =>
            {
                Puts($"Checking Average Time: Please Wait...");
                foreach (var plugin in plugins.GetAll().OrderByDescending(x => x.TotalHookTime))
                {
                    var name = plugin.Name;
                    if (name == Name || plugin.IsCorePlugin || config.excludedPlugins.Contains(name))
                    {
                        continue;
                    }
                    double time = plugin.TotalHookTime;
                    List<double> averageList;
                    if (!averageTime.TryGetValue(plugin.Name, out averageList))
                    {
                        averageList = new List<double>();
                    }
                    // Change into a list of strings just like the one above, but just with the average of it instead.Done by waiting until
                    // length is equal to the number of repeats.Then set info = $"{name} ({version}), Total Hook Time = {time}"; and time is
                    // equal to the average of the 3.averageList.Add(time);
                    averageTime[plugin.Name] = averageList;
                    pastTime = time;
                }
            });
            currentReport.pluginsAverage = averageTime;
        }

        private IEnumerator CompleteEntitiesReport()
        {
            if (config.runEntitiesReport == false)
            {
                yield break;
            }
            var entities = UnityEngine.Object.FindObjectsOfType<BaseEntity>();
            var entitiesByShortname = currentReport.entities.list;
            currentReport.entitiesTotal = entities.Length;

            for (var i = 0; i < entities.Length; i++)
            {
                currentReport.entitiesChecked++;
                currentReport.statusBar = Convert.ToInt32(i * 100 / entities.Length);

                var entity = entities[i];
                if (entity.IsValid() == false)
                {
                    continue;
                }

                var shortname = entity.ShortPrefabName;
                if (config.excludedEntities.Contains(shortname) == true)
                {
                    continue;
                }

                var info = (EntityInfo) null;
                if (entitiesByShortname.TryGetValue(shortname, out info) == false)
                {
                    info = new EntityInfo();
                    entitiesByShortname.Add(shortname, info);
                }


                if (entity.OwnerID == 0)
                {
                    info.countUnowned++;
                    currentReport.entities.countUnowned++;
                }
                else
                {
                    info.countOwned++;
                    currentReport.entities.countOwned++;
                }

                info.countGlobal++;
                currentReport.entities.countGlobal++;
            }

            currentReport.entities.list = currentReport.entities.list.OrderByDescending(x => x.Value.countGlobal).ToDictionary(x => x.Key, y => y.Value);

            currentReport.entities.completed = true;
        }

        #endregion

        #region Utils
        
        private void SaveReport(PerformanceDump dump)
        {
            string name1 = "";
            if(config.EuropeanTimeSave) name1 = DateTime.Now.ToString("dd/MM/yyyy").Replace("/", "-");
            else name1 = DateTime.Now.ToString("MM/dd/yyyy").Replace("/", "-");
            string name2 = DateTime.Now.ToString(Time()).Replace(':', '-');
            string filename = $"PerformanceMonitor/Reports/{name1}/{name2}";
            Interface.Oxide.DataFileSystem.WriteObject(filename, dump);
        }

        private string Time()
        {
            return DateTime.Now.ToString("HH:mm:ss");
        }

        #endregion
        
        #region Configuration | 2.0.0

        private static ConfigData config = new ConfigData();

        private class ConfigData
        {
            [JsonProperty(PropertyName = "Save file dates in European Format 27-06-2023 (other format is North American 06-27-2023)")]
            public bool EuropeanTimeSave = false;
            
            [JsonProperty(PropertyName = "Create reports every (seconds)")]
            public int checkTime = 0;

            [JsonProperty(PropertyName = "Create plugins report")]
            public bool runPluginsReport = true;
            
            [JsonProperty(PropertyName = "Create plugins average hook-time report (Will substantially increase time of report)")]
            public bool runPluginsReportAverage = false;

            [JsonProperty(PropertyName = "Create entities report")]
            public bool runEntitiesReport = true;

            [JsonProperty(PropertyName = "Excluded entities")]
            public string[] excludedEntities =
            {
                "shortname here",
                "another here"
            };

            [JsonProperty(PropertyName = "Excluded plugins")]
            public string[] excludedPlugins =
            {
                "name here",
                "another name"
            };
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();

            try
            {
                config = Config.ReadObject<ConfigData>();

                if (config == null)
                {
                    LoadDefaultConfig();
                }
            }
            catch
            {
                PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");

                timer.Every(10f,
                    () =>
                    {
                        PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
                    });
                LoadDefaultConfig();
                return;
            }

            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            config = new ConfigData();
        }

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

        #endregion

        #region Classes

        private class PerformanceDump
        {
            [JsonProperty(PropertyName = "Online players")]
            public int onlinePlayers = BasePlayer.activePlayerList.Count;

            [JsonProperty(PropertyName = "Offline players")]
            public int offlinePlayers = BasePlayer.sleepingPlayerList.Count;

            [JsonProperty(PropertyName = "Entities report")]
            public EntitiesReport entities = new EntitiesReport();
            
            [JsonProperty(PropertyName = "Plugins report")]
            public string[] plugins;

            [JsonProperty(PropertyName = "Plugins Average")]
            public Dictionary<string, List<double>> pluginsAverage;

            [JsonProperty(PropertyName = "Performance report")]
            public Performance.Tick performance = Performance.current;
            
            [JsonIgnore] 
            public int statusBar;

            [JsonIgnore] 
            public int entitiesChecked;

            [JsonIgnore]
            public int entitiesTotal;
        }

        private class EntitiesReport
        {
            [JsonProperty(PropertyName = "Total")]
            public int countGlobal;
            
            [JsonProperty(PropertyName = "Owned")]
            public int countOwned;
            
            [JsonProperty(PropertyName = "Unowned")]
            public int countUnowned;
            
            [JsonProperty(PropertyName = "List")]
            public Dictionary<string, EntityInfo> list = new Dictionary<string, EntityInfo>();

            [JsonIgnore] 
            public bool completed;
        }

        private class EntityInfo
        {
            [JsonProperty(PropertyName = "Total")]
            public int countGlobal;
            
            [JsonProperty(PropertyName = "Owned")]
            public int countOwned;
            
            [JsonProperty(PropertyName = "Unowned")]
            public int countUnowned;
        }

        #endregion
    }
}

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