diff --git a/BadgeSystem/Badge.cs b/BadgeSystem/Badge.cs new file mode 100644 index 0000000..f84d9b1 --- /dev/null +++ b/BadgeSystem/Badge.cs @@ -0,0 +1,137 @@ +using EasyTools.Configs; +using EasyTools.Events; +using GameCore; +using LabApi.Features.Wrappers; +using MEC; +using NewXp.IniApi; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Log = LabApi.Features.Console.Logger; + +namespace EasyTools.BadgeSystem +{ + public class Badge + { + public static string[] FMoreColo = new string[] + { + "pink", + "silver", + "cyan", + "aqua", + "tomato", + "yellow", + "magenta", + "orange", + "lime", + "green", + "red", + "brown", + "red", + "orange", + "yellow", + "green", + "blue_green", + "magenta", + "pink", + "brown", + "silver", + "light_green", + "crimson", + "cyan", + "aqua", + "deep_pink", + "tomato", + "blue_green", + "lime", + "emerald", + "carmine", + "nickel", + "mint", + "army_green", + "pumpkin" + }; + + public static List rainbw = new List(); + + public static IEnumerator Rainbw() + { + while (true) + { + foreach (var item in rainbw) + { + item.GroupColor = FMoreColo.RandomItem(); + } + yield return Timing.WaitForSeconds(CustomEventHandler.BadgeConfig.each); + } + + } + + public static void Handler(Player player) + { + string filePath = Path.Combine(CustomEventHandler.BadgeConfig.Pach, player.UserId + ".ini"); + + if (!File.Exists(filePath)) + { + IniFile iniFile = new IniFile(); + iniFile.Section("DIR").Set("称号", "空", "称号"); + iniFile.Section("DIR").Set("称号颜色", "空"); + iniFile.Section("DIR").Set("管理权限组", "空"); + iniFile.Save(filePath); + } + else + { + + IniFile iniFile = new IniFile(filePath); + iniFile.Save(filePath); + if (iniFile.Section("DIR").Get("管理权限组") == "空") + { + if (iniFile.Section("DIR").Get("称号") != "空") + { + player.GroupName = iniFile.Section("DIR").Get("称号"); + switch (iniFile.Section("DIR").Get("称号颜色")) + { + case "rainbow": + rainbw.Add(player); + break; + default: + player.GroupColor = iniFile.Section("DIR").Get("称号颜色"); + break; + } + } + + } + else + { + Server.RunCommand($"/setgroup {player.PlayerId} {iniFile.Section("DIR").Get("管理权限组")}"); + Log.Info($"已经给予{player.Nickname}-{player.UserId}==={iniFile.Section("DIR").Get("管理权限组")}权限"); + if (iniFile.Section("DIR").Get("称号") != "空") + { + player.GroupName = iniFile.Section("DIR").Get("称号"); + switch (iniFile.Section("DIR").Get("称号颜色")) + { + case "rainbow": + rainbw.Add(player); + break; + default: + player.GroupColor = iniFile.Section("DIR").Get("称号颜色"); + break; + } + } + } + } + } + + public static void Remove(Player player) + { + if (Badge.rainbw.Contains(player)) + { + Badge.rainbw.Remove(player); + } + } + + } +} diff --git a/Configs/BadgeConfig.cs b/Configs/BadgeConfig.cs new file mode 100644 index 0000000..d1287d4 --- /dev/null +++ b/Configs/BadgeConfig.cs @@ -0,0 +1,20 @@ +using LabApi.Features.Wrappers; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EasyTools.Configs +{ + public class BadgeConfig + { + [Description("是否启用称号系统")] + public bool Enable { get; set; } = true; + [Description("存储路径")] + public string Pach { get; set; } = "/home/shiroko/.config/DIRSave"; + [Description("彩色称号更新频率")] + public int each { get; set; } = 1; + } +} diff --git a/EasyTools.csproj b/EasyTools.csproj index a71817f..16be4a6 100644 --- a/EasyTools.csproj +++ b/EasyTools.csproj @@ -115,16 +115,19 @@ + + + diff --git a/Plugins.cs b/Plugins.cs index 3a8df1c..1423061 100644 --- a/Plugins.cs +++ b/Plugins.cs @@ -1,11 +1,14 @@ using EasyTools.Configs; using EasyTools.Events; using LabApi.Events.CustomHandlers; +using LabApi.Events.Handlers; using LabApi.Features; +using LabApi.Features.Wrappers; using LabApi.Loader; using LabApi.Loader.Features.Plugins; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -14,15 +17,19 @@ namespace EasyTools { public class Plugins : Plugin { - public CustomEventHandler Events { get; } = new(); - public override void LoadConfigs() { base.LoadConfigs(); CustomEventHandler.Config = this.LoadConfig("config.yml"); CustomEventHandler.TranslateConfig = this.LoadConfig("translateConfig.yml"); + CustomEventHandler.BadgeConfig = this.LoadConfig("badgeConfig.yml"); + + if (!Directory.Exists(CustomEventHandler.BadgeConfig.Pach)) + { + Directory.CreateDirectory(CustomEventHandler.BadgeConfig.Pach); + } } diff --git a/Utils/Ini.cs b/Utils/Ini.cs new file mode 100644 index 0000000..1cf4854 --- /dev/null +++ b/Utils/Ini.cs @@ -0,0 +1,300 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewXp.IniApi +{ + /// + /// Represents a property in an INI file. + /// + public class IniProperty + { + /// + /// Property name (key). + /// + public string Name { get; set; } + + /// + /// Property value. + /// + public string Value { get; set; } + + /// + /// Set the comment to display above this property. + /// + public string Comment { get; set; } + } + + /// + /// Represents a section in an INI file. + /// + public class IniSection + { + private readonly IDictionary _properties; + + /// + /// Section name. + /// + public string Name { get; set; } + + /// + /// Set the comment to display above this section. + /// + public string Comment { get; set; } + + /// + /// Get the properties in this section. + /// + public IniProperty[] Properties => _properties.Values.ToArray(); + + /// + /// Create a new IniSection. + /// + /// + public IniSection(string name) + { + Name = name; + _properties = new Dictionary(); + } + + /// + /// Get a property value. + /// + /// Name of the property. + /// Value of the property or null if it doesn't exist. + public string Get(string name) + { + if (_properties.ContainsKey(name)) + return _properties[name].Value; + + return null; + } + + /// + /// Get a property value, coercing the type of the value + /// into the type given by the generic parameter. + /// + /// Name of the property. + /// The type to coerce the value into. + /// + public T Get(string name) + { + if (_properties.ContainsKey(name)) + return (T)Convert.ChangeType(_properties[name].Value, typeof(T)); + + return default(T); + } + + /// + /// Set a property value. + /// + /// Name of the property. + /// Value of the property. + /// A comment to display above the property. + public void Set(string name, string value, string comment = null) + { + if (string.IsNullOrWhiteSpace(value)) + { + RemoveProperty(name); + return; + } + + if (!_properties.ContainsKey(name)) + _properties.Add(name, new IniProperty { Name = name, Value = value, Comment = comment }); + else + { + _properties[name].Value = value; + if (comment != null) + _properties[name].Comment = comment; + } + } + + /// + /// Remove a property from this section. + /// + /// The property name to remove. + public void RemoveProperty(string propertyName) + { + if (_properties.ContainsKey(propertyName)) + _properties.Remove(propertyName); + } + } + + /// + /// Represenst an INI file that can be read from or written to. + /// + public class IniFile + { + private readonly IDictionary _sections; + + /// + /// If True, writes extra spacing between the property name and the property value. + /// (foo=bar) vs (foo = bar) + /// + public bool WriteSpacingBetweenNameAndValue { get; set; } + + /// + /// The character a comment line will begin with. Default '#'. + /// + public char CommentChar { get; set; } + + /// + /// Get the sections in this IniFile. + /// + public IniSection[] Sections => _sections.Values.ToArray(); + + /// + /// Create a new IniFile instance. + /// + public IniFile() + { + _sections = new Dictionary(); + CommentChar = '#'; + } + + /// + /// Load an INI file from the file system. + /// + /// Path to the INI file. + public IniFile(string path) : this() + { + Load(path); + } + + /// + /// Load an INI file. + /// + /// A TextReader instance. + public IniFile(TextReader reader) : this() + { + Load(reader); + } + + private void Load(string path) + { + using (var file = new StreamReader(path)) + Load(file); + } + + private void Load(TextReader reader) + { + IniSection section = null; + + string line; + while ((line = reader.ReadLine()) != null) + { + line = line.Trim(); + + // skip empty lines + if (line == string.Empty) + continue; + + // skip comments + if (line.StartsWith(";") || line.StartsWith("#")) + continue; + + if (line.StartsWith("[") && line.EndsWith("]")) + { + var sectionName = line.Substring(1, line.Length - 2); + if (!_sections.ContainsKey(sectionName)) + { + section = new IniSection(sectionName); + _sections.Add(sectionName, section); + } + continue; + } + + if (section != null) + { + var keyValue = line.Split(new[] { "=" }, 2, StringSplitOptions.RemoveEmptyEntries); + if (keyValue.Length != 2) + continue; + + section.Set(keyValue[0].Trim(), keyValue[1].Trim()); + } + } + } + + /// + /// Get a section by name. If the section doesn't exist, it is created. + /// + /// The name of the section. + /// A section. If the section doesn't exist, it is created. + public IniSection Section(string sectionName) + { + IniSection section; + if (!_sections.TryGetValue(sectionName, out section)) + { + section = new IniSection(sectionName); + _sections.Add(sectionName, section); + } + + return section; + } + + /// + /// Remove a section. + /// + /// Name of the section to remove. + public void RemoveSection(string sectionName) + { + if (_sections.ContainsKey(sectionName)) + _sections.Remove(sectionName); + } + + /// + /// Create a new INI file. + /// + /// Path to the INI file to create. + public void Save(string path) + { + using (var file = new StreamWriter(path)) + Save(file); + } + + /// + /// Create a new INI file. + /// + /// A TextWriter instance. + public void Save(TextWriter writer) + { + foreach (var section in _sections.Values) + { + if (section.Properties.Length == 0) + continue; + + if (section.Comment != null) + writer.WriteLine($"{CommentChar} {section.Comment}"); + + writer.WriteLine($"[{section.Name}]"); + + foreach (var property in section.Properties) + { + if (property.Comment != null) + writer.WriteLine($"{CommentChar} {property.Comment}"); + + var format = WriteSpacingBetweenNameAndValue ? "{0} = {1}" : "{0}={1}"; + writer.WriteLine(format, property.Name, property.Value); + } + + writer.WriteLine(); + } + } + + /// + /// Returns the content of this INI file as a string. + /// + /// The text content of this INI file. + public override string ToString() + { + using (var sw = new StringWriter()) + { + Save(sw); + return sw.ToString(); + } + } + } +}