Decompiled source of MikuShowcase v1.0.1

plugins/com.github.Thanks.MikuShowcase.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using MikuDanceProject.Core;
using MikuDanceProject.Mmd;
using MikuDanceProject.Runtime;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	internal static class IsExternalInit
	{
	}
}
namespace MikuDanceProject.Mmd
{
	internal static class CoordinateConverter
	{
		public static Vector3 Position(Vector3 value)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(0f - value.x, value.y, value.z);
		}

		public static Vector3 Normal(Vector3 value)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(0f - value.x, value.y, value.z);
		}

		public static Quaternion Rotation(Quaternion value)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(value.x, 0f - value.y, 0f - value.z, value.w);
		}
	}
	internal static class BinaryReaderExtensions
	{
		public static Vector2 ReadVector2(this BinaryReader reader)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(reader.ReadSingle(), reader.ReadSingle());
		}

		public static Vector3 ReadVector3(this BinaryReader reader)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
		}

		public static Vector4 ReadVector4(this BinaryReader reader)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
		}

		public static Quaternion ReadQuaternion(this BinaryReader reader)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
		}

		public static string ReadPmxString(this BinaryReader reader, Encoding encoding)
		{
			int num = reader.ReadInt32();
			if (num <= 0)
			{
				return string.Empty;
			}
			byte[] bytes = reader.ReadBytes(num);
			return encoding.GetString(bytes);
		}

		public static string ReadFixedString(this BinaryReader reader, int byteCount, Encoding encoding)
		{
			byte[] array = reader.ReadBytes(byteCount);
			int num = Array.IndexOf(array, (byte)0);
			if (num < 0)
			{
				num = array.Length;
			}
			return encoding.GetString(array, 0, num).Trim();
		}

		public static int ReadSizedIndex(this BinaryReader reader, int size, bool allowNegative = true)
		{
			return size switch
			{
				1 => allowNegative ? ((int)reader.ReadSByte()) : ((int)reader.ReadByte()), 
				2 => allowNegative ? ((int)reader.ReadInt16()) : ((int)reader.ReadUInt16()), 
				4 => reader.ReadInt32(), 
				_ => throw new InvalidDataException($"Unsupported PMX index size: {size}."), 
			};
		}
	}
	internal sealed class PmxModel
	{
		public string ModelName { get; init; } = string.Empty;


		public List<PmxVertex> Vertices { get; } = new List<PmxVertex>();


		public List<int> Indices { get; } = new List<int>();


		public List<string> Textures { get; } = new List<string>();


		public List<PmxMaterial> Materials { get; } = new List<PmxMaterial>();


		public List<PmxBone> Bones { get; } = new List<PmxBone>();


		public List<PmxMorph> Morphs { get; } = new List<PmxMorph>();

	}
	internal sealed class PmxVertex
	{
		public Vector3 Position { get; init; }

		public Vector3 Normal { get; init; }

		public Vector2 Uv { get; init; }

		public BoneWeight BoneWeight { get; init; }
	}
	internal sealed class PmxMaterial
	{
		public string Name { get; init; } = string.Empty;


		public Color Diffuse { get; init; } = Color.white;


		public int TextureIndex { get; init; }

		public int IndexCount { get; init; }
	}
	internal sealed class PmxBone
	{
		public string NameLocal { get; init; } = string.Empty;


		public string NameUniversal { get; init; } = string.Empty;


		public int ParentIndex { get; init; }

		public Vector3 Position { get; init; }

		public PmxIkDefinition? IkDefinition { get; init; }

		public string DisplayName
		{
			get
			{
				if (!string.IsNullOrWhiteSpace(NameLocal))
				{
					return NameLocal;
				}
				return NameUniversal;
			}
		}
	}
	internal sealed class PmxIkDefinition
	{
		public int TargetBoneIndex { get; init; }

		public int LoopCount { get; init; }

		public float LimitRadian { get; init; }

		public List<PmxIkLink> Links { get; } = new List<PmxIkLink>();

	}
	internal sealed class PmxIkLink
	{
		public int BoneIndex { get; init; }

		public bool HasAngleLimit { get; init; }

		public Vector3 MinimumAngle { get; init; }

		public Vector3 MaximumAngle { get; init; }
	}
	internal sealed class PmxMorph
	{
		public string NameLocal { get; init; } = string.Empty;


		public string NameUniversal { get; init; } = string.Empty;


		public byte MorphType { get; init; }

		public List<PmxVertexMorphOffset> VertexOffsets { get; } = new List<PmxVertexMorphOffset>();


		public List<PmxGroupMorphOffset> GroupOffsets { get; } = new List<PmxGroupMorphOffset>();


		public string DisplayName
		{
			get
			{
				if (!string.IsNullOrWhiteSpace(NameLocal))
				{
					return NameLocal;
				}
				return NameUniversal;
			}
		}
	}
	internal sealed class PmxVertexMorphOffset
	{
		public int VertexIndex { get; init; }

		public Vector3 PositionOffset { get; init; }
	}
	internal sealed class PmxGroupMorphOffset
	{
		public int MorphIndex { get; init; }

		public float Weight { get; init; }
	}
	internal sealed class VmdMotion
	{
		public string ModelName { get; init; } = string.Empty;


		public List<VmdBoneFrame> BoneFrames { get; } = new List<VmdBoneFrame>();


		public List<VmdMorphFrame> MorphFrames { get; } = new List<VmdMorphFrame>();

	}
	internal sealed class VmdBoneFrame
	{
		public string BoneName { get; init; } = string.Empty;


		public uint FrameIndex { get; init; }

		public Vector3 Position { get; init; }

		public Quaternion Rotation { get; init; }
	}
	internal sealed class VmdMorphFrame
	{
		public string MorphName { get; init; } = string.Empty;


		public uint FrameIndex { get; init; }

		public float Weight { get; init; }
	}
	internal static class VmdReader
	{
		private const int HeaderByteCount = 30;

		private const int ModelNameByteCount = 20;

		private const int BoneNameByteCount = 15;

		private const int MorphNameByteCount = 15;

		private const int BoneFramePayloadByteCount = 96;

		private const int BoneFrameByteCount = 111;

		public static VmdMotion Read(string filePath)
		{
			using FileStream input = File.OpenRead(filePath);
			using BinaryReader reader = new BinaryReader(input);
			return Read(reader, includeBoneFrames: true);
		}

		public static VmdMotion Read(byte[] bytes)
		{
			using MemoryStream input = new MemoryStream(bytes, writable: false);
			using BinaryReader reader = new BinaryReader(input);
			return Read(reader, includeBoneFrames: true);
		}

		public static VmdMotion ReadMorphOnly(byte[] bytes)
		{
			using MemoryStream input = new MemoryStream(bytes, writable: false);
			using BinaryReader reader = new BinaryReader(input);
			return Read(reader, includeBoneFrames: false);
		}

		private static VmdMotion Read(BinaryReader reader, bool includeBoneFrames)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00b6: 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)
			string text = Encoding.ASCII.GetString(reader.ReadBytes(30)).TrimEnd('\0', ' ');
			if (!text.StartsWith("Vocaloid Motion Data", StringComparison.Ordinal))
			{
				throw new InvalidDataException("Unexpected VMD header: " + text);
			}
			VmdMotion vmdMotion = new VmdMotion
			{
				ModelName = ReadShiftJisString(reader, 20)
			};
			uint num = reader.ReadUInt32();
			if (includeBoneFrames)
			{
				for (uint num2 = 0u; num2 < num; num2++)
				{
					string boneName = ReadShiftJisString(reader, 15);
					uint frameIndex = reader.ReadUInt32();
					Vector3 position = CoordinateConverter.Position(reader.ReadVector3());
					Quaternion rotation = CoordinateConverter.Rotation(reader.ReadQuaternion());
					reader.ReadBytes(64);
					vmdMotion.BoneFrames.Add(new VmdBoneFrame
					{
						BoneName = boneName,
						FrameIndex = frameIndex,
						Position = position,
						Rotation = rotation
					});
				}
			}
			else
			{
				checked
				{
					SkipBytes(reader, unchecked((long)num) * 111L);
				}
			}
			uint num3 = reader.ReadUInt32();
			for (uint num4 = 0u; num4 < num3; num4++)
			{
				vmdMotion.MorphFrames.Add(new VmdMorphFrame
				{
					MorphName = ReadShiftJisString(reader, 15),
					FrameIndex = reader.ReadUInt32(),
					Weight = reader.ReadSingle()
				});
			}
			return vmdMotion;
		}

		private static string ReadShiftJisString(BinaryReader reader, int byteCount)
		{
			return ShiftJisDecoder.Decode(reader.ReadBytes(byteCount));
		}

		private static void SkipBytes(BinaryReader reader, long byteCount)
		{
			if (byteCount <= 0)
			{
				return;
			}
			Stream baseStream = reader.BaseStream;
			if (baseStream.CanSeek)
			{
				baseStream.Seek(byteCount, SeekOrigin.Current);
				return;
			}
			long num = byteCount;
			byte[] array = new byte[4096];
			while (num > 0)
			{
				int count = (int)Math.Min(num, array.Length);
				int num2 = reader.Read(array, 0, count);
				if (num2 <= 0)
				{
					throw new EndOfStreamException("Unexpected end of stream while skipping VMD bone frames.");
				}
				num -= num2;
			}
		}
	}
	internal static class VmdAnimationBuilder
	{
		private static readonly HashSet<string> IgnoredControlBones = new HashSet<string>(StringComparer.Ordinal) { "全ての親", "センター", "グルーブ", "操作中心", "センター先", "Root", "Center", "Groove" };

		public static AnimationClip BuildLegacyClip(VmdMotion motion, Transform animationRoot, IReadOnlyDictionary<string, Transform> boneMap, SkinnedMeshRenderer renderer, out int matchedBoneCount, out int matchedMorphCount)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			matchedBoneCount = 0;
			matchedMorphCount = 0;
			AnimationClip val = new AnimationClip
			{
				name = (string.IsNullOrWhiteSpace(motion.ModelName) ? "MikuDanceMotion" : motion.ModelName),
				legacy = true,
				wrapMode = (WrapMode)2
			};
			foreach (IGrouping<string, VmdBoneFrame> item in from frame in motion.BoneFrames
				where !string.IsNullOrWhiteSpace(frame.BoneName)
				group frame by frame.BoneName)
			{
				if (IgnoredControlBones.Contains(item.Key) || !boneMap.TryGetValue(item.Key, out Transform value))
				{
					continue;
				}
				matchedBoneCount++;
				string text = BuildPath(animationRoot, value);
				VmdBoneFrame[] array = (from frame in item
					group frame by frame.FrameIndex into @group
					select @group.Last() into frame
					orderby frame.FrameIndex
					select frame).ToArray();
				if (array.Length != 0)
				{
					Vector3 localPosition = value.localPosition;
					Quaternion localRotation = value.localRotation;
					AnimationCurve val2 = new AnimationCurve();
					AnimationCurve val3 = new AnimationCurve();
					AnimationCurve val4 = new AnimationCurve();
					AnimationCurve val5 = new AnimationCurve();
					AnimationCurve val6 = new AnimationCurve();
					AnimationCurve val7 = new AnimationCurve();
					AnimationCurve val8 = new AnimationCurve();
					if (array[0].FrameIndex != 0)
					{
						AddTransformKey(0f, localPosition, localRotation, val2, val3, val4, val5, val6, val7, val8);
					}
					VmdBoneFrame[] array2 = array;
					foreach (VmdBoneFrame vmdBoneFrame in array2)
					{
						AddTransformKey((float)vmdBoneFrame.FrameIndex / 30f, localPosition + vmdBoneFrame.Position, localRotation * vmdBoneFrame.Rotation, val2, val3, val4, val5, val6, val7, val8);
					}
					MakeCurvesLinear(val2, val3, val4, val5, val6, val7, val8);
					val.SetCurve(text, typeof(Transform), "localPosition.x", val2);
					val.SetCurve(text, typeof(Transform), "localPosition.y", val3);
					val.SetCurve(text, typeof(Transform), "localPosition.z", val4);
					val.SetCurve(text, typeof(Transform), "localRotation.x", val5);
					val.SetCurve(text, typeof(Transform), "localRotation.y", val6);
					val.SetCurve(text, typeof(Transform), "localRotation.z", val7);
					val.SetCurve(text, typeof(Transform), "localRotation.w", val8);
				}
			}
			matchedMorphCount = BuildMorphCurves(motion, animationRoot, renderer, val, 0u);
			val.EnsureQuaternionContinuity();
			return val;
		}

		public static AnimationClip? BuildMorphOnlyClip(VmdMotion motion, Transform animationRoot, SkinnedMeshRenderer renderer, uint trimStartFrame, out int matchedMorphCount)
		{
			//IL_0004: 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_0033: 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_0042: Expected O, but got Unknown
			matchedMorphCount = 0;
			AnimationClip val = new AnimationClip
			{
				name = (string.IsNullOrWhiteSpace(motion.ModelName) ? "MikuMorphMotion" : (motion.ModelName + "_Morph")),
				legacy = true,
				wrapMode = (WrapMode)2
			};
			matchedMorphCount = BuildMorphCurves(motion, animationRoot, renderer, val, trimStartFrame);
			if (matchedMorphCount <= 0)
			{
				return null;
			}
			return val;
		}

		private static int BuildMorphCurves(VmdMotion motion, Transform animationRoot, SkinnedMeshRenderer renderer, AnimationClip clip, uint trimStartFrame)
		{
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			Mesh sharedMesh = renderer.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null || sharedMesh.blendShapeCount == 0)
			{
				return 0;
			}
			string text = BuildPath(animationRoot, ((Component)renderer).transform);
			Dictionary<string, string> dictionary = (from @group in (from name in Enumerable.Range(0, sharedMesh.blendShapeCount).Select((Func<int, string>)sharedMesh.GetBlendShapeName)
					where !string.IsNullOrWhiteSpace(name)
					select name).GroupBy<string, string>(NormalizeMorphNameForMatch, StringComparer.Ordinal)
				where !string.IsNullOrWhiteSpace(@group.Key)
				select @group).ToDictionary<IGrouping<string, string>, string, string>((IGrouping<string, string> group) => group.Key, (IGrouping<string, string> group) => group.OrderBy((string name) => name.Length).ThenBy<string, string>((string name) => name, StringComparer.Ordinal).First(), StringComparer.Ordinal);
			int num = 0;
			foreach (IGrouping<string, VmdMorphFrame> item in from frame in motion.MorphFrames
				where !string.IsNullOrWhiteSpace(frame.MorphName)
				group frame by frame.MorphName)
			{
				string text2 = NormalizeMorphNameForMatch(item.Key);
				if (string.IsNullOrWhiteSpace(text2) || !dictionary.TryGetValue(text2, out var value))
				{
					continue;
				}
				VmdMorphFrame[] array = (from frame in item
					group frame by frame.FrameIndex into @group
					select @group.Last() into frame
					where frame.FrameIndex >= trimStartFrame
					orderby frame.FrameIndex
					select frame).ToArray();
				if (array.Length != 0)
				{
					AnimationCurve val = new AnimationCurve();
					if (array[0].FrameIndex > trimStartFrame)
					{
						val.AddKey(0f, 0f);
					}
					VmdMorphFrame[] array2 = array;
					foreach (VmdMorphFrame vmdMorphFrame in array2)
					{
						val.AddKey((float)(vmdMorphFrame.FrameIndex - trimStartFrame) / 30f, vmdMorphFrame.Weight * 100f);
					}
					MakeCurvesLinear(val);
					clip.SetCurve(text, typeof(SkinnedMeshRenderer), "blendShape." + value, val);
					num++;
				}
			}
			return num;
		}

		private static string NormalizeMorphNameForMatch(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return string.Empty;
			}
			char[] array = new char[value.Length];
			int num = 0;
			for (int i = 0; i < value.Length; i++)
			{
				char c = char.ToLowerInvariant(value[i]);
				if (!char.IsWhiteSpace(c) && c != '_' && c != '-' && c != '.' && c != '/' && c != '\\' && c != '(' && c != ')' && c != '[' && c != ']' && c != '・')
				{
					array[num++] = c;
				}
			}
			if (num == 0)
			{
				return string.Empty;
			}
			string text = new string(array, 0, num);
			int j;
			for (j = 0; j < text.Length && char.IsDigit(text[j]); j++)
			{
			}
			if (j <= 0 || j >= text.Length)
			{
				return text;
			}
			return text.Substring(j);
		}

		internal static string NormalizeMorphNameForDiagnostics(string value)
		{
			return NormalizeMorphNameForMatch(value);
		}

		private static void AddTransformKey(float time, Vector3 position, Quaternion rotation, AnimationCurve posX, AnimationCurve posY, AnimationCurve posZ, AnimationCurve rotX, AnimationCurve rotY, AnimationCurve rotZ, AnimationCurve rotW)
		{
			//IL_0002: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			posX.AddKey(time, position.x);
			posY.AddKey(time, position.y);
			posZ.AddKey(time, position.z);
			rotX.AddKey(time, rotation.x);
			rotY.AddKey(time, rotation.y);
			rotZ.AddKey(time, rotation.z);
			rotW.AddKey(time, rotation.w);
		}

		private static void MakeCurvesLinear(params AnimationCurve[] curves)
		{
			foreach (AnimationCurve val in curves)
			{
				for (int j = 0; j < val.length; j++)
				{
					AnimationUtilityCompat.SetKeyLinear(val, j);
				}
			}
		}

		private static string BuildPath(Transform root, Transform target)
		{
			if ((Object)(object)target == (Object)(object)root)
			{
				return string.Empty;
			}
			Stack<string> stack = new Stack<string>();
			Transform val = target;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				stack.Push(((Object)val).name);
				val = val.parent;
			}
			return string.Join("/", stack.ToArray());
		}
	}
	internal static class AnimationUtilityCompat
	{
		public static void SetKeyLinear(AnimationCurve curve, int index)
		{
			//IL_000c: 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_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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0052: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			if (curve.length >= 2)
			{
				Keyframe val = curve[index];
				int num = Mathf.Max(index - 1, 0);
				int num2 = Mathf.Min(index + 1, curve.length - 1);
				if (num != index)
				{
					Keyframe from = curve[num];
					((Keyframe)(ref val)).inTangent = CalculateTangent(from, val);
				}
				if (num2 != index)
				{
					Keyframe to = curve[num2];
					((Keyframe)(ref val)).outTangent = CalculateTangent(val, to);
				}
				curve.MoveKey(index, val);
			}
		}

		private static float CalculateTangent(Keyframe from, Keyframe to)
		{
			float num = ((Keyframe)(ref to)).time - ((Keyframe)(ref from)).time;
			if (Mathf.Abs(num) <= float.Epsilon)
			{
				return 0f;
			}
			return (((Keyframe)(ref to)).value - ((Keyframe)(ref from)).value) / num;
		}
	}
	internal static class ShiftJisDecoder
	{
		private const uint CodePageShiftJis = 932u;

		private static readonly bool IsWindowsPlatform = IsRunningOnWindows();

		private static readonly bool CodePagesProviderRegistered = TryRegisterCodePagesProvider();

		private static readonly Encoding? CachedShiftJisEncoding = CreateShiftJisEncoding();

		public static string DiagnosticSummary
		{
			get
			{
				if (CachedShiftJisEncoding == null)
				{
					if (!IsWindowsPlatform)
					{
						return $"fallback-utf8-ascii(providerRegistered={CodePagesProviderRegistered})";
					}
					return $"kernel32-cp932(providerRegistered={CodePagesProviderRegistered})";
				}
				return $"{CachedShiftJisEncoding.WebName}(codePage={CachedShiftJisEncoding.CodePage}, providerRegistered={CodePagesProviderRegistered})";
			}
		}

		public static string Decode(byte[] bytes)
		{
			int num = Array.IndexOf(bytes, (byte)0);
			if (num < 0)
			{
				num = bytes.Length;
			}
			if (num == 0)
			{
				return string.Empty;
			}
			if (CachedShiftJisEncoding != null)
			{
				try
				{
					return CachedShiftJisEncoding.GetString(bytes, 0, num);
				}
				catch
				{
				}
			}
			if (TryDecodeWithWindowsCodePage(bytes, num, out string value))
			{
				return value;
			}
			try
			{
				return Encoding.UTF8.GetString(bytes, 0, num);
			}
			catch
			{
				return Encoding.ASCII.GetString(bytes, 0, num);
			}
		}

		private static Encoding? CreateShiftJisEncoding()
		{
			_ = CodePagesProviderRegistered;
			Encoding encoding = TryGetEncoding(932);
			if (encoding != null)
			{
				return encoding;
			}
			encoding = TryGetEncoding("shift_jis");
			if (encoding != null)
			{
				return encoding;
			}
			encoding = TryGetEncoding("shift-jis");
			if (encoding != null)
			{
				return encoding;
			}
			return TryGetEncoding("cp932");
		}

		private static Encoding? TryGetEncoding(int codePage)
		{
			try
			{
				return Encoding.GetEncoding(codePage);
			}
			catch
			{
				return null;
			}
		}

		private static Encoding? TryGetEncoding(string name)
		{
			try
			{
				return Encoding.GetEncoding(name);
			}
			catch
			{
				return null;
			}
		}

		private static bool TryDecodeWithWindowsCodePage(byte[] bytes, int length, out string value)
		{
			value = string.Empty;
			if (!IsWindowsPlatform || length <= 0)
			{
				return false;
			}
			try
			{
				int num = MultiByteToWideCharCount(932u, 0u, bytes, length, IntPtr.Zero, 0);
				if (num <= 0)
				{
					return false;
				}
				char[] array = new char[num];
				int num2 = MultiByteToWideCharChars(932u, 0u, bytes, length, array, array.Length);
				if (num2 <= 0)
				{
					return false;
				}
				value = new string(array, 0, num2);
				return true;
			}
			catch (DllNotFoundException)
			{
				return false;
			}
			catch (EntryPointNotFoundException)
			{
				return false;
			}
			catch (BadImageFormatException)
			{
				return false;
			}
		}

		private static bool TryRegisterCodePagesProvider()
		{
			try
			{
				Type type = ResolveCodePagesProviderType();
				if (type == null)
				{
					return false;
				}
				object obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null);
				if (obj == null)
				{
					return false;
				}
				MethodInfo methodInfo = typeof(Encoding).GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault((MethodInfo method) => string.Equals(method.Name, "RegisterProvider", StringComparison.Ordinal) && method.GetParameters().Length == 1);
				if (methodInfo == null)
				{
					return false;
				}
				methodInfo.Invoke(null, new object[1] { obj });
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static Type? ResolveCodePagesProviderType()
		{
			Type type = Type.GetType("System.Text.CodePagesEncodingProvider, System.Text.Encoding.CodePages", throwOnError: false);
			if (type != null)
			{
				return type;
			}
			try
			{
				type = Assembly.Load("System.Text.Encoding.CodePages").GetType("System.Text.CodePagesEncodingProvider", throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			catch
			{
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				type = assemblies[i].GetType("System.Text.CodePagesEncodingProvider", throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}

		private static bool IsRunningOnWindows()
		{
			PlatformID platform = Environment.OSVersion.Platform;
			if ((uint)platform <= 3u)
			{
				return true;
			}
			return false;
		}

		[DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "MultiByteToWideChar", SetLastError = true)]
		private static extern int MultiByteToWideCharCount(uint codePage, uint flags, byte[] multiByteString, int byteCount, IntPtr wideCharBuffer, int wideCharCount);

		[DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "MultiByteToWideChar", SetLastError = true)]
		private static extern int MultiByteToWideCharChars(uint codePage, uint flags, byte[] multiByteString, int byteCount, [Out] char[] wideCharBuffer, int wideCharCount);
	}
}
namespace MikuDanceProject.Runtime
{
	internal sealed class DanceController : MonoBehaviour
	{
		private sealed class RuntimeLightingMaterialSnapshot
		{
			private readonly Dictionary<string, Color> _colors = new Dictionary<string, Color>();

			private RuntimeLightingMaterialSnapshot()
			{
			}

			public static RuntimeLightingMaterialSnapshot Capture(Material material, IEnumerable<string> propertyNames)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				RuntimeLightingMaterialSnapshot runtimeLightingMaterialSnapshot = new RuntimeLightingMaterialSnapshot();
				foreach (string propertyName in propertyNames)
				{
					if (material.HasProperty(propertyName))
					{
						runtimeLightingMaterialSnapshot._colors[propertyName] = material.GetColor(propertyName);
					}
				}
				return runtimeLightingMaterialSnapshot;
			}

			public bool TryGetColor(string propertyName, out Color color)
			{
				return _colors.TryGetValue(propertyName, out color);
			}
		}

		private readonly struct PlacementPose
		{
			public Vector3 Position { get; }

			public Vector3 Forward { get; }

			public string Source { get; }

			private PlacementPose(Vector3 position, Vector3 forward, string source)
			{
				//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)
				Position = position;
				Forward = forward;
				Source = source;
			}

			public static PlacementPose Create(Vector3 position, Vector3 forward, string source)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return new PlacementPose(position, forward, source);
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateSecondaryAnimators>d__234 : IEnumerable<Animator>, IEnumerable, IEnumerator<Animator>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Animator <>2__current;

			private int <>l__initialThreadId;

			public DanceController <>4__this;

			private int <index>5__2;

			Animator IEnumerator<Animator>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateSecondaryAnimators>d__234(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				DanceController danceController = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_007f;
				}
				<>1__state = -1;
				if (danceController._activeAnimators == null || danceController._activeAnimators.Length == 0)
				{
					return false;
				}
				<index>5__2 = 0;
				goto IL_008f;
				IL_007f:
				<index>5__2++;
				goto IL_008f;
				IL_008f:
				if (<index>5__2 < danceController._activeAnimators.Length)
				{
					Animator val = danceController._activeAnimators[<index>5__2];
					if (!((Object)(object)val == (Object)null) && val != danceController._activeAnimator && !((Object)(object)val.runtimeAnimatorController == (Object)null))
					{
						<>2__current = val;
						<>1__state = 1;
						return true;
					}
					goto IL_007f;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Animator> IEnumerable<Animator>.GetEnumerator()
			{
				<EnumerateSecondaryAnimators>d__234 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <EnumerateSecondaryAnimators>d__234(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Animator>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadAssetsRoutine>d__109 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public DanceController <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadAssetsRoutine>d__109(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				DanceController danceController = <>4__this;
				if (num != 0)
				{
					return false;
				}
				<>1__state = -1;
				if (danceController._config == null || danceController._logger == null || danceController._isLoading || danceController._loadedPrefab != null)
				{
					return false;
				}
				danceController._isLoading = true;
				string text = danceController._config.ResolveUnityBundlePath();
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				danceController.LogVerbose("Starting Unity asset bundle load. bundlePath='" + text + "'.");
				try
				{
					if (!File.Exists(text))
					{
						danceController._logger.LogError((object)("Required Unity asset bundle file was not found: '" + text + "'."));
						return false;
					}
					danceController._loadedPrefab = danceController._unityBundleLoader.Load(text, danceController._logger);
					Object.DontDestroyOnLoad((Object)(object)danceController._loadedPrefab.Template);
					danceController.LogVerbose($"Using Unity asset bundle dancer source '{text}'. loadDuration={Time.realtimeSinceStartup - realtimeSinceStartup:0.###}s.");
				}
				catch (Exception arg)
				{
					danceController._logger.LogError((object)$"Failed to load Unity asset bundle dancer source '{text}': {arg}");
				}
				finally
				{
					danceController._isLoading = false;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const float GroundProbeStartHeight = 80f;

		private const float GroundProbeDistance = 200f;

		private const float PlayerGroundProbeStartHeight = 1.25f;

		private const float PlayerGroundProbeMaxRise = 0.6f;

		private const float PlayerGroundProbePreferredMaxDrop = 0.9f;

		private const float PlayerGroundProbeFallbackMaxDrop = 1.25f;

		private const float PlayerGroundProbeSearchRadius = 3f;

		private const float PlayerColliderFootPadding = 0.05f;

		private const float RuntimeRefreshInterval = 0.25f;

		private const float OfflinePauseTimeScaleThreshold = 0.001f;

		private const float DistancePauseThresholdMeters = 100f;

		private const float AudioMinDistanceMeters = 1f;

		private const float LegacyMotionTrimStartFrame = 0f;

		private const float LegacyMotionFrameRate = 30f;

		private const float AudioFadeDurationSeconds = 0.35f;

		private const float AudioRestartLeadTimeSeconds = 0.05f;

		private const float AudioDriftCorrectionThresholdSeconds = 0.35f;

		private const float AudioHardResyncThresholdSeconds = 1.25f;

		private const float SavePlacementHoldDurationSeconds = 3f;

		private static readonly bool EnableVerboseRuntimeLogs = false;

		private static readonly string[] NativeFacialClipTokens = new string[21]
		{
			"face", "facial", "expression", "morph", "blend", "blendshape", "viseme", "mouth", "lip", "eye",
			"brow", "smile", "blink", "表情", "脸", "口", "目", "眉", "モーフ", "フェイス",
			"表情"
		};

		private const string ShadowBlobObjectName = "MikuShadowBlob";

		private const int ShadowBlobTextureSize = 64;

		private const float ShadowBlobOpacity = 0.38f;

		private const float ShadowBlobWorldLift = 0.025f;

		private const float ShadowBlobWidthFactor = 0.34f;

		private const float ShadowBlobDepthFactor = 0.24f;

		private const float ShadowBlobMinWorldWidth = 0.85f;

		private const float ShadowBlobMaxWorldWidth = 2.4f;

		private const float ShadowBlobMinWorldDepth = 0.65f;

		private const float ShadowBlobMaxWorldDepth = 1.8f;

		private static readonly string[] PreferredPivotBoneTokens = new string[12]
		{
			"hips", "pelvis", "hip", "cf_j_hips", "j_bip_c_hips", "j_bip_c_pelvis", "腰", "下半身", "骨盤", "センター",
			"center", "centre"
		};

		private static readonly string[] LightingSensitiveShaderTokens = new string[6] { "lit", "toon", "mmd", "standard", "outline", "cel" };

		private static readonly string[] LightingNeutralShaderTokens = new string[3] { "unlit", "sprites/default", "sprite" };

		private static readonly string[] LightingSensitiveMaterialProperties = new string[12]
		{
			"_Ambient", "_IndirectLightMinColor", "_CelShadeMidPoint", "_CelShadeSoftness", "_ReceiveShadowMappingAmount", "_ShadowMapColor", "_SpecularHighlights", "_EnvironmentReflections", "_Metallic", "_Smoothness",
			"_Glossiness", "_SpecColor"
		};

		private static readonly string[] RuntimeLightingExposureColorProperties = new string[5] { "_BaseColor", "_Color", "_TintColor", "_MainColor", "_LitColor" };

		private const BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private const BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private const string DancerObjectName = "MikuDanceDisplay";

		private const string WrappedModelRootName = "MikuLobbyModel";

		private static readonly DancePlaybackMetadata LegacyPlaybackMetadata = DancePlaybackMetadata.CreateDefault();

		private static readonly Vector3 AirportDisplayPosition = new Vector3(-16.78f, 2.55f, 64.85f);

		private static readonly Vector3 AirportDisplayForward = Vector3.right;

		private static readonly Vector3[] PlayerGroundProbeSampleOffsets = BuildPlayerGroundSampleOffsets();

		private static readonly Type? CharacterType = FindGameType("Character");

		private static readonly Type? PlayerType = FindGameType("Player");

		private static readonly Type? MenuWindowType = FindGameType("MenuWindow");

		private static readonly FieldInfo? LocalCharacterField = CharacterType?.GetField("localCharacter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo? LocalPlayerField = PlayerType?.GetField("localPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo? AllActiveWindowsField = MenuWindowType?.GetField("AllActiveWindows", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo? CharacterCenterProperty = CharacterType?.GetProperty("Center", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo? CharacterVirtualCenterProperty = CharacterType?.GetProperty("VirtualCenter", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo? PlayerCharacterProperty = PlayerType?.GetProperty("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo? PlayerCharacterField = PlayerType?.GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo? MenuWindowIsOpenProperty = MenuWindowType?.GetProperty("isOpen", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private readonly UnityAssetBundleLoader _unityBundleLoader = new UnityAssetBundleLoader();

		private DancePluginConfig? _config;

		private ManualLogSource? _logger;

		private LoadedDancePrefab? _loadedPrefab;

		private GameObject? _activeDancer;

		private Animator? _activeAnimator;

		private Animator[] _activeAnimators = Array.Empty<Animator>();

		private Animation? _activeAnimation;

		private AudioSource? _activeAudioSource;

		private AnimationClip? _activePrimaryAnimatorClip;

		private readonly List<Material> _runtimeLightingStabilizedMaterials = new List<Material>();

		private readonly Dictionary<Material, RuntimeLightingMaterialSnapshot> _runtimeLightingMaterialSnapshots = new Dictionary<Material, RuntimeLightingMaterialSnapshot>();

		private PlacementPose _activePlacement;

		private bool _hasActivePlacement;

		private bool _isLoading;

		private float _nextRefreshTime;

		private string? _lastSceneName;

		private bool _loggedSceneHint;

		private bool _lastAudioEnabledState;

		private bool _audioRetrySuppressed;

		private bool _isPausedForOfflineMenu;

		private bool _isPausedForDistance;

		private bool _audioPausedForPlaybackPause;

		private AudioSource? _fadingAudioSource;

		private float _audioFadeStartTime;

		private float _audioFadeDuration;

		private float _audioFadeTargetVolume;

		private int _animatorSegmentLoopIndex;

		private int _lastAnimatorLoopIndex = -1;

		private int _lastMorphLoopIndex = -1;

		private GameObject? _activeShadowBlob;

		private bool _hasAppliedPlacementConfiguration;

		private float _appliedModelScale;

		private bool _hasResolvedPlacementPivot;

		private Vector3 _resolvedPlacementPivotLocalPosition;

		private bool _hasCachedRuntimeComponents;

		private GameObject? _cachedRuntimeComponentRoot;

		private RuntimeAnimatorController? _cachedAnimatorController;

		private bool _hasNativeFacialAnimationControl;

		private float _placementHotkeyPressedAt = -1f;

		private bool _placementHotkeyHoldConsumed;

		private KeyCode _lastObservedSpawnModelKey;

		private bool _pendingRuntimeLightingRefresh;

		private bool _lastAppliedStabilizeModelLighting;

		private float _lastAppliedLightingExposureCompensation = -1f;

		private static Mesh? s_shadowBlobMesh;

		private static Texture2D? s_shadowBlobTexture;

		private static Material? s_shadowBlobMaterial;

		public void Initialize(DancePluginConfig config, ManualLogSource logger)
		{
			_config = config;
			_logger = logger;
			_lastAudioEnabledState = config.EnableAudio.Value;
			_lastAppliedStabilizeModelLighting = config.StabilizeModelLighting.Value;
			_lastAppliedLightingExposureCompensation = config.ResolvedLightingExposureCompensation;
			config.StabilizeModelLighting.SettingChanged += HandleRuntimeLightingConfigChanged;
			config.LightingExposureCompensation.SettingChanged += HandleRuntimeLightingConfigChanged;
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(LoadAssetsRoutine());
		}

		private void OnDestroy()
		{
			if (_config != null)
			{
				_config.StabilizeModelLighting.SettingChanged -= HandleRuntimeLightingConfigChanged;
				_config.LightingExposureCompensation.SettingChanged -= HandleRuntimeLightingConfigChanged;
			}
			DestroyActiveDancer("Dance controller destroyed.");
			DestroyRuntimeLightingStabilizedMaterials();
			_unityBundleLoader.UnloadRetainedBundle();
		}

		private void Update()
		{
			if (_config == null || _logger == null)
			{
				return;
			}
			TrackSceneTransitions();
			if (!_config.ModEnabled.Value)
			{
				if ((Object)(object)_activeDancer != (Object)null)
				{
					DestroyActiveDancer("Model hidden because ModEnabled=False.");
				}
				_hasActivePlacement = false;
				ResetPlacementHotkeyState();
				return;
			}
			EnsureAirportLobbyDisplay();
			ProcessSpawnHotkey();
			MaintainSynchronizedLoopPlayback();
			UpdateActiveAudioFade();
			RefreshRuntimeLightingIfConfigChanged();
			if (Time.unscaledTime < _nextRefreshTime)
			{
				return;
			}
			_nextRefreshTime = Time.unscaledTime + 0.25f;
			if (!((Object)(object)_activeDancer == (Object)null))
			{
				if (_hasActivePlacement && HasPlacementConfigurationChanged())
				{
					ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab);
					UpdateShadowPresentation(_activeDancer);
					RecordAppliedPlacementConfiguration();
				}
				RefreshLivePlayback(_activeDancer);
			}
		}

		private void LateUpdate()
		{
			if (_config != null && _logger != null)
			{
				MaintainMorphPlaybackAfterAnimator();
			}
		}

		private void HandleRuntimeLightingConfigChanged(object? sender, EventArgs eventArgs)
		{
			_pendingRuntimeLightingRefresh = true;
		}

		[IteratorStateMachine(typeof(<LoadAssetsRoutine>d__109))]
		private IEnumerator LoadAssetsRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadAssetsRoutine>d__109(0)
			{
				<>4__this = this
			};
		}

		private void TrackSceneTransitions()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (!string.Equals(name, _lastSceneName, StringComparison.Ordinal))
			{
				_lastSceneName = name;
				_loggedSceneHint = false;
				_nextRefreshTime = 0f;
				if ((Object)(object)_activeDancer != (Object)null)
				{
					DestroyActiveDancer("Scene changed to '" + name + "'. The model must be placed again in the new scene.");
				}
				_hasActivePlacement = false;
				_isPausedForOfflineMenu = false;
				_isPausedForDistance = false;
				_audioPausedForPlaybackPause = false;
				ResetPlacementHotkeyState();
			}
		}

		private void EnsureAirportLobbyDisplay()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (_loadedPrefab == null || (Object)(object)_activeDancer != (Object)null || _hasActivePlacement)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (string.Equals(((Scene)(ref activeScene)).name, "Airport", StringComparison.OrdinalIgnoreCase))
			{
				_activePlacement = ResolveAirportLobbyPlacement();
				_hasActivePlacement = true;
				if (EnsureDancerInstance() && !((Object)(object)_activeDancer == (Object)null))
				{
					ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab);
					UpdateShadowPresentation(_activeDancer);
					RecordAppliedPlacementConfiguration();
					ConfigurePlayback(_activeDancer);
					string text = $"Spawned default Airport display model at {_activeDancer.transform.position}. ";
					Quaternion rotation = _activeDancer.transform.rotation;
					LogVerbose(text + $"rotation={((Quaternion)(ref rotation)).eulerAngles}, scale={_activeDancer.transform.localScale}.");
				}
			}
		}

		private void ProcessSpawnHotkey()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_0036: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (_config == null || _logger == null)
			{
				return;
			}
			if (!_loggedSceneHint)
			{
				_loggedSceneHint = true;
				string[] obj = new string[5] { "Placement hotkey ready in scene '", null, null, null, null };
				Scene activeScene = SceneManager.GetActiveScene();
				obj[1] = ((Scene)(ref activeScene)).name;
				obj[2] = "'. ";
				obj[3] = $"Tap {_config.SpawnModelKey.Value} to spawn or move the model to the local player's ground position. ";
				obj[4] = $"Hold it for {3f:0.#} seconds in Airport to save the lobby showcase position into the config file for future launches.";
				LogVerbose(string.Concat(obj));
			}
			KeyCode value = _config.SpawnModelKey.Value;
			if (value != _lastObservedSpawnModelKey)
			{
				ResetPlacementHotkeyState();
				_lastObservedSpawnModelKey = value;
				LogVerbose($"Updated placement hotkey binding to '{value}'. Tap/hold behavior now follows this key.");
			}
			if ((int)value == 0)
			{
				ResetPlacementHotkeyState();
				return;
			}
			if (Input.GetKeyDown(value))
			{
				_placementHotkeyPressedAt = Time.unscaledTime;
				_placementHotkeyHoldConsumed = false;
			}
			if (Input.GetKey(value))
			{
				if (!_placementHotkeyHoldConsumed && _placementHotkeyPressedAt >= 0f && Time.unscaledTime - _placementHotkeyPressedAt >= 3f)
				{
					_placementHotkeyHoldConsumed = true;
					SaveCurrentAirportDisplayPlacement();
				}
			}
			else if (Input.GetKeyUp(value))
			{
				bool num = !_placementHotkeyHoldConsumed;
				ResetPlacementHotkeyState();
				if (num)
				{
					SpawnOrMoveToCurrentPlayer();
				}
			}
		}

		private void SpawnOrMoveToCurrentPlayer()
		{
			//IL_006e: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			if (_config == null || _logger == null)
			{
				return;
			}
			if (_loadedPrefab == null)
			{
				if (!_isLoading)
				{
					((MonoBehaviour)this).StartCoroutine(LoadAssetsRoutine());
				}
				_logger.LogWarning((object)(_isLoading ? "The Unity asset bundle is still loading. Try the placement hotkey again in a moment." : "The model resources are loading now. Press the placement hotkey again in a moment."));
				return;
			}
			if (!TryResolveCurrentLocalPlayerPose(out Vector3 position, out Vector3 forward, out Transform ignoredRoot, out string source))
			{
				_logger.LogWarning((object)"The local player transform is not available yet, so the model cannot be moved right now.");
				return;
			}
			Vector3 forward2 = ResolveFacingDirection(forward);
			_activePlacement = CreatePlayerGroundLockedPlacement(position, forward2, source, ignoredRoot);
			_hasActivePlacement = true;
			bool flag = EnsureDancerInstance();
			if (!((Object)(object)_activeDancer == (Object)null))
			{
				ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab);
				UpdateShadowPresentation(_activeDancer);
				RecordAppliedPlacementConfiguration();
				if (flag)
				{
					ConfigurePlayback(_activeDancer);
				}
				else
				{
					RefreshLivePlayback(_activeDancer);
				}
				string[] obj = new string[7]
				{
					flag ? "Spawned" : "Moved",
					" display model in scene '",
					null,
					null,
					null,
					null,
					null
				};
				Scene activeScene = SceneManager.GetActiveScene();
				obj[2] = ((Scene)(ref activeScene)).name;
				obj[3] = "'. ";
				obj[4] = $"source={source}, playerPosition={position}, groundedPosition={_activePlacement.Position}, ";
				object arg = _activeDancer.transform.position;
				Quaternion rotation = _activeDancer.transform.rotation;
				obj[5] = $"modelPosition={arg}, modelRotation={((Quaternion)(ref rotation)).eulerAngles}, ";
				obj[6] = $"modelScale={_activeDancer.transform.localScale}.";
				LogVerbose(string.Concat(obj));
			}
		}

		private void SaveCurrentAirportDisplayPlacement()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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)
			if (_config == null || _logger == null)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (!string.Equals(((Scene)(ref activeScene)).name, "Airport", StringComparison.OrdinalIgnoreCase))
			{
				_logger.LogWarning((object)$"Hold {_config.SpawnModelKey.Value} for {3f:0.#} seconds only in the Airport lobby to save the lobby showcase position.");
				return;
			}
			if (!TryResolveCurrentLocalPlayerPose(out Vector3 position, out Vector3 forward, out Transform ignoredRoot, out string source))
			{
				_logger.LogWarning((object)"The local player transform is not available yet, so the Airport showcase position could not be saved.");
				return;
			}
			Vector3 forward2 = ResolveFacingDirection(forward);
			PlacementPose activePlacement = CreatePlayerGroundLockedPlacement(position, forward2, source + ".SavedAirportDisplay", ignoredRoot);
			_config.SaveAirportPlacement(activePlacement.Position, activePlacement.Forward);
			_activePlacement = activePlacement;
			_hasActivePlacement = true;
			bool flag = EnsureDancerInstance();
			if ((Object)(object)_activeDancer != (Object)null)
			{
				ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab);
				UpdateShadowPresentation(_activeDancer);
				RecordAppliedPlacementConfiguration();
				if (flag)
				{
					ConfigurePlayback(_activeDancer);
				}
				else
				{
					RefreshLivePlayback(_activeDancer);
				}
			}
			_logger.LogInfo((object)($"Saved Airport showcase placement to config. source={source}, groundedPosition={activePlacement.Position}, " + $"forward={activePlacement.Forward}, createdNow={flag}."));
		}

		private bool EnsureDancerInstance()
		{
			if ((Object)(object)_activeDancer != (Object)null || _loadedPrefab == null)
			{
				return false;
			}
			_activeDancer = Object.Instantiate<GameObject>(_loadedPrefab.Template);
			((Object)_activeDancer).name = "MikuDanceDisplay";
			RemoveAllColliders(_activeDancer);
			ResetAudioPlaybackState();
			ClearResolvedPlacementPivot();
			CacheActiveRuntimeComponents(_activeDancer);
			LogVerbose("Using embedded Animator playback for '" + ((Object)_activeDancer).name + "'. " + $"preBakedMorphClipAvailable={(Object)(object)_loadedPrefab.MorphClip != (Object)null}.");
			NormalizeRendererMaterials(_activeDancer);
			ConfigureFacialExpressions(_activeDancer);
			_activeDancer.SetActive(true);
			return true;
		}

		private void DestroyActiveDancer(string reason)
		{
			if (!((Object)(object)_activeDancer == (Object)null))
			{
				AudioSource activeAudioSource = _activeAudioSource;
				if ((Object)(object)activeAudioSource != (Object)null && activeAudioSource.isPlaying)
				{
					activeAudioSource.Stop();
				}
				ClearActiveAudioFade(activeAudioSource);
				Object.Destroy((Object)(object)_activeDancer);
				_activeDancer = null;
				_activeShadowBlob = null;
				DestroyRuntimeLightingStabilizedMaterials();
				ClearAppliedPlacementConfiguration();
				ClearResolvedPlacementPivot();
				ClearActiveRuntimeComponents();
				ResetAudioPlaybackState();
				LogVerbose(reason);
			}
		}

		private void ApplyPlacement(Transform dancerTransform, PlacementPose placement, DancePluginConfig config, LoadedDancePrefab? prefab)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_001d: 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_0028: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0049: 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_004f: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			float resolvedModelScale = config.ResolvedModelScale;
			Quaternion val = Quaternion.LookRotation(ResolveFacingDirection(placement.Forward), Vector3.up);
			Vector3 val2 = ResolvePlacementPivotLocalPosition(dancerTransform, prefab) * resolvedModelScale;
			dancerTransform.localScale = Vector3.one * resolvedModelScale;
			dancerTransform.rotation = val;
			dancerTransform.position = placement.Position - val * val2;
		}

		private Vector3 ResolvePlacementPivotLocalPosition(Transform dancerTransform, LoadedDancePrefab? prefab)
		{
			//IL_0009: 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_002e: 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_0049: 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_0056: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0089: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			if (_hasResolvedPlacementPivot)
			{
				return _resolvedPlacementPivotLocalPosition;
			}
			float num = prefab?.LocalMinY ?? 0f;
			if (TryResolvePlacementPivotFromAnimator(dancerTransform, num, out var pivotLocalPosition))
			{
				_resolvedPlacementPivotLocalPosition = pivotLocalPosition;
				_hasResolvedPlacementPivot = true;
				return pivotLocalPosition;
			}
			if (TryResolvePlacementPivotFromNamedBone(dancerTransform, num, out var pivotLocalPosition2))
			{
				_resolvedPlacementPivotLocalPosition = pivotLocalPosition2;
				_hasResolvedPlacementPivot = true;
				return pivotLocalPosition2;
			}
			Vector3 result = (_resolvedPlacementPivotLocalPosition = ((prefab == null) ? new Vector3(0f, num, 0f) : new Vector3(prefab.LocalBoundsCenter.x, num, prefab.LocalBoundsCenter.z)));
			_hasResolvedPlacementPivot = true;
			return result;
		}

		private static PlacementPose CreateGroundLockedPlacement(Vector3 desiredPosition, Vector3 forward, string source)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			Vector3 position = desiredPosition;
			position.y = ResolveGroundYExact(desiredPosition, desiredPosition.y + 80f, 200f, float.PositiveInfinity);
			return PlacementPose.Create(position, forward, source);
		}

		private static PlacementPose CreatePlayerGroundLockedPlacement(Vector3 desiredPosition, Vector3 forward, string source, Transform? ignoredRoot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = desiredPosition;
			position.y = ResolveGroundYNearPlayer(desiredPosition, desiredPosition.y + 1.25f, 200f, desiredPosition.y + 0.6f, ignoredRoot);
			return PlacementPose.Create(position, forward, source);
		}

		private PlacementPose ResolveAirportLobbyPlacement()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			if (_config != null && _config.TryGetSavedAirportPlacement(out var position, out var forward))
			{
				return CreateGroundLockedPlacement(position, forward, "AirportLobbyDisplay.Saved");
			}
			return CreateGroundLockedPlacement(AirportDisplayPosition, AirportDisplayForward, "AirportLobbyDisplay.Default");
		}

		private bool HasPlacementConfigurationChanged()
		{
			if (_config == null)
			{
				return false;
			}
			if (!_hasAppliedPlacementConfiguration)
			{
				return true;
			}
			return Mathf.Abs(_appliedModelScale - _config.ResolvedModelScale) > 0.0001f;
		}

		private void RecordAppliedPlacementConfiguration()
		{
			if (_config == null)
			{
				ClearAppliedPlacementConfiguration();
				return;
			}
			_hasAppliedPlacementConfiguration = true;
			_appliedModelScale = _config.ResolvedModelScale;
		}

		private void ClearAppliedPlacementConfiguration()
		{
			_hasAppliedPlacementConfiguration = false;
			_appliedModelScale = 0f;
		}

		private void ClearResolvedPlacementPivot()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_hasResolvedPlacementPivot = false;
			_resolvedPlacementPivotLocalPosition = Vector3.zero;
		}

		private void ResetPlacementHotkeyState()
		{
			_placementHotkeyPressedAt = -1f;
			_placementHotkeyHoldConsumed = false;
		}

		private bool TryResolvePlacementPivotFromAnimator(Transform dancerTransform, float pivotY, out Vector3 pivotLocalPosition)
		{
			//IL_006d: 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)
			Animator componentInChildren = ((Component)dancerTransform).GetComponentInChildren<Animator>(true);
			if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isHuman)
			{
				try
				{
					Transform boneTransform = componentInChildren.GetBoneTransform((HumanBodyBones)0);
					if (TryBuildPlacementPivotFromBone(dancerTransform, boneTransform, pivotY, out pivotLocalPosition))
					{
						LogVerbose($"Resolved placement pivot from humanoid hips bone '{((Object)boneTransform).name}' at local {pivotLocalPosition}.");
						return true;
					}
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to resolve humanoid hips pivot: " + ex.Message);
				}
			}
			pivotLocalPosition = default(Vector3);
			return false;
		}

		private bool TryResolvePlacementPivotFromNamedBone(Transform dancerTransform, float pivotY, out Vector3 pivotLocalPosition)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Transform[] componentsInChildren = ((Component)dancerTransform).GetComponentsInChildren<Transform>(true);
			Transform val = null;
			int num = int.MinValue;
			Transform[] array = componentsInChildren;
			foreach (Transform val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && val2 != dancerTransform)
				{
					int num2 = ScorePlacementPivotCandidate(((Object)val2).name);
					if (num2 > num)
					{
						num = num2;
						val = val2;
					}
				}
			}
			if ((Object)(object)val != (Object)null && TryBuildPlacementPivotFromBone(dancerTransform, val, pivotY, out pivotLocalPosition))
			{
				LogVerbose($"Resolved placement pivot from named bone '{((Object)val).name}' at local {pivotLocalPosition}.");
				return true;
			}
			pivotLocalPosition = default(Vector3);
			return false;
		}

		private static bool TryBuildPlacementPivotFromBone(Transform dancerTransform, Transform? pivotBone, float pivotY, out Vector3 pivotLocalPosition)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			if ((Object)(object)pivotBone == (Object)null)
			{
				pivotLocalPosition = default(Vector3);
				return false;
			}
			Vector3 val = dancerTransform.InverseTransformPoint(pivotBone.position);
			pivotLocalPosition = new Vector3(val.x, pivotY, val.z);
			return true;
		}

		private static int ScorePlacementPivotCandidate(string? name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return int.MinValue;
			}
			string text = (name ?? string.Empty).Trim().ToLowerInvariant();
			int num = int.MinValue;
			for (int i = 0; i < PreferredPivotBoneTokens.Length; i++)
			{
				string text2 = PreferredPivotBoneTokens[i];
				if (string.Equals(text, text2, StringComparison.Ordinal))
				{
					return 1000 - i;
				}
				if (text.IndexOf(text2, StringComparison.Ordinal) >= 0)
				{
					num = Mathf.Max(num, 500 - i);
				}
			}
			return num;
		}

		private static Vector3 ResolveFacingDirection(Vector3 forward)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_000b: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(forward, Vector3.up);
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private static bool TryResolveCurrentLocalPlayerPose(out Vector3 position, out Vector3 forward, out Transform? ignoredRoot, out string source)
		{
			//IL_0039: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetLocalCharacterObject(out object source2) && TryResolveCharacterPose(source2, "Character.localCharacter", out position, out forward, out ignoredRoot, out source))
			{
				return true;
			}
			if (TryGetLocalPlayerCharacterObject(out object source3) && TryResolveCharacterPose(source3, "Player.localPlayer.character", out position, out forward, out ignoredRoot, out source))
			{
				return true;
			}
			position = default(Vector3);
			forward = Vector3.forward;
			ignoredRoot = null;
			source = string.Empty;
			return false;
		}

		private static float ResolveGroundYExact(Vector3 desiredPosition, float startY, float maxDistance, float maxAcceptedY, Transform? ignoredRoot = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			Transform ignoredRoot2 = ignoredRoot;
			RaycastHit[] array = Physics.RaycastAll(new Vector3(desiredPosition.x, startY, desiredPosition.z), Vector3.down, maxDistance, -1, (QueryTriggerInteraction)1);
			if (array.Length == 0)
			{
				return desiredPosition.y;
			}
			RaycastHit[] array2 = (from hit in array
				where (Object)(object)((RaycastHit)(ref hit)).collider != (Object)null
				where ((RaycastHit)(ref hit)).normal.y > 0.35f
				where !ShouldIgnoreGroundHit(hit, ignoredRoot2)
				select hit).ToArray();
			if (array2.Length == 0)
			{
				return desiredPosition.y;
			}
			if (!float.IsPositiveInfinity(maxAcceptedY))
			{
				RaycastHit val = (from hit in array2
					where ((RaycastHit)(ref hit)).point.y <= maxAcceptedY
					orderby ((RaycastHit)(ref hit)).point.y descending, ((RaycastHit)(ref hit)).distance
					select hit).FirstOrDefault();
				if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null)
				{
					return ((RaycastHit)(ref val)).point.y;
				}
				return desiredPosition.y;
			}
			RaycastHit val2 = (from hit in array2
				orderby ((RaycastHit)(ref hit)).point.y descending, ((RaycastHit)(ref hit)).distance
				select hit).FirstOrDefault();
			if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null))
			{
				return ((RaycastHit)(ref val2)).point.y;
			}
			return desiredPosition.y;
		}

		private static float ResolveGroundYNearPlayer(Vector3 desiredPosition, float startY, float maxDistance, float maxAcceptedY, Transform? ignoredRoot)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0105: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			GroundSampleCandidate? groundSampleCandidate = null;
			GroundSampleCandidate? groundSampleCandidate2 = null;
			for (int i = 0; i < PlayerGroundProbeSampleOffsets.Length; i++)
			{
				GroundSampleCandidate? groundSampleCandidate3 = TryResolveGroundCandidate(desiredPosition + PlayerGroundProbeSampleOffsets[i], startY, maxDistance, maxAcceptedY, ignoredRoot);
				if (groundSampleCandidate3.HasValue)
				{
					if (!groundSampleCandidate2.HasValue || groundSampleCandidate3.Value.IsBetterThan(groundSampleCandidate2.Value))
					{
						groundSampleCandidate2 = groundSampleCandidate3;
					}
					if (!(desiredPosition.y - groundSampleCandidate3.Value.Y > 0.9f) && (!groundSampleCandidate.HasValue || groundSampleCandidate3.Value.IsBetterThan(groundSampleCandidate.Value)))
					{
						groundSampleCandidate = groundSampleCandidate3;
					}
				}
			}
			if (groundSampleCandidate.HasValue)
			{
				return groundSampleCandidate.Value.Y;
			}
			if (groundSampleCandidate2.HasValue && desiredPosition.y - groundSampleCandidate2.Value.Y <= 1.25f)
			{
				return groundSampleCandidate2.Value.Y;
			}
			return desiredPosition.y;
		}

		private static GroundSampleCandidate? TryResolveGroundCandidate(Vector3 desiredPosition, float startY, float maxDistance, float maxAcceptedY, Transform? ignoredRoot)
		{
			//IL_0016: 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_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)
			Transform ignoredRoot2 = ignoredRoot;
			RaycastHit[] array = Physics.RaycastAll(new Vector3(desiredPosition.x, startY, desiredPosition.z), Vector3.down, maxDistance, -1, (QueryTriggerInteraction)1);
			if (array.Length == 0)
			{
				return null;
			}
			GroundSampleCandidate[] array2 = (from hit in array
				where (Object)(object)((RaycastHit)(ref hit)).collider != (Object)null
				where ((RaycastHit)(ref hit)).normal.y > 0.35f
				where !ShouldIgnoreGroundHit(hit, ignoredRoot2)
				where ((RaycastHit)(ref hit)).point.y <= maxAcceptedY
				select new GroundSampleCandidate(((RaycastHit)(ref hit)).point.y, Mathf.Abs(desiredPosition.y - ((RaycastHit)(ref hit)).point.y), Vector2.Distance(new Vector2(desiredPosition.x, desiredPosition.z), new Vector2(((RaycastHit)(ref hit)).point.x, ((RaycastHit)(ref hit)).point.z)), ((RaycastHit)(ref hit)).distance) into hit
				orderby hit.VerticalDelta, hit.HorizontalDelta, hit.RaycastDistance
				select hit).ToArray();
			if (array2.Length != 0)
			{
				return array2[0];
			}
			return null;
		}

		private static bool TryGetLocalCharacterObject(out object source)
		{
			source = LocalCharacterField?.GetValue(null);
			return source != null;
		}

		private static bool TryGetLocalPlayerCharacterObject(out object source)
		{
			object obj = LocalPlayerField?.GetValue(null);
			if (obj == null)
			{
				source = null;
				return false;
			}
			source = PlayerCharacterProperty?.GetValue(obj, null) ?? PlayerCharacterField?.GetValue(obj);
			return source != null;
		}

		private static bool TryResolveCharacterPose(object source, string sourceName, out Vector3 position, out Vector3 forward, out Transform? ignoredRoot, out string resolvedSource)
		{
			//IL_002c: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			resolvedSource = sourceName;
			if (!TryExtractTransform(source, out Transform transform))
			{
				position = default(Vector3);
				forward = Vector3.forward;
				ignoredRoot = null;
				return false;
			}
			ignoredRoot = transform;
			position = transform.position;
			Vector3 vector2;
			if (TryExtractVector3(CharacterCenterProperty?.GetValue(source, null), out var vector))
			{
				position = new Vector3(vector.x, position.y, vector.z);
				resolvedSource = sourceName + ".CenterXZ";
			}
			else if (TryExtractVector3(CharacterVirtualCenterProperty?.GetValue(source, null), out vector2))
			{
				position = new Vector3(vector2.x, position.y, vector2.z);
				resolvedSource = sourceName + ".VirtualCenterXZ";
			}
			position = new Vector3(position.x, ResolveCharacterFootY(transform, position.y), position.z);
			resolvedSource += ".FootY";
			forward = ResolvePreferredPlayerForward(transform, position, out string source2);
			resolvedSource = resolvedSource + "." + source2;
			return true;
		}

		private static float ResolveCharacterFootY(Transform root, float fallbackY)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			float num = float.PositiveInfinity;
			Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger)
				{
					Bounds bounds = val.bounds;
					float y = ((Bounds)(ref bounds)).min.y;
					if (!float.IsNaN(y) && !float.IsInfinity(y))
					{
						num = Mathf.Min(num, y);
						flag = true;
					}
				}
			}
			if (!flag)
			{
				return fallbackY;
			}
			return num + 0.05f;
		}

		private static bool ShouldIgnoreGroundHit(RaycastHit hit, Transform? ignoredRoot)
		{
			if ((Object)(object)ignoredRoot == (Object)null || (Object)(object)((RaycastHit)(ref hit)).collider == (Object)null)
			{
				return false;
			}
			if (IsSameOrChildTransform(((Component)((RaycastHit)(ref hit)).collider).transform, ignoredRoot))
			{
				return true;
			}
			Rigidbody attachedRigidbody = ((RaycastHit)(ref hit)).collider.attachedRigidbody;
			if ((Object)(object)attachedRigidbody != (Object)null)
			{
				return IsSameOrChildTransform(((Component)attachedRigidbody).transform, ignoredRoot);
			}
			return false;
		}

		private static bool IsSameOrChildTransform(Transform? candidate, Transform root)
		{
			if ((Object)(object)candidate != (Object)null)
			{
				if (!((Object)(object)candidate == (Object)(object)root))
				{
					return candidate.IsChildOf(root);
				}
				return true;
			}
			return false;
		}

		private static Vector3[] BuildPlayerGroundSampleOffsets()
		{
			//IL_0012: 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_0028: 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_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_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_006a: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			Vector2[] obj = new Vector2[8]
			{
				new Vector2(1f, 0f),
				new Vector2(-1f, 0f),
				new Vector2(0f, 1f),
				new Vector2(0f, -1f),
				default(Vector2),
				default(Vector2),
				default(Vector2),
				default(Vector2)
			};
			Vector2 val = new Vector2(1f, 1f);
			obj[4] = ((Vector2)(ref val)).normalized;
			val = new Vector2(1f, -1f);
			obj[5] = ((Vector2)(ref val)).normalized;
			val = new Vector2(-1f, 1f);
			obj[6] = ((Vector2)(ref val)).normalized;
			val = new Vector2(-1f, -1f);
			obj[7] = ((Vector2)(ref val)).normalized;
			Vector2[] array = (Vector2[])(object)obj;
			float[] array2 = new float[6] { 0.35f, 0.7f, 1.1f, 1.6f, 2.2f, 3f };
			List<Vector3> list = new List<Vector3>(1 + array.Length * array2.Length) { Vector3.zero };
			float[] array3 = array2;
			foreach (float num in array3)
			{
				foreach (Vector2 val2 in array)
				{
					list.Add(new Vector3(val2.x * num, 0f, val2.y * num));
				}
			}
			return list.ToArray();
		}

		private static bool TryExtractTransform(object? source, out Transform transform)
		{
			Transform val = (Transform)((source is Transform) ? source : null);
			if (val == null)
			{
				Component val2 = (Component)((source is Component) ? source : null);
				if (val2 == null)
				{
					GameObject val3 = (GameObject)((source is GameObject) ? source : null);
					if (val3 != null)
					{
						transform = val3.transform;
						return true;
					}
					transform = null;
					return false;
				}
				transform = val2.transform;
				return (Object)(object)transform != (Object)null;
			}
			transform = val;
			return true;
		}

		private static bool TryExtractVector3(object? value, out Vector3 vector)
		{
			//IL_0019: 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_000e: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			if (value is Vector3 val)
			{
				vector = val;
				return true;
			}
			vector = default(Vector3);
			return false;
		}

		private static Vector3 ResolvePlanarForward(Transform transform)
		{
			//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_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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(transform.forward, Vector3.up);
			if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private static Vector3 ResolvePreferredPlayerForward(Transform playerRoot, Vector3 playerPosition, out string source)
		{
			//IL_0000: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			if (TryResolveCameraPlanarForward(playerPosition, out Vector3 forward, out string source2))
			{
				source = source2;
				return forward;
			}
			source = "TransformForward";
			return ResolvePlanarForward(playerRoot);
		}

		private static bool TryResolveCameraPlanarForward(Vector3 playerPosition, out Vector3 forward, out string source)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_002b: 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_0035: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_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)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			source = string.Empty;
			forward = Vector3.zero;
			Camera main = Camera.main;
			if (IsUsableGameplayCamera(main))
			{
				Vector3 val = Vector3.ProjectOnPlane(((Component)main).transform.forward, Vector3.up);
				if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
				{
					forward = ((Vector3)(ref val)).normalized;
					source = "Camera:" + ((Object)main).name;
					return true;
				}
			}
			Camera val2 = null;
			float num = float.PositiveInfinity;
			Camera[] allCameras = Camera.allCameras;
			foreach (Camera val3 in allCameras)
			{
				if (!IsUsableGameplayCamera(val3))
				{
					continue;
				}
				Vector3 val4 = Vector3.ProjectOnPlane(((Component)val3).transform.forward, Vector3.up);
				if (!(((Vector3)(ref val4)).sqrMagnitude <= 0.01f))
				{
					float num2 = Vector3.Distance(((Component)val3).transform.position, playerPosition);
					if (!(num2 >= num))
					{
						num = num2;
						val2 = val3;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			Vector3 val5 = Vector3.ProjectOnPlane(((Component)val2).transform.forward, Vector3.up);
			forward = ((Vector3)(ref val5)).normalized;
			source = "Camera:" + ((Object)val2).name;
			return true;
		}

		private static bool IsUsableGameplayCamera(Camera? camera)
		{
			if ((Object)(object)camera != (Object)null && ((Behaviour)camera).enabled && ((Component)camera).gameObject.activeInHierarchy)
			{
				return !camera.orthographic;
			}
			return false;
		}

		private static Type? FindGameType(string typeName)
		{
			return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => string.Equals(assembly.GetName().Name, "Assembly-CSharp", StringComparison.Ordinal))?.GetType(typeName, throwOnError: false, ignoreCase: false);
		}

		private static void RemoveAllColliders(GameObject root)
		{
			Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
		}

		private void NormalizeRendererMaterials(GameObject root)
		{
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if (_logger == null)
			{
				return;
			}
			bool flag = _config?.StabilizeModelLighting.Value ?? true;
			float num = _config?.ResolvedLightingExposureCompensation ?? 0.82f;
			Dictionary<Material, Material> materialCache = new Dictionary<Material, Material>();
			int num2 = 0;
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = true;
				val.shadowCastingMode = (ShadowCastingMode)1;
				val.receiveShadows = true;
				val.allowOcclusionWhenDynamic = true;
				val.lightProbeUsage = (LightProbeUsage)1;
				val.reflectionProbeUsage = (ReflectionProbeUsage)1;
				int expectedMaterialCount = GetExpectedMaterialCount(val);
				if (expectedMaterialCount > 0)
				{
					Material[] array = val.sharedMaterials ?? Array.Empty<Material>();
					if (array.Length != expectedMaterialCount || array.Any((Material material) => (Object)(object)material == (Object)null))
					{
						val.sharedMaterials = BuildNormalizedRendererMaterialArray(array, expectedMaterialCount);
						LogVerbose($"Normalized runtime materials for '{((Object)val).name}'. subMeshes={expectedMaterialCount}, materials={val.sharedMaterials.Length}.");
					}
				}
				if (flag && TryBuildLightingStabilizedMaterialArray(val, val.sharedMaterials ?? Array.Empty<Material>(), materialCache, _runtimeLightingStabilizedMaterials, _runtimeLightingMaterialSnapshots, num, out Material[] stabilizedMaterials, out int newStabilizedMaterialCount))
				{
					val.sharedMaterials = stabilizedMaterials;
					num2 += newStabilizedMaterialCount;
				}
				EnableShadowSupport(val.sharedMaterials);
				SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
				if (val2 != null)
				{
					val2.updateWhenOffscreen = true;
					if ((Object)(object)val2.sharedMesh != (Object)null)
					{
						Bounds bounds = val2.sharedMesh.bounds;
						((Bounds)(ref bounds)).Expand(0.5f);
						((Renderer)val2).localBounds = bounds;
					}
				}
			}
			if (num2 > 0)
			{
				LogVerbose($"Applied runtime lighting stabilization to {num2} material(s). " + $"exposureCompensation={num:0.###}.");
			}
			RecordAppliedRuntimeLightingConfiguration(flag, num);
		}

		private static Material[] BuildNormalizedRendererMaterialArray(Material[] sharedMaterials, int expectedCount)
		{
			Material[] array = (Material[])(object)new Material[Mathf.Max(1, expectedCount)];
			Material val = ((IEnumerable<Material>)sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material material) => (Object)(object)material != (Object)null)) ?? CreateFallbackRendererMaterial();
			for (int i = 0; i < array.Length; i++)
			{
				Material val2 = ((i < sharedMaterials.Length) ? sharedMaterials[i] : null);
				if ((Object)(object)val2 != (Object)null)
				{
					array[i] = val2;
					val = val2;
				}
				else
				{
					array[i] = val;
				}
			}
			return array;
		}

		private static bool TryBuildLightingStabilizedMaterialArray(Renderer renderer, Material[] sharedMaterials, Dictionary<Material, Material> materialCache, List<Material> runtimeMaterials, Dictionary<Material, RuntimeLightingMaterialSnapshot> runtimeMaterialSnapshots, float exposureCompensation, out Material[] stabilizedMaterials, out int newStabilizedMaterialCount)
		{
			stabilizedMaterials = sharedMaterials;
			newStabilizedMaterialCount = 0;
			if ((Object)(object)renderer == (Object)null || sharedMaterials == null || sharedMaterials.Length == 0)
			{
				return false;
			}
			Material[] array = null;
			for (int i = 0; i < sharedMaterials.Length; i++)
			{
				Material val = sharedMaterials[i];
				if (!((Object)(object)val == (Object)null) && IsLightingSensitiveMaterial(val))
				{
					if (!materialCache.TryGetValue(val, out Material value))
					{
						value = (materialCache[val] = CreateLightingStabilizedMaterial(val, exposureCompensation, out RuntimeLightingMaterialSnapshot snapshot));
						runtimeMaterials.Add(value);
						runtimeMaterialSnapshots[value] = snapshot;
						newStabilizedMaterialCount++;
					}
					if (array == null)
					{
						array = (Material[])sharedMaterials.Clone();
					}
					array[i] = value;
				}
			}
			if (array == null)
			{
				return false;
			}
			stabilizedMaterials = array;
			return true;
		}

		private static bool IsLightingSensitiveMaterial(Material material)
		{
			if ((Object)(object)material == (Object)null || (Object)(object)material.shader == (Object)null)
			{
				return false;
			}
			string text = ((Object)material.shader).name ?? string.Empty;
			if (string.IsNullOrWhiteSpace(text))
			{
				return HasAnyMaterialProperty(material, LightingSensitiveMaterialProperties);
			}
			string lowerShaderName = text.ToLowerInvariant();
			if (LightingNeutralShaderTokens.Any((string token) => lowerShaderName.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0) && !lowerShaderName.Contains("toon"))
			{
				return false;
			}
			if (!LightingSensitiveShaderTokens.Any((string token) => lowerShaderName.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0))
			{
				return HasAnyMaterialProperty(material, LightingSensitiveMaterialProperties);
			}
			return true;
		}

		private static Material CreateLightingStabilizedMaterial(Material sourceMaterial, float exposureCompensation, out RuntimeLightingMaterialSnapshot snapshot)
		{
			//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_0031: Expected O, but got Unknown
			//IL_011b: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(sourceMaterial)
			{
				name = (string.IsNullOrWhiteSpace(((Object)sourceMaterial).nam