using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MoreCustomizations.Data;
using MoreCustomizations.Helpers;
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.1.9.0")]
[assembly: AssemblyInformationalVersion("1.1.9+2a20ef1f5ca7aef984dc05ebef9144738444c7d4")]
[assembly: AssemblyProduct("MoreCustomizations")]
[assembly: AssemblyTitle("MoreCustomizations")]
[assembly: AssemblyVersion("1.1.9.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.1.9")]
public class MoreCustomizationsPlugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
internal static Harmony _patcher = new Harmony("MoreCustomizations");
internal static MoreCustomizationsPlugin Singleton { get; private set; }
public static int BaseHatCount { get; internal set; } = 0;
public static int OverrideHatCount { get; internal set; } = 0;
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(PassportButtonPatch));
_patcher.PatchAll(typeof(CharacterCustomizationPatch));
_patcher.PatchAll(typeof(CharacterCustomizationDataPatch));
_patcher.PatchAll(typeof(PlayerCustomizationDummyPatch));
_patcher.PatchAll(typeof(PeakHandlePatch));
Logger.LogInfo((object)"MoreCustomizations is loaded!");
}
private void LoadAllCustomizations()
{
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
//IL_02f7: 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));
}
CustomizationData[] array2 = val.LoadAllAssets<CustomizationData>();
CustomizationData[] array3 = array2;
foreach (CustomizationData customizationData in array3)
{
((Object)customizationData).name = $"{text3.GetHashCode()}_{((Object)customizationData).name}";
}
list.AddRange(array2);
}
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)
{
IEnumerable<ValidateStatus> enumerable = from status in item.GetValidateContentStatuses()
where status.Type != ValidateStatus.ValidateType.Valid
select status;
bool flag = false;
foreach (ValidateStatus item2 in enumerable)
{
flag |= item2.Type == ValidateStatus.ValidateType.Error;
switch (item2.Type)
{
case ValidateStatus.ValidateType.Warning:
Logger.LogWarning((object)("[Validation Warning:" + ((Object)item).name + "] " + item2.Message));
break;
case ValidateStatus.ValidateType.Error:
Logger.LogError((object)("[Validation Error:" + ((Object)item).name + "] " + item2.Message));
break;
}
}
if (!flag)
{
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.1.9";
}
}
namespace MoreCustomizations.Data
{
public abstract class CustomizationData : ScriptableObject
{
public abstract Texture IconTexture { get; }
public bool IsValid => GetValidateContentStatuses().All((ValidateStatus status) => status.Type != ValidateStatus.ValidateType.Error);
public abstract Type Type { get; }
public abstract IEnumerable<ValidateStatus> GetValidateContentStatuses();
}
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;
}
public abstract class CustomFitData : CustomizationData
{
public sealed override Type Type => (Type)40;
}
[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 IEnumerable<ValidateStatus> GetValidateContentStatuses()
{
if (!Object.op_Implicit((Object)(object)Texture))
{
yield return ValidateStatus.Error("Texture is empty.");
}
else
{
yield return ValidateStatus.Valid;
}
}
}
[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 IEnumerable<ValidateStatus> GetValidateContentStatuses()
{
if (!Object.op_Implicit((Object)(object)Texture))
{
yield return ValidateStatus.Error("Texture is empty.");
}
else
{
yield return ValidateStatus.Valid;
}
}
}
[CreateAssetMenu(menuName = "PEAK More Customizations/Fit", fileName = "New Custom Fit", order = int.MinValue)]
public class CustomFit_V1 : CustomFitData
{
[field: SerializeField]
[field: Tooltip("The texture for the icon in the Passport")]
public Texture Icon { get; internal set; }
[field: SerializeField]
[field: Tooltip("If set to true, the eyes are rendered on top of the outfit at all times")]
public bool DrawUnderEye { get; internal set; }
[field: SerializeField]
[field: Tooltip("The Mesh of the outfit we imported earlier")]
public Mesh FitMesh { get; internal set; }
[field: SerializeField]
[field: Tooltip("The color texture for the second material slot")]
public Texture FitMainTexture { get; internal set; }
[field: SerializeField]
[field: Tooltip("The color texture for the third material slot")]
public Texture FitShoeTexture { get; internal set; }
[field: SerializeField]
[field: Tooltip("The color texture that can override the pants material. Leave blank to use the default pants material.")]
public Texture FitOverridePantsTexture { get; internal set; }
[field: SerializeField]
[field: Tooltip("The color texture that can override the hat material. Only works on hats 0 and 1. Leave blank to use the default hat material.")]
public Texture FitOverrideHatTexture { get; internal set; }
[field: SerializeField]
[field: Tooltip("Indicated whether the skirt or shorts mesh should be enabled for this outfit variant.")]
public bool IsSkirt { get; internal set; }
[field: SerializeField]
[field: Tooltip("If true, hides both the skirt and shorts mesh for this outfit. Used for outfits like the Astronaut suit, that have no gendered variants.")]
public bool NoPants { get; internal set; }
public override Texture IconTexture => Icon;
public override IEnumerable<ValidateStatus> GetValidateContentStatuses()
{
bool flag = false;
if (!Object.op_Implicit((Object)(object)Icon))
{
yield return ValidateStatus.Error("Icon is empty.");
flag = true;
}
if (!Object.op_Implicit((Object)(object)FitMesh))
{
yield return ValidateStatus.Error("FitMesh is empty.");
flag = true;
}
if (!Object.op_Implicit((Object)(object)FitMainTexture))
{
yield return ValidateStatus.Error("FitMainTexture is empty.");
flag = true;
}
if (!Object.op_Implicit((Object)(object)FitShoeTexture))
{
yield return ValidateStatus.Error("FitShoeTexture is empty.");
flag = true;
}
if (!flag)
{
yield return ValidateStatus.Valid;
}
}
}
[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 IEnumerable<ValidateStatus> GetValidateContentStatuses()
{
bool flag = false;
if (!Object.op_Implicit((Object)(object)Icon))
{
yield return ValidateStatus.Error("Icon is empty.");
flag = true;
}
if (!Object.op_Implicit((Object)(object)Prefab))
{
yield return ValidateStatus.Error("Prefab is empty.");
flag = true;
}
if (!flag)
{
yield return ValidateStatus.Valid;
}
}
}
[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 IEnumerable<ValidateStatus> GetValidateContentStatuses()
{
if (!Object.op_Implicit((Object)(object)Texture))
{
yield return ValidateStatus.Error("Texture is empty.");
}
else
{
yield return ValidateStatus.Valid;
}
}
}
public struct ValidateStatus
{
public enum ValidateType
{
Valid,
Warning,
Error
}
public static readonly ValidateStatus Valid = new ValidateStatus("This asset is valid.", ValidateType.Valid);
public readonly string Message;
public readonly ValidateType Type;
public ValidateStatus(string message, ValidateType type)
{
Message = message;
Type = type;
}
public static ValidateStatus Warning(string message)
{
return new ValidateStatus(message, ValidateType.Warning);
}
public static ValidateStatus Error(string message)
{
return new ValidateStatus(message, ValidateType.Error);
}
}
}
namespace MoreCustomizations.Patches
{
public class CharacterCustomizationDataPatch
{
[HarmonyPatch(typeof(CharacterCustomizationData), "CorrectValues")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> CorrectValuesTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = instructions.ToList();
for (int j = 0; j < codes.Count - 2; j++)
{
if (codes[j].opcode == OpCodes.Ldarg_0 && codes[j + 1].opcode == OpCodes.Ldfld && codes[j + 1].operand.ToString().Contains("currentHat") && codes[j + 2].opcode == OpCodes.Call && codes[j + 2].operand.ToString().Contains("get_Instance") && codes[j + 3].opcode == OpCodes.Ldfld && codes[j + 3].operand.ToString().Contains("hats") && codes[j + 4].opcode == OpCodes.Ldlen && codes[j + 5].opcode == OpCodes.Conv_I4)
{
yield return codes[j];
yield return codes[j + 1];
yield return codes[j + 2];
yield return codes[j + 3];
yield return codes[j + 4];
yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Property(typeof(MoreCustomizationsPlugin), "OverrideHatCount").GetGetMethod(nonPublic: true));
yield return new CodeInstruction(OpCodes.Add, (object)null);
yield return codes[j + 5];
j += 5;
}
else
{
yield return codes[j];
}
}
for (int j = codes.Count - 2; j < codes.Count; j++)
{
if (j >= 0)
{
yield return codes[j];
}
}
}
}
public class CharacterCustomizationPatch
{
public const string HAT_PATH = "Scout/Armature/Hip/Mid/AimJoint/Torso/Head/Hat";
private static Shader _characterShader;
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 in CharacterCustomizationPatch...");
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();
}
[HarmonyPatch(typeof(CharacterCustomization), "SetCharacterHat")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> SetCharacterHatTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = instructions.ToList();
for (int j = 0; j < codes.Count - 2; j++)
{
if (codes[j].opcode == OpCodes.Ldarg_0 && codes[j + 1].opcode == OpCodes.Call && codes[j + 1].operand.ToString().Contains("get_Instance") && codes[j + 2].opcode == OpCodes.Ldfld && codes[j + 2].operand.ToString().Contains("hats") && codes[j + 3].opcode == OpCodes.Ldlen && codes[j + 4].opcode == OpCodes.Conv_I4)
{
yield return codes[j];
yield return codes[j + 1];
yield return codes[j + 2];
yield return codes[j + 3];
yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Property(typeof(MoreCustomizationsPlugin), "OverrideHatCount").GetGetMethod(nonPublic: true));
yield return new CodeInstruction(OpCodes.Add, (object)null);
yield return codes[j + 4];
j += 4;
}
else
{
yield return codes[j];
}
}
for (int j = codes.Count - 2; j < codes.Count; j++)
{
if (j >= 0)
{
yield return codes[j];
}
}
}
}
public class PassportButtonPatch
{
[HarmonyPatch(typeof(PassportButton), "SetButton")]
[HarmonyPostfix]
private static void SetButton(ref int ___currentIndex, CustomizationOption option)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
if (!((Object)(object)option == (Object)null) && (int)option.type == 50 && ___currentIndex >= MoreCustomizationsPlugin.BaseHatCount)
{
___currentIndex += MoreCustomizationsPlugin.OverrideHatCount;
}
}
}
public class PassportManagerPatch
{
private static Material materialTemplate;
[HarmonyPatch(typeof(PassportManager), "Awake")]
[HarmonyPostfix]
private static void Awake(PassportManager __instance)
{
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Invalid comparison between Unknown and I4
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Invalid comparison between Unknown and I4
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Invalid comparison between Unknown and I4
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Invalid comparison between Unknown and I4
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Invalid comparison between Unknown and I4
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Invalid comparison between Unknown and I4
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Invalid comparison between Unknown and I4
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);
MoreCustomizationsPlugin.BaseHatCount = list6.Count;
MoreCustomizationsPlugin.OverrideHatCount = 0;
foreach (CustomizationOption item in list5)
{
if (item.overrideHat)
{
MoreCustomizationsPlugin.OverrideHatCount++;
}
}
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_014b;
}
list7 = list3;
}
else
{
list7 = list2;
}
}
else
{
list7 = list;
}
}
else if ((int)val2 != 30)
{
if ((int)val2 != 40)
{
if ((int)val2 != 50)
{
goto IL_014b;
}
list7 = list6;
}
else
{
list7 = list5;
}
}
else
{
list7 = list4;
}
goto IL_014e;
IL_014b:
list7 = null;
goto IL_014e;
IL_014e:
List<CustomizationOption> list8 = list7;
if (list8 == null)
{
continue;
}
foreach (CustomizationData item2 in readOnlyList2)
{
if (!Object.op_Implicit((Object)(object)item2) || !item2.IsValid)
{
continue;
}
CustomizationOption val3 = ScriptableObject.CreateInstance<CustomizationOption>();
val3.requiredAchievement = (ACHIEVEMENTTYPE)0;
((Object)val3).name = ((Object)item2).name;
val3.type = item2.Type;
val3.texture = item2.IconTexture;
if ((int)val2 == 40)
{
CustomFit_V1 customFit_V = item2 as CustomFit_V1;
if (!Object.op_Implicit((Object)(object)customFit_V))
{
continue;
}
if (!Object.op_Implicit((Object)(object)materialTemplate))
{
materialTemplate = component?.fits.FirstOrDefault()?.fitMaterial;
if (!Object.op_Implicit((Object)(object)materialTemplate))
{
MoreCustomizationsPlugin.Logger.LogWarning((object)"Could not find existing fitMaterial to copy! Using fallback material, expect some visual errors.");
materialTemplate = FitMaterialFallback.MaterialTemplate;
}
}
val3.fitMesh = customFit_V.FitMesh;
val3.isSkirt = customFit_V.IsSkirt;
val3.noPants = customFit_V.NoPants;
val3.drawUnderEye = customFit_V.DrawUnderEye;
val3.fitMaterial = Object.Instantiate<Material>(materialTemplate);
val3.fitMaterial.SetTexture("_MainTex", customFit_V.FitMainTexture);
val3.fitMaterialShoes = Object.Instantiate<Material>(materialTemplate);
val3.fitMaterialShoes.SetTexture("_MainTex", customFit_V.FitShoeTexture);
if (Object.op_Implicit((Object)(object)customFit_V.FitOverrideHatTexture))
{
val3.fitMaterialOverrideHat = Object.Instantiate<Material>(materialTemplate);
val3.fitMaterialOverrideHat.SetTexture("_MainTex", customFit_V.FitOverrideHatTexture);
}
if (Object.op_Implicit((Object)(object)customFit_V.FitOverridePantsTexture))
{
val3.fitMaterialOverridePants = Object.Instantiate<Material>(materialTemplate);
val3.fitMaterialOverridePants.SetTexture("_MainTex", customFit_V.FitOverridePantsTexture);
}
}
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();
}
[HarmonyPatch(typeof(PassportManager), "SetActiveButton")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> SetActiveButton(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = instructions.ToList();
for (int j = 0; j < codes.Count - 2; j++)
{
if (codes[j].opcode == OpCodes.Ldloc_0 && codes[j + 1].opcode == OpCodes.Ldfld && codes[j + 1].operand.ToString().Contains("customizationData") && codes[j + 2].opcode == OpCodes.Ldfld && codes[j + 2].operand.ToString().Contains("currentHat") && codes[j + 3].opcode == OpCodes.Stloc_1)
{
yield return codes[j];
yield return codes[j + 1];
yield return codes[j + 2];
yield return new CodeInstruction(OpCodes.Dup, (object)null);
yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Property(typeof(MoreCustomizationsPlugin), "BaseHatCount").GetGetMethod(nonPublic: true));
Label skipLabel = default(Label);
yield return new CodeInstruction(OpCodes.Ble_S, (object)null)
{
operand = skipLabel
};
yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Property(typeof(MoreCustomizationsPlugin), "OverrideHatCount").GetGetMethod(nonPublic: true));
yield return new CodeInstruction(OpCodes.Sub, (object)null);
CodeInstruction val = new CodeInstruction(OpCodes.Nop, (object)null);
val.labels.Add(skipLabel);
yield return val;
yield return codes[j + 3];
j += 3;
}
else
{
yield return codes[j];
}
}
for (int j = codes.Count - 2; j < codes.Count; j++)
{
if (j >= 0)
{
yield return codes[j];
}
}
}
[HarmonyPatch(typeof(PassportManager), "CameraIn")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> CameraInTranspiler(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_R4 && instruction.operand != null && instruction.operand.Equals(1f))
{
instruction.operand = 3f;
yield return instruction;
}
else
{
yield return instruction;
}
}
}
[HarmonyPatch(typeof(PassportManager), "CameraOut")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> CameraOutTranspiler(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Ldc_R4 && instruction.operand != null && instruction.operand.Equals(1f))
{
instruction.operand = 3f;
yield return instruction;
}
else
{
yield return instruction;
}
}
}
}
public class PeakHandlePatch
{
[HarmonyPatch(typeof(PeakHandler), "SetCosmetics")]
[HarmonyPrefix]
private static void SetCosmetics(PeakHandler __instance, List<Character> characters)
{
if (!CustomizationRefsHelper.SyncCustomHats(__instance.firstCutsceneScout))
{
MoreCustomizationsPlugin.Logger.LogError((object)"Something went wrong in PeakHandlePatch [firstCutsceneScout]...");
}
for (int i = 0; i < __instance.cutsceneScoutRefs.Count(); i++)
{
if (!CustomizationRefsHelper.SyncCustomHats(__instance.cutsceneScoutRefs[i]))
{
MoreCustomizationsPlugin.Logger.LogError((object)string.Format("Something went wrong in {0} [cutsceneScoutRefs-{1}]...", "PeakHandlePatch", i));
}
}
}
}
public class PlayerCustomizationDummyPatch
{
[HarmonyPatch(typeof(PlayerCustomizationDummy), "SetPlayerHat")]
[HarmonyPrefix]
private static void SetPlayerHat(PlayerCustomizationDummy __instance, int index)
{
if (!CustomizationRefsHelper.SyncCustomHats(__instance.refs))
{
MoreCustomizationsPlugin.Logger.LogError((object)"Something went wrong in SetPlayerHat patch...");
}
}
}
}
namespace MoreCustomizations.Helpers
{
public class CustomizationRefsHelper
{
public const string REF_TO_HATS_PATH = "Armature/Hip/Mid/AimJoint/Torso/Head/Hat";
public static bool SyncCustomHats(CustomizationRefs dstRefs, CustomizationRefs srcRefs = null)
{
if ((Object)(object)srcRefs == (Object)null)
{
Character localCharacter = Character.localCharacter;
CharacterCustomization val = default(CharacterCustomization);
if (!Object.op_Implicit((Object)(object)localCharacter) || !((Component)localCharacter).TryGetComponent<CharacterCustomization>(ref val))
{
MoreCustomizationsPlugin.Logger.LogError((object)"Cannot get [LocalCharacter] or its' [CustomizationRefs] ...");
return false;
}
srcRefs = val.refs;
}
Renderer[] playerHats = srcRefs.playerHats;
Renderer[] playerHats2 = dstRefs.playerHats;
if (playerHats.Length == playerHats2.Length)
{
return true;
}
Renderer val2 = playerHats2.FirstOrDefault();
if (!Object.op_Implicit((Object)(object)val2))
{
MoreCustomizationsPlugin.Logger.LogError((object)"Cannot find renders in dstPlayerHats...");
return false;
}
int layer = ((Component)val2).gameObject.layer;
Transform val3 = ((Component)srcRefs).transform.Find("Armature/Hip/Mid/AimJoint/Torso/Head/Hat");
Transform val4 = ((Component)dstRefs).transform.Find("Armature/Hip/Mid/AimJoint/Torso/Head/Hat");
List<Renderer> list = new List<Renderer>(playerHats2);
for (int i = playerHats2.Length; i < playerHats.Length; i++)
{
Transform val5 = ((Component)playerHats[i]).transform;
while ((Object)(object)val5.parent != (Object)(object)val3)
{
val5 = val5.parent;
}
GameObject obj = Object.Instantiate<GameObject>(((Component)val5).gameObject, val4, false);
((Object)obj).name = ((Object)val5).name;
Renderer componentInChildren = obj.GetComponentInChildren<Renderer>(true);
((Component)componentInChildren).gameObject.layer = layer;
list.Add(componentInChildren);
}
dstRefs.playerHats = list.ToArray();
return true;
}
}
public static class FitMaterialFallback
{
private static readonly (string, float)[] FLOATS = new(string, float)[83]
{
("_AddPrecomputedVelocity", 0f),
("_AddSpecular", 0f),
("_AlphaClip", 0f),
("_AlphaCutoff", 0.5f),
("_AlphaToMask", 0f),
("_BaseSmooth", 0f),
("_Blend", 0f),
("_BlendModePreserveSpecular", 1f),
("_Brightness", 1f),
("_BumpScale", 1f),
("_ClearCoatMask", 0f),
("_ClearCoatSmoothness", 0f),
("_Cull", 2f),
("_Cutoff", 0.5f),
("_DetailAlbedoMapScale", 1f),
("_DetailNormalMapScale", 1f),
("_DstBlend", 0f),
("_DstBlendAlpha", 0f),
("_EnvironmentReflections", 1f),
("_Flip1", 0f),
("_Flip2", 0f),
("_Flip3", 0f),
("_Flip4", 0f),
("_FlipHeightMask", 0f),
("_GlossMapScale", 0f),
("_Glossiness", 0f),
("_GlossyReflections", 0f),
("_Glow", 0f),
("_Height1", 0f),
("_Height2", 0f),
("_Height3", 0f),
("_Height4", 0f),
("_HueStr", 1f),
("_INTERACTABLE", 0f),
("_Interactable", 0f),
("_Metalic", 0f),
("_Metallic", 0f),
("_Mode", 0f),
("_OcclusionStrength", 1f),
("_Opacity", 1f),
("_Outline", 1f),
("_Parallax", 0.005f),
("_QueueControl", 0f),
("_QueueOffset", 0f),
("_ReceiveShadows", 1f),
("_ReflectionBoost", 0f),
("_Smooth1", 0f),
("_Smooth2", 0f),
("_Smooth3", 0f),
("_Smooth4", 0f),
("_Smoothness", 0.5f),
("_SmoothnessTextureChannel", 0f),
("_SpecularHighlights", 1f),
("_SrcBlend", 1f),
("_SrcBlendAlpha", 1f),
("_StatusGlow", 0f),
("_Surface", 0f),
("_ToggleSwitch0", 0f),
("_Triplanar1", 0f),
("_Triplanar1On", 0f),
("_Triplanar2", 0f),
("_Triplanar2On", 0f),
("_Triplanar3", 0f),
("_Triplanar3On", 0f),
("_Triplanar4", 0f),
("_Triplanar4On", 0f),
("_UV1", 1.15f),
("_UV2", 0.27f),
("_UV3", 1f),
("_UV4", 1f),
("_UVSec", 0f),
("_UseHeightMask1", 0f),
("_UseHeightMask2", 0f),
("_UseHeightMask3", 0f),
("_UseHeightMask4", 0f),
("_UseRawVertexColor", 0f),
("_UseSkinTone", 0f),
("_UseTextureAlpha", 0f),
("_UseVertexColor", 0f),
("_VertexColor", 1f),
("_VertexGhost", 0f),
("_WorkflowMode", 1f),
("_ZWrite", 1f)
};
private static readonly (string, Color)[] COLORS = new(string, Color)[18]
{
("_BaseColor", new Color(1f, 1f, 1f, 1f)),
("_Color", new Color(1f, 1f, 1f, 1f)),
("_Color0", new Color(4f, 2.191751f, 0f, 0f)),
("_Color1", new Color(91f / 106f, 0.6924617f, 0.6924617f, 1f)),
("_Color2", new Color(69f / 106f, 0.58534664f, 0.5066305f, 0.6509804f)),
("_Color3", new Color(1f, 1f, 1f, 0f)),
("_Color4", new Color(1f, 1f, 1f, 0f)),
("_EmissionColor", new Color(0f, 0f, 0f, 1f)),
("_HeightMaskSmoothness", new Color(0f, 0f, 0f, 0f)),
("_HueShifts", new Color(0f, 0f, 0f, 0f)),
("_Remap1", new Color(0.35514024f, 0.551402f, 0f, 0f)),
("_Remap2", new Color(0.31775698f, 0.71962625f, 0f, 0f)),
("_Remap3", new Color(0f, 1f, 0f, 0f)),
("_Remap4", new Color(0f, 1f, 0f, 0f)),
("_SkinColor", new Color(1f, 1f, 1f, 0f)),
("_SpecColor", new Color(0.19999996f, 0.19999996f, 0.19999996f, 1f)),
("_StatusColor", new Color(2.600001f, 0.5094339f, 4f, 1f)),
("_Tint", new Color(1f, 1f, 1f, 1f))
};
public static Material MaterialTemplate
{
get
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
Material val = new Material(Shader.Find("W/Character"));
(string, float)[] fLOATS = FLOATS;
for (int i = 0; i < fLOATS.Length; i++)
{
var (text, num) = fLOATS[i];
val.SetFloat(text, num);
}
(string, Color)[] cOLORS = COLORS;
for (int i = 0; i < cOLORS.Length; i++)
{
var (text2, val2) = cOLORS[i];
val.SetColor(text2, val2);
}
return val;
}
}
}
}