Decompiled source of MikuShowcase v1.0.2

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.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using MikuDanceProject.Core;
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]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	internal static class IsExternalInit
	{
	}
}
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);
			}
		}

		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 AudioDriftCorrectionThresholdSeconds = 0.35f;

		private const float AudioHardResyncThresholdSeconds = 1.25f;

		private const float LoopIntervalSeconds = 5f;

		private const float SavePlacementHoldDurationSeconds = 3f;

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

		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 readonly Dictionary<Material, Color> _originalMaterialColors = new Dictionary<Material, Color>();

		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 bool _isInLoopInterval;

		private float _loopIntervalEndTime = -1f;

		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;

		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;
			config.HairColorEnabled.SettingChanged += HandleColorConfigChanged;
			config.HairColorR.SettingChanged += HandleColorConfigChanged;
			config.HairColorG.SettingChanged += HandleColorConfigChanged;
			config.HairColorB.SettingChanged += HandleColorConfigChanged;
			config.ClothColorEnabled.SettingChanged += HandleColorConfigChanged;
			config.ClothColorR.SettingChanged += HandleColorConfigChanged;
			config.ClothColorG.SettingChanged += HandleColorConfigChanged;
			config.ClothColorB.SettingChanged += HandleColorConfigChanged;
			config.RandomizeColors.SettingChanged += HandleColorConfigChanged;
		}

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

		private void OnDestroy()
		{
			if (_config != null)
			{
				_config.StabilizeModelLighting.SettingChanged -= HandleRuntimeLightingConfigChanged;
				_config.LightingExposureCompensation.SettingChanged -= HandleRuntimeLightingConfigChanged;
				_config.HairColorEnabled.SettingChanged -= HandleColorConfigChanged;
				_config.HairColorR.SettingChanged -= HandleColorConfigChanged;
				_config.HairColorG.SettingChanged -= HandleColorConfigChanged;
				_config.HairColorB.SettingChanged -= HandleColorConfigChanged;
				_config.ClothColorEnabled.SettingChanged -= HandleColorConfigChanged;
				_config.ClothColorR.SettingChanged -= HandleColorConfigChanged;
				_config.ClothColorG.SettingChanged -= HandleColorConfigChanged;
				_config.ClothColorB.SettingChanged -= HandleColorConfigChanged;
				_config.RandomizeColors.SettingChanged -= HandleColorConfigChanged;
			}
			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;
		}

		private void HandleColorConfigChanged(object? sender, EventArgs eventArgs)
		{
			if (!((Object)(object)_activeDancer == (Object)null) && _config != null)
			{
				if (sender == _config.RandomizeColors)
				{
					_config.RefreshRandomColors();
				}
				ReapplyAllMaterialColors();
			}
		}

		private void ReapplyAllMaterialColors()
		{
			if ((Object)(object)_activeDancer == (Object)null || _config == null)
			{
				return;
			}
			Renderer[] componentsInChildren = _activeDancer.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				LogVerbose($"Reapplying material colors. randomize={_config.RandomizeColors.Value} " + $"hairEnabled={_config.HairColorEnabled.Value} " + $"hair=({_config.HairColorR.Value:0.###},{_config.HairColorG.Value:0.###},{_config.HairColorB.Value:0.###}) " + $"clothEnabled={_config.ClothColorEnabled.Value} " + $"cloth=({_config.ClothColorR.Value:0.###},{_config.ClothColorG.Value:0.###},{_config.ClothColorB.Value:0.###}) " + $"renderers={componentsInChildren.Length}.");
				Renderer[] array = componentsInChildren;
				foreach (Renderer renderer in array)
				{
					ApplyLocalizedMaterialColors(renderer);
				}
			}
		}

		private IEnumerator LoadAssetsRoutine()
		{
			if (_config == null || _logger == null || _isLoading || _loadedPrefab != null)
			{
				yield break;
			}
			_isLoading = true;
			string text = _config.ResolveUnityBundlePath();
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			LogVerbose("Starting Unity asset bundle load. bundlePath='" + text + "'.");
			try
			{
				if (!File.Exists(text))
				{
					_logger.LogError((object)("Required Unity asset bundle file was not found: '" + text + "'."));
					yield break;
				}
				_loadedPrefab = _unityBundleLoader.Load(text, _logger);
				Object.DontDestroyOnLoad((Object)(object)_loadedPrefab.Template);
				LogVerbose($"Using Unity asset bundle dancer source '{text}'. loadDuration={Time.realtimeSinceStartup - realtimeSinceStartup:0.###}s.");
			}
			catch (Exception arg)
			{
				_logger.LogError((object)$"Failed to load Unity asset bundle dancer source '{text}': {arg}");
			}
			finally
			{
				_isLoading = false;
			}
		}

		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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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)
			{
				return;
			}
			ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab);
			UpdateShadowPresentation(_activeDancer);
			RecordAppliedPlacementConfiguration();
			if (flag)
			{
				ConfigurePlayback(_activeDancer);
			}
			else
			{
				RefreshLivePlayback(_activeDancer);
				if (_config != null && _config.RandomizeColors.Value)
				{
					_config.RefreshRandomColors();
					ReapplyAllMaterialColors();
				}
			}
			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();
				_originalMaterialColors.Clear();
				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)
			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, ignoredRoot)
				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)
			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, ignoredRoot)
				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 = null;
			Object val = (Object)((source is Object) ? source : null);
			if (val != null && val == (Object)null)
			{
				return false;
			}
			try
			{
				Transform val2 = (Transform)((source is Transform) ? source : null);
				if (val2 == null)
				{
					Component val3 = (Component)((source is Component) ? source : null);
					if (val3 == null)
					{
						GameObject val4 = (GameObject)((source is GameObject) ? source : null);
						if (val4 != null)
						{
							if ((Object)(object)val4 == (Object)null)
							{
								return false;
							}
							transform = val4.transform;
							return (Object)(object)transform != (Object)null;
						}
						return false;
					}
					if ((Object)(object)val3 == (Object)null)
					{
						return false;
					}
					transform = val3.transform;
					return (Object)(object)transform != (Object)null;
				}
				transform = val2;
				return (Object)(object)val2 != (Object)null;
			}
			catch (MissingReferenceException)
			{
				transform = null;
				return false;
			}
			catch (NullReferenceException)
			{
				transform = null;
				return false;
			}
		}

		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_01a0: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
			if (_logger == null)
			{
				return;
			}
			_config?.RefreshRandomColors();
			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 = false;
				val.allowOcclusionWhenDynamic = true;
				val.lightProbeUsage = (LightProbeUsage)0;
				val.reflectionProbeUsage = (ReflectionProbeUsage)0;
				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);
				ApplyLocalizedMaterialColors(val);
				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 void ApplyLocalizedMaterialColors(Renderer renderer)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)renderer == (Object)null)
			{
				return;
			}
			Color color = Color.white;
			Color color2 = Color.white;
			bool flag = _config != null && _config.TryResolveHairColor(out color);
			bool flag2 = _config != null && _config.TryResolveClothColor(out color2);
			if (!flag && !flag2 && _originalMaterialColors.Count == 0)
			{
				return;
			}
			Material[] sharedMaterials = renderer.sharedMaterials;
			if (sharedMaterials == null || sharedMaterials.Length == 0)
			{
				return;
			}
			bool flag3 = false;
			Material[] array = sharedMaterials;
			foreach (Material val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string normalizedName = NormalizeMaterialName(((Object)val).name, ((Object)renderer).name);
					if (IsHairMaterialName(normalizedName) || IsClothMaterialName(normalizedName))
					{
						flag3 = true;
						break;
					}
				}
			}
			if (!flag3)
			{
				if (!VerboseLogState.Enabled)
				{
					return;
				}
				ManualLogSource? logger = _logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"No material matched on '{((Object)renderer).name}' ({sharedMaterials.Length} materials). Listing all:");
				}
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (!((Object)(object)sharedMaterials[j] == (Object)null))
					{
						ManualLogSource? logger2 = _logger;
						if (logger2 != null)
						{
							logger2.LogInfo((object)$"  [{j}] '{((Object)sharedMaterials[j]).name}'");
						}
					}
				}
				return;
			}
			Material[] sharedMaterials2 = renderer.sharedMaterials;
			Material[] materials = renderer.materials;
			int num = 0;
			int num2 = 0;
			array = materials;
			foreach (Material val2 in array)
			{
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				string normalizedName2 = NormalizeMaterialName(((Object)val2).name, ((Object)renderer).name);
				bool flag4 = IsHairMaterialName(normalizedName2);
				bool flag5 = IsClothMaterialName(normalizedName2);
				if (!flag4 && !flag5)
				{
					continue;
				}
				if (!_originalMaterialColors.ContainsKey(val2))
				{
					_originalMaterialColors[val2] = ReadMaterialColor(val2);
				}
				Color color3 = _originalMaterialColors[val2];
				if (flag4)
				{
					if (flag)
					{
						SetMaterialColor(val2, color);
						num++;
					}
					else
					{
						SetMaterialColor(val2, color3);
						num2++;
					}
				}
				else if (flag2)
				{
					SetMaterialColor(val2, color2);
					num++;
				}
				else
				{
					SetMaterialColor(val2, color3);
					num2++;
				}
			}
			renderer.sharedMaterials = materials;
			MigrateStabilizedMaterialReferences(sharedMaterials2, materials);
			if (num > 0 || num2 > 0)
			{
				LogVerbose($"Applied localized material colors on '{((Object)renderer).name}'. applied={num} restored={num2} " + $"hair={(object)(Color)(flag ? color : default(Color))} cloth={(object)(Color)(flag2 ? color2 : default(Color))}.");
			}
			if (!VerboseLogState.Enabled)
			{
				return;
			}
			for (int k = 0; k < materials.Length; k++)
			{
				if (!((Object)(object)materials[k] == (Object)null))
				{
					string normalizedName3 = NormalizeMaterialName(((Object)materials[k]).name, ((Object)renderer).name);
					bool flag6 = IsHairMaterialName(normalizedName3);
					bool flag7 = IsClothMaterialName(normalizedName3);
					string arg = (flag6 ? (flag ? "HAIR" : "HAIR(off,restored)") : ((!flag7) ? "SKIP" : (flag2 ? "CLOTH" : "CLOTH(off,restored)")));
					ManualLogSource? logger3 = _logger;
					if (logger3 != null)
					{
						logger3.LogInfo((object)$"  [{k}] '{((Object)materials[k]).name}' -> {arg}");
					}
				}
			}
		}

		private static Color ReadMaterialColor(Material material)
		{
			//IL_0013: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty("_BaseColor"))
			{
				return material.GetColor("_BaseColor");
			}
			if (material.HasProperty("_Color"))
			{
				return material.GetColor("_Color");
			}
			return Color.white;
		}

		private void MigrateStabilizedMaterialReferences(Material[] beforeMaterials, Material[] afterMaterials)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (beforeMaterials == null || afterMaterials == null || _runtimeLightingStabilizedMaterials.Count == 0)
			{
				return;
			}
			int num = Mathf.Min(beforeMaterials.Length, afterMaterials.Length);
			for (int i = 0; i < num; i++)
			{
				Material val = beforeMaterials[i];
				Material val2 = afterMaterials[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && val != val2)
				{
					if (_runtimeLightingMaterialSnapshots.TryGetValue(val, out RuntimeLightingMaterialSnapshot value))
					{
						_runtimeLightingStabilizedMaterials.Remove(val);
						_runtimeLightingStabilizedMaterials.Add(val2);
						_runtimeLightingMaterialSnapshots[val2] = value;
						_runtimeLightingMaterialSnapshots.Remove(val);
					}
					if (_originalMaterialColors.TryGetValue(val, out var value2))
					{
						_originalMaterialColors[val2] = value2;
						_originalMaterialColors.Remove(val);
					}
				}
			}
		}

		private static string NormalizeMaterialName(string materialName, string rendererName)
		{
			string text = (materialName ?? string.Empty) + "|" + (rendererName ?? string.Empty);
			int num = text.IndexOf("_Runtime", StringComparison.Ordinal);
			if (num >= 0)
			{
				text = text.Substring(0, num) + text.Substring(num + "_Runtime".Length);
			}
			return text;
		}

		private static bool IsHairMaterialName(string normalizedName)
		{
			if (normalizedName.IndexOf("Hair", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("Tails", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("TailS", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("头发", StringComparison.Ordinal) < 0 && normalizedName.IndexOf("前髪", StringComparison.Ordinal) < 0 && normalizedName.IndexOf("後髪", StringComparison.Ordinal) < 0)
			{
				return normalizedName.IndexOf("後ろ髪", StringComparison.Ordinal) >= 0;
			}
			return true;
		}

		private static bool IsClothMaterialName(string normalizedName)
		{
			if (normalizedName.IndexOf("Cloth", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("Dress", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("Shirt", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("服装", StringComparison.Ordinal) < 0 && normalizedName.IndexOf("衣服", StringComparison.Ordinal) < 0 && normalizedName.IndexOf("上着", StringComparison.Ordinal) < 0 && normalizedName.IndexOf("Skirt", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("裙子", StringComparison.Ordinal) < 0 && normalizedName.IndexOf("Sock_", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("Bow_", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("Frill_", StringComparison.OrdinalIgnoreCase) < 0 && normalizedName.IndexOf("Buttons_", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return normalizedName.IndexOf("Ribbon", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private static void SetMaterialColor(Material material, Color color)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", color);
			}
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", color);
			}
		}

		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 num = 0; num < array.Length; num++)
			{
				Material val2 = ((num < sharedMaterials.Length) ? sharedMaterials[num] : null);
				if ((Object)(object)val2 != (Object)null)
				{
					array[num] = val2;
					val = val2;
				}
				else
				{
					array[num] = 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 bool IsSkinMaterialName(string materialName)
		{
			string text = materialName ?? string.Empty;
			if (text.IndexOf("Skin", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("皮肤", StringComparison.Ordinal) >= 0;
			}
			return true;
		}

		private static bool IsExposureAffectedMaterialName(string materialName)
		{
			string text = materialName ?? string.Empty;
			if (text.IndexOf("Skin", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("皮肤", StringComparison.Ordinal) < 0 && text.IndexOf("Face", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("脸", StringComparison.Ordinal) < 0 && text.IndexOf("Neck", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("脖子", StringComparison.Ordinal) < 0 && text.IndexOf("Jaw", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("下巴", StringComparison.Ordinal) >= 0;
			}
			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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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)
			Material val = new Material(sourceMaterial)
			{
				name = (string.IsNullOrWhiteSpace(((Object)sourceMaterial).name) ? "MikuLightSafeMaterial" : (((Object)sourceMaterial).name + "_LightSafe"))
			};
			float exposure = Mathf.Clamp(exposureCompensation, 0.4f, 1f);
			snapshot = RuntimeLightingMaterialSnapshot.Capture(val, RuntimeLightingExposureColorProperties);
			if (IsExposureAffectedMaterialName(((Object)sourceMaterial).name))
			{
				ApplyLightingExposure(val, snapshot, exposure);
			}
			ClampColorPropertyMax(val, "_Ambient", 0.22f);
			ClampColorPropertyMax(val, "_IndirectLightMinColor", 0.06f);
			ClampColorPropertyMax(val, "_SpecColor", 0.18f);
			ClampColorPropertyMax(val, "_EmissionColor", 0.45f);
			SetFloatIfPresent(val, "_Metallic", 0f);
			ClampFloatPropertyMax(val, "_Smoothness", 0.18f);
			ClampFloatPropertyMax(val, "_Glossiness", 0.18f);
			SetFloatIfPresent(val, "_SpecularHighlights", 0f);
			SetFloatIfPresent(val, "_EnvironmentReflections", 0f);
			SetFloatIfPresent(val, "_ReceiveShadowMappingAmount", 0.9f);
			ClampFloatPropertyMin(val, "_ShadowLum", 1.35f);
			if (IsSkinMaterialName(((Object)sourceMaterial).name))
			{
				SetFloatIfPresent(val, "_Smoothness", 0f);
				SetFloatIfPresent(val, "_Glossiness", 0f);
				SetFloatIfPresent(val, "_OcclusionStrength", 0f);
			}
			if (val.HasProperty("_ToonTone"))
			{
				Vector4 vector = val.GetVector("_ToonTone");
				vector.y = Mathf.Min(vector.y, 0.42f);
				vector.z = Mathf.Min(vector.z, 0.45f);
				val.SetVector("_ToonTone", vector);
			}
			if (val.HasProperty("_SphereMapMode") && val.GetFloat("_SphereMapMode") > 1.5f)
			{
				val.SetFloat("_SphereMapMode", 1f);
			}
			val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4;
			return val;
		}

		private void RefreshRuntimeLightingIfConfigChanged()
		{
			if (_config == null)
			{
				return;
			}
			bool value = _config.StabilizeModelLighting.Value;
			float resolvedLightingExposureCompensation = _config.ResolvedLightingExposureCompensation;
			if (!_pendingRuntimeLightingRefresh && _lastAppliedStabilizeModelLighting == value && Mathf.Approximately(_lastAppliedLightingExposureCompensation, resolvedLightingExposureCompensation))
			{
				return;
			}
			_pendingRuntimeLightingRefresh = false;
			if ((Object)(object)_activeDancer == (Object)null)
			{
				RecordAppliedRuntimeLightingConfiguration(value, resolvedLightingExposureCompensation);
				return;
			}
			if (value)
			{
				if (_runtimeLightingStabilizedMaterials.Count == 0)
				{
					NormalizeRendererMaterials(_activeDancer);
					LogVerbose("Runtime lighting stabilization enabled from config without respawning model. " + $"exposureCompensation={resolvedLightingExposureCompensation:0.###}.");
					return;
				}
				ApplyRuntimeLightingExposure(resolvedLightingExposureCompensation);
				ReapplyAllMaterialColors();
			}
			else
			{
				ApplyRuntimeLightingExposure(1f);
				ReapplyAllMaterialColors();
			}
			RecordAppliedRuntimeLightingConfiguration(value, resolvedLightingExposureCompensation);
			LogVerbose($"Applied live runtime lighting config. stabilizeLighting={value}, " + $"exposureCompensation={resolvedLightingExposureCompensation:0.###}, activeMaterials={_runtimeLightingStabilizedMaterials.Count}.");
		}

		private void ApplyRuntimeLightingExposure(float exposureCompensation)
		{
			float exposure = Mathf.Clamp(exposureCompensation, 0.4f, 1f);
			foreach (Material runtimeLightingStabilizedMaterial in _runtimeLightingStabilizedMaterials)
			{
				if (!((Object)(object)runtimeLightingStabilizedMaterial == (Object)null) && _runtimeLightingMaterialSnapshots.TryGetValue(runtimeLightingStabilizedMaterial, out RuntimeLightingMaterialSnapshot value) && IsExposureAffectedMaterialName(((Object)runtimeLightingStabilizedMaterial).name))
				{
					ApplyLightingExposure(runtimeLightingStabilizedMaterial, value, exposure);
				}
			}
		}

		private static void ApplyLightingExposure(Material material, RuntimeLightingMaterialSnapshot snapshot, float exposure)
		{
			//IL_0024: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			string[] runtimeLightingExposureColorProperties = RuntimeLightingExposureColorProperties;
			foreach (string text in runtimeLightingExposureColorProperties)
			{
				if (material.HasProperty(text) && snapshot.TryGetColor(text, out var color))
				{
					material.SetColor(text, new Color(Mathf.Clamp01(color.r * exposure), Mathf.Clamp01(color.g * exposure), Mathf.Clamp01(color.b * exposure), color.a));
				}
			}
		}

		private void RecordAppliedRuntimeLightingConfiguration(bool stabilizeLighting, float exposureCompensation)
		{
			_lastAppliedStabilizeModelLighting = stabilizeLighting;
			_lastAppliedLightingExposureCompensation = Mathf.Clamp(exposureCompensation, 0.4f, 1f);
		}

		private static bool HasAnyMaterialProperty(Material material, IEnumerable<string> propertyNames)
		{
			return propertyNames.Any((Func<string, bool>)material.HasProperty);
		}

		private static void ClampColorPropertyMax(Material material, string propertyName, float maxChannel)
		{
			//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_001c: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty(propertyName))
			{
				maxChannel = Mathf.Clamp01(maxChannel);
				Color color = material.GetColor(propertyName);
				material.SetColor(propertyName, new Color(Mathf.Min(color.r, maxChannel), Mathf.Min(color.g, maxChannel), Mathf.Min(color.b, maxChannel), color.a));
			}
		}

		private static void SetFloatIfPresent(Material material, string propertyName, float value)
		{
			if (material.HasProperty(propertyName))
			{
				material.SetFloat(propertyName, value);
			}
		}

		private static void ClampFloatPropertyMax(Material material, string propertyName, float maxValue)
		{
			if (material.HasProperty(propertyName))
			{
				material.SetFloat(propertyName, Mathf.Min(material.GetFloat(propertyName), maxValue));
			}
		}

		private static void ClampFloatPropertyMin(Material material, string propertyName, float minValue)
		{
			if (material.HasProperty(propertyName))
			{
				material.SetFloat(propertyName, Mathf.Max(material.GetFloat(propertyName), minValue));
			}
		}

		private static Material CreateFallbackRendererMaterial()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			Shader val = Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Diffuse");
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return new Material(val);
		}

		private void DestroyRuntimeLightingStabilizedMaterials()
		{
			if (_runtimeLightingStabilizedMaterials.Count == 0)
			{
				_runtimeLightingMaterialSnapshots.Clear();
				return;
			}
			for (int i = 0; i < _runtimeLightingStabilizedMaterials.Count; i++)
			{
				Material val = _runtimeLightingStabilizedMaterials[i];
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			_runtimeLightingStabilizedMaterials.Clear();
			_runtimeLightingMaterialSnapshots.Clear();
		}

		private static int GetExpectedMaterialCount(Renderer renderer)
		{
			SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
			if (val != null && (Object)(object)val.sharedMesh != (Object)null)
			{
				return Mathf.Max(1, val.sharedMesh.subMeshCount);
			}
			MeshFilter val2 = default(MeshFilter);
			if (((Component)renderer).TryGetComponent<MeshFilter>(ref val2) && (Object)(object)val2.sharedMesh != (Object)null)
			{
				return Mathf.Max(1, val2.sharedMesh.subMeshCount);
			}
			Material[] sharedMaterials = renderer.sharedMaterials;
			return Mathf.Max(1, (sharedMaterials != null) ? sharedMaterials.Length : 0);
		}

		private void UpdateShadowPresentation(GameObject root)
		{
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)_activeShadowBlob != (Object)null) || !((Object)(object)((Component)val).gameObject == (Object)(object)_activeShadowBlob))
				{
					val.enabled = true;
					val.shadowCastingMode = (ShadowCastingMode)1;
					val.receiveShadows = false;
					val.allowOcclusionWhenDynamic = true;
					val.lightProbeUsage = (LightProbeUsage)0;
					val.reflectionProbeUsage = (ReflectionProbeUsage)0;
					EnableShadowSupport(val.sharedMaterials);
				}
			}
			DestroyActiveShadowBlob();
		}

		private void DestroyActiveShadowBlob()
		{
			if (!((Object)(object)_activeShadowBlob == (Object)null))
			{
				LogVerbose("Destroying shadow blob '" + ((Object)_activeShadowBlob).name + "' (replaced by Unity standard shadows).");
				Object.Destroy((Object)(object)_activeShadowBlob);
				_activeShadowBlob = null;
			}
		}

		private static void EnableShadowSupport(Material[]? materials)
		{
			if (materials != null)
			{
				for (int i = 0; i < materials.Length; i++)
				{
					EnableShadowSupport(materials[i]);
				}
			}
		}

		private static void EnableShadowSupport(Material? material)
		{
			if (!((Object)(object)material == (Object)null))
			{
				if (material.HasProperty("_ReceiveShadows"))
				{
					material.SetFloat("_ReceiveShadows", 1f);
				}
				if (material.HasProperty("_CastShadows"))
				{
					material.SetFloat("_CastShadows", 1f);
				}
				material.SetShaderPassEnabled("ShadowCaster", true);
			}
		}

		private void ConfigurePlayback(GameObject dancer)
		{
			CacheActiveRuntimeComponents(dancer);
			AudioSource activeAudioSource = _activeAudioSource;
			AudioClip val = ResolveAudioClip(activeAudioSource);
			Animator activeAnimator = _activeAnimator;
			if ((Object)(object)activeAnimator != (Object)null && (Object)(object)activeAnimator.runtimeAnimatorController != (Object)null)
			{
				ConfigureAudioSource(activeAudioSource, val);
				AnimationClip val2 = ResolveSynchronizedAnimatorClip(activeAnimator);
				float num = ResolveSynchronizedAnimatorSpeed(val2, val);
				bool num2 = HasNativeFacialAnimationControl(dancer);
				activeAnimator.cullingMode = (AnimatorCullingMode)0;
				activeAnimator.applyRootMotion = false;
				activeAnimator.updateMode = (AnimatorUpdateMode)0;
				activeAnimator.speed = num;
				activeAnimator.Rebind();
				activeAnimator.Update(0f);
				StartAnimatorAtBeginning(activeAnimator, val2);
				if (num2)
				{
					StopRuntimeMorphPlayback();
				}
				else
				{
					StartMorphPlayback(dancer);
				}
				ConfigureSecondaryNativeAnimators(val2, num);
				ApplyActiveAnimationPlaybackSpeed(val);
				bool flag = (Object)(object)activeAudioSource != (Object)null && (Object)(object)val != (Object)null && SynchronizeAudioWithAnimator(activeAnimator, activeAudioSource, val, val2, startIfNeeded: true, allowFadeOnStart: true, suppressFurtherRetries: true, logCorrections: false);
				string[] obj = new string[11]
				{
					"Animator configured for '",
					((Object)dancer).name,
					"', controller='",
					((Object)activeAnimator.runtimeAnimatorController).name,
					"', avatar='",
					null,
					null,
					null,
					null,
					null,
					null
				};
				Avatar avatar = activeAnimator.avatar;
				obj[5] = ((avatar != null) ? ((Object)avatar).name : null) ?? "(none)";
				obj[6] = "', ";
				obj[7] = string.Format("clip='{0}', clipLength={1:0.###}, ", ((val2 != null) ? ((Object)val2).name : null) ?? "(none)", (val2 != null) ? val2.length : 0f);
				obj[8] = string.Format("audioEnabled={0}, audioClip='{1}', audioLength={2:0.###}, ", _config?.EnableAudio.Value ?? false, ((val != null) ? ((Object)val).name : null) ?? "(none)", (val != null) ? val.length : 0f);
				obj[9] = $"audioSegmentStart={ResolveAudioSegmentStartSeconds(val2, val):0.###}, audioSegmentLength={ResolveAudioSegmentDuration(val2, val):0.###}, ";
				obj[10] = $"animatorSpeed={num:0.###}, audioVolume={_config?.ResolvedAudioVolume ?? 0f:0.###}, audioRange={_config?.ResolvedAudioRangeMeters ?? 0f:0.###}, audioStarted={flag}, audioIsPlaying={activeAudioSource != null && activeAudioSource.isPlaying}.";
				LogVerbose(string.Concat(obj));
				return;
			}
			Animation activeAnimation = _activeAnimation;
			if ((Object)(object)activeAnimation != (Object)null && (Object)(object)_loadedPrefab?.Clip != (Object)null)
			{
				activeAnimation.cullingType = (AnimationCullingType)0;
				if ((Object)(object)activeAnimation.GetClip(((Object)_loadedPrefab.Clip).name) == (Object)null)
				{
					activeAnimation.AddClip(_loadedPrefab.Clip, ((Object)_loadedPrefab.Clip).name);
				}
				activeAnimation.clip = _loadedPrefab.Clip;
				activeAnimation.wrapMode = (WrapMode)2;
				activeAnimation.Stop();
				activeAnimation.Rewind();
				activeAnimation.Play(((Object)_loadedPrefab.Clip).name);
				ConfigureAudioSource(activeAudioSource, val);
				ApplyActiveAnimationPlaybackSpeed(val);
				if (HasNativeFacialAnimationControl(dancer))
				{
					StopRuntimeMorphPlayback();
				}
				StartAudioIfEnabled(activeAudioSource, val, _loadedPrefab.Clip, suppressFurtherRetries: true);
				LogVerbose($"Animation configured for '{((Object)dancer).name}', clip='{((Object)_loadedPrefab.Clip).name}', isPlaying={activeAnimation.isPlaying}.");
			}
			else if (HasNativeFacialAnimationControl(dancer))
			{
				StopRuntimeMorphPlayback();
			}
			else
			{
				StartMorphPlayback(dancer);
			}
		}

		private void ConfigureFacialExpressions(GameObject dancer)
		{
			CacheActiveRuntimeComponents(dancer);
			if (HasNativeFacialAnimationControl(dancer))
			{
				MikuFacialExpressionController component = dancer.GetComponent<MikuFacialExpressionController>();
				if ((Object)(object)component != (Object)null)
				{
					((Behaviour)component).enabled = false;
				}
				StopRuntimeMorphPlayback();
				LogVerbose("Skipping runtime facial expression playback for '" + ((Object)dancer).name + "' because Unity-native facial animation control was detected.");
				return;
			}
			if ((Object)(object)_loadedPrefab?.MorphClip != (Object)null)
			{
				MikuFacialExpressionController component2 = dancer.GetComponent<MikuFacialExpressionController>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = false;
				}
				LogVerbose("Skipping fallback facial expression controller for '" + ((Object)dancer).name + "' because a bundled morph clip is available.");
				return;
			}
			LoadedDancePrefab? loadedPrefab = _loadedPrefab;
			if (loadedPrefab != null && loadedPrefab.Source == LoadedPrefabSource.UnityAssetBundle && (Object)(object)_activeAnimator != (Object)null && (Object)(object)_activeAnimator.runtimeAnimatorController != (Object)null && (Object)(object)_activePrimaryAnimatorClip != (Object)null)
			{
				LogVerbose("Unity AssetBundle Animator clip '" + ((Object)_activePrimaryAnimatorClip).name + "' is active on '" + ((Object)dancer).name + "', but no morph bridge is available. Falling back to simplified facial controller.");
			}
			(dancer.GetComponent<MikuFacialExpressionController>() ?? dancer.AddComponent<MikuFacialExpressionController>()).Initialize(_activeAudioSource, _activeAnimator, _logger);
		}

		private void RefreshLivePlayback(GameObject dancer)
		{
			CacheActiveRuntimeComponents(dancer);
			Animator activeAnimator = _activeAnimator;
			AudioSource activeAudioSource = _activeAudioSource;
			AudioClip val = ResolveAudioClip(activeAudioSource);
			ConfigureAudioSource(activeAudioSource, val);
			HandleAudioToggleState();
			if (HandlePlaybackPause(dancer, activeAnimator, activeAudioSource, val) || _isInLoopInterval)
			{
				return;
			}
			if ((Object)(object)activeAnimator != (Object)null && (Object)(object)activeAnimator.runtimeAnimatorController != (Object)null)
			{
				AnimationClip val2 = ResolveSynchronizedAnimatorClip(activeAnimator);
				activeAnimator.speed = ResolveSynchronizedAnimatorSpeed(val2, val);
				ForceAnimatorLayerWeights(activeAnimator, 1f);
				RefreshSecondaryNativeAnimators(activeAnimator, val2);
				ApplyActiveAnimationPlaybackSpeed(val);
				DancePluginConfig? config = _config;
				if (config != null && config.EnableAudio.Value && (Object)(object)activeAudioSource != (Object)null && (Object)(object)val != (Object)null && !_audioRetrySuppressed)
				{
					bool isPlaying = activeAudioSource.isPlaying;
					if (SynchronizeAudioWithAnimator(activeAnimator, activeAudioSource, val, val2, startIfNeeded: true, allowFadeOnStart: true, suppressFurtherRetries: true, logCorrections: false) && !isPlaying)
					{
						LogVerbose("Audio was enabled while the model was already active. Aligned synchronized playback with clip '" + ((Object)val).name + "'.");
					}
				}
			}
			else
			{
				DancePluginConfig? config2 = _config;
				if (config2 != null && config2.EnableAudio.Value && (Object)(object)activeAudioSource != (Object)null && (Object)(object)val != (Object)null && !activeAudioSource.isPlaying && !_audioRetrySuppressed)
				{
					StartAudioIfEnabled(activeAudioSource, val, _loadedPrefab?.Clip, suppressFurtherRetries: true);
				}
			}
		}

		private void HandleAudioToggleState()
		{
			bool flag = _config?.EnableAudio.Value ?? false;
			if (flag != _lastAudioEnabledState)
			{
				_audioRetrySuppressed = false;
				_lastAudioEnabledState = flag;
			}
		}

		private void ResetAudioPlaybackState()
		{
			_audioRetrySuppressed = false;
			_lastAudioEnabledState = _config?.EnableAudio.Value ?? false;
			_animatorSegmentLoopIndex = 0;
			_lastAnimatorLoopIndex = -1;
			_lastMorphLoopIndex = -1;
			_isInLoopInterval = false;
			_loopIntervalEndTime = -1f;
			_isPausedForOfflineMenu = false;
			_isPausedForDistance = false;
			_audioPausedForPlaybackPause = false;
			ClearActiveAudioFade();
		}

		private void ConfigureAudioSource(AudioSource? audioSource, AudioClip? audioClip)
		{
			if (!((Object)(object)audioSource == (Object)null))
			{
				if ((Object)(object)audioClip != (Object)null && (Object)(object)audioSource.clip == (Object)null)
				{
					audioSource.clip = audioClip;
				}
				audioSource.playOnAwake = false;
				audioSource.loop = false;
				DancePluginConfig? config = _config;
				audioSource.mute = config == null || !config.EnableAudio.Value;
				if (!IsActiveAudioFade(audioSource))
				{
					audioSource.volume = _config?.ResolvedAudioVolume ?? 1f;
				}
				float maxDistance = Mathf.Max(1.01f, _config?.ResolvedAudioRangeMeters ?? 5f);
				audioSource.spatialBlend = 1f;
				audioSource.dopplerLevel = 0f;
				audioSource.priority = 32;
				audioSource.rolloffMode = (AudioRolloffMode)1;
				audioSource.minDistance = 1f;
				audioSource.maxDistance = maxDistance;
				audioSource.spread = 0f;
				DancePluginConfig? config2 = _config;
				if (config2 != null && config2.EnableAudio.Value)
				{
					RequestAudioClipLoad(audioClip);
				}
				DancePluginConfig? config3 = _config;
				if ((config3 == null || !config3.EnableAudio.Value) && audioSource.isPlaying)
				{
					ClearActiveAudioFade(audioSource);
					audioSource.Stop();
					audioSource.time = 0f;
				}
			}
		}

		private bool StartAudioIfEnabled(AudioSource? audioSource, AudioClip? audioClip, AnimationClip? animationClip, bool suppressFurtherRetries)
		{
			DancePluginConfig? config = _config;
			if (config == null || !config.EnableAudio.Value || (Object)(object)audioSource == (Object)null || (Object)(object)audioClip == (Object)null)
			{
				if ((Object)(object)audioSource != (Object)null)
				{
					ClearActiveAudioFade(audioSource);
					audioSource.Stop();
					aud