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

FREE KillFeed : 1.17 1.17

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

namespace Oxide.Plugins
{
    [Info("Kill Feed", "Tuntenfisch", "1.17", ResourceId = 1433)]
    [Description("Displays a basic Kill Feed on screen!")]
    public class KillFeed : RustPlugin
    {
        #region Fields
        const float _screenAspectRatio = 9f / 16f;
        const float _height = 0.1f;
        const float _halfHeight = _height / 2f;

        static int _debugging;

        static bool useServerFileStorage;

        static char _formattingChar = '§';

        static List<string> debugLog;

        static GameObject _killFeedObject;

        static FileManager _fileManager;

        static Timer _timer;

        static Dictionary<ulong, KillFeedPlayer> _players;

        float width;
        float horizontalSpacing;
        float verticalSpacing;
        float fadeIn;
        float fadeOut;
        float destroyAfter;
        float iconHalfHeight;
        float iconHalfWidth;
        float halfWidth;

        int numberOfCharacters;
        int fontSize;

        bool outline;
        bool removeTags;
        bool removeSpecialCharacters;
        bool enableAnimals;
        bool displayPlayerDeaths;
        bool logEntries;
        bool printEntriesToConsole;
        bool[] allowedCharacters;

        string chatIcon;
        string font;
        string formatting;

        Vector2 anchormin;
        Vector2 anchormax;

        CuiElementContainer[] entries;

        List<string> entryLog;
        #endregion

        #region Hooks
        /// <summary>
        /// Effectively, the entry point for this plugin./// </summary>
        void OnServerInitialized()
        {
            // initialize _killFeedObject
            _killFeedObject = new GameObject();

            // initialize _fileManager
            _fileManager = _killFeedObject.AddComponent<FileManager>();

            // initialize _timer
            _timer = _killFeedObject.AddComponent<Timer>();

            // initialize allowedCharacters and populate initial allowedCharacters population
            allowedCharacters = new bool[65536];
            for (char c = '0'; c <= '9'; c++) allowedCharacters[c] = true;
            for (char c = 'A'; c <= 'Z'; c++) allowedCharacters[c] = true;
            for (char c = 'a'; c <= 'z'; c++) allowedCharacters[c] = true;

            LoadConfig();

            LoadDefaultLang();

            // initialize and populate _players
            _players = new Dictionary<ulong, KillFeedPlayer>();
            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                AddPlayer(player);
            }

            if (logEntries)
            {
                if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Title}/EntryLog"))
                {
                    entryLog = Interface.Oxide.DataFileSystem.ReadObject<List<string>>($"{Title}/EntryLog");        // either get existing entryLog or...}
                else
                {
                    entryLog = new List<string>();                                                                  //...create a new entryLog if no existing entryLog is found
                }
            }
            if (_debugging == 2)
            {
                if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Title}/DebugLog"))
                {
                    debugLog = Interface.Oxide.DataFileSystem.ReadObject<List<string>>($"{Title}/DebugLog");        // either get existing debugLog or...}
                else
                {
                    debugLog = new List<string>();                                                                  //...create a new debugLog if no existing debugLog is found
                }
            }
        }

        /// <summary>
        /// Makes sure that the plugin doesn't leave traces behind if the plugin is unloaded./// </summary>
        void Unload()
        {
            if (entries != null)
            {
                DestroyUI(ConvertToSingleContainer(entries));
            }

            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                RemovePlayer(player);
            }

            if (logEntries && entryLog.Count > 0)
            {
                Interface.Oxide.DataFileSystem.WriteObject($"{Title}/EntryLog", entryLog);                          // save the entryLog to EntryLog.json if necessary
            }
            if (_debugging == 2 && debugLog.Count > 0)
            {
                Interface.Oxide.DataFileSystem.WriteObject($"{Title}/DebugLog", debugLog);                          // save the debugLog to DebugLog.json if necessary
            }

