Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EnumUtils v1.0.5
LCEnumUtils.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MegaPiggy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2023 MegaPiggy")] [assembly: AssemblyDescription("Lethal Company library for dynamically creating and getting Enums.")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5+0dea91ec0e6ee8c69fe9441a589fda69963c77e6")] [assembly: AssemblyProduct("LCEnumUtils")] [assembly: AssemblyTitle("LCEnumUtils")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MegaPiggy/LethalCompanyEnumUtils.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class EnumHolderAttribute : Attribute { } public static class EnumUtils { private static class EnumInfoPatch { public static void FixEnum(object type, ref ulong[] oldValues, ref string[] oldNames) { if (!TryGetRawPatch(type as Type, out var patch)) { return; } List<KeyValuePair<ulong, string>> pairs = patch.GetPairs(); List<ulong> list = new List<ulong>(oldValues); List<string> list2 = new List<string>(oldNames); foreach (KeyValuePair<ulong, string> item in pairs) { list.Add(item.Key); list2.Add(item.Value); } oldValues = list.ToArray(); oldNames = list2.ToArray(); Array.Sort(oldValues, oldNames, Comparer<ulong>.Default); } public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { using IEnumerator<CodeInstruction> enumerator = instructions.GetEnumerator(); while (enumerator.MoveNext()) { CodeInstruction v2 = enumerator.Current; if (v2.operand is MethodInfo methodInfo && methodInfo.Name == "Sort") { yield return v2; enumerator.MoveNext(); v2 = enumerator.Current; List<Label> labels = v2.labels; v2.labels = new List<Label>(); yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null) { labels = labels }; yield return new CodeInstruction(OpCodes.Ldloca, (object)1); yield return new CodeInstruction(OpCodes.Ldloca, (object)2); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(EnumInfoPatch), "FixEnum", (Type[])null, (Type[])null)); yield return v2; } else { yield return v2; } } } } private class EnumPatch { private Dictionary<ulong, List<string>> values = new Dictionary<ulong, List<string>>(); public List<KeyValuePair<ulong, string>> GetPairs() { List<KeyValuePair<ulong, string>> list = new List<KeyValuePair<ulong, string>>(); foreach (KeyValuePair<ulong, List<string>> value in values) { foreach (string item in value.Value) { list.Add(new KeyValuePair<ulong, string>(value.Key, item)); } } return list; } public bool HasValue(ulong value) { return values.Keys.Contains(value); } public bool HasName(string name) { foreach (string item in values.Values.SelectMany((List<string> l) => l)) { if (name.Equals(item)) { return true; } } return false; } public void AddValue(ulong enumValue, string name) { if (values.ContainsKey(enumValue)) { values[enumValue].Add(name); return; } values.Add(enumValue, new List<string> { name }); } public void RemoveValue(ulong enumValue) { values.Remove(enumValue); } public void RemoveValue(string name) { if (string.IsNullOrEmpty(name)) { return; } foreach (KeyValuePair<ulong, List<string>> value in values) { value.Value.Remove(name); } } } private static readonly Random Rng = new Random(); private static Dictionary<Type, EnumPatch> patches = new Dictionary<Type, EnumPatch>(); private static FieldInfo cache = AccessTools.Field(AccessTools.TypeByName("System.RuntimeType"), "GenericCache"); internal static void Initialize(Harmony harmony, ManualLogSource logger) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown try { harmony.Patch((MethodBase)AccessTools.Method(Type.GetType("System.Enum"), "GetCachedValuesAndNames", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(EnumInfoPatch), "Transpiler", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception arg) { logger.LogError((object)$"Exception while patching System.Enum.GetCachedValuesAndNames: {arg}"); } } private static void ClearEnumCache(Type enumType) { cache.SetValue(enumType, null); } public static T Create<T>(string name) where T : Enum { return (T)Create(typeof(T), name); } public static T Create<T>(string name, T value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, short value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, ushort value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, int value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, uint value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, long value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, ulong value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, byte value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(string name, sbyte value) where T : Enum { return Create<T>(value, name); } public static T Create<T>(short value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(ushort value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(int value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(uint value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(long value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(ulong value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(byte value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(sbyte value, string name) where T : Enum { return Create<T>(Enum.ToObject(typeof(T), value), name); } public static T Create<T>(object value, string name) where T : Enum { Create(typeof(T), value, name); return (T)value; } public static object Create(Type enumType, string name) { object firstFreeValue = GetFirstFreeValue(enumType); Create(enumType, GetFirstFreeValue(enumType), name); return firstFreeValue; } public static void Create(Type enumType, string name, object value) { Create(enumType, value, name); } public static void Create(Type enumType, object value, string name) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } if (AlreadyHasName(enumType, name) || IsDefined(enumType, name)) { throw new Exception("The enum (" + enumType.FullName + ") already has a value with the name \"" + name + "\""); } if (!TryGetRawPatch(enumType, out var patch)) { patch = new EnumPatch(); patches.Add(enumType, patch); } patch.AddValue(value.ToFriendlyValue(), name); ClearEnumCache(enumType); } internal static ulong ToFriendlyValue<T>(this T value) where T : Enum { return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture); } internal static ulong ToFriendlyValue(this object value) { return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture); } public static void Remove<T>(string name) where T : Enum { Remove(typeof(T), name); } public static void Remove<T>(T value) where T : Enum { Remove(typeof(T), value); } public static void Remove<T>(object value) where T : Enum { Remove(typeof(T), value); } public static void Remove(Type enumType, string name) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } if (TryGetRawPatch(enumType, out var patch) && patch.HasName(name)) { patch.RemoveValue(name); ClearEnumCache(enumType); } } public static void Remove(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } ulong num = value.ToFriendlyValue(); if (TryGetRawPatch(enumType, out var patch) && patch.HasValue(num)) { patch.RemoveValue(num); ClearEnumCache(enumType); } } public static bool IsDynamic<T>(string name) where T : Enum { return IsDynamic(typeof(T), name); } public static bool IsDynamic<T>(this T value) where T : Enum { return IsDynamic(typeof(T), value); } public static bool IsDynamic<T>(object value) where T : Enum { return IsDynamic(typeof(T), value); } public static bool IsDynamic(Type enumType, string name) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } if (TryGetRawPatch(enumType, out var patch)) { return patch.HasName(name); } return false; } public static bool IsDynamic(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } ulong value2 = value.ToFriendlyValue(); if (TryGetRawPatch(enumType, out var patch)) { return patch.HasValue(value2); } return false; } public static bool IsStatic<T>(string name) where T : Enum { return IsStatic(typeof(T), name); } public static bool IsStatic<T>(this T value) where T : Enum { return IsStatic(typeof(T), value); } public static bool IsStatic<T>(object value) where T : Enum { return IsStatic(typeof(T), value); } public static bool IsStatic(Type enumType, string name) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return !IsDynamic(enumType, name); } public static bool IsStatic(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return !IsDynamic(enumType, value); } private static bool TryAsNumber(this object value, Type type, out object result) { if (type.IsSubclassOf(typeof(IConvertible))) { throw new ArgumentException("The type must inherit the IConvertible interface", "type"); } result = null; if (type.IsInstanceOfType(value)) { result = value; return true; } if (value is IConvertible) { if (type.IsEnum) { result = Enum.ToObject(type, value); return true; } NumberFormatInfo currentInfo = NumberFormatInfo.CurrentInfo; result = (value as IConvertible).ToType(type, currentInfo); return true; } return false; } private static bool IsPowerOfTwo(this ulong x) { if (x != 0) { return (x & (x - 1)) == 0; } return false; } public static bool IsPowerOfTwoEnum<T>() where T : Enum { return IsFlagsEnum<T>(); } public static bool IsPowerOfTwoEnum(Type enumType) { return IsFlagsEnum(enumType); } public static bool IsFlagsEnum<T>() where T : Enum { return typeof(T).IsDefined(typeof(FlagsAttribute), inherit: false); } public static bool IsFlagsEnum(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return enumType.IsDefined(typeof(FlagsAttribute), inherit: false); } public static T GetFirstFreeValue<T>() where T : Enum { return (T)GetFirstFreeValue(typeof(T)); } public static object GetFirstFreeValue(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } Array values = Enum.GetValues(enumType); bool flag = IsPowerOfTwoEnum(enumType); long num = 0L; for (ulong num2 = 0uL; num2 <= ulong.MaxValue; num2++) { if (flag && !num2.IsPowerOfTwo()) { continue; } if (!num2.TryAsNumber(enumType, out var result)) { break; } while (true) { if (num < values.LongLength) { if (values.GetValue(num).Equals(result)) { break; } num++; continue; } return result; } } if (!flag) { long num3 = -1L; object result2; while (num3 >= long.MinValue && num3.TryAsNumber(enumType, out result2)) { while (true) { if (num < values.LongLength) { if (values.GetValue(num).Equals(result2)) { break; } num++; continue; } return result2; } num3--; } } throw new Exception((flag ? "No unused values in power of two enum " : "No unused values in enum ") + enumType.FullName); } private static bool TryGetRawPatch<T>(out EnumPatch patch) where T : Enum { return TryGetRawPatch(typeof(T), out patch); } private static bool TryGetRawPatch(Type enumType, out EnumPatch patch) { return patches.TryGetValue(enumType, out patch); } private static bool AlreadyHasName(Type enumType, string name) { if (TryGetRawPatch(enumType, out var patch)) { return patch.HasName(name); } return false; } public static void RegisterAllEnumHolders(Assembly assembly) { Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (!type.IsDefined(typeof(EnumHolderAttribute), inherit: true)) { continue; } FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType.IsEnum) { if (Convert.ToInt64(fieldInfo.GetValue(null)) == 0L) { fieldInfo.SetValue(null, Create(fieldInfo.FieldType, fieldInfo.Name)); } else { Create(fieldInfo.FieldType, fieldInfo.GetValue(null), fieldInfo.Name); } } } } } public static object Parse(Type enumType, string value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } try { return Enum.Parse(enumType, value); } catch { return null; } } public static object Parse(Type enumType, string value, bool ignoreCase) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } try { return Enum.Parse(enumType, value, ignoreCase); } catch { return null; } } public static bool TryParse(Type enumType, string value, out object result) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } try { result = Enum.Parse(enumType, value); return true; } catch { result = null; return false; } } public static bool TryParse(Type enumType, string value, bool ignoreCase, out object result) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } try { result = Enum.Parse(enumType, value, ignoreCase); return true; } catch { result = null; return false; } } public static object FromObject(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, sbyte value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, byte value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, short value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, ushort value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, int value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, uint value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, long value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static object FromObject(Type enumType, ulong value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.ToObject(enumType, value); } public static Type GetUnderlyingType(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetUnderlyingType(enumType); } public static string GetName(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetName(enumType, value); } public static string[] GetNames(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetNames(enumType); } public static string[] GetNamesWithoutFirst(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetNames(enumType).Skip(1).ToArray(); } public static object[] GetValues(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetValues(enumType).Cast<object>().ToArray(); } public static object[] GetValuesWithoutFirst(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetValues(enumType).Cast<object>().Skip(1) .ToArray(); } public static int Count(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return Enum.GetValues(enumType).Length; } public static bool IsDefined(Type enumType, object value) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } try { return Enum.IsDefined(enumType, value); } catch { return false; } } public static bool IsDefined(Type enumType, sbyte value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, byte value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, short value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, ushort value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, int value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, uint value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, long value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, ulong value) { return IsDefined(enumType, (object)value); } public static bool IsDefined(Type enumType, string value) { return IsDefined(enumType, (object)value); } public static object GetMinValue(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return GetValues(enumType).Min(); } public static object GetMaxValue(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } return GetValues(enumType).Max(); } public static object GetRandom(Type enumType) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } Array values = Enum.GetValues(enumType); int index = Rng.Next(0, values.Length); return values.GetValue(index); } public static object GetRandom(Type enumType, params object[] excluded) { if (enumType == null) { throw new ArgumentNullException("enumType"); } if (!enumType.IsEnum) { throw new NotAnEnumException(enumType); } if (excluded == null) { throw new ArgumentNullException("excluded"); } object[] array = (from object v in Enum.GetValues(enumType) where !excluded.Contains(v) select v).ToArray(); int index = Rng.Next(0, array.Length); return array.GetValue(index); } public static T Parse<T>(string value, T errorReturn = default(T)) where T : Enum { try { return (T)Enum.Parse(typeof(T), value); } catch { return errorReturn; } } public static T Parse<T>(string value, bool ignoreCase, T errorReturn = default(T)) where T : Enum { try { return (T)Enum.Parse(typeof(T), value, ignoreCase); } catch { return errorReturn; } } public static bool TryParse<T>(string value, out T result) where T : Enum { try { result = (T)Enum.Parse(typeof(T), value); return true; } catch { result = default(T); return false; } } public static bool TryParse<T>(string value, bool ignoreCase, out T result) where T : Enum { try { result = (T)Enum.Parse(typeof(T), value, ignoreCase); return true; } catch { result = default(T); return false; } } public static T FromObject<T>(object value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(sbyte value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(byte value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(short value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(ushort value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(int value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(uint value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(long value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static T FromObject<T>(ulong value) where T : Enum { return (T)Enum.ToObject(typeof(T), value); } public static Type GetUnderlyingType<T>() where T : Enum { return Enum.GetUnderlyingType(typeof(T)); } public static string GetName<T>(this T value) where T : Enum { return Enum.GetName(typeof(T), value); } public static string[] GetNames<T>() where T : Enum { return Enum.GetNames(typeof(T)); } public static string[] GetNamesWithoutFirst<T>() where T : Enum { return Enum.GetNames(typeof(T)).Skip(1).ToArray(); } public static string[] GetNames<T>(params T[] excluded) where T : Enum { return GetValues(excluded).Select(GetName).ToArray(); } public static T[] GetValues<T>() where T : Enum { return Enum.GetValues(typeof(T)).Cast<T>().ToArray(); } public static T[] GetValuesWithoutFirst<T>() where T : Enum { return Enum.GetValues(typeof(T)).Cast<T>().Skip(1) .ToArray(); } public static T[] GetValues<T>(params T[] excluded) where T : Enum { return (from T v in Enum.GetValues(typeof(T)) where !excluded.Contains(v) select v).ToArray(); } public static T[] GetDynamicValues<T>() where T : Enum { return Enum.GetValues(typeof(T)).Cast<T>().Where(IsDynamic) .ToArray(); } public static T[] GetStaticValues<T>() where T : Enum { return Enum.GetValues(typeof(T)).Cast<T>().Where(IsStatic) .ToArray(); } public static int Count<T>() where T : Enum { return Enum.GetValues(typeof(T)).Length; } public static bool IsDefined<T>(object value) where T : Enum { try { return Enum.IsDefined(typeof(T), value); } catch { return false; } } public static bool IsDefined<T>(sbyte value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(byte value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(short value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(ushort value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(int value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(uint value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(long value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(ulong value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(string value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static bool IsDefined<T>(this T value) where T : Enum { return EnumUtils.IsDefined<T>((object)value); } public static T GetMinValue<T>() where T : Enum { return GetValues<T>().Min(); } public static T GetMaxValue<T>() where T : Enum { return GetValues<T>().Max(); } public static string Format<T>(this T value, string format) where T : Enum { return Enum.Format(typeof(T), value, format); } public static T GetRandom<T>() where T : Enum { T[] values = GetValues<T>(); int index = Rng.Next(0, values.Length); return (T)values.GetValue(index); } public static T GetRandom<T>(params T[] excluded) where T : Enum { T[] array = (from T v in Enum.GetValues(typeof(T)) where !excluded.Contains(v) select v).ToArray(); int index = Rng.Next(0, array.Length); return (T)array.GetValue(index); } public static string GetRandomName<T>() where T : Enum { string[] names = GetNames<T>(); int index = Rng.Next(0, names.Length); return (string)names.GetValue(index); } public static string GetRandomName<T>(params T[] excluded) where T : Enum { T[] array = (from T v in Enum.GetNames(typeof(T)) where !excluded.Contains(v) select v).ToArray(); int index = Rng.Next(0, array.Length); return (string)array.GetValue(index); } public static IDictionary<T, string> GetDescriptions<T>() where T : Enum { Type typeFromHandle = typeof(T); Dictionary<T, string> dictionary = new Dictionary<T, string>(); T[] values = GetValues<T>(); foreach (T val in values) { FieldInfo? field = typeFromHandle.GetField($"{val}"); string value = null; if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute descriptionAttribute) { value = descriptionAttribute.Description; } dictionary.Add(val, value); } return dictionary; } public static void ThrowIfNotEnum(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (!type.IsEnum) { throw new NotAnEnumException(type); } } public static void ThrowIfNotEnum<T>() { if (!typeof(T).IsEnum) { throw new NotAnEnumException(typeof(T)); } } public static T EnumCast<T>(this Enum value) where T : Enum { if (value.GetType() != typeof(T)) { throw new InvalidCastException("Enums are not of the same type"); } return (T)value; } public static IEnumerable<T> EnumCast<T>(this IEnumerable<Enum> values) where T : Enum { return values.Select((Enum e) => e.EnumCast<T>()); } public static bool HasFlag<T>(T flags, T flag) where T : Enum { return flags.HasFlag(flag); } public static T SetFlag<T>(this T flags, T flag, bool setBit) where T : Enum { if (!setBit) { return flags.RemoveFlag(flag); } return flags.AddFlag(flag); } public static T AddFlag<T>(this T flags, T flag) where T : Enum { return FromObject<T>(flags.ToFriendlyValue() | flag.ToFriendlyValue()); } public static T RemoveFlag<T>(this T flags, T flag) where T : Enum { return FromObject<T>(flags.ToFriendlyValue() & ~flag.ToFriendlyValue()); } public static T ToggleFlag<T>(this T flags, T flag) where T : Enum { return FromObject<T>(flags.ToFriendlyValue() ^ flag.ToFriendlyValue()); } public static T GetFlagsValue<T>(int index) where T : Enum { return FromObject<T>(1 << index); } public static T GetNoFlags<T>() where T : Enum { return FromObject<T>(0); } public static T GetAllFlags<T>() where T : Enum { return FromObject<T>(-1); } public static T[] GetFlagsValues<T>(this T flags) where T : Enum { if (!IsFlagsEnum<T>()) { throw new ArgumentException($"The type '{typeof(T)}' must have an attribute '{typeof(FlagsAttribute)}'."); } Type underlyingType = GetUnderlyingType<T>(); ulong num = flags.ToFriendlyValue(); IEnumerable<ulong> enumerable = GetValues<T>().Select(ToFriendlyValue); IList<T> list = new List<T>(); foreach (ulong item in enumerable) { if ((num & item) == item && item != 0L) { list.Add((T)Convert.ChangeType(item, underlyingType, CultureInfo.CurrentCulture)); } } if (list.Count == 0 && enumerable.SingleOrDefault((ulong v) => v == 0) != 0L) { list.Add(default(T)); } return list.ToArray(); } public static T CombineFlagsValues<T>(this T[] values) where T : Enum { if (!IsFlagsEnum<T>()) { throw new ArgumentException($"The type '{typeof(T)}' must have an attribute '{typeof(FlagsAttribute)}'."); } T val = default(T); if (values != null && values.Length != 0) { foreach (T flag in values) { val = val.AddFlag(flag); } } return val; } } public class NotAnEnumException : Exception { private Type _type; public Type Type => _type; public NotAnEnumException(Type type) : base("The given type isn't an enum (" + type.FullName + " isn't an Enum)") { _type = type; } public NotAnEnumException(Type type, Exception innerException) : base("The given type isn't an enum (" + type.FullName + " isn't an Enum)", innerException) { _type = type; } } namespace LCEnumUtils { [BepInPlugin("MegaPiggy.EnumUtils", "Enum Utils", "1.0.5")] internal class Initializer : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("MegaPiggy.EnumUtils"); private static Initializer Instance; private static ManualLogSource LoggerInstance => ((BaseUnityPlugin)Instance).Logger; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } EnumUtils.Initialize(harmony, ((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Enum Utils is loaded with version 1.0.5!"); } } public static class PluginInfo { public const string ModGUID = "MegaPiggy.EnumUtils"; public const string ModName = "Enum Utils"; public const string ModVersion = "1.0.5"; } }