Decompiled source of Dizzy Mod v1.1.0

BepInEx/plugins/RepoHammerSkin/RepoHammerSkin.dll

Decompiled 3 days ago
using System;
using System.Collections;
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.Configuration;
using Microsoft.CodeAnalysis;
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("RepoHammerSkin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.0.0")]
[assembly: AssemblyInformationalVersion("0.5.0")]
[assembly: AssemblyProduct("RepoHammerSkin")]
[assembly: AssemblyTitle("RepoHammerSkin")]
[assembly: AssemblyVersion("0.5.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 RepoHammerSkin
{
	[BepInPlugin("BrandonMarian.RepoHammerSkin", "REPO Hammer Skin", "0.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class TargetRecord
		{
			public GameObject Prefab { get; }

			public HashSet<string> Origins { get; } = new HashSet<string>(StringComparer.Ordinal);

			public TargetRecord(GameObject prefab)
			{
				Prefab = prefab;
			}
		}

		private sealed class VisualSlot
		{
			public Renderer Renderer { get; }

			public MeshRenderer? MeshRenderer { get; }

			public MeshFilter? MeshFilter { get; }

			public SkinnedMeshRenderer? SkinnedRenderer { get; }

			public Mesh Mesh { get; }

			public Transform Transform => ((Component)Renderer).transform;

			public string Kind { get; }

			public string Path { get; }

			public VisualSlot(GameObject root, Renderer renderer, MeshFilter? meshFilter, SkinnedMeshRenderer? skinnedRenderer, Mesh mesh, string kind)
			{
				Renderer = renderer;
				MeshRenderer = (MeshRenderer?)(object)((renderer is MeshRenderer) ? renderer : null);
				MeshFilter = meshFilter;
				SkinnedRenderer = skinnedRenderer;
				Mesh = mesh;
				Kind = kind;
				Path = GetPath(root.transform, ((Component)renderer).transform);
			}

			private static string GetPath(Transform root, Transform current)
			{
				Stack<string> stack = new Stack<string>();
				Transform val = current;
				while ((Object)(object)val != (Object)null)
				{
					stack.Push(((Object)val).name);
					if ((Object)(object)val == (Object)(object)root)
					{
						break;
					}
					val = val.parent;
				}
				return string.Join("/", stack);
			}
		}

		public const string PluginGuid = "BrandonMarian.RepoHammerSkin";

		public const string PluginName = "REPO Hammer Skin";

		public const string PluginVersion = "0.5.0";

		public const string LethalThingsGuid = "evaisa.lethalthings";

		public const string LethalLibGuid = "evaisa.lethallib";

		private const string BundleFileName = "repohammerskin";

		private const string DefaultPrefabPath = "Assets/RepoHammerSkin/RepoHammer.prefab";

		private const string ToyHammerTypeName = "LethalThings.ToyHammer";

		private const string PreferredTargetName = "Hammer";

		private AssetBundle? _assetBundle;

		private GameObject? _replacementPrefab;

		private VisualSlot? _replacementVisual;

		private ConfigEntry<string> _prefabPath;

		private ConfigEntry<bool> _hideOtherOriginalRenderers;

		private ConfigEntry<bool> _applyReplacementPrefabTransform;

		private ConfigEntry<float> _positionX;

		private ConfigEntry<float> _positionY;

		private ConfigEntry<float> _positionZ;

		private ConfigEntry<float> _rotationX;

		private ConfigEntry<float> _rotationY;

		private ConfigEntry<float> _rotationZ;

		private ConfigEntry<float> _scaleX;

		private ConfigEntry<float> _scaleY;

		private ConfigEntry<float> _scaleZ;

		private ConfigEntry<int> _hammerHitForce;

		private ConfigEntry<float> _hammerHitChancePercent;

		private void Awake()
		{
			BindConfiguration();
			if (!LoadReplacementAssets())
			{
				return;
			}
			Dictionary<int, TargetRecord> dictionary = new Dictionary<int, TargetRecord>();
			CollectLethalThingsContentPrefabs(dictionary);
			CollectLethalLibItemPrefabs(dictionary);
			CollectLethalLibNetworkPrefabs(dictionary);
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Discovered {dictionary.Count} distinct registered Toy Hammer prefab instance(s).");
			if (dictionary.Count == 0)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"No registered prefab containing component type 'LethalThings.ToyHammer' was found. The reflection diagnostics above identify which registry was unavailable.");
				return;
			}
			int num = 0;
			foreach (TargetRecord item in dictionary.Values.OrderBy((TargetRecord record) => ((Object)record.Prefab).GetInstanceID()))
			{
				if (PatchToyHammerPrefab(item))
				{
					num++;
				}
			}
			if (num != dictionary.Count)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Only patched {num} of {dictionary.Count} discovered Toy Hammer prefab instance(s).");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)($"Patched all {num} registered Toy Hammer prefab instance(s), including LethalLib clones. " + "Visual and gameplay settings are applied directly to the registered prefabs."));
			}
		}

		private void BindConfiguration()
		{
			_prefabPath = ((BaseUnityPlugin)this).Config.Bind<string>("Asset", "PrefabPath", "Assets/RepoHammerSkin/RepoHammer.prefab", "Path of the replacement prefab inside the AssetBundle.");
			_hideOtherOriginalRenderers = ((BaseUnityPlugin)this).Config.Bind<bool>("Replacement", "HideOriginalRenderers", true, "Disable every original Toy Hammer renderer except the renderer receiving the replacement mesh.");
			_applyReplacementPrefabTransform = ((BaseUnityPlugin)this).Config.Bind<bool>("Replacement", "AttachToOriginalRendererTransform", true, "Apply the replacement prefab's internal model transform on top of the original Hammer renderer alignment.");
			_positionX = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "PositionX", 0f, "Additional local X offset.");
			_positionY = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "PositionY", 0f, "Additional local Y offset.");
			_positionZ = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "PositionZ", 0f, "Additional local Z offset.");
			_rotationX = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "RotationX", 0f, "Additional local X rotation in degrees.");
			_rotationY = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "RotationY", 0f, "Additional local Y rotation in degrees.");
			_rotationZ = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "RotationZ", 0f, "Additional local Z rotation in degrees.");
			_scaleX = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "ScaleX", 1f, "Additional local X scale.");
			_scaleY = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "ScaleY", 1f, "Additional local Y scale.");
			_scaleZ = ((BaseUnityPlugin)this).Config.Bind<float>("Transform", "ScaleZ", 1f, "Additional local Z scale.");
			_hammerHitForce = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "HammerHitForce", 2, "Force passed to IHittable.Hit when the Toy Hammer deals damage. LethalThings defaults to 1.");
			_hammerHitChancePercent = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "HammerHitChancePercent", 100f, "Chance from 0 to 100 that a valid Toy Hammer contact deals damage. LethalThings defaults to 1.");
		}

		private bool LoadReplacementAssets()
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath, "repohammerskin");
			if (!File.Exists(text))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("AssetBundle not found: " + text));
				return false;
			}
			_assetBundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_assetBundle == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Unity could not load AssetBundle: " + text));
				return false;
			}
			_replacementPrefab = _assetBundle.LoadAsset<GameObject>(_prefabPath.Value) ?? _assetBundle.LoadAllAssets<GameObject>().FirstOrDefault();
			if ((Object)(object)_replacementPrefab == (Object)null)
			{
				string text2 = string.Join(", ", _assetBundle.GetAllAssetNames());
				((BaseUnityPlugin)this).Logger.LogError((object)("No GameObject prefab could be loaded. Assets found: " + text2));
				return false;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded replacement prefab '" + ((Object)_replacementPrefab).name + "' from '" + _prefabPath.Value + "'."));
			List<VisualSlot> slots = FindVisualSlots(_replacementPrefab);
			LogVisualSlots("Replacement prefab", slots);
			_replacementVisual = SelectLargestSlot(slots);
			if (_replacementVisual == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"The replacement prefab contains no usable mesh renderer.");
				return false;
			}
			return true;
		}

		private void CollectLethalThingsContentPrefabs(Dictionary<int, TargetRecord> targets)
		{
			if (!((Type.GetType("LethalThings.Content, LethalThings", throwOnError: false)?.GetField("Prefabs", BindingFlags.Static | BindingFlags.Public))?.GetValue(null) is IDictionary dictionary))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not read LethalThings.Content.Prefabs.");
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (DictionaryEntry item in dictionary)
			{
				object? value = item.Value;
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if (val != null)
				{
					num++;
					string text = item.Key?.ToString() ?? "<null>";
					if (TryAddToyHammerTarget(targets, val, "LethalThings.Content.Prefabs['" + text + "']"))
					{
						num2++;
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"LethalThings.Content.Prefabs: inspected {num}, matched {num2} Toy Hammer reference(s).");
		}

		private void CollectLethalLibItemPrefabs(Dictionary<int, TargetRecord> targets)
		{
			Type type = Type.GetType("LethalLib.Modules.Items, LethalLib", throwOnError: false);
			if (type == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not resolve LethalLib.Modules.Items.");
				return;
			}
			CollectItemRegistryField(type, "scrapItems", targets);
			CollectItemRegistryField(type, "shopItems", targets);
			CollectItemRegistryField(type, "plainItems", targets);
		}

		private void CollectItemRegistryField(Type itemsType, string fieldName, Dictionary<int, TargetRecord> targets)
		{
			if (!(itemsType.GetField(fieldName, BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is IEnumerable enumerable))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read LethalLib.Modules.Items." + fieldName + "."));
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (object item in enumerable)
			{
				if (item == null)
				{
					continue;
				}
				num++;
				Type type = item.GetType();
				string[] array = new string[2] { "item", "origItem" };
				foreach (string text in array)
				{
					object? obj = type.GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(item);
					Item val = (Item)((obj is Item) ? obj : null);
					if (val != null && !((Object)(object)val.spawnPrefab == (Object)null))
					{
						string text2 = (string.IsNullOrEmpty(val.itemName) ? ((Object)val).name : val.itemName);
						string origin = "LethalLib.Items." + fieldName + "." + text + " item='" + text2 + "'";
						if (TryAddToyHammerTarget(targets, val.spawnPrefab, origin))
						{
							num2++;
						}
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"LethalLib.Items.{fieldName}: inspected {num} record(s), matched {num2} Toy Hammer reference(s).");
		}

		private void CollectLethalLibNetworkPrefabs(Dictionary<int, TargetRecord> targets)
		{
			if (!((Type.GetType("LethalLib.Modules.NetworkPrefabs, LethalLib", throwOnError: false)?.GetField("_networkPrefabs", BindingFlags.Static | BindingFlags.NonPublic))?.GetValue(null) is IEnumerable enumerable))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not read LethalLib.Modules.NetworkPrefabs._networkPrefabs.");
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (object item in enumerable)
			{
				GameObject val = (GameObject)((item is GameObject) ? item : null);
				if (val != null)
				{
					num++;
					if (TryAddToyHammerTarget(targets, val, "LethalLib.NetworkPrefabs._networkPrefabs"))
					{
						num2++;
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"LethalLib.NetworkPrefabs: inspected {num}, matched {num2} Toy Hammer reference(s).");
		}

		private bool TryAddToyHammerTarget(Dictionary<int, TargetRecord> targets, GameObject prefab, string origin)
		{
			if (!HasToyHammerComponent(prefab))
			{
				return false;
			}
			int instanceID = ((Object)prefab).GetInstanceID();
			if (!targets.TryGetValue(instanceID, out TargetRecord value))
			{
				value = new TargetRecord(prefab);
				targets.Add(instanceID, value);
			}
			value.Origins.Add(origin);
			return true;
		}

		private static bool HasToyHammerComponent(GameObject prefab)
		{
			return (Object)(object)FindToyHammerComponent(prefab) != (Object)null;
		}

		private static Component? FindToyHammerComponent(GameObject prefab)
		{
			Component[] components = prefab.GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val != (Object)null && string.Equals(((object)val).GetType().FullName, "LethalThings.ToyHammer", StringComparison.Ordinal))
				{
					return val;
				}
			}
			return null;
		}

		private bool PatchToyHammerPrefab(TargetRecord record)
		{
			//IL_0070: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_replacementPrefab == (Object)null || _replacementVisual == null)
			{
				return false;
			}
			GameObject prefab = record.Prefab;
			if (!ConfigureToyHammerGameplay(prefab))
			{
				return false;
			}
			List<VisualSlot> list = FindVisualSlots(prefab);
			VisualSlot visualSlot = SelectCompatibleTarget(list, _replacementVisual);
			((BaseUnityPlugin)this).Logger.LogInfo((object)($"Patching Toy Hammer prefab instance {((Object)prefab).GetInstanceID()} " + $"name='{((Object)prefab).name}', hideFlags={((Object)prefab).hideFlags}, " + "origins=[" + string.Join("; ", record.Origins.OrderBy((string origin) => origin)) + "]."));
			LogVisualSlots($"Target prefab {((Object)prefab).GetInstanceID()}", list);
			if (visualSlot == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"No compatible renderer exists on Toy Hammer prefab instance {((Object)prefab).GetInstanceID()}.");
				return false;
			}
			string name = ((Object)visualSlot.Mesh).name;
			Matrix4x4 localToWorldMatrix = visualSlot.Transform.localToWorldMatrix;
			if (!CopyMeshAndMaterials(_replacementVisual, visualSlot))
			{
				return false;
			}
			if (_applyReplacementPrefabTransform.Value)
			{
				Matrix4x4 val = _replacementPrefab.transform.worldToLocalMatrix * _replacementVisual.Transform.localToWorldMatrix;
				Matrix4x4 val2 = Matrix4x4.TRS(new Vector3(_positionX.Value, _positionY.Value, _positionZ.Value), Quaternion.Euler(_rotationX.Value, _rotationY.Value, _rotationZ.Value), new Vector3(_scaleX.Value, _scaleY.Value, _scaleZ.Value));
				Matrix4x4 val3 = localToWorldMatrix * val2 * val;
				Matrix4x4 matrix = (((Object)(object)visualSlot.Transform.parent != (Object)null) ? (visualSlot.Transform.parent.worldToLocalMatrix * val3) : val3);
				ApplyLocalMatrix(visualSlot.Transform, matrix);
			}
			foreach (VisualSlot item in list)
			{
				item.Renderer.enabled = !_hideOtherOriginalRenderers.Value || item == visualSlot;
			}
			visualSlot.Renderer.enabled = true;
			object obj;
			if (!((Object)(object)visualSlot.MeshFilter != (Object)null))
			{
				SkinnedMeshRenderer? skinnedRenderer = visualSlot.SkinnedRenderer;
				obj = ((skinnedRenderer != null) ? skinnedRenderer.sharedMesh : null);
			}
			else
			{
				obj = visualSlot.MeshFilter.sharedMesh;
			}
			Mesh val4 = (Mesh)obj;
			bool flag = val4 == _replacementVisual.Mesh;
			((BaseUnityPlugin)this).Logger.LogInfo((object)($"Patched instance {((Object)prefab).GetInstanceID()}: target='{visualSlot.Path}', " + "oldMesh='" + name + "', newMesh='" + (((val4 != null) ? ((Object)val4).name : null) ?? "<null>") + "', " + $"verified={flag}, localPosition={visualSlot.Transform.localPosition}, " + $"localRotation={visualSlot.Transform.localEulerAngles}, localScale={visualSlot.Transform.localScale}."));
			return flag;
		}

		private bool ConfigureToyHammerGameplay(GameObject targetPrefab)
		{
			Component val = FindToyHammerComponent(targetPrefab);
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Toy Hammer component disappeared from prefab instance {((Object)targetPrefab).GetInstanceID()} before gameplay configuration.");
				return false;
			}
			Type type = ((object)val).GetType();
			FieldInfo field = type.GetField("hammerHitForce", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo field2 = type.GetField("hammerHitPercentage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null || field2 == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not resolve Toy Hammer gameplay fields on '" + type.FullName + "'. " + $"hammerHitForce found={field != null}, hammerHitPercentage found={field2 != null}."));
				return false;
			}
			if (field.FieldType != typeof(int) || field2.FieldType != typeof(float))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Unexpected Toy Hammer field types: hammerHitForce=" + field.FieldType.FullName + ", hammerHitPercentage=" + field2.FieldType.FullName + "."));
				return false;
			}
			int num = Mathf.Clamp(_hammerHitForce.Value, 0, 100);
			float num2 = Mathf.Clamp(_hammerHitChancePercent.Value, 0f, 100f);
			int num3 = (int)(field.GetValue(val) ?? ((object)0));
			float num4 = (float)(field2.GetValue(val) ?? ((object)0f));
			field.SetValue(val, num);
			field2.SetValue(val, num2);
			int num5 = (int)(field.GetValue(val) ?? ((object)(-1)));
			float num6 = (float)(field2.GetValue(val) ?? ((object)(-1f)));
			bool flag = num5 == num && Mathf.Approximately(num6, num2);
			((BaseUnityPlugin)this).Logger.LogInfo((object)($"Configured Toy Hammer gameplay on instance {((Object)targetPrefab).GetInstanceID()}: " + $"force {num3} -> {num5}, hit chance {num4:0.###}% -> {num6:0.###}%, " + $"verified={flag}."));
			return flag;
		}

		private bool CopyMeshAndMaterials(VisualSlot source, VisualSlot target)
		{
			if ((Object)(object)source.MeshFilter != (Object)null && (Object)(object)target.MeshFilter != (Object)null && (Object)(object)source.MeshRenderer != (Object)null && (Object)(object)target.MeshRenderer != (Object)null)
			{
				target.MeshFilter.sharedMesh = source.MeshFilter.sharedMesh;
				((Renderer)target.MeshRenderer).sharedMaterials = ((Renderer)source.MeshRenderer).sharedMaterials;
				return true;
			}
			if ((Object)(object)source.SkinnedRenderer != (Object)null && (Object)(object)target.SkinnedRenderer != (Object)null)
			{
				target.SkinnedRenderer.sharedMesh = source.SkinnedRenderer.sharedMesh;
				((Renderer)target.SkinnedRenderer).sharedMaterials = ((Renderer)source.SkinnedRenderer).sharedMaterials;
				return true;
			}
			((BaseUnityPlugin)this).Logger.LogError((object)("Renderer type mismatch: replacement=" + source.Kind + ", target=" + target.Kind + "."));
			return false;
		}

		private static List<VisualSlot> FindVisualSlots(GameObject root)
		{
			List<VisualSlot> list = new List<VisualSlot>();
			MeshRenderer[] componentsInChildren = root.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				if (!((Object)(object)((component != null) ? component.sharedMesh : null) == (Object)null))
				{
					list.Add(new VisualSlot(root, (Renderer)(object)val, component, null, component.sharedMesh, "MeshRenderer"));
				}
			}
			SkinnedMeshRenderer[] componentsInChildren2 = root.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2.sharedMesh == (Object)null))
				{
					list.Add(new VisualSlot(root, (Renderer)(object)val2, null, val2, val2.sharedMesh, "SkinnedMeshRenderer"));
				}
			}
			return list;
		}

		private static VisualSlot? SelectLargestSlot(List<VisualSlot> slots)
		{
			return slots.OrderByDescending((VisualSlot slot) => slot.Mesh.vertexCount).FirstOrDefault();
		}

		private static VisualSlot? SelectCompatibleTarget(List<VisualSlot> targetSlots, VisualSlot source)
		{
			return (from slot in ((Object)(object)source.MeshFilter != (Object)null) ? targetSlots.Where((VisualSlot slot) => (Object)(object)slot.MeshFilter != (Object)null) : targetSlots.Where((VisualSlot slot) => (Object)(object)slot.SkinnedRenderer != (Object)null)
				orderby ((Object)slot.Transform).name.Equals("Hammer", StringComparison.OrdinalIgnoreCase) ? 1 : 0 descending, slot.Mesh.vertexCount descending
				select slot).FirstOrDefault();
		}

		private void LogVisualSlots(string label, List<VisualSlot> slots)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"{label}: {slots.Count} usable visual renderer(s).");
			foreach (VisualSlot slot in slots)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("  [" + slot.Kind + "] path='" + slot.Path + "', mesh='" + ((Object)slot.Mesh).name + "', " + $"vertices={slot.Mesh.vertexCount}, materials={slot.Renderer.sharedMaterials.Length}, " + $"active={((Component)slot.Renderer).gameObject.activeSelf}, enabled={slot.Renderer.enabled}."));
			}
		}

		private static void ApplyLocalMatrix(Transform transform, Matrix4x4 matrix)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = default(Vector3);
			((Vector3)(ref localPosition))..ctor(matrix.m03, matrix.m13, matrix.m23);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(matrix.m00, matrix.m10, matrix.m20);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(matrix.m01, matrix.m11, matrix.m21);
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(matrix.m02, matrix.m12, matrix.m22);
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(((Vector3)(ref val)).magnitude, ((Vector3)(ref val2)).magnitude, ((Vector3)(ref val3)).magnitude);
			if (val4.x < 1E-06f || val4.y < 1E-06f || val4.z < 1E-06f)
			{
				throw new InvalidOperationException($"Cannot decompose transform matrix with scale {val4}.");
			}
			if (Vector3.Dot(Vector3.Cross(val, val2), val3) < 0f)
			{
				val4.x = 0f - val4.x;
				val = -val;
			}
			Quaternion localRotation = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, ((Vector3)(ref val2)).normalized);
			transform.localPosition = localPosition;
			transform.localRotation = localRotation;
			transform.localScale = val4;
		}
	}
}