The BepInEx console will not appear when launching like it does for other games on Thunderstore. This is normal (and helps prevent crashes during startup). You can turn it back on in your BepInEx.cfg file.
Decompiled source of More Customizations v1.1.0
BepInEx/plugins/MoreCustomizations/MoreCustomizations.dll
Decompiled a day 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 BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using MoreCustomizations.Data; using MoreCustomizations.Patches; 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("MoreCustomizations")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+aa1d1ef9ba51bf8be4e0fafbf3059f3bd50c11fd")] [assembly: AssemblyProduct("MoreCustomizations")] [assembly: AssemblyTitle("MoreCustomizations")] [assembly: AssemblyVersion("1.0.0.0")] [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 MoreCustomizations { [BepInPlugin("MoreCustomizations", "MoreCustomizations", "1.0.0")] public class MoreCustomizationsPlugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static Harmony _patcher = new Harmony("MoreCustomizations"); internal static MoreCustomizationsPlugin Singleton { get; private set; } public static IReadOnlyDictionary<Type, IReadOnlyList<CustomizationData>> AllCustomizationsData { get; private set; } private void Awake() { Singleton = this; Logger = ((BaseUnityPlugin)this).Logger; LoadAllCustomizations(); Logger.LogInfo((object)"Patching methods..."); _patcher.PatchAll(typeof(PassportManagerPatch)); _patcher.PatchAll(typeof(CharacterCustomizationPatch)); Logger.LogInfo((object)"MoreCustomizations is loaded!"); } private void LoadAllCustomizations() { //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) AllCustomizationsData = null; Dictionary<Type, List<CustomizationData>> dictionary = new Dictionary<Type, List<CustomizationData>>(); string[] files = Directory.GetFiles(Path.Combine(Paths.BepInExRootPath, "plugins"), "*.pcab", SearchOption.AllDirectories); if (files.Length == 0) { throw new FileNotFoundException("No customization files found in '" + Paths.PluginPath + "'."); } Logger.LogInfo((object)$"Found {files.Length} possible contents."); List<CustomizationData> list = new List<CustomizationData>(); string[] array = files; foreach (string text in array) { string text2 = text; int length = Paths.PluginPath.Length; string text3 = text2.Substring(length, text2.Length - length); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); try { AssetBundle val = AssetBundle.LoadFromFile(text); Logger.LogInfo((object)("Asset bundle '" + fileNameWithoutExtension + "' loaded! (" + text3 + ")")); Logger.LogInfo((object)"Catalog list :"); string[] allAssetNames = val.GetAllAssetNames(); foreach (string text4 in allAssetNames) { Logger.LogInfo((object)("- " + text4)); } list.AddRange(val.LoadAllAssets<CustomizationData>()); } catch (Exception ex) { Logger.LogError((object)("Error occurred while loading custom asset bundle. (" + text3 + ")")); Logger.LogError((object)ex.Message); Logger.LogError((object)ex.StackTrace); } } Logger.LogInfo((object)$"Loading {list.Count} customizations..."); foreach (CustomizationData item in list) { Type type = item.Type; if (!dictionary.TryGetValue(type, out var value2)) { value2 = (dictionary[type] = new List<CustomizationData>()); } value2.Add(item); Logger.LogInfo((object)("Loaded '" + ((Object)item).name + "'!")); } Logger.LogInfo((object)"Done!"); AllCustomizationsData = ((IEnumerable<KeyValuePair<Type, List<CustomizationData>>>)dictionary).ToDictionary((Func<KeyValuePair<Type, List<CustomizationData>>, Type>)((KeyValuePair<Type, List<CustomizationData>> key) => key.Key), (Func<KeyValuePair<Type, List<CustomizationData>>, IReadOnlyList<CustomizationData>>)((KeyValuePair<Type, List<CustomizationData>> value) => value.Value)); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "MoreCustomizations"; public const string PLUGIN_NAME = "MoreCustomizations"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace MoreCustomizations.Data { public abstract class CustomizationData : ScriptableObject { public abstract Texture IconTexture { get; } public abstract Type Type { get; } public abstract bool IsValid(); } public abstract class CustomAccessoryData : CustomizationData { public sealed override Type Type => (Type)10; } public abstract class CustomEyesData : CustomizationData { public sealed override Type Type => (Type)20; } public abstract class CustomMouthData : CustomizationData { public sealed override Type Type => (Type)30; } public abstract class CustomHatData : CustomizationData { public sealed override Type Type => (Type)50; } [CreateAssetMenu(menuName = "PEAK More Customizations/Accessory", fileName = "New Custom Accessory", order = int.MinValue)] public class CustomAccessory_V1 : CustomAccessoryData { [field: SerializeField] public Texture Texture { get; internal set; } public override Texture IconTexture => Texture; public override bool IsValid() { return Object.op_Implicit((Object)(object)Texture); } } [CreateAssetMenu(menuName = "PEAK More Customizations/Eye", fileName = "New Custom Eye", order = int.MinValue)] public class CustomEyes_V1 : CustomEyesData { [field: SerializeField] public Texture Texture { get; internal set; } public override Texture IconTexture => Texture; public override bool IsValid() { return Object.op_Implicit((Object)(object)Texture); } } [CreateAssetMenu(menuName = "PEAK More Customizations/Hat", fileName = "New Custom Hat", order = int.MinValue)] public class CustomHat_V1 : CustomHatData { [field: SerializeField] public Texture Icon { get; internal set; } [field: SerializeField] public GameObject Prefab { get; internal set; } [field: SerializeField] public Texture MainTexture { get; internal set; } [field: SerializeField] public Texture SubTexture { get; internal set; } [field: SerializeField] public Vector3 PositionOffset { get; internal set; } [field: SerializeField] public Vector3 EulerAngleOffset { get; internal set; } public Vector3 SwizzledPositionOffset => new Vector3(PositionOffset.x, 0f - PositionOffset.z, PositionOffset.y); public Vector3 SwizzledRotationOffset => new Vector3(EulerAngleOffset.x, 0f - EulerAngleOffset.z, 0f - EulerAngleOffset.y); public override Texture IconTexture => Icon; public override bool IsValid() { if (Object.op_Implicit((Object)(object)Icon)) { return Object.op_Implicit((Object)(object)Prefab); } return false; } } [CreateAssetMenu(menuName = "PEAK More Customizations/Mouth", fileName = "New Custom Mouth", order = int.MinValue)] public class CustomMouth_V1 : CustomMouthData { [field: SerializeField] public Texture Texture { get; internal set; } public override Texture IconTexture => Texture; public override bool IsValid() { return Object.op_Implicit((Object)(object)Texture); } } } namespace MoreCustomizations.Patches { public class CharacterCustomizationPatch { public const string HAT_PATH = "Scout/Armature/Hip/Mid/AimJoint/Torso/Head/Hat"; private static Shader _characterShader; private static MaterialPropertyBlock _materialPropertyBlock = new MaterialPropertyBlock(); private static readonly Vector3 INITIAL_HAT_OFFSET = new Vector3(0f, 0.2f, 6f); [HarmonyPatch(typeof(CharacterCustomization), "Awake")] [HarmonyPostfix] private static void Awake(CharacterCustomization __instance) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown IReadOnlyDictionary<Type, IReadOnlyList<CustomizationData>> allCustomizationsData = MoreCustomizationsPlugin.AllCustomizationsData; if (allCustomizationsData == null) { MoreCustomizationsPlugin.Logger.LogError((object)"Customizations data are not loaded!"); return; } if (allCustomizationsData.Count == 0) { MoreCustomizationsPlugin.Logger.LogWarning((object)"There's no customizations data."); return; } if (!Object.op_Implicit((Object)(object)_characterShader)) { _characterShader = Shader.Find("W/Character"); } if (!allCustomizationsData.TryGetValue((Type)50, out var value)) { return; } Transform val = ((Component)__instance).transform.Find("Scout/Armature/Hip/Mid/AimJoint/Torso/Head/Hat"); if (!Object.op_Implicit((Object)(object)val)) { MoreCustomizationsPlugin.Logger.LogError((object)"Something went wrong..."); return; } List<Renderer> list = new List<Renderer>(__instance.refs.playerHats); foreach (CustomHat_V1 item in value.OfType<CustomHat_V1>()) { if (!Object.op_Implicit((Object)(object)item) || !item.IsValid()) { continue; } GameObject val2 = Object.Instantiate<GameObject>(item.Prefab, val, false); Renderer componentInChildren = val2.GetComponentInChildren<Renderer>(); if (!Object.op_Implicit((Object)(object)componentInChildren)) { MoreCustomizationsPlugin.Logger.LogError((object)("Cannot find Renderer component of customization data '" + ((Object)item).name + "'.")); Object.Destroy((Object)(object)val2); continue; } val2.transform.localPosition = INITIAL_HAT_OFFSET + item.SwizzledPositionOffset; val2.transform.localRotation = Quaternion.Euler(item.SwizzledRotationOffset) * Quaternion.AngleAxis(90f, Vector3.right); ((Component)componentInChildren).gameObject.SetActive(false); ((Object)componentInChildren).name = ((Object)item).name; Material val3 = new Material(_characterShader); Material val4 = new Material(_characterShader); if (Object.op_Implicit((Object)(object)item.MainTexture)) { val3.SetTexture("_MainTex", item.MainTexture); } if (Object.op_Implicit((Object)(object)item.SubTexture)) { val4.SetTexture("_MainTex", item.SubTexture); } componentInChildren.materials = (Material[])(object)new Material[2] { val3, val4 }; list.Add(componentInChildren); } __instance.refs.playerHats = list.ToArray(); } } public class PassportManagerPatch { [HarmonyPatch(typeof(PassportManager), "Awake")] [HarmonyPrefix] private static void Awake(PassportManager __instance) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Invalid comparison between Unknown and I4 //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Invalid comparison between Unknown and I4 //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Invalid comparison between Unknown and I4 //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) IReadOnlyDictionary<Type, IReadOnlyList<CustomizationData>> allCustomizationsData = MoreCustomizationsPlugin.AllCustomizationsData; if (allCustomizationsData == null) { MoreCustomizationsPlugin.Logger.LogError((object)"Customizations data are not loaded!"); return; } if (allCustomizationsData.Count == 0) { MoreCustomizationsPlugin.Logger.LogWarning((object)"There's no customizations data."); return; } Customization component = ((Component)__instance).GetComponent<Customization>(); List<CustomizationOption> list = new List<CustomizationOption>(component.skins); List<CustomizationOption> list2 = new List<CustomizationOption>(component.accessories); List<CustomizationOption> list3 = new List<CustomizationOption>(component.eyes); List<CustomizationOption> list4 = new List<CustomizationOption>(component.mouths); List<CustomizationOption> list5 = new List<CustomizationOption>(component.fits); List<CustomizationOption> list6 = new List<CustomizationOption>(component.hats); foreach (var (val2, readOnlyList2) in allCustomizationsData) { List<CustomizationOption> list7; if ((int)val2 <= 20) { if ((int)val2 != 0) { if ((int)val2 != 10) { if ((int)val2 != 20) { goto IL_00fb; } list7 = list3; } else { list7 = list2; } } else { list7 = list; } } else if ((int)val2 != 30) { if ((int)val2 != 40) { if ((int)val2 != 50) { goto IL_00fb; } list7 = list6; } else { list7 = list5; } } else { list7 = list4; } goto IL_00fe; IL_00fb: list7 = null; goto IL_00fe; IL_00fe: List<CustomizationOption> list8 = list7; if (list8 == null) { continue; } foreach (CustomizationData item in readOnlyList2) { if (Object.op_Implicit((Object)(object)item) && item.IsValid()) { CustomizationOption val3 = ScriptableObject.CreateInstance<CustomizationOption>(); val3.requiredAchievement = (ACHIEVEMENTTYPE)0; ((Object)val3).name = ((Object)item).name; val3.type = item.Type; val3.texture = item.IconTexture; list8.Add(val3); } } } component.skins = list.ToArray(); component.accessories = list2.ToArray(); component.eyes = list3.ToArray(); component.mouths = list4.ToArray(); component.fits = list5.ToArray(); component.hats = list6.ToArray(); } } }