Decompiled source of MikuShowcase v1.0.2
plugins/com.github.Thanks.MikuShowcase.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
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