Decompiled source of DynamicSkinsFix v1.0.6

DynamicSkinsFix.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HG;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;

[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: AssemblyCompany("DynamicSkinsFix")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3ce1eeb1de06abb8422c4263dadf492c43185cb4")]
[assembly: AssemblyProduct("DynamicSkinsFix")]
[assembly: AssemblyTitle("DynamicSkinsFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 DynamicSkinsFix
{
	[BepInPlugin("Miyowi.DynamicSkinsFix", "DynamicSkinsFix", "1.0.4")]
	public class DynamicSkinsFix : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Init <0>__SwapAcridRenderer;

			public static Manipulator <1>__CallObsolete;

			public static Manipulator <2>__ObsoleteRet;

			public static Manipulator <3>__AccessOldArray;
		}

		public const string PluginGUID = "Miyowi.DynamicSkinsFix";

		public const string PluginAuthor = "Miyowi";

		public const string PluginName = "DynamicSkinsFix";

		public const string PluginVersion = "1.0.4";

		private Random random = new Random();

		private static int callCount;

		private const int callLimit = 50;

		public void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			Log.Init(((BaseUnityPlugin)this).Logger);
			DupeRenderer();
			AttachAcridComponent();
			object obj = <>O.<0>__SwapAcridRenderer;
			if (obj == null)
			{
				hook_Init val = SwapAcridRenderer;
				<>O.<0>__SwapAcridRenderer = val;
				obj = (object)val;
			}
			SkinCatalog.Init += (hook_Init)obj;
			object obj2 = <>O.<1>__CallObsolete;
			if (obj2 == null)
			{
				Manipulator val2 = CallObsolete;
				<>O.<1>__CallObsolete = val2;
				obj2 = (object)val2;
			}
			SkinDef.ApplyAsync += (Manipulator)obj2;
			object obj3 = <>O.<2>__ObsoleteRet;
			if (obj3 == null)
			{
				Manipulator val3 = ObsoleteRet;
				<>O.<2>__ObsoleteRet = val3;
				obj3 = (object)val3;
			}
			SkinDef.Apply += (Manipulator)obj3;
			object obj4 = <>O.<3>__AccessOldArray;
			if (obj4 == null)
			{
				Manipulator val4 = AccessOldArray;
				<>O.<3>__AccessOldArray = val4;
				obj4 = (object)val4;
			}
			BodyCatalog.GetBodySkins += (Manipulator)obj4;
		}

		private static void ObsoleteRet(ILContext il)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Func<bool> func = delegate
			{
				callCount++;
				StackTrace stackTrace = new StackTrace();
				StackFrame[] frames = stackTrace.GetFrames();
				foreach (StackFrame stackFrame in frames)
				{
					MethodBase method = stackFrame.GetMethod();
					if (callCount > 50)
					{
						Log.Warning("Potential infinite loop detected. Aborting to prevent game crash");
						return true;
					}
					if (method.Name == "DMD<RoR2.SkinDef::ApplyAsync>" || method.Name == "ApplyAsync")
					{
						return true;
					}
				}
				return false;
			};
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0)
			}))
			{
				ILLabel val2 = val.DefineLabel();
				val.EmitDelegate<Func<bool>>(func);
				val.Emit(OpCodes.Brfalse, (object)val2);
				val.Emit(OpCodes.Ret);
				val.MarkLabel(val2);
			}
			else
			{
				Log.Error("ILHook failed. Some dynamic skins will not work, or worse");
			}
		}

		private static void CallObsolete(ILContext il)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Action<SkinDef, GameObject> action = delegate(SkinDef self, GameObject modelObject)
			{
				self.Apply(modelObject);
			};
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchRet(x)
			}))
			{
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldarg_1);
				val.EmitDelegate<Action<SkinDef, GameObject>>(action);
			}
			else
			{
				Log.Error("ILHook failed. Some dynamic skins will not work, or worse");
			}
		}

		private static void AccessOldArray(ILContext il)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			Func<BodyIndex, SkinDef[]> func = delegate(BodyIndex bodyIndex)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected I4, but got Unknown
				SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(bodyIndex);
				if (bodySkinDefs.Length == 0)
				{
					SkinDef[][] skins = BodyCatalog.skins;
					SkinDef[] array = Array.Empty<SkinDef>();
					return ArrayUtils.GetSafe<SkinDef[]>(skins, (int)bodyIndex, ref array);
				}
				return bodySkinDefs;
			};
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0)
			}))
			{
				ILLabel val2 = val.DefineLabel();
				val.Emit(OpCodes.Br, (object)val2);
				if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchRet(x)
				}))
				{
					val.MarkLabel(val2);
					val.Emit(OpCodes.Ldarg_0);
					val.EmitDelegate<Func<BodyIndex, SkinDef[]>>(func);
					val.Emit(OpCodes.Ret);
				}
				else
				{
					Log.Error("ILHook failed. Some dynamic skins will not work, or worse");
				}
			}
			else
			{
				Log.Error("ILHook failed. Some dynamic skins will not work, or worse");
			}
		}

		private static void AttachAcridComponent()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Croco/CrocoBody.prefab").WaitForCompletion();
			val.AddComponent<FixAcridMissingGoo>();
		}

		private static void DupeRenderer()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Croco/CrocoBody.prefab").WaitForCompletion();
			if ((Object)(object)val != (Object)null)
			{
				GameObject gameObject = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
				Transform val2 = gameObject.transform.Find("CrocoSpineMesh");
				SkinnedMeshRenderer component = ((Component)val2).GetComponent<SkinnedMeshRenderer>();
				Transform val3 = Object.Instantiate<Transform>(gameObject.transform.Find("CrocoSpineMesh"));
				SkinnedMeshRenderer component2 = ((Component)val3).GetComponent<SkinnedMeshRenderer>();
				((Object)((Component)component2).transform).name = "CrocoSpineMesh";
				component2.sharedMesh = component.sharedMesh;
				val3.parent = gameObject.transform;
			}
			else
			{
				Log.Error("Could not find CrocoBody Prefab. Acrid fixes not applied.");
			}
		}

		private static IEnumerator SwapAcridRenderer(orig_Init orig)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Croco/CrocoBody.prefab").WaitForCompletion();
			GameObject gameObject = ((Component)val.GetComponent<ModelLocator>().modelTransform).gameObject;
			ModelSkinController component = gameObject.GetComponent<ModelSkinController>();
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
			SkinDef[] skins = component.skins;
			foreach (SkinDef val2 in skins)
			{
				bool flag = false;
				for (int j = 0; j < val2.meshReplacements.Length; j++)
				{
					flag = (Object)(object)componentsInChildren[3] == (Object)(object)val2.meshReplacements[j].renderer;
					if (flag)
					{
						break;
					}
				}
				if (!flag)
				{
					for (int k = 0; k < val2.rendererInfos.Length; k++)
					{
						flag = (Object)(object)componentsInChildren[3] == (Object)(object)val2.rendererInfos[k].renderer;
						if (flag)
						{
							break;
						}
					}
					for (int l = 0; l < val2.gameObjectActivations.Length; l++)
					{
						flag = (Object)(object)((Component)componentsInChildren[3]).gameObject == (Object)(object)val2.gameObjectActivations[l].gameObject;
						if (flag)
						{
							break;
						}
					}
				}
				if (flag)
				{
					for (int m = 0; m < val2.meshReplacements.Length; m++)
					{
						val2.meshReplacements[m].renderer = GetCorrectRenderer(val2.meshReplacements[m].renderer, componentsInChildren);
					}
					for (int n = 0; n < val2.rendererInfos.Length; n++)
					{
						val2.rendererInfos[n].renderer = GetCorrectRenderer(val2.rendererInfos[n].renderer, componentsInChildren);
					}
					for (int num = 0; num < val2.gameObjectActivations.Length; num++)
					{
						val2.gameObjectActivations[num].gameObject = GetCorrectGameObject(val2.gameObjectActivations[num], componentsInChildren);
					}
				}
			}
			BodyCatalog.skins[BodyCatalog.FindBodyIndex("CrocoBody")] = component.skins;
			return orig.Invoke();
		}

		private static Renderer GetCorrectRenderer(Renderer renderer, Renderer[] componentsInChildren)
		{
			return componentsInChildren[Array.IndexOf(componentsInChildren, renderer) - 1];
		}

		private static GameObject GetCorrectGameObject(GameObjectActivation gameObjectActivation, Renderer[] componentsInChildren)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gameObjectActivation.gameObject == (Object)(object)((Component)componentsInChildren[3]).gameObject)
			{
				return ((Component)componentsInChildren[2]).gameObject;
			}
			if ((Object)(object)gameObjectActivation.gameObject == (Object)(object)((Component)componentsInChildren[2]).gameObject)
			{
				return ((Component)componentsInChildren[1]).gameObject;
			}
			return ((Component)componentsInChildren[0]).gameObject;
		}

		private void FixedUpdate()
		{
			callCount = 0;
		}
	}
	public class FixAcridMissingGoo : MonoBehaviour
	{
		public void Start()
		{
			ModelLocator component = ((Component)this).GetComponent<ModelLocator>();
			object obj;
			if (component == null)
			{
				obj = null;
			}
			else
			{
				ChildLocator component2 = ((Component)component.modelTransform).GetComponent<ChildLocator>();
				if (component2 == null)
				{
					obj = null;
				}
				else
				{
					Transform obj2 = component2.FindChild("Head");
					if (obj2 == null)
					{
						obj = null;
					}
					else
					{
						Transform obj3 = obj2.Find("Goo");
						obj = ((obj3 != null) ? ((Component)obj3).GetComponent<ParticleSystemRenderer>() : null);
					}
				}
			}
			ParticleSystemRenderer val = (ParticleSystemRenderer)obj;
			if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)val).sharedMaterial == (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
			Object.Destroy((Object)(object)this);
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
}