Decompiled source of ModelReplacementAPIHotfix v1.0.2

BepInEx/plugins/abooban1-ModelReplacementAPIHotfix/ModelReplacementAPIHotfix.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using ModelReplacement.Monobehaviors;
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("ModelReplacementAPIHotfix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ee5258aa22dafa5aed30e6f636ac63dae5ac7703")]
[assembly: AssemblyProduct("ModelReplacementAPIHotfix")]
[assembly: AssemblyTitle("ModelReplacementAPIHotfix")]
[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 ModelReplacementAPIHotfix
{
	[BepInPlugin("abooban1.modelreplacementapi.hotfix", "ModelReplacementAPI Hotfix", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("abooban1.modelreplacementapi.hotfix");
			try
			{
				ApplyHotfix(_harmony, ((BaseUnityPlugin)this).Logger);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Failed to apply ModelReplacementAPI hotfix:");
				((BaseUnityPlugin)this).Logger.LogError((object)ex);
			}
		}

		private static void ApplyHotfix(Harmony harmony, ManualLogSource logger)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0119: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//IL_0189: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Expected O, but got Unknown
			//IL_01f9: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Expected O, but got Unknown
			//IL_0269: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(GrabbableObject), "LateUpdate", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				logger.LogError((object)"Could not find GrabbableObject.LateUpdate.");
				return;
			}
			Type type = AccessTools.TypeByName("ModelReplacement.Patches.LocateHeldObjectsOnModelReplacementPatch");
			if (type == null)
			{
				logger.LogWarning((object)"Could not find ModelReplacementAPI LocateHeldObjectsOnModelReplacementPatch type.");
			}
			MethodInfo methodInfo2 = ((type == null) ? null : AccessTools.Method(type, "LateUpdatePatch", (Type[])null, (Type[])null));
			if (methodInfo2 != null)
			{
				harmony.Unpatch((MethodBase)methodInfo, methodInfo2);
				logger.LogInfo((object)"Unpatched broken ModelReplacementAPI held-object postfix.");
			}
			else
			{
				logger.LogWarning((object)"Could not find broken postfix. Safe postfix will still be applied.");
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(SafeHeldObjectPatch), "LateUpdatePatch", (Type[])null, (Type[])null);
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Applied safe ModelReplacementAPI held-object postfix.");
			MethodInfo methodInfo4 = AccessTools.Method(typeof(BodyReplacementBase), "LateUpdate", (Type[])null, (Type[])null);
			if (methodInfo4 != null)
			{
				harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(SafeBodyReplacementLateUpdatePatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(SafeBodyReplacementLateUpdatePatch), "Finalizer", (Type[])null), (HarmonyMethod)null);
				logger.LogInfo((object)"Applied safe BodyReplacementBase.LateUpdate guard.");
			}
			else
			{
				logger.LogWarning((object)"Could not find BodyReplacementBase.LateUpdate.");
			}
			MethodInfo methodInfo5 = AccessTools.Method(typeof(MoreCompanyCosmeticManager), "UpdateModelReplacement", (Type[])null, (Type[])null);
			if (methodInfo5 != null)
			{
				harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(DisableCosmeticsOnModelReplacementPatch), "PrefixUpdateModelReplacement", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(DisableCosmeticsOnModelReplacementPatch), "Finalizer", (Type[])null), (HarmonyMethod)null);
				logger.LogInfo((object)"Patched MoreCompanyCosmeticManager.UpdateModelReplacement to disable cosmetics on model replacements.");
			}
			else
			{
				logger.LogWarning((object)"Could not find MoreCompanyCosmeticManager.UpdateModelReplacement.");
			}
			MethodInfo methodInfo6 = AccessTools.Method(typeof(MoreCompanyCosmeticManager), "SafeRenderCosmetics", (Type[])null, (Type[])null);
			if (methodInfo6 != null)
			{
				harmony.Patch((MethodBase)methodInfo6, new HarmonyMethod(typeof(DisableCosmeticsOnModelReplacementPatch), "PrefixRenderCosmetics", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(DisableCosmeticsOnModelReplacementPatch), "Finalizer", (Type[])null), (HarmonyMethod)null);
				logger.LogInfo((object)"Patched MoreCompanyCosmeticManager.SafeRenderCosmetics.");
			}
			else
			{
				logger.LogWarning((object)"Could not find MoreCompanyCosmeticManager.SafeRenderCosmetics.");
			}
			MethodInfo methodInfo7 = AccessTools.Method(typeof(MoreCompanyCosmeticManager), "DangerousRenderCosmetics", (Type[])null, (Type[])null);
			if (methodInfo7 != null)
			{
				harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(typeof(DisableCosmeticsOnModelReplacementPatch), "PrefixRenderCosmetics", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(DisableCosmeticsOnModelReplacementPatch), "Finalizer", (Type[])null), (HarmonyMethod)null);
				logger.LogInfo((object)"Patched MoreCompanyCosmeticManager.DangerousRenderCosmetics.");
			}
			else
			{
				logger.LogWarning((object)"Could not find MoreCompanyCosmeticManager.DangerousRenderCosmetics.");
			}
		}
	}
	internal static class SafeHeldObjectPatch
	{
		public static void LateUpdatePatch(ref GrabbableObject __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0076: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00a5: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null || (Object)__instance.parentObject == (Object)null || (Object)__instance.playerHeldBy == (Object)null)
			{
				return;
			}
			PlayerControllerB playerHeldBy = __instance.playerHeldBy;
			if (playerHeldBy.ItemSlots == null)
			{
				return;
			}
			int currentItemSlot = playerHeldBy.currentItemSlot;
			if (currentItemSlot >= 0 && currentItemSlot < playerHeldBy.ItemSlots.Length && !((Object)playerHeldBy.ItemSlots[currentItemSlot] != (Object)__instance))
			{
				BodyReplacementBase component = ((Component)playerHeldBy).gameObject.GetComponent<BodyReplacementBase>();
				if ((Object)(object)component != (Object)null && (Object)component.heldItem != (Object)__instance)
				{
					component.heldItem = __instance;
				}
			}
		}
	}
	internal static class SafeBodyReplacementLateUpdatePatch
	{
		private static int _logCount;

		public static bool Prefix(BodyReplacementBase __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null)
			{
				return false;
			}
			if ((Object)__instance == (Object)null)
			{
				return false;
			}
			try
			{
				RunSafeLateUpdate(__instance);
			}
			catch (Exception ex)
			{
				if (_logCount < 10)
				{
					_logCount++;
					ModelReplacementAPI.Instance.Logger.LogWarning((object)("[Hotfix] Safe BodyReplacementBase.LateUpdate failed: " + ex));
				}
			}
			return false;
		}

		public static Exception Finalizer(Exception __exception)
		{
			return null;
		}

		private static void RunSafeLateUpdate(BodyReplacementBase body)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			if ((Object)(object)body.controller == (Object)null)
			{
				return;
			}
			GameObject val = null;
			try
			{
				if ((Object)(object)body.controller.deadBody != (Object)null)
				{
					val = ((Component)body.controller.deadBody).gameObject;
				}
			}
			catch
			{
				val = null;
			}
			if ((Object)body.replacementDeadBody != (Object)null && (Object)val == (Object)null)
			{
				body.cosmeticAvatar = body.avatar;
				Object.Destroy((Object)(object)body.replacementDeadBody);
				body.replacementDeadBody = null;
			}
			if ((Object)val != (Object)null && !val.activeInHierarchy && (Object)body.replacementDeadBody != (Object)null)
			{
				body.replacementDeadBody.SetActive(false);
			}
			TryRun("avatar.Update", delegate
			{
				if (body.avatar != null)
				{
					body.avatar.Update();
				}
			});
			TryRun("shadowAvatar.Update", delegate
			{
				if (body.shadowAvatar != null)
				{
					body.shadowAvatar.Update();
				}
			});
			TryRun("ragdollAvatar.Update", delegate
			{
				if (body.ragdollAvatar != null)
				{
					body.ragdollAvatar.Update();
				}
			});
			TryRun("viewModelAvatar.Update", delegate
			{
				if (body.viewModelAvatar != null)
				{
					body.viewModelAvatar.Update();
				}
			});
			TryRun("cosmeticManager.UpdateModelReplacement", delegate
			{
				if ((Object)(object)body.cosmeticManager == (Object)null)
				{
					body.cosmeticManager = ((Component)body).GetComponent<MoreCompanyCosmeticManager>();
				}
				if ((Object)(object)body.cosmeticManager != (Object)null)
				{
					((ManagerBase)body.cosmeticManager).UpdateModelReplacement();
				}
			});
			TryRun("nameTagCollider bounds", delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: 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)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)body.replacementModel == (Object)null))
				{
					if ((Object)(object)body.nameTagCollider == (Object)null)
					{
						CreateNameTagCollider(body);
					}
					if (!((Object)(object)body.nameTagCollider == (Object)null))
					{
						Bounds val2 = CalculateBounds(body.replacementModel);
						body.nameTagCollider.center = ((Bounds)(ref val2)).center;
						body.nameTagCollider.size = ((Bounds)(ref val2)).size;
					}
				}
			});
		}

		private static void TryRun(string name, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				if (_logCount < 20)
				{
					_logCount++;
					ModelReplacementAPI.Instance.Logger.LogWarning((object)("[Hotfix] Skipped broken LateUpdate block: " + name + "\n" + ex.GetType().Name + ": " + ex.Message));
				}
			}
		}

		private static void CreateNameTagCollider(BodyReplacementBase body)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (!((Object)body.replacementModel == (Object)null))
			{
				GameObject val = new GameObject("MRAPINameCollider_Hotfix");
				val.layer = 23;
				val.transform.SetParent(body.replacementModel.transform, false);
				body.nameTagCollider = val.AddComponent<BoxCollider>();
				((Collider)body.nameTagCollider).isTrigger = true;
				RaycastTarget obj = val.AddComponent<RaycastTarget>();
				obj.controller = body.controller;
				obj.bodyReplacement = body;
				obj.modelObj = body.replacementModel;
			}
		}

		private static Bounds CalculateBounds(GameObject model)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				return new Bounds(Vector3.zero, Vector3.one);
			}
			Bounds bounds = componentsInChildren[0].bounds;
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
				}
			}
			return new Bounds(model.transform.InverseTransformPoint(((Bounds)(ref bounds)).center), ((Bounds)(ref bounds)).size);
		}
	}
	internal static class DisableCosmeticsOnModelReplacementPatch
	{
		private static int _logCount;

		public static bool PrefixUpdateModelReplacement(MoreCompanyCosmeticManager __instance)
		{
			DisableCosmetics(__instance);
			return false;
		}

		public static bool PrefixRenderCosmetics(MoreCompanyCosmeticManager __instance, bool useAvatarTransforms)
		{
			if (useAvatarTransforms)
			{
				DisableCosmetics(__instance);
				return false;
			}
			return true;
		}

		public static Exception Finalizer(Exception __exception)
		{
			return null;
		}

		private static void DisableCosmetics(MoreCompanyCosmeticManager manager)
		{
			if ((Object)(object)manager == (Object)null)
			{
				return;
			}
			try
			{
				DisableCachedCosmeticInstances(manager);
				DisableSpawnedCosmeticsOnPlayer(manager);
			}
			catch (Exception ex)
			{
				if (_logCount < 10)
				{
					_logCount++;
					ModelReplacementAPI.Instance.Logger.LogWarning((object)("[Hotfix] Failed to disable MoreCompany cosmetics: " + ex.GetType().Name + ": " + ex.Message));
				}
			}
		}

		private static void DisableCachedCosmeticInstances(MoreCompanyCosmeticManager manager)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			if (!(AccessTools.Field(typeof(MoreCompanyCosmeticManager), "cosmeticInstances")?.GetValue(manager) is IEnumerable enumerable))
			{
				return;
			}
			foreach (object item in enumerable)
			{
				if (item == null)
				{
					continue;
				}
				FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "cosmetic");
				if (!(fieldInfo == null))
				{
					object? value = fieldInfo.GetValue(item);
					GameObject val = (GameObject)((value is GameObject) ? value : null);
					if ((Object)val != (Object)null)
					{
						val.SetActive(false);
					}
				}
			}
		}

		private static void DisableSpawnedCosmeticsOnPlayer(MoreCompanyCosmeticManager manager)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			if ((Object)manager == (Object)null)
			{
				return;
			}
			GameObject gameObject = ((Component)manager).gameObject;
			PlayerControllerB val = ((Component)manager).GetComponent<PlayerControllerB>();
			if ((Object)val == (Object)null)
			{
				val = ((Component)manager).GetComponentInParent<PlayerControllerB>();
			}
			if ((Object)val == (Object)null)
			{
				val = ((Component)manager).GetComponentInChildren<PlayerControllerB>(true);
			}
			if ((Object)val != (Object)null)
			{
				gameObject = ((Component)val).gameObject;
			}
			MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if ((Object)val2 == (Object)null)
				{
					continue;
				}
				Type type = ((object)val2).GetType();
				if ((type.Name != "CosmeticApplication" && type.FullName != "MoreCompany.Cosmetics.CosmeticApplication") || !((AccessTools.Field(type, "spawnedCosmetics")?.GetValue(val2) ?? AccessTools.Property(type, "spawnedCosmetics")?.GetValue(val2, null)) is IEnumerable enumerable))
				{
					continue;
				}
				foreach (object item in enumerable)
				{
					Component val3 = (Component)((item is Component) ? item : null);
					if (val3 != null)
					{
						val3.gameObject.SetActive(false);
					}
				}
			}
		}
	}
}