Decompiled source of DynamicSkinsFix v1.0.4

DynamicSkinsFix.dll

Decompiled 2 weeks 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+19a730ae2d0c3a1ba0a514a3805695c93db259eb")]
[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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			Log.Init(((BaseUnityPlugin)this).Logger);
			DupeRenderer();
			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 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_00cc: 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);
			Log.Info(component.skins.Length);
			SkinDef[] skins = component.skins;
			foreach (SkinDef val2 in skins)
			{
				Log.Info(val2.meshReplacements.Length);
				if (val2.meshReplacements.Length >= 2)
				{
					val2.meshReplacements[0].renderer = componentsInChildren[1];
					val2.meshReplacements[1].renderer = componentsInChildren[2];
				}
			}
			BodyCatalog.skins[BodyCatalog.FindBodyIndex("CrocoBody")] = component.skins;
			return orig.Invoke();
		}

		private void FixedUpdate()
		{
			callCount = 0;
		}
	}
	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);
		}
	}
}