Decompiled source of MikuFufu v2.0.5

plugins/MikuFufu2.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("MikuFufu2")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("MikuFufu2")]
[assembly: AssemblyTitle("MikuFufu2")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	public sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		private readonly string _assemblyName;

		public string AssemblyName => _assemblyName;

		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
			_assemblyName = assemblyName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	public sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte value)
		{
			Flag = value;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	public sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int version)
		{
			Version = version;
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	public sealed class BepInAutoPluginAttribute : Attribute
	{
		private string _guid;

		private string _name;

		private string _version;

		public string GUID
		{
			get
			{
				return _guid;
			}
			set
			{
				_guid = value;
			}
		}

		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		public string Version
		{
			get
			{
				return _version;
			}
			set
			{
				_version = value;
			}
		}

		public BepInAutoPluginAttribute(string guid = null, string name = null, string version = null)
		{
			_guid = guid;
			_name = name;
			_version = version;
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
	public sealed class PatcherAutoPluginAttribute : Attribute
	{
		private string _guid;

		private string _name;

		private string _version;

		public string GUID
		{
			get
			{
				return _guid;
			}
			set
			{
				_guid = value;
			}
		}

		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		public string Version
		{
			get
			{
				return _version;
			}
			set
			{
				_version = value;
			}
		}

		public PatcherAutoPluginAttribute(string guid = null, string name = null, string version = null)
		{
			_guid = guid;
			_name = name;
			_version = version;
		}
	}
}
namespace MikuBongFix
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.github.Thanks.MikuFufu2", "MikuFufu2", "2.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private static readonly string[] LegacyPluginIds = new string[2] { "com.github.Thanks.MikuBongFix", "com.github.FelineEntity.MikuBongFix" };

		private const string BundleFileName = "mikupeak";

		private const string RuntimeReplacementFolderName = "FUFU";

		private const string ExternalIconFileName = "Fufu2.png";

		private const string PrefabAssetPath = "assets/mikufumo/mikufumo.prefab";

		private const string MaterialAssetPath = "assets/mikufumo/m_mikufumo.mat";

		private const string IconTextureAssetPath = "assets/mikufumo/miku_icon.png";

		private const string MainTextureAssetPath = "assets/mikufumo/miku.png";

		private const string ConfigSection = "Main";

		private const float WorldMinScaleMultiplier = 0.4f;

		private const float WorldMaxScaleMultiplier = 1.1f;

		private const float BackpackMinScaleMultiplier = 0.2f;

		private const float BackpackMaxScaleMultiplier = 1f;

		private const float DefaultWorldScaleMultiplier = 0.9f;

		private const float DefaultBackpackScaleMultiplier = 0.4f;

		private const string DefaultExpressionName = "None";

		private const float DefaultExpressionWeight = 1f;

		private static readonly Vector3 DefaultReplacementBaseScale = new Vector3(1.5f, 1.5f, 1.5f);

		private static readonly string[] PreferredTextureProps = new string[2] { "_BaseMap", "_MainTex" };

		private static readonly string[] PrefabNameHints = new string[3] { "mikufumo", "miku", "fumo" };

		private static readonly string[] MaterialNameHints = new string[3] { "m_mikufumo", "mikufumo", "miku" };

		private static readonly string[] IconTextureNameHints = new string[3] { "miku_icon", "icon", "miku" };

		private static readonly string[] MainTextureNameHints = new string[3] { "miku", "mikufumo", "albedo" };

		private static readonly Color MikuStyleTint = new Color(0.98f, 1f, 1f, 1f);

		private static ConfigEntry<bool> _modEnabled;

		private static ConfigEntry<float> _worldScaleMultiplier;

		private static ConfigEntry<float> _backpackScaleMultiplier;

		private static ManualLogSource _log;

		private static AssetBundle _bundle;

		private static GameObject _mochiPrefab;

		private static Material _mochiMaterial;

		private static Material _runtimeMikuMaterial;

		private static Texture2D _mochiTexture;

		private static Texture2D _mikuMainTexture;

		private static RuntimeReplacementModel _runtimeReplacementModel;

		public const string Name = "MikuFufu2";

		public const string Id = "com.github.Thanks.MikuFufu2";

		public const string Version = "2.0.5";

		internal static Harmony Harmony = new Harmony("com.github.Thanks.MikuFufu2");

		internal static ManualLogSource Log
		{
			get
			{
				return _log;
			}
			private set
			{
				_log = value;
			}
		}

		internal static AssetBundle Bundle
		{
			get
			{
				return _bundle;
			}
			private set
			{
				_bundle = value;
			}
		}

		internal static GameObject MochiPrefab
		{
			get
			{
				return _mochiPrefab;
			}
			private set
			{
				_mochiPrefab = value;
			}
		}

		internal static Material MochiMaterial
		{
			get
			{
				return _mochiMaterial;
			}
			private set
			{
				_mochiMaterial = value;
			}
		}

		internal static Material RuntimeMikuMaterial
		{
			get
			{
				return _runtimeMikuMaterial;
			}
			private set
			{
				_runtimeMikuMaterial = value;
			}
		}

		internal static Texture2D MochiTexture
		{
			get
			{
				return _mochiTexture;
			}
			private set
			{
				_mochiTexture = value;
			}
		}

		internal static Texture2D MikuMainTexture
		{
			get
			{
				return _mikuMainTexture;
			}
			private set
			{
				_mikuMainTexture = value;
			}
		}

		internal static RuntimeReplacementModel RuntimeReplacementModel
		{
			get
			{
				return _runtimeReplacementModel;
			}
			private set
			{
				_runtimeReplacementModel = value;
			}
		}

		internal static bool ModEnabled
		{
			get
			{
				if (_modEnabled != null)
				{
					return _modEnabled.Value;
				}
				return true;
			}
		}

		internal static bool KeepOriginalRendererRefs => RuntimeReplacementModel == null;

		internal static bool EnableVisibilityGuard => true;

		internal static float WorldScaleMultiplier
		{
			get
			{
				if (_worldScaleMultiplier != null)
				{
					return Mathf.Clamp(_worldScaleMultiplier.Value, 0.4f, 1.1f);
				}
				return 0.9f;
			}
		}

		internal static float BackpackScaleMultiplier
		{
			get
			{
				if (_backpackScaleMultiplier != null)
				{
					return Mathf.Clamp(_backpackScaleMultiplier.Value, 0.2f, 1f);
				}
				return 0.4f;
			}
		}

		internal static Vector3 ReplacementBaseScale
		{
			get
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: 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)
				if (RuntimeReplacementModel == null)
				{
					return DefaultReplacementBaseScale * 0.78f * 1.5f;
				}
				return RuntimeReplacementModel.RecommendedBaseScale * 0.78f * 1.5f;
			}
		}

		internal static string ExpressionName => "None";

		internal static float ExpressionWeight => 1f;

		internal static string ReplacementDisplayName
		{
			get
			{
				if (RuntimeReplacementModel == null)
				{
					return "Miku";
				}
				return RuntimeReplacementModel.DisplayName;
			}
		}

		internal static string directory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			MigrateLegacyConfigIfNeeded();
			InitializeConfig();
			LoadAssets();
			try
			{
				Harmony.PatchAll(Assembly.GetExecutingAssembly());
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to apply Harmony patches: " + ex));
			}
		}

		private void MigrateLegacyConfigIfNeeded()
		{
			try
			{
				string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
				if (string.IsNullOrEmpty(configFilePath) || File.Exists(configFilePath) || LegacyPluginIds == null)
				{
					return;
				}
				for (int i = 0; i < LegacyPluginIds.Length; i++)
				{
					string text = LegacyPluginIds[i];
					if (!string.IsNullOrEmpty(text))
					{
						string text2 = Path.Combine(Paths.ConfigPath, text + ".cfg");
						if (File.Exists(text2))
						{
							File.Copy(text2, configFilePath, overwrite: false);
							((BaseUnityPlugin)this).Config.Reload();
							Log.LogInfo((object)("Migrated legacy config to: " + configFilePath));
							break;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to migrate legacy config file: " + ex.Message));
			}
		}

		private void InitializeConfig()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			_modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Main", "Enable Fufu Replacement", true, new ConfigDescription("Master switch for the mod. When disabled, the original BingBong visuals, name, icon, and colliders are restored.", (AcceptableValueBase)null, Array.Empty<object>()));
			_worldScaleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Main", "Fufu Size In World", 0.9f, new ConfigDescription("Scale multiplier for Fufu while held or lying in the world.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.4f, 1.1f), Array.Empty<object>()));
			_backpackScaleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Main", "Fufu Size In Backpack", 0.4f, new ConfigDescription("Scale multiplier for the Fufu replacement while stored in the backpack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
		}

		private void LoadAssets()
		{
			Texture2D val = LoadExternalIconTexture();
			RuntimeReplacementModel = RuntimePmxLoader.Load(Path.Combine(directory, "FUFU"), Log);
			if (RuntimeReplacementModel != null)
			{
				MochiPrefab = null;
				Bundle = null;
				MochiTexture = val ?? RuntimeReplacementModel.IconTexture ?? RuntimeReplacementModel.PrimaryTexture;
				MikuMainTexture = RuntimeReplacementModel.PrimaryTexture;
				MochiMaterial = RuntimeReplacementModel.PrimaryMaterial;
				RuntimeMikuMaterial = RuntimeReplacementModel.PrimaryMaterial ?? CreateRuntimeMikuMaterial(MikuMainTexture);
				Log.LogInfo((object)("Loaded runtime FUFU replacement from folder: " + Path.Combine(directory, "FUFU")));
				return;
			}
			string text = Path.Combine(directory, "mikupeak");
			Bundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)Bundle == (Object)null)
			{
				Log.LogError((object)("Failed to load runtime FUFU assets and failed to load AssetBundle: " + text));
				return;
			}
			MochiPrefab = LoadBundleAssetWithFallback<GameObject>("assets/mikufumo/mikufumo.prefab", PrefabNameHints);
			MochiMaterial = LoadBundleAssetWithFallback<Material>("assets/mikufumo/m_mikufumo.mat", MaterialNameHints);
			MochiTexture = val ?? LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku_icon.png", IconTextureNameHints);
			Texture2D val2 = LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku.png", MainTextureNameHints);
			MikuMainTexture = CreateReadableTexture(val2) ?? val2;
			if ((Object)(object)MochiPrefab == (Object)null)
			{
				Log.LogError((object)"Failed to load replacement prefab from asset bundle.");
				return;
			}
			ConfigureMochiMaterial(MikuMainTexture);
			RuntimeMikuMaterial = CreateRuntimeMikuMaterial(MikuMainTexture);
			if ((Object)(object)RuntimeMikuMaterial == (Object)null)
			{
				Log.LogWarning((object)"Runtime fallback material was not created. The bundled material will be used when available.");
			}
			if ((Object)(object)MochiTexture == (Object)null)
			{
				Log.LogWarning((object)"Failed to load replacement icon texture.");
			}
			if ((Object)(object)MikuMainTexture == (Object)null)
			{
				Log.LogWarning((object)"Failed to load replacement main texture.");
			}
		}

		private Texture2D LoadExternalIconTexture()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_00aa: 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_00bb: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(directory, "Fufu2.png");
			if (!File.Exists(text))
			{
				return null;
			}
			try
			{
				using FileStream fileStream = File.OpenRead(text);
				Bitmap val = new Bitmap((Stream)fileStream);
				try
				{
					int width = ((Image)val).Width;
					int height = ((Image)val).Height;
					Color32[] array = (Color32[])(object)new Color32[width * height];
					for (int i = 0; i < height; i++)
					{
						for (int j = 0; j < width; j++)
						{
							Color pixel = val.GetPixel(j, height - 1 - i);
							array[i * width + j] = new Color32(pixel.R, pixel.G, pixel.B, pixel.A);
						}
					}
					Texture2D val2 = new Texture2D(width, height, (TextureFormat)4, false, false)
					{
						name = Path.GetFileNameWithoutExtension(text)
					};
					val2.SetPixels32(array);
					((Texture)val2).filterMode = (FilterMode)1;
					((Texture)val2).wrapMode = (TextureWrapMode)1;
					((Texture)val2).anisoLevel = 1;
					val2.Apply(false, false);
					return val2;
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to load external icon texture '" + text + "': " + ex.Message));
				return null;
			}
		}

		internal static GameObject CreateReplacementVisualInstance(string name)
		{
			if (RuntimeReplacementModel != null)
			{
				return RuntimeReplacementModel.Instantiate(name);
			}
			if ((Object)(object)MochiPrefab == (Object)null)
			{
				return null;
			}
			return Object.Instantiate<GameObject>(MochiPrefab);
		}

		internal static void VerboseLog(string message)
		{
		}

		private static T LoadBundleAssetWithFallback<T>(string preferredPath, params string[] nameHints) where T : Object
		{
			if ((Object)(object)Bundle == (Object)null)
			{
				return default(T);
			}
			if (!string.IsNullOrEmpty(preferredPath))
			{
				T val = Bundle.LoadAsset<T>(preferredPath);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			string[] allAssetNames = Bundle.GetAllAssetNames();
			if (allAssetNames != null)
			{
				foreach (string text in allAssetNames)
				{
					if (AssetNameLooksRelevant(text, preferredPath, nameHints))
					{
						T val2 = Bundle.LoadAsset<T>(text);
						if ((Object)(object)val2 != (Object)null)
						{
							Log.LogWarning((object)("Loaded fallback " + typeof(T).Name + " from bundle path: " + text));
							return val2;
						}
					}
				}
			}
			T[] array = Bundle.LoadAllAssets<T>();
			if (array == null || array.Length == 0)
			{
				Log.LogWarning((object)("No " + typeof(T).Name + " assets found in bundle for requested path: " + preferredPath));
				return default(T);
			}
			T val3 = FindAssetByObjectName(array, preferredPath, nameHints);
			if ((Object)(object)val3 != (Object)null)
			{
				Log.LogWarning((object)("Loaded fallback " + typeof(T).Name + " by object name: " + ((Object)val3).name));
				return val3;
			}
			if (array.Length == 1)
			{
				Log.LogWarning((object)("Loaded only available " + typeof(T).Name + " asset as fallback: " + ((Object)array[0]).name));
				return array[0];
			}
			Log.LogWarning((object)("Unable to identify " + typeof(T).Name + " for requested path '" + preferredPath + "'. Candidates: " + string.Join(", ", Array.ConvertAll(array, (T asset) => (!((Object)(object)asset != (Object)null)) ? "<null>" : ((Object)asset).name))));
			return default(T);
		}

		private static T FindAssetByObjectName<T>(T[] assets, string preferredPath, string[] nameHints) where T : Object
		{
			string needle = (string.IsNullOrEmpty(preferredPath) ? string.Empty : Path.GetFileNameWithoutExtension(preferredPath));
			foreach (T val in assets)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string value = ((Object)val).name ?? string.Empty;
					if (NameMatches(value, needle) || NameMatchesAnyHint(value, nameHints))
					{
						return val;
					}
				}
			}
			return default(T);
		}

		private static bool AssetNameLooksRelevant(string assetName, string preferredPath, string[] nameHints)
		{
			if (string.IsNullOrEmpty(assetName))
			{
				return false;
			}
			if (!string.IsNullOrEmpty(preferredPath))
			{
				if (assetName.Equals(preferredPath, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				string fileName = Path.GetFileName(preferredPath);
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(preferredPath);
				if (!string.IsNullOrEmpty(fileName) && assetName.EndsWith(fileName, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				if (NameMatches(assetName, fileNameWithoutExtension))
				{
					return true;
				}
			}
			return NameMatchesAnyHint(assetName, nameHints);
		}

		private static bool NameMatchesAnyHint(string value, string[] hints)
		{
			if (string.IsNullOrEmpty(value) || hints == null)
			{
				return false;
			}
			for (int i = 0; i < hints.Length; i++)
			{
				if (NameMatches(value, hints[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static bool NameMatches(string value, string needle)
		{
			if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(needle))
			{
				return false;
			}
			return value.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static void ConfigureMochiMaterial(Texture2D mikuMainTexture)
		{
			if ((Object)(object)MochiMaterial == (Object)null)
			{
				return;
			}
			if ((Object)(object)MochiMaterial.shader == (Object)null || !MochiMaterial.shader.isSupported)
			{
				Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
				if ((Object)(object)val != (Object)null)
				{
					MochiMaterial.shader = val;
				}
			}
			if ((Object)(object)mikuMainTexture != (Object)null)
			{
				ApplyTextureSet(MochiMaterial, mikuMainTexture);
			}
			ApplyMikuColorStyle(MochiMaterial);
			VerboseLog("Configured bundled material: " + ((Object)MochiMaterial).name);
		}

		private static bool TryAssignTextureIfMissing(Material material, string propertyName, Texture2D texture)
		{
			//IL_0043: 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)
			if ((Object)(object)material == (Object)null || (Object)(object)texture == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName))
			{
				return false;
			}
			try
			{
				if ((Object)(object)material.GetTexture(propertyName) != (Object)null)
				{
					return false;
				}
				material.SetTexture(propertyName, (Texture)(object)texture);
				material.SetTextureScale(propertyName, Vector2.one);
				material.SetTextureOffset(propertyName, Vector2.zero);
				return true;
			}
			catch (Exception ex)
			{
				VerboseLog("Skip texture assignment on material '" + ((Object)material).name + "', property '" + propertyName + "': " + ex.Message);
				return false;
			}
		}

		private static void TryAssignTextureIfMissing(Material material, string[] propertyNames, Texture2D texture)
		{
			if (!((Object)(object)material == (Object)null) && !((Object)(object)texture == (Object)null) && propertyNames != null)
			{
				for (int i = 0; i < propertyNames.Length; i++)
				{
					TryAssignTextureIfMissing(material, propertyNames[i], texture);
				}
			}
		}

		private static void ApplyTextureSet(Material material, Texture2D albedo)
		{
			if (!((Object)(object)material == (Object)null))
			{
				TryAssignTextureIfMissing(material, PreferredTextureProps, albedo);
				ApplyMikuColorStyle(material);
			}
		}

		private static void ApplyMikuColorStyle(Material material)
		{
			//IL_001d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)material == (Object)null))
			{
				if (material.HasProperty("_Tint"))
				{
					material.SetColor("_Tint", MikuStyleTint);
				}
				if (material.HasProperty("_BaseColor"))
				{
					material.SetColor("_BaseColor", MikuStyleTint);
				}
				if (material.HasProperty("_Color"))
				{
					material.SetColor("_Color", MikuStyleTint);
				}
				if (material.HasProperty("_Smoothness"))
				{
					material.SetFloat("_Smoothness", 0.3f);
				}
				if (material.HasProperty("_Glossiness"))
				{
					material.SetFloat("_Glossiness", 0.3f);
				}
				if (material.HasProperty("_Metallic"))
				{
					material.SetFloat("_Metallic", 0f);
				}
				if (material.HasProperty("_BumpScale"))
				{
					material.SetFloat("_BumpScale", 0f);
				}
				if (material.HasProperty("_OcclusionStrength"))
				{
					material.SetFloat("_OcclusionStrength", 0f);
				}
				if (material.HasProperty("_SpecularHighlights"))
				{
					material.SetFloat("_SpecularHighlights", 0f);
				}
				if (material.HasProperty("_EnvironmentReflections"))
				{
					material.SetFloat("_EnvironmentReflections", 0f);
				}
				if (material.HasProperty("_EmissionColor"))
				{
					material.SetColor("_EmissionColor", Color.black);
					material.DisableKeyword("_EMISSION");
				}
				material.DisableKeyword("_NORMALMAP");
				material.DisableKeyword("_METALLICSPECGLOSSMAP");
				material.DisableKeyword("_OCCLUSIONMAP");
			}
		}

		private static Texture2D CreateReadableTexture(Texture2D source)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			try
			{
				source.GetPixel(0, 0);
				return source;
			}
			catch
			{
			}
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0);
			RenderTexture active = RenderTexture.active;
			try
			{
				Graphics.Blit((Texture)(object)source, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, true, false)
				{
					name = ((Object)source).name + "_Readable"
				};
				val.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0);
				val.Apply(true, false);
				return val;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}

		private static Material CreateRuntimeMikuMaterial(Texture2D texture)
		{
			//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)
			//IL_0052: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("W/Peak_Standard");
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Failed to create runtime material because no compatible shader was found.");
				return null;
			}
			Material val2 = new Material(val)
			{
				name = "Miku_RuntimeMaterial",
				renderQueue = 2000,
				color = Color.white
			};
			if ((Object)(object)texture != (Object)null)
			{
				TryAssignTextureIfMissing(val2, "_BaseMap", texture);
				TryAssignTextureIfMissing(val2, "_MainTex", texture);
			}
			if (val2.HasProperty("_Surface"))
			{
				val2.SetFloat("_Surface", 0f);
			}
			if (val2.HasProperty("_Blend"))
			{
				val2.SetFloat("_Blend", 0f);
			}
			if (val2.HasProperty("_ZWrite"))
			{
				val2.SetFloat("_ZWrite", 1f);
			}
			if (val2.HasProperty("_Cull"))
			{
				val2.SetFloat("_Cull", 0f);
			}
			val2.SetOverrideTag("RenderType", "Opaque");
			val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val2.EnableKeyword("_SURFACE_TYPE_OPAQUE");
			ApplyMikuColorStyle(val2);
			return val2;
		}
	}
	public class MikuMarker : MonoBehaviour
	{
	}
	public class MikuDeformGuard : MonoBehaviour
	{
		private const float SqueezeDuration = 0.78f;

		private const float SqueezeCompressPhase = 0.42f;

		private Transform[] _allTransforms = Array.Empty<Transform>();

		private Vector3[] _initialChildScales = Array.Empty<Vector3>();

		private Vector3 _rootLocalPosition;

		private Quaternion _rootLocalRotation;

		private Vector3 _rootLocalScale;

		private Item _boundItem;

		private bool _wasUsing;

		private float _squeezeElapsed = 0.78f;

		public void Initialize(Vector3 rootLocalPosition, Quaternion rootLocalRotation, Vector3 rootLocalScale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_rootLocalPosition = rootLocalPosition;
			_rootLocalRotation = rootLocalRotation;
			_rootLocalScale = rootLocalScale;
			_wasUsing = false;
			_squeezeElapsed = 0.78f;
			Capture();
		}

		public void Bind(Item item)
		{
			_boundItem = item;
		}

		public void SetRootTarget(Vector3 rootLocalPosition, Quaternion rootLocalRotation, Vector3 rootLocalScale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_rootLocalPosition = rootLocalPosition;
			_rootLocalRotation = rootLocalRotation;
			_rootLocalScale = rootLocalScale;
		}

		private bool IsHeldAndUsing()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			if ((Object)(object)_boundItem != (Object)null && (int)_boundItem.itemState == 1)
			{
				if (!_boundItem.isUsingPrimary)
				{
					return _boundItem.isUsingSecondary;
				}
				return true;
			}
			return false;
		}

		private void UpdateSingleSqueezeState()
		{
			bool flag = IsHeldAndUsing();
			if (flag && !_wasUsing)
			{
				_squeezeElapsed = 0f;
			}
			_wasUsing = flag;
			if (_squeezeElapsed < 0.78f)
			{
				_squeezeElapsed += Time.deltaTime;
			}
		}

		private float EvaluateSingleSqueezeWeight()
		{
			if (_squeezeElapsed >= 0.78f)
			{
				return 0f;
			}
			float num = Mathf.Clamp01(_squeezeElapsed / 0.78f);
			if (num <= 0.42f)
			{
				return Mathf.SmoothStep(0f, 1f, num / 0.42f);
			}
			float num2 = (num - 0.42f) / 0.58000004f;
			return Mathf.SmoothStep(1f, 0f, Mathf.Clamp01(num2));
		}

		private Vector3 GetDesiredRootScale(float squeezeWeight)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (squeezeWeight <= 0.0005f)
			{
				return _rootLocalScale;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(1f - 0.14f * squeezeWeight, 1f + 0.11f * squeezeWeight, 1f - 0.14f * squeezeWeight);
			return Vector3.Scale(_rootLocalScale, val);
		}

		public void Capture()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			_allTransforms = ((Component)this).GetComponentsInChildren<Transform>(true);
			_initialChildScales = (Vector3[])(object)new Vector3[_allTransforms.Length];
			for (int i = 0; i < _allTransforms.Length; i++)
			{
				_initialChildScales[i] = _allTransforms[i].localScale;
			}
		}

		private void LateUpdate()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0056: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0093: 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_00a1: 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)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (_allTransforms.Length == 0 || _allTransforms.Length != _initialChildScales.Length)
			{
				Capture();
			}
			if (((Component)this).transform.localPosition != _rootLocalPosition)
			{
				((Component)this).transform.localPosition = _rootLocalPosition;
			}
			if (((Component)this).transform.localRotation != _rootLocalRotation)
			{
				((Component)this).transform.localRotation = _rootLocalRotation;
			}
			UpdateSingleSqueezeState();
			float squeezeWeight = EvaluateSingleSqueezeWeight();
			Vector3 desiredRootScale = GetDesiredRootScale(squeezeWeight);
			if (((Component)this).transform.localScale != desiredRootScale)
			{
				((Component)this).transform.localScale = desiredRootScale;
			}
			for (int i = 0; i < _allTransforms.Length; i++)
			{
				Transform val = _allTransforms[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)((Component)this).transform) && val.localScale != _initialChildScales[i])
				{
					val.localScale = _initialChildScales[i];
				}
			}
		}
	}
	public class MikuRendererGuard : MonoBehaviour
	{
		private const float RefreshInterval = 0.1f;

		private float _nextRefreshTime;

		private Item _boundItem;

		private Renderer[] _cachedRenderers = Array.Empty<Renderer>();

		public void Bind(Item item)
		{
			_boundItem = item;
		}

		private void LateUpdate()
		{
			if (!Plugin.ModEnabled || !Plugin.EnableVisibilityGuard || Time.time < _nextRefreshTime)
			{
				return;
			}
			_nextRefreshTime = Time.time + 0.1f;
			if (!((Component)this).gameObject.activeSelf)
			{
				((Component)this).gameObject.SetActive(true);
			}
			int num = (((Object)(object)_boundItem != (Object)null) ? ((Component)_boundItem).gameObject.layer : ((Component)this).gameObject.layer);
			if (((Component)this).gameObject.layer != num)
			{
				((Component)this).gameObject.layer = num;
			}
			Renderer[] renderableChildren = GetRenderableChildren();
			foreach (Renderer val in renderableChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					EnsureRendererVisible(val, num);
				}
			}
		}

		private Renderer[] GetRenderableChildren()
		{
			if (_cachedRenderers.Length == 0 || HasNullRenderer(_cachedRenderers))
			{
				_cachedRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
			}
			return _cachedRenderers;
		}

		private static bool HasNullRenderer(Renderer[] renderers)
		{
			for (int i = 0; i < renderers.Length; i++)
			{
				if ((Object)(object)renderers[i] == (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private static void EnsureRendererVisible(Renderer renderer, int targetLayer)
		{
			if (!((Component)renderer).gameObject.activeSelf)
			{
				((Component)renderer).gameObject.SetActive(true);
			}
			if (renderer.forceRenderingOff)
			{
				renderer.forceRenderingOff = false;
			}
			if (!renderer.enabled)
			{
				renderer.enabled = true;
			}
			renderer.SetPropertyBlock((MaterialPropertyBlock)null);
			((Component)renderer).gameObject.layer = targetLayer;
			renderer.allowOcclusionWhenDynamic = false;
		}

		private static void NormalizeRendererMaterialColor(Renderer renderer)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			Material[] sharedMaterials = renderer.sharedMaterials;
			foreach (Material val in sharedMaterials)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Color white = Color.white;
					if (val.HasProperty("_Tint"))
					{
						val.SetColor("_Tint", white);
					}
					if (val.HasProperty("_BaseColor"))
					{
						val.SetColor("_BaseColor", white);
					}
					if (val.HasProperty("_Color"))
					{
						val.SetColor("_Color", white);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(Item))]
	public class ItemPatch
	{
		private const int VisibleLayer = 0;

		private static readonly Color MikuMaterialTint = new Color(0.98f, 1f, 1f, 1f);

		private const string MikuVisualName = "MikuFumo_Visual";

		private static readonly Vector3 WorldMikuLocalPosition = new Vector3(0f, 0.2f, 0.1f);

		private static readonly Quaternion WorldMikuLocalRotation = Quaternion.identity;

		private static readonly Vector3 HeldMikuLocalPosition = new Vector3(0f, -0.1f, 0.45f);

		private static readonly Quaternion HeldMikuLocalRotation = Quaternion.Euler(10f, 0f, 0f);

		private static readonly string[] UnwantedFootKeywords = new string[3] { "hand", "glove", "mitten" };

		private static bool IsBingBong(Item item)
		{
			if ((Object)(object)item != (Object)null)
			{
				return ((Object)item).name.IndexOf("BingBong", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		internal static bool IsMikuTransform(Transform transform)
		{
			if ((Object)(object)transform != (Object)null)
			{
				return (Object)(object)((Component)transform).GetComponentInParent<MikuMarker>() != (Object)null;
			}
			return false;
		}

		private static bool IsInBackpack(Item item)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			if ((Object)(object)item != (Object)null)
			{
				return (int)item.itemState == 2;
			}
			return false;
		}

		private static bool IsHeld(Item item)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			if ((Object)(object)item != (Object)null)
			{
				return (int)item.itemState == 1;
			}
			return false;
		}

		private static bool ShouldShowReplacement(Item item)
		{
			if ((Object)(object)item != (Object)null)
			{
				return Plugin.ModEnabled;
			}
			return false;
		}

		private static Vector3 ResolveScaleByState(Item item)
		{
			//IL_0015: 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)
			float num = (IsInBackpack(item) ? Plugin.BackpackScaleMultiplier : Plugin.WorldScaleMultiplier);
			return Plugin.ReplacementBaseScale * num;
		}

		private static Vector3 ApplyPlayerFacingScale(Vector3 scale)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(0f - Mathf.Abs(scale.x), Mathf.Abs(scale.y), 0f - Mathf.Abs(scale.z));
		}

		private static void ResolvePoseByState(Item item, out Vector3 localPosition, out Quaternion localRotation, out Vector3 localScale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_002c: 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_005e: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ResolveScaleByState(item);
			if (IsHeld(item))
			{
				localPosition = HeldMikuLocalPosition;
				localRotation = HeldMikuLocalRotation;
				localScale = ApplyPlayerFacingScale(val);
			}
			else if (IsInBackpack(item))
			{
				localPosition = WorldMikuLocalPosition;
				localRotation = WorldMikuLocalRotation;
				localScale = val;
			}
			else
			{
				localPosition = WorldMikuLocalPosition;
				localRotation = WorldMikuLocalRotation;
				localScale = ApplyPlayerFacingScale(val);
			}
		}

		private static Transform FindMikuRoot(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			MikuMarker[] componentsInChildren = ((Component)item).GetComponentsInChildren<MikuMarker>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					return ((Component)componentsInChildren[i]).transform;
				}
			}
			return ((Component)item).transform.Find("MikuFumo_Visual");
		}

		private static MikuExpressionController FindExpressionController(Transform mikuRoot)
		{
			if (!((Object)(object)mikuRoot != (Object)null))
			{
				return null;
			}
			return ((Component)mikuRoot).GetComponentInChildren<MikuExpressionController>(true);
		}

		private static Texture GetMikuTexture()
		{
			if ((Object)(object)Plugin.MikuMainTexture != (Object)null)
			{
				return (Texture)(object)Plugin.MikuMainTexture;
			}
			Texture val = TryGetTexture(Plugin.MochiMaterial);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			return TryGetTexture(Plugin.RuntimeMikuMaterial);
		}

		private static Texture TryGetTexture(Material material)
		{
			if ((Object)(object)material == (Object)null)
			{
				return null;
			}
			if (material.HasProperty("_BaseMap"))
			{
				Texture texture = material.GetTexture("_BaseMap");
				if ((Object)(object)texture != (Object)null)
				{
					return texture;
				}
			}
			if (material.HasProperty("_MainTex"))
			{
				return material.GetTexture("_MainTex");
			}
			return null;
		}

		private static bool TrySetTextureSafe(Material material, string propertyName, Texture texture)
		{
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName))
			{
				return false;
			}
			try
			{
				material.SetTexture(propertyName, texture);
				return true;
			}
			catch (Exception ex)
			{
				Plugin.VerboseLog("[ItemPatch] Skip SetTexture on material '" + ((Object)material).name + "' property '" + propertyName + "': " + ex.Message);
				return false;
			}
		}

		private static void TrySetTextureTransformSafe(Material material, string propertyName, Vector2 scale, Vector2 offset)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName))
			{
				return;
			}
			try
			{
				material.SetTextureScale(propertyName, scale);
				material.SetTextureOffset(propertyName, offset);
			}
			catch (Exception ex)
			{
				Plugin.VerboseLog("[ItemPatch] Skip texture transform on material '" + ((Object)material).name + "' property '" + propertyName + "': " + ex.Message);
			}
		}

		private static void ApplyMikuTextureSafe(Material material, Texture mikuTexture)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (!((Object)(object)material == (Object)null) && !((Object)(object)mikuTexture == (Object)null))
			{
				if (TrySetTextureSafe(material, "_BaseMap", mikuTexture))
				{
					TrySetTextureTransformSafe(material, "_BaseMap", Vector2.one, Vector2.zero);
				}
				if (TrySetTextureSafe(material, "_MainTex", mikuTexture))
				{
					TrySetTextureTransformSafe(material, "_MainTex", Vector2.one, Vector2.zero);
				}
			}
		}

		private static void DisableOptionalSurfaceTextures(Material material)
		{
			if (!((Object)(object)material == (Object)null))
			{
				TrySetTextureSafe(material, "_BumpMap", null);
				TrySetTextureSafe(material, "_NormalMap", null);
				TrySetTextureSafe(material, "_OcclusionMap", null);
				TrySetTextureSafe(material, "_MetallicGlossMap", null);
				TrySetTextureSafe(material, "_SpecGlossMap", null);
				material.DisableKeyword("_NORMALMAP");
				material.DisableKeyword("_METALLICSPECGLOSSMAP");
				material.DisableKeyword("_OCCLUSIONMAP");
			}
		}

		private static void OptimizeTextureSampling(Texture texture)
		{
			Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null);
			if (!((Object)(object)val == (Object)null))
			{
				((Texture)val).filterMode = (FilterMode)2;
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).anisoLevel = Mathf.Max(((Texture)val).anisoLevel, 16);
				((Texture)val).mipMapBias = Mathf.Min(((Texture)val).mipMapBias, -0.75f);
			}
		}

		private static void ApplyRealisticMaterialTuning(Material material)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0062: 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)
			if (!((Object)(object)material == (Object)null))
			{
				Color val = ResolveMaterialTint(material);
				val.a = 1f;
				if (material.HasProperty("_Tint"))
				{
					material.SetColor("_Tint", val);
				}
				if (material.HasProperty("_BaseColor"))
				{
					material.SetColor("_BaseColor", val);
				}
				if (material.HasProperty("_Color"))
				{
					material.SetColor("_Color", val);
				}
				if (material.HasProperty("_Smoothness"))
				{
					material.SetFloat("_Smoothness", 0.3f);
				}
				if (material.HasProperty("_Glossiness"))
				{
					material.SetFloat("_Glossiness", 0.3f);
				}
				if (material.HasProperty("_Metallic"))
				{
					material.SetFloat("_Metallic", 0f);
				}
				if (material.HasProperty("_BumpScale"))
				{
					material.SetFloat("_BumpScale", 0f);
				}
				if (material.HasProperty("_OcclusionStrength"))
				{
					material.SetFloat("_OcclusionStrength", 0f);
				}
				if (material.HasProperty("_SpecularHighlights"))
				{
					material.SetFloat("_SpecularHighlights", 0f);
				}
				if (material.HasProperty("_EnvironmentReflections"))
				{
					material.SetFloat("_EnvironmentReflections", 0f);
				}
				DisableOptionalSurfaceTextures(material);
				if (material.HasProperty("_EmissionColor"))
				{
					material.SetColor("_EmissionColor", Color.black);
					material.DisableKeyword("_EMISSION");
				}
			}
		}

		private static Material CreateFallbackMaterial()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("W/Peak_Standard");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return new Material(val)
			{
				color = Color.white
			};
		}

		private static Color ResolveMaterialTint(Material material)
		{
			//IL_0009: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)material == (Object)null)
			{
				return MikuMaterialTint;
			}
			if (material.HasProperty("_Tint"))
			{
				return material.GetColor("_Tint");
			}
			if (material.HasProperty("_BaseColor"))
			{
				return material.GetColor("_BaseColor");
			}
			if (material.HasProperty("_Color"))
			{
				return material.GetColor("_Color");
			}
			return MikuMaterialTint;
		}

		private static void OptimizeMaterialTextureSampling(Material material)
		{
			OptimizeTextureSampling(TryGetTexture(material));
		}

		private static Material CreateRendererMaterialInstance(Material template = null)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			template = template ?? Plugin.RuntimeMikuMaterial ?? Plugin.MochiMaterial;
			if ((Object)(object)template == (Object)null)
			{
				Material val = CreateFallbackMaterial();
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				template = val;
			}
			Material val2 = new Material(template);
			Texture val3 = TryGetTexture(val2);
			Texture mikuTexture = GetMikuTexture();
			if ((Object)(object)val3 != (Object)null)
			{
				OptimizeTextureSampling(val3);
			}
			else if ((Object)(object)mikuTexture != (Object)null)
			{
				OptimizeTextureSampling(mikuTexture);
				ApplyMikuTextureSafe(val2, mikuTexture);
			}
			DisableOptionalSurfaceTextures(val2);
			if (val2.HasProperty("_Surface"))
			{
				val2.SetFloat("_Surface", 0f);
			}
			if (val2.HasProperty("_Blend"))
			{
				val2.SetFloat("_Blend", 0f);
			}
			if (val2.HasProperty("_ZWrite"))
			{
				val2.SetFloat("_ZWrite", 1f);
			}
			if (val2.HasProperty("_SrcBlend"))
			{
				val2.SetFloat("_SrcBlend", 1f);
			}
			if (val2.HasProperty("_DstBlend"))
			{
				val2.SetFloat("_DstBlend", 0f);
			}
			if (val2.HasProperty("_Cull"))
			{
				val2.SetFloat("_Cull", 0f);
			}
			if (val2.HasProperty("_AlphaClip"))
			{
				val2.SetFloat("_AlphaClip", 0f);
			}
			if (val2.HasProperty("_Cutoff"))
			{
				val2.SetFloat("_Cutoff", 0f);
			}
			if (val2.HasProperty("_LOD"))
			{
				val2.SetFloat("_LOD", 600f);
			}
			val2.renderQueue = 2000;
			val2.SetOverrideTag("RenderType", "Opaque");
			val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val2.EnableKeyword("_SURFACE_TYPE_OPAQUE");
			val2.DisableKeyword("_ALPHATEST_ON");
			val2.DisableKeyword("_ALPHABLEND_ON");
			val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			val2.DisableKeyword("LOD_FADE_CROSSFADE");
			ApplyRealisticMaterialTuning(val2);
			return val2;
		}

		private static Material[] BuildMaterialArray(Material[] sourceMaterials, int subMeshCount)
		{
			int num = Mathf.Max(1, subMeshCount);
			Material[] array = (Material[])(object)new Material[num];
			for (int i = 0; i < num; i++)
			{
				Material template = null;
				if (sourceMaterials != null && sourceMaterials.Length != 0)
				{
					template = sourceMaterials[Mathf.Min(i, sourceMaterials.Length - 1)];
				}
				Material val = CreateRendererMaterialInstance(template);
				if ((Object)(object)val == (Object)null)
				{
					val = CreateFallbackMaterial();
				}
				if ((Object)(object)val != (Object)null)
				{
					Texture val2 = TryGetTexture(val);
					if ((Object)(object)val2 == (Object)null)
					{
						Texture mikuTexture = GetMikuTexture();
						if ((Object)(object)mikuTexture != (Object)null)
						{
							OptimizeTextureSampling(mikuTexture);
							ApplyMikuTextureSafe(val, mikuTexture);
						}
					}
					else
					{
						OptimizeTextureSampling(val2);
					}
					DisableOptionalSurfaceTextures(val);
					ApplyRealisticMaterialTuning(val);
				}
				array[i] = val;
			}
			return array;
		}

		private static void ApplyMaterialToMeshRenderer(MeshRenderer renderer)
		{
			int subMeshCount = 1;
			MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
			{
				subMeshCount = Mathf.Max(1, component.sharedMesh.subMeshCount);
			}
			((Renderer)renderer).sharedMaterials = BuildMaterialArray(((Renderer)renderer).sharedMaterials, subMeshCount);
		}

		private static void ApplyMaterialToSkinnedRenderer(SkinnedMeshRenderer renderer)
		{
			//IL_0048: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			int subMeshCount = 1;
			if ((Object)(object)renderer.sharedMesh != (Object)null)
			{
				subMeshCount = Mathf.Max(1, renderer.sharedMesh.subMeshCount);
			}
			((Renderer)renderer).sharedMaterials = BuildMaterialArray(((Renderer)renderer).sharedMaterials, subMeshCount);
			if ((Object)(object)renderer.sharedMesh != (Object)null)
			{
				Bounds bounds = renderer.sharedMesh.bounds;
				((Bounds)(ref bounds)).Expand(0.5f);
				((Renderer)renderer).localBounds = bounds;
			}
		}

		private static bool HasVisibleReplacementRenderers(Transform mikuRoot)
		{
			if ((Object)(object)mikuRoot == (Object)null)
			{
				return false;
			}
			Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				if (sharedMaterials == null || sharedMaterials.Length == 0)
				{
					continue;
				}
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if ((Object)(object)sharedMaterials[j] != (Object)null)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static void DisableOriginalRenderers(Item item)
		{
			Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform))
				{
					val.enabled = false;
				}
			}
		}

		private static void EnableOriginalRenderers(Item item)
		{
			Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform))
				{
					val.enabled = true;
				}
			}
		}

		private static void EnableOriginalColliders(Item item)
		{
			Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true);
			List<Collider> list = new List<Collider>();
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform))
				{
					val.enabled = true;
					list.Add(val);
				}
			}
			if ((Object)(object)item != (Object)null)
			{
				item.colliders = list.ToArray();
			}
		}

		private static void DisableOriginalColliders(Item item)
		{
			Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform))
				{
					val.enabled = false;
				}
			}
		}

		private static Collider FindColliderTemplate(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !IsMikuTransform(((Component)val).transform))
				{
					return val;
				}
			}
			return null;
		}

		private static Vector3 ClampColliderSize(Vector3 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(Mathf.Max(size.x, 0.02f), Mathf.Max(size.y, 0.02f), Mathf.Max(size.z, 0.02f));
		}

		private static bool HasNegativeScaleInHierarchy(Transform transform)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				Vector3 localScale = val.localScale;
				if (localScale.x < 0f || localScale.y < 0f || localScale.z < 0f)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void CopyColliderSettings(Collider source, Collider target)
		{
			if (!((Object)(object)target == (Object)null))
			{
				if ((Object)(object)source != (Object)null)
				{
					target.isTrigger = source.isTrigger;
					target.sharedMaterial = source.sharedMaterial;
					target.contactOffset = source.contactOffset;
				}
				target.enabled = true;
			}
		}

		private static Collider AddConvexMeshColliderForMeshRenderer(MeshRenderer renderer, Collider templateCollider)
		{
			if ((Object)(object)renderer == (Object)null)
			{
				return null;
			}
			MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
			{
				return null;
			}
			MeshCollider val = ((Component)renderer).gameObject.GetComponent<MeshCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)renderer).gameObject.AddComponent<MeshCollider>();
			}
			val.sharedMesh = null;
			val.convex = true;
			val.sharedMesh = component.sharedMesh;
			CopyColliderSettings(templateCollider, (Collider)(object)val);
			return (Collider)(object)val;
		}

		private static Collider AddBoxColliderForMeshRenderer(MeshRenderer renderer, Collider templateCollider)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)renderer == (Object)null)
			{
				return null;
			}
			if (HasNegativeScaleInHierarchy(((Component)renderer).transform))
			{
				return null;
			}
			MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
			{
				return null;
			}
			Bounds bounds = component.sharedMesh.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (((Vector3)(ref size)).sqrMagnitude <= 0f)
			{
				return null;
			}
			BoxCollider val = ((Component)renderer).gameObject.GetComponent<BoxCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)renderer).gameObject.AddComponent<BoxCollider>();
			}
			val.center = ((Bounds)(ref bounds)).center;
			val.size = ClampColliderSize(((Bounds)(ref bounds)).size);
			CopyColliderSettings(templateCollider, (Collider)(object)val);
			return (Collider)(object)val;
		}

		private static Collider AddBoxColliderForSkinnedRenderer(SkinnedMeshRenderer renderer, Collider templateCollider)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//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_0053: 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_004b: 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_008d: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)renderer == (Object)null)
			{
				return null;
			}
			if (HasNegativeScaleInHierarchy(((Component)renderer).transform))
			{
				return null;
			}
			Bounds val = ((Renderer)renderer).localBounds;
			Vector3 size = ((Bounds)(ref val)).size;
			if (((Vector3)(ref size)).sqrMagnitude <= 0f && (Object)(object)renderer.sharedMesh != (Object)null)
			{
				val = renderer.sharedMesh.bounds;
			}
			size = ((Bounds)(ref val)).size;
			if (((Vector3)(ref size)).sqrMagnitude <= 0f)
			{
				return null;
			}
			BoxCollider val2 = ((Component)renderer).gameObject.GetComponent<BoxCollider>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)renderer).gameObject.AddComponent<BoxCollider>();
			}
			val2.center = ((Bounds)(ref val)).center;
			val2.size = ClampColliderSize(((Bounds)(ref val)).size);
			CopyColliderSettings(templateCollider, (Collider)(object)val2);
			return (Collider)(object)val2;
		}

		private static void EncapsulateBoundsCorners(ref Bounds aggregateBounds, ref bool hasBounds, Transform root, Bounds rendererBounds)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0020: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_005e: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00dd: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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)
			Vector3 center = ((Bounds)(ref rendererBounds)).center;
			Vector3 extents = ((Bounds)(ref rendererBounds)).extents;
			Vector3[] array = (Vector3[])(object)new Vector3[8]
			{
				center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z),
				center + new Vector3(0f - extents.x, 0f - extents.y, extents.z),
				center + new Vector3(0f - extents.x, extents.y, 0f - extents.z),
				center + new Vector3(0f - extents.x, extents.y, extents.z),
				center + new Vector3(extents.x, 0f - extents.y, 0f - extents.z),
				center + new Vector3(extents.x, 0f - extents.y, extents.z),
				center + new Vector3(extents.x, extents.y, 0f - extents.z),
				center + new Vector3(extents.x, extents.y, extents.z)
			};
			for (int i = 0; i < array.Length; i++)
			{
				Vector3 val = root.InverseTransformPoint(array[i]);
				if (!hasBounds)
				{
					aggregateBounds = new Bounds(val, Vector3.zero);
					hasBounds = true;
				}
				else
				{
					((Bounds)(ref aggregateBounds)).Encapsulate(val);
				}
			}
		}

		private static Collider AddFallbackRootCollider(Transform mikuRoot, Collider templateCollider)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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)
			//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)
			if ((Object)(object)mikuRoot == (Object)null)
			{
				return null;
			}
			Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true);
			Bounds aggregateBounds = default(Bounds);
			bool hasBounds = false;
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					EncapsulateBoundsCorners(ref aggregateBounds, ref hasBounds, mikuRoot, val.bounds);
				}
			}
			if (!hasBounds)
			{
				return null;
			}
			BoxCollider val2 = ((Component)mikuRoot).gameObject.GetComponent<BoxCollider>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)mikuRoot).gameObject.AddComponent<BoxCollider>();
			}
			val2.center = ((Bounds)(ref aggregateBounds)).center;
			val2.size = ClampColliderSize(((Bounds)(ref aggregateBounds)).size);
			CopyColliderSettings(templateCollider, (Collider)(object)val2);
			return (Collider)(object)val2;
		}

		private static void RebuildModelColliders(Item item, Transform mikuRoot)
		{
			if ((Object)(object)item == (Object)null || (Object)(object)mikuRoot == (Object)null)
			{
				return;
			}
			Collider templateCollider = FindColliderTemplate(item);
			Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			List<Collider> list = new List<Collider>();
			bool flag = Plugin.RuntimeReplacementModel != null;
			MeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				Collider val2 = (flag ? AddConvexMeshColliderForMeshRenderer(componentsInChildren2[j], templateCollider) : AddBoxColliderForMeshRenderer(componentsInChildren2[j], templateCollider));
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(val2);
				}
			}
			SkinnedMeshRenderer[] componentsInChildren3 = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				Collider val3 = AddBoxColliderForSkinnedRenderer(componentsInChildren3[k], templateCollider);
				if ((Object)(object)val3 != (Object)null)
				{
					list.Add(val3);
				}
			}
			if (list.Count == 0)
			{
				Collider val4 = AddFallbackRootCollider(mikuRoot, templateCollider);
				if ((Object)(object)val4 != (Object)null)
				{
					list.Add(val4);
				}
			}
			if (list.Count > 0)
			{
				item.colliders = list.ToArray();
				DisableOriginalColliders(item);
			}
		}

		private static void EnsureModelColliders(Item item, Transform mikuRoot)
		{
			if (!((Object)(object)item == (Object)null) && !((Object)(object)mikuRoot == (Object)null))
			{
				Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true);
				if (componentsInChildren.Length == 0)
				{
					RebuildModelColliders(item, mikuRoot);
					componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true);
				}
				if (componentsInChildren.Length != 0)
				{
					SetColliderArrayEnabled(componentsInChildren, enabled: true);
					item.colliders = componentsInChildren;
					DisableOriginalColliders(item);
				}
			}
		}

		private static void SetColliderArrayEnabled(Collider[] colliders, bool enabled)
		{
			if (colliders == null)
			{
				return;
			}
			foreach (Collider val in colliders)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.enabled = enabled;
				}
			}
		}

		private static void SyncCollidersByState(Item item, Transform mikuRoot)
		{
			if (!((Object)(object)item == (Object)null) && !((Object)(object)mikuRoot == (Object)null))
			{
				Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true);
				if (IsHeld(item))
				{
					SetColliderArrayEnabled(componentsInChildren, enabled: false);
					EnableOriginalColliders(item);
				}
				else
				{
					EnsureModelColliders(item, mikuRoot);
				}
			}
		}

		private static int DetermineTargetLayer(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return 0;
			}
			Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform))
				{
					return ((Component)val).gameObject.layer;
				}
			}
			return ((Component)item).gameObject.layer;
		}

		private static void ConfigureMikuRenderer(Renderer renderer, int targetLayer)
		{
			((Component)renderer).gameObject.layer = targetLayer;
			renderer.allowOcclusionWhenDynamic = false;
			renderer.shadowCastingMode = (ShadowCastingMode)1;
			renderer.receiveShadows = true;
			renderer.forceRenderingOff = false;
			renderer.enabled = true;
			renderer.SetPropertyBlock((MaterialPropertyBlock)null);
			if (!((Component)renderer).gameObject.activeSelf)
			{
				((Component)renderer).gameObject.SetActive(true);
			}
		}

		private static bool RendererHasMainTexSlot(Renderer renderer)
		{
			if ((Object)(object)renderer == (Object)null)
			{
				return false;
			}
			Material[] sharedMaterials = renderer.sharedMaterials;
			if (sharedMaterials == null || sharedMaterials.Length == 0)
			{
				return false;
			}
			foreach (Material val in sharedMaterials)
			{
				if ((Object)(object)val != (Object)null && val.HasProperty("_MainTex"))
				{
					return true;
				}
			}
			return false;
		}

		private static Material CreateMainTexCompatMaterial(Texture texture)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0060: 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_0076: Expected O, but got Unknown
			Shader val = Shader.Find("Standard") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("W/Peak_Standard");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val)
			{
				name = "Miku_MainTexCompat",
				color = Color.white,
				renderQueue = 2000
			};
			if ((Object)(object)texture != (Object)null)
			{
				ApplyMikuTextureSafe(val2, texture);
			}
			ApplyRealisticMaterialTuning(val2);
			return val2;
		}

		private static void EnsureRendererMainTexCompatibility(Renderer renderer)
		{
			if ((Object)(object)renderer == (Object)null || Plugin.RuntimeReplacementModel != null)
			{
				return;
			}
			Material[] sharedMaterials = renderer.sharedMaterials;
			if (sharedMaterials == null || sharedMaterials.Length == 0)
			{
				Material val = CreateMainTexCompatMaterial(GetMikuTexture()) ?? CreateRendererMaterialInstance();
				if ((Object)(object)val != (Object)null)
				{
					renderer.sharedMaterial = val;
				}
				return;
			}
			for (int i = 0; i < sharedMaterials.Length; i++)
			{
				if ((Object)(object)sharedMaterials[i] != (Object)null && sharedMaterials[i].HasProperty("_MainTex"))
				{
					return;
				}
			}
			Material val2 = CreateMainTexCompatMaterial(GetMikuTexture());
			if (!((Object)(object)val2 == (Object)null))
			{
				sharedMaterials[0] = val2;
				renderer.sharedMaterials = sharedMaterials;
			}
		}

		private static Renderer[] BuildAdditionalRenderers(Renderer primaryRenderer, Renderer[] renderers)
		{
			if (renderers == null || renderers.Length == 0)
			{
				return Array.Empty<Renderer>();
			}
			List<Renderer> list = new List<Renderer>();
			foreach (Renderer val in renderers)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)primaryRenderer))
				{
					list.Add(val);
				}
			}
			if (list.Count != 0)
			{
				return list.ToArray();
			}
			return Array.Empty<Renderer>();
		}

		private static bool TryGetOriginalItemRenderers(Item item, out Renderer primaryRenderer, out Renderer[] additionalRenderers)
		{
			primaryRenderer = null;
			additionalRenderers = Array.Empty<Renderer>();
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true);
			List<Renderer> list = new List<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform))
				{
					list.Add(val);
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			for (int j = 0; j < list.Count; j++)
			{
				Renderer val2 = list[j];
				if ((Object)(object)primaryRenderer == (Object)null)
				{
					primaryRenderer = val2;
				}
				if (RendererHasMainTexSlot(val2))
				{
					primaryRenderer = val2;
					break;
				}
			}
			if ((Object)(object)primaryRenderer == (Object)null)
			{
				return false;
			}
			additionalRenderers = BuildAdditionalRenderers(primaryRenderer, list.ToArray());
			return true;
		}

		private static void EnsureItemRendererRefs(Item item, Transform mikuRoot)
		{
			if (Plugin.KeepOriginalRendererRefs && TryGetOriginalItemRenderers(item, out var primaryRenderer, out var additionalRenderers))
			{
				item.mainRenderer = primaryRenderer;
				item.addtlRenderers = additionalRenderers;
				return;
			}
			Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren.Length == 0)
			{
				return;
			}
			Renderer val = null;
			foreach (Renderer val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					if ((Object)(object)val == (Object)null)
					{
						val = val2;
					}
					if (RendererHasMainTexSlot(val2))
					{
						val = val2;
						break;
					}
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				EnsureRendererMainTexCompatibility(val);
				item.mainRenderer = val;
				item.addtlRenderers = BuildAdditionalRenderers(val, componentsInChildren);
			}
		}

		private static void RestoreOriginalItemRendererRefs(Item item)
		{
			if (!((Object)(object)item == (Object)null) && TryGetOriginalItemRenderers(item, out var primaryRenderer, out var additionalRenderers))
			{
				item.mainRenderer = primaryRenderer;
				item.addtlRenderers = additionalRenderers;
			}
		}

		private static void RemoveReplacement(Item item, Transform mikuRoot)
		{
			EnableOriginalRenderers(item);
			EnableOriginalColliders(item);
			RestoreOriginalItemRendererRefs(item);
			if ((Object)(object)mikuRoot != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)mikuRoot).gameObject);
			}
		}

		private static void ApplyInitialMikuRendererSetup(Item item, Transform mikuRoot)
		{
			int num = DetermineTargetLayer(item);
			((Component)mikuRoot).gameObject.layer = num;
			MeshRenderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true);
			SkinnedMeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			Plugin.VerboseLog("[ItemPatch] Renderer layout for " + ((Object)item).name + ": MeshRenderers=" + componentsInChildren.Length + ", SkinnedMeshRenderers=" + componentsInChildren2.Length);
			foreach (MeshRenderer renderer in componentsInChildren)
			{
				ConfigureMikuRenderer((Renderer)(object)renderer, num);
				ApplyMaterialToMeshRenderer(renderer);
			}
			foreach (SkinnedMeshRenderer obj in componentsInChildren2)
			{
				obj.updateWhenOffscreen = true;
				ConfigureMikuRenderer((Renderer)(object)obj, num);
				ApplyMaterialToSkinnedRenderer(obj);
			}
			EnsureItemRendererRefs(item, mikuRoot);
		}

		private static bool IsWhitelistedBehaviour(MonoBehaviour behaviour)
		{
			if (!(behaviour is MikuMarker) && !(behaviour is MikuRendererGuard) && !(behaviour is MikuDeformGuard))
			{
				return behaviour is MikuExpressionController;
			}
			return true;
		}

		private static void SanitizeVisualObject(GameObject visualRoot, int targetLayer)
		{
			Collider[] componentsInChildren = visualRoot.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					val.enabled = false;
					Object.Destroy((Object)(object)val);
				}
			}
			Rigidbody[] componentsInChildren2 = visualRoot.GetComponentsInChildren<Rigidbody>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if ((Object)(object)componentsInChildren2[j] != (Object)null)
				{
					Object.Destroy((Object)(object)componentsInChildren2[j]);
				}
			}
			Joint[] componentsInChildren3 = visualRoot.GetComponentsInChildren<Joint>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				if ((Object)(object)componentsInChildren3[k] != (Object)null)
				{
					Object.Destroy((Object)(object)componentsInChildren3[k]);
				}
			}
			LODGroup[] componentsInChildren4 = visualRoot.GetComponentsInChildren<LODGroup>(true);
			foreach (LODGroup val2 in componentsInChildren4)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.enabled = false;
					Object.Destroy((Object)(object)val2);
				}
			}
			MonoBehaviour[] componentsInChildren5 = visualRoot.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val3 in componentsInChildren5)
			{
				if (!((Object)(object)val3 == (Object)null) && !IsWhitelistedBehaviour(val3))
				{
					((Behaviour)val3).enabled = false;
					Object.Destroy((Object)(object)val3);
				}
			}
			Transform[] componentsInChildren6 = visualRoot.GetComponentsInChildren<Transform>(true);
			foreach (Transform val4 in componentsInChildren6)
			{
				if (!((Object)(object)val4 == (Object)null))
				{
					((Component)val4).gameObject.tag = "Untagged";
					((Component)val4).gameObject.layer = targetLayer;
				}
			}
		}

		private static bool ContainsKeyword(string value, string[] keywords)
		{
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			string text = value.ToLowerInvariant();
			for (int i = 0; i < keywords.Length; i++)
			{
				if (text.Contains(keywords[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static void RemoveUnwantedFootAttachments(Transform mikuRoot)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true);
			int num = 0;
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && ContainsKeyword(((Object)((Component)val).gameObject).name, UnwantedFootKeywords))
				{
					Bounds bounds = val.bounds;
					if (!(mikuRoot.InverseTransformPoint(((Bounds)(ref bounds)).center).y > 0.2f))
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
						num++;
					}
				}
			}
			if (num > 0)
			{
				Plugin.VerboseLog("[ItemPatch] Removed unwanted foot attachments: " + num);
			}
		}

		private static void SyncVisibilityState(Item item)
		{
			//IL_0031: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindMikuRoot(item);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int num = DetermineTargetLayer(item);
			((Component)val).gameObject.layer = num;
			ResolvePoseByState(item, out var localPosition, out var localRotation, out var localScale);
			if (val.localPosition != localPosition)
			{
				val.localPosition = localPosition;
			}
			if (val.localRotation != localRotation)
			{
				val.localRotation = localRotation;
			}
			if (val.localScale != localScale)
			{
				val.localScale = localScale;
			}
			MikuDeformGuard component = ((Component)val).GetComponent<MikuDeformGuard>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetRootTarget(localPosition, localRotation, localScale);
			}
			bool flag = ShouldShowReplacement(item);
			if (((Component)val).gameObject.activeSelf != flag)
			{
				((Component)val).gameObject.SetActive(flag);
			}
			if (!flag)
			{
				EnableOriginalRenderers(item);
				EnableOriginalColliders(item);
				RestoreOriginalItemRendererRefs(item);
				return;
			}
			SyncCollidersByState(item, val);
			if (HasVisibleReplacementRenderers(val))
			{
				DisableOriginalRenderers(item);
			}
			else
			{
				EnableOriginalRenderers(item);
			}
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					ConfigureMikuRenderer(val2, num);
				}
			}
			EnsureItemRendererRefs(item, val);
		}

		private static Transform EnsureMikuModel(Item item, bool createIfMissing)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0110: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindMikuRoot(item);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if (!createIfMissing)
			{
				return null;
			}
			GameObject val2 = Plugin.CreateReplacementVisualInstance("MikuFumo_Visual");
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[ItemPatch] Replacement visual is unavailable, cannot create model yet.");
				return null;
			}
			val2.transform.SetParent(((Component)item).transform, false);
			((Object)val2).name = "MikuFumo_Visual";
			val2.SetActive(true);
			int targetLayer = (val2.layer = DetermineTargetLayer(item));
			ResolvePoseByState(item, out var localPosition, out var localRotation, out var localScale);
			val2.transform.localPosition = localPosition;
			val2.transform.localRotation = localRotation;
			val2.transform.localScale = localScale;
			if ((Object)(object)val2.GetComponent<MikuMarker>() == (Object)null)
			{
				val2.AddComponent<MikuMarker>();
			}
			RemoveUnwantedFootAttachments(val2.transform);
			SanitizeVisualObject(val2, targetLayer);
			MikuRendererGuard mikuRendererGuard = val2.GetComponent<MikuRendererGuard>();
			if ((Object)(object)mikuRendererGuard == (Object)null)
			{
				mikuRendererGuard = val2.AddComponent<MikuRendererGuard>();
			}
			mikuRendererGuard.Bind(item);
			MikuDeformGuard mikuDeformGuard = val2.GetComponent<MikuDeformGuard>();
			if ((Object)(object)mikuDeformGuard == (Object)null)
			{
				mikuDeformGuard = val2.AddComponent<MikuDeformGuard>();
			}
			mikuDeformGuard.Bind(item);
			mikuDeformGuard.Initialize(localPosition, localRotation, localScale);
			MikuExpressionController mikuExpressionController = FindExpressionController(val2.transform);
			if ((Object)(object)mikuExpressionController != (Object)null)
			{
				mikuExpressionController.Bind(item);
			}
			ApplyInitialMikuRendererSetup(item, val2.transform);
			RebuildModelColliders(item, val2.transform);
			SyncVisibilityState(item);
			Plugin.VerboseLog("[ItemPatch] Created Miku replacement model under item: " + ((Object)item).name);
			return val2.transform;
		}

		private static void EnsureReplacementAndVisibility(Item item, bool createIfMissing)
		{
			if (!IsBingBong(item))
			{
				return;
			}
			Transform val = FindMikuRoot(item);
			if (!Plugin.ModEnabled)
			{
				if ((Object)(object)val != (Object)null)
				{
					RemoveReplacement(item, val);
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				val = EnsureMikuModel(item, createIfMissing);
			}
			if (!((Object)(object)val == (Object)null))
			{
				MikuRendererGuard component = ((Component)val).GetComponent<MikuRendererGuard>();
				if ((Object)(object)component != (Object)null)
				{
					component.Bind(item);
				}
				MikuDeformGuard component2 = ((Component)val).GetComponent<MikuDeformGuard>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.Bind(item);
				}
				MikuExpressionController mikuExpressionController = FindExpressionController(val);
				if ((Object)(object)mikuExpressionController != (Object)null)
				{
					mikuExpressionController.Bind(item);
				}
				SyncVisibilityState(item);
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Item_Start(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: true);
			if (IsBingBong(__instance))
			{
				Plugin.VerboseLog("[ItemPatch] Model replacement complete for: " + ((Object)__instance).name);
			}
		}

		[HarmonyPatch("OnEnable")]
		[HarmonyPostfix]
		public static void Item_OnEnable(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: true);
		}

		[HarmonyPatch("SetState")]
		[HarmonyPrefix]
		public static void Item_SetState_Prefix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: true);
		}

		[HarmonyPatch("SetState")]
		[HarmonyPostfix]
		public static void Item_SetState_Postfix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: true);
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void Item_Update_Postfix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: false);
		}

		[HarmonyPatch("RequestPickup")]
		[HarmonyPrefix]
		public static void Item_RequestPickup_Prefix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: true);
		}

		[HarmonyPatch("RequestPickup")]
		[HarmonyPostfix]
		public static void Item_RequestPickup_Postfix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: true);
		}

		[HarmonyPatch("HideRenderers")]
		[HarmonyPrefix]
		public static bool Item_HideRenderers_Prefix(Item __instance)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.ModEnabled || !IsBingBong(__instance))
			{
				return true;
			}
			Transform val = EnsureMikuModel(__instance, createIfMissing: false);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			ResolvePoseByState(__instance, out var localPosition, out var localRotation, out var localScale);
			val.localPosition = localPosition;
			val.localRotation = localRotation;
			val.localScale = localScale;
			if (!((Component)val).gameObject.activeSelf)
			{
				((Component)val).gameObject.SetActive(true);
			}
			MikuDeformGuard component = ((Component)val).GetComponent<MikuDeformGuard>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetRootTarget(localPosition, localRotation, localScale);
			}
			SyncCollidersByState(__instance, val);
			int targetLayer = DetermineTargetLayer(__instance);
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					ConfigureMikuRenderer(val2, targetLayer);
				}
			}
			DisableOriginalRenderers(__instance);
			EnsureItemRendererRefs(__instance, val);
			return false;
		}

		[HarmonyPatch("PutInBackpackRPC")]
		[HarmonyPostfix]
		public static void Item_PutInBackpackRPC_Postfix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: false);
		}

		[HarmonyPatch("ClearDataFromBackpack")]
		[HarmonyPostfix]
		public static void Item_ClearDataFromBackpack_Postfix(Item __instance)
		{
			EnsureReplacementAndVisibility(__instance, createIfMissing: false);
		}

		[HarmonyPatch(typeof(ItemUIData), "GetIcon")]
		[HarmonyPostfix]
		public static void Item_GetIcon(ItemUIData __instance, ref Texture2D __result)
		{
			if (Plugin.ModEnabled && __instance.itemName == "Bing Bong" && (Object)(object)Plugin.MochiTexture != (Object)null)
			{
				__result = Plugin.MochiTexture;
			}
		}

		[HarmonyPatch("GetName")]
		[HarmonyPostfix]
		public static void Item_GetName_Postfix(Item __instance, ref string __result)
		{
			if (Plugin.ModEnabled && IsBingBong(__instance))
			{
				__result = Plugin.ReplacementDisplayName;
			}
		}

		[HarmonyPatch("GetItemName")]
		[HarmonyPostfix]
		public static void Item_GetItemName_Postfix(Item __instance, ref string __result)
		{
			if (Plugin.ModEnabled && IsBingBong(__instance))
			{
				__result = Plugin.ReplacementDisplayName;
			}
		}
	}
	[HarmonyPatch]
	public static class MikuTintCompatibilityPatch
	{
		private delegate void ItemCookingIntMethod(ItemCooking instance, int value);

		private static readonly FieldRef<BackpackOnBackVisuals, MeshRenderer[]> BackpackRenderersRef = AccessTools.FieldRefAccess<BackpackOnBackVisuals, MeshRenderer[]>("renderers");

		private static readonly FieldRef<BackpackOnBackVisuals, Color[]> BackpackDefaultTintsRef = AccessTools.FieldRefAccess<BackpackOnBackVisuals, Color[]>("defaultTints");

		private static readonly FieldRef<ItemCooking, Renderer[]> ItemCookingRenderersRef = AccessTools.FieldRefAccess<ItemCooking, Renderer[]>("renderers");

		private static readonly FieldRef<ItemCooking, Color[]> ItemCookingDefaultTintsRef = AccessTools.FieldRefAccess<ItemCooking, Color[]>("defaultTints");

		private static readonly FieldRef<ItemCooking, bool> ItemCookingSetupRef = AccessTools.FieldRefAccess<ItemCooking, bool>("setup");

		private static readonly FieldRef<ItemCooking, int> ItemCookingPreCookedRef = AccessTools.FieldRefAccess<ItemCooking, int>("preCooked");

		private static readonly FieldRef<ItemCooking, bool> ItemCookingIgnoreDefaultCookBehaviorRef = AccessTools.FieldRefAccess<ItemCooking, bool>("ignoreDefaultCookBehavior");

		private static readonly FieldRef<ItemCooking, int> ItemCookingTimesCookedLocalRef = AccessTools.FieldRefAccess<ItemCooking, int>("<timesCookedLocal>k__BackingField");

		private static readonly ItemCookingIntMethod RunAdditionalCookingBehaviorsDelegate = AccessTools.MethodDelegate<ItemCookingIntMethod>(AccessTools.Method(typeof(ItemCooking), "RunAdditionalCookingBehaviors", (Type[])null, (Type[])null), (object)null, true);

		private static readonly ItemCookingIntMethod ChangeStatsCookedDelegate = AccessTools.MethodDelegate<ItemCookingIntMethod>(AccessTools.Method(typeof(ItemCooking), "ChangeStatsCooked", (Type[])null, (Type[])null), (object)null, true);

		private static readonly ItemCookingIntMethod CookVisuallyDelegate = AccessTools.MethodDelegate<ItemCookingIntMethod>(AccessTools.Method(typeof(ItemCooking), "CookVisually", (Type[])null, (Type[])null), (object)null, true);

		private static Color GetSafeTint(Material material)
		{
			//IL_0009: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)material == (Object)null)
			{
				return Color.white;
			}
			if (material.HasProperty("_Tint"))
			{
				return material.GetColor("_Tint");
			}
			if (material.HasProperty("_BaseColor"))
			{
				return material.GetColor("_BaseColor");
			}
			if (material.HasProperty("_Color"))
			{
				return material.GetColor("_Color");
			}
			return Color.white;
		}

		private static void TryApplyTint(Material material, Color color)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)material != (Object)null && material.HasProperty("_Tint"))