            UnityEngine.Object.Destroy(_killFeedObject);
        }

        /// <summary>
        /// Adds a new player to _players if one connects./// </summary>
        /// <param name="player"> The player who connected.</param>
        void OnPlayerInit(BasePlayer player)
        {
            AddPlayer(player);
        }

        /// <summary>
        /// Removes an existing player from the _players if he disconnects./// </summary>
        /// <param name="player"> The <c>BasePlayer</c> instance which disconnected.</param>
        void OnPlayerDisconnected(BasePlayer player)
        {
            RemovePlayer(player);
        }

        /// <summary>
        /// The entry point for a new Kill Feed entry.Only encompasses players being wounded./// </summary>
        /// <remarks>
        /// If <c>displayPlayerDeaths</c> is true, player deaths will be processed by <c>OnEntityDeath(BaseCombatEntity entity, HitInfo info)</c> instead./// </remarks>
        /// <param name="player"> The player who was wounded.</param>
        /// <param name="info"> Contains information about the, in this case, wounding hit.</param>
        void CanBeWounded(BasePlayer player, HitInfo info)
        {
            if (displayPlayerDeaths) return;

            if (info == null) return;

            if (!enableAnimals && info.Initiator is BaseNpc) return;                                            // if animals are off and the initiator is an animal, return

            EntryData entryData = new EntryData(player, info);

            if (entryData.weaponInfo == null) return;

            OnWoundedOrDeath(entryData);
        }

        /// <summary>
        /// The second entry point for a new Kill Feed entry.Encompasses all entity deaths./// </summary>
        /// <param name="entity"> The entity that died.</param>
        /// <param name="info"> Contains information about the, in this case, killing hit.</param>
        void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            if (!enableAnimals && !displayPlayerDeaths) return;

            if (info == null) return;

            if (!enableAnimals && (info.Initiator is BaseNpc || entity is BaseNpc)) return;                     // if animals are off and either the initator or the entity is an animal, return
            if (!displayPlayerDeaths && entity.ToPlayer() != null) return;

            if (!(entity is BaseNpc) && !(entity is BaseHelicopter) && entity.ToPlayer() == null) return;       // if the entity isn't an animal, patrolhelicopter or player, return
            if ((info.Initiator is BaseNpc || info.Initiator is BaseHelicopter) && entity is BaseNpc) return;   // if the initator is either an animal or a patrolhelicopter and the entity is an animal, return
            if (entity is BaseNpc && (info.damageTypes?.GetMajorityDamageType() == DamageType.Hunger
                || info.damageTypes?.GetMajorityDamageType() == DamageType.Thirst)) return;                     // if an animal either died of hunger or of thirst, return

            EntryData entryData = new EntryData(entity, info);

            if (entryData.weaponInfo == null) return;

            OnWoundedOrDeath(entryData);
        }
        #endregion

        #region Commands
        /// <summary>
        /// Chat command for disabling, enabling the visual component of the plugin on a per player basis./// </summary>
        /// <param name="player"> The player who used the command.</param>
        /// <param name="command"> The command that was entered.</param>
        /// <param name="args"> List of chat arguments trailing the initial command.</param>
        [ChatCommand("killfeed")]
        void ChatCommand(BasePlayer player, string command, string[] args)
        {
            if (args.Length == 0)                                                                               // if no arguments are given, output additional information about possible arguments to the player
            {
                player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed", this));
            }
            else if (args[0].Equals("enable"))                                                                  // the player wants to enable the visual component of the plugin
            {
                KillFeedPlayer p;
                if (_players.TryGetValue(player.userID, out p))
                {
                    if (!p.enabled)
                    {
                        p.enabled = true;
                        AddUI(ConvertToSingleContainer(entries), p);

                        player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed enable > enabled", this));
                    }
                    else
                    {
                        player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed enable > already enabled", this));
                    }
                }
            }
            else if (args[0].Equals("disable"))                                                                 // the player wants to disable the visual component of the plugin
            {
                KillFeedPlayer p;
                if (_players.TryGetValue(player.userID, out p))
                {
                    if (p.enabled)
                    {
                        DestroyUI(ConvertToSingleContainer(entries), p);
                        p.enabled = false;

                        player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed disable > disabled", this));
                    }
                    else
                    {
                        player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed disable > already disabled", this));
                    }
                }
            }
            else if (args[0].Equals("status"))                                                                  // the player wants to know whether the visual component of the plugin is enabled or disabled
            {
                KillFeedPlayer p;
                if (_players.TryGetValue(player.userID, out p))
                {
                    if (p.enabled)
                    {
                        player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed status > is enabled", this));
                    }
                    else
                    {
                        player.SendConsoleCommand("chat.add", chatIcon, lang.GetMessage("killfeed status > is disabled", this));
                    }
                }
            }
        }
        #endregion

        #region Config
        /// <summary>
        /// Provides the default values for each configuration file value for easy access./// </summary>
        static class DefaultConfig
        {
            public static readonly Dictionary<string, ConfigValue> values = new Dictionary<string, ConfigValue>()
            {
                { "chatIcon",                   new ConfigValue("76561198263554080",                                                        "1.General", "1.1 chat icon") },
                { "font",                       new ConfigValue("robotocondensed-bold.ttf",                                                 "1.General", "1.2 Text", "1.2.1 font") },
                { "outline",                    new ConfigValue(false,                                                                      "1.General", "1.2 Text", "1.2.2 outline") },
                { "fontSize",                   new ConfigValue(18,                                                                         "1.General", "1.2 Text", "1.2.3 font size") },
                { "numberOfCharacters",         new ConfigValue(12,                                                                         "1.General", "1.2 Text", "1.2.4 number of characters") },
                { "removeSpecialCharacters",    new ConfigValue(true,                                                                       "1.General", "1.2 Text", "1.2.5 remove special characters") },
                { "removeTags",                 new ConfigValue(false,                                                                      "1.General", "1.2 Text", "1.2.6 remove tags") },
                { "enableAnimals",              new ConfigValue(true,                                                                       "1.General", "1.3 Eligible For Entry", "1.3.1 animals") },
                { "displayPlayerDeaths",        new ConfigValue(false,                                                                      "1.General", "1.3 Eligible For Entry", "1.3.2 player deaths") },
                { "logEntries",                 new ConfigValue(false,                                                                      "1.General", "1.4 Monitoring", "1.4.1 log entries") },
                { "printEntriesToConsole",      new ConfigValue(false,                                                                      "1.General", "1.4 Monitoring", "1.4.2 print entries to console") },
                { "debugging",                  new ConfigValue(0,                                                                          "1.General", "1.4 Monitoring", "1.4.3 debugging") },

                { "formatting",                 new ConfigValue("{initiator}§{hitBone}§{distance}§{hitEntity}",                             "2.Kill Feed", "2.1 formatting") },
                { "numberOfEntries",            new ConfigValue(3,                                                                          "2.Kill Feed", "2.2 number of entries") },
                { "destroyAfter",               new ConfigValue(30.0f,                                                                      "2.Kill Feed", "2.3 destroy after") },
                { "width",                      new ConfigValue(0.3f,                                                                       "2.Kill Feed", "2.4 Dimensions", "2.4.1 width") },
                { "iconHalfHeight",             new ConfigValue(0.35f,                                                                      "2.Kill Feed", "2.4 Dimensions", "2.4.2 icon half-height") },
                { "x",                          new ConfigValue(0.175f,                                                                     "2.Kill Feed", "2.5 Position", "2.5.1 x") },
                { "y",                          new ConfigValue(0.95f,                                                                      "2.Kill Feed", "2.5 Position", "2.5.2 y") },
                { "horizontal",                 new ConfigValue(0.0f,                                                                       "2.Kill Feed", "2.6 Spacing", "2.6.1 horizontal") },
                { "vertical",                   new ConfigValue(-0.005f,                                                                    "2.Kill Feed", "2.6 Spacing", "2.6.2 vertical") },
                { "in",                         new ConfigValue(0.0f,                                                                       "2.Kill Feed", "2.7 Fade", "2.7.1 in") },
                { "out",                        new ConfigValue(0.0f,                                                                       "2.Kill Feed", "2.7 Fade", "2.7.2 out") },
                { "initiator",                  new ConfigValue("#336699",                                                                  "2.Kill Feed", "2.8 Colors", "2.8.1 inititator") },
                { "info",                       new ConfigValue("#b38600",                                                                  "2.Kill Feed", "2.8 Colors", "2.8.2 info") },
                { "hitEntity",                  new ConfigValue("#800000",                                                                  "2.Kill Feed", "2.8 Colors", "2.8.3 hit entity") },
                { "npc",                        new ConfigValue("#267326",                                                                  "2.Kill Feed", "2.8 Colors", "2.8.4 npc") },

                { "useServerFileStorage",       new ConfigValue(true,                                                                       "3.Data", "3.1 use server file storage") },
                { "fileDirectory",              new ConfigValue("http://vignette1.wikia.nocookie.net/play-rust/images/",                    "3.Data", "3.2 file directory") },
                { "Files",                      new ConfigValue(GetDefaultFiles(),                                                          "3.Data", "3.3 Files") },
                { "DamageTypeFiles",            new ConfigValue(GetDefaultDamageTypeFiles(),                                                "3.Data", "3.4 Damagetype Files") },
                { "NPCNames",                   new ConfigValue(GetDefaultNPCNames(),                                                       "3.Data", "3.5 NPC Names") },
                { "BoneNames",                  new ConfigValue(GetDefaultBoneNames(),                                                      "3.Data", "3.6 Bone Names") },
                { "AllowedSpecialCharacters",   new ConfigValue(GetDefaultAllowedSpecialCharacters(),                                       "3.Data", "3.7 Allowed Special Characters") }
            };

            private static Dictionary<string, string> GetDefaultFiles()
            {
                Dictionary<string, string> files = new Dictionary<string, string>()
                {
                    { "autoturret", "f/f9/Auto_Turret_icon.png" },
                    { "axe.salvaged", "c/c9/Salvaged_Axe_icon.png" },
                    { "barricade.metal", "b/bb/Metal_Barricade_icon.png" },
                    { "barricade.wood", "e/e5/Wooden_Barricade_icon.png" },
                    { "barricade.woodwire", "7/7b/Barbed_Wooden_Barricade_icon.png" },
                    { "bone.club", "1/19/Bone_Club_icon.png" },
                    { "bow.hunting", "2/25/Hunting_Bow_icon.png" },
                    { "crossbow", "2/23/Crossbow_icon.png" },
                    { "explosive.satchel", "0/0b/Satchel_Charge_icon.png" },
                    { "explosive.timed", "6/6c/Timed_Explosive_Charge_icon.png" },
                    { "flamethrower", "5/55/Flame_Thrower_icon.png" },
                    { "flameturret", "f/f9/Flame_Turret_icon.png" },
                    { "gates.external.high.stone", "8/85/High_External_Stone_Gate_icon.png" },
                    { "gates.external.high.wood", "5/53/High_External_Wooden_Gate_icon.png" },
                    { "grenade.beancan", "b/be/Beancan_Grenade_icon.png" },
                    { "grenade.f1", "5/52/F1_Grenade_icon.png" },
                    { "guntrap", "http://i.imgur.com/10MOtwu.png" },
                    { "hammer.salvaged", "f/f8/Salvaged_Hammer_icon.png" },
                    { "hatchet", "0/06/Hatchet_icon.png" },
                    { "icepick.salvaged", "e/e1/Salvaged_Icepick_icon.png" },
                    { "knife.bone", "c/c7/Bone_Knife_icon.png" },
                    { "landmine", "8/83/Land_Mine_icon.png" },
                    { "lmg.m249", "c/c6/M249_icon.png" },
                    { "lock.code", "0/0c/Code_Lock_icon.png" },
                    { "longsword", "3/34/Longsword_icon.png" },
                    { "mace", "4/4d/Mace_icon.png" },
                    { "machete", "3/34/Machete_icon.png" },
                    { "pickaxe", "8/86/Pick_Axe_icon.png" },
                    { "pistol.eoka", "b/b5/Eoka_Pistol_icon.png" },
                    { "pistol.m92", "4/43/M92_Pistol_icon.png" },
                    { "pistol.python", "d/d4/Python_Revolver_icon.png" },
                    { "pistol.revolver", "5/58/Revolver_icon.png" },
                    { "pistol.semiauto", "6/6b/Semi-Automatic_Pistol_icon.png" },
                    { "rifle.ak", "d/d1/Assault_Rifle_icon.png" },
                    { "rifle.bolt", "5/55/Bolt_Action_Rifle_icon.png" },
                    { "rifle.lr300", "d/d9/LR-300_Assault_Rifle_icon.png" },
                    { "rifle.semiauto", "8/8d/Semi-Automatic_Rifle_icon.png" },
                    { "rock", "f/ff/Rock_icon.png" },
                    { "rocket.launcher", "0/06/Rocket_Launcher_icon.png" },
                    { "salvaged.cleaver", "7/7e/Salvaged_Cleaver_icon.png" },
                    { "salvaged.sword", "7/77/Salvaged_Sword_icon.png" },
                    { "shotgun.pump", "6/60/Pump_Shotgun_icon.png" },
                    { "shotgun.waterpipe", "1/1b/Waterpipe_Shotgun_icon.png" },
                    { "shotgun.double", "3/3f/Double_Barrel_Shotgun_icon.png" },
                    { "smg.2", "9/95/Custom_SMG_icon.png" },
                    { "smg.mp5", "c/c0/MP5A4_icon.png" },
                    { "smg.thompson", "4/4e/Thompson_icon.png" },
                    { "spear.stone", "0/0a/Stone_Spear_icon.png" },
                    { "spear.wooden", "f/f2/Wooden_Spear_icon.png" },
                    { "spikes.floor", "f/f7/Wooden_Floor_Spikes_icon.png" },
                    { "stone.pickaxe", "7/77/Stone_Pick_Axe_icon.png" },
                    { "stonehatchet", "9/9b/Stone_Hatchet_icon.png" },
                    { "surveycharge", "9/9a/Survey_Charge_icon.png" },
                    { "torch", "4/48/Torch_icon.png" },
                    { "trap.bear", "b/b0/Snap_Trap_icon.png" },
                    { "wall.external.high", "9/96/High_External_Wooden_Wall_icon.png" },
                    { "wall.external.high.stone", "b/b6/High_External_Stone_Wall_icon.png" }
                };
                return files;
            }

            private static Dictionary<string, string> GetDefaultDamageTypeFiles()
            {
                Dictionary<string, string> files = new Dictionary<string, string>()
                {
                    { "bite", "1/17/Bite_icon.png" },
                    { "bleeding", "e/e5/Bleeding_icon.png" },
                    { "blunt", "8/83/Blunt_icon.png" },
                    { "bullet", "5/5a/Bullet_icon.png" },
                    { "cold", "7/74/Freezing_icon.png" },
                    { "drowned", "8/81/Drowning_icon.png" },
                    { "electricShock", "a/af/Electric_icon.png" },
                    { "explosion", "5/50/Explosion_icon.png" },
                    { "fall", "f/ff/Fall_icon.png" },
                    { "generic", "b/be/Missing_icon.png" },
                    { "heat", "e/e4/Ignite_icon.png" },
                    { "hunger", "8/84/Hunger_icon.png" },
                    { "poison", "8/84/Poison_icon.png" },
                    { "radiation", "4/44/Radiation_icon.png" },
                    { "slash", "5/50/Slash_icon.png" },
                    { "stab", "3/3e/Stab_icon.png" },
                    { "suicide", "b/be/Missing_icon.png" },
                    { "thirst", "8/8e/Thirst_icon.png" }
                };
                return files;
            }

            private static Dictionary<string, string> GetDefaultNPCNames()
            {
                Dictionary<string, string> names = new Dictionary<string, string>()
                {
                    { "bear", "Bear" },
                    { "boar", "Boar" },
                    { "chicken", "Chicken" },
                    { "horse", "Horse" },
                    { "patrolhelicopter", "Helicopter" },
                    { "stag", "Stag" },
                    { "wolf", "Wolf" }
                };
                return names;
            }

            private static Dictionary<string, string> GetDefaultBoneNames()
            {
                Dictionary<string, string> names = new Dictionary<string, string>()
                {
                    { "body", "Body" },
                    { "chest", "Chest" },
                    { "groin", "Groin" },
                    { "head", "Head" },
                    { "hip", "Hip" },
                    { "jaw", "Jaw" },
                    { "left arm", "Arm" },
                    { "left eye", "Eye" },
                    { "left foot", "Foot" },
                    { "left forearm", "Forearm" },
                    { "left hand", "Hand" },
                    { "left knee", "Knee" },
                    { "left ring finger", "Finger" },
                    { "left shoulder", "Shoulder" },
                    { "left thumb", "Thumb" },
                    { "left toe", "Toe" },
                    { "left wrist", "Wrist" },
                    { "lower spine", "Spine" },
                    { "neck", "Neck" },
                    { "pelvis", "Pelvis" },
                    { "right arm", "Arm" },
                    { "right eye", "Eye" },
                    { "right foot", "Foot" },
                    { "right forearm", "Forearm" },
                    { "right hand", "Hand" },
                    { "right knee", "Knee" },
                    { "right ring finger", "Finger" },
                    { "right shoulder", "Shoulder" },
                    { "right thumb", "Thumb" },
                    { "right toe", "Toe" },
                    { "right wrist", "Wrist" },
                    { "stomach", "Stomach" }
                };
                return names;
            }

            private static List<char> GetDefaultAllowedSpecialCharacters()
            {
                List<char> characters = new List<char>
                {
                    '.',
                    ' ',
                    '[',
                    ']',
                    '(',
                    ')',
                    '<',
                    '>'
                };
                return characters;
            }
        }

        /// <summary>
        /// Wrapper for a config value./// </summary>
        /// <remarks>
        /// Contains both, the config value and the corresponding path./// </remarks>
        class ConfigValue
        {
            public object value { private set; get; }
            public string[] path { private set; get; }

            public ConfigValue(object value, params string[] path)
            {
                this.value = value;
                this.path = path;
            }
        }

        /// <summary>
        /// Responsible for getting a value from the configuration file./// </summary>
        /// <typeparam name="T"> The type that should be returned.</typeparam>
        /// <param name="saveConfig"> Indicates whether the configuration file should be saved.</param>
        /// <param name="defaultValue"> The defaultValue that will be returned if the actual value cannot be found.</param>
        /// <param name="keys"> The keys pointing to the value which should be returned.</param>
        /// <returns> Returns either the defaultValue or the value of the configuration file associated with the provided keys.</returns>
        T GetConfig<T>(ref bool saveConfig, T defaultValue, params string[] keys)
        {
            object value = Config.Get(keys);

            // get the value associated with the provided keys and check if the value is valid
            if (!IsValueValid(value, defaultValue))
            {
                object[] objArray = new object[keys.Length + 1];
                for (int i = 0; i < keys.Length; i++)
                {
                    objArray[i] = keys[i];
                }
                objArray[keys.Length] = defaultValue;

                Config.Set(objArray);

                saveConfig = true;
                return defaultValue;
            }
            return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(value));
        }

        /// <summary>
        /// Overload function for getting a value from the configuration file./// </summary>
        /// <typeparam name="T"> The type that should be returned.</typeparam>
        /// <param name="saveConfig"> Indicates whether the configuration file should be saved.</param>
        /// <param name="configValue"> Holds information both about the actual config value and the corresponding path.</param>
        /// <returns> Returns either the defaultValue or the value of the configuration file associated with the provided keys.</returns>
        T GetConfig<T>(ref bool saveConfig, ConfigValue configValue)
        {
            string[] keys = configValue.path;
            object defaultValue = configValue.value;

            return GetConfig(ref saveConfig, (T)defaultValue, keys);
        }

        /// <summary>
        /// Checks if a value is valid by comparing the types of two objects and checking if both objects are of the same type or not./// </summary>
        /// <param name="value"> The value that needs to be checked for validity.</param>
        /// <param name="defaultValue"> The defaultValue which is used for checking if the value is valid.</param>
        /// <returns> A bool indicating whether the value is valid.</returns>
        bool IsValueValid(object value, object defaultValue)
        {
            if (value == null) return false;

            Type type = value.GetType();
            Type defaultType = defaultValue.GetType();

            if (type != defaultType && type != typeof(double) && defaultType != typeof(float))
            {
                if (type.IsGenericType && defaultType.IsGenericType)
                {
                    if (type.GetGenericTypeDefinition() != defaultType.GetGenericTypeDefinition())
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Checks whether the configuration file contains unused keys and removes them./// </summary>
        void CleanupConfig()
        {
            List<string[]> paths = new List<string[]>();

            // iterate over the current configuration file to find all existing paths
            IEnumerator enumerator = Config.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    KeyValuePair<string, object> pair = (KeyValuePair<string, object>)enumerator.Current;

                    if (pair.Value.GetType().IsGenericType && pair.Value.GetType().GetGenericTypeDefinition() == typeof(Dictionary<,>) && ((IDictionary)pair.Value).Count != 0)
                    {
                        Dictionary<string, object> dictionary = new Dictionary<string, object>();
                        foreach (DictionaryEntry entry in (IDictionary)pair.Value)
                        {
                            dictionary.Add((string)entry.Key, entry.Value);
                        }

                        foreach (KeyValuePair<string, object> pair2 in dictionary)
                        {
                            if (pair2.Value.GetType().IsGenericType && pair2.Value.GetType().GetGenericTypeDefinition() == typeof(Dictionary<,>) && ((IDictionary)pair.Value).Count != 0)
                            {
                                Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
                                foreach (DictionaryEntry entry in (IDictionary)pair2.Value)
                                {
                                    dictionary2.Add((string)entry.Key, entry.Value);
                                }

                                foreach (KeyValuePair<string, object> pair3 in dictionary2)
                                {
                                    if (char.IsDigit(pair3.Key[0]) && pair3.Key[1].Equals('.') && char.IsDigit(pair3.Key[2]) && pair3.Key[3].Equals('.') && char.IsDigit(pair3.Key[4]))
                                    {
                                        paths.Add(new string[3] { pair.Key, pair2.Key, pair3.Key });
                                    }
                                    else
                                    {
                                        paths.Add(new string[2] { pair.Key, pair2.Key });
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                paths.Add(new string[2] { pair.Key, pair2.Key });
                            }
                        }
                    }
                    else
                    {
                        paths.Add(new string[1] { pair.Key });
                    }
                }
            }
            finally
            {
                ((IDisposable)enumerator).Dispose();
            }

            // iterate over the found paths and determine whether they are part of the default configuration
            foreach (string[] path in paths)
            {
                int index = -1;

                foreach (ConfigValue value in DefaultConfig.values.Values)
                {
                    if (path.Length != value.path.Length) continue;

                    for (int j = 0; j < path.Length; j++)
                    {
                        if (path[j].Equals(value.path[j]))
                        {
                            index = j > index ? j : index;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                // if a path is not part of the default configuration remove it
                if (index < path.Length - 1)
                {
                    if (index == -1)
                    {
                        Config.Remove(path[index + 1]);
                    }
                    else
                    {
                        string[] strArray = new string[index + 1];
                        for (int j = 0; j < strArray.Length; j++)
                        {
                            strArray[j] = path[j];
                        }
                        ((Dictionary<string, object>)Config.Get(strArray)).Remove(path[index + 1]);
                    }
                }
            }
        }

        /// <summary>
        /// Responsible for creating a configuration file and populating it with the required default values./// </summary>
        /// <remarks>
        /// This function is called automatically by oxide if no configuration file could be found./// </remarks>
        protected override void LoadDefaultConfig()
        {
            PrintWarning("Creating configuration file!");

            Config.Clear();

            foreach (ConfigValue value in DefaultConfig.values.Values)
            {
                object[] objArray = new object[value.path.Length + 1];
                for (int i = 0; i < value.path.Length; i++)
                {
                    objArray[i] = value.path[i];
                }
                objArray[value.path.Length] = value.value;

                Config.Set(objArray);
            }
            SaveConfig();
        }

        /// <summary>
        /// Responsible for loading the configuration file./// </summary>
        new void LoadConfig()
        {
            Puts("Loading configuration file!");

            bool saveConfig = false;

            // 1.General
            chatIcon = GetConfig<string>(ref saveConfig, DefaultConfig.values["chatIcon"]);
            font = GetConfig<string>(ref saveConfig, DefaultConfig.values["font"]);
            outline = GetConfig<bool>(ref saveConfig, DefaultConfig.values["outline"]);
            fontSize = GetConfig<int>(ref saveConfig, DefaultConfig.values["fontSize"]);
            numberOfCharacters = GetConfig<int>(ref saveConfig, DefaultConfig.values["numberOfCharacters"]);
            removeSpecialCharacters = GetConfig<bool>(ref saveConfig, DefaultConfig.values["removeSpecialCharacters"]);
            removeTags = GetConfig<bool>(ref saveConfig, DefaultConfig.values["removeTags"]);
            enableAnimals = GetConfig<bool>(ref saveConfig, DefaultConfig.values["enableAnimals"]);
            displayPlayerDeaths = GetConfig<bool>(ref saveConfig, DefaultConfig.values["displayPlayerDeaths"]);
            logEntries = GetConfig<bool>(ref saveConfig, DefaultConfig.values["logEntries"]);
            printEntriesToConsole = GetConfig<bool>(ref saveConfig, DefaultConfig.values["printEntriesToConsole"]);
            _debugging = GetConfig<int>(ref saveConfig, DefaultConfig.values["debugging"]);

            // 2.Kill Feed
            formatting = GetConfig<string>(ref saveConfig, DefaultConfig.values["formatting"]);

            int numberOfEntries = GetConfig<int>(ref saveConfig, DefaultConfig.values["numberOfEntries"]);
            entries = new CuiElementContainer[numberOfEntries];

            width = GetConfig<float>(ref saveConfig, DefaultConfig.values["width"]);
            halfWidth = width / 2f;

            iconHalfHeight = GetConfig<float>(ref saveConfig, DefaultConfig.values["iconHalfHeight"]);
            iconHalfWidth = iconHalfHeight * _screenAspectRatio / (width / _height);

            destroyAfter = GetConfig<float>(ref saveConfig, DefaultConfig.values["destroyAfter"]);

            float x = GetConfig<float>(ref saveConfig, DefaultConfig.values["x"]);
            float y = GetConfig<float>(ref saveConfig, DefaultConfig.values["y"]);
            anchormin = new Vector2(x - halfWidth, y - _halfHeight);
            anchormax = new Vector2(x + halfWidth, y + _halfHeight);

            float xSpacing = GetConfig<float>(ref saveConfig, DefaultConfig.values["horizontal"]);
            if (xSpacing != 0.0f)
            {
                bool positive = xSpacing > 0.0f;
                horizontalSpacing = positive ? xSpacing + halfWidth : xSpacing - halfWidth;
            }
            else
            {
                horizontalSpacing = xSpacing;
            }

            float ySpacing = GetConfig<float>(ref saveConfig, DefaultConfig.values["vertical"]);
            if (ySpacing != 0.0f)
            {
                bool positive = ySpacing > 0.0f;
                verticalSpacing = positive ? ySpacing + _halfHeight : ySpacing - _halfHeight;
            }
            else
            {
                verticalSpacing = ySpacing;
            }

            fadeIn = GetConfig<float>(ref saveConfig, DefaultConfig.values["in"]);
            fadeOut = GetConfig<float>(ref saveConfig, DefaultConfig.values["out"]);
            EntryData._initiatorColor = GetConfig<string>(ref saveConfig, DefaultConfig.values["initiator"]);
            EntryData._infoColor = GetConfig<string>(ref saveConfig, DefaultConfig.values["info"]);
            EntryData._hitEntityColor = GetConfig<string>(ref saveConfig, DefaultConfig.values["hitEntity"]);
            EntryData._npcColor = GetConfig<string>(ref saveConfig, DefaultConfig.values["npc"]);

            // 3.Data
            useServerFileStorage = GetConfig<bool>(ref saveConfig, DefaultConfig.values["useServerFileStorage"]);

            FileManager.fileDirectory = GetConfig<string>(ref saveConfig, DefaultConfig.values["fileDirectory"]);

            FileManager.fileIDs.Clear();
            FileManager.Store(GetConfig<Dictionary<string, string>>(ref saveConfig, DefaultConfig.values["Files"]));
            FileManager.Store(GetConfig<Dictionary<string, string>>(ref saveConfig, DefaultConfig.values["DamageTypeFiles"]));

            EntryData._npcNames.Clear();
            EntryData._npcNames = GetConfig<Dictionary<string, string>>(ref saveConfig, DefaultConfig.values["NPCNames"]);

            EntryData._boneNames.Clear();
            EntryData._boneNames = GetConfig<Dictionary<string, string>>(ref saveConfig, DefaultConfig.values["BoneNames"]);

            foreach (char c in GetConfig<List<char>>(ref saveConfig, DefaultConfig.values["AllowedSpecialCharacters"]))
            {
                if (c == _formattingChar) continue;
                allowedCharacters[c] = true;
            }

            if (saveConfig)
            {
                CleanupConfig();

                PrintWarning("Updating configuration file!");

                SaveConfig();
            }
        }
        #endregion

        #region Lang
        /// <summary>
        /// Provides the default values for each language file value for easy access./// </summary>
        static class DefaultLangValues
        {
            public static Dictionary<string, string> GetDefaultMessages()
            {
                Dictionary<string, string> messages = new Dictionary<string, string>()
                {
                    { "killfeed", "<color=red>[KillFeed]</color> /killfeed disable<color=red>|</color>enable<color=red>|</color>status" },
                    { "killfeed enable > enabled", "<color=red>[KillFeed]</color> enabled!" },
                    { "killfeed enable > already enabled", "<color=red>[KillFeed]</color> already enabled!" },
                    { "killfeed disable > disabled", "<color=red>[KillFeed]</color> disabled!" },
                    { "killfeed disable > already disabled", "<color=red>[KillFeed]</color> already disabled!" },
                    { "killfeed status > is enabled", "<color=red>[KillFeed]</color> is enabled!" },
                    { "killfeed status > is disabled", "<color=red>[KillFeed]</color> is disabled!" },
                };
                return messages;
            }
        }

        /// <summary>
        /// Responsible for creating a language file and populating it with the required default values./// </summary>
        void LoadDefaultLang()
        {
            lang.RegisterMessages(DefaultLangValues.GetDefaultMessages(), this);
        }
        #endregion

        #region Helper
        /// <summary>
        /// Set of helper functions for modifying strings./// </summary>
        static class StringHelper
        {
            /// <summary>
            /// Removes a tag infront of a string./// </summary>
            /// <param name="str"> The string that contains the tag.</param>
            /// <returns> The string without the tag.</returns>
            public static string RemoveTag(string str)
            {
                if (str.StartsWith("[") && str.Contains("]") && str.Length > str.IndexOf("]"))
                {
                    str = str.Substring(str.IndexOf("]") + 1).Trim();
                }
                return str;
            }

            /// <summary>
            /// Removes special characters from a string./// </summary>
            /// <param name="str"> The string that should be modified.</param>
            /// <param name="allowedCharacters"> The characters that are allowed.</param>
            /// /// <param name="flag"> The flag indicates whether the characters provided are allowed characters (false) or banned characters (true).</param>
            /// <returns> The string with all non allowed characters removed.</returns>
            public static string RemoveSpecialCharacters(string str, bool[] characters, bool flag = false)
            {
                char[] buffer = new char[str.Length];
                int index = 0;
                foreach (char c in str)
                {
                    if (characters[c] ^ flag)
                    {
                        buffer[index] = c;
                        index++;
                    }
                }
                return new string(buffer, 0, index);
            }

            /// <summary>
            /// Trims a string to a defined size if the string is longer./// </summary>
            /// <param name="str"> the string that should be trimmed.</param>
            /// <param name="size"> the maximum size of the string.</param>
            /// <returns> The string trimmed to the defined size.</returns>
            public static string TrimToSize(string str, int size)
            {
                if (str.Length > size)
                {
                    str = str.Substring(0, size);
                }
                return str;
            }
        }

        /// <summary>
        /// Wrapper for logging debug messages./// </summary>
        /// <param name="args"> The debug messages which should be logged.</param>
        static void LogDebug(params string[] args)
        {
            if (_debugging != 1 && _debugging != 2) return;

            StringBuilder builder = new StringBuilder("{1}");
            for (int i = 0; i < args.Length; i++)
            {
                builder.Append(" ");
                builder.Append("{" + i + "}");
            }

            if (_debugging == 1)
            {
                Interface.Oxide.LogDebug(builder.ToString(), args);
            }
            else if (_debugging == 2)
            {
                debugLog.Add(string.Format(builder.ToString(), args));
            }
        }
        #endregion

        #region FileManager
        /// <summary>
        /// Responsible for storing the png files in the server's file storage and keeping track of them./// </summary>
        class FileManager : MonoBehaviour
        {
            public static string fileDirectory;

            public static Dictionary<string, string> fileIDs = new Dictionary<string, string>();

            /// <summary>
            /// Stores a value inside the server's file storage./// </summary>
            /// <param name="key"> The key that is used to keep track of the value.</param>
            /// <param name="value"> The value containing the url to the png file.</param>
            public static void Store(string key, string value)
            {
                StringBuilder url = new StringBuilder();
                if (value.StartsWith("file:///") || value.StartsWith("http://"))
                {
                    url.Append(value);
                }
                else
                {
                    url.Append(fileDirectory);
                    url.Append(value);
                }

                if (useServerFileStorage)
                {
                    _fileManager.StartCoroutine(WaitForRequest(key, url.ToString()));
                }
                else
                {
                    fileIDs[key] = url.ToString();
                }
            }

            /// <summary>
            /// Stores a list of value inside the server's file storage./// </summary>
            /// <param name="files"> The list of values that should be stored.The list of keys is used to keep track of the values.</param>
            public static void Store(Dictionary<string, string> files)
            {
                foreach (KeyValuePair<string, string> pair in files)
                {
                    Store(pair.Key, pair.Value);
                }
            }

            /// <summary>
            /// Coroutine that waits for the url data to be loaded and stores it once it is loaded./// </summary>
            /// <param name="shortname"> The shortname of a given item.</param>
            /// <param name="url"> The url that points to the data that should be stored.</param>
         
// ... [Code preview truncated due to length. Full source in attached file] ...

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