Decompiled source of MinecraftStrongholdLevelFix v0.3.0

patchers/MinecraftStrongholdLevelFix.Patcher.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;

[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("MinecraftStrongholdLevelFix.Patcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MinecraftStrongholdLevelFix.Patcher")]
[assembly: AssemblyTitle("MinecraftStrongholdLevelFix.Patcher")]
[assembly: AssemblyVersion("1.0.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 MinecraftStrongholdLevelFix.Patcher
{
	public static class ValuableVolumeVisualizerPatcher
	{
		public static IEnumerable<string> TargetDLLs { get; } = new string[1] { "Assembly-CSharp.dll" };

		public static void Patch(AssemblyDefinition assembly)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			ModuleDefinition mainModule = assembly.MainModule;
			if (mainModule.GetType("ValuableVolumeVisualizer") == null)
			{
				AssemblyNameReference val = ((IEnumerable<AssemblyNameReference>)mainModule.AssemblyReferences).First((AssemblyNameReference reference) => reference.Name == "UnityEngine.CoreModule");
				TypeReference val2 = new TypeReference("UnityEngine", "MonoBehaviour", mainModule, (IMetadataScope)(object)val);
				TypeDefinition val3 = new TypeDefinition(string.Empty, "ValuableVolumeVisualizer", (TypeAttributes)1048577, val2);
				MethodDefinition val4 = new MethodDefinition(".ctor", (MethodAttributes)6150, mainModule.TypeSystem.Void);
				MethodReference val5 = new MethodReference(".ctor", mainModule.TypeSystem.Void, val2)
				{
					HasThis = true
				};
				val4.Body.GetILProcessor().Append(Instruction.Create(OpCodes.Ldarg_0));
				val4.Body.GetILProcessor().Append(Instruction.Create(OpCodes.Call, val5));
				val4.Body.GetILProcessor().Append(Instruction.Create(OpCodes.Ret));
				val3.Methods.Add(val4);
				mainModule.Types.Add(val3);
			}
		}
	}
}

plugins/MinecraftStrongholdLevelFix.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib;
using REPOLib.Modules;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("nezzy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyInformationalVersion("0.3.0")]
[assembly: AssemblyProduct("MinecraftStrongholdLevelFix")]
[assembly: AssemblyTitle("MinecraftStrongholdLevelFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
[module: UnverifiableCode]
[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 MinecraftStrongholdLevelFix
{
	internal static class GoldenAppleLocalization
	{
		internal const string DisplayName = "Golden Apple";

		internal static bool IsAffectedPrefab(string name)
		{
			return name.StartsWith("MC Item Golden Apple", StringComparison.Ordinal);
		}
	}
	public sealed class MinecartSpawnIdentity : IEquatable<MinecartSpawnIdentity>
	{
		public int XMillimeters { get; }

		public int YMillimeters { get; }

		public int ZMillimeters { get; }

		public int Occurrence { get; }

		private MinecartSpawnIdentity(int xMillimeters, int yMillimeters, int zMillimeters, int occurrence)
		{
			XMillimeters = xMillimeters;
			YMillimeters = yMillimeters;
			ZMillimeters = zMillimeters;
			Occurrence = occurrence;
		}

		public static MinecartSpawnIdentity FromPosition(float x, float y, float z, int occurrence)
		{
			return new MinecartSpawnIdentity(ToMillimeters(x), ToMillimeters(y), ToMillimeters(z), occurrence);
		}

		public bool Equals(MinecartSpawnIdentity? other)
		{
			if (other != null && XMillimeters == other.XMillimeters && YMillimeters == other.YMillimeters && ZMillimeters == other.ZMillimeters)
			{
				return Occurrence == other.Occurrence;
			}
			return false;
		}

		public override bool Equals(object? obj)
		{
			return Equals(obj as MinecartSpawnIdentity);
		}

		public override int GetHashCode()
		{
			int num = 17;
			num = num * 31 + XMillimeters;
			num = num * 31 + YMillimeters;
			num = num * 31 + ZMillimeters;
			return num * 31 + Occurrence;
		}

		public override string ToString()
		{
			return $"({(float)XMillimeters / 1000f:F3}, {(float)YMillimeters / 1000f:F3}, {(float)ZMillimeters / 1000f:F3}) #{Occurrence}";
		}

		public static bool operator ==(MinecartSpawnIdentity? left, MinecartSpawnIdentity? right)
		{
			return object.Equals(left, right);
		}

		public static bool operator !=(MinecartSpawnIdentity? left, MinecartSpawnIdentity? right)
		{
			return !object.Equals(left, right);
		}

		private static int ToMillimeters(float coordinate)
		{
			return (int)Math.Round(coordinate * 1000f, MidpointRounding.AwayFromZero);
		}
	}
	public sealed class MinecartSpawnPolicy
	{
		private readonly HashSet<MinecartSpawnIdentity> claimed = new HashSet<MinecartSpawnIdentity>();

		public bool TryClaim(MinecartSpawnIdentity identity, bool isHost)
		{
			if (isHost)
			{
				return claimed.Add(identity);
			}
			return false;
		}

		public void ResetForLevelLoad()
		{
			claimed.Clear();
		}
	}
	[BepInPlugin("nezzy.MinecraftStrongholdLevelFix", "Minecraft Stronghold Level Fix", "0.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			MinecartReplacementAssets.Load(((BaseUnityPlugin)this).Info.Location);
			new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID).PatchAll();
		}

		internal static bool IsStrongholdLevel()
		{
			if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null)
			{
				return ((Object)RunManager.instance.levelCurrent).name.IndexOf("Stronghold", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		[Conditional("DEBUG")]
		internal static void DebugLog(string message)
		{
			Log.LogInfo((object)message);
		}
	}
	internal sealed class MinecartReplacementMarker : MonoBehaviour
	{
	}
	internal static class MinecartReplacementAssets
	{
		internal const string PrefabId = "nezzy.MinecartFix";

		internal const string PrefabAssetName = "StrongholdMinecartReplacement";

		private static bool loadRequested;

		internal static void Load(string pluginLocation)
		{
			if (loadRequested)
			{
				return;
			}
			loadRequested = true;
			string path = Path.GetDirectoryName(pluginLocation) ?? string.Empty;
			string text = Path.Combine(path, "assets", "minecart", "StrongholdMinecartReplacement.bundle");
			if (!File.Exists(text))
			{
				string text2 = Path.Combine(path, "StrongholdMinecartReplacement.bundle");
				if (!File.Exists(text2))
				{
					Plugin.Log.LogError((object)("Minecart replacement bundle is missing at '" + text + "' or '" + text2 + "'. Spawned Minecarts will remain suppressed."));
					return;
				}
				text = text2;
			}
			BundleLoader.LoadBundle(text, (Action<AssetBundle>)delegate(AssetBundle bundle)
			{
				GameObject val = bundle.LoadAsset<GameObject>("StrongholdMinecartReplacement");
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogError((object)"Minecart replacement bundle does not contain prefab 'StrongholdMinecartReplacement'. Spawned Minecarts will remain suppressed.");
				}
				else if (!ValidateNativeComponents(val))
				{
					Plugin.Log.LogError((object)"Minecart replacement bundle is not a complete native Small Cart prefab.");
				}
				else
				{
					PrefabRef val2 = NetworkPrefabs.RegisterNetworkPrefab("nezzy.MinecartFix", val);
					if (val2 == null)
					{
						Plugin.Log.LogError((object)"Minecart replacement prefab 'StrongholdMinecartReplacement' could not be registered for networking. Spawned Minecarts will remain suppressed.");
					}
				}
			}, false);
		}

		internal static void ConfigureSpawnedReplacement(GameObject replacement)
		{
			if ((Object)(object)replacement.GetComponent<MinecartReplacementMarker>() == (Object)null)
			{
				replacement.AddComponent<MinecartReplacementMarker>();
			}
			if (!ValidateNativeComponents(replacement))
			{
				Plugin.Log.LogError((object)"Dedicated Minecart replacement is missing a native Small Cart component.");
			}
		}

		internal static bool IsReplacement(GameObject gameObject)
		{
			return ((Object)gameObject).name.StartsWith("StrongholdMinecartReplacement", StringComparison.Ordinal);
		}

		private static bool ValidateNativeComponents(GameObject prefab)
		{
			if ((Object)(object)prefab.GetComponent<PhotonView>() != (Object)null && (Object)(object)prefab.GetComponent<PhotonTransformView>() != (Object)null && (Object)(object)prefab.GetComponent<Rigidbody>() != (Object)null && (Object)(object)prefab.GetComponent<PhysGrabObject>() != (Object)null && (Object)(object)prefab.GetComponent<PhysGrabObjectImpactDetector>() != (Object)null && (Object)(object)prefab.GetComponent<PhysGrabCart>() != (Object)null && (Object)(object)prefab.GetComponent<PhysGrabObjectGrabArea>() != (Object)null && (Object)(object)prefab.GetComponent<ItemAttributes>() != (Object)null)
			{
				return (Object)(object)prefab.GetComponent<ItemEquippable>() != (Object)null;
			}
			return false;
		}
	}
	internal sealed class MinecartReplacementController : MonoBehaviour
	{
		private readonly MinecartSpawnPolicy spawnPolicy = new MinecartSpawnPolicy();

		private readonly Dictionary<MinecartSpawnIdentity, GameObject> suppressedMinecarts = new Dictionary<MinecartSpawnIdentity, GameObject>();

		private readonly Dictionary<string, int> positionOccurrences = new Dictionary<string, int>();

		private readonly HashSet<int> processedInstanceIds = new HashSet<int>();

		private const float UniqueVisualMatchDistanceSquared = 0.25f;

		internal static void Replace(GameObject legacyCart)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			MinecartReplacementController minecartReplacementController = Object.FindObjectOfType<MinecartReplacementController>();
			if ((Object)(object)minecartReplacementController == (Object)null)
			{
				minecartReplacementController = new GameObject("Stronghold Minecart Replacement").AddComponent<MinecartReplacementController>();
				Object.DontDestroyOnLoad((Object)(object)((Component)minecartReplacementController).gameObject);
			}
			minecartReplacementController.HandleLegacyMinecart(legacyCart);
		}

		internal static void ResetForLevelLoad()
		{
			MinecartReplacementController minecartReplacementController = Object.FindObjectOfType<MinecartReplacementController>();
			if (!((Object)(object)minecartReplacementController == (Object)null))
			{
				minecartReplacementController.spawnPolicy.ResetForLevelLoad();
				minecartReplacementController.suppressedMinecarts.Clear();
				minecartReplacementController.positionOccurrences.Clear();
				minecartReplacementController.processedInstanceIds.Clear();
			}
		}

		internal static void AttachIncomingReplacement(GameObject replacement)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			MinecartReplacementAssets.ConfigureSpawnedReplacement(replacement);
			if (!TryGetReplacementIdentity(replacement, out MinecartSpawnIdentity identity))
			{
				Plugin.Log.LogError((object)"Dedicated Minecart replacement was spawned without valid host identity data; its local Minecart visual cannot be attached.");
				return;
			}
			MinecartReplacementController minecartReplacementController = Object.FindObjectOfType<MinecartReplacementController>();
			if ((Object)(object)minecartReplacementController == (Object)null)
			{
				minecartReplacementController = new GameObject("Stronghold Minecart Replacement").AddComponent<MinecartReplacementController>();
				Object.DontDestroyOnLoad((Object)(object)((Component)minecartReplacementController).gameObject);
			}
			((MonoBehaviour)minecartReplacementController).StartCoroutine(minecartReplacementController.AttachVisualWhenReady(replacement, identity));
		}

		private void HandleLegacyMinecart(GameObject legacyCart)
		{
			//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_002f: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)legacyCart == (Object)null || !processedInstanceIds.Add(((Object)legacyCart).GetInstanceID()))
			{
				return;
			}
			Vector3 position = legacyCart.transform.position;
			Quaternion rotation = legacyCart.transform.rotation;
			MinecartSpawnIdentity minecartSpawnIdentity = CreateIdentity(position);
			ValidateSpawnedMinecartPreset(legacyCart, minecartSpawnIdentity);
			legacyCart.SetActive(false);
			suppressedMinecarts[minecartSpawnIdentity] = legacyCart;
			AttachWaitingReplacements();
			bool isHost = !SemiFunc.IsMultiplayer() || PhotonNetwork.IsMasterClient;
			if (!spawnPolicy.TryClaim(minecartSpawnIdentity, isHost))
			{
				return;
			}
			PrefabRef val = default(PrefabRef);
			if (!NetworkPrefabs.TryGetNetworkPrefabRef("nezzy.MinecartFix", ref val))
			{
				Plugin.Log.LogError((object)$"Minecart {minecartSpawnIdentity} was spawned, but the dedicated replacement prefab is not registered. The malformed original remains suppressed.");
				return;
			}
			GameObject val2 = NetworkPrefabs.SpawnNetworkPrefab(val, position, rotation, (byte)0, new object[7] { 1f, 1f, 1f, minecartSpawnIdentity.XMillimeters, minecartSpawnIdentity.YMillimeters, minecartSpawnIdentity.ZMillimeters, minecartSpawnIdentity.Occurrence });
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogError((object)$"Minecart {minecartSpawnIdentity} could not be network-spawned by the host. The malformed original remains suppressed.");
				return;
			}
			((Object)val2).name = "Minecart";
			if ((Object)(object)val2.GetComponent<MinecartReplacementMarker>() == (Object)null)
			{
				val2.AddComponent<MinecartReplacementMarker>();
			}
			AttachVisual(val2, minecartSpawnIdentity);
			Plugin.Log.LogInfo((object)"Broken Minecart found and replaced.");
		}

		private MinecartSpawnIdentity CreateIdentity(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			string key = $"{Math.Round(position.x, 3)}:{Math.Round(position.y, 3)}:{Math.Round(position.z, 3)}";
			positionOccurrences.TryGetValue(key, out var value);
			positionOccurrences[key] = value + 1;
			return MinecartSpawnIdentity.FromPosition(position.x, position.y, position.z, value);
		}

		private bool AttachVisual(GameObject replacement, MinecartSpawnIdentity identity, bool logFailure = true)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00d2: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)replacement.transform.Find("Minecart Visual") != (Object)null)
			{
				return true;
			}
			if (!suppressedMinecarts.TryGetValue(identity, out GameObject value))
			{
				value = FindUniqueLocalMinecartNear(identity);
				if ((Object)(object)value == (Object)null)
				{
					return false;
				}
			}
			MeshRenderer val = Array.Find(value.GetComponentsInChildren<MeshRenderer>(true), (MeshRenderer candidate) => ((Object)candidate).name == "Cart Mesh");
			MeshFilter val2 = (((Object)(object)val == (Object)null) ? null : ((Component)val).GetComponent<MeshFilter>());
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sharedMesh == (Object)null)
			{
				return false;
			}
			Material fallbackMaterial = FindNativeFallbackMaterial(replacement);
			GameObject val3 = new GameObject("Minecart Visual");
			val3.transform.SetParent(replacement.transform, false);
			Transform transform = ((Component)val).transform;
			val3.transform.localPosition = value.transform.InverseTransformPoint(transform.position);
			val3.transform.localRotation = Quaternion.Inverse(value.transform.rotation) * transform.rotation;
			val3.transform.localScale = transform.localScale;
			val3.AddComponent<MeshFilter>().sharedMesh = val2.sharedMesh;
			MeshRenderer val4 = val3.AddComponent<MeshRenderer>();
			((Renderer)val4).sharedMaterials = CompatibleMaterials(((Renderer)val).sharedMaterials, fallbackMaterial);
			((Renderer)val4).shadowCastingMode = ((Renderer)val).shadowCastingMode;
			((Renderer)val4).receiveShadows = ((Renderer)val).receiveShadows;
			Renderer[] componentsInChildren = replacement.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val5 in componentsInChildren)
			{
				if ((Object)(object)((Component)val5).gameObject != (Object)(object)val3 && ((Object)((Component)val5).gameObject).name != "Minecart Strong Grab Marker")
				{
					val5.enabled = false;
				}
			}
			Canvas[] componentsInChildren2 = replacement.GetComponentsInChildren<Canvas>(true);
			foreach (Canvas val6 in componentsInChildren2)
			{
				((Behaviour)val6).enabled = false;
			}
			return true;
		}

		private GameObject? FindUniqueLocalMinecartNear(MinecartSpawnIdentity identity)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor((float)identity.XMillimeters / 1000f, (float)identity.YMillimeters / 1000f, (float)identity.ZMillimeters / 1000f);
			List<GameObject> list = new List<GameObject>();
			foreach (GameObject value in suppressedMinecarts.Values)
			{
				if ((Object)(object)value != (Object)null && Vector3.SqrMagnitude(value.transform.position - val) <= 0.25f)
				{
					list.Add(value);
				}
			}
			if (list.Count != 1)
			{
				return null;
			}
			return list[0];
		}

		private static Material? FindNativeFallbackMaterial(GameObject replacement)
		{
			MeshRenderer[] componentsInChildren = replacement.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				if ((Object)(object)((Renderer)val).sharedMaterial != (Object)null && (Object)(object)((Renderer)val).sharedMaterial.shader != (Object)null)
				{
					return ((Renderer)val).sharedMaterial;
				}
			}
			return null;
		}

		private static Material[] CompatibleMaterials(Material[] materials, Material? fallbackMaterial)
		{
			//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_005b: 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_0068: Expected O, but got Unknown
			Material[] array = (Material[])(object)new Material[materials.Length];
			for (int i = 0; i < materials.Length; i++)
			{
				Material val = materials[i];
				if ((Object)(object)val == (Object)null || (Object)(object)val.shader != (Object)null || (Object)(object)((fallbackMaterial != null) ? fallbackMaterial.shader : null) == (Object)null)
				{
					array[i] = val;
					continue;
				}
				array[i] = new Material(fallbackMaterial.shader)
				{
					mainTexture = val.mainTexture,
					color = val.color
				};
			}
			return array;
		}

		private void AttachWaitingReplacements()
		{
			PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>();
			foreach (PhysGrabCart val in array)
			{
				GameObject gameObject = ((Component)val).gameObject;
				if ((MinecartReplacementAssets.IsReplacement(gameObject) || (Object)(object)gameObject.GetComponent<MinecartReplacementMarker>() != (Object)null) && TryGetReplacementIdentity(gameObject, out MinecartSpawnIdentity identity))
				{
					AttachVisual(gameObject, identity, logFailure: false);
				}
			}
		}

		private IEnumerator AttachVisualWhenReady(GameObject replacement, MinecartSpawnIdentity identity)
		{
			for (int frame = 0; frame < 300; frame++)
			{
				if ((Object)(object)replacement == (Object)null)
				{
					break;
				}
				if (AttachVisual(replacement, identity, logFailure: false))
				{
					break;
				}
				yield return null;
			}
		}

		private static bool TryGetReplacementIdentity(GameObject replacement, out MinecartSpawnIdentity identity)
		{
			PhotonView component = replacement.GetComponent<PhotonView>();
			object[] array = ((component != null) ? component.InstantiationData : null);
			if (array == null || array.Length != 7 || !(array[3] is int num) || !(array[4] is int num2) || !(array[5] is int num3) || !(array[6] is int occurrence))
			{
				identity = null;
				return false;
			}
			identity = MinecartSpawnIdentity.FromPosition((float)num / 1000f, (float)num2 / 1000f, (float)num3 / 1000f, occurrence);
			return true;
		}

		private static void ValidateSpawnedMinecartPreset(GameObject legacyCart, MinecartSpawnIdentity identity)
		{
			MonoBehaviour[] components = legacyCart.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				FieldInfo field = ((object)val).GetType().GetField("physAttributePreset", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null) && field.GetValue(val) == null)
				{
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(RunManager), "ChangeLevel")]
	internal static class MinecartReplacementLevelResetPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			MinecartReplacementController.ResetForLevelLoad();
		}
	}
	[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")]
	internal static class MinecartImpactDetectorPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabObjectImpactDetector __instance, Collision __0)
		{
			if ((Object)(object)((Component)__instance).GetComponent<MinecartReplacementMarker>() != (Object)null)
			{
				return false;
			}
			if (__0 != null)
			{
				return (Object)(object)((Component)__0.collider).GetComponentInParent<MinecartReplacementMarker>() == (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "ObjectsInCart")]
	internal static class MinecartCartStoragePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabCart __instance)
		{
			return (Object)(object)((Component)__instance).GetComponent<MinecartReplacementMarker>() == (Object)null;
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "StateSwitch")]
	internal static class MinecartCartVisualStatePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabCart __instance)
		{
			return (Object)(object)((Component)__instance).GetComponent<MinecartReplacementMarker>() == (Object)null;
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "StateMessages")]
	internal static class MinecartCartStateMessagesPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(PhysGrabCart __instance)
		{
			//IL_00c5: 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)
			if ((Object)(object)((Component)__instance).GetComponent<MinecartReplacementMarker>() == (Object)null)
			{
				return true;
			}
			PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>();
			if ((bool?)AccessTools.Field(typeof(PhysGrabObject), "grabbedLocal")?.GetValue(component) == true)
			{
				string text = AccessTools.Field(typeof(PhysGrabCart), "currentState")?.GetValue(__instance)?.ToString();
				bool flag = text == "Handled";
				ItemInfoExtraUI.instance.ItemInfoText(flag ? "Mode: Strong" : "Mode: Weak", flag ? new Color(0.2f, 0.8f, 0.1f) : new Color(1f, 0.46f, 0f));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PhysGrabCart), "Start")]
	internal static class StrongholdMinecartReplacementPatch
	{
		private static bool Prefix(PhysGrabCart __instance)
		{
			if (MinecartReplacementAssets.IsReplacement(((Component)__instance).gameObject) || (Object)(object)((Component)__instance).GetComponent<MinecartReplacementMarker>() != (Object)null)
			{
				MinecartReplacementController.AttachIncomingReplacement(((Component)__instance).gameObject);
				return true;
			}
			if (!Plugin.IsStrongholdLevel() || ((Object)((Component)__instance).gameObject).name.IndexOf("Minecart", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return true;
			}
			MinecartReplacementController.Replace(((Component)__instance).gameObject);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class StrongholdWeaponPhotonRepairPatch
	{
		private static MethodBase? TargetMethod()
		{
			return AccessTools.Method(typeof(PhotonView), "Awake", (Type[])null, (Type[])null);
		}

		private static void Prefix(PhotonView __instance)
		{
			if (IsAffectedWeapon(((Object)((Component)__instance).gameObject).name))
			{
				__instance.ObservedComponents.RemoveAll((Component component) => component is ItemMelee);
			}
		}

		private static bool IsAffectedWeapon(string name)
		{
			if (!name.StartsWith("MC Item Iron Pickaxe", StringComparison.Ordinal) && !name.StartsWith("MC Item Iron Sword", StringComparison.Ordinal))
			{
				return name.StartsWith("MC Item Diamond Sword", StringComparison.Ordinal);
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class StrongholdKinematicInventoryItemPatch
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool LinearVelocityPrefix(Rigidbody __instance)
		{
			return !IsLegacyStrongholdInventoryBody(__instance);
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static bool AngularVelocityPrefix(Rigidbody __instance)
		{
			return !IsLegacyStrongholdInventoryBody(__instance);
		}

		private static bool IsLegacyStrongholdInventoryBody(Rigidbody body)
		{
			if (Plugin.IsStrongholdLevel() && body.isKinematic)
			{
				return (Object)(object)((Component)body).GetComponent<ItemEquippable>() != (Object)null;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")]
	internal static class MinecartItemNamePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemAttributes __instance, ref string __result)
		{
			if ((Object)(object)((Component)__instance).GetComponent<MinecartReplacementMarker>() == (Object)null)
			{
				return true;
			}
			__result = "Minecart";
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")]
	internal static class StrongholdGoldenAppleLocalizationPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ItemAttributes __instance, ref string __result)
		{
			if (!Plugin.IsStrongholdLevel() || !GoldenAppleLocalization.IsAffectedPrefab(((Object)((Component)__instance).gameObject).name))
			{
				return true;
			}
			__result = "Golden Apple";
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemAttributes), "Start")]
	internal static class StrongholdCarvedPumpkinIconPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ItemAttributes __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			if (!Plugin.IsStrongholdLevel() || (Object)(object)__instance.icon != (Object)null || !((Object)((Component)__instance).gameObject).name.StartsWith("Item Carved Pumpkin", StringComparison.Ordinal))
			{
				return;
			}
			SemiIconMaker val = ((Component)__instance).GetComponentInChildren<SemiIconMaker>(true);
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = new GameObject("Stronghold Pumpkin Icon Maker");
				val2.transform.SetParent(((Component)__instance).transform, false);
				val = val2.AddComponent<SemiIconMaker>();
			}
			Bounds? val3 = CalculateRenderableBounds(((Component)__instance).transform);
			if (!val3.HasValue)
			{
				Plugin.Log.LogError((object)"Carved Pumpkin icon repair could not find a renderable mesh.");
				return;
			}
			Camera val4 = val.iconCamera;
			if ((Object)(object)val4 == (Object)null)
			{
				GameObject val5 = new GameObject("Icon Camera");
				val5.transform.SetParent(((Component)val).transform, false);
				val4 = (val.iconCamera = val5.AddComponent<Camera>());
			}
			((Component)val4).transform.SetParent(((Component)val).transform, false);
			val4.orthographic = true;
			val4.clearFlags = (CameraClearFlags)2;
			val4.backgroundColor = new Color(0f, 0f, 0f, 0f);
			val4.cullingMask = -1;
			val4.nearClipPlane = 0.01f;
			val4.farClipPlane = 100f;
			Transform transform = ((Component)__instance).transform;
			Bounds value = val3.Value;
			Vector3 val6 = transform.InverseTransformPoint(((Bounds)(ref value)).center);
			value = val3.Value;
			Vector3 size = ((Bounds)(ref value)).size;
			((Component)val4).transform.localPosition = val6 + Vector3.back * (Mathf.Max(new float[3] { size.x, size.y, size.z }) + 1f);
			((Component)val4).transform.localRotation = Quaternion.identity;
			val4.orthographicSize = Mathf.Max(new float[3]
			{
				size.y * 0.6f,
				size.x * 0.6f,
				0.5f
			});
			if ((Object)(object)val.renderTexture == (Object)null)
			{
				val.renderTexture = new RenderTexture(256, 256, 16, (RenderTextureFormat)0)
				{
					name = "Stronghold Pumpkin Icon RenderTexture"
				};
			}
			val.ambientLight = Color.white;
			val.iconCameraPlacementDone = true;
			((Component)val).gameObject.SetActive(false);
			Plugin.Log.LogInfo((object)"Repaired the Carved Pumpkin inventory icon renderer.");
		}

		private static Bounds? CalculateRenderableBounds(Transform root)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds value = default(Bounds);
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!(val is ParticleSystemRenderer) && !((Object)((Component)val).gameObject).name.Contains("Icon", StringComparison.Ordinal))
				{
					if (!flag)
					{
						value = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref value)).Encapsulate(val.bounds);
					}
				}
			}
			if (!flag)
			{
				return null;
			}
			return value;
		}
	}
	[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { })]
	internal static class StrongholdEmptyAudioPatch
	{
		private static bool Prefix(AudioSource __instance)
		{
			if (Plugin.IsStrongholdLevel())
			{
				return (Object)(object)__instance.clip != (Object)null;
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal static class StrongholdJukeboxMixerPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type type = AccessTools.TypeByName("REPOLib.Extensions.AudioSourceExtensions");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "FixAudioMixerGroup", new Type[1] { typeof(AudioSource) }, (Type[])null));
			MethodInfo sourceAndObject = ((type == null) ? null : AccessTools.Method(type, "FixAudioMixerGroup", new Type[2]
			{
				typeof(AudioSource),
				typeof(GameObject)
			}, (Type[])null));
			if (methodInfo != null)
			{
				yield return methodInfo;
			}
			if (sourceAndObject != null)
			{
				yield return sourceAndObject;
			}
		}

		private static bool Prefix(AudioSource __0)
		{
			if ((Object)(object)__0.outputAudioMixerGroup != (Object)null || !IsLegacyJukeboxAudio(__0))
			{
				return true;
			}
			AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>();
			foreach (AudioSource val in array)
			{
				if ((Object)(object)val.outputAudioMixerGroup != (Object)null && ((Object)val.outputAudioMixerGroup).name == "Sound Effects")
				{
					__0.outputAudioMixerGroup = val.outputAudioMixerGroup;
					return false;
				}
			}
			return true;
		}

		private static bool IsLegacyJukeboxAudio(AudioSource source)
		{
			Transform val = ((Component)source).transform;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name == "Valuable Jukebox 13" || ((Object)val).name == "Valuable Jukebox Cat" || ((Object)val).name == "Valuable Jukebox OS")
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}
	}
}