Please disclose if your mod was created primarily 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 Lethal Wardrobe v0.2.2
LethalWardrobe.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using LethalWardrobe.Model; using LethalWardrobe.Model.Config; using LethalWardrobe.Model.Factories; using LethalWardrobe.Model.Suit; using LethalWardrobe.Model.Suit.Store; using LethalWardrobe.Model.Util; using LethalWardrobe.Patches; using LethalWardrobeAPI.Model; using LethalWardrobeAPI.Model.Suit; using Microsoft.CodeAnalysis; using On; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: AssemblyCompany("LethalWardrobe")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("A streamlined, More Suits compatiable, mod that allows for easy addition of custom suits to Lethal Company")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0-alpha.0.5+cd61d42946511c0b12a684330d3794d5bb53f515")] [assembly: AssemblyProduct("LethalWardrobe")] [assembly: AssemblyTitle("LethalWardrobe")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.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; } } } namespace LethalWardrobe { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Curiosity-Core.Lethal_Wardrobe", "Lethal Wardrobe", "0.0.1")] public class LethalWardrobe : BaseUnityPlugin { private const string ModGuid = "Curiosity-Core.Lethal_Wardrobe"; private const string ModName = "Lethal Wardrobe"; private const string ModVersion = "0.0.1"; private void Awake() { Terminal terminal = Object.FindObjectOfType<Terminal>(); InitConfig(); InitAPI(); StartOfRoundPatches.Init(terminal); } private void InitConfig() { ConfigHandler.Instance.Initialize(((BaseUnityPlugin)this).Config); } private void InitAPI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("APILoader"); val.AddComponent<APILoader>(); Object.DontDestroyOnLoad((Object)(object)val); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalWardrobe"; public const string PLUGIN_NAME = "LethalWardrobe"; public const string PLUGIN_VERSION = "0.0.0"; } } namespace LethalWardrobe.Patches { public class StartOfRoundPatches { [CompilerGenerated] private static class <>O { public static hook_Start <0>__StartOfRoundOnStart; public static hook_PositionSuitsOnRack <1>__StartOfRoundOnPositionSuitsOnRack; } private static Terminal _terminal; private static ISuitFactory _suitFactory; public static void Init(Terminal terminal) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown _terminal = terminal; Debug.Log((object)"LethalWardrobe: StartOfRoundPatches!!!!!!"); object obj = <>O.<0>__StartOfRoundOnStart; if (obj == null) { hook_Start val = StartOfRoundOnStart; <>O.<0>__StartOfRoundOnStart = val; obj = (object)val; } StartOfRound.Start += (hook_Start)obj; object obj2 = <>O.<1>__StartOfRoundOnPositionSuitsOnRack; if (obj2 == null) { hook_PositionSuitsOnRack val2 = StartOfRoundOnPositionSuitsOnRack; <>O.<1>__StartOfRoundOnPositionSuitsOnRack = val2; obj2 = (object)val2; } StartOfRound.PositionSuitsOnRack += (hook_PositionSuitsOnRack)obj2; } private static void StartOfRoundOnStart(orig_Start orig, StartOfRound self) { _suitFactory = InitializeSuitFactory(ref self); _suitFactory.AddFolderPaths(Directory.GetDirectories(Paths.PluginPath, "moresuits", SearchOption.AllDirectories).ToList()); _suitFactory.AddPatchInstance(self); SuitHandler.Instance.RegisterSuits(((IListFactory<ISuit>)_suitFactory).Create(), self, _terminal); orig.Invoke(self); } private static void StartOfRoundOnPositionSuitsOnRack(orig_PositionSuitsOnRack orig, StartOfRound self) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) List<UnlockableSuit> list = (from suit in Object.FindObjectsOfType<UnlockableSuit>().ToList() orderby suit.syncedSuitID.Value select suit).ToList(); int num = 0; foreach (UnlockableSuit item in list) { AutoParentToShip component = ((Component)item).gameObject.GetComponent<AutoParentToShip>(); component.overrideOffset = true; float num2 = 0.18f; if (ConfigHandler.Instance.GetConfigValue<bool>(ConfigKey.AutoFitSuitsOnRack) && list.Count > 13) { num2 /= (float)Math.Min(list.Count, 20) / 12f; } component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + self.rightmostSuitPosition.forward * num2 * (float)num; component.rotationOffset = new Vector3(0f, 90f, 0f); num++; } } private static ISuitFactory InitializeSuitFactory(ref StartOfRound startOfRound) { return ((Component)startOfRound).gameObject.AddComponent<SuitFactory>(); } } } namespace LethalWardrobe.Model { public class APILoader : MonoBehaviour, IApiLoader { public ISuitManager SuitManager => (ISuitManager)(object)global::LethalWardrobe.Model.Suit.SuitManager.Instance; } } namespace LethalWardrobe.Model.Util { public class SuitUtils { private static UnlockableItem _originalSuit; public static UnlockableItem GetOriginalSuit(ref StartOfRound instance) { if (_originalSuit == null) { _originalSuit = ((IEnumerable<UnlockableItem>)instance.unlockablesList.unlockables).FirstOrDefault((Func<UnlockableItem, bool>)((UnlockableItem item) => (Object)(object)item.suitMaterial != (Object)null && item.alreadyUnlocked)); if (_originalSuit == null) { throw new InvalidOperationException("Original suit not found: The specified suit does not exist in the main code. Ensure that all suit references are correctly defined and loaded."); } } return _originalSuit; } public static UnlockableItem InitDummySuit(ref StartOfRound instance) { UnlockableItem originalSuit = GetOriginalSuit(ref instance); return JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)originalSuit)); } public static UnlockableItem InitDummySuitForRack(ref StartOfRound instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) UnlockableItem val = InitDummySuit(ref instance); val.alreadyUnlocked = false; val.hasBeenMoved = false; val.placedPosition = Vector3.zero; val.placedRotation = Vector3.zero; val.unlockableType = 753; return val; } } } namespace LethalWardrobe.Model.Suit { public class CustomSuit : ISuit { public ulong Id { get; set; } public string UnlockableName { get; set; } public Material SuitMaterial { get; set; } public bool IsDefault { get; set; } public bool IsUnlocked { get; set; } } public class SuitHandler { private static readonly Lazy<SuitHandler> LazyInstance = new Lazy<SuitHandler>(() => new SuitHandler()); private TerminalNode _cancelPurchase; public static SuitHandler Instance => LazyInstance.Value; public void RegisterSuits(List<ISuit> suits, StartOfRound instance, Terminal terminal) { int suitCount = 0; suits.ForEach(delegate(ISuit suit) { int count = instance.unlockablesList.unlockables.Count; RegisterSuit(suit, instance); IPurchasable val = (IPurchasable)(object)((suit is IPurchasable) ? suit : null); if (val != null) { HandlePurchasable(val, instance, terminal, suitCount); } suitCount++; UnlockableItem item = SuitUtils.InitDummySuitForRack(ref instance); while (instance.unlockablesList.unlockables.Count < count + ConfigHandler.Instance.GetConfigValue<int>(ConfigKey.MaxSuits)) { instance.unlockablesList.unlockables.Add(item); } }); } private void RegisterSuit(ISuit suit, StartOfRound instance) { UnlockableItem originalSuit = SuitUtils.GetOriginalSuit(ref instance); UnlockableItem val = (suit.IsDefault ? originalSuit : JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)originalSuit))); val.suitMaterial = suit.SuitMaterial; val.unlockableName = suit.UnlockableName; val.alreadyUnlocked = true; instance.unlockablesList.unlockables.Add(val); } private void HandlePurchasable(IPurchasable purchasable, StartOfRound instance, Terminal terminal, int unlockableID) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Expected O, but got Unknown UnlockableItem val = instance.unlockablesList.unlockables.Last(); TerminalKeyword val2 = null; for (int i = 0; i < terminal.terminalNodes.allKeywords.Length; i++) { if (((Object)terminal.terminalNodes.allKeywords[i]).name == "Buy") { val2 = terminal.terminalNodes.allKeywords[i]; break; } } if ((Object)(object)val2 == (Object)null) { throw new InvalidOperationException("Buy keyword could not be found for registering purchasable!"); } val.alreadyUnlocked = false; val.hasBeenMoved = false; val.placedPosition = Vector3.zero; val.placedRotation = Vector3.zero; val.shopSelectionNode = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val.shopSelectionNode).name = val.unlockableName + "SuitBuy1"; val.shopSelectionNode.creatureName = val.unlockableName + " suit"; val.shopSelectionNode.displayText = "You have requested to order " + val.unlockableName + " suits.\nTotal cost of item: [totalCost].\n\nPlease CONFIRM or DENY.\n\n"; val.shopSelectionNode.clearPreviousText = true; val.shopSelectionNode.shipUnlockableID = unlockableID; val.shopSelectionNode.itemCost = purchasable.Price; val.shopSelectionNode.overrideOptions = true; CompatibleNoun val3 = new CompatibleNoun(); val3.noun = ScriptableObject.CreateInstance<TerminalKeyword>(); val3.noun.word = "confirm"; val3.noun.isVerb = true; val3.result = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val3.result).name = val.unlockableName + "SuitBuyConfirm"; val3.result.creatureName = ""; val3.result.displayText = "Ordered " + val.unlockableName + " suits! Your new balance is [playerCredits].\n\n"; val3.result.clearPreviousText = true; val3.result.shipUnlockableID = unlockableID; val3.result.buyUnlockable = true; val3.result.itemCost = purchasable.Price; val3.result.terminalEvent = ""; CompatibleNoun val4 = new CompatibleNoun(); val4.noun = ScriptableObject.CreateInstance<TerminalKeyword>(); val4.noun.word = "deny"; val4.noun.isVerb = true; if ((Object)(object)_cancelPurchase == (Object)null) { _cancelPurchase = ScriptableObject.CreateInstance<TerminalNode>(); } val4.result = _cancelPurchase; ((Object)val4.result).name = "MoreSuitsCancelPurchase"; val4.result.displayText = "Cancelled order.\n"; val.shopSelectionNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { val3, val4 }; TerminalKeyword val5 = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)val5).name = val.unlockableName + "Suit"; val5.word = val.unlockableName.ToLower() + " suit"; val5.defaultVerb = val2; CompatibleNoun val6 = new CompatibleNoun(); val6.noun = val5; val6.result = val.shopSelectionNode; List<CompatibleNoun> list = val2.compatibleNouns.ToList(); list.Add(val6); val2.compatibleNouns = list.ToArray(); List<TerminalKeyword> list2 = terminal.terminalNodes.allKeywords.ToList(); list2.Add(val5); list2.Add(val3.noun); list2.Add(val4.noun); terminal.terminalNodes.allKeywords = list2.ToArray(); } } public class SuitManager : ISuitManager { private static readonly Lazy<SuitManager> instance = new Lazy<SuitManager>(() => new SuitManager()); private Dictionary<ulong, ISuit> _suits = new Dictionary<ulong, ISuit>(); private Dictionary<string, ISuit> _suitNameCache = new Dictionary<string, ISuit>(); public static SuitManager Instance => instance.Value; public void RegisterSuit(ISuit suit) { _suits.Add(suit.Id, suit); _suitNameCache.Add(suit.UnlockableName, suit); } public void UnregisterSuit(ulong id) { _suits.Remove(id); } public ISuit GetSuit(ulong id) { return _suits.GetValueOrDefault(id); } public ISuit GetSuit(string name) { return _suitNameCache.GetValueOrDefault(name); } public List<ISuit> GetSuits() { return _suits.Values.ToList(); } } } namespace LethalWardrobe.Model.Suit.Store { public class PurchaseableSuit : ISuit, IPurchasable { public ulong Id { get; set; } public string UnlockableName { get; set; } public Material SuitMaterial { get; set; } public bool IsDefault { get; set; } public bool IsUnlocked { get; set; } public int Price { get; set; } } } namespace LethalWardrobe.Model.Factories { public interface ISuitFactory : IListFactory<ISuit> { void AddFolderPaths(List<string> paths); void AddPatchInstance(StartOfRound instance); } public class SuitFactory : MonoBehaviour, ISuitFactory, IListFactory<ISuit> { private List<string> _assetPaths = new List<string>(); private readonly Dictionary<string, Material> _customMaterialCache = new Dictionary<string, Material>(); private StartOfRound _instance; private List<string> _texturePaths = new List<string>(); private readonly Dictionary<string, Material> _materialCache = new Dictionary<string, Material>(); private Material _defaultMaterial; public List<string> SuitFolderPaths { get; set; } public List<ISuit> Create() { List<ISuit> list = new List<ISuit>(); SetPaths(); SortPaths(); foreach (string assetPath in _assetPaths) { AssetBundle val = AssetBundle.LoadFromFile(assetPath); Object[] array = val.LoadAllAssets(); Object[] array2 = array; foreach (Object val2 in array2) { Material val3 = (Material)(object)((val2 is Material) ? val2 : null); if (val3 != null) { _customMaterialCache.Add(((Object)val3).name, val3); } } } ulong num = 0uL; foreach (string texturePath in _texturePaths) { ISuit val4 = HandleSuitModifications(InitSuitFromPath(texturePath, num), texturePath); SuitManager.Instance.RegisterSuit(val4); list.Add(val4); num++; } Debug.Log((object)$"Created {list.Count} suits!!!"); return list.ToList(); } public void AddFolderPaths(List<string> paths) { SuitFolderPaths = paths; Debug.Log((object)$"Paths found: {SuitFolderPaths.Count}"); } public void AddPatchInstance(StartOfRound instance) { _instance = instance; } private ISuit InitSuitFromPath(string texturePath, ulong suitsCount) { if (string.IsNullOrEmpty(texturePath)) { Debug.LogError((object)"Texture path is null or empty."); return null; } ISuit val = (ISuit)(object)new CustomSuit(); val.Id = suitsCount; val.UnlockableName = Path.GetFileNameWithoutExtension(texturePath); val.SuitMaterial = InitMaterialFromPath(texturePath); if ((Object)(object)val.SuitMaterial == (Object)null) { Debug.LogError((object)("Failed to initialize material from path: " + texturePath)); } return val; } private Material InitMaterialFromPath(string texturePath) { if (_materialCache.TryGetValue(texturePath, out var value)) { return value; } UnlockableItem originalSuit = SuitUtils.GetOriginalSuit(ref _instance); Material val = ((Path.GetFileNameWithoutExtension(texturePath).ToLower() == "default") ? GetDefaultMaterial() : Object.Instantiate<Material>(JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)originalSuit)).suitMaterial)); val.mainTexture = (Texture)(object)InitSuitTextureFromPath(texturePath); _materialCache[texturePath] = val; return val; } private Material GetDefaultMaterial() { if ((Object)(object)_defaultMaterial == (Object)null) { _defaultMaterial = SuitUtils.GetOriginalSuit(ref _instance).suitMaterial; } return _defaultMaterial; } private Texture2D InitSuitTextureFromPath(string texturePath) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown byte[] array = File.ReadAllBytes(texturePath); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); val.Apply(true, true); return val; } private void SetPaths() { (_texturePaths, _assetPaths) = InitPaths(); } private void SortPaths() { _texturePaths.Sort(); _assetPaths.Sort(); } private (List<string> texturePaths, List<string> assetPaths) InitPaths() { List<string> list = new List<string>(); List<string> list2 = new List<string>(); foreach (string suitFolderPath in SuitFolderPaths) { if (!(suitFolderPath == "")) { string[] files = Directory.GetFiles(suitFolderPath, "*.png"); string[] files2 = Directory.GetFiles(suitFolderPath, "*.matbundle"); list.AddRange(files); list2.AddRange(files2); Debug.Log((object)$"Found {list.Count} texture paths. Found {list2.Count} asset paths."); } } return (list, list2); } private ISuit HandleSuitModifications(ISuit suit, string texturePath) { string path = Path.Combine(Path.GetDirectoryName(texturePath) ?? throw new InvalidOperationException(), "advanced", suit.UnlockableName + ".json"); if (!File.Exists(path)) { return suit; } string[] array = File.ReadAllLines(path); foreach (string text in array) { string[] array2 = text.Trim().Split(':'); if (array2.Length != 2) { continue; } string text2 = array2[0].Trim('"', ' ', ','); string text3 = array2[1].Trim('"', ' ', ','); if (text3.EndsWith(".png")) { LoadAdvancedTexture(texturePath, text3, text2, suit.SuitMaterial); continue; } switch (text3) { case "KEYWORD": suit.SuitMaterial.EnableKeyword(text2); break; case "DISABLEKEYWORD": suit.SuitMaterial.DisableKeyword(text2); break; case "SHADERPASS": suit.SuitMaterial.SetShaderPassEnabled(text2, true); break; case "DISABLESHADERPASS": suit.SuitMaterial.SetShaderPassEnabled(text2, false); break; default: suit.SuitMaterial = ApplyNumericOrVectorValue(text2, text3, suit.SuitMaterial); break; } switch (text2) { case "PRICE": { if (int.TryParse(text3, out var result)) { suit = (ISuit)(object)new PurchaseableSuit { Id = suit.Id, UnlockableName = suit.UnlockableName, SuitMaterial = suit.SuitMaterial, Price = result }; } break; } case "SHADER": { Shader shader = Shader.Find(text3); suit.SuitMaterial.shader = shader; break; } case "MATERIAL": suit.SuitMaterial = ApplyCustomMaterial(text3, suit.SuitMaterial.mainTexture); break; } } return suit; } private void LoadAdvancedTexture(string baseTexturePath, string textureFileName, string textureKey, Material material) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown string path = Path.Combine(Path.GetDirectoryName(baseTexturePath) ?? throw new InvalidOperationException(), "advanced", textureFileName); byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); val.Apply(true, true); material.SetTexture(textureKey, (Texture)(object)val); } private Material ApplyCustomMaterial(string materialName, Texture mainTexture) { Material val = Object.Instantiate<Material>(_customMaterialCache[materialName]); val.mainTexture = mainTexture; return val; } private Material ApplyNumericOrVectorValue(string key, string value, Material material) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) Vector4 vector; if (float.TryParse(value, out var result)) { material.SetFloat(key, result); } else if (TryParseVector4(value, out vector)) { material.SetVector(key, vector); } return material; } private static bool TryParseVector4(string input, out Vector4 vector) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) vector = Vector4.zero; string[] array = input.Split(','); if (array.Length == 4 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3) && float.TryParse(array[3], out var result4)) { vector = new Vector4(result, result2, result3, result4); return true; } return false; } } } namespace LethalWardrobe.Model.Config { public class ConfigHandler { private static readonly Lazy<ConfigHandler> LazyInstance = new Lazy<ConfigHandler>(() => new ConfigHandler()); private readonly Dictionary<ConfigKey, object> _configValues = new Dictionary<ConfigKey, object>(); public static ConfigHandler Instance => LazyInstance.Value; public void Initialize(ConfigFile config) { _configValues[ConfigKey.MaxSuits] = config.Bind<int>("General", "Max Suits", 5, "Max Suits that can be loaded.").Value; _configValues[ConfigKey.AllSuitsUnlocked] = config.Bind<bool>("General", "All Suits Unlocked", false, "Makes all suits wearable from the start of the game.").Value; _configValues[ConfigKey.LoadAllSuits] = config.Bind<bool>("General", "Load All Suits", false, "Loads all suits regardless of amount.").Value; _configValues[ConfigKey.AutoFitSuitsOnRack] = config.Bind<bool>("General", "Auto Fit Suits On Rack", false, (ConfigDescription)null).Value; } public T GetConfigValue<T>(ConfigKey key) { object value; return _configValues.TryGetValue(key, out value) ? ((T)value) : default(T); } } public enum ConfigKey { MaxSuits, AllSuitsUnlocked, LoadAllSuits, AutoFitSuitsOnRack } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }