using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using Y4NGZInteractions.InteractionAnimationApi; using Y4NGZInteractions.InteractionAnimationApi.Authoring; using Y4NGZInteractions.InteractionAnimationApi.Presenters; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Y4NGZInteractions.Tests")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Y4NGZInteractions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Consumer-agnostic local animation presentation API for Lethal Company")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("Y4NGZInteractions")] [assembly: AssemblyTitle("Y4NGZInteractions")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Y4NGZInteractions { internal sealed class InteractionRuntimeHost : MonoBehaviour { private Harmony harmony; private ManualLogSource log; private bool applicationQuitting; private bool tornDown; internal void Initialize(Harmony harmony, ManualLogSource log) { this.harmony = harmony; this.log = log; Application.quitting += OnApplicationQuitting; } private void LateUpdate() { InteractionAnimationApiRestoreDiagnostics.BeginCoordinatorLateUpdateTick(); try { InteractionAnimationApiPlugin.Tick(Time.deltaTime); } finally { InteractionAnimationApiRestoreDiagnostics.EndCoordinatorLateUpdateTick(); } } private void OnApplicationQuit() { applicationQuitting = true; } private void OnApplicationQuitting() { applicationQuitting = true; TearDown(); } private void OnDestroy() { Application.quitting -= OnApplicationQuitting; if (!applicationQuitting) { ManualLogSource obj = log; if (obj != null) { obj.LogError((object)("Y4NGZInteractions runtime host destroyed outside application shutdown " + string.Format("(frame={0}, host='{1}'). ", Time.frameCount, ((Object)(object)((Component)this).gameObject != (Object)null) ? ((Object)((Component)this).gameObject).name : "") + "The interaction animation API and all Harmony patches are going down with it.")); } } TearDown(); } private void TearDown() { if (tornDown) { return; } tornDown = true; try { InteractionAnimationApiPlugin.Shutdown(); InteractionAnimationApiRestoreDiagnostics.Shutdown(); } catch (Exception ex) { ManualLogSource obj = log; if (obj != null) { obj.LogWarning((object)("Y4NGZInteractions shutdown warning: " + ex.Message)); } } Harmony obj2 = harmony; if (obj2 != null) { obj2.UnpatchSelf(); } } } [BepInPlugin("com.y4ngz.interactions", "Y4NGZInteractions", "1.0.1")] internal sealed class Plugin : BaseUnityPlugin { internal const string Guid = "com.y4ngz.interactions"; internal const string Name = "Y4NGZInteractions"; internal const string Version = "1.0.1"; internal const string HostObjectName = "Y4NGZInteractions_Host"; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static InteractionRuntimeHost Host { get; private set; } private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Harmony harmony = new Harmony("com.y4ngz.interactions"); GameObject val = new GameObject("Y4NGZInteractions_Host") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); Host = val.AddComponent(); Host.Initialize(harmony, ((BaseUnityPlugin)this).Logger); InitializeModule("Interaction Animation API", delegate { InteractionAnimationApiPlugin.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); }); InitializeModule("Interaction Animation API Restoration", delegate { InteractionAnimationApiRestoreDiagnostics.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); }); InitializeModule("Interaction Animation API Spawn Hooks", delegate { harmony.PatchAll(); }); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Y4NGZInteractions v1.0.1 loaded."); } private void InitializeModule(string label, Action initialize) { try { initialize(); ((BaseUnityPlugin)this).Logger.LogInfo((object)(label + " initialized.")); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"{label} initialization failed: {arg}"); } } } internal static class BuildVersion { internal const string Value = "1.0.1"; } } namespace Y4NGZInteractions.InteractionAnimationApi { internal static class InteractionAnimationApiPlugin { private static ManualLogSource logger; private static InteractionAnimationCoordinator coordinator; private static bool initialized; internal static void Initialize(ConfigFile config, ManualLogSource log) { if (!initialized) { logger = log; coordinator = new InteractionAnimationCoordinator(logger); LCInteractionAnimationAPI.Initialize(coordinator); initialized = true; ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)"[LCInteractionAnimationAPI] api.initialized: standalone local presentation API ready."); } } } internal static void Tick(float deltaTime) { if (initialized) { coordinator?.Tick(deltaTime); } } internal static void Shutdown() { if (initialized) { coordinator?.Shutdown(); LiveBodyAnimatorPresenter.ShutdownBundleCache(); LCInteractionAnimationAPI.Shutdown(); coordinator = null; initialized = false; ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)"[LCInteractionAnimationAPI] api.shutdown: restoration complete."); } logger = null; } } } internal enum AnimatorStateRestoreMode { Fresh, Crossfade, Replay } internal sealed class AnimatorStateSnapshot { private readonly struct LayerSnapshot { public readonly int FullPathHash; public readonly float NormalizedTime; public readonly float Weight; public readonly bool InTransition; public LayerSnapshot(int fullPathHash, float normalizedTime, float weight, bool inTransition) { FullPathHash = fullPathHash; NormalizedTime = normalizedTime; Weight = weight; InTransition = inTransition; } } private readonly struct ParameterSnapshot { private readonly int nameHash; private readonly AnimatorControllerParameterType type; private readonly bool boolValue; private readonly int intValue; private readonly float floatValue; private ParameterSnapshot(int nameHash, AnimatorControllerParameterType type, bool boolValue, int intValue, float floatValue) { //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) this.nameHash = nameHash; this.type = type; this.boolValue = boolValue; this.intValue = intValue; this.floatValue = floatValue; } public static ParameterSnapshot Capture(Animator animator, AnimatorControllerParameter parameter) { //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_0007: 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_001f: Expected I4, but got Unknown //IL_0070: 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_004c: 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) AnimatorControllerParameterType val = parameter.type; return (val - 1) switch { 3 => new ParameterSnapshot(parameter.nameHash, parameter.type, animator.GetBool(parameter.nameHash), 0, 0f), 2 => new ParameterSnapshot(parameter.nameHash, parameter.type, boolValue: false, animator.GetInteger(parameter.nameHash), 0f), 0 => new ParameterSnapshot(parameter.nameHash, parameter.type, boolValue: false, 0, animator.GetFloat(parameter.nameHash)), _ => new ParameterSnapshot(parameter.nameHash, parameter.type, boolValue: false, 0, 0f), }; } public void Restore(Animator animator) { //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_0007: 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_001f: Expected I4, but got Unknown AnimatorControllerParameterType val = type; switch (val - 1) { case 3: animator.SetBool(nameHash, boolValue); break; case 2: animator.SetInteger(nameHash, intValue); break; case 0: animator.SetFloat(nameHash, floatValue); break; case 1: break; } } } private const float CrossfadeDurationSeconds = 0.12f; private readonly LayerSnapshot[] layers; private readonly ParameterSnapshot[] parameters; public RuntimeAnimatorController RuntimeAnimatorController { get; } public float Speed { get; } public bool? CapturedCrouching { get; set; } private AnimatorStateSnapshot(RuntimeAnimatorController runtimeAnimatorController, float speed, LayerSnapshot[] layers, ParameterSnapshot[] parameters) { RuntimeAnimatorController = runtimeAnimatorController; Speed = speed; this.layers = layers ?? Array.Empty(); this.parameters = parameters ?? Array.Empty(); } public static AnimatorStateSnapshot Capture(Animator animator) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)animator == (Object)null) { return null; } try { RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController; float speed = animator.speed; if (!animator.isInitialized) { return new AnimatorStateSnapshot(runtimeAnimatorController, speed, Array.Empty(), Array.Empty()); } int num = Math.Max(0, animator.layerCount); LayerSnapshot[] array = new LayerSnapshot[num]; for (int i = 0; i < num; i++) { AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(i); array[i] = new LayerSnapshot(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, animator.GetLayerWeight(i), animator.IsInTransition(i)); } AnimatorControllerParameter[] array2 = animator.parameters ?? Array.Empty(); ParameterSnapshot[] array3 = new ParameterSnapshot[array2.Length]; for (int j = 0; j < array2.Length; j++) { AnimatorControllerParameter parameter = array2[j]; array3[j] = ParameterSnapshot.Capture(animator, parameter); } return new AnimatorStateSnapshot(runtimeAnimatorController, speed, array, array3); } catch { return null; } } public int ReapplyParameters(Animator animator) { if ((Object)(object)animator == (Object)null) { return 0; } int num = 0; for (int i = 0; i < parameters.Length; i++) { try { parameters[i].Restore(animator); num++; } catch { } } return num; } public bool TryReapplyLayerState(Animator animator, int layerIndex) { if ((Object)(object)animator == (Object)null || layerIndex < 0 || layerIndex >= layers.Length || layerIndex >= animator.layerCount) { return false; } try { LayerSnapshot layerSnapshot = layers[layerIndex]; if (layerSnapshot.InTransition || layerSnapshot.FullPathHash == 0 || !animator.HasState(layerIndex, layerSnapshot.FullPathHash)) { return false; } animator.SetLayerWeight(layerIndex, layerSnapshot.Weight); animator.Play(layerSnapshot.FullPathHash, layerIndex, layerSnapshot.NormalizedTime); return true; } catch { return false; } } public bool Restore(Animator animator) { return Restore(animator, RuntimeAnimatorController); } public bool Restore(Animator animator, RuntimeAnimatorController expectedCurrentController) { return Restore(animator, expectedCurrentController, rebindAnimator: true); } public bool Restore(Animator animator, RuntimeAnimatorController expectedCurrentController, bool rebindAnimator) { return Restore(animator, expectedCurrentController, rebindAnimator, AnimatorStateRestoreMode.Replay); } public bool Restore(Animator animator, RuntimeAnimatorController expectedCurrentController, bool rebindAnimator, AnimatorStateRestoreMode restoreMode) { return Restore(animator, expectedCurrentController, rebindAnimator, restoreMode, null, restoreBaseLayerState: true); } public bool Restore(Animator animator, RuntimeAnimatorController expectedCurrentController, bool rebindAnimator, AnimatorStateRestoreMode restoreMode, Action syncParametersBeforeStateReplay, bool restoreBaseLayerState) { if ((Object)(object)animator == (Object)null) { return false; } try { if ((Object)(object)expectedCurrentController != (Object)null && (Object)(object)animator.runtimeAnimatorController != (Object)(object)expectedCurrentController) { return false; } animator.runtimeAnimatorController = RuntimeAnimatorController; if (rebindAnimator) { animator.Rebind(); } animator.speed = Speed; for (int i = 0; i < parameters.Length; i++) { parameters[i].Restore(animator); } if (syncParametersBeforeStateReplay != null) { try { syncParametersBeforeStateReplay(); } catch { } } int num = Math.Min(animator.layerCount, layers.Length); for (int j = 0; j < num; j++) { LayerSnapshot layerSnapshot = layers[j]; animator.SetLayerWeight(j, layerSnapshot.Weight); if ((j != 0 || restoreBaseLayerState) && layerSnapshot.FullPathHash != 0) { switch (restoreMode) { case AnimatorStateRestoreMode.Crossfade: animator.CrossFadeInFixedTime(layerSnapshot.FullPathHash, 0.12f, j, Mathf.Repeat(layerSnapshot.NormalizedTime, 1f)); break; case AnimatorStateRestoreMode.Replay: animator.Play(layerSnapshot.FullPathHash, j, layerSnapshot.NormalizedTime); break; } } } animator.Update(0f); return true; } catch { return false; } } } internal static class InteractionAnimationAssetPathResolver { internal const string RootMissingReason = "pack_asset_root_missing"; internal const string PathEscapesRootReason = "asset_bundle_path_escapes_root"; internal static bool TryNormalizeAssetRoot(string assetRootPath, out string normalizedRoot, out string reason) { normalizedRoot = string.Empty; reason = string.Empty; if (string.IsNullOrWhiteSpace(assetRootPath)) { reason = "pack_asset_root_missing"; return false; } try { normalizedRoot = TrimEndingDirectorySeparators(Path.GetFullPath(assetRootPath.Trim())); } catch (Exception ex) { reason = "pack_asset_root_invalid:" + ex.GetType().Name; normalizedRoot = string.Empty; return false; } if (!Directory.Exists(normalizedRoot)) { reason = "pack_asset_root_missing:" + normalizedRoot; normalizedRoot = string.Empty; return false; } return true; } internal static bool TryResolveBundlePath(string bundleFileName, string normalizedAssetRoot, out string resolvedPath, out string reason) { resolvedPath = string.Empty; reason = string.Empty; if (string.IsNullOrWhiteSpace(bundleFileName)) { reason = "asset_bundle_file_empty"; return false; } if (string.IsNullOrWhiteSpace(normalizedAssetRoot)) { reason = "pack_asset_root_missing"; return false; } try { string text = (Path.IsPathRooted(bundleFileName) ? Path.GetFullPath(bundleFileName) : Path.GetFullPath(Path.Combine(normalizedAssetRoot, bundleFileName))); if (!IsWithinRoot(normalizedAssetRoot, text)) { reason = "asset_bundle_path_escapes_root:" + bundleFileName; return false; } resolvedPath = text; return true; } catch (Exception ex) { reason = "asset_bundle_path_invalid:" + ex.GetType().Name; return false; } } private static bool IsWithinRoot(string normalizedRoot, string candidate) { string text = TrimEndingDirectorySeparators(Path.GetFullPath(normalizedRoot)); string fullPath = Path.GetFullPath(candidate); if (string.Equals(text, fullPath, StringComparison.OrdinalIgnoreCase)) { return true; } return fullPath.StartsWith(text + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); } private static string TrimEndingDirectorySeparators(string path) { string text = Path.GetPathRoot(path) ?? string.Empty; while (path.Length > text.Length && (path[path.Length - 1] == Path.DirectorySeparatorChar || path[path.Length - 1] == Path.AltDirectorySeparatorChar)) { path = path.Substring(0, path.Length - 1); } return path; } } internal delegate bool InteractionAnimationBodyOwnershipValidator(PlayerControllerB player, InteractionAnimationPresentationKind presentationKind, InteractionAnimationHandle[] conflicts, out string reason); internal sealed class InteractionAnimationCoordinator { private readonly ManualLogSource logger; private readonly Func presenterFactory; private readonly Func localPlayerResolver; private readonly InteractionAnimationBodyOwnershipValidator bodyOwnershipValidator; private readonly Func sessionFactory; private readonly Dictionary packs = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary activeSessions = new Dictionary(); private readonly InteractionAnimationResourceLeaseRegistry leases = new InteractionAnimationResourceLeaseRegistry(); internal InteractionAnimationCoordinator(ManualLogSource logger, Func presenterFactory = null, Func localPlayerResolver = null, InteractionAnimationBodyOwnershipValidator bodyOwnershipValidator = null, Func sessionFactory = null) { this.logger = logger; this.presenterFactory = presenterFactory ?? new Func(CreateDefaultPresenter); this.localPlayerResolver = localPlayerResolver ?? new Func(ResolveDefaultLocalPlayer); this.bodyOwnershipValidator = bodyOwnershipValidator ?? new InteractionAnimationBodyOwnershipValidator(TryValidateBodyAnimatorOwnership); this.sessionFactory = sessionFactory ?? ((Func)((InteractionAnimationContext context, IInteractionPresenter presenter) => new InteractionAnimationSession(context, presenter))); } internal bool TryRegisterInteractionPack(InteractionAnimationPackDefinition pack, out string reason) { RegisteredPackSnapshot snapshot; InteractionAnimationValidationReport interactionAnimationValidationReport = InteractionAnimationPackValidator.Validate(pack, out snapshot); reason = InteractionAnimationManifestValidator.GetFirstErrorCode(interactionAnimationValidationReport); if (!interactionAnimationValidationReport.IsValid) { return false; } if (packs.ContainsKey(snapshot.PackId)) { reason = "pack_already_registered"; return false; } packs.Add(snapshot.PackId, snapshot); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)("[LCInteractionAnimationAPI] pack.registered: pack='" + snapshot.PackId + "' version='" + snapshot.Version + "' " + $"interactions={snapshot.InteractionCount}.")); } return true; } internal bool TryStartInteraction(InteractionAnimationRequest request, out InteractionAnimationHandle handle, out string reason) { handle = InteractionAnimationHandle.Empty; if (!TryResolveRequest(request, out var pack, out var interaction, out reason)) { return false; } PlayerControllerB val = ResolveLocalPlayer(); bool flag = request.Player == val; if (interaction.PresentationKind == InteractionAnimationPresentationKind.DedicatedLocalViewmodel && !flag) { reason = "dedicated_viewmodel_requires_local_player"; return false; } InteractionAnimationResourceClaim[] claims = BuildClaims(request.Player, interaction.PresentationKind, flag); if (!leases.TryPlanAcquisition(claims, request.ConflictPolicy, out var conflicts, out reason)) { return false; } if (!bodyOwnershipValidator(request.Player, interaction.PresentationKind, conflicts, out reason)) { return false; } handle = InteractionAnimationHandle.NewHandle(); InteractionAnimationRequest request2 = new InteractionAnimationRequest { Player = request.Player, PackId = pack.PackId, InteractionId = interaction.InteractionId, ConflictPolicy = request.ConflictPolicy }; InteractionAnimationContext arg = new InteractionAnimationContext(handle, request2, interaction.CreateDefinition(), interaction.Manifest, pack.AssetRootPath, logger); IInteractionPresenter arg2 = CreatePresenter(interaction.PresentationKind); InteractionAnimationSession interactionAnimationSession = sessionFactory(arg, arg2); if (!interactionAnimationSession.TryPreflight(out reason)) { handle = InteractionAnimationHandle.Empty; return false; } InteractionAnimationSession[] suspended = Array.Empty(); if (conflicts.Length != 0 && !TrySuspendConflicts(conflicts, out suspended, out reason)) { handle = InteractionAnimationHandle.Empty; return false; } if (!leases.TryAcquire(handle, claims, out reason)) { ResumeConflicts(suspended); handle = InteractionAnimationHandle.Empty; return false; } if (!interactionAnimationSession.TryStart(out reason)) { leases.Release(handle); ResumeConflicts(suspended); handle = InteractionAnimationHandle.Empty; return false; } FinalizeConflicts(suspended); activeSessions.Add(handle, interactionAnimationSession); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)("[LCInteractionAnimationAPI] interaction.started: " + $"handle={handle} pack='{pack.PackId}' interaction='{interaction.InteractionId}' " + $"presentation='{interaction.PresentationKind}'.")); } return true; } internal bool TryPreloadInteractionAssets(string packId, string interactionId, out string reason) { reason = string.Empty; if (string.IsNullOrWhiteSpace(packId) || string.IsNullOrWhiteSpace(interactionId)) { reason = "preload_invalid_identity"; return false; } if (!packs.TryGetValue(packId, out var value)) { reason = "pack_not_registered"; return false; } if (!value.TryGetInteraction(interactionId, out var interaction)) { reason = "interaction_not_registered"; return false; } if (interaction.PresentationKind == InteractionAnimationPresentationKind.BodyWorld) { return LiveBodyAnimatorPresenter.TryPreloadBundles(interaction.Manifest, value.AssetRootPath, logger, out reason); } return LocalViewmodelPresenter.TryBeginPreload(interaction.Manifest, value.AssetRootPath, logger, out reason); } internal bool TryStopInteraction(InteractionAnimationHandle handle, InteractionAnimationStopReason reason) { if (!activeSessions.TryGetValue(handle, out var value)) { return false; } if (!value.TryStopAndRestore(reason)) { return false; } leases.Release(handle); activeSessions.Remove(handle); NotifyEnded(value, reason); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)("[LCInteractionAnimationAPI] interaction.stopped: " + $"handle={handle} reason='{reason}'.")); } return true; } internal bool IsInteractionActive(InteractionAnimationHandle handle) { if (activeSessions.TryGetValue(handle, out var value)) { return value.IsActive; } return false; } internal bool TryGetActiveInteraction(PlayerControllerB player, InteractionAnimationPresentationKind presentationKind, out InteractionAnimationHandle handle) { handle = InteractionAnimationHandle.Empty; if (player == null) { return false; } foreach (KeyValuePair activeSession in activeSessions) { if (activeSession.Value.IsActive && activeSession.Value.Player == player && activeSession.Value.PresentationKind == presentationKind) { handle = activeSession.Key; return true; } } return false; } internal bool TrySetInteractionAnimatorParameter(InteractionAnimationHandle handle, string parameterName, AnimatorControllerParameterType parameterType, float value) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (activeSessions.TryGetValue(handle, out var value2)) { return value2.TrySetAnimatorParameter(parameterName, parameterType, value); } return false; } internal bool TryBeginInteractionExit(InteractionAnimationHandle handle, out string reason) { reason = string.Empty; if (!activeSessions.TryGetValue(handle, out var value) || !value.IsActive) { reason = "interaction_not_active"; return false; } float num = value.BeginExit(); ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)("[LCInteractionAnimationAPI] interaction.exit_begun: " + $"handle={handle} exitSeconds={num:0.###}.")); } return true; } internal void Tick(float deltaTime) { if (activeSessions.Count == 0) { return; } InteractionAnimationHandle[] array = activeSessions.Keys.ToArray(); for (int i = 0; i < array.Length; i++) { if (activeSessions.TryGetValue(array[i], out var value)) { InteractionAnimationStopReason? interactionAnimationStopReason = value.Tick(deltaTime); if (interactionAnimationStopReason.HasValue) { TryStopInteraction(array[i], interactionAnimationStopReason.Value); } } } } internal void Shutdown() { InteractionAnimationHandle[] array = activeSessions.Keys.ToArray(); for (int i = 0; i < array.Length; i++) { TryStopInteraction(array[i], InteractionAnimationStopReason.Shutdown); } leases.Clear(); packs.Clear(); } private bool TryResolveRequest(InteractionAnimationRequest request, out RegisteredPackSnapshot pack, out RegisteredInteractionSnapshot interaction, out string reason) { pack = null; interaction = null; reason = string.Empty; if (request == null) { reason = "request_null"; return false; } if (request.Player == null) { reason = "request_player_missing"; return false; } if (string.IsNullOrWhiteSpace(request.PackId)) { reason = "request_pack_id_empty"; return false; } if (string.IsNullOrWhiteSpace(request.InteractionId)) { reason = "request_interaction_id_empty"; return false; } if (!Enum.IsDefined(typeof(InteractionAnimationConflictPolicy), request.ConflictPolicy)) { reason = "request_conflict_policy_invalid"; return false; } if (!packs.TryGetValue(request.PackId, out pack)) { reason = "pack_not_registered"; return false; } if (!pack.TryGetInteraction(request.InteractionId, out interaction)) { reason = "interaction_not_registered"; return false; } return true; } private bool TryValidateBodyAnimatorOwnership(PlayerControllerB player, InteractionAnimationPresentationKind presentationKind, InteractionAnimationHandle[] conflicts, out string reason) { reason = string.Empty; if (presentationKind != InteractionAnimationPresentationKind.BodyWorld) { return true; } Animator val = (((Object)(object)player != (Object)null) ? player.playerBodyAnimator : null); if ((Object)(object)val == (Object)null) { reason = "missing_body_animator"; return false; } for (int i = 0; i < conflicts.Length; i++) { if (activeSessions.TryGetValue(conflicts[i], out var value) && value.Player == player && value.PresentationKind == InteractionAnimationPresentationKind.BodyWorld && value.HasResourceOwnership) { return true; } } RuntimeAnimatorController val2 = ResolveExpectedVanillaController(player); if ((Object)(object)val2 == (Object)null) { reason = "expected_player_animator_controller_missing"; return false; } if ((Object)(object)val.runtimeAnimatorController != (Object)(object)val2) { reason = "player_animator_owned_externally"; return false; } return true; } private bool TrySuspendConflicts(InteractionAnimationHandle[] handles, out InteractionAnimationSession[] suspended, out string reason) { reason = string.Empty; List list = new List(); for (int i = 0; i < handles.Length; i++) { if (!activeSessions.TryGetValue(handles[i], out var value)) { continue; } if (!value.TrySuspend(out reason)) { for (int j = 0; j < list.Count; j++) { InteractionAnimationSession interactionAnimationSession = list[j]; if (!interactionAnimationSession.TryResume(out var _)) { leases.Release(interactionAnimationSession.Handle); activeSessions.Remove(interactionAnimationSession.Handle); interactionAnimationSession.TryStopAndRestore(InteractionAnimationStopReason.PresenterFailure); NotifyEnded(interactionAnimationSession, InteractionAnimationStopReason.PresenterFailure); } } if (value.IsEnded) { leases.Release(value.Handle); activeSessions.Remove(value.Handle); NotifyEnded(value, InteractionAnimationStopReason.PresenterFailure); } suspended = Array.Empty(); return false; } list.Add(value); } suspended = list.ToArray(); for (int k = 0; k < suspended.Length; k++) { leases.Release(suspended[k].Handle); } return true; } private void ResumeConflicts(InteractionAnimationSession[] sessions) { foreach (InteractionAnimationSession interactionAnimationSession in sessions) { bool isLocal = interactionAnimationSession.Player == ResolveLocalPlayer(); InteractionAnimationResourceClaim[] claims = BuildClaims(interactionAnimationSession.Player, interactionAnimationSession.PresentationKind, isLocal); if (!leases.TryAcquire(interactionAnimationSession.Handle, claims, out var reason) || !interactionAnimationSession.TryResume(out reason)) { leases.Release(interactionAnimationSession.Handle); activeSessions.Remove(interactionAnimationSession.Handle); interactionAnimationSession.TryStopAndRestore(InteractionAnimationStopReason.PresenterFailure); NotifyEnded(interactionAnimationSession, InteractionAnimationStopReason.PresenterFailure); } } } private void FinalizeConflicts(InteractionAnimationSession[] sessions) { foreach (InteractionAnimationSession interactionAnimationSession in sessions) { activeSessions.Remove(interactionAnimationSession.Handle); if (interactionAnimationSession.TryFinalizeSuspended()) { NotifyEnded(interactionAnimationSession, InteractionAnimationStopReason.Interrupted); } } } private void NotifyEnded(InteractionAnimationSession session, InteractionAnimationStopReason reason) { LCInteractionAnimationAPI.NotifyInteractionEnded(session.CreateEndedEvent(reason)); } private static InteractionAnimationResourceClaim[] BuildClaims(PlayerControllerB player, InteractionAnimationPresentationKind presentationKind, bool isLocal) { if (presentationKind != InteractionAnimationPresentationKind.DedicatedLocalViewmodel) { if (!isLocal) { return new InteractionAnimationResourceClaim[1] { new InteractionAnimationResourceClaim(InteractionAnimationResourceKind.BodyAnimator, player) }; } return new InteractionAnimationResourceClaim[2] { new InteractionAnimationResourceClaim(InteractionAnimationResourceKind.BodyAnimator, player), new InteractionAnimationResourceClaim(InteractionAnimationResourceKind.LocalCameraAndArms, player) }; } return new InteractionAnimationResourceClaim[1] { new InteractionAnimationResourceClaim(InteractionAnimationResourceKind.LocalCameraAndArms, player) }; } private PlayerControllerB ResolveLocalPlayer() { return localPlayerResolver(); } private static PlayerControllerB ResolveDefaultLocalPlayer() { try { return GameNetworkManager.Instance?.localPlayerController ?? StartOfRound.Instance?.localPlayerController; } catch { return null; } } private RuntimeAnimatorController ResolveExpectedVanillaController(PlayerControllerB player) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || player == null) { return null; } if (player != ResolveLocalPlayer()) { return instance.otherClientsAnimatorController; } return instance.localClientAnimatorController; } private IInteractionPresenter CreatePresenter(InteractionAnimationPresentationKind presentationKind) { return presenterFactory(presentationKind); } private static IInteractionPresenter CreateDefaultPresenter(InteractionAnimationPresentationKind presentationKind) { return presentationKind switch { InteractionAnimationPresentationKind.DedicatedLocalViewmodel => new LocalViewmodelPresenter(), InteractionAnimationPresentationKind.BodyWorld => new LiveBodyAnimatorPresenter(), _ => null, }; } } internal sealed class RegisteredPackSnapshot { private readonly Dictionary interactions; internal string PackId { get; } internal string Version { get; } internal string AssetRootPath { get; } internal int InteractionCount => interactions.Count; internal RegisteredPackSnapshot(string packId, string version, string assetRootPath, Dictionary interactions) { PackId = packId; Version = version; AssetRootPath = assetRootPath; this.interactions = interactions; } internal bool TryGetInteraction(string interactionId, out RegisteredInteractionSnapshot interaction) { return interactions.TryGetValue(interactionId, out interaction); } } internal sealed class RegisteredInteractionSnapshot { internal string InteractionId { get; } internal InteractionAnimationPresentationKind PresentationKind { get; } internal string ManifestJson { get; } internal InteractionAnimationManifest Manifest { get; } internal RegisteredInteractionSnapshot(string interactionId, InteractionAnimationPresentationKind presentationKind, string manifestJson, InteractionAnimationManifest manifest) { InteractionId = interactionId; PresentationKind = presentationKind; ManifestJson = manifestJson; Manifest = manifest; } internal InteractionAnimationDefinition CreateDefinition() { return new InteractionAnimationDefinition { InteractionId = InteractionId, PresentationKind = PresentationKind, ManifestJson = ManifestJson }; } } internal static class InteractionAnimationPackValidator { internal static InteractionAnimationValidationReport Validate(InteractionAnimationPackDefinition pack, out RegisteredPackSnapshot snapshot) { snapshot = null; List issues = new List(); if (pack == null) { AddError(issues, "pack_null", "$", "Pack definition is required."); return new InteractionAnimationValidationReport(issues); } RequireValue(pack.PackId, "$.PackId", "pack_id_empty", issues); RequireValue(pack.Version, "$.Version", "pack_version_empty", issues); string normalizedRoot = string.Empty; if (!InteractionAnimationAssetPathResolver.TryNormalizeAssetRoot(pack.AssetRootPath, out normalizedRoot, out var reason)) { AddError(issues, ReasonCode(reason), "$.AssetRootPath", "AssetRootPath must name an existing directory and is required for path confinement."); } Dictionary interactions = new Dictionary(StringComparer.OrdinalIgnoreCase); if (pack.Interactions == null || pack.Interactions.Length == 0) { AddError(issues, "pack_interactions_empty", "$.Interactions", "At least one interaction is required."); } else { for (int i = 0; i < pack.Interactions.Length; i++) { ValidateInteraction(pack.Interactions[i], i, interactions, issues); } } InteractionAnimationValidationReport interactionAnimationValidationReport = new InteractionAnimationValidationReport(issues); if (interactionAnimationValidationReport.IsValid) { snapshot = new RegisteredPackSnapshot(pack.PackId, pack.Version, normalizedRoot, interactions); } return interactionAnimationValidationReport; } private static void ValidateInteraction(InteractionAnimationDefinition definition, int index, IDictionary interactions, IList issues) { string text = "$.Interactions[" + index + "]"; if (definition == null) { AddError(issues, "interaction_null", text, "Interaction is required."); return; } RequireValue(definition.InteractionId, text + ".InteractionId", "interaction_id_empty", issues); if (!Enum.IsDefined(typeof(InteractionAnimationPresentationKind), definition.PresentationKind)) { AddError(issues, "presentation_kind_invalid", text + ".PresentationKind", "Only BodyWorld and DedicatedLocalViewmodel are supported."); } InteractionAnimationManifest manifest; InteractionAnimationValidationReport interactionAnimationValidationReport = InteractionAnimationManifestValidator.Validate(definition.ManifestJson, definition.InteractionId, definition.PresentationKind, out manifest); for (int i = 0; i < interactionAnimationValidationReport.Issues.Count; i++) { InteractionAnimationValidationIssue interactionAnimationValidationIssue = interactionAnimationValidationReport.Issues[i]; issues.Add(new InteractionAnimationValidationIssue(interactionAnimationValidationIssue.Code, text + ".ManifestJson" + interactionAnimationValidationIssue.JsonPath.Substring(1), interactionAnimationValidationIssue.Message, interactionAnimationValidationIssue.Severity)); } if (!string.IsNullOrWhiteSpace(definition.InteractionId)) { if (interactions.ContainsKey(definition.InteractionId)) { AddError(issues, "interaction_id_duplicate", text + ".InteractionId", "Interaction ids must be unique within a pack."); } else if (interactionAnimationValidationReport.IsValid && manifest != null) { interactions.Add(definition.InteractionId, new RegisteredInteractionSnapshot(definition.InteractionId, definition.PresentationKind, definition.ManifestJson ?? string.Empty, manifest)); } } } private static void RequireValue(string value, string path, string code, IList issues) { if (string.IsNullOrWhiteSpace(value) || value != value.Trim()) { AddError(issues, code, path, "A trimmed non-empty value is required."); } } private static string ReasonCode(string reason) { if (string.IsNullOrWhiteSpace(reason)) { return "pack_asset_root_invalid"; } int num = reason.IndexOf(':'); if (num < 0) { return reason; } return reason.Substring(0, num); } private static void AddError(IList issues, string code, string path, string message) { issues.Add(new InteractionAnimationValidationIssue(code, path, message, InteractionAnimationValidationSeverity.Error)); } } internal enum InteractionAnimationResourceKind { BodyAnimator, LocalCameraAndArms } internal readonly struct InteractionAnimationResourceClaim : IEquatable { internal InteractionAnimationResourceKind Kind { get; } internal object Owner { get; } internal InteractionAnimationResourceClaim(InteractionAnimationResourceKind kind, object owner) { Kind = kind; Owner = owner; } public bool Equals(InteractionAnimationResourceClaim other) { if (Kind == other.Kind) { return Owner == other.Owner; } return false; } public override bool Equals(object obj) { if (obj is InteractionAnimationResourceClaim other) { return Equals(other); } return false; } public override int GetHashCode() { return ((int)Kind * 397) ^ ((Owner != null) ? RuntimeHelpers.GetHashCode(Owner) : 0); } } internal sealed class InteractionAnimationResourceLeaseRegistry { private readonly Dictionary owners = new Dictionary(); private readonly Dictionary claimsByHandle = new Dictionary(); internal bool TryPlanAcquisition(InteractionAnimationResourceClaim[] claims, InteractionAnimationConflictPolicy policy, out InteractionAnimationHandle[] conflicts, out string reason) { reason = string.Empty; HashSet hashSet = new HashSet(); claims = claims ?? Array.Empty(); for (int i = 0; i < claims.Length; i++) { if (claims[i].Owner == null) { conflicts = Array.Empty(); reason = "interaction_resource_owner_missing"; return false; } if (owners.TryGetValue(claims[i], out var value)) { hashSet.Add(value); } } conflicts = new InteractionAnimationHandle[hashSet.Count]; hashSet.CopyTo(conflicts); if (conflicts.Length != 0 && policy == InteractionAnimationConflictPolicy.RejectIfBusy) { reason = "interaction_resource_busy"; return false; } return true; } internal bool TryAcquire(InteractionAnimationHandle handle, InteractionAnimationResourceClaim[] claims, out string reason) { reason = string.Empty; if (!handle.IsValid || claimsByHandle.ContainsKey(handle)) { reason = "interaction_lease_handle_invalid"; return false; } claims = claims ?? Array.Empty(); for (int i = 0; i < claims.Length; i++) { if (claims[i].Owner == null || owners.ContainsKey(claims[i])) { reason = "interaction_resource_busy"; return false; } } InteractionAnimationResourceClaim[] array = new InteractionAnimationResourceClaim[claims.Length]; Array.Copy(claims, array, claims.Length); claimsByHandle.Add(handle, array); for (int j = 0; j < array.Length; j++) { owners.Add(array[j], handle); } return true; } internal void Release(InteractionAnimationHandle handle) { if (!claimsByHandle.TryGetValue(handle, out var value)) { return; } claimsByHandle.Remove(handle); for (int i = 0; i < value.Length; i++) { if (owners.TryGetValue(value[i], out var value2) && value2 == handle) { owners.Remove(value[i]); } } } internal bool IsOwned(InteractionAnimationResourceKind kind, object owner, out InteractionAnimationHandle handle) { return owners.TryGetValue(new InteractionAnimationResourceClaim(kind, owner), out handle); } internal void Clear() { owners.Clear(); claimsByHandle.Clear(); } } internal sealed class InteractionAnimationSession { private readonly InteractionAnimationContext context; private readonly IInteractionPresenter presenter; private readonly StartOfRound owningRound; private readonly bool wasPlayerControlled; private readonly Func utcNow; private readonly Func invalidationResolver; private DateTime startedUtc; private DateTime exitStopAtUtc = DateTime.MaxValue; private bool active; private bool suspended; private bool ended; internal InteractionAnimationHandle Handle => context.Handle; internal PlayerControllerB Player => context.Request.Player; internal string PackId => context.Request.PackId; internal string InteractionId => context.Request.InteractionId; internal InteractionAnimationPresentationKind PresentationKind => context.Definition.PresentationKind; internal bool IsActive { get { if (active) { return !ended; } return false; } } internal bool IsSuspended { get { if (suspended) { return !ended; } return false; } } internal bool IsEnded => ended; internal bool HasResourceOwnership { get { if (active) { return presenter.HasResourceOwnership; } return false; } } internal InteractionAnimationSession(InteractionAnimationContext context, IInteractionPresenter presenter, Func utcNow = null, Func invalidationResolver = null) { this.context = context; this.presenter = presenter; this.utcNow = utcNow ?? ((Func)(() => DateTime.UtcNow)); this.invalidationResolver = invalidationResolver ?? new Func(GetInvalidationReason); try { owningRound = StartOfRound.Instance; } catch { owningRound = null; } try { wasPlayerControlled = context != null && context.Request?.Player?.isPlayerControlled == true; } catch { wasPlayerControlled = false; } } internal bool TryPreflight(out string reason) { reason = string.Empty; try { if (presenter == null) { reason = "presenter_missing"; return false; } return presenter.TryPreflight(context, out reason); } catch (Exception ex) { reason = "presenter_preflight_exception:" + ex.GetType().Name; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] presenter.preflight_failed: " + ex)); } return false; } } internal bool TryStart(out string reason) { reason = string.Empty; try { if (presenter == null) { reason = "presenter_missing"; return false; } if (!presenter.TryStart(context, out reason)) { TryRestore(InteractionAnimationStopReason.PresenterFailure); return false; } startedUtc = utcNow(); exitStopAtUtc = DateTime.MaxValue; active = true; suspended = false; return true; } catch (Exception ex) { reason = "presenter_start_exception:" + ex.GetType().Name; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] presenter.start_failed: " + ex)); } TryRestore(InteractionAnimationStopReason.PresenterFailure); return false; } } internal bool TrySuspend(out string reason) { reason = string.Empty; if (!active || ended) { return false; } try { presenter.Stop(InteractionAnimationStopReason.Interrupted); active = false; suspended = true; return true; } catch (Exception ex) { active = false; suspended = false; TryRestore(InteractionAnimationStopReason.PresenterFailure); ended = true; reason = "presenter_suspend_exception:" + ex.GetType().Name; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] presenter.suspend_failed: " + ex)); } return false; } } internal bool TryResume(out string reason) { reason = string.Empty; if (!suspended || ended) { return false; } DateTime dateTime = startedUtc; DateTime dateTime2 = exitStopAtUtc; if (!TryPreflight(out reason) || !TryStart(out reason)) { return false; } startedUtc = dateTime; exitStopAtUtc = dateTime2; return true; } internal bool TryFinalizeSuspended() { if (!suspended || ended) { return false; } suspended = false; ended = true; return true; } internal bool TryStopAndRestore(InteractionAnimationStopReason reason) { if (ended) { return false; } if (active) { TryRestore(reason); } active = false; suspended = false; ended = true; return true; } internal InteractionAnimationStopReason? Tick(float deltaTime) { if (!active || ended) { return null; } InteractionAnimationStopReason? result = invalidationResolver(); if (result.HasValue) { return result; } try { presenter.Tick(deltaTime); } catch (Exception ex) { ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] presenter.tick_failed: " + ex)); } return InteractionAnimationStopReason.PresenterFailure; } if (presenter.RequestedStopReason.HasValue) { return presenter.RequestedStopReason; } DateTime dateTime = utcNow(); if (dateTime >= exitStopAtUtc) { return InteractionAnimationStopReason.NaturalEnd; } float durationSeconds = context.Manifest.durationSeconds; if (durationSeconds > 0f && (dateTime - startedUtc).TotalSeconds >= (double)durationSeconds) { return InteractionAnimationStopReason.NaturalEnd; } return null; } internal float BeginExit() { if (!active || presenter == null) { return 0f; } float num = Math.Max(0f, presenter.BeginExit()); exitStopAtUtc = utcNow().AddSeconds(num); return num; } internal bool TrySetAnimatorParameter(string parameterName, AnimatorControllerParameterType parameterType, float value) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (active && presenter != null) { return presenter.TrySetAnimatorParameter(parameterName, parameterType, value); } return false; } internal InteractionAnimationEndedEventArgs CreateEndedEvent(InteractionAnimationStopReason reason) { return new InteractionAnimationEndedEventArgs(Handle, Player, PackId, InteractionId, PresentationKind, reason); } private InteractionAnimationStopReason? GetInvalidationReason() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB player = Player; try { if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).gameObject == (Object)null) { goto IL_0033; } Scene scene = ((Component)player).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { goto IL_0033; } if (player.isPlayerDead) { return InteractionAnimationStopReason.PlayerDied; } if (wasPlayerControlled && !player.isPlayerControlled) { return InteractionAnimationStopReason.PlayerInvalidated; } if ((Object)(object)owningRound != (Object)null && (Object)(object)StartOfRound.Instance != (Object)(object)owningRound) { return InteractionAnimationStopReason.RoundUnloaded; } goto end_IL_0007; IL_0033: return InteractionAnimationStopReason.PlayerInvalidated; end_IL_0007:; } catch { return InteractionAnimationStopReason.PlayerInvalidated; } return null; } private void TryRestore(InteractionAnimationStopReason reason) { try { presenter?.Stop(reason); } catch (Exception ex) { ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] presenter.restore_failed: " + ex)); } } } } public enum InteractionAnimationPresentationKind { DedicatedLocalViewmodel, BodyWorld } public enum InteractionAnimationConflictPolicy { RejectIfBusy, InterruptExisting } public enum InteractionAnimationStopReason { Requested, NaturalEnd, Interrupted, PlayerInvalidated, PlayerDied, RoundUnloaded, PresenterFailure, Shutdown } public readonly struct InteractionAnimationHandle : IEquatable { private readonly Guid value; public static InteractionAnimationHandle Empty => new InteractionAnimationHandle(Guid.Empty); public bool IsValid => value != Guid.Empty; private InteractionAnimationHandle(Guid value) { this.value = value; } internal static InteractionAnimationHandle NewHandle() { return new InteractionAnimationHandle(Guid.NewGuid()); } public bool Equals(InteractionAnimationHandle other) { Guid guid = value; return guid.Equals(other.value); } public override bool Equals(object obj) { if (obj is InteractionAnimationHandle other) { return Equals(other); } return false; } public override int GetHashCode() { return value.GetHashCode(); } public override string ToString() { return value.ToString(); } public static bool operator ==(InteractionAnimationHandle left, InteractionAnimationHandle right) { return left.Equals(right); } public static bool operator !=(InteractionAnimationHandle left, InteractionAnimationHandle right) { return !left.Equals(right); } } public sealed class InteractionAnimationPackDefinition { public string PackId { get; set; } = string.Empty; public string Version { get; set; } = string.Empty; public string AssetRootPath { get; set; } = string.Empty; public InteractionAnimationDefinition[] Interactions { get; set; } = Array.Empty(); } public sealed class InteractionAnimationDefinition { public string InteractionId { get; set; } = string.Empty; public InteractionAnimationPresentationKind PresentationKind { get; set; } public string ManifestJson { get; set; } = string.Empty; } public sealed class InteractionAnimationRequest { public PlayerControllerB Player { get; set; } public string PackId { get; set; } = string.Empty; public string InteractionId { get; set; } = string.Empty; public InteractionAnimationConflictPolicy ConflictPolicy { get; set; } } public enum InteractionAnimationValidationSeverity { Warning, Error } public sealed class InteractionAnimationValidationIssue { public string Code { get; } public string JsonPath { get; } public string Message { get; } public InteractionAnimationValidationSeverity Severity { get; } internal InteractionAnimationValidationIssue(string code, string jsonPath, string message, InteractionAnimationValidationSeverity severity) { Code = code ?? string.Empty; JsonPath = jsonPath ?? "$"; Message = message ?? string.Empty; Severity = severity; } } public sealed class InteractionAnimationValidationReport { private readonly ReadOnlyCollection issues; public bool IsValid { get { for (int i = 0; i < issues.Count; i++) { if (issues[i].Severity == InteractionAnimationValidationSeverity.Error) { return false; } } return true; } } public IReadOnlyList Issues => issues; internal InteractionAnimationValidationReport(IList issues) { this.issues = new ReadOnlyCollection(new List(issues ?? Array.Empty())); } } public sealed class InteractionAnimationEndedEventArgs : EventArgs { public InteractionAnimationHandle Handle { get; } public PlayerControllerB Player { get; } public string PackId { get; } public string InteractionId { get; } public InteractionAnimationPresentationKind PresentationKind { get; } public InteractionAnimationStopReason StopReason { get; } internal InteractionAnimationEndedEventArgs(InteractionAnimationHandle handle, PlayerControllerB player, string packId, string interactionId, InteractionAnimationPresentationKind presentationKind, InteractionAnimationStopReason stopReason) { Handle = handle; Player = player; PackId = packId ?? string.Empty; InteractionId = interactionId ?? string.Empty; PresentationKind = presentationKind; StopReason = stopReason; } } internal sealed class InteractionAnimationContext { internal InteractionAnimationHandle Handle { get; } internal InteractionAnimationRequest Request { get; } internal InteractionAnimationDefinition Definition { get; } internal InteractionAnimationManifest Manifest { get; } internal string AssetRootPath { get; } internal ManualLogSource Logger { get; } internal InteractionAnimationContext(InteractionAnimationHandle handle, InteractionAnimationRequest request, InteractionAnimationDefinition definition, InteractionAnimationManifest manifest, string assetRootPath, ManualLogSource logger) { Handle = handle; Request = request; Definition = definition; Manifest = manifest; AssetRootPath = assetRootPath ?? string.Empty; Logger = logger; } } public static class LCInteractionAnimationAPI { private static InteractionAnimationCoordinator coordinator; public static bool IsInitialized => coordinator != null; public static event EventHandler InteractionEnded; public static InteractionAnimationValidationReport ValidateInteractionPack(InteractionAnimationPackDefinition pack) { RegisteredPackSnapshot snapshot; return InteractionAnimationPackValidator.Validate(pack, out snapshot); } public static InteractionAnimationValidationReport ValidateInteractionManifest(string manifestJson, string expectedInteractionId, InteractionAnimationPresentationKind presentationKind) { InteractionAnimationManifest manifest; return InteractionAnimationManifestValidator.Validate(manifestJson, expectedInteractionId, presentationKind, out manifest); } public static bool TryRegisterInteractionPack(InteractionAnimationPackDefinition pack, out string reason) { if (coordinator == null) { reason = "interaction_animation_api_not_initialized"; return false; } return coordinator.TryRegisterInteractionPack(pack, out reason); } public static bool TryStartInteraction(InteractionAnimationRequest request, out InteractionAnimationHandle handle, out string reason) { handle = InteractionAnimationHandle.Empty; if (coordinator == null) { reason = "interaction_animation_api_not_initialized"; return false; } return coordinator.TryStartInteraction(request, out handle, out reason); } public static bool TryPreloadInteractionAssets(string packId, string interactionId, out string reason) { if (coordinator == null) { reason = "interaction_animation_api_not_initialized"; return false; } return coordinator.TryPreloadInteractionAssets(packId, interactionId, out reason); } public static bool TryStopInteraction(InteractionAnimationHandle handle, InteractionAnimationStopReason stopReason) { if (coordinator != null) { return coordinator.TryStopInteraction(handle, stopReason); } return false; } public static bool IsInteractionActive(InteractionAnimationHandle handle) { if (coordinator != null) { return coordinator.IsInteractionActive(handle); } return false; } public static bool TryGetActiveInteraction(PlayerControllerB player, InteractionAnimationPresentationKind presentationKind, out InteractionAnimationHandle handle) { handle = InteractionAnimationHandle.Empty; if (coordinator != null) { return coordinator.TryGetActiveInteraction(player, presentationKind, out handle); } return false; } public static bool TrySetInteractionBool(InteractionAnimationHandle handle, string parameterName, bool value) { if (coordinator != null) { return coordinator.TrySetInteractionAnimatorParameter(handle, parameterName, (AnimatorControllerParameterType)4, value ? 1f : 0f); } return false; } public static bool TrySetInteractionInt(InteractionAnimationHandle handle, string parameterName, int value) { if (coordinator != null) { return coordinator.TrySetInteractionAnimatorParameter(handle, parameterName, (AnimatorControllerParameterType)3, value); } return false; } public static bool TrySetInteractionFloat(InteractionAnimationHandle handle, string parameterName, float value) { if (coordinator != null) { return coordinator.TrySetInteractionAnimatorParameter(handle, parameterName, (AnimatorControllerParameterType)1, value); } return false; } public static bool TryFireInteractionTrigger(InteractionAnimationHandle handle, string parameterName) { if (coordinator != null) { return coordinator.TrySetInteractionAnimatorParameter(handle, parameterName, (AnimatorControllerParameterType)9, 0f); } return false; } public static bool TryBeginInteractionExit(InteractionAnimationHandle handle, out string reason) { reason = string.Empty; if (coordinator == null) { reason = "interaction_animation_api_not_initialized"; return false; } return coordinator.TryBeginInteractionExit(handle, out reason); } internal static void Initialize(InteractionAnimationCoordinator value) { coordinator = value; } internal static void NotifyInteractionEnded(InteractionAnimationEndedEventArgs args) { Delegate[] array = LCInteractionAnimationAPI.InteractionEnded?.GetInvocationList(); if (array == null) { return; } for (int i = 0; i < array.Length; i++) { try { ((EventHandler)array[i])(null, args); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[LCInteractionAnimationAPI] interaction_ended_handler_failed: " + ex)); } } } } internal static void Shutdown() { coordinator = null; } } [HarmonyPatch(typeof(PlayerControllerB), "UpdatePlayerAnimationsToOtherClients")] internal static class PlayerAnimationSyncStateGuardPatch { [HarmonyPrefix] private static void EnsureAnimationStateHashCounts(PlayerControllerB __instance, ref List ___currentAnimationStateHash, ref List ___previousAnimationStateHash) { int? obj; if (__instance == null) { obj = null; } else { Animator playerBodyAnimator = __instance.playerBodyAnimator; obj = ((playerBodyAnimator != null) ? new int?(playerBodyAnimator.layerCount) : ((int?)null)); } int? num = obj; int valueOrDefault = num.GetValueOrDefault(); bool num2 = EnsureCount(ref ___currentAnimationStateHash, valueOrDefault); bool flag = EnsureCount(ref ___previousAnimationStateHash, valueOrDefault); if (num2 || flag) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[LCInteractionAnimationAPI] live_body.sync_state_capacity_expanded: " + $"player={__instance.playerClientId}, layers={valueOrDefault}.")); } } } internal static bool EnsureCount(ref List states, int requiredCount) { if (requiredCount > 0) { List obj = states; if (obj == null || obj.Count < requiredCount) { if (states == null) { states = new List(requiredCount); } while (states.Count < requiredCount) { states.Add(0); } return true; } } return false; } } internal static class InteractionAnimationApiRestoreDiagnostics { internal sealed class CameraChainPoseSnapshot { private readonly Transform[] transforms; private readonly Vector3[] localPositions; private readonly string[] names; internal int Count => transforms.Length; internal string MissingTargets { get; } internal string Source { get; private set; } = "player_awake_prefix_authored_default"; private CameraChainPoseSnapshot(Transform[] transforms, Vector3[] localPositions, string[] names, string missingTargets) { this.transforms = transforms; this.localPositions = localPositions; this.names = names; MissingTargets = missingTargets; } internal bool RefinePositions(string newSource) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) bool flag = false; for (int i = 0; i < transforms.Length; i++) { Transform val = transforms[i]; if (!((Object)(object)val == (Object)null)) { localPositions[i] = val.localPosition; flag = true; } } if (flag) { Source = newSource; } return flag; } internal static CameraChainPoseSnapshot Capture(PlayerControllerB player) { List list = new List(4); List list2 = new List(4); List list3 = new List(4); List list4 = new List(4); CaptureTarget("cameraContainer", SafeGet(() => player.cameraContainerTransform), list, list2, list3, list4); CaptureTarget("gameplayCamera", SafeGet(() => (!((Object)(object)player.gameplayCamera != (Object)null)) ? null : ((Component)player.gameplayCamera).transform), list, list2, list3, list4); CaptureTarget("playerModelArmsMetarig", SafeGet(() => player.playerModelArmsMetarig), list, list2, list3, list4); CaptureTarget("localArmsTransform", SafeGet(() => player.localArmsTransform), list, list2, list3, list4); return new CameraChainPoseSnapshot(list.ToArray(), list2.ToArray(), list3.ToArray(), string.Join(",", list4.ToArray())); } private static Transform SafeGet(Func getter) { try { return getter(); } catch { return null; } } private static void CaptureTarget(string name, Transform target, List capturedTransforms, List capturedPositions, List capturedNames, List missing) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { missing.Add(name); return; } capturedTransforms.Add(target); capturedPositions.Add(target.localPosition); capturedNames.Add(name); } internal int RestorePositions() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) int num = 0; for (int i = 0; i < transforms.Length; i++) { Transform val = transforms[i]; if (!((Object)(object)val == (Object)null)) { val.localPosition = localPositions[i]; num++; } } return num; } internal string DescribePositions() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) List list = new List(names.Length); for (int i = 0; i < names.Length; i++) { list.Add(names[i] + "Local=" + FormatVector(localPositions[i])); } return string.Join(" ", list.ToArray()); } } private sealed class RestoreFrameSample { internal readonly int[] LayerStateHashes; internal readonly float[] LayerNormalizedTimes; internal bool Valid; internal int Frame; internal Vector3 GameplayCameraWorldPosition; internal Vector3 CameraContainerLocalPosition; internal Vector3 CameraContainerWorldPosition; internal Vector3 ArmsMetarigWorldPosition; internal string ControllerName; internal int ActualLayerCount; internal int CapturedLayerCount; internal RestoreFrameSample(int maxAnimatorLayers) { LayerStateHashes = new int[maxAnimatorLayers]; LayerNormalizedTimes = new float[maxAnimatorLayers]; ControllerName = ""; } } private sealed class RenderSeamFrameSample { internal bool Valid; internal PlayerControllerB Player; internal int Frame; internal float DeltaTime; internal float UnscaledDeltaTime; internal RenderPoseSample GameplayCamera; internal RenderPoseSample RightHand; internal RenderPoseSample LeftHand; internal RenderPoseSample ArmsMetarig; internal RenderPoseSample LocalArms; internal RenderPoseSample LocalVisor; internal RenderPoseSample LocalVisorTargetPoint; internal RenderVisibilitySample LocalVisorVisibility; internal bool VisorCameraPresent; internal bool VisorCameraEnabled; internal bool CameraParametersPresent; internal float CameraFieldOfView; internal float CameraNearClipPlane; internal RenderVisibilitySample HeldItem; internal void CopyFrom(RenderSeamFrameSample other) { if (other == null) { Reset(); return; } Valid = other.Valid; Player = other.Player; Frame = other.Frame; DeltaTime = other.DeltaTime; UnscaledDeltaTime = other.UnscaledDeltaTime; GameplayCamera = other.GameplayCamera; RightHand = other.RightHand; LeftHand = other.LeftHand; ArmsMetarig = other.ArmsMetarig; LocalArms = other.LocalArms; LocalVisor = other.LocalVisor; LocalVisorTargetPoint = other.LocalVisorTargetPoint; LocalVisorVisibility = other.LocalVisorVisibility; VisorCameraPresent = other.VisorCameraPresent; VisorCameraEnabled = other.VisorCameraEnabled; CameraParametersPresent = other.CameraParametersPresent; CameraFieldOfView = other.CameraFieldOfView; CameraNearClipPlane = other.CameraNearClipPlane; HeldItem = other.HeldItem; } internal void Reset() { Valid = false; Player = null; Frame = 0; DeltaTime = 0f; UnscaledDeltaTime = 0f; GameplayCamera = default(RenderPoseSample); RightHand = default(RenderPoseSample); LeftHand = default(RenderPoseSample); ArmsMetarig = default(RenderPoseSample); LocalArms = default(RenderPoseSample); LocalVisor = default(RenderPoseSample); LocalVisorTargetPoint = default(RenderPoseSample); LocalVisorVisibility = default(RenderVisibilitySample); VisorCameraPresent = false; VisorCameraEnabled = false; CameraParametersPresent = false; CameraFieldOfView = 0f; CameraNearClipPlane = 0f; HeldItem = default(RenderVisibilitySample); } } private sealed class RenderSeamWindow { internal readonly string Phase; internal bool Active; internal int SeamFrame; internal int EndFrame; internal int LastLoggedFrame; internal GameObject AnimatedProp; internal RenderSeamWindow(string phase) { Phase = phase; Reset(); } internal void Activate(int seamFrame, int endFrame, GameObject animatedProp) { Active = true; SeamFrame = seamFrame; EndFrame = endFrame; LastLoggedFrame = -1; AnimatedProp = animatedProp; } internal void Reset() { Active = false; SeamFrame = 0; EndFrame = 0; LastLoggedFrame = -1; AnimatedProp = null; } } private struct RenderPoseSample { internal bool Present; internal Vector3 WorldPosition; internal Vector3 WorldEulerAngles; } private struct RenderVisibilitySample { internal bool Present; internal string Name; internal bool ActiveInHierarchy; internal int RendererCount; internal int EnabledRendererCount; internal bool AnyRendererEnabled; internal bool ReadFailed; } internal sealed class ThirdPersonRigPoseSnapshot { private readonly ThirdPersonRigPoseBaseline[] baselines; internal int FullPoseCount { get; } internal int RotationOnlyCount { get; } internal int TotalCount => baselines.Length; internal bool IsComplete { get; } internal string MissingTargets { get; } internal bool PlausibleAtCapture { get; private set; } internal string Source { get; private set; } = "player_awake_prefix_authored_default"; internal void SetCaptureMetadata(bool plausibleAtCapture, string source) { PlausibleAtCapture = plausibleAtCapture; Source = source; } private ThirdPersonRigPoseSnapshot(ThirdPersonRigPoseBaseline[] baselines, int fullPoseCount, int rotationOnlyCount, string[] missingTargets) { this.baselines = baselines ?? Array.Empty(); FullPoseCount = fullPoseCount; RotationOnlyCount = rotationOnlyCount; IsComplete = missingTargets == null || missingTargets.Length == 0; MissingTargets = (IsComplete ? "" : string.Join(",", missingTargets)); } internal static ThirdPersonRigPoseSnapshot Capture(PlayerControllerB player) { Transform val = null; try { val = (((Object)(object)player != (Object)null && (Object)(object)player.playerBodyAnimator != (Object)null) ? ((Component)player.playerBodyAnimator).transform : null); } catch { } if ((Object)(object)val == (Object)null) { return null; } Transform parent = FindChildRecursive(val, "spine.003"); Transform parent2 = FindChildRecursive(val, "Rig 1"); Transform val2 = FindDirectChild(parent2, "LeftLeg"); Transform val3 = FindDirectChild(parent2, "RightLeg"); List list = new List(12); HashSet capturedTransforms = new HashSet(); List list2 = new List(10); AddFullPose(FindDirectChild(parent, "LeftArm_target"), "spine.003/LeftArm_target", list, capturedTransforms, list2); AddFullPose(FindDirectChild(parent, "RightArm_target"), "spine.003/RightArm_target", list, capturedTransforms, list2); AddControlGroup(val2, "Rig 1/LeftLeg", new string[2] { "LeftLeg_hint", "LeftLeg_target" }, list, capturedTransforms, list2); AddControlGroup(val3, "Rig 1/RightLeg", new string[2] { "RightLeg_hint", "RightLeg_target" }, list, capturedTransforms, list2); AddRotationOnly(FindChildRecursive(val, "shin.L"), "spine/thigh.L/shin.L", list, capturedTransforms, list2); AddRotationOnly(FindChildRecursive(val, "shin.R"), "spine/thigh.R/shin.R", list, capturedTransforms, list2); int num = 0; int num2 = 0; for (int i = 0; i < list.Count; i++) { if (list[i].RotationOnly) { num2++; } else { num++; } } return new ThirdPersonRigPoseSnapshot(list.ToArray(), num, num2, list2.ToArray()); } private static void AddControlGroup(Transform group, string groupPath, string[] requiredChildren, ICollection captured, ISet capturedTransforms, ICollection missing) { if ((Object)(object)group == (Object)null) { missing.Add(groupPath); for (int i = 0; i < requiredChildren.Length; i++) { missing.Add(groupPath + "/" + requiredChildren[i]); } return; } Transform[] componentsInChildren = ((Component)group).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { string relativePath = GetRelativePath(group, val); string path = ((group == val) ? groupPath : (groupPath + relativePath.Substring(((Object)group).name.Length))); AddFullPose(val, path, captured, capturedTransforms, null); } foreach (string text in requiredChildren) { if ((Object)(object)FindDirectChild(group, text) == (Object)null) { missing.Add(groupPath + "/" + text); } } } private static void AddFullPose(Transform transform, string path, ICollection captured, ISet capturedTransforms, ICollection missing) { if ((Object)(object)transform == (Object)null) { missing?.Add(path); } else if (capturedTransforms.Add(transform)) { captured.Add(new ThirdPersonRigPoseBaseline(transform, path, rotationOnly: false)); } } private static void AddRotationOnly(Transform transform, string path, ICollection captured, ISet capturedTransforms, ICollection missing) { if ((Object)(object)transform == (Object)null) { missing.Add(path); } else if (capturedTransforms.Add(transform)) { captured.Add(new ThirdPersonRigPoseBaseline(transform, path, rotationOnly: true)); } } internal ThirdPersonRigPlausibility EvaluateVanillaRestPlausibility() { //IL_004f: 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_0085: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; int num3 = 0; float num4 = 0f; float num5 = 0f; float num6 = 0f; bool flag = false; for (int i = 0; i < baselines.Length; i++) { ThirdPersonRigPoseBaseline thirdPersonRigPoseBaseline = baselines[i]; if (!thirdPersonRigPoseBaseline.HasExpectedVanillaRest) { continue; } if (!thirdPersonRigPoseBaseline.Finite) { flag = true; continue; } float num7 = Quaternion.Angle(thirdPersonRigPoseBaseline.ExpectedLocalRotation, thirdPersonRigPoseBaseline.LocalRotation); num5 = Mathf.Max(num5, num7); if (num7 > 8f) { num2++; } if (!thirdPersonRigPoseBaseline.RotationOnly) { float num8 = Vector3.Distance(thirdPersonRigPoseBaseline.ExpectedLocalPosition, thirdPersonRigPoseBaseline.LocalPosition); float num9 = Vector3.Distance(thirdPersonRigPoseBaseline.ExpectedLocalScale, thirdPersonRigPoseBaseline.LocalScale); num4 = Mathf.Max(num4, num8); num6 = Mathf.Max(num6, num9); if (num8 > 0.05f) { num++; } if (num9 > 0.01f) { num3++; } } } bool flag2 = IsComplete && !flag && num == 0 && num2 == 0 && num3 == 0; string reason = ((!IsComplete) ? "required_transforms_missing" : (flag ? "non_finite_local_pose" : (flag2 ? "within_vanilla_rest_thresholds" : "outside_vanilla_rest_thresholds"))); return new ThirdPersonRigPlausibility(flag2, reason, num, num2, num3, num4, num5, num6); } internal void RestoreExcept(ISet excludedTransforms, ISet restoredTransforms, out int fullPoseRestored, out int rotationOnlyRestored) { fullPoseRestored = 0; rotationOnlyRestored = 0; for (int i = 0; i < baselines.Length; i++) { ThirdPersonRigPoseBaseline thirdPersonRigPoseBaseline = baselines[i]; Transform transform = thirdPersonRigPoseBaseline.Transform; if (!((Object)(object)transform == (Object)null) && (excludedTransforms == null || !excludedTransforms.Contains(transform)) && thirdPersonRigPoseBaseline.Restore()) { restoredTransforms?.Add(transform); if (thirdPersonRigPoseBaseline.RotationOnly) { rotationOnlyRestored++; } else { fullPoseRestored++; } } } } } private sealed class ThirdPersonRigPoseBaseline { internal Transform Transform { get; } internal string Path { get; } internal bool RotationOnly { get; } internal Vector3 LocalPosition { get; } internal Quaternion LocalRotation { get; } internal Vector3 LocalScale { get; } internal bool HasExpectedVanillaRest { get; } internal Vector3 ExpectedLocalPosition { get; } internal Quaternion ExpectedLocalRotation { get; } internal Vector3 ExpectedLocalScale { get; } internal bool Finite { get { //IL_0001: 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_001b: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(LocalPosition) && IsFinite(LocalRotation)) { return IsFinite(LocalScale); } return false; } } internal ThirdPersonRigPoseBaseline(Transform transform, string path, bool rotationOnly) { //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_0029: 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_0035: 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_0052: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Transform = transform; Path = path; RotationOnly = rotationOnly; LocalPosition = transform.localPosition; LocalRotation = transform.localRotation; LocalScale = transform.localScale; HasExpectedVanillaRest = TryGetExpectedVanillaRest(path, out var localPosition, out var localRotation, out var localScale); ExpectedLocalPosition = localPosition; ExpectedLocalRotation = localRotation; ExpectedLocalScale = localScale; } internal bool Restore() { //IL_0041: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Transform == (Object)null) { return false; } if (!RotationOnly) { Transform.localPosition = LocalPosition; Transform.localScale = LocalScale; } Transform.localRotation = LocalRotation; return true; } private static bool TryGetExpectedVanillaRest(string path, out Vector3 localPosition, out Quaternion localRotation, out Vector3 localScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) localPosition = Vector3.zero; localRotation = Quaternion.identity; localScale = Vector3.one; switch (path) { case "spine.003/LeftArm_target": localPosition = new Vector3(-1.045884f, -0.057756394f, -0.044099636f); localRotation = new Quaternion(-0.78043324f, 0.6235791f, 0.028422598f, 0.03557171f); return true; case "spine.003/RightArm_target": localPosition = new Vector3(1.0641153f, -0.06609607f, -0.030803302f); localRotation = new Quaternion(-0.7733263f, -0.6323711f, -0.028823216f, 0.0352481f); return true; case "Rig 1/LeftLeg": case "Rig 1/RightLeg": localPosition = new Vector3(-9.584f, 0f, -11.081f); return true; case "Rig 1/LeftLeg/LeftLeg_hint": localPosition = new Vector3(1.001f, 0.746f, 2.4f); return true; case "Rig 1/LeftLeg/LeftLeg_target": localPosition = new Vector3(0.99f, 0.209f, 1.011f); localRotation = new Quaternion(0.89385676f, -1.803443E-06f, -1.1043475E-06f, 0.4483527f); return true; case "Rig 1/RightLeg/RightLeg_hint": localPosition = new Vector3(1.486f, 0.658f, 2.823f); return true; case "Rig 1/RightLeg/RightLeg_target": localPosition = new Vector3(1.436f, 0.27f, 1.058f); localRotation = new Quaternion(0.89385664f, 3.9951823E-07f, -6.130153E-08f, 0.44835275f); return true; case "spine/thigh.L/shin.L": localRotation = new Quaternion(0.036354546f, -0.0022051183f, -0.008516384f, 0.99930024f); return true; case "spine/thigh.R/shin.R": localRotation = new Quaternion(0.036352716f, 0.002243982f, 0.008508066f, 0.9993003f); return true; default: return false; } } private static bool IsFinite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(value.x) && IsFinite(value.y)) { return IsFinite(value.z); } return false; } private static bool IsFinite(Quaternion value) { //IL_0000: 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_001a: 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) if (IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z)) { return IsFinite(value.w); } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } internal readonly struct ThirdPersonRigPlausibility { internal bool Plausible { get; } internal string Reason { get; } internal int PositionOutliers { get; } internal int RotationOutliers { get; } internal int ScaleOutliers { get; } internal float MaxPositionDelta { get; } internal float MaxRotationDeltaDegrees { get; } internal float MaxScaleDelta { get; } internal ThirdPersonRigPlausibility(bool plausible, string reason, int positionOutliers, int rotationOutliers, int scaleOutliers, float maxPositionDelta, float maxRotationDeltaDegrees, float maxScaleDelta) { Plausible = plausible; Reason = reason; PositionOutliers = positionOutliers; RotationOutliers = rotationOutliers; ScaleOutliers = scaleOutliers; MaxPositionDelta = maxPositionDelta; MaxRotationDeltaDegrees = maxRotationDeltaDegrees; MaxScaleDelta = maxScaleDelta; } } private sealed class RemoteRigProbeSchedule { internal PlayerControllerB Player { get; } internal int ProbeId { get; } internal int RestoreFrame { get; } internal float FiveSecondRealtime { get; } internal int LateUpdatesRemaining { get; set; } internal bool LateUpdateSampleLogged { get; set; } internal bool FiveSecondSampleLogged { get; set; } internal RemoteRigProbeSchedule(PlayerControllerB player, int probeId, int restoreFrame, float fiveSecondRealtime) { Player = player; ProbeId = probeId; RestoreFrame = restoreFrame; FiveSecondRealtime = fiveSecondRealtime; LateUpdatesRemaining = 2; } } private sealed class PristineRigSnapshot { internal readonly PlayerControllerB Player; internal readonly TransformBaseline[] Transforms; internal readonly TwoBoneIkBaseline[] TwoBoneConstraints; internal readonly ChainIkBaseline[] ChainConstraints; internal readonly RigWeightBaseline[] Rigs; internal readonly RigLayerBaseline[] RigLayers; private PristineRigSnapshot(PlayerControllerB player, TransformBaseline[] transforms, TwoBoneIkBaseline[] twoBoneConstraints, ChainIkBaseline[] chainConstraints, RigWeightBaseline[] rigs, RigLayerBaseline[] rigLayers) { Player = player; Transforms = transforms; TwoBoneConstraints = twoBoneConstraints; ChainConstraints = chainConstraints; Rigs = rigs; RigLayers = rigLayers; } internal static PristineRigSnapshot Capture(PlayerControllerB player, Transform metarig, Transform rigArms, Type twoBoneIkConstraintType, Type chainIkConstraintType) { Transform[] componentsInChildren = ((Component)rigArms).GetComponentsInChildren(true); TransformBaseline[] array = new TransformBaseline[componentsInChildren.Length + 1]; array[0] = new TransformBaseline(metarig, ((Object)metarig).name + " (metarig root)"); for (int i = 0; i < componentsInChildren.Length; i++) { Transform transform = componentsInChildren[i]; array[i + 1] = new TransformBaseline(transform, GetRelativePath(metarig, transform)); } Component[] componentsInChildren2 = ((Component)metarig).GetComponentsInChildren(true); List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); foreach (Component val in componentsInChildren2) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); string? a = type.FullName ?? type.Name; string relativePath = GetRelativePath(metarig, val.transform); if (twoBoneIkConstraintType != null && twoBoneIkConstraintType.IsAssignableFrom(type)) { list.Add(new TwoBoneIkBaseline(val, relativePath)); } if (chainIkConstraintType != null && chainIkConstraintType.IsAssignableFrom(type)) { list2.Add(new ChainIkBaseline(val, relativePath)); } if (string.Equals(a, "UnityEngine.Animations.Rigging.Rig", StringComparison.Ordinal)) { list3.Add(new RigWeightBaseline(val, relativePath)); } if (!string.Equals(a, "UnityEngine.Animations.Rigging.RigBuilder", StringComparison.Ordinal) || !(ReadMember(val, "layers", "m_RigLayers") is IList list5)) { continue; } for (int k = 0; k < list5.Count; k++) { object obj = list5[k]; if (obj != null) { list4.Add(new RigLayerBaseline(obj, relativePath + "/layer[" + k.ToString(CultureInfo.InvariantCulture) + "]")); } } } return new PristineRigSnapshot(player, array, list.ToArray(), list2.ToArray(), list3.ToArray(), list4.ToArray()); } internal int RestoreRigControlPose(Transform rigArms, ISet restoredTransforms) { int num = 0; for (int i = 0; i < Transforms.Length; i++) { TransformBaseline transformBaseline = Transforms[i]; Transform transform = transformBaseline.Transform; if (!((Object)(object)transform == (Object)null) && (transform == rigArms || transform.IsChildOf(rigArms))) { transformBaseline.Restore(); restoredTransforms.Add(transform); num++; } } return num; } } private sealed class TransformBaseline { internal readonly Transform Transform; internal readonly string Path; internal readonly Vector3 LocalPosition; internal readonly Quaternion LocalRotation; internal readonly Vector3 LocalScale; internal TransformBaseline(Transform transform, string path) { //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_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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Transform = transform; Path = path; LocalPosition = transform.localPosition; LocalRotation = transform.localRotation; LocalScale = transform.localScale; } internal void Restore() { //IL_0007: 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_0029: Unknown result type (might be due to invalid IL or missing references) Transform.localPosition = LocalPosition; Transform.localRotation = LocalRotation; Transform.localScale = LocalScale; } } private readonly struct TwoBoneIkValues : IEquatable { internal readonly string TargetName; internal readonly string HintName; internal readonly float Weight; internal readonly float TargetPositionWeight; internal readonly float TargetRotationWeight; internal readonly float HintWeight; internal readonly bool MaintainTargetPositionOffset; internal readonly bool MaintainTargetRotationOffset; internal TwoBoneIkValues(Component component) { object instance = ReadMember(component, null, "m_Data"); TargetName = ReadObjectName(instance, "target", "m_Target"); HintName = ReadObjectName(instance, "hint", "m_Hint"); Weight = ReadFloat(component, "weight", "m_Weight"); TargetPositionWeight = ReadFloat(instance, "targetPositionWeight", "m_TargetPositionWeight"); TargetRotationWeight = ReadFloat(instance, "targetRotationWeight", "m_TargetRotationWeight"); HintWeight = ReadFloat(instance, "hintWeight", "m_HintWeight"); MaintainTargetPositionOffset = ReadBool(instance, "maintainTargetPositionOffset", "m_MaintainTargetPositionOffset"); MaintainTargetRotationOffset = ReadBool(instance, "maintainTargetRotationOffset", "m_MaintainTargetRotationOffset"); } public bool Equals(TwoBoneIkValues other) { if (string.Equals(TargetName, other.TargetName, StringComparison.Ordinal) && string.Equals(HintName, other.HintName, StringComparison.Ordinal) && Weight.Equals(other.Weight) && TargetPositionWeight.Equals(other.TargetPositionWeight) && TargetRotationWeight.Equals(other.TargetRotationWeight) && HintWeight.Equals(other.HintWeight) && MaintainTargetPositionOffset == other.MaintainTargetPositionOffset) { return MaintainTargetRotationOffset == other.MaintainTargetRotationOffset; } return false; } } private sealed class TwoBoneIkBaseline { private readonly Component component; internal readonly string Path; internal readonly TwoBoneIkValues Values; internal TwoBoneIkBaseline(Component component, string path) { this.component = component; Path = path; Values = new TwoBoneIkValues(component); } internal bool TryReadCurrent(out TwoBoneIkValues current) { if ((Object)(object)component == (Object)null) { current = default(TwoBoneIkValues); return false; } current = new TwoBoneIkValues(component); return true; } } private readonly struct ChainIkValues : IEquatable { internal readonly string RootName; internal readonly string TipName; internal readonly string TargetName; internal readonly float Weight; internal readonly float ChainRotationWeight; internal readonly float TipRotationWeight; internal readonly int MaxIterations; internal readonly float Tolerance; internal readonly bool MaintainTargetPositionOffset; internal readonly bool MaintainTargetRotationOffset; internal ChainIkValues(Component component) { object instance = ReadMember(component, null, "m_Data"); RootName = ReadObjectName(instance, "root", "m_Root"); TipName = ReadObjectName(instance, "tip", "m_Tip"); TargetName = ReadObjectName(instance, "target", "m_Target"); Weight = ReadFloat(component, "weight", "m_Weight"); ChainRotationWeight = ReadFloat(instance, "chainRotationWeight", "m_ChainRotationWeight"); TipRotationWeight = ReadFloat(instance, "tipRotationWeight", "m_TipRotationWeight"); MaxIterations = ReadInt(instance, "maxIterations", "m_MaxIterations"); Tolerance = ReadFloat(instance, "tolerance", "m_Tolerance"); MaintainTargetPositionOffset = ReadBool(instance, "maintainTargetPositionOffset", "m_MaintainTargetPositionOffset"); MaintainTargetRotationOffset = ReadBool(instance, "maintainTargetRotationOffset", "m_MaintainTargetRotationOffset"); } public bool Equals(ChainIkValues other) { if (string.Equals(RootName, other.RootName, StringComparison.Ordinal) && string.Equals(TipName, other.TipName, StringComparison.Ordinal) && string.Equals(TargetName, other.TargetName, StringComparison.Ordinal) && Weight.Equals(other.Weight) && ChainRotationWeight.Equals(other.ChainRotationWeight) && TipRotationWeight.Equals(other.TipRotationWeight) && MaxIterations == other.MaxIterations && Tolerance.Equals(other.Tolerance) && MaintainTargetPositionOffset == other.MaintainTargetPositionOffset) { return MaintainTargetRotationOffset == other.MaintainTargetRotationOffset; } return false; } } private sealed class ChainIkBaseline { private readonly Component component; internal readonly string Path; internal readonly ChainIkValues Values; internal ChainIkBaseline(Component component, string path) { this.component = component; Path = path; Values = new ChainIkValues(component); } internal bool TryReadCurrent(out ChainIkValues current) { if ((Object)(object)component == (Object)null) { current = default(ChainIkValues); return false; } current = new ChainIkValues(component); return true; } } private sealed class RigWeightBaseline { private readonly Component component; internal readonly string Path; internal readonly float Weight; internal RigWeightBaseline(Component component, string path) { this.component = component; Path = path; Weight = ReadFloat(component, "weight", "m_Weight"); } internal bool TryReadCurrent(out float currentWeight) { if ((Object)(object)component == (Object)null) { currentWeight = float.NaN; return false; } currentWeight = ReadFloat(component, "weight", "m_Weight"); return true; } } private readonly struct RigLayerValues : IEquatable { internal readonly string RigName; internal readonly bool Active; internal readonly float Weight; internal RigLayerValues(object layer) { object obj = ReadMember(layer, "rig", "m_Rig"); Component val = (Component)((obj is Component) ? obj : null); RigName = (((Object)(object)val != (Object)null) ? ((Object)val).name : ""); Active = ReadBool(layer, "active", "m_Active"); Weight = ReadFloat(val, "weight", "m_Weight"); } public bool Equals(RigLayerValues other) { if (string.Equals(RigName, other.RigName, StringComparison.Ordinal) && Active == other.Active) { return Weight.Equals(other.Weight); } return false; } } private sealed class RigLayerBaseline { private readonly object layer; internal readonly string Path; internal readonly RigLayerValues Values; internal RigLayerBaseline(object layer, string path) { this.layer = layer; Path = path; Values = new RigLayerValues(layer); } internal bool TryReadCurrent(out RigLayerValues current) { if (layer == null) { current = default(RigLayerValues); return false; } current = new RigLayerValues(layer); return true; } } [CompilerGenerated] private static class <>O { public static UnityAction <0>__LogRestoreRenderFrame; } internal const string ConfigSection = "Interaction Animation API Restore Diagnostics"; internal const string DefaultRestoreStateMode = "fresh"; private const int RestoreHistoryFrames = 3; private const int RestoreFutureFrames = 6; private const int StartRenderFutureFrames = 3; private const int StopRenderFutureFrames = 5; private const int MaxAnimatorLayers = 32; private const float RigPositionDeltaThreshold = 0.0005f; private const float RigRotationDeltaThresholdDegrees = 0.05f; private const float ThirdPersonRigRestPositionThreshold = 0.05f; private const float ThirdPersonRigRestRotationThresholdDegrees = 8f; private const float ThirdPersonRigRestScaleThreshold = 0.01f; private const float RemoteRigDiffPostRestoreSeconds = 5f; private const float IkBakeDegenerateThreshold = 0.001f; private const int IkBakeChainWalkGuard = 64; internal const string IkBakeProbePhaseAwake = "awake"; internal const string IkBakeProbePhasePreStartBuild = "pre-start-build"; internal const string IkBakeProbePhasePreRestoreBuild = "pre-restore-build"; internal const string IkBakeProbePhasePostRestore = "post-restore"; private const string TwoBoneIkConstraintTypeName = "UnityEngine.Animations.Rigging.TwoBoneIKConstraint"; private const string ChainIkConstraintTypeName = "UnityEngine.Animations.Rigging.ChainIKConstraint"; private const string RigTypeName = "UnityEngine.Animations.Rigging.Rig"; private const string RigBuilderTypeName = "UnityEngine.Animations.Rigging.RigBuilder"; private static readonly RestoreFrameSample[] RestoreHistory = new RestoreFrameSample[3] { new RestoreFrameSample(32), new RestoreFrameSample(32), new RestoreFrameSample(32) }; private static ManualLogSource logger; private static ConfigEntry enableRestoreSeamFrameLogger; private static ConfigEntry enableRestoreRigStateLogger; private static ConfigEntry enablePristineRigDiffProbe; private static ConfigEntry restoreRigControlPose; private static ConfigEntry restorePristineRigControlPose; private static ConfigEntry restoreThirdPersonRigControlPose; private static ConfigEntry restorePristineThirdPersonRigControlPose; private static ConfigEntry recaptureImplausiblePristineRigBaseline; private static ConfigEntry restoreVanillaArmsGlue; private static ConfigEntry restoreCameraPin; private static ConfigEntry restoreCameraRotation; private static ConfigEntry stabilizeCameraRotationDuringSession; private static ConfigEntry restoreCameraRotationSnapToRest; private static ConfigEntry restoreCameraChainPositionSnapToRest; private static ConfigEntry healCameraDriftAtSessionStart; private static ConfigEntry restoreVisorPose; private static ConfigEntry hardVisorGlueDuringSession; private static ConfigEntry enableExternalCameraPresentationLogger; private static ConfigEntry enableRemoteRigDiffProbe; private static ConfigEntry enableIkBakeProbe; private static ConfigEntry restoreStateMode; private static InteractionAnimationRestoreDiagnosticsRunner runner; private static PlayerControllerB observedPlayer; private static PlayerControllerB renderSessionPlayer; private static Camera renderSessionGameplayCamera; private static Transform renderSessionCamera; private static Transform renderSessionRightHand; private static Transform renderSessionLeftHand; private static Transform renderSessionArmsMetarig; private static Transform renderSessionLocalArms; private static Transform renderSessionLocalVisor; private static Transform renderSessionLocalVisorTargetPoint; private static Camera renderSessionVisorCamera; private static readonly RenderSeamFrameSample LatestRenderFrame = new RenderSeamFrameSample(); private static readonly RenderSeamFrameSample PendingStartBeforeRenderFrame = new RenderSeamFrameSample(); private static readonly RenderSeamWindow StartRenderSeam = new RenderSeamWindow("start"); private static readonly RenderSeamWindow StopRenderSeam = new RenderSeamWindow("stop"); private static readonly List RenderVisibilityBuffer = new List(16); private static PristineRigSnapshot pristineRig; private static readonly Dictionary PristineThirdPersonRigPoses = new Dictionary(); private static readonly Dictionary PristineCameraChainPoses = new Dictionary(); private static readonly Dictionary ActiveRemoteRigProbeIds = new Dictionary(); private static readonly List PendingRemoteRigProbes = new List(); private static readonly HashSet IkBakeProbeAwakeLoggedPlayers = new HashSet(); private static bool customAnimationHasRun; private static bool coordinatorLateUpdateTick; private static bool initialized; private static int restoreHistoryNext; private static int restoreHistoryCount; private static int restoreFutureFramesRemaining; private static int restoreFutureFrameIndex; private static int activeStopFrame; private static string activeStopInvocation = "consumer_call"; private static bool renderSamplerSubscribed; private static int pendingRigDiffLateUpdates = -1; private static bool samplerFailureLogged; private static bool twoBoneIkTypeUnavailableLogged; private static bool chainIkTypeUnavailableLogged; private static bool invalidRestoreStateModeWarningLogged; private static bool prepareForLiveBodyStartUninitializedLogged; private static bool remoteRigProbeSessionBeginUninitializedLogged; private static bool playerAwakeCaptureUninitializedLogged; private static PlayerControllerB ikBakeProbePlayer; private static int pendingIkBakeProbeLateUpdates = -1; private static int nextRemoteRigProbeId; internal const string CameraChainAuthoredDefaultSource = "player_awake_prefix_authored_default"; internal const string CameraChainRuntimeSettledSource = "session_entry_runtime_settled"; internal const string ThirdPersonRigAuthoredDefaultSource = "player_awake_prefix_authored_default"; internal const string ThirdPersonRigRuntimeSettledSource = "session_entry_runtime_settled"; internal static bool RestoreScopedCameraPinEnabled { get { if (initialized) { return ReadEnabled(restoreCameraPin, fallback: true); } return false; } } internal static bool RestoreCameraRotationEnabled { get { if (initialized) { return ReadEnabled(restoreCameraRotation, fallback: true); } return false; } } internal static bool StabilizeCameraRotationDuringSessionEnabled { get { if (initialized) { return ReadEnabled(stabilizeCameraRotationDuringSession, fallback: true); } return false; } } internal static bool RestoreCameraRotationSnapToRestEnabled { get { if (initialized) { return ReadEnabled(restoreCameraRotationSnapToRest, fallback: true); } return false; } } internal static bool RestoreCameraChainPositionSnapToRestEnabled { get { if (initialized) { return ReadEnabled(restoreCameraChainPositionSnapToRest, fallback: true); } return false; } } internal static bool HealCameraDriftAtSessionStartEnabled { get { if (initialized) { return ReadEnabled(healCameraDriftAtSessionStart, fallback: true); } return false; } } internal static ManualLogSource StaticLogger => logger ?? Plugin.Log; internal static bool RestoreVisorPoseEnabled { get { if (initialized) { return ReadEnabled(restoreVisorPose, fallback: true); } return false; } } internal static bool HardVisorGlueDuringSessionEnabled { get { if (initialized) { return ReadEnabled(hardVisorGlueDuringSession, fallback: true); } return false; } } internal static bool ExternalCameraPresentationLoggerEnabled { get { if (initialized) { return ReadEnabled(enableExternalCameraPresentationLogger, fallback: false); } return false; } } internal static bool RestoreSeamFrameLoggerEnabled { get { if (initialized) { return ReadEnabled(enableRestoreSeamFrameLogger, fallback: false); } return false; } } internal static bool RestoreRigControlPoseEnabled { get { if (initialized) { return ReadEnabled(restoreRigControlPose, fallback: true); } return false; } } internal static bool RestorePristineRigControlPoseEnabled { get { if (initialized) { return ReadEnabled(restorePristineRigControlPose, fallback: true); } return false; } } internal static bool RestoreThirdPersonRigControlPoseEnabled { get { if (initialized) { return ReadEnabled(restoreThirdPersonRigControlPose, fallback: true); } return false; } } internal static bool RestorePristineThirdPersonRigControlPoseEnabled { get { if (initialized) { return ReadEnabled(restorePristineThirdPersonRigControlPose, fallback: true); } return false; } } internal static bool RecaptureImplausiblePristineRigBaselineEnabled { get { if (initialized) { return ReadEnabled(recaptureImplausiblePristineRigBaseline, fallback: true); } return false; } } internal static bool IkBakeProbeEnabled { get { if (initialized) { return ReadEnabled(enableIkBakeProbe, fallback: true); } return false; } } internal static bool RestoreVanillaArmsGlueEnabled { get { if (initialized) { return ReadEnabled(restoreVanillaArmsGlue, fallback: true); } return false; } } internal static AnimatorStateRestoreMode ReadRestoreStateMode() { string text; try { text = ((restoreStateMode != null) ? restoreStateMode.Value : "fresh"); } catch { text = "fresh"; } if (string.Equals(text, "fresh", StringComparison.OrdinalIgnoreCase)) { return AnimatorStateRestoreMode.Fresh; } if (string.Equals(text, "crossfade", StringComparison.OrdinalIgnoreCase)) { return AnimatorStateRestoreMode.Crossfade; } if (string.Equals(text, "replay", StringComparison.OrdinalIgnoreCase)) { return AnimatorStateRestoreMode.Replay; } if (!invalidRestoreStateModeWarningLogged) { invalidRestoreStateModeWarningLogged = true; ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("[RestoreSeam.mode] invalid Restore State Mode '" + (text ?? "") + "'; using 'fresh'.")); } } return AnimatorStateRestoreMode.Fresh; } internal static void Initialize(ConfigFile config, ManualLogSource log) { //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown if (initialized) { return; } logger = log; if (config != null) { enableRestoreSeamFrameLogger = config.Bind("Interaction Animation API Restore Diagnostics", "Enable Restore Seam Frame Logger", false, "Samples local-player state around each live-body Stop and samples final rendered transforms, visibility, camera parameters, and timing around both Start and Stop seams."); enableRestoreRigStateLogger = config.Bind("Interaction Animation API Restore Diagnostics", "Enable Restore Rig State Logger", false, "Logs every player-body animator layer immediately before and after the restore RigBuilder.Build loop, then after the final Animator.Update(0)."); enablePristineRigDiffProbe = config.Bind("Interaction Animation API Restore Diagnostics", "Enable Pristine Rig Diff Probe", false, "Captures the local first-person RigArms controls before any API live-body animation and enables automatic post-restore diffs."); restoreRigControlPose = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Rig Control Pose", true, "When enabled, every live-body session captures the player's RigArms control subtree before the controller swap and restores it after the vanilla animator snapshot but before RigBuilder rebuilds."); restorePristineRigControlPose = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Pristine Rig Control Pose", true, "When enabled, local live-body restores use the startup-pristine RigArms local poses first and use the equip-time capture only for transforms with no pristine baseline."); restoreThirdPersonRigControlPose = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Third-Person Rig Control Pose", true, "When enabled, every local or remote live-body session captures and restores the third-person arm targets, leg control groups, and shin pole-seed rotations. This is a new kill-switch so existing profiles receive the default-on fix."); restorePristineThirdPersonRigControlPose = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Pristine Third-Person Rig Control Pose", true, "When enabled, third-person rig restores use each player's serialized authored-default pose captured before PlayerControllerB.Awake as the primary source and the session-entry pose only as fallback. Vanilla-rest plausibility is logged as secondary sanity telemetry and does not reject the authored baseline."); recaptureImplausiblePristineRigBaseline = config.Bind("Interaction Animation API Restore Diagnostics", "Recapture Implausible Pristine Rig Baseline", true, "When enabled, a third-person rig baseline captured at PlayerControllerB.Awake that the vanilla-rest sanity check flagged implausible is replaced by a fresh capture taken at the first verified-clean idle session entry (standing, not in a special animation, near-zero horizontal speed, camera at vanilla rest). The recapture runs only for the local player and only through the session-entry camera-drift heal, so it requires Heal Camera Drift At Session Start to be enabled and does not repair remote players' baselines (their Stops keep restoring the Awake-time capture). This is a new key so existing profiles receive the default-on fix."); restoreVanillaArmsGlue = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Vanilla Arms Glue", true, "When enabled, local live-body restores apply vanilla's camera-Y and first-person arm glue before the same-frame Animator and RigBuilder evaluation."); restoreCameraPin = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Camera Pin", true, "When enabled, every local live-body Stop pins the camera at its Stop-entry player-local position through the restore and two LateUpdates. Supersedes the old Enable Restore-Scoped Camera Pin key so existing profiles receive the default-on setting."); restoreCameraRotation = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Camera Rotation", true, "When enabled, local live-body Start and Stop preserve the gameplay camera and camera-container local rotations across controller swaps and Animator.Rebind. This is a new key so existing profiles receive the default-on seam fix."); stabilizeCameraRotationDuringSession = config.Bind("Interaction Animation API Restore Diagnostics", "Stabilize Camera Rotation During Session", true, "When enabled, local live-body sessions preserve vanilla-owned gameplay-camera pitch while writing local yaw and roll as absolute values from the session-entry baseline after other LateUpdate writers and immediately before rendering. This prevents consumer camera effects from feeding their previous output back into later frames."); restoreCameraRotationSnapToRest = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Camera Rotation Snap To Rest", true, "When enabled, local live-body Stop preserves gameplay-camera pitch but discards stop-entry yaw/roll, snapping them to zero, and restores CameraContainer exactly to its authored local rest rotation (90, 359.8182, 0). The stop gate logs the discarded residue."); restoreCameraChainPositionSnapToRest = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Camera Chain Position Snap To Rest", true, "When enabled, local live-body Stop restores the local positions of CameraContainer, the gameplay camera, the first-person arms metarig root, and the local-arms transform to the authored defaults captured before PlayerControllerB.Awake. Authored clips can write positions on these transforms that vanilla never rewrites; without this snap each session leaves a small permanent viewpoint offset that accumulates. This is a new key so existing profiles receive the default-on fix."); healCameraDriftAtSessionStart = config.Bind("Interaction Animation API Restore Diagnostics", "Heal Camera Drift At Session Start", true, "When enabled, each local live-body session start measures the gameplay camera against its vanilla player-local rest position (0, 2.35, 0.01) and, when it deviates by more than the heal threshold (2 cm) but less than the displacement-guard threshold, restores the camera chain local positions to the authored defaults before capturing the session baseline. This repairs viewpoint drift accumulated by earlier sessions or other mods instead of adopting the contaminated pose as the restore target. This is a new key so existing profiles receive the default-on fix."); restoreVisorPose = config.Bind("Interaction Animation API Restore Diagnostics", "Restore Visor Pose", true, "When enabled, local live-body Start and Stop preserve animator-owned helmet-visor transforms across controller swaps and Animator.Rebind, then synchronously restore vanilla visor position glue without advancing its rotation lerp. This is a new key so existing profiles receive the default-on seam fix."); hardVisorGlueDuringSession = config.Bind("Interaction Animation API Restore Diagnostics", "Hard Visor Glue During Session", true, "When enabled, first-person local live-body sessions re-glue the helmet visor to its camera target point (position AND rotation, no lerp) just before each render. Vanilla's own glue smooths rotation at 53 deg/s, which lags fast scripted or animated camera moves and sweeps the mask edge into frame; this keeps the mask stable so consumers no longer need to hide it. A visor a consumer has parked away from the camera is left alone, and consumer-owned camera sessions always stand down because their camera owner also owns visor presentation."); enableExternalCameraPresentationLogger = config.Bind("Interaction Animation API Restore Diagnostics", "Enable External Camera Presentation Logger", false, "For consumer-owned-camera BodyWorld sessions, logs the final pre-render body, first-person-arms, and local-visor renderer state once at entry and again only when render eligibility changes. This low-noise invariant probe identifies local presentation leaks without enabling the full restore seam frame logger."); enableRemoteRigDiffProbe = config.Bind("Interaction Animation API Restore Diagnostics", "Enable Remote Rig Diff Probe", false, "When enabled, every remote live-body session logs third-person arm-target, leg-target, and shin local TRS at session begin, two LateUpdates after restore, and five seconds after restore. This verbose diagnostics probe remains opt-in."); enableIkBakeProbe = config.Bind("Interaction Animation API Restore Diagnostics", "Enable IK Bake Probe", true, "When enabled, the ChainIK and TwoBoneIK constraints under the local player's first-person arms metarig are sampled at four checkpoints per live-body session (first PlayerControllerB.Awake, immediately before the start rebuild, immediately before the restore rebuild, and two LateUpdates after restore) and each sample logs the world-space link distances, maxReach, and tip-versus-target offsets that RigBuilder.Build() bakes permanently into its job arrays. A link distance or bone lossy scale below 0.001 at either pre-build checkpoint raises a warning, because that bake outlives the session and leaves the affected limb mispositioned in vanilla animation. Four compact rounds per session; safe to leave on."); restoreStateMode = config.Bind("Interaction Animation API Restore Diagnostics", "Restore State Mode", "fresh", new ConfigDescription("Selects how vanilla animator layer states resume at live-body Stop: fresh starts from controller defaults, crossfade blends to captured states, and replay immediately restores captured states.", (AcceptableValueBase)(object)new AcceptableValueList(new string[3] { "fresh", "crossfade", "replay" }), Array.Empty())); } bool flag = ReadEnabled(enableRestoreSeamFrameLogger, fallback: false); bool flag2 = ReadEnabled(enableRestoreRigStateLogger, fallback: false); bool flag3 = ReadEnabled(enablePristineRigDiffProbe, fallback: false); bool flag4 = ReadEnabled(restoreRigControlPose, fallback: true); bool flag5 = ReadEnabled(restorePristineRigControlPose, fallback: true); bool flag6 = ReadEnabled(restoreThirdPersonRigControlPose, fallback: true); bool flag7 = ReadEnabled(restorePristineThirdPersonRigControlPose, fallback: true); bool flag8 = ReadEnabled(restoreVanillaArmsGlue, fallback: true); bool flag9 = ReadEnabled(restoreCameraPin, fallback: true); bool flag10 = ReadEnabled(restoreCameraRotation, fallback: true); bool flag11 = ReadEnabled(stabilizeCameraRotationDuringSession, fallback: true); bool flag12 = ReadEnabled(restoreCameraRotationSnapToRest, fallback: true); bool flag13 = ReadEnabled(restoreCameraChainPositionSnapToRest, fallback: true); bool flag14 = ReadEnabled(healCameraDriftAtSessionStart, fallback: true); bool flag15 = ReadEnabled(restoreVisorPose, fallback: true); bool flag16 = ReadEnabled(enableExternalCameraPresentationLogger, fallback: false); bool flag17 = ReadEnabled(enableRemoteRigDiffProbe, fallback: false); bool flag18 = ReadEnabled(enableIkBakeProbe, fallback: true); initialized = true; if (flag) { SubscribeRenderSampler(); } if (flag || flag3 || flag5 || flag7 || flag17 || flag18) { try { GameObject val = (((Object)(object)Plugin.Host != (Object)null) ? ((Component)Plugin.Host).gameObject : null); if ((Object)(object)val != (Object)null) { runner = val.AddComponent(); } else { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)"[RestoreSeam] diagnostics_runner_unavailable: plugin GameObject was not available."); } } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("[RestoreSeam] diagnostics_runner_failed: " + ex.Message)); } } } if (flag || flag2 || flag3 || flag4 || flag5 || flag6 || flag7 || flag8 || flag9 || flag10 || flag11 || flag12 || flag13 || flag14 || flag15 || flag16 || flag17 || flag18) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RestoreSeam] diagnostics_ready: " + $"frameLogger={flag} " + $"rigStateLogger={flag2} " + $"rigDiff={flag3} " + $"restoreRigControlPose={flag4} " + $"restorePristineRigControlPose={flag5} " + $"restoreThirdPersonRigControlPose={flag6} " + $"restorePristineThirdPersonRigControlPose={flag7} " + $"restoreVanillaArmsGlue={flag8} " + $"restoreCameraPin={flag9} " + $"restoreCameraRotation={flag10} " + $"stabilizeCameraRotationDuringSession={flag11} " + $"restoreCameraRotationSnapToRest={flag12} " + $"restoreCameraChainPositionSnapToRest={flag13} " + $"healCameraDriftAtSessionStart={flag14} " + $"restoreVisorPose={flag15} " + $"externalCameraPresentationLogger={flag16} " + $"remoteRigDiffProbe={flag17} " + $"ikBakeProbe={flag18}.")); } } } internal static void Shutdown() { initialized = false; coordinatorLateUpdateTick = false; UnsubscribeRenderSampler(); if ((Object)(object)runner != (Object)null) { try { ((Behaviour)runner).enabled = false; Object.Destroy((Object)(object)runner); } catch { } } runner = null; observedPlayer = null; ClearRenderSessionTransforms(); pristineRig = null; PristineThirdPersonRigPoses.Clear(); PristineCameraChainPoses.Clear(); ActiveRemoteRigProbeIds.Clear(); PendingRemoteRigProbes.Clear(); customAnimationHasRun = false; ResetRestoreHistory(); pendingRigDiffLateUpdates = -1; samplerFailureLogged = false; twoBoneIkTypeUnavailableLogged = false; chainIkTypeUnavailableLogged = false; invalidRestoreStateModeWarningLogged = false; prepareForLiveBodyStartUninitializedLogged = false; remoteRigProbeSessionBeginUninitializedLogged = false; playerAwakeCaptureUninitializedLogged = false; IkBakeProbeAwakeLoggedPlayers.Clear(); ikBakeProbePlayer = null; pendingIkBakeProbeLateUpdates = -1; nextRemoteRigProbeId = 0; enableRestoreSeamFrameLogger = null; enableRestoreRigStateLogger = null; enablePristineRigDiffProbe = null; restoreRigControlPose = null; restorePristineRigControlPose = null; restoreThirdPersonRigControlPose = null; restorePristineThirdPersonRigControlPose = null; recaptureImplausiblePristineRigBaseline = null; restoreVanillaArmsGlue = null; restoreCameraPin = null; restoreCameraRotation = null; stabilizeCameraRotationDuringSession = null; restoreCameraRotationSnapToRest = null; restoreCameraChainPositionSnapToRest = null; healCameraDriftAtSessionStart = null; restoreVisorPose = null; hardVisorGlueDuringSession = null; enableExternalCameraPresentationLogger = null; enableRemoteRigDiffProbe = null; enableIkBakeProbe = null; restoreStateMode = null; logger = null; } internal static void BeginCoordinatorLateUpdateTick() { if (initialized && ReadEnabled(enableRestoreSeamFrameLogger, fallback: false)) { coordinatorLateUpdateTick = true; } } internal static void EndCoordinatorLateUpdateTick() { coordinatorLateUpdateTick = false; } internal static void PrepareForLiveBodyStart(PlayerControllerB player) { if (!initialized) { if (!prepareForLiveBodyStartUninitializedLogged) { prepareForLiveBodyStartUninitializedLogged = true; ManualLogSource staticLogger = StaticLogger; if (staticLogger != null) { staticLogger.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + "initialized=False reason='restore_diagnostics_not_initialized' action='skip_prepare_for_live_body_start'.")); } } return; } LogPristineThirdPersonRigPoseAvailability(player); if (!IsLocalPlayer(player)) { return; } ObservePlayer(player); if (ReadEnabled(enableRestoreSeamFrameLogger, fallback: false)) { SubscribeRenderSampler(); CacheRenderSessionTransforms(player); if (LatestRenderFrame.Valid && LatestRenderFrame.Player == player) { PendingStartBeforeRenderFrame.CopyFrom(LatestRenderFrame); } else { CaptureRenderFrame(player, PendingStartBeforeRenderFrame); } } if (PristineRigCaptureEnabled() && !customAnimationHasRun) { TryCapturePristineRig(player); } } internal static void NotifyLiveBodyStarted(PlayerControllerB player, GameObject animatedProp) { if (!initialized || !ReadEnabled(enableRestoreSeamFrameLogger, fallback: false) || !IsLocalPlayer(player)) { return; } try { ObservePlayer(player); if (renderSessionPlayer != player) { CacheRenderSessionTransforms(player); } SubscribeRenderSampler(); int frameCount = Time.frameCount; StartRenderSeam.Activate(frameCount, frameCount + 3, animatedProp); if (PendingStartBeforeRenderFrame.Valid && PendingStartBeforeRenderFrame.Player == player) { LogRenderFrame(PendingStartBeforeRenderFrame, StartRenderSeam, "before", captureAnimatedProp: false); } } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("[RestoreSeam.render] start_activate_failed: " + ex.Message)); } } } internal static void NotifyLiveBodyAnimationRan(PlayerControllerB player) { if (initialized && PristineRigCaptureEnabled() && IsLocalPlayer(player)) { ObservePlayer(player); customAnimationHasRun = true; } } internal static bool TryRestorePristineRigControlPose(PlayerControllerB player, Transform rigArms, ISet restoredTransforms, out int restored) { restored = 0; if (!RestorePristineRigControlPoseEnabled || !IsLocalPlayer(player) || (Object)(object)rigArms == (Object)null || restoredTransforms == null) { return false; } try { if (pristineRig == null || pristineRig.Player != player) { return false; } restored = pristineRig.RestoreRigControlPose(rigArms, restoredTransforms); return restored > 0; } catch (Exception ex) { ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("[RestoreSeam.rigpose] pristine_restore_failed: " + ex.Message)); } restored = 0; restoredTransforms.Clear(); return false; } } internal static ThirdPersonRigPoseSnapshot CaptureThirdPersonRigControlPose(PlayerControllerB player) { return ThirdPersonRigPoseSnapshot.Capture(player); } internal static bool TryRestorePristineThirdPersonRigControlPose(PlayerControllerB player, ISet restoredTransforms, out int fullPoseRestored, out int rotationOnlyRestored, out string gateReason) { fullPoseRestored = 0; rotationOnlyRestored = 0; gateReason = "unknown"; if (!RestorePristineThirdPersonRigControlPoseEnabled) { gateReason = "kill_switch_disabled"; return false; } if ((Object)(object)player == (Object)null) { gateReason = "player_missing"; return false; } if (restoredTransforms == null) { gateReason = "restore_set_missing"; return false; } if (!PristineThirdPersonRigPoses.TryGetValue(player, out var value) || value == null) { gateReason = "pristine_baseline_unavailable"; return false; } try { value.RestoreExcept(null, restoredTransforms, out fullPoseRestored, out rotationOnlyRestored); gateReason = ((fullPoseRestored + rotationOnlyRestored > 0) ? "pristine_primary_restored" : "pristine_targets_unavailable"); return fullPoseRestored + rotationOnlyRestored > 0; } catch (Exception ex) { gateReason = "restore_failed:" + ex.Message; fullPoseRestored = 0; rotationOnlyRestored = 0; restoredTransforms.Clear(); return false; } } internal static bool TryRecapturePristineThirdPersonRigPoseIfImplausible(PlayerControllerB player, out string reason) { reason = string.Empty; if (!initialized) { reason = "restore_diagnostics_not_initialized"; return false; } if (!RecaptureImplausiblePristineRigBaselineEnabled) { reason = "kill_switch_disabled"; return false; } if ((Object)(object)player == (Object)null) { reason = "player_missing"; return false; } if (!PristineThirdPersonRigPoses.TryGetValue(player, out var value) || value == null) { reason = "pristine_baseline_unavailable"; return false; } if (string.Equals(value.Source, "session_entry_runtime_settled", StringComparison.Ordinal)) { reason = "already_recaptured"; return false; } if (value.PlausibleAtCapture) { reason = "baseline_already_plausible"; return false; } try { ThirdPersonRigPoseSnapshot thirdPersonRigPoseSnapshot = ThirdPersonRigPoseSnapshot.Capture(player); if (thirdPersonRigPoseSnapshot == null || thirdPersonRigPoseSnapshot.TotalCount == 0 || !thirdPersonRigPoseSnapshot.IsComplete || !thirdPersonRigPoseSnapshot.EvaluateVanillaRestPlausibility().Plausible) { reason = "candidate_still_implausible"; ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam.tprig] rest_baseline_recapture_skipped: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + $"candidatePresent={thirdPersonRigPoseSnapshot != null} " + $"candidateComplete={thirdPersonRigPoseSnapshot?.IsComplete ?? false} " + "reason='candidate_still_implausible' action='retry_next_clean_entry'.")); } return false; } ThirdPersonRigPlausibility thirdPersonRigPlausibility = value.EvaluateVanillaRestPlausibility(); thirdPersonRigPoseSnapshot.SetCaptureMetadata(plausibleAtCapture: true, "session_entry_runtime_settled"); PristineThirdPersonRigPoses[player] = thirdPersonRigPoseSnapshot; ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RestoreSeam.tprig] rest_baseline_recaptured: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + $"outliersBefore={thirdPersonRigPlausibility.PositionOutliers + thirdPersonRigPlausibility.RotationOutliers + thirdPersonRigPlausibility.ScaleOutliers} " + $"fullPoseTransforms={thirdPersonRigPoseSnapshot.FullPoseCount} " + $"rotationOnlyTransforms={thirdPersonRigPoseSnapshot.RotationOnlyCount} " + "source='session_entry_runtime_settled' action='replace_authored_default_with_runtime_settled'.")); } return true; } catch (Exception ex) { reason = "recapture_failed:" + ex.Message; ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RestoreSeam.tprig] rest_baseline_recapture_skipped: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + "reason='" + SanitizeLogValue(reason) + "' action='retry_next_clean_entry'.")); } return false; } } internal static void NotifyStop(PlayerControllerB player, GameObject animatedProp) { if (initialized && ReadEnabled(enableRestoreSeamFrameLogger, fallback: false) && IsLocalPlayer(player)) { ObservePlayer(player); if (renderSessionPlayer != player) { CacheRenderSessionTransforms(player); } activeStopFrame = Time.frameCount; activeStopInvocation = (coordinatorLateUpdateTick ? "coordinator_late_update" : "consumer_call"); SubscribeRenderSampler(); StopRenderSeam.Activate(activeStopFrame, activeStopFrame + 5, animatedProp); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam] " + $"frame={activeStopFrame} phase=stop_entry stopInvocation='{activeStopInvocation}' " + $"bufferedBefore={restoreHistoryCount} futureFrames={6}.")); } for (int i = 0; i < restoreHistoryCount; i++) { int num = (restoreHistoryNext - restoreHistoryCount + i + 3) % 3; int num2 = restoreHistoryCount - i; LogRestoreFrame(RestoreHistory[num], "before-" + num2.ToString(CultureInfo.InvariantCulture)); } restoreFutureFramesRemaining = 6; restoreFutureFrameIndex = 0; } } internal static void NotifyRestoreCompleted(PlayerControllerB player) { if (initialized) { NotifyRemoteRigProbeRestoreCompleted(player); ScheduleIkBakeProbeAfterRestore(player); if (ReadEnabled(enablePristineRigDiffProbe, fallback: false) && pristineRig != null && pristineRig.Player == player) { pendingRigDiffLateUpdates = 2; } } } internal static void NotifyRemoteRigProbeSessionBegin(PlayerControllerB player) { if (!initialized) { if (!remoteRigProbeSessionBeginUninitializedLogged) { remoteRigProbeSessionBeginUninitializedLogged = true; ManualLogSource staticLogger = StaticLogger; if (staticLogger != null) { staticLogger.LogInfo((object)("[RemoteRigDiff] gate: " + $"frame={Time.frameCount} phase='session_begin' " + "player='" + DescribePlayer(player) + "' initialized=False action='skip_restore_diagnostics_not_initialized'.")); } } } else { if ((Object)(object)player == (Object)null || IsLocalPlayer(player)) { return; } bool num = ReadEnabled(enableRemoteRigDiffProbe, fallback: false); string text = DescribePlayer(player); if (!num) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RemoteRigDiff] gate: " + $"frame={Time.frameCount} phase='session_begin' " + "player='" + text + "' enabled=False action='skip'.")); } } else { int num2 = ++nextRemoteRigProbeId; ActiveRemoteRigProbeIds[player] = num2; LogRemoteRigPose(player, num2, "session_begin"); } } } private static void NotifyRemoteRigProbeRestoreCompleted(PlayerControllerB player) { if ((Object)(object)player == (Object)null || IsLocalPlayer(player)) { return; } bool num = ReadEnabled(enableRemoteRigDiffProbe, fallback: false); string text = DescribePlayer(player); ActiveRemoteRigProbeIds.TryGetValue(player, out var value); ActiveRemoteRigProbeIds.Remove(player); if (value <= 0) { value = ++nextRemoteRigProbeId; } if (!num) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RemoteRigDiff] gate: " + $"frame={Time.frameCount} phase='restore_schedule' " + $"probeId={value} player='{text}' " + "enabled=False action='skip'.")); } return; } RemoteRigProbeSchedule item = new RemoteRigProbeSchedule(player, value, Time.frameCount, Time.realtimeSinceStartup + 5f); PendingRemoteRigProbes.Add(item); ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RemoteRigDiff] restore_scheduled: " + $"frame={Time.frameCount} probeId={value} " + "player='" + text + "' lateUpdates=2 seconds=" + FormatFloat(5f) + ".")); } } private static void TickRemoteRigDiffProbes(bool enabled) { for (int num = PendingRemoteRigProbes.Count - 1; num >= 0; num--) { RemoteRigProbeSchedule remoteRigProbeSchedule = PendingRemoteRigProbes[num]; if (remoteRigProbeSchedule == null) { PendingRemoteRigProbes.RemoveAt(num); } else if (!enabled) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RemoteRigDiff] gate: " + $"frame={Time.frameCount} phase='scheduled_samples' " + $"probeId={remoteRigProbeSchedule.ProbeId} " + "player='" + DescribePlayer(remoteRigProbeSchedule.Player) + "' enabled=False action='cancel'.")); } PendingRemoteRigProbes.RemoveAt(num); } else { if (!remoteRigProbeSchedule.LateUpdateSampleLogged && Time.frameCount > remoteRigProbeSchedule.RestoreFrame) { remoteRigProbeSchedule.LateUpdatesRemaining--; if (remoteRigProbeSchedule.LateUpdatesRemaining <= 0) { remoteRigProbeSchedule.LateUpdateSampleLogged = true; LogRemoteRigPose(remoteRigProbeSchedule.Player, remoteRigProbeSchedule.ProbeId, "restore_plus_2_lateupdates"); } } if (!remoteRigProbeSchedule.FiveSecondSampleLogged && Time.realtimeSinceStartup >= remoteRigProbeSchedule.FiveSecondRealtime) { remoteRigProbeSchedule.FiveSecondSampleLogged = true; LogRemoteRigPose(remoteRigProbeSchedule.Player, remoteRigProbeSchedule.ProbeId, "restore_plus_5_seconds"); } if (remoteRigProbeSchedule.LateUpdateSampleLogged && remoteRigProbeSchedule.FiveSecondSampleLogged) { PendingRemoteRigProbes.RemoveAt(num); } } } } private static void LogRemoteRigPose(PlayerControllerB player, int probeId, string phase) { string text = DescribePlayer(player); Transform val = null; try { val = (((Object)(object)player != (Object)null && (Object)(object)player.playerBodyAnimator != (Object)null) ? ((Component)player.playerBodyAnimator).transform : null); } catch { } Transform parent = FindChildRecursive(val, "spine.003"); Transform parent2 = FindChildRecursive(val, "Rig 1"); Transform parent3 = FindDirectChild(parent2, "LeftLeg"); Transform parent4 = FindDirectChild(parent2, "RightLeg"); Transform transform = FindDirectChild(parent, "LeftArm_target"); Transform transform2 = FindDirectChild(parent, "RightArm_target"); Transform transform3 = FindDirectChild(parent3, "LeftLeg_target"); Transform transform4 = FindDirectChild(parent4, "RightLeg_target"); Transform transform5 = FindChildRecursive(val, "shin.L"); Transform transform6 = FindChildRecursive(val, "shin.R"); ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RemoteRigDiff] sample_begin: " + $"frame={Time.frameCount} phase='{phase}' probeId={probeId} " + $"player='{text}' animatorRootPresent={(Object)(object)val != (Object)null}.")); } int num = 0; num += LogRemoteRigTransform(transform, "spine.003/LeftArm_target", text, probeId, phase); num += LogRemoteRigTransform(transform2, "spine.003/RightArm_target", text, probeId, phase); num += LogRemoteRigTransform(transform3, "Rig 1/LeftLeg/LeftLeg_target", text, probeId, phase); num += LogRemoteRigTransform(transform4, "Rig 1/RightLeg/RightLeg_target", text, probeId, phase); num += LogRemoteRigTransform(transform5, "spine/thigh.L/shin.L", text, probeId, phase); num += LogRemoteRigTransform(transform6, "spine/thigh.R/shin.R", text, probeId, phase); ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RemoteRigDiff] sample_end: " + $"frame={Time.frameCount} phase='{phase}' probeId={probeId} " + $"player='{text}' present={num} missing={6 - num}.")); } } private static int LogRemoteRigTransform(Transform transform, string path, string playerDescription, int probeId, string phase) { //IL_00cd: 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_0114: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RemoteRigDiff] transform_unavailable: " + $"frame={Time.frameCount} phase='{phase}' probeId={probeId} " + "player='" + playerDescription + "' path='" + path + "'.")); } return 0; } try { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RemoteRigDiff] transform: " + $"frame={Time.frameCount} phase='{phase}' probeId={probeId} " + "player='" + playerDescription + "' path='" + path + "' localPosition=" + FormatVector(transform.localPosition) + " localRotation=" + FormatQuaternion(transform.localRotation) + " localEuler=" + FormatVector(transform.localEulerAngles) + " localScale=" + FormatVector(transform.localScale) + ".")); } return 1; } catch (Exception ex) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RemoteRigDiff] transform_unavailable: " + $"frame={Time.frameCount} phase='{phase}' probeId={probeId} " + "player='" + playerDescription + "' path='" + path + "' reason='read_failed:" + SanitizeLogValue(ex.Message) + "'.")); } return 0; } } internal static void LogIkBakeProbeAtPlayerAwake(PlayerControllerB player) { if (IkBakeProbeEnabled && !((Object)(object)player == (Object)null) && IkBakeProbeAwakeLoggedPlayers.Add(player)) { LogIkBakeProbeCore(player, "awake"); } } internal static void LogIkBakeProbe(PlayerControllerB player, string phase) { if (IkBakeProbeEnabled && IsLocalPlayer(player)) { LogIkBakeProbeCore(player, phase); } } private static void ScheduleIkBakeProbeAfterRestore(PlayerControllerB player) { if (IkBakeProbeEnabled && IsLocalPlayer(player)) { ikBakeProbePlayer = player; pendingIkBakeProbeLateUpdates = 2; } } private static void TickIkBakeProbe() { if (pendingIkBakeProbeLateUpdates > 0) { pendingIkBakeProbeLateUpdates--; if (pendingIkBakeProbeLateUpdates <= 0) { PlayerControllerB player = ikBakeProbePlayer; ikBakeProbePlayer = null; pendingIkBakeProbeLateUpdates = -1; LogIkBakeProbeCore(player, "post-restore"); } } } private static void LogIkBakeProbeCore(PlayerControllerB player, string phase) { string text = DescribePlayer(player); try { Transform val = (((Object)(object)player != (Object)null) ? ((Component)player).transform : null); Transform val2 = (((Object)(object)player != (Object)null) ? player.playerModelArmsMetarig : null); string text2 = "arms-metarig"; if ((Object)(object)val2 == (Object)null) { val2 = FindChildRecursive(val, "RigArms"); text2 = "rig-arms"; } if ((Object)(object)val2 == (Object)null) { val2 = val; text2 = "player-fallback"; } if ((Object)(object)val2 == (Object)null) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[IkBakeProbe] sample_unavailable: " + $"frame={Time.frameCount} phase='{phase}' " + "player='" + text + "' reason='rig_root_unavailable'.")); } return; } Type constraintType = ResolveTwoBoneIkConstraintType(); Type constraintType2 = ResolveChainIkConstraintType(); Component[] array = ReadIkConstraints(val2, constraintType); Component[] array2 = ReadIkConstraints(val2, constraintType2); ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[IkBakeProbe] sample_begin: " + $"frame={Time.frameCount} phase='{phase}' player='{text}' " + "scanRoot='" + text2 + "' root='" + ((Object)val2).name + "' " + $"twoBoneIkConstraints={array.Length} " + $"chainIkConstraints={array2.Length} " + "degenerateThreshold=" + FormatFloat(0.001f) + ".")); } bool warnOnDegenerate = string.Equals(phase, "pre-start-build", StringComparison.Ordinal) || string.Equals(phase, "pre-restore-build", StringComparison.Ordinal); int num = 0; int num2 = 0; for (int i = 0; i < array.Length; i++) { if (LogIkBakeConstraint(array[i], "TwoBoneIK", val2, phase, text, warnOnDegenerate, out var degenerate)) { num++; } if (degenerate) { num2++; } } for (int j = 0; j < array2.Length; j++) { if (LogIkBakeConstraint(array2[j], "ChainIK", val2, phase, text, warnOnDegenerate, out var degenerate2)) { num++; } if (degenerate2) { num2++; } } ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[IkBakeProbe] sample_end: " + $"frame={Time.frameCount} phase='{phase}' player='{text}' " + $"constraints={num} degenerate={num2}.")); } } catch (Exception ex) { ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogWarning((object)("[IkBakeProbe] sample_failed: " + $"frame={Time.frameCount} phase='{phase}' player='{text}' " + "reason='" + SanitizeLogValue(ex.Message) + "'.")); } } } private static Component[] ReadIkConstraints(Transform root, Type constraintType) { if ((Object)(object)root == (Object)null || constraintType == null) { return Array.Empty(); } try { return ((Component)root).GetComponentsInChildren(constraintType, true) ?? Array.Empty(); } catch { return Array.Empty(); } } private static bool LogIkBakeConstraint(Component component, string kind, Transform pathRoot, string phase, string playerDescription, bool warnOnDegenerate, out bool degenerate) { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) degenerate = false; if ((Object)(object)component == (Object)null) { return false; } string text = ""; try { text = GetRelativePath(pathRoot, component.transform); object instance = ReadMember(component, null, "m_Data"); Transform val = ReadTransformMember(instance, "root", "m_Root"); Transform val2 = ReadTransformMember(instance, "mid", "m_Mid"); Transform val3 = ReadTransformMember(instance, "tip", "m_Tip"); Transform val4 = ReadTransformMember(instance, "target", "m_Target"); float value = ReadFloat(component, "weight", "m_Weight"); bool flag = ReadBool(instance, "maintainTargetPositionOffset", "m_MaintainTargetPositionOffset"); bool flag2 = ReadBool(instance, "maintainTargetRotationOffset", "m_MaintainTargetRotationOffset"); List list = (((Object)(object)val2 != (Object)null) ? BuildIkBoneList(val, val2, val3) : ExtractIkChain(val, val3)); StringBuilder stringBuilder = new StringBuilder(); float num = 0f; float num2 = float.PositiveInfinity; string text2 = ""; for (int i = 0; i + 1 < list.Count; i++) { Transform val5 = list[i]; Transform val6 = list[i + 1]; if (!((Object)(object)val5 == (Object)null) && !((Object)(object)val6 == (Object)null)) { float num3 = Vector3.Distance(val5.position, val6.position); num += num3; if (num3 < num2) { num2 = num3; text2 = ((Object)val5).name + ">" + ((Object)val6).name; } if (stringBuilder.Length > 0) { stringBuilder.Append('|'); } stringBuilder.Append(((Object)val5).name).Append('>').Append(((Object)val6).name) .Append('=') .Append(FormatFloat(num3)); } } float minComponent = float.PositiveInfinity; string minName = ""; TrackMinLossyScale(val, ref minComponent, ref minName); TrackMinLossyScale(val2, ref minComponent, ref minName); TrackMinLossyScale(val3, ref minComponent, ref minName); float num4; if (!((Object)(object)val3 != (Object)null) || !((Object)(object)val4 != (Object)null)) { num4 = float.NaN; } else { Vector3 val7 = val3.position - val4.position; num4 = ((Vector3)(ref val7)).magnitude; } float value2 = num4; float value3 = (((Object)(object)val3 != (Object)null && (Object)(object)val4 != (Object)null) ? Quaternion.Angle(val4.rotation, val3.rotation) : float.NaN); degenerate = (list.Count > 1 && num2 < 0.001f) || minComponent < 0.001f; ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[IkBakeProbe] constraint: " + $"frame={Time.frameCount} phase='{phase}' player='{playerDescription}' " + "kind='" + kind + "' path='" + text + "' weight=" + FormatFloat(value) + " " + $"maintainTargetPositionOffset={flag} " + $"maintainTargetRotationOffset={flag2} " + "rootLossyScaleX=" + FormatLossyScaleX(val) + " midLossyScaleX=" + FormatLossyScaleX(val2) + " tipLossyScaleX=" + FormatLossyScaleX(val3) + " " + $"chainLength={list.Count} links='{DescribeIkLinks(stringBuilder, val, val2, val3)}' " + "maxReach=" + FormatFloat(num) + " tipToTargetDistance=" + FormatFloat(value2) + " tipToTargetAngleDegrees=" + FormatFloat(value3) + " " + $"degenerate={degenerate}.")); } if (degenerate && warnOnDegenerate) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("[IkBakeProbe] degenerate_bake_input: " + $"frame={Time.frameCount} phase='{phase}' player='{playerDescription}' " + "kind='" + kind + "' path='" + text + "' smallestLink='" + text2 + "' smallestLinkDistance=" + FormatFloat(num2) + " smallestLossyScaleBone='" + minName + "' smallestLossyScaleComponent=" + FormatFloat(minComponent) + " threshold=" + FormatFloat(0.001f) + " rootLossyScale=" + FormatLossyScale(val) + " midLossyScale=" + FormatLossyScale(val2) + " tipLossyScale=" + FormatLossyScale(val3) + " impact='RigBuilder.Build() is about to bake these world-space link lengths, maxReach, and maintain-offset values permanently into the IK job arrays; they are never re-derived, so a collapsed bone here leaves this limb mispositioned in vanilla animation after the session ends'.")); } } return true; } catch (Exception ex) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[IkBakeProbe] constraint_unavailable: " + $"frame={Time.frameCount} phase='{phase}' player='{playerDescription}' " + "kind='" + kind + "' path='" + text + "' reason='read_failed:" + SanitizeLogValue(ex.Message) + "'.")); } return false; } } private static string DescribeIkLinks(StringBuilder links, Transform root, Transform mid, Transform tip) { if (links != null && links.Length > 0) { return links.ToString(); } if ((Object)(object)root == (Object)null || (Object)(object)tip == (Object)null) { return ""; } if (!((Object)(object)mid != (Object)null)) { return ""; } return ""; } private static List BuildIkBoneList(Transform root, Transform mid, Transform tip) { List list = new List(3); if ((Object)(object)root != (Object)null) { list.Add(root); } if ((Object)(object)mid != (Object)null) { list.Add(mid); } if ((Object)(object)tip != (Object)null) { list.Add(tip); } return list; } private static List ExtractIkChain(Transform root, Transform tip) { List list = new List(); if ((Object)(object)root == (Object)null || (Object)(object)tip == (Object)null) { return list; } Transform val = tip; int num = 0; while ((Object)(object)val != (Object)null && val != root && num++ < 64) { list.Add(val); val = val.parent; } if (val != root) { list.Clear(); return list; } list.Add(root); list.Reverse(); return list; } private static void TrackMinLossyScale(Transform transform, ref float minComponent, ref string minName) { //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_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform == (Object)null)) { Vector3 lossyScale = transform.lossyScale; float num = Mathf.Min(Mathf.Abs(lossyScale.x), Mathf.Min(Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z))); if (!(num >= minComponent)) { minComponent = num; minName = ((Object)transform).name; } } } private static string FormatLossyScaleX(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform != (Object)null)) { return ""; } return FormatFloat(transform.lossyScale.x); } private static string FormatLossyScale(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform != (Object)null)) { return ""; } return FormatVector(transform.lossyScale); } private static Transform ReadTransformMember(object instance, string propertyName, string fieldName) { object obj = ReadMember(instance, propertyName, fieldName); return (Transform)((obj is Transform) ? obj : null); } internal static void LogRigAnimatorStates(Animator animator, string checkpoint) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (!initialized || !ReadEnabled(enableRestoreRigStateLogger, fallback: false)) { return; } try { if ((Object)(object)animator == (Object)null) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam.rig] " + $"frame={Time.frameCount} checkpoint='{checkpoint}' animator=''.")); } return; } int num = Math.Max(0, animator.layerCount); string text = (((Object)(object)animator.runtimeAnimatorController != (Object)null) ? ((Object)animator.runtimeAnimatorController).name : ""); if (num == 0) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RestoreSeam.rig] " + $"frame={Time.frameCount} checkpoint='{checkpoint}' " + "controller='" + text + "' layerCount=0.")); } return; } for (int i = 0; i < num; i++) { AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(i); ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RestoreSeam.rig] " + $"frame={Time.frameCount} checkpoint='{checkpoint}' " + $"controller='{text}' layer={i} " + $"fullPathHash={((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash} " + "normalizedTime=" + ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime.ToString("R", CultureInfo.InvariantCulture) + ".")); } } } catch (Exception ex) { ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogWarning((object)("[RestoreSeam.rig] " + $"frame={Time.frameCount} checkpoint='{checkpoint}' error='{ex.Message}'.")); } } } internal static void LateUpdate() { if (!initialized) { return; } bool flag = ReadEnabled(enableRestoreSeamFrameLogger, fallback: false); bool flag2 = ReadEnabled(enablePristineRigDiffProbe, fallback: false); bool flag3 = PristineRigCaptureEnabled(); bool flag4 = ReadEnabled(enableRemoteRigDiffProbe, fallback: false); if (!flag && !flag3 && !flag4 && PendingRemoteRigProbes.Count == 0 && pendingIkBakeProbeLateUpdates <= 0) { return; } try { TickIkBakeProbe(); TickRemoteRigDiffProbes(flag4); if (!flag && !flag3) { return; } PlayerControllerB val = ResolveLocalPlayer(); if ((Object)(object)val == (Object)null) { if ((Object)(object)observedPlayer != (Object)null) { ObservePlayer(null); } return; } ObservePlayer(val); if (flag) { RestoreFrameSample sample = RestoreHistory[restoreHistoryNext]; CaptureRestoreFrame(val, sample); restoreHistoryNext = (restoreHistoryNext + 1) % 3; if (restoreHistoryCount < 3) { restoreHistoryCount++; } if (restoreFutureFramesRemaining > 0) { restoreFutureFrameIndex++; LogRestoreFrame(sample, "after+" + restoreFutureFrameIndex.ToString(CultureInfo.InvariantCulture)); restoreFutureFramesRemaining--; } } if (flag3 && !customAnimationHasRun && pristineRig == null) { TryCapturePristineRig(val); } if (flag2 && pendingRigDiffLateUpdates > 0) { pendingRigDiffLateUpdates--; if (pendingRigDiffLateUpdates == 0) { DumpRigDiff(val, "auto_restore_plus_2_lateupdates"); pendingRigDiffLateUpdates = -1; } } } catch (Exception ex) { if (!samplerFailureLogged) { samplerFailureLogged = true; ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("[RestoreSeam] diagnostics_late_update_failed: " + ex.Message)); } } } } private static void ObservePlayer(PlayerControllerB player) { if (observedPlayer != player) { observedPlayer = player; ClearRenderSessionTransforms(); pristineRig = null; customAnimationHasRun = false; pendingRigDiffLateUpdates = -1; IkBakeProbeAwakeLoggedPlayers.Clear(); ikBakeProbePlayer = null; pendingIkBakeProbeLateUpdates = -1; ResetRestoreHistory(); } } private static void ResetRestoreHistory() { restoreHistoryNext = 0; restoreHistoryCount = 0; restoreFutureFramesRemaining = 0; restoreFutureFrameIndex = 0; activeStopFrame = 0; activeStopInvocation = "consumer_call"; for (int i = 0; i < RestoreHistory.Length; i++) { RestoreHistory[i].Valid = false; } } private static void CacheRenderSessionTransforms(PlayerControllerB player) { renderSessionPlayer = player; renderSessionGameplayCamera = null; renderSessionCamera = null; renderSessionRightHand = null; renderSessionLeftHand = null; renderSessionArmsMetarig = null; renderSessionLocalArms = null; renderSessionLocalVisor = null; renderSessionLocalVisorTargetPoint = null; renderSessionVisorCamera = null; try { Camera val = (renderSessionGameplayCamera = (((Object)(object)player != (Object)null) ? player.gameplayCamera : null)); renderSessionCamera = (((Object)(object)val != (Object)null) ? ((Component)val).transform : null); renderSessionArmsMetarig = (((Object)(object)player != (Object)null) ? player.playerModelArmsMetarig : null); renderSessionLocalArms = (((Object)(object)player != (Object)null) ? player.localArmsTransform : null); renderSessionLocalVisor = (((Object)(object)player != (Object)null) ? player.localVisor : null); renderSessionLocalVisorTargetPoint = (((Object)(object)player != (Object)null) ? player.localVisorTargetPoint : null); renderSessionVisorCamera = (((Object)(object)player != (Object)null) ? player.visorCamera : null); renderSessionRightHand = FindChildRecursive(renderSessionArmsMetarig, "hand.R"); renderSessionLeftHand = FindChildRecursive(renderSessionArmsMetarig, "hand.L"); } catch { renderSessionGameplayCamera = null; renderSessionCamera = null; renderSessionRightHand = null; renderSessionLeftHand = null; renderSessionArmsMetarig = null; renderSessionLocalArms = null; renderSessionLocalVisor = null; renderSessionLocalVisorTargetPoint = null; renderSessionVisorCamera = null; } } private static void ClearRenderSessionTransforms() { renderSessionPlayer = null; renderSessionGameplayCamera = null; renderSessionCamera = null; renderSessionRightHand = null; renderSessionLeftHand = null; renderSessionArmsMetarig = null; renderSessionLocalArms = null; renderSessionLocalVisor = null; renderSessionLocalVisorTargetPoint = null; renderSessionVisorCamera = null; LatestRenderFrame.Reset(); PendingStartBeforeRenderFrame.Reset(); StartRenderSeam.Reset(); StopRenderSeam.Reset(); } private static void SubscribeRenderSampler() { //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_0038: Expected O, but got Unknown if (renderSamplerSubscribed || !initialized || !ReadEnabled(enableRestoreSeamFrameLogger, fallback: false)) { return; } try { object obj = <>O.<0>__LogRestoreRenderFrame; if (obj == null) { UnityAction val = LogRestoreRenderFrame; <>O.<0>__LogRestoreRenderFrame = val; obj = (object)val; } Application.onBeforeRender += (UnityAction)obj; renderSamplerSubscribed = true; } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("[RestoreSeam.render] subscribe_failed: " + ex.Message)); } UnsubscribeRenderSampler(); } } private static void LogRestoreRenderFrame() { if (!renderSamplerSubscribed) { return; } try { if (!initialized || !ReadEnabled(enableRestoreSeamFrameLogger, fallback: false)) { UnsubscribeRenderSampler(); return; } PlayerControllerB val = ResolveLocalPlayer(); if (!((Object)(object)val == (Object)null)) { if (renderSessionPlayer != val) { CacheRenderSessionTransforms(val); } CaptureRenderFrame(val, LatestRenderFrame); LogActiveRenderSeam(LatestRenderFrame, StartRenderSeam); LogActiveRenderSeam(LatestRenderFrame, StopRenderSeam); } } catch (Exception ex) { if (!samplerFailureLogged) { samplerFailureLogged = true; ManualLogSource obj = logger; if (obj != null) { obj.LogWarning((object)("[RestoreSeam.render] sample_failed: " + ex.Message)); } } } } private static void LogActiveRenderSeam(RenderSeamFrameSample sample, RenderSeamWindow seam) { if (!seam.Active || sample == null || !sample.Valid) { return; } if (sample.Frame > seam.EndFrame) { seam.Reset(); } else if (sample.Frame >= seam.SeamFrame && sample.Frame != seam.LastLoggedFrame) { seam.LastLoggedFrame = sample.Frame; int num = sample.Frame - seam.SeamFrame; LogRenderFrame(sample, seam, (num == 0) ? "seam+0" : ("after+" + num.ToString(CultureInfo.InvariantCulture)), captureAnimatedProp: true); if (sample.Frame >= seam.EndFrame) { seam.Reset(); } } } private static void UnsubscribeRenderSampler() { //IL_0017: 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: Expected O, but got Unknown if (renderSamplerSubscribed) { try { object obj = <>O.<0>__LogRestoreRenderFrame; if (obj == null) { UnityAction val = LogRestoreRenderFrame; <>O.<0>__LogRestoreRenderFrame = val; obj = (object)val; } Application.onBeforeRender -= (UnityAction)obj; } catch { } } renderSamplerSubscribed = false; StartRenderSeam.Reset(); StopRenderSeam.Reset(); } private static void CaptureRenderFrame(PlayerControllerB player, RenderSeamFrameSample sample) { if (sample == null) { return; } sample.Reset(); sample.Player = player; try { sample.Frame = Time.frameCount; } catch { } try { sample.DeltaTime = Time.deltaTime; } catch { } try { sample.UnscaledDeltaTime = Time.unscaledDeltaTime; } catch { } sample.GameplayCamera = CaptureRenderPose(renderSessionCamera); sample.RightHand = CaptureRenderPose(renderSessionRightHand); sample.LeftHand = CaptureRenderPose(renderSessionLeftHand); sample.ArmsMetarig = CaptureRenderPose(renderSessionArmsMetarig); sample.LocalArms = CaptureRenderPose(renderSessionLocalArms); sample.LocalVisor = CaptureRenderPose(renderSessionLocalVisor); sample.LocalVisorTargetPoint = CaptureRenderPose(renderSessionLocalVisorTargetPoint); sample.LocalVisorVisibility = CaptureRenderVisibility(((Object)(object)renderSessionLocalVisor != (Object)null) ? ((Component)renderSessionLocalVisor).gameObject : null); try { if ((Object)(object)renderSessionVisorCamera != (Object)null) { sample.VisorCameraPresent = true; sample.VisorCameraEnabled = ((Behaviour)renderSessionVisorCamera).enabled; } } catch { sample.VisorCameraPresent = false; } try { if ((Object)(object)renderSessionGameplayCamera != (Object)null) { sample.CameraParametersPresent = true; sample.CameraFieldOfView = renderSessionGameplayCamera.fieldOfView; sample.CameraNearClipPlane = renderSessionGameplayCamera.nearClipPlane; } } catch { sample.CameraParametersPresent = false; } GameObject root = null; try { GrabbableObject val = (((Object)(object)player != (Object)null) ? player.currentlyHeldObjectServer : null); root = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); } catch { } sample.HeldItem = CaptureRenderVisibility(root); sample.Valid = true; } private static RenderPoseSample CaptureRenderPose(Transform transform) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //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_0035: 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) RenderPoseSample result = default(RenderPoseSample); try { if ((Object)(object)transform == (Object)null) { return result; } result.Present = true; result.WorldPosition = transform.position; Quaternion rotation = transform.rotation; result.WorldEulerAngles = ((Quaternion)(ref rotation)).eulerAngles; } catch { result.Present = false; } return result; } private static RenderVisibilitySample CaptureRenderVisibility(GameObject root) { RenderVisibilitySample result = new RenderVisibilitySample { Name = "" }; try { if ((Object)(object)root == (Object)null) { return result; } result.Present = true; result.Name = ((Object)root).name ?? ""; result.ActiveInHierarchy = root.activeInHierarchy; RenderVisibilityBuffer.Clear(); root.GetComponentsInChildren(true, RenderVisibilityBuffer); result.RendererCount = RenderVisibilityBuffer.Count; for (int i = 0; i < RenderVisibilityBuffer.Count; i++) { Renderer val = RenderVisibilityBuffer[i]; if (!((Object)(object)val == (Object)null) && val.enabled) { result.EnabledRendererCount++; result.AnyRendererEnabled = true; } } } catch { result.ReadFailed = true; } return result; } private static void LogRenderFrame(RenderSeamFrameSample sample, RenderSeamWindow seam, string samplePhase, bool captureAnimatedProp) { if (sample == null || !sample.Valid || seam == null) { return; } try { RenderVisibilitySample sample2 = CaptureRenderVisibility(captureAnimatedProp ? seam.AnimatedProp : null); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam.render] " + $"phase={seam.Phase} frame={sample.Frame} seamFrame={seam.SeamFrame} " + "sample=" + samplePhase + " deltaTime=" + FormatRenderFloat(sample.DeltaTime) + " unscaledDeltaTime=" + FormatRenderFloat(sample.UnscaledDeltaTime) + " cameraWorldPos=" + FormatRenderPosition(sample.GameplayCamera) + " cameraWorldEuler=" + FormatRenderEuler(sample.GameplayCamera) + " cameraFov=" + FormatOptionalRenderFloat(sample.CameraParametersPresent, sample.CameraFieldOfView) + " cameraNearClip=" + FormatOptionalRenderFloat(sample.CameraParametersPresent, sample.CameraNearClipPlane) + " hand.RWorldPos=" + FormatRenderPosition(sample.RightHand) + " hand.RWorldEuler=" + FormatRenderEuler(sample.RightHand) + " hand.LWorldPos=" + FormatRenderPosition(sample.LeftHand) + " hand.LWorldEuler=" + FormatRenderEuler(sample.LeftHand) + " playerModelArmsMetarigWorldPos=" + FormatRenderPosition(sample.ArmsMetarig) + " playerModelArmsMetarigWorldEuler=" + FormatRenderEuler(sample.ArmsMetarig) + " localArmsTransformWorldPos=" + FormatRenderPosition(sample.LocalArms) + " localArmsTransformWorldEuler=" + FormatRenderEuler(sample.LocalArms) + " animatedProp=" + FormatRenderVisibility(sample2) + " heldItem=" + FormatRenderVisibility(sample.HeldItem) + " localVisorWorldPos=" + FormatRenderPosition(sample.LocalVisor) + " localVisorWorldEuler=" + FormatRenderEuler(sample.LocalVisor) + " localVisorTargetPointWorldPos=" + FormatRenderPosition(sample.LocalVisorTargetPoint) + " localVisorTargetPointWorldEuler=" + FormatRenderEuler(sample.LocalVisorTargetPoint) + " localVisorRenderers=" + FormatRenderVisibility(sample.LocalVisorVisibility) + " visorCameraEnabled=" + FormatOptionalRenderBool(sample.VisorCameraPresent, sample.VisorCameraEnabled) + ".")); } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("[RestoreSeam.render] log_failed: " + $"phase={seam.Phase} frame={sample.Frame} " + $"seamFrame={seam.SeamFrame} error='{ex.Message}'.")); } } } private static string FormatRenderPosition(RenderPoseSample sample) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!sample.Present) { return ""; } return FormatVector(sample.WorldPosition); } private static string FormatRenderEuler(RenderPoseSample sample) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!sample.Present) { return ""; } return FormatVector(sample.WorldEulerAngles); } private static string FormatRenderFloat(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private static string FormatOptionalRenderFloat(bool present, float value) { if (!present) { return ""; } return FormatRenderFloat(value); } private static string FormatOptionalRenderBool(bool present, bool value) { if (!present) { return ""; } return FormatRenderBool(value); } private static string FormatRenderVisibility(RenderVisibilitySample sample) { return "[present=" + FormatRenderBool(sample.Present) + " name='" + SanitizeRenderLogValue(sample.Name) + "' activeInHierarchy=" + FormatRenderBool(sample.ActiveInHierarchy) + " rendererCount=" + sample.RendererCount.ToString(CultureInfo.InvariantCulture) + " enabledRendererCount=" + sample.EnabledRendererCount.ToString(CultureInfo.InvariantCulture) + " anyRendererEnabled=" + FormatRenderBool(sample.AnyRendererEnabled) + " readFailed=" + FormatRenderBool(sample.ReadFailed) + "]"; } private static string FormatRenderBool(bool value) { if (!value) { return "false"; } return "true"; } private static string SanitizeRenderLogValue(string value) { if (!string.IsNullOrEmpty(value)) { return value.Replace('\r', ' ').Replace('\n', ' ').Replace('\'', '"'); } return ""; } private static void CaptureRestoreFrame(PlayerControllerB player, RestoreFrameSample sample) { //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_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_0029: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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) sample.Valid = false; sample.Frame = Time.frameCount; sample.GameplayCameraWorldPosition = Vector3.zero; sample.CameraContainerLocalPosition = Vector3.zero; sample.CameraContainerWorldPosition = Vector3.zero; sample.ArmsMetarigWorldPosition = Vector3.zero; sample.ControllerName = ""; sample.ActualLayerCount = 0; sample.CapturedLayerCount = 0; Camera gameplayCamera = player.gameplayCamera; Transform cameraContainerTransform = player.cameraContainerTransform; Transform playerModelArmsMetarig = player.playerModelArmsMetarig; Animator playerBodyAnimator = player.playerBodyAnimator; if ((Object)(object)gameplayCamera != (Object)null) { sample.GameplayCameraWorldPosition = ((Component)gameplayCamera).transform.position; } if ((Object)(object)cameraContainerTransform != (Object)null) { sample.CameraContainerLocalPosition = cameraContainerTransform.localPosition; sample.CameraContainerWorldPosition = cameraContainerTransform.position; } if ((Object)(object)playerModelArmsMetarig != (Object)null) { sample.ArmsMetarigWorldPosition = playerModelArmsMetarig.position; } if ((Object)(object)playerBodyAnimator != (Object)null) { RuntimeAnimatorController runtimeAnimatorController = playerBodyAnimator.runtimeAnimatorController; sample.ControllerName = (((Object)(object)runtimeAnimatorController != (Object)null) ? ((Object)runtimeAnimatorController).name : ""); sample.ActualLayerCount = Math.Max(0, playerBodyAnimator.layerCount); sample.CapturedLayerCount = Math.Min(sample.ActualLayerCount, sample.LayerStateHashes.Length); for (int i = 0; i < sample.CapturedLayerCount; i++) { AnimatorStateInfo currentAnimatorStateInfo = playerBodyAnimator.GetCurrentAnimatorStateInfo(i); sample.LayerStateHashes[i] = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash; sample.LayerNormalizedTimes[i] = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime; } } sample.Valid = true; } private static void LogRestoreFrame(RestoreFrameSample sample, string phase) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) if (sample == null || !sample.Valid) { return; } StringBuilder stringBuilder = new StringBuilder(128); stringBuilder.Append('['); for (int i = 0; i < sample.CapturedLayerCount; i++) { if (i > 0) { stringBuilder.Append(','); } stringBuilder.Append(i); stringBuilder.Append(':'); stringBuilder.Append(sample.LayerStateHashes[i]); stringBuilder.Append('@'); stringBuilder.Append(sample.LayerNormalizedTimes[i].ToString("R", CultureInfo.InvariantCulture)); } stringBuilder.Append(']'); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam] " + $"frame={sample.Frame} phase={phase} stopFrame={activeStopFrame} " + "stopInvocation='" + activeStopInvocation + "' gameplayCameraWorld=" + FormatVector(sample.GameplayCameraWorldPosition) + " cameraContainerLocal=" + FormatVector(sample.CameraContainerLocalPosition) + " cameraContainerWorld=" + FormatVector(sample.CameraContainerWorldPosition) + " armsMetarigWorld=" + FormatVector(sample.ArmsMetarigWorldPosition) + " controller='" + sample.ControllerName + "' " + $"layerCount={sample.ActualLayerCount} capturedLayers={sample.CapturedLayerCount} " + $"states={stringBuilder}.")); } } internal static void CapturePristineThirdPersonRigPoseAtPlayerAwake(PlayerControllerB player) { if (!initialized) { if (!playerAwakeCaptureUninitializedLogged) { playerAwakeCaptureUninitializedLogged = true; ManualLogSource staticLogger = StaticLogger; if (staticLogger != null) { staticLogger.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + "initialized=False source='player_awake_prefix_authored_default' reason='restore_diagnostics_not_initialized' action='skip'.")); } } } else { TryCapturePristineThirdPersonRigPose(player); } } internal static void CapturePristineCameraChainPoseAtPlayerAwake(PlayerControllerB player) { if (!initialized || (Object)(object)player == (Object)null || PristineCameraChainPoses.ContainsKey(player)) { return; } try { CameraChainPoseSnapshot cameraChainPoseSnapshot = CameraChainPoseSnapshot.Capture(player); if (cameraChainPoseSnapshot == null || cameraChainPoseSnapshot.Count == 0) { ManualLogSource staticLogger = StaticLogger; if (staticLogger != null) { staticLogger.LogInfo((object)("[RestoreSeam.camerachain] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + "source='player_awake_prefix_authored_default' reason='camera_chain_unavailable' action='use_session_entry_fallback'.")); } return; } PristineCameraChainPoses[player] = cameraChainPoseSnapshot; ManualLogSource staticLogger2 = StaticLogger; if (staticLogger2 != null) { staticLogger2.LogInfo((object)("[RestoreSeam.camerachain] pristine_captured: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + $"transforms={cameraChainPoseSnapshot.Count} missing='{cameraChainPoseSnapshot.MissingTargets}' " + cameraChainPoseSnapshot.DescribePositions() + " source='player_awake_prefix_authored_default'.")); } } catch (Exception ex) { ManualLogSource staticLogger3 = StaticLogger; if (staticLogger3 != null) { staticLogger3.LogInfo((object)("[RestoreSeam.camerachain] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + "source='player_awake_prefix_authored_default' reason='capture_failed:" + SanitizeLogValue(ex.Message) + "' action='use_session_entry_fallback'.")); } } } internal static bool TryRestorePristineCameraChainPositions(PlayerControllerB player, out int restored, out string reason, out string source) { restored = 0; reason = string.Empty; source = "player_awake_prefix_authored_default"; if ((Object)(object)player == (Object)null) { reason = "player_missing"; return false; } if (!PristineCameraChainPoses.TryGetValue(player, out var value) || value == null) { reason = "pristine_baseline_unavailable"; return false; } source = value.Source; restored = value.RestorePositions(); if (restored == 0) { reason = "no_transforms_restored"; return false; } return true; } internal static bool TryRefineCameraChainRestBaseline(PlayerControllerB player, out string reason) { reason = string.Empty; if ((Object)(object)player == (Object)null) { reason = "player_missing"; return false; } if (!PristineCameraChainPoses.TryGetValue(player, out var value) || value == null) { reason = "pristine_baseline_unavailable"; return false; } if (string.Equals(value.Source, "session_entry_runtime_settled", StringComparison.Ordinal)) { reason = "already_refined"; return false; } string text = value.DescribePositions(); if (!value.RefinePositions("session_entry_runtime_settled")) { reason = "no_transforms_refined"; return false; } ManualLogSource staticLogger = StaticLogger; if (staticLogger != null) { staticLogger.LogInfo((object)("[RestoreSeam.camerachain] rest_baseline_refined: " + $"frame={Time.frameCount} player='{DescribePlayer(player)}' " + "before[" + text + "] after[" + value.DescribePositions() + "] source='session_entry_runtime_settled'.")); } return true; } private static void LogPristineThirdPersonRigPoseAvailability(PlayerControllerB player) { bool num = ReadEnabled(restorePristineThirdPersonRigControlPose, fallback: true); bool flag = IsLocalPlayer(player); string arg = DescribePlayer(player); if (!num) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + $"localPlayer={flag} enabled=False " + "reason='kill_switch_disabled' action='use_equip_fallback'.")); } } else if ((Object)(object)player == (Object)null) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='' localPlayer=False enabled=True " + "reason='player_missing' action='use_equip_fallback'.")); } } else if (PristineThirdPersonRigPoses.ContainsKey(player)) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + $"localPlayer={flag} enabled=True " + "reason='already_captured' baseline_contaminated=False source='player_awake_prefix_authored_default' action='keep_pristine'.")); } } else { ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + $"localPlayer={flag} enabled=True baseline_contaminated=True " + "reason='authored_default_capture_unavailable' action='use_equip_fallback'.")); } } } private static void TryCapturePristineThirdPersonRigPose(PlayerControllerB player) { bool num = ReadEnabled(restorePristineThirdPersonRigControlPose, fallback: true); bool flag = IsLocalPlayer(player); string arg = DescribePlayer(player); if (!num) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + string.Format("localPlayer={0} enabled=False source='{1}' ", flag, "player_awake_prefix_authored_default") + "reason='kill_switch_disabled' action='use_equip_fallback'.")); } return; } if ((Object)(object)player == (Object)null) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='' localPlayer=False enabled=True " + "source='player_awake_prefix_authored_default' reason='player_missing' action='skip'.")); } return; } if (PristineThirdPersonRigPoses.ContainsKey(player)) { ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + string.Format("localPlayer={0} enabled=True source='{1}' ", flag, "player_awake_prefix_authored_default") + "reason='already_captured' baseline_contaminated=False action='keep_pristine'.")); } return; } try { ThirdPersonRigPoseSnapshot thirdPersonRigPoseSnapshot = ThirdPersonRigPoseSnapshot.Capture(player); if (thirdPersonRigPoseSnapshot == null || thirdPersonRigPoseSnapshot.TotalCount == 0) { ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + string.Format("localPlayer={0} enabled=True source='{1}' ", flag, "player_awake_prefix_authored_default") + "reason='third_person_rig_unavailable' baseline_contaminated=True action='use_equip_fallback'.")); } return; } ThirdPersonRigPlausibility thirdPersonRigPlausibility = thirdPersonRigPoseSnapshot.EvaluateVanillaRestPlausibility(); string text = (thirdPersonRigPlausibility.Plausible ? "accept_authored_default" : "accept_authored_default_pending_runtime_recapture"); ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_sanity: " + $"frame={Time.frameCount} player='{arg}' " + string.Format("localPlayer={0} enabled=True source='{1}' ", flag, "player_awake_prefix_authored_default") + $"plausibleAgainstVanillaRest={thirdPersonRigPlausibility.Plausible} " + $"complete={thirdPersonRigPoseSnapshot.IsComplete} missing='{thirdPersonRigPoseSnapshot.MissingTargets}' " + $"positionOutliers={thirdPersonRigPlausibility.PositionOutliers} " + $"rotationOutliers={thirdPersonRigPlausibility.RotationOutliers} " + $"scaleOutliers={thirdPersonRigPlausibility.ScaleOutliers} " + "maxPositionDelta=" + FormatFloat(thirdPersonRigPlausibility.MaxPositionDelta) + " maxRotationDeltaDegrees=" + FormatFloat(thirdPersonRigPlausibility.MaxRotationDeltaDegrees) + " maxScaleDelta=" + FormatFloat(thirdPersonRigPlausibility.MaxScaleDelta) + " positionThreshold=" + FormatFloat(0.05f) + " rotationThresholdDegrees=" + FormatFloat(8f) + " scaleThreshold=" + FormatFloat(0.01f) + " reason='" + thirdPersonRigPlausibility.Reason + "' action='" + text + "'.")); } thirdPersonRigPoseSnapshot.SetCaptureMetadata(thirdPersonRigPlausibility.Plausible, "player_awake_prefix_authored_default"); PristineThirdPersonRigPoses[player] = thirdPersonRigPoseSnapshot; ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogInfo((object)("[RestoreSeam.tprig] pristine_captured: " + $"frame={Time.frameCount} player='{arg}' " + $"localPlayer={flag} enabled=True baseline_contaminated=False " + $"complete={thirdPersonRigPoseSnapshot.IsComplete} missing='{thirdPersonRigPoseSnapshot.MissingTargets}' " + $"fullPoseTransforms={thirdPersonRigPoseSnapshot.FullPoseCount} " + $"rotationOnlyTransforms={thirdPersonRigPoseSnapshot.RotationOnlyCount} " + $"plausibleAgainstVanillaRest={thirdPersonRigPlausibility.Plausible} " + "source='player_awake_prefix_authored_default'.")); } } catch (Exception ex) { ManualLogSource obj7 = logger; if (obj7 != null) { obj7.LogInfo((object)("[RestoreSeam.tprig] pristine_capture_skipped: " + $"frame={Time.frameCount} player='{arg}' " + string.Format("localPlayer={0} enabled=True source='{1}' ", flag, "player_awake_prefix_authored_default") + "reason='capture_failed:" + SanitizeLogValue(ex.Message) + "' action='use_equip_fallback'.")); } } } private static void TryCapturePristineRig(PlayerControllerB player) { if (pristineRig != null || customAnimationHasRun || !IsLocalPlayer(player)) { return; } try { Transform playerModelArmsMetarig = player.playerModelArmsMetarig; Transform val = FindChildRecursive(playerModelArmsMetarig, "RigArms"); if (!((Object)(object)playerModelArmsMetarig == (Object)null) && !((Object)(object)val == (Object)null)) { pristineRig = PristineRigSnapshot.Capture(player, playerModelArmsMetarig, val, ResolveTwoBoneIkConstraintType(), ResolveChainIkConstraintType()); ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RigDiff] pristine_captured: " + $"frame={Time.frameCount} transforms={pristineRig.Transforms.Length} " + $"twoBoneIkConstraints={pristineRig.TwoBoneConstraints.Length} " + $"chainIkConstraints={pristineRig.ChainConstraints.Length} " + $"rigs={pristineRig.Rigs.Length} rigLayers={pristineRig.RigLayers.Length} " + "metarig='" + ((Object)playerModelArmsMetarig).name + "' rigArms='" + ((Object)val).name + "'.")); } } } catch (Exception ex) { ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)("[RigDiff] pristine_capture_failed: " + ex.Message)); } } } private static Type ResolveTwoBoneIkConstraintType() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { Type type = assemblies[i].GetType("UnityEngine.Animations.Rigging.TwoBoneIKConstraint", throwOnError: false, ignoreCase: false); if (type != null) { return type; } } catch { } } if (!twoBoneIkTypeUnavailableLogged) { twoBoneIkTypeUnavailableLogged = true; ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)"[RigDiff] two_bone_ik_type_unavailable: type='UnityEngine.Animations.Rigging.TwoBoneIKConstraint' constraint-field capture disabled."); } } return null; } private static Type ResolveChainIkConstraintType() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { Type type = assemblies[i].GetType("UnityEngine.Animations.Rigging.ChainIKConstraint", throwOnError: false, ignoreCase: false); if (type != null) { return type; } } catch { } } if (!chainIkTypeUnavailableLogged) { chainIkTypeUnavailableLogged = true; ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogWarning((object)"[RigDiff] chain_ik_type_unavailable: type='UnityEngine.Animations.Rigging.ChainIKConstraint' constraint-field capture disabled."); } } return null; } private static void DumpRigDiff(PlayerControllerB player, string reason) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_023b: Unknown result type (might be due to invalid IL or missing references) if (pristineRig == null || (Object)(object)player == (Object)null || pristineRig.Player != player) { ManualLogSource obj = logger; if (obj != null) { obj.LogInfo((object)("[RigDiff] dump_unavailable: " + $"frame={Time.frameCount} reason='{reason}' pristineCaptured=False.")); } return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; ManualLogSource obj2 = logger; if (obj2 != null) { obj2.LogInfo((object)("[RigDiff] dump_begin: " + $"frame={Time.frameCount} reason='{reason}' " + "positionThreshold=" + 0.0005f.ToString("R", CultureInfo.InvariantCulture) + " rotationThresholdDegrees=" + 0.05f.ToString("R", CultureInfo.InvariantCulture) + ".")); } for (int i = 0; i < pristineRig.Transforms.Length; i++) { TransformBaseline transformBaseline = pristineRig.Transforms[i]; Transform transform = transformBaseline.Transform; if ((Object)(object)transform == (Object)null) { num++; ManualLogSource obj3 = logger; if (obj3 != null) { obj3.LogInfo((object)("[RigDiff] transform_missing: " + $"frame={Time.frameCount} reason='{reason}' path='{transformBaseline.Path}'.")); } continue; } Vector3 value = transform.localPosition - transformBaseline.LocalPosition; float magnitude = ((Vector3)(ref value)).magnitude; float num5 = Quaternion.Angle(transformBaseline.LocalRotation, transform.localRotation); if (!(magnitude <= 0.0005f) || !(num5 <= 0.05f)) { num++; Vector3 value2 = transform.localScale - transformBaseline.LocalScale; ManualLogSource obj4 = logger; if (obj4 != null) { obj4.LogInfo((object)("[RigDiff] transform_changed: " + $"frame={Time.frameCount} reason='{reason}' path='{transformBaseline.Path}' " + "localPositionDelta=" + FormatVector(value) + " positionDeltaMagnitude=" + magnitude.ToString("R", CultureInfo.InvariantCulture) + " rotationDeltaDegrees=" + num5.ToString("R", CultureInfo.InvariantCulture) + " localScaleDelta=" + FormatVector(value2) + ".")); } } } for (int j = 0; j < pristineRig.TwoBoneConstraints.Length; j++) { TwoBoneIkBaseline twoBoneIkBaseline = pristineRig.TwoBoneConstraints[j]; if (!twoBoneIkBaseline.TryReadCurrent(out var current)) { num2++; ManualLogSource obj5 = logger; if (obj5 != null) { obj5.LogInfo((object)("[RigDiff] constraint_missing: " + $"frame={Time.frameCount} reason='{reason}' path='{twoBoneIkBaseline.Path}'.")); } } else if (!twoBoneIkBaseline.Values.Equals(current)) { num2++; ManualLogSource obj6 = logger; if (obj6 != null) { obj6.LogInfo((object)("[RigDiff] constraint_changed: " + $"frame={Time.frameCount} reason='{reason}' path='{twoBoneIkBaseline.Path}' " + "target='" + twoBoneIkBaseline.Values.TargetName + "'->'" + current.TargetName + "' hint='" + twoBoneIkBaseline.Values.HintName + "'->'" + current.HintName + "' weight=" + FormatDelta(twoBoneIkBaseline.Values.Weight, current.Weight) + " targetPositionWeight=" + FormatDelta(twoBoneIkBaseline.Values.TargetPositionWeight, current.TargetPositionWeight) + " targetRotationWeight=" + FormatDelta(twoBoneIkBaseline.Values.TargetRotationWeight, current.TargetRotationWeight) + " hintWeight=" + FormatDelta(twoBoneIkBaseline.Values.HintWeight, current.HintWeight) + " " + $"maintainTargetPositionOffset={twoBoneIkBaseline.Values.MaintainTargetPositionOffset}->{current.MaintainTargetPositionOffset} " + $"maintainTargetRotationOffset={twoBoneIkBaseline.Values.MaintainTargetRotationOffset}->{current.MaintainTargetRotationOffset}.")); } } } for (int k = 0; k < pristineRig.ChainConstraints.Length; k++) { ChainIkBaseline chainIkBaseline = pristineRig.ChainConstraints[k]; if (!chainIkBaseline.TryReadCurrent(out var current2)) { num2++; ManualLogSource obj7 = logger; if (obj7 != null) { obj7.LogInfo((object)("[RigDiff] chain_constraint_missing: " + $"frame={Time.frameCount} reason='{reason}' path='{chainIkBaseline.Path}'.")); } } else if (!chainIkBaseline.Values.Equals(current2)) { num2++; ManualLogSource obj8 = logger; if (obj8 != null) { obj8.LogInfo((object)("[RigDiff] chain_constraint_changed: " + $"frame={Time.frameCount} reason='{reason}' path='{chainIkBaseline.Path}' " + "root='" + chainIkBaseline.Values.RootName + "'->'" + current2.RootName + "' tip='" + chainIkBaseline.Values.TipName + "'->'" + current2.TipName + "' target='" + chainIkBaseline.Values.TargetName + "'->'" + current2.TargetName + "' weight=" + FormatDelta(chainIkBaseline.Values.Weight, current2.Weight) + " chainRotationWeight=" + FormatDelta(chainIkBaseline.Values.ChainRotationWeight, current2.ChainRotationWeight) + " tipRotationWeight=" + FormatDelta(chainIkBaseline.Values.TipRotationWeight, current2.TipRotationWeight) + " " + $"maxIterations={chainIkBaseline.Values.MaxIterations}->{current2.MaxIterations} " + "tolerance=" + FormatDelta(chainIkBaseline.Values.Tolerance, current2.Tolerance) + " " + $"maintainTargetPositionOffset={chainIkBaseline.Values.MaintainTargetPositionOffset}->{current2.MaintainTargetPositionOffset} " + $"maintainTargetRotationOffset={chainIkBaseline.Values.MaintainTargetRotationOffset}->{current2.MaintainTargetRotationOffset}.")); } } } for (int l = 0; l < pristineRig.Rigs.Length; l++) { RigWeightBaseline rigWeightBaseline = pristineRig.Rigs[l]; if (!rigWeightBaseline.TryReadCurrent(out var currentWeight)) { num3++; ManualLogSource obj9 = logger; if (obj9 != null) { obj9.LogInfo((object)("[RigDiff] rig_missing: " + $"frame={Time.frameCount} reason='{reason}' path='{rigWeightBaseline.Path}'.")); } } else if (!rigWeightBaseline.Weight.Equals(currentWeight)) { num3++; ManualLogSource obj10 = logger; if (obj10 != null) { obj10.LogInfo((object)("[RigDiff] rig_changed: " + $"frame={Time.frameCount} reason='{reason}' path='{rigWeightBaseline.Path}' " + "weight=" + FormatDelta(rigWeightBaseline.Weight, currentWeight) + ".")); } } } for (int m = 0; m < pristineRig.RigLayers.Length; m++) { RigLayerBaseline rigLayerBaseline = pristineRig.RigLayers[m]; if (!rigLayerBaseline.TryReadCurrent(out var current3)) { num4++; ManualLogSource obj11 = logger; if (obj11 != null) { obj11.LogInfo((object)("[RigDiff] rig_layer_missing: " + $"frame={Time.frameCount} reason='{reason}' path='{rigLayerBaseline.Path}'.")); } } else if (!rigLayerBaseline.Values.Equals(current3)) { num4++; ManualLogSource obj12 = logger; if (obj12 != null) { obj12.LogInfo((object)("[RigDiff] rig_layer_changed: " + $"frame={Time.frameCount} reason='{reason}' path='{rigLayerBaseline.Path}' " + "rig='" + rigLayerBaseline.Values.RigName + "'->'" + current3.RigName + "' " + $"active={rigLayerBaseline.Values.Active}->{current3.Active} " + "weight=" + FormatDelta(rigLayerBaseline.Values.Weight, current3.Weight) + ".")); } } } ManualLogSource obj13 = logger; if (obj13 != null) { obj13.LogInfo((object)("[RigDiff] dump_end: " + $"frame={Time.frameCount} reason='{reason}' " + $"transformChanges={num} constraintChanges={num2} " + $"rigChanges={num3} rigLayerChanges={num4}.")); } } private static bool IsLocalPlayer(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } try { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null && (Object)(object)StartOfRound.Instance != (Object)null) { val = StartOfRound.Instance.localPlayerController; } return player == val; } catch { return false; } } private static PlayerControllerB ResolveLocalPlayer() { try { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null && (Object)(object)StartOfRound.Instance != (Object)null) { val = StartOfRound.Instance.localPlayerController; } return val; } catch { return null; } } private static Transform FindChildRecursive(Transform root, string childName) { if ((Object)(object)root == (Object)null) { return null; } if (string.Equals(((Object)root).name, childName, StringComparison.Ordinal)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildRecursive(root.GetChild(i), childName); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Transform FindDirectChild(Transform parent, string childName) { if ((Object)(object)parent == (Object)null) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child != (Object)null && string.Equals(((Object)child).name, childName, StringComparison.Ordinal)) { return child; } } return null; } private static string GetRelativePath(Transform root, Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } if ((Object)(object)root == (Object)null || root == transform) { return ((Object)transform).name; } List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null && val != root) { list.Add(((Object)val).name); val = val.parent; } if (val == root) { list.Add(((Object)root).name); } list.Reverse(); return string.Join("/", list); } private static bool ReadEnabled(ConfigEntry entry, bool fallback) { try { return entry?.Value ?? fallback; } catch { return fallback; } } private static bool PristineRigCaptureEnabled() { if (!ReadEnabled(enablePristineRigDiffProbe, fallback: false)) { return ReadEnabled(restorePristineRigControlPose, fallback: true); } return true; } private static string FormatVector(Vector3 value) { return "(" + value.x.ToString("R", CultureInfo.InvariantCulture) + "," + value.y.ToString("R", CultureInfo.InvariantCulture) + "," + value.z.ToString("R", CultureInfo.InvariantCulture) + ")"; } private static string FormatQuaternion(Quaternion value) { return "(" + value.x.ToString("R", CultureInfo.InvariantCulture) + "," + value.y.ToString("R", CultureInfo.InvariantCulture) + "," + value.z.ToString("R", CultureInfo.InvariantCulture) + "," + value.w.ToString("R", CultureInfo.InvariantCulture) + ")"; } private static string FormatFloat(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private static string DescribePlayer(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return ""; } try { return SanitizeLogValue(string.IsNullOrWhiteSpace(player.playerUsername) ? ((Object)player).name : player.playerUsername) + " (clientId=" + player.actualClientId.ToString(CultureInfo.InvariantCulture) + ")"; } catch { return ""; } } private static string SanitizeLogValue(string value) { if (!string.IsNullOrEmpty(value)) { return value.Replace('\r', ' ').Replace('\n', ' ').Replace('\'', '"'); } return ""; } private static string FormatDelta(float before, float after) { return before.ToString("R", CultureInfo.InvariantCulture) + "->" + after.ToString("R", CultureInfo.InvariantCulture) + " delta=" + (after - before).ToString("R", CultureInfo.InvariantCulture); } private static object ReadMember(object instance, string propertyName, string fieldName) { if (instance == null) { return null; } Type type = instance.GetType(); FieldInfo fieldInfo = FindField(type, fieldName); if (fieldInfo != null) { try { return fieldInfo.GetValue(instance); } catch { } } if (!string.IsNullOrWhiteSpace(propertyName)) { try { PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(instance, null); } } catch { } } return null; } private static FieldInfo FindField(Type type, string fieldName) { while (type != null) { FieldInfo field = type.GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type = type.BaseType; } return null; } private static float ReadFloat(object instance, string propertyName, string fieldName) { object obj = ReadMember(instance, propertyName, fieldName); try { return (obj != null) ? Convert.ToSingle(obj, CultureInfo.InvariantCulture) : float.NaN; } catch { return float.NaN; } } private static int ReadInt(object instance, string propertyName, string fieldName) { object obj = ReadMember(instance, propertyName, fieldName); try { return (obj != null) ? Convert.ToInt32(obj, CultureInfo.InvariantCulture) : int.MinValue; } catch { return int.MinValue; } } private static bool ReadBool(object instance, string propertyName, string fieldName) { object obj = ReadMember(instance, propertyName, fieldName); try { return obj != null && Convert.ToBoolean(obj, CultureInfo.InvariantCulture); } catch { return false; } } private static string ReadObjectName(object instance, string propertyName, string fieldName) { object obj = ReadMember(instance, propertyName, fieldName); Object val = (Object)((obj is Object) ? obj : null); if (!(val != (Object)null)) { return ""; } return val.name; } } [DefaultExecutionOrder(32000)] internal sealed class InteractionAnimationRestoreDiagnosticsRunner : MonoBehaviour { private void LateUpdate() { InteractionAnimationApiRestoreDiagnostics.LateUpdate(); } } [HarmonyPatch(typeof(PlayerControllerB), "Awake")] internal static class InteractionAnimationAuthoredThirdPersonRigCapturePatch { [HarmonyPrefix] [HarmonyPriority(800)] private static void CaptureBeforePlayerScriptsRun(PlayerControllerB __instance) { InteractionAnimationApiRestoreDiagnostics.CapturePristineThirdPersonRigPoseAtPlayerAwake(__instance); InteractionAnimationApiRestoreDiagnostics.CapturePristineCameraChainPoseAtPlayerAwake(__instance); InteractionAnimationApiRestoreDiagnostics.LogIkBakeProbeAtPlayerAwake(__instance); } } } namespace Y4NGZInteractions.InteractionAnimationApi.Presenters { internal interface IInteractionPresenter { InteractionAnimationStopReason? RequestedStopReason { get; } bool HasResourceOwnership { get; } bool TryPreflight(InteractionAnimationContext context, out string reason); bool TryStart(InteractionAnimationContext context, out string reason); void Tick(float deltaTime); void Stop(InteractionAnimationStopReason stopReason); float BeginExit(); bool TrySetAnimatorParameter(string parameterName, AnimatorControllerParameterType parameterType, float value); } internal sealed class LiveBodyAnimatorPresenter : IInteractionPresenter { private readonly struct LocomotionState { internal bool Walking { get; } internal bool Sprinting { get; } internal bool Crouching { get; } internal bool Jumping { get; } internal bool JumpingKnown { get; } internal float HorizontalSpeed { get; } internal string Source { get; } internal LocomotionState(bool walking, bool sprinting, bool crouching, bool jumping, bool jumpingKnown, float horizontalSpeed, string source) { Walking = walking; Sprinting = sprinting; Crouching = crouching; Jumping = jumping; JumpingKnown = jumpingKnown; HorizontalSpeed = horizontalSpeed; Source = source; } } private sealed class ExternalCameraRendererProbe { internal Renderer Renderer { get; } internal string Role { get; } internal string Path { get; } internal int InstanceId { get; } internal ExternalCameraRendererProbe(Renderer renderer, string role, string path) { Renderer = renderer; Role = role; Path = path; InstanceId = (((Object)(object)renderer != (Object)null) ? ((Object)renderer).GetInstanceID() : 0); } } private struct ExternalCameraRendererState { internal bool Present; internal bool ActiveInHierarchy; internal bool Enabled; internal bool ForceRenderingOff; internal bool IsVisible; internal int Layer; internal ShadowCastingMode ShadowCastingMode; internal bool CameraDrawsLayer; internal bool RenderEligible; internal bool ReadFailed; internal int Signature => (((((((((Present ? 1 : 0) * 31 + (ActiveInHierarchy ? 1 : 0)) * 31 + (Enabled ? 1 : 0)) * 31 + (ForceRenderingOff ? 1 : 0)) * 31 + (IsVisible ? 1 : 0)) * 31 + Layer) * 31 + ShadowCastingMode) * 31 + CameraDrawsLayer) * 31 + RenderEligible) * 31 + ReadFailed; } private sealed class SeamPhaseStopwatch { private readonly Stopwatch stopwatch = Stopwatch.StartNew(); private long previousElapsedTicks; internal double TotalMilliseconds => stopwatch.Elapsed.TotalMilliseconds; internal double LapMilliseconds() { long elapsedTicks = stopwatch.ElapsedTicks; long num = elapsedTicks - previousElapsedTicks; previousElapsedTicks = elapsedTicks; return (double)num * 1000.0 / (double)Stopwatch.Frequency; } } private readonly struct CameraRotationSnapshot { internal Transform GameplayCameraTransform { get; } internal Quaternion GameplayCameraLocalRotation { get; } internal bool GameplayCameraCaptured { get; } internal Transform CameraContainerTransform { get; } internal Quaternion CameraContainerLocalRotation { get; } internal bool CameraContainerCaptured { get; } internal bool HasAnyRotation { get { if (!GameplayCameraCaptured) { return CameraContainerCaptured; } return true; } } internal CameraRotationSnapshot(Transform gameplayCameraTransform, Quaternion gameplayCameraLocalRotation, bool gameplayCameraCaptured, Transform cameraContainerTransform, Quaternion cameraContainerLocalRotation, bool cameraContainerCaptured) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_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) GameplayCameraTransform = gameplayCameraTransform; GameplayCameraLocalRotation = gameplayCameraLocalRotation; GameplayCameraCaptured = gameplayCameraCaptured; CameraContainerTransform = cameraContainerTransform; CameraContainerLocalRotation = cameraContainerLocalRotation; CameraContainerCaptured = cameraContainerCaptured; } } private readonly struct VisorPoseSnapshot { internal SeamTransformPose LocalVisor { get; } internal SeamTransformPose LocalVisorTargetPoint { get; } internal bool HasAnyPose { get { if (!LocalVisor.Captured) { return LocalVisorTargetPoint.Captured; } return true; } } internal bool HasAnyRestoreEligiblePose { get { if (!LocalVisor.Captured || !LocalVisor.UnderAnimatorHierarchy) { if (LocalVisorTargetPoint.Captured) { return LocalVisorTargetPoint.UnderAnimatorHierarchy; } return false; } return true; } } internal VisorPoseSnapshot(SeamTransformPose localVisor, SeamTransformPose localVisorTargetPoint) { LocalVisor = localVisor; LocalVisorTargetPoint = localVisorTargetPoint; } } private readonly struct SeamTransformPose { internal Transform Transform { get; } internal Vector3 LocalPosition { get; } internal Quaternion LocalRotation { get; } internal Vector3 LocalScale { get; } internal Vector3 WorldPosition { get; } internal Quaternion WorldRotation { get; } internal Vector3 WorldScale { get; } internal bool UnderAnimatorHierarchy { get; } internal bool Captured { get; } internal SeamTransformPose(Transform transform, bool underAnimatorHierarchy) { //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_0015: 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) //IL_0021: 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_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_0039: 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_0045: 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) Transform = transform; LocalPosition = transform.localPosition; LocalRotation = transform.localRotation; LocalScale = transform.localScale; WorldPosition = transform.position; WorldRotation = transform.rotation; WorldScale = transform.lossyScale; UnderAnimatorHierarchy = underAnimatorHierarchy; Captured = true; } } private readonly struct RigBuilderState { private readonly Behaviour behaviour; internal RigBuilderState(Behaviour behaviour) { this.behaviour = behaviour; } internal void Restore() { if ((Object)(object)behaviour != (Object)null) { behaviour.enabled = true; } } } private sealed class TransformPoseSnapshot { private readonly TransformPose[] poses; internal int Count => poses.Length; private TransformPoseSnapshot(TransformPose[] poses) { this.poses = poses ?? Array.Empty(); } internal static TransformPoseSnapshot CaptureDescendants(Transform root) { return Capture(root, includeRoot: false); } internal static TransformPoseSnapshot CaptureSubtree(Transform root) { return Capture(root, includeRoot: true); } private static TransformPoseSnapshot Capture(Transform root, bool includeRoot) { if ((Object)(object)root == (Object)null) { return new TransformPoseSnapshot(Array.Empty()); } Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); List list = new List(includeRoot ? componentsInChildren.Length : Math.Max(0, componentsInChildren.Length - 1)); foreach (Transform val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && (includeRoot || !((Object)(object)val == (Object)(object)root))) { list.Add(new TransformPose(val)); } } return new TransformPoseSnapshot(list.ToArray()); } internal int Restore() { int num = 0; for (int i = 0; i < poses.Length; i++) { if (poses[i].Restore()) { num++; } } return num; } internal int RestoreExcept(ISet excludedTransforms) { int num = 0; for (int i = 0; i < poses.Length; i++) { Transform transform = poses[i].Transform; if ((excludedTransforms == null || !excludedTransforms.Contains(transform)) && poses[i].Restore()) { num++; } } return num; } } private readonly struct TransformPose { private readonly Transform transform; private readonly Vector3 localPosition; private readonly Quaternion localRotation; private readonly Vector3 localScale; internal Transform Transform => transform; internal TransformPose(Transform transform) { //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_0015: 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) //IL_0021: 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) this.transform = transform; localPosition = transform.localPosition; localRotation = transform.localRotation; localScale = transform.localScale; } internal bool Restore() { //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_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return false; } transform.localPosition = localPosition; transform.localRotation = localRotation; transform.localScale = localScale; return true; } } private const float CameraDisplacementGuardThreshold = 1.25f; private const float CameraRotationResidueThresholdDegrees = 0.02f; private const float CameraDriftHealThresholdMeters = 0.02f; private const float VanillaCameraCrouchedPlayerLocalRestHeight = 1.17f; private const float StanceViewpointHeightToleranceMeters = 0.15f; private const double PlaybackRateSampleIntervalSeconds = 1.0; private const double PlaybackRateMinimumSampleSeconds = 0.05; private const float StanceViewpointMismatchSecondsRequired = 0.5f; private const int CameraBaselineDeferralFrames = 4; private const float RemoteWalkEnterSpeed = 0.35f; private const float RemoteWalkExitSpeed = 0.15f; private const float RemoteSprintEnterSpeed = 5.5f; private const float RemoteSprintExitSpeed = 4.5f; private const float RemoteSpeedSmoothingPerSecond = 12f; private const string VanillaStartCrouchingTrigger = "startCrouching"; private const string VanillaCrouchingBool = "crouching"; private const string CameraDisplacementGuardBaselineSource = "try_start_pre_controller"; private static readonly Vector3 VanillaCameraPlayerLocalRestExpectation = new Vector3(0f, 2.35f, 0.01f); private static readonly Vector3 VanillaCameraContainerLocalRestEuler = new Vector3(90f, 359.8182f, 0f); private static readonly HashSet RetainedBundles = new HashSet(); private static bool visorHierarchyLogged; private readonly List suppressedRigBuilders = new List(); private readonly List externalCameraRendererProbes = new List(); private InteractionAnimationContext context; private Animator bodyAnimator; private AssetBundle bundle; private bool ownsBundle; private AssetBundle clipPackBundle; private bool ownsClipPackBundle; private RuntimeAnimatorController appliedController; private AnimatorStateSnapshot snapshot; private TransformPoseSnapshot rigControlPoseSnapshot; private Transform rigControlRoot; private InteractionAnimationApiRestoreDiagnostics.ThirdPersonRigPoseSnapshot thirdPersonRigControlPoseSnapshot; private TransformPoseSnapshot scopedFirstPersonPoseSnapshot; private bool rigEvaluateMethodMissingLogged; private int fullBodyLayerIndex = -1; private int firstPersonLayerIndex = -1; private float elapsedSeconds; private float nextDiagnosticsAtSeconds; private float nextTransformChainDiagnosticsAtSeconds; private int lastTransformChainDiagnosticsFrame = -1; private bool transformChainDiagnosticsSubscribed; private bool externalCameraPresentationDiagnosticsSubscribed; private int lastExternalCameraPresentationFrame = -1; private int lastExternalCameraPresentationSignature; private bool hasExternalCameraPresentationSignature; private bool externalCameraPresentationSampleFailureLogged; private bool visorHardGlueSubscribed; private Transform visorHardGlueVisor; private Transform visorHardGlueTarget; private bool visorHardGlueAppliedLogged; private bool visorHardGlueParkedLogged; private Transform rightArmIkTarget; private Transform leftArmIkTarget; private Transform rightHandBone; private Transform rightShoulderBone; private GameObject propInstance; private bool propReleased; private bool exitRequested; private float exitElapsedSeconds; private float exitDurationSeconds; private float exitStartFullBodyWeight; private float exitStartFirstPersonWeight; private int lastMovementValue = -1; private bool playbackRateHasBaseline; private int playbackRateLayerIndex = -1; private int playbackRateFullPathHash; private int playbackRateShortNameHash; private float playbackRateBaselineNormalizedTime; private long playbackRateBaselineTimestamp; private int playbackRateStateSegments; private double playbackRateMeasuredWallSeconds; private double playbackRateNormalizedCycles; private double playbackRateClipSeconds; private int playbackRateCompletedCycles; private bool playbackRateFailureLogged; private Vector3 cameraPlayerLocalPositionAtStart; private bool hasCameraPlayerLocalBaseline; private float gameplayCameraLocalYawAtStart; private float gameplayCameraLocalRollAtStart; private bool hasGameplayCameraLocalRotationBaseline; private float cameraBaselineDisplacementFromVanillaRest; private bool cameraGuardPreExistingDisplacementDetected; private bool cameraGuardBaselineContaminated; private bool consumerOwnedCameraLogged; private bool cameraGuardPreExistingSuppressionLogged; private bool cameraGuardVanillaRestEnvelopeSuppressionLogged; private bool cameraGuardEvaluationUnavailableLogged; private float stanceViewpointMismatchSeconds; private bool stanceViewpointLastCrouchState; private bool hasStanceViewpointLastCrouchState; private bool stanceViewpointGuardExemptLogged; private bool cameraGuardRequestedStop; private int cameraBaselineDeferredFramesRemaining; private bool cameraBaselineDeferralLogged; private bool hasLastSyncedCrouchState; private bool lastSyncedCrouchState; private int lastLocomotionSyncSignature = -1; private int locomotionStateFrame = -1; private LocomotionState locomotionStateCache; private Vector3 remoteLocomotionLastLocalPosition; private float remoteLocomotionLastSampleTime; private bool hasRemoteLocomotionSample; private float remoteLocomotionSmoothedSpeed; private bool remoteLocomotionWalking; private bool remoteLocomotionSprinting; private LocalCameraPositionStabilizer cameraPositionStabilizer; private LocalCameraRotationStabilizer cameraRotationStabilizer; private bool specialAnimationAutoStopExemptLogged; private InteractionAnimationStopReason? requestedStopReason; private bool active; private static readonly FieldInfo VanillaIsWalkingField = typeof(PlayerControllerB).GetField("isWalking", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo VanillaIsJumpingField = typeof(PlayerControllerB).GetField("isJumping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private const float VisorHardGlueMaxTrackDistanceMeters = 2f; private RuntimeAnimatorController parameterCacheController; private readonly Dictionary<(string, AnimatorControllerParameterType), bool> parameterPresenceCache = new Dictionary<(string, AnimatorControllerParameterType), bool>(); public InteractionAnimationStopReason? RequestedStopReason => requestedStopReason; public bool HasResourceOwnership { get { if (active && (Object)(object)bodyAnimator != (Object)null && (Object)(object)appliedController != (Object)null) { return (Object)(object)bodyAnimator.runtimeAnimatorController == (Object)(object)appliedController; } return false; } } private ManualLogSource RestoreLogger => context?.Logger ?? InteractionAnimationApiRestoreDiagnostics.StaticLogger; private bool LocalCameraOwnedExternally { get { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext == null) { return false; } return interactionAnimationContext.Manifest?.body?.localCameraOwnedExternally == true; } } private bool PreserveGameplayCamera { get { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext == null) { return true; } return interactionAnimationContext.Manifest?.body?.preserveGameplayCamera != false; } } private bool StopOnGameplayCameraDisplacement { get { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext == null) { return true; } return interactionAnimationContext.Manifest?.body?.stopOnGameplayCameraDisplacement != false; } } internal static bool TryPreloadBundles(InteractionAnimationManifest manifest, string assetRootPath, ManualLogSource logger, out string reason) { reason = string.Empty; InteractionAnimationManifest.BodyManifest bodyManifest = manifest?.body; if (bodyManifest == null || !bodyManifest.enabled) { return true; } if (!TryPreloadBundle(manifest.bundleInternalName, bodyManifest.bundleFileName, assetRootPath, "controller", out var loaded, out reason)) { return false; } RuntimeAnimatorController val = null; if (!string.IsNullOrWhiteSpace(bodyManifest.controllerAssetName)) { val = loaded.LoadAsset(bodyManifest.controllerAssetName); } if ((Object)(object)val == (Object)null) { reason = "live_body.preload_controller_missing:" + bodyManifest.controllerAssetName; return false; } InteractionAnimationManifest.ClipPackManifest clipPack = bodyManifest.clipPack; AssetBundle val2 = loaded; if (clipPack != null && clipPack.enabled) { if (!TryPreloadBundle(clipPack.bundleInternalName, clipPack.bundleFileName, assetRootPath, "clip_pack", out var loaded2, out reason)) { return false; } val2 = loaded2; if (clipPack.overrides != null) { for (int i = 0; i < clipPack.overrides.Length; i++) { string text = clipPack.overrides[i]?.clip; if (!string.IsNullOrWhiteSpace(text) && (Object)(object)loaded2.LoadAsset(text) == (Object)null) { reason = "live_body.preload_clip_missing:" + text; return false; } } } } if (bodyManifest.prop != null && bodyManifest.prop.enabled && !string.IsNullOrWhiteSpace(bodyManifest.prop.prefabAssetName) && (Object)(object)val2.LoadAsset(bodyManifest.prop.prefabAssetName) == (Object)null) { reason = "live_body.preload_prop_missing:" + bodyManifest.prop.prefabAssetName; return false; } if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.preloaded: interaction='" + manifest.interactionId + "' controller='" + ((Object)val).name + "'.")); } return true; } private static bool TryPreloadBundle(string internalName, string fileName, string assetRootPath, string role, out AssetBundle loaded, out string reason) { loaded = null; reason = string.Empty; if (!TryResolveBundlePath(fileName, assetRootPath, out var resolvedPath, out reason)) { reason = "live_body.preload_" + role + "_bundle_rejected:" + reason; return false; } if (!string.IsNullOrWhiteSpace(internalName)) { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && string.Equals(((Object)allLoadedAssetBundle).name, internalName, StringComparison.OrdinalIgnoreCase)) { loaded = allLoadedAssetBundle; return true; } } } if (string.IsNullOrWhiteSpace(resolvedPath) || !File.Exists(resolvedPath)) { reason = "live_body.preload_" + role + "_bundle_missing:" + fileName; return false; } loaded = AssetBundle.LoadFromFile(resolvedPath); if ((Object)(object)loaded == (Object)null) { reason = "live_body.preload_" + role + "_bundle_load_failed:" + resolvedPath; return false; } RetainedBundles.Add(loaded); return true; } public bool TryPreflight(InteractionAnimationContext context, out string reason) { reason = string.Empty; InteractionAnimationManifest.BodyManifest bodyManifest = context?.Manifest?.body; if (bodyManifest == null || !bodyManifest.enabled) { reason = "missing_body_manifest"; return false; } if ((Object)(object)context.Request?.Player == (Object)null || (Object)(object)context.Request.Player.playerBodyAnimator == (Object)null) { reason = "missing_body_animator"; return false; } if (!TryPreloadBundles(context.Manifest, context.AssetRootPath, context.Logger, out reason)) { return false; } if (bodyManifest.prop != null && bodyManifest.prop.enabled && (Object)(object)ResolvePropAttachBone(((Object)(object)context.Request.Player.playerModelArmsMetarig != (Object)null) ? context.Request.Player.playerModelArmsMetarig : ((Component)context.Request.Player.playerBodyAnimator).transform, bodyManifest.prop) == (Object)null) { reason = "live_body.prop_attach_bone_missing:" + bodyManifest.prop.attachBonePath; return false; } return true; } public bool TryStart(InteractionAnimationContext context, out string reason) { reason = string.Empty; if (context == null) { reason = "missing_context"; return false; } InteractionAnimationManifest manifest = context.Manifest; InteractionAnimationManifest.BodyManifest bodyManifest = manifest?.body; if (bodyManifest == null || !bodyManifest.enabled) { reason = "missing_body_manifest"; return false; } if ((Object)(object)context.Request?.Player == (Object)null || (Object)(object)context.Request.Player.playerBodyAnimator == (Object)null) { reason = "missing_body_animator"; return false; } this.context = context; bodyAnimator = context.Request.Player.playerBodyAnimator; CaptureLocalCameraBaseline(); SeamPhaseStopwatch seamPhaseStopwatch = (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled ? new SeamPhaseStopwatch() : null); InteractionAnimationApiRestoreDiagnostics.PrepareForLiveBodyStart(context.Request.Player); CaptureRigControlPose(); CaptureThirdPersonRigControlPose(); CaptureScopedFirstPersonPose(bodyManifest); StartLocalCameraPositionStabilizer(bodyManifest); StartLocalCameraRotationStabilizer(); exitRequested = false; exitElapsedSeconds = 0f; exitDurationSeconds = 0f; exitStartFullBodyWeight = 0f; exitStartFirstPersonWeight = 0f; double num = LapMilliseconds(seamPhaseStopwatch); if (!TryLoadBundle(manifest, bodyManifest, out reason)) { CleanupFailedStart(); return false; } double num2 = LapMilliseconds(seamPhaseStopwatch); InteractionAnimationApiRestoreDiagnostics.NotifyRemoteRigProbeSessionBegin(context.Request.Player); CameraRotationSnapshot captured = CaptureSeamCameraRotation("start"); double num3 = LapMilliseconds(seamPhaseStopwatch); VisorPoseSnapshot captured2 = CaptureSeamVisorPose("start"); double num4 = LapMilliseconds(seamPhaseStopwatch); if (!TryApplyController(bodyManifest, out reason)) { CleanupFailedStart(); return false; } double num5 = LapMilliseconds(seamPhaseStopwatch); InteractionAnimationApiRestoreDiagnostics.NotifyLiveBodyAnimationRan(context.Request.Player); double num6 = 0.0; if (!bodyManifest.rebuildRigBuilders) { SuppressLiveRigBuilders(); } else { InteractionAnimationApiRestoreDiagnostics.LogIkBakeProbe(context.Request.Player, "pre-start-build"); num6 = LapMilliseconds(seamPhaseStopwatch); RebuildRigBuilders("start"); } double num7 = LapMilliseconds(seamPhaseStopwatch); ReapplySeamCameraRotation(captured, "start", animatorRestored: true); double num8 = LapMilliseconds(seamPhaseStopwatch); ReapplySeamVisorPose(captured2, "start", animatorRestored: true); double num9 = LapMilliseconds(seamPhaseStopwatch); try { bodyAnimator.Update(0f); } catch { } double num10 = LapMilliseconds(seamPhaseStopwatch); if (bodyManifest.rebuildRigBuilders) { EvaluateRigBuilders("start"); } double num11 = LapMilliseconds(seamPhaseStopwatch); ApplyLocalCameraPositionStabilizerNow(); if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { ResolveDiagnosticTransforms(); } double num12 = LapMilliseconds(seamPhaseStopwatch); AttachPropIfConfigured(); double num13 = LapMilliseconds(seamPhaseStopwatch); InteractionAnimationApiRestoreDiagnostics.NotifyLiveBodyStarted(context.Request.Player, propInstance); elapsedSeconds = 0f; nextDiagnosticsAtSeconds = 0f; exitRequested = false; lastMovementValue = -1; ResetLocomotionStateResolution(); ResetPlaybackRateProbe(); requestedStopReason = null; active = true; StartTransformChainDiagnostics(); StartExternalCameraPresentationDiagnostics(); StartLocalVisorHardGlue(); double num14 = LapMilliseconds(seamPhaseStopwatch); if (seamPhaseStopwatch != null) { ManualLogSource logger = context.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.timing] " + $"phase='start' frame={Time.frameCount} handle={context.Handle} " + $"totalMs={seamPhaseStopwatch.TotalMilliseconds:0.###} setupMs={num:0.###} " + $"bundleLoadMs={num2:0.###} cameraCaptureMs={num3:0.###} " + $"visorCaptureMs={num4:0.###} " + $"controllerSwapMs={num5:0.###} ikProbeMs={num6:0.###} " + $"rigBuildMs={num7:0.###} " + $"cameraReapplyMs={num8:0.###} visorReapplyMs={num9:0.###} " + $"animatorUpdateMs={num10:0.###} " + $"rigEvaluateMs={num11:0.###} diagnosticsMs={num12:0.###} " + $"propInstantiateMs={num13:0.###} finalizeMs={num14:0.###}.")); } } ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.started: " + $"handle={context.Handle} interaction='{manifest.interactionId}' " + "controller='" + ((Object)appliedController).name + "' animator='" + ((Object)bodyAnimator).name + "' " + $"fullBodyLayer={fullBodyLayerIndex} firstPersonArmsLayer={firstPersonLayerIndex} " + $"rigBuildersSuppressed={suppressedRigBuilders.Count} " + $"preserveGameplayCamera={bodyManifest.preserveGameplayCamera} " + $"stopOnGameplayCameraDisplacement={bodyManifest.stopOnGameplayCameraDisplacement} " + $"stabilizeLocalCameraPosition={bodyManifest.stabilizeLocalCameraPosition} " + $"localCameraOwnedExternally={bodyManifest.localCameraOwnedExternally}.")); } return true; } public void Tick(float deltaTime) { if (!active || (Object)(object)bodyAnimator == (Object)null) { return; } if ((Object)(object)appliedController != (Object)null && (Object)(object)bodyAnimator.runtimeAnimatorController != (Object)(object)appliedController) { requestedStopReason = InteractionAnimationStopReason.PresenterFailure; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { string text = $"handle={context.Handle} currentController='"; RuntimeAnimatorController runtimeAnimatorController = bodyAnimator.runtimeAnimatorController; logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.ownership_lost: " + text + (((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? "") + "'.")); } } return; } RetryDeferredCameraBaselineCapture(); DetectUnsafeCameraDisplacement(deltaTime); if (!requestedStopReason.HasValue) { elapsedSeconds += deltaTime; ReleasePropIfDue(); if (exitRequested) { exitElapsedSeconds += Mathf.Max(0f, deltaTime); } ApplyLayerWeights(); SyncVanillaLocomotionParameters("tick"); DriveMovementParameter(); SamplePlaybackRateProgression(); DetectAutoStopConditions(); LogFrameDiagnostics(); } } private void DetectAutoStopConditions() { if (requestedStopReason.HasValue) { return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null) { return; } try { if (!val.inSpecialInteractAnimation && !val.isPlayerDead && !val.isClimbingLadder) { return; } string arg = context?.Manifest?.interactionId; if (val.inSpecialInteractAnimation && !val.isPlayerDead && !val.isClimbingLadder) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null && interactionAnimationContext.Manifest?.body?.stopOnVanillaSpecialAnimation == false) { if (specialAnimationAutoStopExemptLogged) { return; } specialAnimationAutoStopExemptLogged = true; InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger = interactionAnimationContext2.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.auto_stop_exempt: " + $"handle={context.Handle} interaction='{arg}' " + $"specialAnim={val.inSpecialInteractAnimation} " + "action='continue_exempt'.")); } } return; } } requestedStopReason = (val.isPlayerDead ? InteractionAnimationStopReason.PlayerDied : InteractionAnimationStopReason.Interrupted); InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger2 = interactionAnimationContext3.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.auto_stop_requested: " + $"handle={context.Handle} specialAnim={val.inSpecialInteractAnimation} " + $"dead={val.isPlayerDead} ladder={val.isClimbingLadder}.")); } } } catch { } } private void CaptureLocalCameraBaseline() { CaptureLocalCameraBaseline(deferredRetry: false); } private void CaptureLocalCameraBaseline(bool deferredRetry) { //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_06f3: Unknown result type (might be due to invalid IL or missing references) //IL_0708: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) if (!deferredRetry) { ResetCameraDisplacementGuardState(); } if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.baseline_unavailable: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + "reason='local_camera_owned_externally' action='guard_disabled_for_session'.")); } } return; } PlayerControllerB val = context?.Request?.Player; bool flag = IsLocalPlayer(val); if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || !flag || (Object)(object)val.gameplayCamera == (Object)null) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.baseline_unavailable: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + $"playerPresent={(Object)(object)val != (Object)null} playerTransformPresent={(Object)(object)((val != null) ? ((Component)val).transform : null) != (Object)null} " + $"localPlayer={flag} gameplayCameraPresent={(Object)(object)val?.gameplayCamera != (Object)null} " + "rotation_residue_available=False pre_existing_rotation_residue=False action='guard_disabled_for_session'.")); } } return; } if (PreserveGameplayCamera && !deferredRetry) { TryHealCameraDriftAtSessionEntry(val); } Transform transform = ((Component)val.gameplayCamera).transform; Vector3 val2 = ((Component)val).transform.InverseTransformPoint(transform.position); bool flag2 = IsStanceTransitionInProgress(val, val2); if (flag2) { if (!deferredRetry) { cameraBaselineDeferredFramesRemaining = 4; } if (cameraBaselineDeferredFramesRemaining > 0) { if (cameraBaselineDeferralLogged) { return; } cameraBaselineDeferralLogged = true; InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.baseline_deferred: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + "candidate_baseline=" + DescribeVector(val2) + " " + $"frames={cameraBaselineDeferredFramesRemaining} " + "reason='stance_transition_in_progress' action='defer_baseline_capture'.")); } } return; } } cameraPlayerLocalPositionAtStart = val2; hasCameraPlayerLocalBaseline = true; Vector3 localEulerAngles = transform.localEulerAngles; gameplayCameraLocalYawAtStart = Mathf.DeltaAngle(0f, localEulerAngles.y); gameplayCameraLocalRollAtStart = Mathf.DeltaAngle(0f, localEulerAngles.z); hasGameplayCameraLocalRotationBaseline = true; Transform cameraContainerTransform = val.cameraContainerTransform; bool flag3 = (Object)(object)cameraContainerTransform != (Object)null; Vector3 val3 = (flag3 ? cameraContainerTransform.localEulerAngles : Vector3.zero); Vector3 val4 = (flag3 ? DescribeEulerDeviation(val3, VanillaCameraContainerLocalRestEuler) : Vector3.zero); bool flag4 = Mathf.Abs(gameplayCameraLocalYawAtStart) > 0.02f || Mathf.Abs(gameplayCameraLocalRollAtStart) > 0.02f || (flag3 && (Mathf.Abs(val4.x) > 0.02f || Mathf.Abs(val4.y) > 0.02f || Mathf.Abs(val4.z) > 0.02f)); cameraBaselineDisplacementFromVanillaRest = Vector3.Distance(cameraPlayerLocalPositionAtStart, VanillaCameraPlayerLocalRestExpectation); cameraGuardPreExistingDisplacementDetected = cameraBaselineDisplacementFromVanillaRest > 1.25f; cameraGuardBaselineContaminated = cameraGuardPreExistingDisplacementDetected || flag2; bool flag5 = false; try { flag5 = val.isCrouching; } catch { } InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.baseline_captured: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + "baseline=" + DescribeVector(cameraPlayerLocalPositionAtStart) + " vanilla_rest_expectation=" + DescribeVector(VanillaCameraPlayerLocalRestExpectation) + " " + $"displacement_from_vanilla_rest={cameraBaselineDisplacementFromVanillaRest:0.###} " + $"threshold={1.25f:0.###} " + "baseline_source='try_start_pre_controller' " + $"pre_existing_displacement={cameraGuardPreExistingDisplacementDetected} " + $"baseline_contaminated={cameraGuardBaselineContaminated} " + "rotation_residue_available=True " + $"gameplay_camera_local_yaw={gameplayCameraLocalYawAtStart:0.######} " + $"gameplay_camera_local_roll={gameplayCameraLocalRollAtStart:0.######} " + $"gameplay_camera_yaw_deviation_from_rest={gameplayCameraLocalYawAtStart:0.######} " + $"gameplay_camera_roll_deviation_from_rest={gameplayCameraLocalRollAtStart:0.######} " + "camera_container_local_euler=" + (flag3 ? DescribeEuler(val3) : "") + " camera_container_rest_euler=" + DescribeEuler(VanillaCameraContainerLocalRestEuler) + " camera_container_deviation_from_rest=" + (flag3 ? DescribeEuler(val4) : "") + " " + $"rotation_residue_threshold_degrees={0.02f:0.###} " + $"pre_existing_rotation_residue={flag4} " + $"baseline_crouching={flag5} " + $"localCameraOwnedExternally={LocalCameraOwnedExternally} " + $"preserveGameplayCamera={PreserveGameplayCamera} " + $"stopOnGameplayCameraDisplacement={StopOnGameplayCameraDisplacement}.")); } } if (!cameraGuardPreExistingDisplacementDetected) { return; } InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogWarning((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.pre_existing_displacement: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + "phase='try_start' " + $"displacement_from_vanilla_rest={cameraBaselineDisplacementFromVanillaRest:0.###} " + $"threshold={1.25f:0.###} " + "baseline=" + DescribeVector(cameraPlayerLocalPositionAtStart) + " vanilla_rest_expectation=" + DescribeVector(VanillaCameraPlayerLocalRestExpectation) + " baseline_source='try_start_pre_controller' pre_existing_displacement=True baseline_contaminated=True action='continue_new_displacement_only'.")); } } } private void TryHealCameraDriftAtSessionEntry(PlayerControllerB player) { //IL_001a: 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) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) if (!InteractionAnimationApiRestoreDiagnostics.HealCameraDriftAtSessionStartEnabled) { return; } try { Vector3 val = ((Component)player).transform.InverseTransformPoint(((Component)player.gameplayCamera).transform.position); float num = Vector3.Distance(val, VanillaCameraPlayerLocalRestExpectation); if (num <= 0.02f) { TryRefineCameraChainRestBaselineAtCleanEntry(player, num); if (TryGetVerifiedCleanIdleState(player, out var _, out var _, out var _)) { InteractionAnimationApiRestoreDiagnostics.TryRecapturePristineThirdPersonRigPoseIfImplausible(player, out var _); } return; } if (num > 1.25f) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerachain] heal_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"displacement={num:0.###} " + $"threshold={0.02f:0.###} " + $"guardThreshold={1.25f:0.###} " + "reason='beyond_guard_threshold' action='defer_to_displacement_guard'.")); } } return; } bool flag = false; bool flag2 = false; try { flag = player.isCrouching; flag2 = player.inSpecialInteractAnimation; } catch { } if (flag || flag2) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.camerachain] heal_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"displacement={num:0.###} crouching={flag} " + $"specialAnimation={flag2} " + "reason='legitimately_displaced_state' action='leave_camera_chain'.")); } } return; } if (!InteractionAnimationApiRestoreDiagnostics.TryRestorePristineCameraChainPositions(player, out var restored, out var reason2, out var source)) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.camerachain] heal_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"displacement={num:0.###} " + "reason='" + reason2 + "' action='leave_camera_chain'.")); } } return; } Vector3 val2 = ((Component)player).transform.InverseTransformPoint(((Component)player.gameplayCamera).transform.position); float num2 = Vector3.Distance(val2, VanillaCameraPlayerLocalRestExpectation); InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.camerachain] heal_applied: " + $"frame={Time.frameCount} handle={context.Handle} " + "interaction='" + (context.Manifest?.interactionId ?? "") + "' " + $"restoredTransforms={restored} " + "beforePlayerLocal=" + DescribeVector(val) + " afterPlayerLocal=" + DescribeVector(val2) + " " + $"displacementBefore={num:0.###} " + $"displacementAfter={num2:0.###} " + "source='" + source + "'.")); } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogWarning((object)("[RestoreSeam.camerachain] heal_failed: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private void TryRefineCameraChainRestBaselineAtCleanEntry(PlayerControllerB player, float displacement) { if (!TryGetVerifiedCleanIdleState(player, out var _, out var _, out var horizontalSpeed)) { return; } if (!InteractionAnimationApiRestoreDiagnostics.TryRefineCameraChainRestBaseline(player, out var reason)) { if (string.Equals(reason, "already_refined", StringComparison.Ordinal)) { return; } InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerachain] rest_baseline_refine_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"displacement={displacement:0.###} reason='{reason}' " + "action='keep_authored_default'.")); } } return; } InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.camerachain] rest_baseline_refine_accepted: " + $"frame={Time.frameCount} handle={context.Handle} " + "interaction='" + (context.Manifest?.interactionId ?? "") + "' " + $"displacement={displacement:0.###} horizontalSpeed={horizontalSpeed:0.###} " + "action='snap_targets_now_runtime_settled'.")); } } } private static bool TryGetVerifiedCleanIdleState(PlayerControllerB player, out bool crouching, out bool specialAnimation, out float horizontalSpeed) { //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_003e: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) crouching = false; specialAnimation = false; horizontalSpeed = -1f; try { crouching = player.isCrouching; specialAnimation = player.inSpecialInteractAnimation; } catch { } try { if ((Object)(object)player.thisController != (Object)null) { Vector3 velocity = player.thisController.velocity; Vector3 val = new Vector3(velocity.x, 0f, velocity.z); horizontalSpeed = ((Vector3)(ref val)).magnitude; } } catch { } if (!crouching && !specialAnimation && horizontalSpeed >= 0f) { return horizontalSpeed <= 0.1f; } return false; } private void ResetCameraDisplacementGuardState() { //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) hasCameraPlayerLocalBaseline = false; cameraPlayerLocalPositionAtStart = Vector3.zero; gameplayCameraLocalYawAtStart = 0f; gameplayCameraLocalRollAtStart = 0f; hasGameplayCameraLocalRotationBaseline = false; cameraBaselineDisplacementFromVanillaRest = 0f; cameraGuardPreExistingDisplacementDetected = false; cameraGuardBaselineContaminated = false; consumerOwnedCameraLogged = false; cameraGuardPreExistingSuppressionLogged = false; cameraGuardVanillaRestEnvelopeSuppressionLogged = false; cameraGuardEvaluationUnavailableLogged = false; stanceViewpointMismatchSeconds = 0f; stanceViewpointLastCrouchState = false; hasStanceViewpointLastCrouchState = false; stanceViewpointGuardExemptLogged = false; cameraGuardRequestedStop = false; cameraBaselineDeferredFramesRemaining = 0; cameraBaselineDeferralLogged = false; } private static float StanceRestHeight(bool crouching) { if (!crouching) { return VanillaCameraPlayerLocalRestExpectation.y; } return 1.17f; } private static bool TryReadCrouching(PlayerControllerB player, out bool crouching) { crouching = false; if ((Object)(object)player == (Object)null) { return false; } try { crouching = player.isCrouching; return true; } catch { return false; } } private static bool IsStanceTransitionInProgress(PlayerControllerB player, Vector3 cameraPlayerLocal) { //IL_000c: 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) if (!TryReadCrouching(player, out var crouching)) { return false; } float num = Mathf.Abs(cameraPlayerLocal.y - StanceRestHeight(crouching)); float num2 = Mathf.Abs(cameraPlayerLocal.y - StanceRestHeight(!crouching)); if (num > 0.15f && num < Mathf.Abs(VanillaCameraPlayerLocalRestExpectation.y - 1.17f)) { return num2 <= num + 0.15f; } return false; } private void StartLocalCameraPositionStabilizer(InteractionAnimationManifest.BodyManifest body) { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) cameraPositionStabilizer = null; if (body == null || !body.stabilizeLocalCameraPosition || !hasCameraPlayerLocalBaseline || LocalCameraOwnedExternally) { return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || (Object)(object)val.gameplayCamera == (Object)null) { return; } bool crouching; bool flag = TryReadCrouching(val, out crouching); float num = StanceRestHeight(crouching); float num2 = Mathf.Abs(cameraPlayerLocalPositionAtStart.y - num); bool flag2 = flag && num2 > 0.15f; if (cameraGuardBaselineContaminated || flag2) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.local_camera_stabilizer_skipped: " + $"handle={context.Handle} " + "baseline=" + DescribeVector(cameraPlayerLocalPositionAtStart) + " " + $"baselineContaminated={cameraGuardBaselineContaminated} " + $"crouching={crouching} crouchingKnown={flag} " + $"stanceRestHeight={num:0.###} " + $"stanceHeightDeviation={num2:0.###} " + $"tolerance={0.15f:0.###} " + "reason='contaminated_baseline' action='run_unpinned'.")); } } return; } try { cameraPositionStabilizer = ((Component)val.gameplayCamera).gameObject.AddComponent(); cameraPositionStabilizer.InitializeStanceRelative(((Component)val).transform, ((Component)val.gameplayCamera).transform, cameraPlayerLocalPositionAtStart, flag ? val : null, crouching, 1.17f, VanillaCameraPlayerLocalRestExpectation.y); InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.local_camera_stabilizer_started: " + $"handle={context.Handle} playerLocalPosition={cameraPlayerLocalPositionAtStart} " + "mode='" + (flag ? "session_stance_relative_pin" : "session_position_pin") + "' " + $"crouchingAtCapture={crouching} " + $"stanceRestHeight={num:0.###} " + $"stanceRelativeHeightOffset={cameraPositionStabilizer.StanceRelativeHeightOffset:0.###} " + "explicitOptIn=True.")); } } } catch (Exception ex) { cameraPositionStabilizer = null; InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[LCInteractionAnimationAPI] live_body.local_camera_stabilizer_failed: " + $"handle={context.Handle} error='{ex.Message}'.")); } } } } private void ApplyLocalCameraPositionStabilizerNow() { try { cameraPositionStabilizer?.ApplyNow(); } catch { } } private void StartLocalCameraRotationStabilizer() { cameraRotationStabilizer = null; if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " enabled=True reason='local_camera_owned_externally' action='leave_rotation_unpinned'.")); } } return; } if (!PreserveGameplayCamera) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " enabled=False reason='manifest_preservation_disabled' action='leave_rotation_unpinned'.")); } } return; } if (!InteractionAnimationApiRestoreDiagnostics.StabilizeCameraRotationDuringSessionEnabled) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " enabled=False reason='kill_switch_disabled' action='leave_rotation_unpinned'.")); } } return; } if (!hasGameplayCameraLocalRotationBaseline) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " enabled=True reason='session_entry_rotation_unavailable' action='leave_rotation_unpinned'.")); } } return; } PlayerControllerB val = context?.Request?.Player; Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val.gameplayCamera).transform : null); if ((Object)(object)val2 == (Object)null) { InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " enabled=True reason='gameplay_camera_missing' action='leave_rotation_unpinned'.")); } } return; } try { cameraRotationStabilizer = ((Component)val2).GetComponent(); if ((Object)(object)cameraRotationStabilizer == (Object)null) { cameraRotationStabilizer = ((Component)val2).gameObject.AddComponent(); } cameraRotationStabilizer.Initialize(val2, gameplayCameraLocalYawAtStart, gameplayCameraLocalRollAtStart); InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_started: " + $"handle={context.Handle} enabled=True " + $"sessionEntryLocalYaw={gameplayCameraLocalYawAtStart:0.######} " + $"sessionEntryLocalRoll={gameplayCameraLocalRollAtStart:0.######} " + "pitchOwner='vanilla_live_x' yZSource='session_entry_absolute'.")); } } } catch (Exception ex) { cameraRotationStabilizer = null; InteractionAnimationContext interactionAnimationContext7 = context; if (interactionAnimationContext7 != null) { ManualLogSource logger7 = interactionAnimationContext7.Logger; if (logger7 != null) { logger7.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " enabled=True reason='start_failed:" + ex.Message + "' action='leave_rotation_unpinned'.")); } } } } private void StopLocalCameraRotationStabilizer(bool restoreSessionEntryRotation) { LocalCameraRotationStabilizer localCameraRotationStabilizer = cameraRotationStabilizer; cameraRotationStabilizer = null; if ((Object)(object)localCameraRotationStabilizer == (Object)null) { return; } try { if (restoreSessionEntryRotation) { localCameraRotationStabilizer.ApplyNow(); } ((Behaviour)localCameraRotationStabilizer).enabled = false; Object.Destroy((Object)(object)localCameraRotationStabilizer); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_stopped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"restoredSessionEntryRotation={restoreSessionEntryRotation}.")); } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_rotation_stabilizer_stop_failed: handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private void StartRestoreScopedCameraPositionStabilizer() { //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) if (!InteractionAnimationApiRestoreDiagnostics.RestoreScopedCameraPinEnabled || !PreserveGameplayCamera) { return; } if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerapin] pin_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='local_camera_owned_externally' action='leave_camera_unpinned'.")); } } return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || (Object)(object)val.gameplayCamera == (Object)null) { return; } try { PlayerControllerB val2 = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val2 == (Object)null && (Object)(object)StartOfRound.Instance != (Object)null) { val2 = StartOfRound.Instance.localPlayerController; } if (val != val2) { return; } Vector3 val3 = ((Component)val).transform.InverseTransformPoint(((Component)val.gameplayCamera).transform.position); if ((Object)(object)cameraPositionStabilizer == (Object)null) { cameraPositionStabilizer = ((Component)val.gameplayCamera).gameObject.AddComponent(); } cameraPositionStabilizer.Initialize(((Component)val).transform, ((Component)val.gameplayCamera).transform, val3); InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.pin] pin_started: " + $"frame={Time.frameCount} handle={context.Handle} " + $"playerLocalPosition={val3}.")); } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[RestoreSeam.pin] pin_failed: " + $"frame={Time.frameCount} handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private void StopLocalCameraPositionStabilizer(bool restorePosition, bool deferRelease) { LocalCameraPositionStabilizer localCameraPositionStabilizer = cameraPositionStabilizer; cameraPositionStabilizer = null; if ((Object)(object)localCameraPositionStabilizer == (Object)null) { return; } try { if (restorePosition) { localCameraPositionStabilizer.ApplyNow(); } if (deferRelease) { localCameraPositionStabilizer.ReleaseAfterLateUpdates(2); return; } ((Behaviour)localCameraPositionStabilizer).enabled = false; Object.Destroy((Object)(object)localCameraPositionStabilizer); } catch { } } private CameraRotationSnapshot CaptureSeamCameraRotation(string phase) { //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) if (LocalCameraOwnedExternally || !PreserveGameplayCamera) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerarotation] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='" + (LocalCameraOwnedExternally ? "local_camera_owned_externally" : "manifest_preservation_disabled") + "'.")); } } return default(CameraRotationSnapshot); } bool flag = string.Equals(phase, "stop", StringComparison.Ordinal) && InteractionAnimationApiRestoreDiagnostics.RestoreCameraRotationSnapToRestEnabled; if (!InteractionAnimationApiRestoreDiagnostics.RestoreCameraRotationEnabled && !flag) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.camerarotation] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='disabled'.")); } } return default(CameraRotationSnapshot); } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.camerarotation] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='missing_player'.")); } } return default(CameraRotationSnapshot); } if (!IsLocalPlayer(val)) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.camerarotation] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='not_local_player'.")); } } return default(CameraRotationSnapshot); } Transform val2 = null; Transform val3 = null; Quaternion val4 = Quaternion.identity; Quaternion val5 = Quaternion.identity; bool flag2 = false; bool flag3 = false; try { val2 = (((Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val.gameplayCamera).transform : null); if ((Object)(object)val2 != (Object)null) { val4 = val2.localRotation; flag2 = true; } else { InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogWarning((object)("[RestoreSeam.camerarotation] capture_target_missing: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='gameplayCamera'.")); } } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogWarning((object)("[RestoreSeam.camerarotation] capture_target_failed: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='gameplayCamera' error='" + ex.Message + "'.")); } } } try { val3 = val.cameraContainerTransform; if ((Object)(object)val3 != (Object)null) { val5 = val3.localRotation; flag3 = true; } else { InteractionAnimationContext interactionAnimationContext7 = context; if (interactionAnimationContext7 != null) { ManualLogSource logger7 = interactionAnimationContext7.Logger; if (logger7 != null) { logger7.LogWarning((object)("[RestoreSeam.camerarotation] capture_target_missing: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='cameraContainerTransform'.")); } } } } catch (Exception ex2) { InteractionAnimationContext interactionAnimationContext8 = context; if (interactionAnimationContext8 != null) { ManualLogSource logger8 = interactionAnimationContext8.Logger; if (logger8 != null) { logger8.LogWarning((object)("[RestoreSeam.camerarotation] capture_target_failed: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='cameraContainerTransform' error='" + ex2.Message + "'.")); } } } if (!flag2 && !flag3) { InteractionAnimationContext interactionAnimationContext9 = context; if (interactionAnimationContext9 != null) { ManualLogSource logger9 = interactionAnimationContext9.Logger; if (logger9 != null) { logger9.LogInfo((object)("[RestoreSeam.camerarotation] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "reason='no_rotation_targets'.")); } } return default(CameraRotationSnapshot); } InteractionAnimationContext interactionAnimationContext10 = context; if (interactionAnimationContext10 != null) { ManualLogSource logger10 = interactionAnimationContext10.Logger; if (logger10 != null) { logger10.LogInfo((object)("[RestoreSeam.camerarotation] captured: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "gameplayCameraLocalEuler=" + DescribeCapturedEuler(flag2, val4) + " cameraContainerLocalEuler=" + DescribeCapturedEuler(flag3, val5) + ".")); } } return new CameraRotationSnapshot(val2, val4, flag2, val3, val5, flag3); } private void ReapplySeamCameraRotation(CameraRotationSnapshot captured, string phase, bool animatorRestored) { //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) if (LocalCameraOwnedExternally || !PreserveGameplayCamera) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerarotation] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='" + (LocalCameraOwnedExternally ? "local_camera_owned_externally" : "manifest_preservation_disabled") + "'.")); } } return; } bool flag = string.Equals(phase, "stop", StringComparison.Ordinal); bool flag2 = flag && InteractionAnimationApiRestoreDiagnostics.RestoreCameraRotationSnapToRestEnabled; if (!animatorRestored) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.camerarotation] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='animator_not_restored'.")); } } return; } if (!InteractionAnimationApiRestoreDiagnostics.RestoreCameraRotationEnabled && !flag2) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.camerarotation] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='disabled'.")); } } return; } if (!captured.HasAnyRotation) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.camerarotation] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='capture_unavailable'.")); } } return; } bool flag3 = false; bool flag4 = false; string arg = (captured.GameplayCameraCaptured ? "" : ""); string arg2 = (captured.CameraContainerCaptured ? "" : ""); Vector3 val; Quaternion val2; if (!captured.GameplayCameraCaptured) { val = Vector3.zero; } else { val2 = captured.GameplayCameraLocalRotation; val = ((Quaternion)(ref val2)).eulerAngles; } Vector3 val3 = val; float num = (captured.GameplayCameraCaptured ? Mathf.DeltaAngle(0f, val3.y) : 0f); float num2 = (captured.GameplayCameraCaptured ? Mathf.DeltaAngle(0f, val3.z) : 0f); Vector3 val4; if (!captured.CameraContainerCaptured) { val4 = Vector3.zero; } else { val2 = captured.CameraContainerLocalRotation; val4 = ((Quaternion)(ref val2)).eulerAngles; } Vector3 current = val4; Vector3 euler = (captured.CameraContainerCaptured ? DescribeEulerDeviation(current, VanillaCameraContainerLocalRestEuler) : Vector3.zero); if (flag) { InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogInfo((object)("[RestoreSeam.camerarotation] stop_restore_gate: " + $"phase='stop' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"restoreCameraRotation={InteractionAnimationApiRestoreDiagnostics.RestoreCameraRotationEnabled} " + $"snapToRest={flag2} " + $"gameplayCameraCaptured={captured.GameplayCameraCaptured} " + $"discardedGameplayCameraLocalYaw={num:0.######} " + $"discardedGameplayCameraLocalRoll={num2:0.######} " + $"cameraContainerCaptured={captured.CameraContainerCaptured} " + "discardedCameraContainerDeviationFromRest=" + (captured.CameraContainerCaptured ? DescribeEuler(euler) : "") + " cameraContainerRestEuler=" + DescribeEuler(VanillaCameraContainerLocalRestEuler) + " action='" + (flag2 ? "preserve_pitch_snap_yaw_roll_and_container_to_rest" : "reapply_stop_entry_rotation") + "'.")); } } } if (captured.GameplayCameraCaptured) { if ((Object)(object)captured.GameplayCameraTransform == (Object)null) { InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogWarning((object)("[RestoreSeam.camerarotation] reapply_target_missing: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='gameplayCamera'.")); } } } else { try { captured.GameplayCameraTransform.localRotation = (flag2 ? Quaternion.Euler(val3.x, 0f, 0f) : captured.GameplayCameraLocalRotation); arg = DescribeEuler(captured.GameplayCameraTransform.localEulerAngles); flag3 = true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext7 = context; if (interactionAnimationContext7 != null) { ManualLogSource logger7 = interactionAnimationContext7.Logger; if (logger7 != null) { logger7.LogWarning((object)("[RestoreSeam.camerarotation] reapply_target_failed: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='gameplayCamera' error='" + ex.Message + "'.")); } } } } } if (captured.CameraContainerCaptured) { if ((Object)(object)captured.CameraContainerTransform == (Object)null) { InteractionAnimationContext interactionAnimationContext8 = context; if (interactionAnimationContext8 != null) { ManualLogSource logger8 = interactionAnimationContext8.Logger; if (logger8 != null) { logger8.LogWarning((object)("[RestoreSeam.camerarotation] reapply_target_missing: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='cameraContainerTransform'.")); } } } else { try { if (flag2) { captured.CameraContainerTransform.localEulerAngles = VanillaCameraContainerLocalRestEuler; } else { captured.CameraContainerTransform.localRotation = captured.CameraContainerLocalRotation; } arg2 = DescribeEuler(captured.CameraContainerTransform.localEulerAngles); flag4 = true; } catch (Exception ex2) { InteractionAnimationContext interactionAnimationContext9 = context; if (interactionAnimationContext9 != null) { ManualLogSource logger9 = interactionAnimationContext9.Logger; if (logger9 != null) { logger9.LogWarning((object)("[RestoreSeam.camerarotation] reapply_target_failed: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='cameraContainerTransform' error='" + ex2.Message + "'.")); } } } } } if (!flag3 && !flag4) { InteractionAnimationContext interactionAnimationContext10 = context; if (interactionAnimationContext10 != null) { ManualLogSource logger10 = interactionAnimationContext10.Logger; if (logger10 != null) { logger10.LogWarning((object)("[RestoreSeam.camerarotation] reapply_failed: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "reason='no_rotation_targets_applied'.")); } } return; } InteractionAnimationContext interactionAnimationContext11 = context; if (interactionAnimationContext11 != null) { ManualLogSource logger11 = interactionAnimationContext11.Logger; if (logger11 != null) { logger11.LogInfo((object)("[RestoreSeam.camerarotation] reapplied: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + $"snapToRest={flag2} " + $"gameplayCameraApplied={flag3} gameplayCameraLocalEuler={arg} " + $"cameraContainerApplied={flag4} cameraContainerLocalEuler={arg2}.")); } } } private VisorPoseSnapshot CaptureSeamVisorPose(string phase) { if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='local_camera_owned_externally' action='leave_visor_to_external_owner'.")); } } return default(VisorPoseSnapshot); } if (!InteractionAnimationApiRestoreDiagnostics.RestoreVisorPoseEnabled) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='disabled'.")); } } return default(VisorPoseSnapshot); } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='missing_player'.")); } } return default(VisorPoseSnapshot); } if (!IsLocalPlayer(val)) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='not_local_player'.")); } } return default(VisorPoseSnapshot); } Transform animatorRoot = (((Object)(object)bodyAnimator != (Object)null) ? ((Component)bodyAnimator).transform : (((Object)(object)val.playerBodyAnimator != (Object)null) ? ((Component)val.playerBodyAnimator).transform : null)); Transform val2 = null; Transform val3 = null; bool flag = false; bool flag2 = false; try { val2 = val.localVisor; } catch (Exception ex) { flag = true; InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogWarning((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='localVisor' reason='field_read_failed' error='" + ex.Message + "'.")); } } } try { val3 = val.localVisorTargetPoint; } catch (Exception ex2) { flag2 = true; InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogWarning((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='localVisorTargetPoint' reason='field_read_failed' error='" + ex2.Message + "'.")); } } } LogVisorHierarchyOnce(animatorRoot, val2, val3, phase); SeamTransformPose captured = default(SeamTransformPose); SeamTransformPose captured2 = default(SeamTransformPose); if (!flag) { TryCaptureSeamVisorTarget(val2, animatorRoot, "localVisor", phase, out captured); } if (!flag2) { TryCaptureSeamVisorTarget(val3, animatorRoot, "localVisorTargetPoint", phase, out captured2); } VisorPoseSnapshot result = new VisorPoseSnapshot(captured, captured2); if (!result.HasAnyPose) { InteractionAnimationContext interactionAnimationContext7 = context; if (interactionAnimationContext7 != null) { ManualLogSource logger7 = interactionAnimationContext7.Logger; if (logger7 != null) { logger7.LogWarning((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "reason='no_pose_targets'.")); } } return default(VisorPoseSnapshot); } if (!result.HasAnyRestoreEligiblePose) { InteractionAnimationContext interactionAnimationContext8 = context; if (interactionAnimationContext8 != null) { ManualLogSource logger8 = interactionAnimationContext8.Logger; if (logger8 != null) { logger8.LogInfo((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "reason='no_targets_under_animator_hierarchy'.")); } } return default(VisorPoseSnapshot); } InteractionAnimationContext interactionAnimationContext9 = context; if (interactionAnimationContext9 != null) { ManualLogSource logger9 = interactionAnimationContext9.Logger; if (logger9 != null) { logger9.LogInfo((object)("[RestoreSeam.visor] captured: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "localVisor=" + DescribeCapturedSeamPose(result.LocalVisor) + " localVisorTargetPoint=" + DescribeCapturedSeamPose(result.LocalVisorTargetPoint) + ".")); } } return result; } private bool TryCaptureSeamVisorTarget(Transform target, Transform animatorRoot, string targetName, string phase, out SeamTransformPose captured) { captured = default(SeamTransformPose); if ((Object)(object)target == (Object)null) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='" + targetName + "' reason='missing_transform'.")); } } return false; } try { bool underAnimatorHierarchy = (Object)(object)animatorRoot != (Object)null && (target == animatorRoot || target.IsChildOf(animatorRoot)); captured = new SeamTransformPose(target, underAnimatorHierarchy); return true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[RestoreSeam.visor] capture_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='" + targetName + "' reason='capture_failed' error='" + ex.Message + "'.")); } } return false; } } private void ReapplySeamVisorPose(VisorPoseSnapshot captured, string phase, bool animatorRestored) { //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='local_camera_owned_externally' action='leave_visor_to_external_owner'.")); } } return; } if (!animatorRestored) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='animator_not_restored'.")); } } return; } if (!InteractionAnimationApiRestoreDiagnostics.RestoreVisorPoseEnabled) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='disabled'.")); } } return; } if (!captured.HasAnyPose) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='capture_unavailable'.")); } } return; } bool flag = TryReapplySeamVisorTarget(captured.LocalVisorTargetPoint, "localVisorTargetPoint", phase, restoreWorldPose: false); bool flag2 = TryReapplySeamVisorTarget(captured.LocalVisor, "localVisor", phase, restoreWorldPose: true); bool flag3 = false; if (captured.LocalVisor.Captured && captured.LocalVisorTargetPoint.Captured && (Object)(object)captured.LocalVisor.Transform != (Object)null && (Object)(object)captured.LocalVisorTargetPoint.Transform != (Object)null) { try { captured.LocalVisor.Transform.position = captured.LocalVisorTargetPoint.Transform.position; captured.LocalVisor.Transform.rotation = captured.LocalVisor.WorldRotation; flag3 = true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='vanillaVisorGlue' reason='apply_failed' error='" + ex.Message + "'.")); } } } } else { InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='vanillaVisorGlue' reason='missing_captured_transform'.")); } } } if (!flag && !flag2 && !flag3) { InteractionAnimationContext interactionAnimationContext7 = context; if (interactionAnimationContext7 != null) { ManualLogSource logger7 = interactionAnimationContext7.Logger; if (logger7 != null) { logger7.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "reason='no_targets_applied'.")); } } return; } InteractionAnimationContext interactionAnimationContext8 = context; if (interactionAnimationContext8 != null) { ManualLogSource logger8 = interactionAnimationContext8.Logger; if (logger8 != null) { string[] obj = new string[14] { "[RestoreSeam.visor] reapplied: ", $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} ", $"localVisorApplied={flag2} ", "localVisor=", DescribeCurrentSeamPose(captured.LocalVisor.Transform), " ", $"localVisorTargetPointApplied={flag} ", "localVisorTargetPoint=", DescribeCurrentSeamPose(captured.LocalVisorTargetPoint.Transform), " ", $"vanillaGlueApplied={flag3} ", "preservedVisorWorldEuler=", null, null }; Quaternion worldRotation = captured.LocalVisor.WorldRotation; obj[12] = DescribeEuler(((Quaternion)(ref worldRotation)).eulerAngles); obj[13] = "."; logger8.LogInfo((object)string.Concat(obj)); } } } private bool TryReapplySeamVisorTarget(SeamTransformPose captured, string targetName, string phase, bool restoreWorldPose) { //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) if (!captured.Captured) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='" + targetName + "' reason='capture_unavailable'.")); } } return false; } if (!captured.UnderAnimatorHierarchy) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='" + targetName + "' reason='not_under_animator_hierarchy'.")); } } return false; } if ((Object)(object)captured.Transform == (Object)null) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='" + targetName + "' reason='target_missing'.")); } } return false; } try { captured.Transform.localPosition = captured.LocalPosition; captured.Transform.localRotation = captured.LocalRotation; captured.Transform.localScale = captured.LocalScale; if (restoreWorldPose) { captured.Transform.SetPositionAndRotation(captured.WorldPosition, captured.WorldRotation); } return true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogWarning((object)("[RestoreSeam.visor] reapply_skipped: " + $"phase='{phase}' frame={Time.frameCount} handle={context.Handle} " + "target='" + targetName + "' reason='apply_failed' error='" + ex.Message + "'.")); } } return false; } } private void LogVisorHierarchyOnce(Transform animatorRoot, Transform localVisor, Transform localVisorTargetPoint, string phase) { if (visorHierarchyLogged) { return; } visorHierarchyLogged = true; try { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.visor] hierarchy: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " animatorRootPath='" + DescribeHierarchyPath(animatorRoot) + "' localVisorPath='" + DescribeHierarchyPath(localVisor) + "' " + $"localVisorUnderAnimatorHierarchy={IsUnderHierarchy(localVisor, animatorRoot)} " + "localVisorTargetPointPath='" + DescribeHierarchyPath(localVisorTargetPoint) + "' " + $"localVisorTargetPointUnderAnimatorHierarchy={IsUnderHierarchy(localVisorTargetPoint, animatorRoot)}.")); } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[RestoreSeam.visor] hierarchy_failed: " + $"phase='{phase}' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private static bool IsUnderHierarchy(Transform target, Transform root) { try { return (Object)(object)target != (Object)null && (Object)(object)root != (Object)null && (target == root || target.IsChildOf(root)); } catch { return false; } } private static string DescribeHierarchyPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } try { List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null) { list.Add(((Object)val).name ?? ""); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()).Replace('\r', ' ').Replace('\n', ' ') .Replace('\'', '"'); } catch (Exception ex) { return ""; } } private static string DescribeCapturedSeamPose(SeamTransformPose captured) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_00a1: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (!captured.Captured) { return "[captured=False]"; } string[] obj = new string[14] { $"[captured=True underAnimatorHierarchy={captured.UnderAnimatorHierarchy} ", "localPos=", DescribeVector(captured.LocalPosition), " localEuler=", null, null, null, null, null, null, null, null, null, null }; Quaternion val = captured.LocalRotation; obj[4] = DescribeEuler(((Quaternion)(ref val)).eulerAngles); obj[5] = " localScale="; obj[6] = DescribeVector(captured.LocalScale); obj[7] = " worldPos="; obj[8] = DescribeVector(captured.WorldPosition); obj[9] = " worldEuler="; val = captured.WorldRotation; obj[10] = DescribeEuler(((Quaternion)(ref val)).eulerAngles); obj[11] = " worldScale="; obj[12] = DescribeVector(captured.WorldScale); obj[13] = "]"; return string.Concat(obj); } private static string DescribeCurrentSeamPose(Transform transform) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) if ((Object)(object)transform == (Object)null) { return ""; } try { string[] obj = new string[13] { "[localPos=", DescribeVector(transform.localPosition), " localEuler=", DescribeEuler(transform.localEulerAngles), " localScale=", DescribeVector(transform.localScale), " worldPos=", DescribeVector(transform.position), " worldEuler=", null, null, null, null }; Quaternion rotation = transform.rotation; obj[9] = DescribeEuler(((Quaternion)(ref rotation)).eulerAngles); obj[10] = " worldScale="; obj[11] = DescribeVector(transform.lossyScale); obj[12] = "]"; return string.Concat(obj); } catch (Exception ex) { return ""; } } private static string DescribeCapturedEuler(bool captured, Quaternion rotation) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!captured) { return ""; } return DescribeEuler(((Quaternion)(ref rotation)).eulerAngles); } private static string DescribeEuler(Vector3 euler) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({euler.x:0.######},{euler.y:0.######},{euler.z:0.######})"; } private static Vector3 DescribeEulerDeviation(Vector3 current, Vector3 rest) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_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_0033: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.DeltaAngle(rest.x, current.x), Mathf.DeltaAngle(rest.y, current.y), Mathf.DeltaAngle(rest.z, current.z)); } private static string DescribeVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.######},{value.y:0.######},{value.z:0.######})"; } private static double LapMilliseconds(SeamPhaseStopwatch stopwatch) { return stopwatch?.LapMilliseconds() ?? 0.0; } private void RetryDeferredCameraBaselineCapture() { if (!hasCameraPlayerLocalBaseline && cameraBaselineDeferredFramesRemaining > 0) { cameraBaselineDeferredFramesRemaining--; CaptureLocalCameraBaseline(deferredRetry: true); if (hasCameraPlayerLocalBaseline) { StartLocalCameraPositionStabilizer(context?.Manifest?.body); } } } private void DetectUnsafeCameraDisplacement(float deltaTime) { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) if (!StopOnGameplayCameraDisplacement || !hasCameraPlayerLocalBaseline || requestedStopReason.HasValue) { return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform == (Object)null || (Object)(object)val.gameplayCamera == (Object)null) { if (cameraGuardEvaluationUnavailableLogged) { return; } cameraGuardEvaluationUnavailableLogged = true; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.evaluation_unavailable: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + $"playerPresent={(Object)(object)val != (Object)null} playerTransformPresent={(Object)(object)((val != null) ? ((Component)val).transform : null) != (Object)null} " + $"gameplayCameraPresent={(Object)(object)val?.gameplayCamera != (Object)null} " + "action='continue_without_guard_evaluation'.")); } } return; } Vector3 current = ((Component)val).transform.InverseTransformPoint(((Component)val.gameplayCamera).transform.position); if (EvaluateStanceViewpointInvariant(val, current, deltaTime)) { return; } float displacement = Vector3.Distance(current, cameraPlayerLocalPositionAtStart); if (displacement <= 1.25f) { return; } float currentDisplacementFromVanillaRest = Vector3.Distance(current, VanillaCameraPlayerLocalRestExpectation); if (LocalCameraOwnedExternally) { if (consumerOwnedCameraLogged) { return; } consumerOwnedCameraLogged = true; InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.guard_exempt: " + BuildMeasurements() + " action='continue_exempt'.")); } } return; } if (cameraGuardPreExistingDisplacementDetected && currentDisplacementFromVanillaRest <= cameraBaselineDisplacementFromVanillaRest) { if (cameraGuardPreExistingSuppressionLogged) { return; } cameraGuardPreExistingSuppressionLogged = true; InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.pre_existing_displacement: " + BuildMeasurements() + " phase='tick' action='continue_pre_existing_not_worsened'.")); } } return; } if (currentDisplacementFromVanillaRest <= 1.25f) { if (cameraGuardVanillaRestEnvelopeSuppressionLogged) { return; } cameraGuardVanillaRestEnvelopeSuppressionLogged = true; InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.continue: " + BuildMeasurements() + " action='continue_within_vanilla_rest_envelope'.")); } } return; } requestedStopReason = InteractionAnimationStopReason.PresenterFailure; cameraGuardRequestedStop = true; InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogError((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.stop: " + BuildMeasurements() + " action='stop_genuinely_new_displacement'.")); } } string BuildMeasurements() { //IL_0071: 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_009c: Unknown result type (might be due to invalid IL or missing references) return string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + $"displacement={displacement:0.###} threshold={1.25f:0.###} " + "baseline=" + DescribeVector(cameraPlayerLocalPositionAtStart) + " current=" + DescribeVector(current) + " vanilla_rest_expectation=" + DescribeVector(VanillaCameraPlayerLocalRestExpectation) + " " + $"baseline_displacement_from_vanilla_rest={cameraBaselineDisplacementFromVanillaRest:0.###} " + $"current_displacement_from_vanilla_rest={currentDisplacementFromVanillaRest:0.###} " + "baseline_source='try_start_pre_controller' " + $"pre_existing_displacement={cameraGuardPreExistingDisplacementDetected} " + $"baseline_contaminated={cameraGuardBaselineContaminated}"; } } private bool EvaluateStanceViewpointInvariant(PlayerControllerB player, Vector3 cameraPlayerLocal, float deltaTime) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) bool isCrouching; bool inSpecialInteractAnimation; try { isCrouching = player.isCrouching; inSpecialInteractAnimation = player.inSpecialInteractAnimation; } catch { return false; } if (inSpecialInteractAnimation) { stanceViewpointMismatchSeconds = 0f; return false; } int num; if (hasStanceViewpointLastCrouchState) { num = ((stanceViewpointLastCrouchState != isCrouching) ? 1 : 0); if (num == 0) { goto IL_0051; } } else { num = 1; } hasStanceViewpointLastCrouchState = true; stanceViewpointLastCrouchState = isCrouching; goto IL_0051; IL_0051: float num2 = (isCrouching ? 1.17f : VanillaCameraPlayerLocalRestExpectation.y); float num3 = Mathf.Abs(cameraPlayerLocal.y - num2); if (!StanceViewpointGuardMath.HasSustainedMismatch((byte)num != 0, exempt: false, num3, 0.15f, deltaTime, 0.5f, ref stanceViewpointMismatchSeconds)) { return false; } string text = string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + $"crouching={isCrouching} camera_player_local_y={cameraPlayerLocal.y:0.###} " + $"expected_height={num2:0.###} height_deviation={num3:0.###} " + $"tolerance={0.15f:0.###} " + $"sustained_seconds={stanceViewpointMismatchSeconds:0.###} " + $"required_seconds={0.5f:0.###}"; if (LocalCameraOwnedExternally) { if (!stanceViewpointGuardExemptLogged) { stanceViewpointGuardExemptLogged = true; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.stance_mismatch_exempt: " + text + " action='continue_exempt'.")); } } } return false; } requestedStopReason = InteractionAnimationStopReason.PresenterFailure; cameraGuardRequestedStop = true; InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogError((object)("[LCInteractionAnimationAPI] live_body.camera_displacement_guard.stop: " + text + " action='stop_stance_mismatched_viewpoint_height'.")); } } return true; } private void CaptureScopedFirstPersonPose(InteractionAnimationManifest.BodyManifest body) { scopedFirstPersonPoseSnapshot = null; if (body == null) { return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)GameNetworkManager.Instance?.localPlayerController || (Object)(object)val.playerModelArmsMetarig == (Object)null) { return; } scopedFirstPersonPoseSnapshot = TransformPoseSnapshot.CaptureSubtree(val.playerModelArmsMetarig); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.scoped_fp_pose_captured: " + $"handle={context.Handle} transforms={scopedFirstPersonPoseSnapshot.Count} " + "includesMetarigRoot=True.")); } } } private void CaptureRigControlPose() { rigControlPoseSnapshot = null; rigControlRoot = null; if (!InteractionAnimationApiRestoreDiagnostics.RestoreRigControlPoseEnabled) { return; } try { PlayerControllerB val = context?.Request?.Player; Transform root = (((Object)(object)val != (Object)null) ? val.playerModelArmsMetarig : null); rigControlRoot = FindChildRecursive(root, "RigArms"); if ((Object)(object)rigControlRoot == (Object)null) { return; } rigControlPoseSnapshot = TransformPoseSnapshot.CaptureSubtree(rigControlRoot); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.rigpose] captured: " + $"handle={context.Handle} transforms={rigControlPoseSnapshot.Count}.")); } } } catch (Exception ex) { rigControlPoseSnapshot = null; rigControlRoot = null; InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[RestoreSeam.rigpose] capture_failed: handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private void RestoreRigControlPose() { if ((Object)(object)rigControlRoot == (Object)null) { return; } HashSet hashSet = new HashSet(); int restored = 0; bool flag = false; try { flag = InteractionAnimationApiRestoreDiagnostics.TryRestorePristineRigControlPose(context?.Request?.Player, rigControlRoot, hashSet, out restored); } catch (Exception ex) { hashSet.Clear(); restored = 0; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[RestoreSeam.rigpose] pristine_restore_dispatch_failed: handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } int num = ((rigControlPoseSnapshot != null) ? rigControlPoseSnapshot.RestoreExcept(hashSet) : 0); InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.rigpose] restored: " + $"handle={context.Handle} pristineBaselineUsed={flag} " + $"pristineRestored={restored} " + $"equipFallbackRestored={num} " + $"equipCaptured={((rigControlPoseSnapshot != null) ? rigControlPoseSnapshot.Count : 0)}.")); } } } private void CaptureThirdPersonRigControlPose() { thirdPersonRigControlPoseSnapshot = null; PlayerControllerB val = context?.Request?.Player; bool flag = IsLocalPlayer(val); if (!InteractionAnimationApiRestoreDiagnostics.RestoreThirdPersonRigControlPoseEnabled) { ManualLogSource restoreLogger = RestoreLogger; if (restoreLogger != null) { restoreLogger.LogInfo((object)("[RestoreSeam.tprig] capture_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"localPlayer={flag} enabled=False " + "reason='kill_switch_disabled' action='leave_third_person_rig_unchanged'.")); } return; } if ((Object)(object)val == (Object)null || (Object)(object)val.playerBodyAnimator == (Object)null) { ManualLogSource restoreLogger2 = RestoreLogger; if (restoreLogger2 != null) { restoreLogger2.LogInfo((object)("[RestoreSeam.tprig] capture_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"localPlayer={flag} enabled=True " + $"playerPresent={(Object)(object)val != (Object)null} animatorPresent={(Object)(object)val?.playerBodyAnimator != (Object)null} " + "reason='player_or_animator_missing' action='restore_unavailable'.")); } return; } try { thirdPersonRigControlPoseSnapshot = InteractionAnimationApiRestoreDiagnostics.CaptureThirdPersonRigControlPose(val); if (thirdPersonRigControlPoseSnapshot == null || thirdPersonRigControlPoseSnapshot.TotalCount == 0) { thirdPersonRigControlPoseSnapshot = null; ManualLogSource restoreLogger3 = RestoreLogger; if (restoreLogger3 != null) { restoreLogger3.LogInfo((object)("[RestoreSeam.tprig] capture_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"localPlayer={flag} enabled=True " + "reason='third_person_rig_unavailable' action='restore_unavailable'.")); } return; } ManualLogSource restoreLogger4 = RestoreLogger; if (restoreLogger4 != null) { restoreLogger4.LogInfo((object)("[RestoreSeam.tprig] captured: " + $"frame={Time.frameCount} handle={context.Handle} " + $"localPlayer={flag} enabled=True " + $"complete={thirdPersonRigControlPoseSnapshot.IsComplete} " + "missing='" + thirdPersonRigControlPoseSnapshot.MissingTargets + "' " + $"fullPoseTransforms={thirdPersonRigControlPoseSnapshot.FullPoseCount} " + $"rotationOnlyTransforms={thirdPersonRigControlPoseSnapshot.RotationOnlyCount} " + "source='session_entry_equip_fallback'.")); } } catch (Exception ex) { thirdPersonRigControlPoseSnapshot = null; ManualLogSource restoreLogger5 = RestoreLogger; if (restoreLogger5 != null) { restoreLogger5.LogInfo((object)("[RestoreSeam.tprig] capture_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"localPlayer={flag} enabled=True " + "reason='capture_failed:" + ex.Message + "' action='restore_unavailable'.")); } } } private void RestoreThirdPersonRigControlPose(bool animatorRestored) { PlayerControllerB player = context?.Request?.Player; bool flag = IsLocalPlayer(player); if (!InteractionAnimationApiRestoreDiagnostics.RestoreThirdPersonRigControlPoseEnabled) { ManualLogSource restoreLogger = RestoreLogger; if (restoreLogger != null) { restoreLogger.LogInfo((object)("[RestoreSeam.tprig] restore_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"localPlayer={flag} enabled=False " + "reason='kill_switch_disabled' action='leave_third_person_rig_unchanged'.")); } return; } if (!animatorRestored) { ManualLogSource restoreLogger2 = RestoreLogger; if (restoreLogger2 != null) { restoreLogger2.LogInfo((object)("[RestoreSeam.tprig] restore_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"localPlayer={flag} enabled=True " + "reason='animator_ownership_restore_rejected' action='respect_external_owner'.")); } return; } if (thirdPersonRigControlPoseSnapshot == null) { ManualLogSource restoreLogger3 = RestoreLogger; if (restoreLogger3 != null) { restoreLogger3.LogInfo((object)("[RestoreSeam.tprig] restore_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"localPlayer={flag} enabled=True " + "reason='session_entry_snapshot_unavailable' action='leave_third_person_rig_unchanged'.")); } return; } HashSet hashSet = new HashSet(); int fullPoseRestored = 0; int rotationOnlyRestored = 0; bool flag2 = false; string gateReason; try { flag2 = InteractionAnimationApiRestoreDiagnostics.TryRestorePristineThirdPersonRigControlPose(player, hashSet, out fullPoseRestored, out rotationOnlyRestored, out gateReason); } catch (Exception ex) { hashSet.Clear(); fullPoseRestored = 0; rotationOnlyRestored = 0; gateReason = "dispatch_failed:" + ex.Message; } ManualLogSource restoreLogger4 = RestoreLogger; if (restoreLogger4 != null) { restoreLogger4.LogInfo((object)("[RestoreSeam.tprig] pristine_restore_gate: " + $"frame={Time.frameCount} handle={context.Handle} " + $"localPlayer={flag} " + $"enabled={InteractionAnimationApiRestoreDiagnostics.RestorePristineThirdPersonRigControlPoseEnabled} " + $"baselineUsed={flag2} reason='{gateReason}' " + $"fullPoseRestored={fullPoseRestored} " + $"rotationOnlyRestored={rotationOnlyRestored}.")); } int fullPoseRestored2; int rotationOnlyRestored2; try { thirdPersonRigControlPoseSnapshot.RestoreExcept(hashSet, null, out fullPoseRestored2, out rotationOnlyRestored2); } catch (Exception ex2) { ManualLogSource restoreLogger5 = RestoreLogger; if (restoreLogger5 != null) { restoreLogger5.LogInfo((object)("[RestoreSeam.tprig] restore_failed: " + $"frame={Time.frameCount} handle={context.Handle} " + $"localPlayer={flag} enabled=True " + "reason='equip_fallback_failed:" + ex2.Message + "' action='continue_teardown'.")); } return; } ManualLogSource restoreLogger6 = RestoreLogger; if (restoreLogger6 != null) { restoreLogger6.LogInfo((object)("[RestoreSeam.tprig] restored: " + $"frame={Time.frameCount} handle={context.Handle} " + $"localPlayer={flag} enabled=True " + $"pristineBaselineUsed={flag2} " + $"pristineFullPoseRestored={fullPoseRestored} " + $"pristineRotationOnlyRestored={rotationOnlyRestored} " + $"equipFallbackFullPoseRestored={fullPoseRestored2} " + $"equipFallbackRotationOnlyRestored={rotationOnlyRestored2} " + $"equipCaptured={thirdPersonRigControlPoseSnapshot.TotalCount}.")); } } private void ApplyStanceRestHeightSnap(PlayerControllerB player, bool crouching, InteractionAnimationStopReason stopReason, string phase) { //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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.gameplayCamera == (Object)null || (Object)(object)((Component)player).transform == (Object)null) { return; } Vector3 val = ((Component)player).transform.InverseTransformPoint(((Component)player.gameplayCamera).transform.position); float num = StanceRestHeight(crouching); ((Component)player.gameplayCamera).transform.position = ((Component)player).transform.TransformPoint(new Vector3(val.x, num, val.z)); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerachain] stance_rest_snap_applied: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"phase='{phase}' stopReason='{stopReason}' crouching={crouching} " + "beforePlayerLocal=" + DescribeVector(val) + " " + $"stanceRestHeight={num:0.###} " + "reason='displacement_guard_stop' action='snap_to_stance_rest_height'.")); } } } private void ApplyCameraChainPositionSnapToRest(InteractionAnimationStopReason stopReason) { //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) if (!PreserveGameplayCamera) { return; } if (!InteractionAnimationApiRestoreDiagnostics.RestoreCameraChainPositionSnapToRestEnabled) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.camerachain] snap_skipped: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='kill_switch_disabled' action='leave_camera_chain'.")); } } return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || !IsLocalPlayer(val)) { return; } if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.camerachain] snap_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + "reason='local_camera_owned_externally' action='leave_camera_chain'.")); } } return; } try { bool flag = false; bool flag2 = false; try { flag = val.isCrouching; flag2 = val.inSpecialInteractAnimation; } catch { } bool flag3 = cameraGuardRequestedStop || stopReason == InteractionAnimationStopReason.PresenterFailure; bool flag4 = flag && !flag2; if (flag2 && !flag3) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.camerachain] snap_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"crouching={flag} specialAnimation={flag2} " + "reason='legitimately_displaced_state' action='leave_camera_chain'.")); } } return; } Vector3 value = (((Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val).transform.InverseTransformPoint(((Component)val.gameplayCamera).transform.position) : Vector3.zero); if (flag3) { ApplyStanceRestHeightSnap(val, flag, stopReason, "pre_pristine"); } if (!InteractionAnimationApiRestoreDiagnostics.TryRestorePristineCameraChainPositions(val, out var restored, out var reason, out var source)) { if (flag3) { cameraPositionStabilizer?.RetargetToCurrentPosition(); } InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.camerachain] snap_skipped: " + $"frame={Time.frameCount} handle={context.Handle} " + $"reason='{reason}' guardStop={flag3} action='leave_camera_chain'.")); } } return; } if ((flag3 || flag4) && flag) { ApplyStanceRestHeightSnap(val, crouching: true, stopReason, "post_pristine"); } Vector3 value2 = (((Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val).transform.InverseTransformPoint(((Component)val.gameplayCamera).transform.position) : Vector3.zero); bool flag5 = false; if ((Object)(object)cameraPositionStabilizer != (Object)null) { cameraPositionStabilizer.RetargetToCurrentPosition(); flag5 = true; } InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogInfo((object)("[RestoreSeam.camerachain] snap_applied: " + $"frame={Time.frameCount} handle={context.Handle} " + $"restoredTransforms={restored} " + "beforePlayerLocal=" + DescribeVector(value) + " afterPlayerLocal=" + DescribeVector(value2) + " source='" + source + "' " + $"stabilizerRetargeted={flag5}.")); } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogWarning((object)("[RestoreSeam.camerachain] snap_failed: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private void ApplyVanillaLocalArmsGlueBeforeRigEvaluation() { //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (!InteractionAnimationApiRestoreDiagnostics.RestoreVanillaArmsGlueEnabled) { return; } PlayerControllerB val = context?.Request?.Player; if (!IsLocalPlayer(val)) { return; } try { bool inSpecialInteractAnimation = val.inSpecialInteractAnimation; bool localArmsMatchCamera = val.localArmsMatchCamera; string text = (inSpecialInteractAnimation ? "specialanim" : (localArmsMatchCamera ? "lateupdate" : "update")); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.armsglue] gates: " + $"frame={Time.frameCount} handle={context.Handle} " + $"inSpecialInteractAnimation={inSpecialInteractAnimation} " + $"localArmsMatchCamera={localArmsMatchCamera} branch={text}.")); } } Transform playerModelArmsMetarig = val.playerModelArmsMetarig; if ((Object)(object)playerModelArmsMetarig == (Object)null) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[RestoreSeam.armsglue] required_transform_missing: " + $"frame={Time.frameCount} handle={context.Handle} branch={text} " + "missing='playerModelArmsMetarig'.")); } } return; } if (inSpecialInteractAnimation) { playerModelArmsMetarig.localEulerAngles = new Vector3(-90f, 0f, 0f); return; } bool flag = true; try { flag = IngamePlayerSettings.Instance.settings.headBobbing; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[RestoreSeam.armsglue] head_bob_read_failed: " + $"frame={Time.frameCount} handle={context.Handle} " + "branch=" + text + " error='" + ex.Message + "'.")); } } } Transform cameraContainerTransform = val.cameraContainerTransform; if (!flag && (Object)(object)cameraContainerTransform != (Object)null && (Object)(object)playerModelArmsMetarig != (Object)null) { cameraContainerTransform.position = new Vector3(cameraContainerTransform.position.x, playerModelArmsMetarig.position.y, cameraContainerTransform.position.z); } else if (!flag) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogWarning((object)("[RestoreSeam.armsglue] camera_y_pin_transform_missing: " + $"frame={Time.frameCount} handle={context.Handle} branch={text} " + $"cameraContainerPresent={(Object)(object)cameraContainerTransform != (Object)null}.")); } } } Transform localArmsTransform = val.localArmsTransform; Transform localArmsRotationTarget = val.localArmsRotationTarget; if ((Object)(object)localArmsTransform == (Object)null || (Object)(object)localArmsRotationTarget == (Object)null) { InteractionAnimationContext interactionAnimationContext5 = context; if (interactionAnimationContext5 != null) { ManualLogSource logger5 = interactionAnimationContext5.Logger; if (logger5 != null) { logger5.LogWarning((object)("[RestoreSeam.armsglue] required_transform_missing: " + $"frame={Time.frameCount} handle={context.Handle} branch={text} " + $"localArmsPresent={(Object)(object)localArmsTransform != (Object)null} " + $"rotationTargetPresent={(Object)(object)localArmsRotationTarget != (Object)null}.")); } } return; } if (localArmsMatchCamera) { Camera gameplayCamera = val.gameplayCamera; if ((Object)(object)cameraContainerTransform == (Object)null || (Object)(object)gameplayCamera == (Object)null) { InteractionAnimationContext interactionAnimationContext6 = context; if (interactionAnimationContext6 != null) { ManualLogSource logger6 = interactionAnimationContext6.Logger; if (logger6 != null) { logger6.LogWarning((object)("[RestoreSeam.armsglue] required_transform_missing: " + $"frame={Time.frameCount} handle={context.Handle} branch={text} " + $"cameraContainerPresent={(Object)(object)cameraContainerTransform != (Object)null} " + $"gameplayCameraPresent={(Object)(object)gameplayCamera != (Object)null}.")); } } return; } localArmsTransform.position = cameraContainerTransform.position + ((Component)gameplayCamera).transform.up * -0.5f; } else { localArmsTransform.position = playerModelArmsMetarig.position + playerModelArmsMetarig.forward * -0.445f; } playerModelArmsMetarig.rotation = localArmsRotationTarget.rotation; } catch (Exception ex2) { InteractionAnimationContext interactionAnimationContext7 = context; if (interactionAnimationContext7 != null) { ManualLogSource logger7 = interactionAnimationContext7.Logger; if (logger7 != null) { logger7.LogWarning((object)("[RestoreSeam.armsglue] apply_failed: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex2.Message + "'.")); } } } } private void RestoreScopedFirstPersonPose() { if (scopedFirstPersonPoseSnapshot == null) { return; } int num = scopedFirstPersonPoseSnapshot.Restore(); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.scoped_fp_pose_restored: " + $"handle={context.Handle} restored={num} " + $"captured={scopedFirstPersonPoseSnapshot.Count}.")); } } } public bool TrySetAnimatorParameter(string parameterName, AnimatorControllerParameterType parameterType, float value) { //IL_0020: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 if (!active || (Object)(object)bodyAnimator == (Object)null || string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, parameterType)) { return false; } try { switch (parameterType - 1) { default: if ((int)parameterType != 9) { break; } bodyAnimator.ResetTrigger(parameterName); bodyAnimator.SetTrigger(parameterName); return true; case 3: bodyAnimator.SetBool(parameterName, value != 0f); return true; case 2: bodyAnimator.SetInteger(parameterName, (int)value); return true; case 0: bodyAnimator.SetFloat(parameterName, value); return true; case 1: break; } return false; } catch { return false; } } public float BeginExit() { InteractionAnimationManifest.BodyManifest bodyManifest = context?.Manifest?.body; if (!active || (Object)(object)bodyAnimator == (Object)null || bodyManifest == null || exitRequested) { return 0f; } exitRequested = true; SetBoolIfExists(bodyManifest.activeBool, value: false); FireTriggerIfExists(bodyManifest.exitTrigger); float num = Mathf.Max(0f, bodyManifest.exitSeconds); exitElapsedSeconds = 0f; exitDurationSeconds = num; exitStartFullBodyWeight = GetLayerWeightOrZero(fullBodyLayerIndex); exitStartFirstPersonWeight = GetLayerWeightOrZero(firstPersonLayerIndex); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.exit_begun: " + $"handle={context.Handle} exitSeconds={num:0.###}.")); } } return num; } private LocomotionState ResolveLocomotionState() { if (locomotionStateFrame == Time.frameCount) { return locomotionStateCache; } PlayerControllerB player = context?.Request?.Player; LocomotionState result = (IsLocalPlayer(player) ? ResolveLocalLocomotionState(player) : ResolveRemoteLocomotionState(player)); locomotionStateFrame = Time.frameCount; locomotionStateCache = result; return result; } private static LocomotionState ResolveLocalLocomotionState(PlayerControllerB player) { //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) bool sprinting = false; bool crouching = false; try { sprinting = player.isSprinting; } catch { } try { crouching = player.isCrouching; } catch { } float num = 0f; try { if ((Object)(object)player.thisController != (Object)null) { Vector3 velocity = player.thisController.velocity; velocity.y = 0f; num = ((Vector3)(ref velocity)).magnitude; } } catch { } object obj4 = null; try { obj4 = VanillaIsWalkingField?.GetValue(player); } catch { } bool walking; string source; if (obj4 is bool flag) { walking = flag; source = "vanilla_isWalking_field"; } else { walking = num > 0.2f; source = "horizontal_velocity_fallback"; } bool jumping = false; bool jumpingKnown = false; try { if (VanillaIsJumpingField?.GetValue(player) is bool flag2) { jumping = flag2; jumpingKnown = true; } } catch { } return new LocomotionState(walking, sprinting, crouching, jumping, jumpingKnown, num, source); } private LocomotionState ResolveRemoteLocomotionState(PlayerControllerB player) { //IL_0063: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { hasRemoteLocomotionSample = false; return new LocomotionState(walking: false, sprinting: false, crouching: false, jumping: false, jumpingKnown: false, 0f, "remote_player_unavailable"); } bool crouching = false; try { crouching = player.isCrouching; } catch { } float num = remoteLocomotionSmoothedSpeed; string source = "remote_position_delta"; try { Transform transform = ((Component)player).transform; if ((Object)(object)transform == (Object)null) { hasRemoteLocomotionSample = false; source = "remote_transform_unavailable"; } else { Vector3 localPosition = transform.localPosition; float time = Time.time; if (!hasRemoteLocomotionSample) { hasRemoteLocomotionSample = true; remoteLocomotionSmoothedSpeed = 0f; num = 0f; source = "remote_position_delta_priming"; } else { float num2 = time - remoteLocomotionLastSampleTime; if (num2 > 0.0001f) { Vector3 val = localPosition - remoteLocomotionLastLocalPosition; val.y = 0f; float num3 = ((Vector3)(ref val)).magnitude / num2; remoteLocomotionSmoothedSpeed = Mathf.Lerp(remoteLocomotionSmoothedSpeed, num3, Mathf.Clamp01(num2 * 12f)); num = remoteLocomotionSmoothedSpeed; } } remoteLocomotionLastLocalPosition = localPosition; remoteLocomotionLastSampleTime = time; } } catch { hasRemoteLocomotionSample = false; source = "remote_position_delta_failed"; } remoteLocomotionWalking = (remoteLocomotionWalking ? (num > 0.15f) : (num > 0.35f)); remoteLocomotionSprinting = (remoteLocomotionSprinting ? (num > 4.5f) : (num > 5.5f)); return new LocomotionState(remoteLocomotionWalking, remoteLocomotionWalking && remoteLocomotionSprinting, crouching, jumping: false, jumpingKnown: false, num, source); } private void SyncVanillaLocomotionParameters(string phase) { PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || (Object)(object)bodyAnimator == (Object)null) { return; } try { LocomotionState locomotionState = ResolveLocomotionState(); bool walking = locomotionState.Walking; bool sprinting = locomotionState.Sprinting; bool crouching = locomotionState.Crouching; bool jumping = locomotionState.Jumping; string source = locomotionState.Source; SetBoolIfExists("Walking", walking); SetBoolIfExists("Sprinting", walking && sprinting); SetBoolIfExists("crouching", crouching); if (locomotionState.JumpingKnown) { SetBoolIfExists("Jumping", jumping); } if (!walking) { SetBoolIfExists("Sideways", value: false); } if (hasLastSyncedCrouchState && crouching != lastSyncedCrouchState) { if (crouching) { FireTriggerIfExists("startCrouching"); } else { ResetTriggerIfExists("startCrouching"); } if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.locomotion] crouch_edge_trigger: " + $"frame={Time.frameCount} handle={context.Handle} phase='{phase}' " + $"crouching={crouching} " + "action='" + (crouching ? "fire" : "reset") + "_startCrouching'.")); } } } } hasLastSyncedCrouchState = true; lastSyncedCrouchState = crouching; int num = (int)((walking ? 1u : 0u) | (uint)(sprinting ? 2 : 0) | (uint)(crouching ? 4 : 0)) | (jumping ? 8 : 0); bool flag = string.Equals(phase, "tick", StringComparison.Ordinal); if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled && (!flag || num != lastLocomotionSyncSignature)) { bool flag2 = IsLocalPlayer(val); string arg = ""; try { arg = val.playerClientId.ToString(); } catch { } InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.locomotion] parameters_synced: " + $"frame={Time.frameCount} handle={context.Handle} phase='{phase}' " + $"playerId={arg} localPlayer={flag2} " + $"walking={walking} walkingSource='{source}' " + $"horizontalSpeed={locomotionState.HorizontalSpeed:0.###} " + $"sprinting={sprinting} crouching={crouching} " + $"jumping={jumping} jumpingKnown={locomotionState.JumpingKnown}.")); } } } lastLocomotionSyncSignature = num; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[RestoreSeam.locomotion] parameters_sync_failed: " + $"frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " phase='" + phase + "' error='" + ex.Message + "'.")); } } } } private void DriveMovementParameter() { InteractionAnimationManifest.BodyManifest bodyManifest = context?.Manifest?.body; if (bodyManifest == null || string.IsNullOrWhiteSpace(bodyManifest.movementParameter) || exitRequested || (Object)(object)context?.Request?.Player == (Object)null) { return; } int num = 0; try { LocomotionState locomotionState = ResolveLocomotionState(); if (locomotionState.HorizontalSpeed > 0.2f) { num = ((!locomotionState.Sprinting) ? 1 : 2); } } catch { num = 0; } if (num != lastMovementValue) { int num2 = lastMovementValue; if (num2 == 2 && num != 2) { FinishPlaybackRateProbe("movement_changed"); } lastMovementValue = num; try { bodyAnimator.SetInteger(bodyManifest.movementParameter, num); } catch { } if (num == 2 && num2 != 2) { ResetPlaybackRateProbe(); } } } private void ResetLocomotionStateResolution() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) locomotionStateFrame = -1; locomotionStateCache = default(LocomotionState); hasRemoteLocomotionSample = false; remoteLocomotionLastLocalPosition = Vector3.zero; remoteLocomotionLastSampleTime = 0f; remoteLocomotionSmoothedSpeed = 0f; remoteLocomotionWalking = false; remoteLocomotionSprinting = false; } private void ResetPlaybackRateProbe() { playbackRateHasBaseline = false; playbackRateLayerIndex = -1; playbackRateFullPathHash = 0; playbackRateShortNameHash = 0; playbackRateBaselineNormalizedTime = 0f; playbackRateBaselineTimestamp = 0L; playbackRateStateSegments = 0; playbackRateMeasuredWallSeconds = 0.0; playbackRateNormalizedCycles = 0.0; playbackRateClipSeconds = 0.0; playbackRateCompletedCycles = 0; playbackRateFailureLogged = false; } private int ResolvePlaybackRateLayerIndex() { if ((Object)(object)bodyAnimator == (Object)null || bodyAnimator.layerCount <= 0) { return -1; } if (firstPersonLayerIndex >= 0 && firstPersonLayerIndex < bodyAnimator.layerCount) { return firstPersonLayerIndex; } if (fullBodyLayerIndex >= 0 && fullBodyLayerIndex < bodyAnimator.layerCount) { return fullBodyLayerIndex; } return 0; } private void BeginPlaybackRateSegment(int layerIndex, AnimatorStateInfo stateInfo, long timestamp) { playbackRateHasBaseline = true; playbackRateLayerIndex = layerIndex; playbackRateFullPathHash = ((AnimatorStateInfo)(ref stateInfo)).fullPathHash; playbackRateShortNameHash = ((AnimatorStateInfo)(ref stateInfo)).shortNameHash; playbackRateBaselineNormalizedTime = ((AnimatorStateInfo)(ref stateInfo)).normalizedTime; playbackRateBaselineTimestamp = timestamp; playbackRateStateSegments++; float num = (((Object)(object)bodyAnimator != (Object)null) ? bodyAnimator.speed : 0f); float num2 = num * ((AnimatorStateInfo)(ref stateInfo)).speed * ((AnimatorStateInfo)(ref stateInfo)).speedMultiplier; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.playback_rate_segment_started: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + $"movement=2 layer={layerIndex} fullPathHash={((AnimatorStateInfo)(ref stateInfo)).fullPathHash} " + $"shortNameHash={((AnimatorStateInfo)(ref stateInfo)).shortNameHash} normalizedTime={((AnimatorStateInfo)(ref stateInfo)).normalizedTime:0.######} " + $"stateLengthSeconds={((AnimatorStateInfo)(ref stateInfo)).length:0.######} looping={((AnimatorStateInfo)(ref stateInfo)).loop} " + $"animatorSpeed={num:0.######} stateSpeed={((AnimatorStateInfo)(ref stateInfo)).speed:0.######} " + $"stateSpeedMultiplier={((AnimatorStateInfo)(ref stateInfo)).speedMultiplier:0.######} " + $"expectedClipSecondsPerWallSecond={num2:0.######}.")); } } } private void SamplePlaybackRateProgression(bool force = false) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if (lastMovementValue != 2 || (Object)(object)bodyAnimator == (Object)null) { return; } int num = ResolvePlaybackRateLayerIndex(); if (num < 0) { return; } try { if (bodyAnimator.IsInTransition(num)) { return; } AnimatorStateInfo currentAnimatorStateInfo = bodyAnimator.GetCurrentAnimatorStateInfo(num); long timestamp = Stopwatch.GetTimestamp(); if (!playbackRateHasBaseline || playbackRateLayerIndex != num || playbackRateFullPathHash != ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash) { BeginPlaybackRateSegment(num, currentAnimatorStateInfo, timestamp); return; } double num2 = (double)(timestamp - playbackRateBaselineTimestamp) / (double)Stopwatch.Frequency; if (num2 < 0.05 || (!force && num2 < 1.0)) { return; } float speed = bodyAnimator.speed; if (!AnimatorPlaybackRateMath.TryMeasure(playbackRateBaselineNormalizedTime, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, num2, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length, speed, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).speed, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).speedMultiplier, out var measurement)) { BeginPlaybackRateSegment(num, currentAnimatorStateInfo, timestamp); return; } playbackRateMeasuredWallSeconds += measurement.WallSeconds; playbackRateNormalizedCycles += measurement.NormalizedCyclesAdvanced; playbackRateClipSeconds += measurement.ClipSecondsAdvanced; playbackRateCompletedCycles += measurement.CompletedCycles; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.playback_rate_sample: " + string.Format("handle={0} interaction='{1}' ", context.Handle, context.Manifest?.interactionId ?? "") + "movement=2 sampleKind='" + (force ? "final" : "interval") + "' " + $"layer={num} fullPathHash={playbackRateFullPathHash} " + $"shortNameHash={playbackRateShortNameHash} " + $"wallSeconds={measurement.WallSeconds:0.######} " + $"normalizedCyclesAdvanced={measurement.NormalizedCyclesAdvanced:0.######} " + $"completedCycles={measurement.CompletedCycles} " + $"effectiveCyclesPerSecond={measurement.EffectiveCyclesPerSecond:0.######} " + $"effectiveClipSecondsPerWallSecond={measurement.EffectiveClipSecondsPerWallSecond:0.######} " + $"expectedClipSecondsPerWallSecond={measurement.ExpectedClipSecondsPerWallSecond:0.######} " + $"effectiveToExpectedRatio={measurement.EffectiveToExpectedRatio:0.######} " + $"animatorSpeed={speed:0.######} stateSpeed={((AnimatorStateInfo)(ref currentAnimatorStateInfo)).speed:0.######} " + $"stateSpeedMultiplier={((AnimatorStateInfo)(ref currentAnimatorStateInfo)).speedMultiplier:0.######}.")); } } playbackRateBaselineNormalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime; playbackRateBaselineTimestamp = timestamp; } catch (Exception ex) { if (playbackRateFailureLogged) { return; } playbackRateFailureLogged = true; InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[LCInteractionAnimationAPI] live_body.playback_rate_unavailable: handle=" + ((context != null) ? context.Handle.ToString() : "") + " reason='" + ex.Message + "'.")); } } } } private void FinishPlaybackRateProbe(string reason) { if (lastMovementValue == 2) { SamplePlaybackRateProgression(force: true); } if (playbackRateMeasuredWallSeconds >= 0.05) { double num = playbackRateClipSeconds / playbackRateMeasuredWallSeconds; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.playback_rate_summary: handle=" + ((context != null) ? context.Handle.ToString() : "") + " interaction='" + (context?.Manifest?.interactionId ?? "") + "' movement=2 " + $"reason='{reason}' stateSegments={playbackRateStateSegments} " + $"measuredWallSeconds={playbackRateMeasuredWallSeconds:0.######} " + $"normalizedCyclesAdvanced={playbackRateNormalizedCycles:0.######} " + $"completedCycles={playbackRateCompletedCycles} " + $"clipSecondsAdvanced={playbackRateClipSeconds:0.######} " + $"effectiveClipSecondsPerWallSecond={num:0.######}.")); } } } ResetPlaybackRateProbe(); } public void Stop(InteractionAnimationStopReason stopReason) { if (!active && (Object)(object)bodyAnimator == (Object)null && (Object)(object)bundle == (Object)null) { return; } FinishPlaybackRateProbe("session_stop"); SeamPhaseStopwatch seamPhaseStopwatch = (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled ? new SeamPhaseStopwatch() : null); StopTransformChainDiagnostics(); StopExternalCameraPresentationDiagnostics(); StopLocalVisorHardGlue(); PlayerControllerB player = context?.Request?.Player; InteractionAnimationApiRestoreDiagnostics.NotifyStop(player, propInstance); StartRestoreScopedCameraPositionStabilizer(); double num = LapMilliseconds(seamPhaseStopwatch); CameraRotationSnapshot captured = CaptureSeamCameraRotation("stop"); StopLocalCameraRotationStabilizer(restoreSessionEntryRotation: true); double num2 = LapMilliseconds(seamPhaseStopwatch); VisorPoseSnapshot captured2 = CaptureSeamVisorPose("stop"); double num3 = LapMilliseconds(seamPhaseStopwatch); DestroyProp(); double num4 = LapMilliseconds(seamPhaseStopwatch); AnimatorStateRestoreMode restoreStateMode; string text = RestoreAnimator(out restoreStateMode); double num5 = LapMilliseconds(seamPhaseStopwatch); bool flag = string.Equals(text, "restored", StringComparison.Ordinal); if (flag) { SyncVanillaLocomotionParameters("stop"); RestoreScopedFirstPersonPose(); RestoreRigControlPose(); } RestoreThirdPersonRigControlPose(flag); double num6 = LapMilliseconds(seamPhaseStopwatch); InteractionAnimationApiRestoreDiagnostics.LogIkBakeProbe(player, "pre-restore-build"); double num7 = LapMilliseconds(seamPhaseStopwatch); RestoreLiveRigBuilders(); InteractionAnimationApiRestoreDiagnostics.LogRigAnimatorStates(bodyAnimator, "before_build"); RebuildRigBuilders("restore"); InteractionAnimationApiRestoreDiagnostics.LogRigAnimatorStates(bodyAnimator, "after_build"); double num8 = LapMilliseconds(seamPhaseStopwatch); ReapplySeamCameraRotation(captured, "stop", flag); ReapplySeamVisorPose(captured2, "stop", flag); if (flag) { ApplyCameraChainPositionSnapToRest(stopReason); ApplyVanillaLocalArmsGlueBeforeRigEvaluation(); } double num9 = LapMilliseconds(seamPhaseStopwatch); try { Animator obj = bodyAnimator; if (obj != null) { obj.Update(0f); } } catch { } double num10 = LapMilliseconds(seamPhaseStopwatch); EvaluateRigBuilders("restore"); double num11 = LapMilliseconds(seamPhaseStopwatch); InteractionAnimationApiRestoreDiagnostics.LogRigAnimatorStates(bodyAnimator, "after_final_update"); StopLocalCameraPositionStabilizer(restorePosition: true, deferRelease: true); InteractionAnimationApiRestoreDiagnostics.NotifyRestoreCompleted(player); ReleaseBundle(stopReason != InteractionAnimationStopReason.Shutdown); double num12 = LapMilliseconds(seamPhaseStopwatch); if (seamPhaseStopwatch != null) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.timing] " + $"phase='stop' frame={Time.frameCount} " + "handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"totalMs={seamPhaseStopwatch.TotalMilliseconds:0.###} setupMs={num:0.###} " + $"cameraCaptureMs={num2:0.###} visorCaptureMs={num3:0.###} " + $"propDestroyMs={num4:0.###} " + $"animatorRestoreMs={num5:0.###} poseRestoreMs={num6:0.###} " + $"ikProbeMs={num7:0.###} rigBuildMs={num8:0.###} " + $"seamGlueMs={num9:0.###} " + $"animatorUpdateMs={num10:0.###} rigEvaluateMs={num11:0.###} " + $"cleanupMs={num12:0.###}.")); } } } InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.restored: " + string.Format("handle={0} reason='{1}' ", (context != null) ? context.Handle.ToString() : "", stopReason) + "controllerRestore='" + text + "' restoreStateMode='" + FormatRestoreStateMode(restoreStateMode) + "'.")); } } bodyAnimator = null; appliedController = null; snapshot = null; rigControlPoseSnapshot = null; rigControlRoot = null; thirdPersonRigControlPoseSnapshot = null; scopedFirstPersonPoseSnapshot = null; suppressedRigBuilders.Clear(); rightArmIkTarget = null; leftArmIkTarget = null; rightHandBone = null; rightShoulderBone = null; propReleased = false; exitRequested = false; exitElapsedSeconds = 0f; exitDurationSeconds = 0f; exitStartFullBodyWeight = 0f; exitStartFirstPersonWeight = 0f; lastMovementValue = -1; ResetPlaybackRateProbe(); hasLastSyncedCrouchState = false; lastSyncedCrouchState = false; lastLocomotionSyncSignature = -1; ResetCameraDisplacementGuardState(); cameraPositionStabilizer = null; cameraRotationStabilizer = null; requestedStopReason = null; active = false; context = null; } private void AttachPropIfConfigured() { //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) InteractionAnimationManifest.PropManifest propManifest = context?.Manifest?.body?.prop; if (propManifest == null || !propManifest.enabled || string.IsNullOrWhiteSpace(propManifest.prefabAssetName)) { return; } AssetBundle val = (((Object)(object)clipPackBundle != (Object)null) ? clipPackBundle : bundle); if ((Object)(object)val == (Object)null) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.prop_no_asset_bundle: " + $"handle={context.Handle} prefab='{propManifest.prefabAssetName}'.")); } } return; } GameObject val2 = val.LoadAsset(propManifest.prefabAssetName); if ((Object)(object)val2 == (Object)null) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[LCInteractionAnimationAPI] live_body.prop_prefab_missing: " + $"handle={context.Handle} prefab='{propManifest.prefabAssetName}'.")); } } return; } Transform val3 = null; try { PlayerControllerB val4 = context?.Request?.Player; val3 = (((Object)(object)val4 != (Object)null && (Object)(object)val4 == (Object)(object)GameNetworkManager.Instance?.localPlayerController) ? val4.playerModelArmsMetarig : null); } catch { } Transform val5 = ResolvePropAttachBone(((Object)(object)val3 != (Object)null) ? val3 : (((Object)(object)bodyAnimator != (Object)null) ? ((Component)bodyAnimator).transform : null), propManifest); if ((Object)(object)val5 == (Object)null) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogWarning((object)("[LCInteractionAnimationAPI] live_body.prop_attach_bone_missing: " + $"handle={context.Handle} bone='{propManifest.attachBonePath}'.")); } } return; } propInstance = Object.Instantiate(val2, val5, false); ((Object)propInstance).name = "Y4NGZ_" + propManifest.prefabAssetName + "_Instance"; propInstance.transform.localPosition = propManifest.localPosition.ToUnityVector3(); propInstance.transform.localEulerAngles = propManifest.localEulerAngles.ToUnityVector3(); propInstance.transform.localScale = Vector3.one * ((propManifest.localScale > 0f) ? propManifest.localScale : 1f); SetLayerRecursive(propInstance, ((Component)val5).gameObject.layer); propReleased = false; InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[LCInteractionAnimationAPI] live_body.prop_attached: " + $"handle={context.Handle} prefab='{propManifest.prefabAssetName}' bone='{propManifest.attachBonePath}' " + $"localPos=({propManifest.localPosition.x:0.###},{propManifest.localPosition.y:0.###},{propManifest.localPosition.z:0.###}) " + $"scale={propManifest.localScale:0.####}.")); } } } private void ReleasePropIfDue() { if (propReleased || (Object)(object)propInstance == (Object)null) { return; } InteractionAnimationManifest.PropManifest propManifest = context?.Manifest?.body?.prop; if (propManifest == null || propManifest.releaseSeconds <= 0f || elapsedSeconds < propManifest.releaseSeconds) { return; } propReleased = true; DestroyProp(); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.prop_released: " + $"handle={context.Handle} elapsed={elapsedSeconds:0.###} releaseSeconds={propManifest.releaseSeconds:0.###}.")); } } } private void DestroyProp() { if (!((Object)(object)propInstance == (Object)null)) { try { Object.Destroy((Object)(object)propInstance); } catch { } propInstance = null; } } private static void SetLayerRecursive(GameObject root, int layer) { if (!((Object)(object)root == (Object)null)) { root.layer = layer; for (int i = 0; i < root.transform.childCount; i++) { SetLayerRecursive(((Component)root.transform.GetChild(i)).gameObject, layer); } } } private bool TryLoadBundle(InteractionAnimationManifest manifest, InteractionAnimationManifest.BodyManifest body, out string reason) { reason = string.Empty; string text = manifest.bundleInternalName ?? string.Empty; if (!TryResolveBundlePath(body.bundleFileName, context.AssetRootPath, out var resolvedPath, out reason)) { return false; } if (!string.IsNullOrWhiteSpace(text)) { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && string.Equals(((Object)allLoadedAssetBundle).name, text, StringComparison.OrdinalIgnoreCase)) { bundle = allLoadedAssetBundle; ownsBundle = false; return true; } } } if (string.IsNullOrWhiteSpace(resolvedPath) || !File.Exists(resolvedPath)) { reason = "live_body.bundle_missing:" + body.bundleFileName; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.bundle_missing: " + $"handle={context.Handle} file='{body.bundleFileName}' resolvedPath='{resolvedPath}'.")); } return false; } bundle = AssetBundle.LoadFromFile(resolvedPath); if ((Object)(object)bundle == (Object)null) { reason = "live_body.bundle_load_failed:" + resolvedPath; return false; } ownsBundle = true; ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.bundle_loaded: " + $"handle={context.Handle} path='{resolvedPath}' internalName='{((Object)bundle).name}'.")); } return true; } private bool TryApplyController(InteractionAnimationManifest.BodyManifest body, out string reason) { reason = string.Empty; RuntimeAnimatorController val = null; if (!string.IsNullOrWhiteSpace(body.controllerAssetName)) { val = bundle.LoadAsset(body.controllerAssetName); } if ((Object)(object)val == (Object)null) { reason = "live_body.controller_missing:" + body.controllerAssetName; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.controller_missing: " + $"handle={context.Handle} assetName='{body.controllerAssetName}'.")); } return false; } snapshot = AnimatorStateSnapshot.Capture(bodyAnimator); if (snapshot == null) { reason = "live_body.snapshot_failed"; return false; } bool flag = false; bool flag2 = false; try { PlayerControllerB val2 = context?.Request?.Player; if ((Object)(object)val2 != (Object)null) { flag = val2.isCrouching; flag2 = true; } } catch { } snapshot.CapturedCrouching = (flag2 ? new bool?(flag) : ((bool?)null)); hasLastSyncedCrouchState = flag2; lastSyncedCrouchState = flag; RuntimeAnimatorController controllerToApply = val; if (!TryApplyClipPackOverride(body, val, ref controllerToApply, out reason)) { snapshot = null; return false; } try { bodyAnimator.runtimeAnimatorController = controllerToApply; } catch (Exception ex) { reason = "live_body.controllerAssetName_apply_exception:" + ex.Message; snapshot = null; return false; } appliedController = controllerToApply; fullBodyLayerIndex = FindLayerIndex(bodyAnimator, body.fullBodyLayer); firstPersonLayerIndex = FindLayerIndex(bodyAnimator, body.firstPersonArmsLayer); int num = snapshot.ReapplyParameters(bodyAnimator); if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.locomotion] parameters_reapplied: " + $"frame={Time.frameCount} handle={context.Handle} phase='start' " + $"count={num}.")); } } bool flag3 = snapshot.TryReapplyLayerState(bodyAnimator, 0); if (flag3 && InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { ManualLogSource logger3 = context.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.locomotion] base_layer_state_replayed: " + $"frame={Time.frameCount} handle={context.Handle} phase='start' " + "action='replay_pre_swap_state_on_shell'.")); } } if (flag && !flag3) { FireTriggerIfExists("startCrouching"); if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { ManualLogSource logger4 = context.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.locomotion] crouch_entry_asserted: " + $"frame={Time.frameCount} handle={context.Handle} phase='start' " + "reason='session_started_while_crouched_base_state_unavailable' action='fire_startCrouching_on_fresh_base_layer'.")); } } } SetBoolIfExists(body.activeBool, value: true); FireTriggerIfExists(body.enterTrigger); elapsedSeconds = 0f; ApplyLayerWeights(); bodyAnimator.Update(0f); ManualLogSource logger5 = context.Logger; if (logger5 != null) { string[] obj2 = new string[10] { "[LCInteractionAnimationAPI] live_body.controllerAssetName_applied: ", $"handle={context.Handle} controller='{((Object)val).name}' ", "previousController='", null, null, null, null, null, null, null }; RuntimeAnimatorController runtimeAnimatorController = snapshot.RuntimeAnimatorController; obj2[3] = ((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? ""; obj2[4] = "' activeBool='"; obj2[5] = body.activeBool; obj2[6] = "' enterTrigger='"; obj2[7] = body.enterTrigger; obj2[8] = "' "; obj2[9] = $"startLayerWeight={body.startLayerWeight:0.###} rampSeconds={body.layerWeightRampSeconds:0.###}."; logger5.LogInfo((object)string.Concat(obj2)); } return true; } private bool TryApplyClipPackOverride(InteractionAnimationManifest.BodyManifest body, RuntimeAnimatorController shellController, ref RuntimeAnimatorController controllerToApply, out string reason) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown reason = string.Empty; InteractionAnimationManifest.ClipPackManifest clipPack = body.clipPack; if (clipPack == null || !clipPack.enabled) { return true; } if (string.IsNullOrWhiteSpace(clipPack.bundleFileName) || clipPack.overrides == null || clipPack.overrides.Length == 0) { reason = "live_body.clip_pack_invalid_manifest"; return false; } if (!TryResolveBundlePath(clipPack.bundleFileName, context.AssetRootPath, out var resolvedPath, out reason)) { return false; } if (!string.IsNullOrWhiteSpace(clipPack.bundleInternalName)) { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && string.Equals(((Object)allLoadedAssetBundle).name, clipPack.bundleInternalName, StringComparison.OrdinalIgnoreCase)) { clipPackBundle = allLoadedAssetBundle; ownsClipPackBundle = false; break; } } } if ((Object)(object)clipPackBundle == (Object)null) { if (string.IsNullOrWhiteSpace(resolvedPath) || !File.Exists(resolvedPath)) { reason = "live_body.clip_pack_bundle_missing:" + clipPack.bundleFileName; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.clip_pack_bundle_missing: " + $"handle={context.Handle} file='{clipPack.bundleFileName}' resolvedPath='{resolvedPath}'.")); } return false; } clipPackBundle = AssetBundle.LoadFromFile(resolvedPath); if ((Object)(object)clipPackBundle == (Object)null) { reason = "live_body.clip_pack_bundle_load_failed:" + resolvedPath; return false; } ownsClipPackBundle = true; } AnimatorOverrideController val = new AnimatorOverrideController(shellController); int num = 0; for (int i = 0; i < clipPack.overrides.Length; i++) { InteractionAnimationManifest.ClipOverrideManifest clipOverrideManifest = clipPack.overrides[i]; if (clipOverrideManifest == null || string.IsNullOrWhiteSpace(clipOverrideManifest.slot) || string.IsNullOrWhiteSpace(clipOverrideManifest.clip)) { continue; } AnimationClip val2 = clipPackBundle.LoadAsset(clipOverrideManifest.clip); if ((Object)(object)val2 == (Object)null) { reason = "live_body.clip_pack_clip_missing:" + clipOverrideManifest.clip; ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogWarning((object)("[LCInteractionAnimationAPI] live_body.clip_pack_clip_missing: " + $"handle={context.Handle} clip='{clipOverrideManifest.clip}' bundle='{clipPack.bundleFileName}'.")); } return false; } val[clipOverrideManifest.slot] = val2; num++; ManualLogSource logger3 = context.Logger; if (logger3 != null) { logger3.LogInfo((object)("[LCInteractionAnimationAPI] live_body.clip_pack_slot_overridden: " + $"handle={context.Handle} slot='{clipOverrideManifest.slot}' clip='{((Object)val2).name}' clipLength={val2.length:0.###}.")); } } if (num == 0) { reason = "live_body.clip_pack_no_overrides_applied"; return false; } controllerToApply = (RuntimeAnimatorController)(object)val; ManualLogSource logger4 = context.Logger; if (logger4 != null) { logger4.LogInfo((object)("[LCInteractionAnimationAPI] live_body.clip_pack_applied: " + $"handle={context.Handle} bundle='{clipPack.bundleFileName}' overriddenSlots={num}.")); } return true; } private void ApplyLayerWeights() { InteractionAnimationManifest.BodyManifest bodyManifest = context?.Manifest?.body; if (bodyManifest != null && !((Object)(object)bodyAnimator == (Object)null)) { float num = Mathf.Clamp01((bodyManifest.startLayerWeight <= 0f) ? 1f : bodyManifest.startLayerWeight); float num2 = ((bodyManifest.layerWeightRampSeconds > 0f) ? Mathf.Lerp(num, 1f, Mathf.Clamp01(elapsedSeconds / bodyManifest.layerWeightRampSeconds)) : 1f); float num3 = ((bodyManifest.fullBodyLayerWeight >= 0f) ? Mathf.Clamp01(bodyManifest.fullBodyLayerWeight) : num2); float num4 = num2; if (bodyManifest.enterLayerFadeSeconds > 0f) { float num5 = Mathf.Clamp01(elapsedSeconds / bodyManifest.enterLayerFadeSeconds); num3 *= num5; num4 *= num5; } if (!exitRequested && bodyManifest.naturalEndLayerFadeSeconds > 0f && context.Manifest.durationSeconds > 0f) { float num6 = Mathf.Clamp01((context.Manifest.durationSeconds - elapsedSeconds) / bodyManifest.naturalEndLayerFadeSeconds); num3 *= num6; num4 *= num6; } if (exitRequested) { float num7 = ((exitDurationSeconds > 1E-05f) ? Mathf.Clamp01(exitElapsedSeconds / exitDurationSeconds) : 1f); num3 = Mathf.Lerp(exitStartFullBodyWeight, 0f, num7); num4 = Mathf.Lerp(exitStartFirstPersonWeight, 0f, num7); } SetLayerWeightIfValid(fullBodyLayerIndex, num3); SetLayerWeightIfValid(firstPersonLayerIndex, num4); } } private string RestoreAnimator(out AnimatorStateRestoreMode restoreStateMode) { restoreStateMode = InteractionAnimationApiRestoreDiagnostics.ReadRestoreStateMode(); if ((Object)(object)bodyAnimator == (Object)null || snapshot == null) { return "no_snapshot"; } try { InteractionAnimationManifest.BodyManifest bodyManifest = context?.Manifest?.body; if (bodyManifest != null) { SetBoolIfExists(bodyManifest.activeBool, value: false); FireTriggerIfExists(bodyManifest.exitTrigger); } bool flag = bodyManifest != null; bool flag2 = false; bool flag3 = false; try { PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val != (Object)null) { flag2 = val.isCrouching; flag3 = true; } } catch { } bool flag4 = snapshot.CapturedCrouching.HasValue && flag3 && flag2 != snapshot.CapturedCrouching.Value; AnimatorStateSnapshot animatorStateSnapshot = AnimatorStateSnapshot.Capture(bodyAnimator); if (flag4 && InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[RestoreSeam.locomotion] stance_changed_during_session: " + $"frame={Time.frameCount} handle={context.Handle} " + $"capturedCrouching={snapshot.CapturedCrouching} " + "action='skip_base_layer_state_replay'.")); } } } if (snapshot.CapturedCrouching.HasValue) { hasLastSyncedCrouchState = true; lastSyncedCrouchState = snapshot.CapturedCrouching.Value; if (flag4 && InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[RestoreSeam.locomotion] crouch_edge_tracker_rebased: " + $"frame={Time.frameCount} handle={context.Handle} phase='stop' " + $"capturedCrouching={snapshot.CapturedCrouching.Value} " + $"currentCrouching={flag2} " + "action='rebase_tracker_to_restored_state_for_stance_edge'.")); } } } } bool flag5 = snapshot.Restore(bodyAnimator, appliedController, !flag, restoreStateMode, delegate { SyncVanillaLocomotionParameters("stop_pre_state_replay"); }, !flag4); bool flag6 = flag5 && (flag4 || restoreStateMode == AnimatorStateRestoreMode.Fresh); bool flag7 = flag6 && animatorStateSnapshot != null && animatorStateSnapshot.TryReapplyLayerState(bodyAnimator, 0); if (flag7) { try { bodyAnimator.Update(0f); } catch { } if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.locomotion] base_layer_state_replayed: " + $"frame={Time.frameCount} handle={context.Handle} phase='stop' " + $"stanceMismatch={flag4} " + "restoreStateMode='" + FormatRestoreStateMode(restoreStateMode) + "' action='replay_live_state_on_restored_controller'.")); } } } } if (flag6 && !flag7 && flag3 && flag2) { FireTriggerIfExists("startCrouching"); try { bodyAnimator.Update(0f); } catch { } if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { InteractionAnimationContext interactionAnimationContext4 = context; if (interactionAnimationContext4 != null) { ManualLogSource logger4 = interactionAnimationContext4.Logger; if (logger4 != null) { logger4.LogInfo((object)("[RestoreSeam.locomotion] crouch_entry_asserted: " + $"frame={Time.frameCount} handle={context.Handle} phase='stop' " + $"stanceMismatch={flag4} " + "restoreStateMode='" + FormatRestoreStateMode(restoreStateMode) + "' action='fire_startCrouching_on_restored_base_layer'.")); } } } } return flag5 ? "restored" : "controller_changed_externally"; } catch (Exception ex) { return "restore_exception:" + ex.Message; } } private static string FormatRestoreStateMode(AnimatorStateRestoreMode restoreStateMode) { return restoreStateMode switch { AnimatorStateRestoreMode.Crossfade => "crossfade", AnimatorStateRestoreMode.Replay => "replay", _ => "fresh", }; } private void SuppressLiveRigBuilders() { Transform val = (((Object)(object)context?.Request?.Player != (Object)null) ? ((Component)context.Request.Player).transform : null); if ((Object)(object)val == (Object)null) { return; } Behaviour[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Behaviour val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && IsRigBuilderComponent((Component)(object)val2)) { suppressedRigBuilders.Add(new RigBuilderState(val2)); val2.enabled = false; } } if (suppressedRigBuilders.Count > 0) { ManualLogSource logger = context.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.rig_suppressed: " + $"handle={context.Handle} rigBuilders={suppressedRigBuilders.Count}.")); } } } private void RestoreLiveRigBuilders() { for (int num = suppressedRigBuilders.Count - 1; num >= 0; num--) { suppressedRigBuilders[num].Restore(); } suppressedRigBuilders.Clear(); } private void RebuildRigBuilders(string phase) { Transform val = (((Object)(object)context?.Request?.Player != (Object)null) ? ((Component)context.Request.Player).transform : null); if ((Object)(object)val == (Object)null) { return; } int num = 0; Behaviour[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Behaviour val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !IsRigBuilderComponent((Component)(object)val2)) { continue; } try { MethodInfo method = ((object)val2).GetType().GetMethod("Build", Type.EmptyTypes); if (method != null) { method.Invoke(val2, null); num++; } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.rig_rebuild_failed: phase='" + phase + "' rigBuilder='" + ((Object)val2).name + "' reason='" + ex.Message + "'.")); } } } } InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.rig_rebuilt: " + string.Format("handle={0} phase='{1}' rigBuilders={2}.", (context != null) ? context.Handle.ToString() : "", phase, num))); } } } private void EvaluateRigBuilders(string phase) { Transform val = (((Object)(object)context?.Request?.Player != (Object)null) ? ((Component)context.Request.Player).transform : null); if ((Object)(object)val == (Object)null) { return; } int num = 0; Behaviour[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Behaviour val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || !val2.isActiveAndEnabled || !IsRigBuilderComponent((Component)(object)val2)) { continue; } try { MethodInfo method = ((object)val2).GetType().GetMethod("Evaluate", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(float) }, null); if (method == null) { if (rigEvaluateMethodMissingLogged) { continue; } rigEvaluateMethodMissingLogged = true; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[RestoreSeam.rigeval] evaluate_method_missing: phase='" + phase + "' rigBuilder='" + ((Object)val2).name + "'.")); } } continue; } method.Invoke(val2, new object[1] { 0f }); num++; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[RestoreSeam.rigeval] evaluate_failed: phase='" + phase + "' rigBuilder='" + ((Object)val2).name + "' reason='" + ex.Message + "'.")); } } } } InteractionAnimationContext interactionAnimationContext3 = context; if (interactionAnimationContext3 != null) { ManualLogSource logger3 = interactionAnimationContext3.Logger; if (logger3 != null) { logger3.LogInfo((object)("[RestoreSeam.rigeval] evaluated: handle=" + ((context != null) ? context.Handle.ToString() : "") + " " + $"phase='{phase}' rigBuilders={num}.")); } } } private void ResolveDiagnosticTransforms() { Transform val = null; try { val = (((Object)(object)context?.Request?.Player != (Object)null) ? context.Request.Player.playerModelArmsMetarig : null); } catch { } Transform val2 = (((Object)(object)val != (Object)null) ? val : (((Object)(object)bodyAnimator != (Object)null) ? ((Component)bodyAnimator).transform : null)); if ((Object)(object)val2 == (Object)null) { return; } rightArmIkTarget = FindChildRecursive(val2, "ArmsRightArm_target"); leftArmIkTarget = FindChildRecursive(val2, "ArmsLeftArm_target"); rightHandBone = FindChildRecursive(val2, "hand.R"); rightShoulderBone = FindChildRecursive(val2, "shoulder.R"); bool flag = (Object)(object)bodyAnimator != (Object)null && (Object)(object)val != (Object)null && val.IsChildOf(((Component)bodyAnimator).transform); string relativePath = GetRelativePath(((Object)(object)bodyAnimator != (Object)null) ? ((Component)bodyAnimator).transform : null, val); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.diagnostic_targets: " + string.Format("handle={0} armsMetarig='{1}' ", context.Handle, ((Object)(object)val != (Object)null) ? ((Object)val).name : "") + $"armsMetarigUnderAnimator={flag} armsRelativePath='{relativePath}' " + $"rightArmIkTarget={(Object)(object)rightArmIkTarget != (Object)null} leftArmIkTarget={(Object)(object)leftArmIkTarget != (Object)null} " + $"rightHandBone={(Object)(object)rightHandBone != (Object)null} rightShoulderBone={(Object)(object)rightShoulderBone != (Object)null}.")); } } } private static string GetRelativePath(Transform root, Transform target) { if ((Object)(object)root == (Object)null || (Object)(object)target == (Object)null || !target.IsChildOf(root)) { return ""; } List list = new List(); Transform val = target; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root && list.Count < 32) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } private void LogFrameDiagnostics() { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled && context?.Logger != null && !(elapsedSeconds < nextDiagnosticsAtSeconds)) { nextDiagnosticsAtSeconds = elapsedSeconds + 0.25f; string arg = DescribeLayerState(fullBodyLayerIndex); string arg2 = DescribeLayerState(firstPersonLayerIndex); Camera val = null; SkinnedMeshRenderer val2 = null; try { val = (((Object)(object)context.Request?.Player != (Object)null) ? context.Request.Player.gameplayCamera : null); val2 = (((Object)(object)context.Request?.Player != (Object)null) ? context.Request.Player.thisPlayerModelArms : null); } catch { } string text = ""; if ((Object)(object)rightHandBone != (Object)null && (Object)(object)val != (Object)null) { Vector3 val3 = val.WorldToViewportPoint(rightHandBone.position); text = $"({val3.x:0.##},{val3.y:0.##},{val3.z:0.##})"; } context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.frame: " + $"handle={context.Handle} elapsed={elapsedSeconds:0.###} " + $"fullBodyLayer={fullBodyLayerIndex} fullBodyWeight={GetLayerWeight(fullBodyLayerIndex):0.###} fullBodyState={arg} " + $"firstPersonArmsLayer={firstPersonLayerIndex} firstPersonArmsWeight={GetLayerWeight(firstPersonLayerIndex):0.###} firstPersonArmsState={arg2} " + "rightTargetLocalPos=" + DescribeLocalPosition(rightArmIkTarget) + " leftTargetLocalPos=" + DescribeLocalPosition(leftArmIkTarget) + " rightShoulderLocalEuler=" + DescribeLocalEuler(rightShoulderBone) + " rightHandLocalEuler=" + DescribeLocalEuler(rightHandBone) + " rightHandViewport=" + text + " " + $"armsRendererEnabled={(Object)(object)val2 != (Object)null && ((Renderer)val2).enabled} " + $"armsRendererVisible={(Object)(object)val2 != (Object)null && ((Renderer)val2).isVisible}.")); LogCalibrationSample(val); } } private void LogCalibrationSample(Camera camera) { if (!((Object)(object)camera == (Object)null) && (!((Object)(object)rightArmIkTarget == (Object)null) || !((Object)(object)leftArmIkTarget == (Object)null))) { context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.calibration: " + $"handle={context.Handle} elapsed={elapsedSeconds:0.###} " + "rightTarget=" + DescribeCalibration(camera, rightArmIkTarget) + " leftTarget=" + DescribeCalibration(camera, leftArmIkTarget) + " rightParent=" + DescribeParentInCameraSpace(camera, rightArmIkTarget) + " leftParent=" + DescribeParentInCameraSpace(camera, leftArmIkTarget) + ".")); } } private static string DescribeCalibration(Camera camera, Transform target) { //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_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_002c: 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_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) //IL_0045: 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_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_008f: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return ""; } Vector3 val = ((Component)camera).transform.InverseTransformPoint(target.position); Quaternion val2 = Quaternion.Inverse(((Component)camera).transform.rotation) * target.rotation; Vector3 eulerAngles = ((Quaternion)(ref val2)).eulerAngles; Vector3 localPosition = target.localPosition; Vector3 localEulerAngles = target.localEulerAngles; return $"[camPos=({val.x:0.####},{val.y:0.####},{val.z:0.####}) " + $"camEuler=({eulerAngles.x:0.##},{eulerAngles.y:0.##},{eulerAngles.z:0.##}) " + $"localPos=({localPosition.x:0.####},{localPosition.y:0.####},{localPosition.z:0.####}) " + $"localEuler=({localEulerAngles.x:0.##},{localEulerAngles.y:0.##},{localEulerAngles.z:0.##})]"; } private static string DescribeParentInCameraSpace(Camera camera, Transform target) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0076: 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_0092: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Transform val = (((Object)(object)target != (Object)null) ? target.parent : null); if ((Object)(object)val == (Object)null) { return ""; } Vector3 val2 = ((Component)camera).transform.InverseTransformPoint(val.position); Quaternion val3 = Quaternion.Inverse(((Component)camera).transform.rotation) * val.rotation; Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles; Vector3 lossyScale = val.lossyScale; return $"[name='{((Object)val).name}' camPos=({val2.x:0.####},{val2.y:0.####},{val2.z:0.####}) " + $"camEuler=({eulerAngles.x:0.##},{eulerAngles.y:0.##},{eulerAngles.z:0.##}) " + $"lossyScale=({lossyScale.x:0.####},{lossyScale.y:0.####},{lossyScale.z:0.####})]"; } private void StartTransformChainDiagnostics() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown StopTransformChainDiagnostics(); if (!InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled) { return; } nextTransformChainDiagnosticsAtSeconds = 0f; lastTransformChainDiagnosticsFrame = -1; try { Application.onBeforeRender += new UnityAction(LogFinalFrameTransformChainDiagnostic); transformChainDiagnosticsSubscribed = true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.transform_chain_subscribe_failed: " + ex.Message)); } } } } private void StopTransformChainDiagnostics() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (transformChainDiagnosticsSubscribed) { try { Application.onBeforeRender -= new UnityAction(LogFinalFrameTransformChainDiagnostic); } catch { } transformChainDiagnosticsSubscribed = false; } } private void StartExternalCameraPresentationDiagnostics() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown StopExternalCameraPresentationDiagnostics(); if (!LocalCameraOwnedExternally || !InteractionAnimationApiRestoreDiagnostics.ExternalCameraPresentationLoggerEnabled) { return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || !IsLocalPlayer(val)) { return; } CacheExternalCameraRendererProbes(val); lastExternalCameraPresentationFrame = -1; lastExternalCameraPresentationSignature = 0; hasExternalCameraPresentationSignature = false; externalCameraPresentationSampleFailureLogged = false; try { Application.onBeforeRender += new UnityAction(LogExternalCameraPresentationState); externalCameraPresentationDiagnosticsSubscribed = true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.external_camera_presentation_subscribe_failed: " + $"handle={context.Handle} error='{ex.Message}'.")); } } StopExternalCameraPresentationDiagnostics(); } } private void StopExternalCameraPresentationDiagnostics() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (externalCameraPresentationDiagnosticsSubscribed) { try { Application.onBeforeRender -= new UnityAction(LogExternalCameraPresentationState); } catch { } } externalCameraPresentationDiagnosticsSubscribed = false; externalCameraRendererProbes.Clear(); lastExternalCameraPresentationFrame = -1; lastExternalCameraPresentationSignature = 0; hasExternalCameraPresentationSignature = false; externalCameraPresentationSampleFailureLogged = false; } private void CacheExternalCameraRendererProbes(PlayerControllerB player) { externalCameraRendererProbes.Clear(); if (!((Object)(object)player == (Object)null) && !((Object)(object)((Component)player).transform == (Object)null)) { HashSet seen = new HashSet(); Transform transform = ((Component)player).transform; Transform root = FindChildRecursive(transform, "ScavengerModelArmsOnly"); AddExternalCameraRendererSubtree(player, root, "first_person_arms", seen); try { AddExternalCameraRendererProbe(player, (Renderer)(object)player.thisPlayerModelArms, "first_person_arms", seen); } catch { } Transform root2 = null; try { root2 = player.localVisor; } catch { } AddExternalCameraRendererSubtree(player, root2, "local_visor", seen); try { AddExternalCameraRendererProbe(player, (Renderer)(object)player.thisPlayerModel, "world_body", seen); AddExternalCameraRendererProbe(player, (Renderer)(object)player.thisPlayerModelLOD1, "world_body", seen); AddExternalCameraRendererProbe(player, (Renderer)(object)player.thisPlayerModelLOD2, "world_body", seen); } catch { } Transform root3 = FindChildRecursive(transform, "ScavengerModel"); AddExternalCameraRendererSubtree(player, root3, "world_body", seen); externalCameraRendererProbes.Sort(CompareExternalCameraRendererProbes); } } private void AddExternalCameraRendererSubtree(PlayerControllerB player, Transform root, string role, HashSet seen) { if ((Object)(object)root == (Object)null) { return; } try { Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { AddExternalCameraRendererProbe(player, componentsInChildren[i], role, seen); } } catch { } } private void AddExternalCameraRendererProbe(PlayerControllerB player, Renderer renderer, string role, HashSet seen) { if (!((Object)(object)renderer == (Object)null) && seen != null && seen.Add(renderer)) { string relativePath = GetRelativePath(((Object)(object)player != (Object)null) ? ((Component)player).transform : null, ((Component)renderer).transform); externalCameraRendererProbes.Add(new ExternalCameraRendererProbe(renderer, role, relativePath)); } } private static int CompareExternalCameraRendererProbes(ExternalCameraRendererProbe left, ExternalCameraRendererProbe right) { int num = string.CompareOrdinal(left?.Role, right?.Role); if (num == 0) { return string.CompareOrdinal(left?.Path, right?.Path); } return num; } private void LogExternalCameraPresentationState() { if (!externalCameraPresentationDiagnosticsSubscribed) { return; } try { if (!active || !LocalCameraOwnedExternally || !InteractionAnimationApiRestoreDiagnostics.ExternalCameraPresentationLoggerEnabled) { StopExternalCameraPresentationDiagnostics(); } else { if (Time.frameCount == lastExternalCameraPresentationFrame) { return; } lastExternalCameraPresentationFrame = Time.frameCount; PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null) { return; } Camera val2 = null; try { val2 = val.gameplayCamera; } catch { } int bodyRenderEligible; int armsRenderEligible; int visorRenderEligible; int bodyVisible; int armsVisible; int visorVisible; int rendererReadFailures; int num = ComputeExternalCameraPresentationSignature(val2, out bodyRenderEligible, out armsRenderEligible, out visorRenderEligible, out bodyVisible, out armsVisible, out visorVisible, out rendererReadFailures); if (hasExternalCameraPresentationSignature && num == lastExternalCameraPresentationSignature) { return; } bool flag = !hasExternalCameraPresentationSignature; lastExternalCameraPresentationSignature = num; hasExternalCameraPresentationSignature = true; int num2 = CountNamedTransforms(((Component)val).transform, "ScavengerModel"); int num3 = CountActiveScenePlayerControllers(); bool flag2 = false; try { flag2 = val.playerBodyAnimator == bodyAnimator; } catch { } bool flag3 = (Object)(object)val2 != (Object)null && num2 == 1 && flag2 && bodyRenderEligible > 0 && armsRenderEligible == 0 && visorRenderEligible == 0 && rendererReadFailures == 0; string text = (flag3 ? "live_body.external_camera_presentation_state" : "live_body.external_camera_presentation_invariant_failed"); string text2 = "[LCInteractionAnimationAPI] " + text + ": " + $"handle={context.Handle} " + "interaction='" + (context.Manifest?.interactionId ?? "") + "' " + $"frame={Time.frameCount} " + "sample='" + (flag ? "initial" : "state_changed") + "' " + $"invariantPassed={flag3} " + $"activeScenePlayerCount={num3} " + $"scavengerModelCountUnderPlayer={num2} " + $"animatorMatchesPlayer={flag2} " + "camera='" + (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : "") + "' cameraCullingMask=" + (((Object)(object)val2 != (Object)null) ? ("0x" + val2.cullingMask.ToString("X8")) : "") + " " + $"bodyRenderEligible={bodyRenderEligible} bodyVisible={bodyVisible} " + $"armsRenderEligible={armsRenderEligible} armsVisible={armsVisible} " + $"visorRenderEligible={visorRenderEligible} visorVisible={visorVisible} " + $"rendererReadFailures={rendererReadFailures} " + "renderers=" + DescribeExternalCameraRenderers(val, val2) + "."; if (flag3) { ManualLogSource logger = context.Logger; if (logger != null) { logger.LogInfo((object)text2); } } else { ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogWarning((object)text2); } } } } catch (Exception ex) { if (externalCameraPresentationSampleFailureLogged) { return; } externalCameraPresentationSampleFailureLogged = true; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger3 = interactionAnimationContext.Logger; if (logger3 != null) { logger3.LogWarning((object)("[LCInteractionAnimationAPI] live_body.external_camera_presentation_sample_failed: handle=" + ((context != null) ? context.Handle.ToString() : "") + " error='" + ex.Message + "'.")); } } } } private int ComputeExternalCameraPresentationSignature(Camera camera, out int bodyRenderEligible, out int armsRenderEligible, out int visorRenderEligible, out int bodyVisible, out int armsVisible, out int visorVisible, out int rendererReadFailures) { bodyRenderEligible = 0; armsRenderEligible = 0; visorRenderEligible = 0; bodyVisible = 0; armsVisible = 0; visorVisible = 0; rendererReadFailures = 0; int num = 17; num = num * 31 + (((Object)(object)camera != (Object)null) ? camera.cullingMask : 0); num = num * 31 + externalCameraRendererProbes.Count; for (int i = 0; i < externalCameraRendererProbes.Count; i++) { ExternalCameraRendererProbe externalCameraRendererProbe = externalCameraRendererProbes[i]; ExternalCameraRendererState externalCameraRendererState = CaptureExternalCameraRendererState(externalCameraRendererProbe?.Renderer, camera); num = num * 31 + (externalCameraRendererProbe?.InstanceId ?? 0); num = num * 31 + externalCameraRendererState.Signature; if (externalCameraRendererState.ReadFailed) { rendererReadFailures++; } if (string.Equals(externalCameraRendererProbe?.Role, "first_person_arms", StringComparison.Ordinal)) { if (externalCameraRendererState.RenderEligible) { armsRenderEligible++; } if (externalCameraRendererState.IsVisible) { armsVisible++; } } else if (string.Equals(externalCameraRendererProbe?.Role, "local_visor", StringComparison.Ordinal)) { if (externalCameraRendererState.RenderEligible) { visorRenderEligible++; } if (externalCameraRendererState.IsVisible) { visorVisible++; } } else { if (externalCameraRendererState.RenderEligible) { bodyRenderEligible++; } if (externalCameraRendererState.IsVisible) { bodyVisible++; } } } return num; } private static ExternalCameraRendererState CaptureExternalCameraRendererState(Renderer renderer, Camera camera) { //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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 ExternalCameraRendererState result = default(ExternalCameraRendererState); if ((Object)(object)renderer == (Object)null) { return result; } try { result.Present = true; result.ActiveInHierarchy = ((Component)renderer).gameObject.activeInHierarchy; result.Enabled = renderer.enabled; result.ForceRenderingOff = renderer.forceRenderingOff; result.IsVisible = renderer.isVisible; result.Layer = ((Component)renderer).gameObject.layer; result.ShadowCastingMode = renderer.shadowCastingMode; result.CameraDrawsLayer = (Object)(object)camera == (Object)null || (camera.cullingMask & (1 << result.Layer)) != 0; result.RenderEligible = result.ActiveInHierarchy && result.Enabled && !result.ForceRenderingOff && result.CameraDrawsLayer && (int)result.ShadowCastingMode != 3; } catch { result.ReadFailed = true; } return result; } private string DescribeExternalCameraRenderers(PlayerControllerB player, Camera camera) { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) if (externalCameraRendererProbes.Count == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(512); for (int i = 0; i < externalCameraRendererProbes.Count; i++) { ExternalCameraRendererProbe externalCameraRendererProbe = externalCameraRendererProbes[i]; Renderer val = externalCameraRendererProbe?.Renderer; ExternalCameraRendererState externalCameraRendererState = CaptureExternalCameraRendererState(val, camera); if (i > 0) { stringBuilder.Append(" | "); } stringBuilder.Append("[role='").Append(externalCameraRendererProbe?.Role ?? "").Append("' id=") .Append(externalCameraRendererProbe?.InstanceId ?? 0) .Append(" path='") .Append(SanitizeExternalCameraLogValue(externalCameraRendererProbe?.Path)) .Append("' present=") .Append(externalCameraRendererState.Present) .Append(" active=") .Append(externalCameraRendererState.ActiveInHierarchy) .Append(" enabled=") .Append(externalCameraRendererState.Enabled) .Append(" forceOff=") .Append(externalCameraRendererState.ForceRenderingOff) .Append(" shadow=") .Append(externalCameraRendererState.ShadowCastingMode) .Append(" isVisible=") .Append(externalCameraRendererState.IsVisible) .Append(" layer=") .Append(externalCameraRendererState.Layer) .Append(" cameraDrawsLayer=") .Append(externalCameraRendererState.CameraDrawsLayer) .Append(" renderEligible=") .Append(externalCameraRendererState.RenderEligible) .Append(" readFailed=") .Append(externalCameraRendererState.ReadFailed); if ((Object)(object)val != (Object)null) { try { Bounds bounds = val.bounds; stringBuilder.Append(" boundsCenter=").Append(DescribeExternalCameraVector(((Bounds)(ref bounds)).center)).Append(" boundsSize=") .Append(DescribeExternalCameraVector(((Bounds)(ref bounds)).size)); SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); if (val2 != null) { stringBuilder.Append(" rootBone='").Append(SanitizeExternalCameraLogValue(GetRelativePath(((Object)(object)player != (Object)null) ? ((Component)player).transform : null, val2.rootBone))).Append("'"); } } catch { } } stringBuilder.Append(']'); } return stringBuilder.ToString(); } private static int CountNamedTransforms(Transform root, string name) { if ((Object)(object)root == (Object)null) { return 0; } int num = (string.Equals(((Object)root).name, name, StringComparison.Ordinal) ? 1 : 0); for (int i = 0; i < root.childCount; i++) { num += CountNamedTransforms(root.GetChild(i), name); } return num; } private static int CountActiveScenePlayerControllers() { //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) int num = 0; try { PlayerControllerB[] array = Resources.FindObjectsOfTypeAll(); foreach (PlayerControllerB val in array) { if ((Object)(object)val != (Object)null) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { num++; } } } } catch { } return num; } private static string SanitizeExternalCameraLogValue(string value) { if (!string.IsNullOrEmpty(value)) { return value.Replace('\r', ' ').Replace('\n', ' ').Replace('\'', '"'); } return ""; } private static string DescribeExternalCameraVector(Vector3 value) { //IL_0005: 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_001b: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.###},{value.y:0.###},{value.z:0.###})"; } private void StartLocalVisorHardGlue() { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown StopLocalVisorHardGlue(); if (LocalCameraOwnedExternally) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.visor_glue_skipped: handle=" + ((context != null) ? context.Handle.ToString() : "") + " interaction='" + (context?.Manifest?.interactionId ?? "") + "' reason='local_camera_owned_externally' action='leave_visor_to_external_owner'.")); } } } else { if (!InteractionAnimationApiRestoreDiagnostics.HardVisorGlueDuringSessionEnabled) { return; } PlayerControllerB val = context?.Request?.Player; if ((Object)(object)val == (Object)null || !IsLocalPlayer(val)) { return; } try { visorHardGlueVisor = val.localVisor; visorHardGlueTarget = val.localVisorTargetPoint; } catch { visorHardGlueVisor = null; visorHardGlueTarget = null; } if ((Object)(object)visorHardGlueVisor == (Object)null || (Object)(object)visorHardGlueTarget == (Object)null) { return; } try { Application.onBeforeRender += new UnityAction(ApplyLocalVisorHardGlue); visorHardGlueSubscribed = true; } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogWarning((object)("[LCInteractionAnimationAPI] live_body.visor_glue_subscribe_failed: " + ex.Message)); } } } } } private void StopLocalVisorHardGlue() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (visorHardGlueSubscribed) { try { Application.onBeforeRender -= new UnityAction(ApplyLocalVisorHardGlue); } catch { } } visorHardGlueSubscribed = false; visorHardGlueVisor = null; visorHardGlueTarget = null; visorHardGlueAppliedLogged = false; visorHardGlueParkedLogged = false; } private void ApplyLocalVisorHardGlue() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) try { if (!active || (Object)(object)visorHardGlueVisor == (Object)null || (Object)(object)visorHardGlueTarget == (Object)null) { return; } Vector3 position = visorHardGlueTarget.position; float num = Vector3.Distance(visorHardGlueVisor.position, position); if (num > 2f) { if (visorHardGlueParkedLogged) { return; } visorHardGlueParkedLogged = true; InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.visor_glue_parked: " + $"handle={context.Handle} positionDelta={num:0.##}m " + "action='skip_while_parked'.")); } } return; } if (!visorHardGlueAppliedLogged) { visorHardGlueAppliedLogged = true; InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] live_body.visor_glue_active: " + $"handle={context.Handle} preGluePositionDelta={num:0.####}m " + $"preGlueRotationDelta={Quaternion.Angle(visorHardGlueVisor.rotation, visorHardGlueTarget.rotation):0.##}deg.")); } } } visorHardGlueVisor.SetPositionAndRotation(position, visorHardGlueTarget.rotation); } catch { } } private void LogFinalFrameTransformChainDiagnostic() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) try { if (active && context?.Logger != null && InteractionAnimationApiRestoreDiagnostics.RestoreSeamFrameLoggerEnabled && !(elapsedSeconds < nextTransformChainDiagnosticsAtSeconds) && Time.frameCount != lastTransformChainDiagnosticsFrame) { Camera val = null; try { val = (((Object)(object)context.Request?.Player != (Object)null) ? context.Request.Player.gameplayCamera : null); } catch { } if (!((Object)(object)val == (Object)null) && !((Object)(object)rightArmIkTarget == (Object)null) && !((Object)(object)rightHandBone == (Object)null)) { lastTransformChainDiagnosticsFrame = Time.frameCount; nextTransformChainDiagnosticsAtSeconds = elapsedSeconds + 0.25f; Transform parent = ((Component)val).transform.parent; Rect pixelRect = val.pixelRect; Vector3 val2 = rightArmIkTarget.InverseTransformPoint(rightHandBone.position); Quaternion val3 = Quaternion.Inverse(rightArmIkTarget.rotation) * rightHandBone.rotation; Vector3 eulerAngles = ((Quaternion)(ref val3)).eulerAngles; float num = Vector3.Distance(rightArmIkTarget.position, rightHandBone.position); float num2 = Quaternion.Angle(rightArmIkTarget.rotation, rightHandBone.rotation); context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] live_body.transform_chain: " + $"handle={context.Handle} phase='before_render' frame={Time.frameCount} " + $"elapsed={elapsedSeconds:0.###} " + "camera=[name='" + ((Object)val).name + "' parent='" + (((Object)(object)parent != (Object)null) ? ((Object)parent).name : "") + "' " + $"fov={val.fieldOfView:0.####} aspect={val.aspect:0.######} " + $"pixelWidth={val.pixelWidth} pixelHeight={val.pixelHeight} " + $"pixelRect=({((Rect)(ref pixelRect)).x:0.##},{((Rect)(ref pixelRect)).y:0.##},{((Rect)(ref pixelRect)).width:0.##},{((Rect)(ref pixelRect)).height:0.##}) " + $"near={val.nearClipPlane:0.####}] " + "rightTarget=" + DescribeTransformInCamera(val, rightArmIkTarget) + " rightHand=" + DescribeTransformInCamera(val, rightHandBone) + " " + $"targetToHand=[position=({val2.x:0.######},{val2.y:0.######},{val2.z:0.######}) " + $"euler=({eulerAngles.x:0.####},{eulerAngles.y:0.####},{eulerAngles.z:0.####}) " + $"positionErrorMeters={num:0.######} " + $"rotationErrorDegrees={num2:0.####}] " + "prop=" + DescribePropTransform(val) + " propBounds=" + DescribePropBounds(val) + " propAimAxis=" + DescribePropAimAxis(val) + ".")); } } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] live_body.transform_chain_failed: " + ex.Message)); } } StopTransformChainDiagnostics(); } } private static string DescribeTransformInCamera(Camera camera, Transform transform) { //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_0029: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_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) //IL_0057: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera == (Object)null || (Object)(object)transform == (Object)null) { return ""; } Vector3 val = ((Component)camera).transform.InverseTransformPoint(transform.position); Quaternion val2 = Quaternion.Inverse(((Component)camera).transform.rotation) * transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref val2)).eulerAngles; Vector3 localPosition = transform.localPosition; Vector3 localEulerAngles = transform.localEulerAngles; Vector3 lossyScale = transform.lossyScale; return $"[camPos=({val.x:0.######},{val.y:0.######},{val.z:0.######}) " + $"camEuler=({eulerAngles.x:0.####},{eulerAngles.y:0.####},{eulerAngles.z:0.####}) " + $"localPos=({localPosition.x:0.######},{localPosition.y:0.######},{localPosition.z:0.######}) " + $"localEuler=({localEulerAngles.x:0.####},{localEulerAngles.y:0.####},{localEulerAngles.z:0.####}) " + $"lossyScale=({lossyScale.x:0.######},{lossyScale.y:0.######},{lossyScale.z:0.######})]"; } private string DescribePropTransform(Camera camera) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_009f: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: 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) if ((Object)(object)propInstance == (Object)null) { return ""; } Transform transform = propInstance.transform; Vector3 val = ((Component)camera).transform.InverseTransformPoint(transform.position); Quaternion val2 = Quaternion.Inverse(((Component)camera).transform.rotation) * transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref val2)).eulerAngles; Vector3 val3 = ((Component)camera).transform.InverseTransformDirection(transform.forward); Vector3 normalized = ((Vector3)(ref val3)).normalized; Vector3 localPosition = transform.localPosition; Vector3 localEulerAngles = transform.localEulerAngles; Vector3 localScale = transform.localScale; Vector3 lossyScale = transform.lossyScale; return $"[localPos=({localPosition.x:0.######},{localPosition.y:0.######},{localPosition.z:0.######}) " + $"localEuler=({localEulerAngles.x:0.####},{localEulerAngles.y:0.####},{localEulerAngles.z:0.####}) " + $"localScale=({localScale.x:0.######},{localScale.y:0.######},{localScale.z:0.######}) " + $"lossyScale=({lossyScale.x:0.######},{lossyScale.y:0.######},{lossyScale.z:0.######}) " + $"camPos=({val.x:0.######},{val.y:0.######},{val.z:0.######}) " + $"camEuler=({eulerAngles.x:0.####},{eulerAngles.y:0.####},{eulerAngles.z:0.####}) " + $"camForward=({normalized.x:0.######},{normalized.y:0.######},{normalized.z:0.######})]"; } private string DescribePropBounds(Camera camera) { //IL_0065: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)propInstance == (Object)null) { return ""; } Bounds bounds; bool flag = TryGetRendererBoundsInSpace(propInstance, ((Component)camera).transform, out bounds); Bounds bounds2; bool flag2 = TryGetRendererBoundsInSpace(propInstance, propInstance.transform, out bounds2); return $"[hasCameraBounds={flag} " + "camMin=" + DescribeBoundsMin(bounds, flag) + " camMax=" + DescribeBoundsMax(bounds, flag) + " " + $"hasLocalBounds={flag2} " + "localMin=" + DescribeBoundsMin(bounds2, flag2) + " localMax=" + DescribeBoundsMax(bounds2, flag2) + "]"; } private string DescribePropAimAxis(Camera camera) { //IL_003c: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00a1: 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_00a9: 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_00b0: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)propInstance == (Object)null) { return ""; } Bounds bounds; float num = (TryGetRendererBoundsInSpace(propInstance, propInstance.transform, out bounds) ? Mathf.Max(0.25f, ((Bounds)(ref bounds)).max.z) : 0.5f); Vector3 zero = Vector3.zero; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0f, num); Vector3 val2 = propInstance.transform.TransformPoint(zero); Vector3 val3 = propInstance.transform.TransformPoint(val); Vector3 val4 = ((Component)camera).transform.InverseTransformPoint(val2); Vector3 val5 = ((Component)camera).transform.InverseTransformPoint(val3); Vector3 val6 = camera.WorldToViewportPoint(val2); Vector3 val7 = camera.WorldToViewportPoint(val3); int num2 = ((camera.pixelWidth > 0) ? camera.pixelWidth : Mathf.Max(1, Screen.width)); int num3 = ((camera.pixelHeight > 0) ? camera.pixelHeight : Mathf.Max(1, Screen.height)); Vector2 val8 = default(Vector2); ((Vector2)(ref val8))..ctor(val6.x * (float)num2, val6.y * (float)num3); Vector2 val9 = new Vector2(val7.x * (float)num2, val7.y * (float)num3); Vector2 val10 = default(Vector2); ((Vector2)(ref val10))..ctor((float)num2 * 0.5f, (float)num3 * 0.5f); Vector2 val11 = val9 - val8; float sqrMagnitude = ((Vector2)(ref val11)).sqrMagnitude; float num4 = 0f; float num5 = float.MaxValue; float num6 = float.MaxValue; bool flag = false; if (sqrMagnitude > 1E-08f) { num4 = Vector2.Dot(val10 - val8, val11) / sqrMagnitude; Vector2 val12 = val8 + val11 * Mathf.Max(0f, num4); num5 = Vector2.Distance(val10, val12); num6 = num5 / (float)num3; flag = num4 >= 0f && val6.z > camera.nearClipPlane && val7.z > camera.nearClipPlane; } return $"[localOrigin=({zero.x:0.######},{zero.y:0.######},{zero.z:0.######}) " + $"localTip=({val.x:0.######},{val.y:0.######},{val.z:0.######}) " + $"camOrigin=({val4.x:0.######},{val4.y:0.######},{val4.z:0.######}) " + $"camTip=({val5.x:0.######},{val5.y:0.######},{val5.z:0.######}) " + $"viewportOrigin=({val6.x:0.######},{val6.y:0.######},{val6.z:0.######}) " + $"viewportTip=({val7.x:0.######},{val7.y:0.######},{val7.z:0.######}) " + $"closestRayParameter={num4:0.######} missPixels={num5:0.###} " + $"missNormalizedHeight={num6:0.######} " + $"pointsTowardCrosshair={flag}]"; } private static bool TryGetRendererBoundsInSpace(GameObject root, Transform space, out Bounds bounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00c2: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00db: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); if ((Object)(object)root == (Object)null || (Object)(object)space == (Object)null) { return false; } bool flag = false; Renderer[] componentsInChildren = root.GetComponentsInChildren(false); Vector3 val2 = default(Vector3); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.enabled) { continue; } Bounds bounds2 = val.bounds; Vector3 min = ((Bounds)(ref bounds2)).min; bounds2 = val.bounds; Vector3 max = ((Bounds)(ref bounds2)).max; for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { for (int l = 0; l < 2; l++) { ((Vector3)(ref val2))..ctor((j == 0) ? min.x : max.x, (k == 0) ? min.y : max.y, (l == 0) ? min.z : max.z); Vector3 val3 = space.InverseTransformPoint(val2); if (!flag) { bounds = new Bounds(val3, Vector3.zero); flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val3); } } } } } return flag; } private static string DescribeBoundsMin(Bounds bounds, bool valid) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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 (!valid) { return ""; } Vector3 min = ((Bounds)(ref bounds)).min; return $"({min.x:0.######},{min.y:0.######},{min.z:0.######})"; } private static string DescribeBoundsMax(Bounds bounds, bool valid) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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 (!valid) { return ""; } Vector3 max = ((Bounds)(ref bounds)).max; return $"({max.x:0.######},{max.y:0.######},{max.z:0.######})"; } private string DescribeLayerState(int layerIndex) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bodyAnimator == (Object)null || layerIndex < 0 || layerIndex >= bodyAnimator.layerCount) { return ""; } try { AnimatorStateInfo currentAnimatorStateInfo = bodyAnimator.GetCurrentAnimatorStateInfo(layerIndex); return $"hash={((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash} normalizedTime={((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime:0.###}"; } catch { return ""; } } private float GetLayerWeight(int layerIndex) { if ((Object)(object)bodyAnimator == (Object)null || layerIndex < 0 || layerIndex >= bodyAnimator.layerCount) { return -1f; } try { return bodyAnimator.GetLayerWeight(layerIndex); } catch { return -1f; } } private static string DescribeLocalPosition(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) if ((Object)(object)transform == (Object)null) { return ""; } Vector3 localPosition = transform.localPosition; return $"({localPosition.x:0.###},{localPosition.y:0.###},{localPosition.z:0.###})"; } private static string DescribeLocalEuler(Transform transform) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) if ((Object)(object)transform == (Object)null) { return ""; } Vector3 localEulerAngles = transform.localEulerAngles; return $"({localEulerAngles.x:0.#},{localEulerAngles.y:0.#},{localEulerAngles.z:0.#})"; } private static Transform FindChildRecursive(Transform root, string childName) { if ((Object)(object)root == (Object)null) { return null; } if (string.Equals(((Object)root).name, childName, StringComparison.Ordinal)) { return root; } for (int i = 0; i < root.childCount; i++) { Transform val = FindChildRecursive(root.GetChild(i), childName); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static Transform ResolvePropAttachBone(Transform root, InteractionAnimationManifest.PropManifest prop) { return PropAttachBoneResolver.Resolve(root, prop, (Transform candidate, string path) => candidate.Find(path), FindChildRecursive); } private static bool IsRigBuilderComponent(Component component) { Type type = (((Object)(object)component != (Object)null) ? ((object)component).GetType() : null); if (type == null) { return false; } if (!string.Equals(type.Name, "RigBuilder", StringComparison.Ordinal)) { return string.Equals(type.FullName, "UnityEngine.Animations.Rigging.RigBuilder", StringComparison.Ordinal); } return true; } private void SetLayerWeightIfValid(int layerIndex, float weight) { if (layerIndex < 0 || (Object)(object)bodyAnimator == (Object)null || layerIndex >= bodyAnimator.layerCount) { return; } try { bodyAnimator.SetLayerWeight(layerIndex, Mathf.Clamp01(weight)); } catch { } } private float GetLayerWeightOrZero(int layerIndex) { if (layerIndex < 0 || (Object)(object)bodyAnimator == (Object)null || layerIndex >= bodyAnimator.layerCount) { return 0f; } try { return Mathf.Clamp01(bodyAnimator.GetLayerWeight(layerIndex)); } catch { return 0f; } } private void SetBoolIfExists(string parameterName, bool value) { if (string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, (AnimatorControllerParameterType)4)) { return; } try { bodyAnimator.SetBool(parameterName, value); } catch { } } private void FireTriggerIfExists(string parameterName) { if (string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, (AnimatorControllerParameterType)9)) { return; } try { bodyAnimator.ResetTrigger(parameterName); bodyAnimator.SetTrigger(parameterName); } catch { } } private void ResetTriggerIfExists(string parameterName) { if (string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, (AnimatorControllerParameterType)9)) { return; } try { bodyAnimator.ResetTrigger(parameterName); } catch { } } private bool HasParameter(string parameterName, AnimatorControllerParameterType parameterType) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bodyAnimator == (Object)null) { return false; } try { RuntimeAnimatorController runtimeAnimatorController = bodyAnimator.runtimeAnimatorController; if (runtimeAnimatorController != parameterCacheController) { parameterPresenceCache.Clear(); parameterCacheController = runtimeAnimatorController; } (string, AnimatorControllerParameterType) key = (parameterName, parameterType); if (parameterPresenceCache.TryGetValue(key, out var value)) { return value; } bool flag = false; AnimatorControllerParameter[] parameters = bodyAnimator.parameters; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].type == parameterType && string.Equals(parameters[i].name, parameterName, StringComparison.Ordinal)) { flag = true; break; } } parameterPresenceCache[key] = flag; return flag; } catch { } return false; } private static int FindLayerIndex(Animator animator, string layerName) { if ((Object)(object)animator == (Object)null || string.IsNullOrWhiteSpace(layerName)) { return -1; } try { for (int i = 0; i < animator.layerCount; i++) { if (string.Equals(animator.GetLayerName(i), layerName, StringComparison.Ordinal)) { return i; } } } catch { } return -1; } private void ReleaseBundle(bool retainOwnedBundles = false) { if ((Object)(object)bundle != (Object)null && ownsBundle) { if (retainOwnedBundles) { RetainedBundles.Add(bundle); } else { bundle.Unload(false); } } bundle = null; ownsBundle = false; if ((Object)(object)clipPackBundle != (Object)null && ownsClipPackBundle) { if (retainOwnedBundles) { RetainedBundles.Add(clipPackBundle); } else { clipPackBundle.Unload(false); } } clipPackBundle = null; ownsClipPackBundle = false; } internal static void ShutdownBundleCache() { foreach (AssetBundle retainedBundle in RetainedBundles) { if (!((Object)(object)retainedBundle == (Object)null)) { try { retainedBundle.Unload(false); } catch { } } } RetainedBundles.Clear(); } private void CleanupFailedStart() { StopTransformChainDiagnostics(); StopExternalCameraPresentationDiagnostics(); StopLocalVisorHardGlue(); DestroyProp(); StopLocalCameraRotationStabilizer(restoreSessionEntryRotation: true); StopLocalCameraPositionStabilizer(restorePosition: true, deferRelease: false); RestoreLiveRigBuilders(); ReleaseBundle(); bodyAnimator = null; appliedController = null; snapshot = null; rigControlPoseSnapshot = null; rigControlRoot = null; thirdPersonRigControlPoseSnapshot = null; scopedFirstPersonPoseSnapshot = null; ResetCameraDisplacementGuardState(); context = null; active = false; } private static bool TryResolveBundlePath(string bundleFileName, string assetRootPath, out string resolvedPath, out string reason) { return InteractionAnimationAssetPathResolver.TryResolveBundlePath(bundleFileName, assetRootPath, out resolvedPath, out reason); } private static bool IsLocalPlayer(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } try { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null && (Object)(object)StartOfRound.Instance != (Object)null) { val = StartOfRound.Instance.localPlayerController; } return player == val; } catch { return false; } } } internal readonly struct AnimatorPlaybackRateMeasurement { internal double WallSeconds { get; } internal double NormalizedCyclesAdvanced { get; } internal int CompletedCycles { get; } internal double ClipSecondsAdvanced { get; } internal double EffectiveCyclesPerSecond { get; } internal double EffectiveClipSecondsPerWallSecond { get; } internal double ExpectedClipSecondsPerWallSecond { get; } internal double EffectiveToExpectedRatio { get; } internal AnimatorPlaybackRateMeasurement(double wallSeconds, double normalizedCyclesAdvanced, int completedCycles, double clipSecondsAdvanced, double effectiveCyclesPerSecond, double effectiveClipSecondsPerWallSecond, double expectedClipSecondsPerWallSecond, double effectiveToExpectedRatio) { WallSeconds = wallSeconds; NormalizedCyclesAdvanced = normalizedCyclesAdvanced; CompletedCycles = completedCycles; ClipSecondsAdvanced = clipSecondsAdvanced; EffectiveCyclesPerSecond = effectiveCyclesPerSecond; EffectiveClipSecondsPerWallSecond = effectiveClipSecondsPerWallSecond; ExpectedClipSecondsPerWallSecond = expectedClipSecondsPerWallSecond; EffectiveToExpectedRatio = effectiveToExpectedRatio; } } internal static class AnimatorPlaybackRateMath { internal static bool TryMeasure(float startNormalizedTime, float endNormalizedTime, double wallSeconds, float stateLengthSeconds, float animatorSpeed, float stateSpeed, float stateSpeedMultiplier, out AnimatorPlaybackRateMeasurement measurement) { measurement = default(AnimatorPlaybackRateMeasurement); if (wallSeconds <= 0.0 || double.IsNaN(wallSeconds) || double.IsInfinity(wallSeconds) || stateLengthSeconds <= 0f || float.IsNaN(stateLengthSeconds) || float.IsInfinity(stateLengthSeconds) || float.IsNaN(startNormalizedTime) || float.IsInfinity(startNormalizedTime) || float.IsNaN(endNormalizedTime) || float.IsInfinity(endNormalizedTime)) { return false; } double num = (double)endNormalizedTime - (double)startNormalizedTime; if (num < 0.0) { return false; } int completedCycles = Math.Max(0, (int)Math.Floor(endNormalizedTime) - (int)Math.Floor(startNormalizedTime)); double num2 = num * (double)stateLengthSeconds; double effectiveCyclesPerSecond = num / wallSeconds; double num3 = num2 / wallSeconds; double num4 = (double)animatorSpeed * (double)stateSpeed * (double)stateSpeedMultiplier; double effectiveToExpectedRatio = ((Math.Abs(num4) > 1E-06) ? (num3 / num4) : 0.0); measurement = new AnimatorPlaybackRateMeasurement(wallSeconds, num, completedCycles, num2, effectiveCyclesPerSecond, num3, num4, effectiveToExpectedRatio); return true; } } [DefaultExecutionOrder(32000)] internal sealed class LocalCameraPositionStabilizer : MonoBehaviour { private Transform playerRoot; private Transform cameraTransform; private Vector3 playerLocalPosition; private int releaseLateUpdates = -1; private PlayerControllerB stancePlayer; private float stanceRelativeHeightOffset; private float crouchRestHeight; private float standRestHeight; private bool stanceRelative; internal float StanceRelativeHeightOffset => stanceRelativeHeightOffset; internal void Initialize(Transform playerRoot, Transform cameraTransform, Vector3 playerLocalPosition) { //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) this.playerRoot = playerRoot; this.cameraTransform = cameraTransform; this.playerLocalPosition = playerLocalPosition; stanceRelative = false; stancePlayer = null; ApplyNow(); } internal void InitializeStanceRelative(Transform playerRoot, Transform cameraTransform, Vector3 playerLocalPosition, PlayerControllerB player, bool crouchingAtCapture, float crouchRestHeight, float standRestHeight) { //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_002e: Unknown result type (might be due to invalid IL or missing references) this.playerRoot = playerRoot; this.cameraTransform = cameraTransform; this.playerLocalPosition = playerLocalPosition; stancePlayer = player; this.crouchRestHeight = crouchRestHeight; this.standRestHeight = standRestHeight; stanceRelativeHeightOffset = playerLocalPosition.y - (crouchingAtCapture ? crouchRestHeight : standRestHeight); stanceRelative = (Object)(object)player != (Object)null; ApplyNow(); } private Vector3 ResolveTargetPlayerLocalPosition() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!stanceRelative || (Object)(object)stancePlayer == (Object)null) { return playerLocalPosition; } bool isCrouching; try { isCrouching = stancePlayer.isCrouching; } catch { return playerLocalPosition; } float num = (isCrouching ? crouchRestHeight : standRestHeight); return new Vector3(playerLocalPosition.x, num + stanceRelativeHeightOffset, playerLocalPosition.z); } internal void ReleaseAfterLateUpdates(int lateUpdates) { releaseLateUpdates = Mathf.Max(1, lateUpdates); } internal void RetargetToCurrentPosition() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)playerRoot == (Object)null || (Object)(object)cameraTransform == (Object)null) { return; } playerLocalPosition = playerRoot.InverseTransformPoint(cameraTransform.position); if (stanceRelative && !((Object)(object)stancePlayer == (Object)null)) { bool isCrouching; try { isCrouching = stancePlayer.isCrouching; } catch { return; } stanceRelativeHeightOffset = playerLocalPosition.y - (isCrouching ? crouchRestHeight : standRestHeight); } } internal void ApplyNow() { //IL_002a: 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) if (!((Object)(object)playerRoot == (Object)null) && !((Object)(object)cameraTransform == (Object)null)) { cameraTransform.position = playerRoot.TransformPoint(ResolveTargetPlayerLocalPosition()); } } private void LateUpdate() { ApplyNow(); if (releaseLateUpdates >= 0) { releaseLateUpdates--; if (releaseLateUpdates <= 0) { ((Behaviour)this).enabled = false; Object.Destroy((Object)(object)this); } } } } [DefaultExecutionOrder(32000)] internal sealed class LocalCameraRotationStabilizer : MonoBehaviour { private Transform cameraTransform; private float sessionEntryLocalYaw; private float sessionEntryLocalRoll; private bool beforeRenderSubscribed; internal void Initialize(Transform cameraTransform, float sessionEntryLocalYaw, float sessionEntryLocalRoll) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown UnsubscribeBeforeRender(); this.cameraTransform = cameraTransform; this.sessionEntryLocalYaw = sessionEntryLocalYaw; this.sessionEntryLocalRoll = sessionEntryLocalRoll; ((Behaviour)this).enabled = true; Application.onBeforeRender += new UnityAction(ApplyNow); beforeRenderSubscribed = true; ApplyNow(); } internal void ApplyNow() { //IL_0015: 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) //IL_0021: 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) if (!((Object)(object)cameraTransform == (Object)null)) { Vector3 localEulerAngles = cameraTransform.localEulerAngles; cameraTransform.localRotation = Quaternion.Euler(localEulerAngles.x, sessionEntryLocalYaw, sessionEntryLocalRoll); } } private void LateUpdate() { ApplyNow(); } private void OnDisable() { UnsubscribeBeforeRender(); } private void OnDestroy() { UnsubscribeBeforeRender(); } private void UnsubscribeBeforeRender() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (beforeRenderSubscribed) { try { Application.onBeforeRender -= new UnityAction(ApplyNow); } catch { } beforeRenderSubscribed = false; } } } internal sealed class LocalViewmodelPresenter : IInteractionPresenter { private readonly struct RendererState { private readonly Renderer renderer; private readonly bool enabled; private RendererState(Renderer renderer, bool enabled) { this.renderer = renderer; this.enabled = enabled; } internal static RendererState Capture(Renderer renderer) { return new RendererState(renderer, (Object)(object)renderer != (Object)null && renderer.enabled); } internal void Restore() { if ((Object)(object)renderer != (Object)null) { renderer.enabled = enabled; } } } private const long SynchronousLoadSizeLimitBytes = 16777216L; private static readonly HashSet PreloadingBundlePaths = new HashSet(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary PreloadedBundles = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly List hiddenRenderers = new List(); private InteractionAnimationContext context; private AssetBundle viewmodelBundle; private bool ownsViewmodelBundle; private GameObject viewmodelRoot; private RuntimeAnimatorController viewmodelController; private Animator viewmodelAnimator; private bool active; private bool exitRequested; public InteractionAnimationStopReason? RequestedStopReason => null; public bool HasResourceOwnership { get { if (active) { return (Object)(object)viewmodelRoot != (Object)null; } return false; } } internal static bool TryBeginPreload(InteractionAnimationManifest manifest, string assetRootPath, ManualLogSource logger, out string reason) { reason = string.Empty; if (manifest == null || manifest.localViewmodel == null) { reason = "missing_viewmodel_manifest"; return false; } if (!TryResolveBundlePath(manifest.localViewmodel.bundleFileName, assetRootPath, out var resolvedPath, out reason)) { if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.bundle_preload_rejected: file='" + manifest.localViewmodel.bundleFileName + "' reason='" + reason + "'.")); } return false; } if (string.IsNullOrWhiteSpace(resolvedPath) || !File.Exists(resolvedPath)) { reason = "viewmodel.bundle_preload_missing:" + manifest.localViewmodel.bundleFileName; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.bundle_preload_missing: file='" + manifest.localViewmodel.bundleFileName + "' resolvedPath='" + resolvedPath + "'.")); } return false; } string bundleInternalName = manifest.bundleInternalName ?? string.Empty; if ((Object)(object)FindLoadedBundle(bundleInternalName, resolvedPath) != (Object)null) { return true; } if (PreloadingBundlePaths.Contains(resolvedPath)) { return true; } if ((Object)(object)Plugin.Host == (Object)null) { if (logger != null) { logger.LogWarning((object)"[LCInteractionAnimationAPI] viewmodel.bundle_preload_unavailable: plugin instance missing."); } reason = "viewmodel.bundle_preload_unavailable"; return false; } PreloadingBundlePaths.Add(resolvedPath); if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] viewmodel.bundle_preload_started: " + $"path='{resolvedPath}' fileBytes={new FileInfo(resolvedPath).Length}.")); } ((MonoBehaviour)Plugin.Host).StartCoroutine(PreloadBundleCoroutine(resolvedPath, bundleInternalName, logger)); return true; } public bool TryPreflight(InteractionAnimationContext context, out string reason) { reason = string.Empty; if (context?.Manifest?.localViewmodel == null) { reason = "missing_viewmodel_manifest"; return false; } this.context = context; InteractionAnimationManifest.LocalViewmodelManifest localViewmodel = context.Manifest.localViewmodel; if (!TryLoadViewmodelBundle(context.Manifest, out reason)) { return false; } GameObject val = viewmodelBundle.LoadAsset(localViewmodel.prefabAssetName); if ((Object)(object)val == (Object)null) { reason = "viewmodel.prefab_missing:" + localViewmodel.prefabAssetName; CleanupFailedStart(); return false; } if ((Object)(object)viewmodelBundle.LoadAsset(localViewmodel.controllerAssetName) == (Object)null) { reason = "viewmodel.controller_missing:" + localViewmodel.controllerAssetName; CleanupFailedStart(); return false; } if ((Object)(object)ResolveCameraParent(out var _) == (Object)null) { reason = "viewmodel.camera_missing"; CleanupFailedStart(); return false; } if ((Object)(object)val.transform.Find(localViewmodel.cameraAnchorPath) == (Object)null) { reason = "viewmodel.camera_anchor_missing:" + localViewmodel.cameraAnchorPath; CleanupFailedStart(); return false; } return true; } public bool TryStart(InteractionAnimationContext context, out string reason) { reason = string.Empty; if (context == null) { reason = "missing_context"; return false; } InteractionAnimationManifest manifest = context.Manifest; if (manifest == null || manifest.localViewmodel == null) { reason = "missing_viewmodel_manifest"; return false; } this.context = context; if ((Object)(object)viewmodelBundle == (Object)null && !TryLoadViewmodelBundle(manifest, out reason)) { return false; } if (!TryInstantiateViewmodel(manifest, out reason)) { CleanupFailedStart(); return false; } HideLiveFirstPersonRenderers(); active = true; exitRequested = false; SetBoolIfExists(manifest.localViewmodel.activeBool, value: true); FireTriggerIfExists(manifest.localViewmodel.enterTrigger); viewmodelAnimator.Update(0f); EvaluateViewmodelRigBuilders(); ManualLogSource logger = context.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.started: " + $"handle={context.Handle} interaction='{manifest.interactionId}' " + "prefab='" + manifest.localViewmodel.prefabAssetName + "' controller='" + manifest.localViewmodel.controllerAssetName + "' cameraAnchorPath='" + manifest.localViewmodel.cameraAnchorPath + "'.")); } return true; } public void Tick(float deltaTime) { if (active) { _ = context; } } public float BeginExit() { InteractionAnimationManifest.LocalViewmodelManifest localViewmodelManifest = context?.Manifest?.localViewmodel; if (!active || (Object)(object)viewmodelAnimator == (Object)null || localViewmodelManifest == null || exitRequested) { return 0f; } exitRequested = true; SetBoolIfExists(localViewmodelManifest.activeBool, value: false); FireTriggerIfExists(localViewmodelManifest.exitTrigger); float num = Mathf.Max(0f, localViewmodelManifest.exitSeconds); ManualLogSource logger = context.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.exit_started: " + $"handle={context.Handle} exitSeconds={num:0.###}.")); } return num; } public bool TrySetAnimatorParameter(string parameterName, AnimatorControllerParameterType parameterType, float value) { //IL_0020: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 if (!active || (Object)(object)viewmodelAnimator == (Object)null || string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, parameterType)) { return false; } try { switch (parameterType - 1) { default: if ((int)parameterType != 9) { break; } viewmodelAnimator.ResetTrigger(parameterName); viewmodelAnimator.SetTrigger(parameterName); return true; case 3: viewmodelAnimator.SetBool(parameterName, value != 0f); return true; case 2: viewmodelAnimator.SetInteger(parameterName, (int)value); return true; case 0: viewmodelAnimator.SetFloat(parameterName, value); return true; case 1: break; } return false; } catch { return false; } } public void Stop(InteractionAnimationStopReason stopReason) { if (!active && (Object)(object)viewmodelRoot == (Object)null && (Object)(object)viewmodelBundle == (Object)null) { return; } RestoreLiveFirstPersonRenderers(); DestroyViewmodel(); ReleaseViewmodelBundle(); InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.stopped: " + $"handle={context.Handle} reason='{stopReason}' restoredRenderers={hiddenRenderers.Count}.")); } } hiddenRenderers.Clear(); active = false; exitRequested = false; context = null; } private void SetBoolIfExists(string parameterName, bool value) { if (string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, (AnimatorControllerParameterType)4)) { return; } try { viewmodelAnimator.SetBool(parameterName, value); } catch { } } private void FireTriggerIfExists(string parameterName) { if (string.IsNullOrWhiteSpace(parameterName) || !HasParameter(parameterName, (AnimatorControllerParameterType)9)) { return; } try { viewmodelAnimator.ResetTrigger(parameterName); viewmodelAnimator.SetTrigger(parameterName); } catch { } } private bool HasParameter(string parameterName, AnimatorControllerParameterType parameterType) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)viewmodelAnimator == (Object)null) { return false; } try { AnimatorControllerParameter[] parameters = viewmodelAnimator.parameters; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].type == parameterType && string.Equals(parameters[i].name, parameterName, StringComparison.Ordinal)) { return true; } } } catch { } return false; } private void RebuildViewmodelRigBuilders() { if ((Object)(object)viewmodelRoot == (Object)null) { return; } int num = 0; Behaviour[] componentsInChildren = viewmodelRoot.GetComponentsInChildren(true); foreach (Behaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null || !IsRigBuilderComponent((Component)(object)val)) { continue; } try { MethodInfo method = ((object)val).GetType().GetMethod("Build", Type.EmptyTypes); if (method != null) { method.Invoke(val, null); num++; } } catch (Exception ex) { InteractionAnimationContext interactionAnimationContext = context; if (interactionAnimationContext != null) { ManualLogSource logger = interactionAnimationContext.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] local_viewmodel.rig_rebuild_failed: " + $"handle={context?.Handle} rigBuilder='{((Object)val).name}' reason='{ex.Message}'.")); } } } } InteractionAnimationContext interactionAnimationContext2 = context; if (interactionAnimationContext2 != null) { ManualLogSource logger2 = interactionAnimationContext2.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.rig_rebuilt: " + $"handle={context?.Handle} rigBuilders={num}.")); } } } private void EvaluateViewmodelRigBuilders() { if ((Object)(object)viewmodelRoot == (Object)null) { return; } Behaviour[] componentsInChildren = viewmodelRoot.GetComponentsInChildren(true); foreach (Behaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.isActiveAndEnabled && IsRigBuilderComponent((Component)(object)val)) { try { ((object)val).GetType().GetMethod("Evaluate", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(float) }, null)?.Invoke(val, new object[1] { 0f }); } catch { } } } } private static bool IsRigBuilderComponent(Component component) { Type type = (((Object)(object)component != (Object)null) ? ((object)component).GetType() : null); if (type == null) { return false; } if (!string.Equals(type.Name, "RigBuilder", StringComparison.Ordinal)) { return string.Equals(type.FullName, "UnityEngine.Animations.Rigging.RigBuilder", StringComparison.Ordinal); } return true; } private bool TryLoadViewmodelBundle(InteractionAnimationManifest manifest, out string reason) { reason = string.Empty; string bundleInternalName = manifest.bundleInternalName ?? string.Empty; if (!TryResolveBundlePath(manifest.localViewmodel.bundleFileName, context.AssetRootPath, out var resolvedPath, out reason)) { return false; } viewmodelBundle = FindLoadedBundle(bundleInternalName, resolvedPath); if ((Object)(object)viewmodelBundle != (Object)null) { ownsViewmodelBundle = false; return true; } if (string.IsNullOrWhiteSpace(resolvedPath) || !File.Exists(resolvedPath)) { reason = "viewmodel.bundle_missing:" + manifest.localViewmodel.bundleFileName; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.bundle_missing: " + $"handle={context.Handle} file='{manifest.localViewmodel.bundleFileName}'.")); } return false; } if (PreloadingBundlePaths.Contains(resolvedPath)) { reason = "viewmodel.bundle_preload_in_progress:" + resolvedPath; ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.bundle_preload_in_progress: " + $"handle={context.Handle} path='{resolvedPath}'.")); } return false; } if (new FileInfo(resolvedPath).Length > 16777216) { TryBeginPreload(manifest, context.AssetRootPath, context.Logger, out var _); reason = "viewmodel.bundle_preload_started:" + resolvedPath; return false; } viewmodelBundle = AssetBundle.LoadFromFile(resolvedPath); if ((Object)(object)viewmodelBundle == (Object)null) { reason = "viewmodel.bundle_load_failed:" + resolvedPath; return false; } ownsViewmodelBundle = true; ManualLogSource logger3 = context.Logger; if (logger3 != null) { logger3.LogInfo((object)("[LCInteractionAnimationAPI] viewmodel.bundle_loaded: " + $"handle={context.Handle} path='{resolvedPath}'.")); } return true; } private static IEnumerator PreloadBundleCoroutine(string bundlePath, string bundleInternalName, ManualLogSource logger) { AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(bundlePath); yield return request; PreloadingBundlePaths.Remove(bundlePath); AssetBundle assetBundle = request.assetBundle; if ((Object)(object)assetBundle == (Object)null) { if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.bundle_preload_failed: path='" + bundlePath + "'.")); } yield break; } PreloadedBundles[bundlePath] = assetBundle; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] viewmodel.bundle_preload_completed: path='" + bundlePath + "' internalName='" + ((Object)assetBundle).name + "' expectedInternalName='" + bundleInternalName + "'.")); } } private static AssetBundle FindLoadedBundle(string bundleInternalName, string bundlePath) { if (!string.IsNullOrWhiteSpace(bundlePath) && PreloadedBundles.TryGetValue(bundlePath, out var value) && (Object)(object)value != (Object)null) { return value; } foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && !string.IsNullOrWhiteSpace(bundleInternalName) && string.Equals(((Object)allLoadedAssetBundle).name, bundleInternalName, StringComparison.OrdinalIgnoreCase)) { return allLoadedAssetBundle; } } return null; } private bool TryInstantiateViewmodel(InteractionAnimationManifest manifest, out string reason) { //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) reason = string.Empty; GameObject val = viewmodelBundle.LoadAsset(manifest.localViewmodel.prefabAssetName); if ((Object)(object)val == (Object)null) { reason = "viewmodel.prefab_missing:" + manifest.localViewmodel.prefabAssetName; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.prefab_missing: " + $"handle={context.Handle} prefab='{manifest.localViewmodel.prefabAssetName}'.")); } return false; } viewmodelController = viewmodelBundle.LoadAsset(manifest.localViewmodel.controllerAssetName); if ((Object)(object)viewmodelController == (Object)null) { reason = "viewmodel.controller_missing:" + manifest.localViewmodel.controllerAssetName; ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogWarning((object)("[LCInteractionAnimationAPI] viewmodel.controller_missing: " + $"handle={context.Handle} controller='{manifest.localViewmodel.controllerAssetName}'.")); } return false; } Camera camera; Transform val2 = ResolveCameraParent(out camera); if ((Object)(object)val2 == (Object)null) { reason = "viewmodel.camera_missing"; return false; } viewmodelRoot = Object.Instantiate(val, val2); ((Object)viewmodelRoot).name = "Y4NGZ_Viewmodel_" + SafeObjectName(manifest.interactionId); viewmodelRoot.transform.localPosition = Vector3.zero; viewmodelRoot.transform.localRotation = Quaternion.identity; viewmodelRoot.transform.localScale = manifest.localViewmodel.localScale.ToUnityVector3(); if (!TryAlignViewmodelToCameraAnchor(manifest, out reason)) { return false; } viewmodelAnimator = viewmodelRoot.GetComponentInChildren(true); if ((Object)(object)viewmodelAnimator == (Object)null) { viewmodelAnimator = viewmodelRoot.AddComponent(); } viewmodelAnimator.runtimeAnimatorController = viewmodelController; viewmodelAnimator.applyRootMotion = false; ((Behaviour)viewmodelAnimator).enabled = true; viewmodelAnimator.Rebind(); RebuildViewmodelRigBuilders(); viewmodelAnimator.Update(0f); EvaluateViewmodelRigBuilders(); ApplyViewmodelRendererVisibility(manifest); ManualLogSource logger3 = context.Logger; if (logger3 != null) { logger3.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.instantiated: " + $"handle={context.Handle} prefab='{manifest.localViewmodel.prefabAssetName}' " + "controller='" + manifest.localViewmodel.controllerAssetName + "' camera='" + ((Object)val2).name + "'.")); } return true; } private Transform ResolveCameraParent(out Camera camera) { camera = (((Object)(object)context?.Request?.Player != (Object)null) ? context.Request.Player.gameplayCamera : null); if ((Object)(object)camera != (Object)null) { return ((Component)camera).transform; } camera = Camera.main; if (!((Object)(object)camera != (Object)null)) { return null; } return ((Component)camera).transform; } private bool TryAlignViewmodelToCameraAnchor(InteractionAnimationManifest manifest, out string reason) { //IL_00b2: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_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_011d: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) reason = string.Empty; if ((Object)(object)viewmodelRoot == (Object)null || manifest?.localViewmodel == null) { reason = "viewmodel.camera_anchor_context_missing"; return false; } string text = manifest.localViewmodel.cameraAnchorPath ?? string.Empty; Transform val = viewmodelRoot.transform.Find(text); if ((Object)(object)val == (Object)null) { reason = "viewmodel.camera_anchor_missing:" + text; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogWarning((object)("[LCInteractionAnimationAPI] local_viewmodel.anchor_missing: " + $"handle={context.Handle} anchorPath='{text}'.")); } return false; } Vector3 val2 = viewmodelRoot.transform.InverseTransformPoint(val.position); Quaternion val3 = Quaternion.Inverse(viewmodelRoot.transform.rotation) * val.rotation; Quaternion val4 = Quaternion.Euler(manifest.localViewmodel.cameraLocalEuler.ToUnityVector3()); viewmodelRoot.transform.localRotation = val4 * Quaternion.Inverse(val3); Vector3 val5 = viewmodelRoot.transform.localRotation * Vector3.Scale(val2, viewmodelRoot.transform.localScale); viewmodelRoot.transform.localPosition = manifest.localViewmodel.cameraLocalPosition.ToUnityVector3() - val5; ManualLogSource logger2 = context.Logger; if (logger2 != null) { logger2.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.anchor_aligned: " + $"handle={context.Handle} anchorPath='{text}' path='{GetTransformPath(val)}' " + "anchorRootLocalPosition=" + FormatVector(val2) + " anchorRootLocalEuler=" + FormatVector(((Quaternion)(ref val3)).eulerAngles) + " targetLocalPosition=" + FormatVector(manifest.localViewmodel.cameraLocalPosition) + " targetLocalEuler=" + FormatVector(manifest.localViewmodel.cameraLocalEuler) + " rootLocalPosition=" + FormatVector(viewmodelRoot.transform.localPosition) + " rootLocalEuler=" + FormatVector(viewmodelRoot.transform.localEulerAngles) + " rootLocalScale=" + FormatVector(viewmodelRoot.transform.localScale) + ".")); } return true; } private void LogCameraDiagnostics(Camera camera, Transform cameraParent, InteractionAnimationManifest manifest) { //IL_003e: 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_002c: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) if (context?.Logger != null && !((Object)(object)viewmodelRoot == (Object)null)) { Vector3 val = (((Object)(object)camera != (Object)null) ? (viewmodelRoot.transform.position - ((Component)camera).transform.position) : Vector3.zero); float value = (((Object)(object)camera != (Object)null) ? ((Vector3)(ref val)).magnitude : (-1f)); float value2 = (((Object)(object)camera != (Object)null && ((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? Vector3.Dot(((Component)camera).transform.forward, ((Vector3)(ref val)).normalized) : 0f); Vector3 value3 = (((Object)(object)camera != (Object)null) ? camera.WorldToViewportPoint(viewmodelRoot.transform.position) : Vector3.zero); bool flag = IsLayerInCullingMask(camera, viewmodelRoot.layer); context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.camera_diagnostics: " + $"handle={context.Handle} camera='{SafeName((Object)(object)camera)}' " + $"cameraEnabled={(Object)(object)camera != (Object)null && ((Behaviour)camera).enabled} " + $"cameraActive={(Object)(object)camera != (Object)null && ((Component)camera).gameObject.activeInHierarchy} " + $"cameraLayer={(((Object)(object)camera != (Object)null) ? ((Component)camera).gameObject.layer : (-1))} " + $"cullingMask={(((Object)(object)camera != (Object)null) ? camera.cullingMask : 0)} " + "nearClip=" + FormatFloat(((Object)(object)camera != (Object)null) ? camera.nearClipPlane : (-1f)) + " farClip=" + FormatFloat(((Object)(object)camera != (Object)null) ? camera.farClipPlane : (-1f)) + " fieldOfView=" + FormatFloat(((Object)(object)camera != (Object)null) ? camera.fieldOfView : (-1f)) + " " + $"orthographic={(Object)(object)camera != (Object)null && camera.orthographic} " + "parent='" + GetTransformPath(cameraParent) + "' root='" + GetTransformPath(viewmodelRoot.transform) + "' " + $"rootActive={viewmodelRoot.activeSelf} rootActiveInHierarchy={viewmodelRoot.activeInHierarchy} " + $"rootLayer={viewmodelRoot.layer} rootLayerVisible={flag} " + "rootLocalPosition=" + FormatVector(viewmodelRoot.transform.localPosition) + " manifestCameraAnchor='" + manifest.localViewmodel.cameraAnchorPath + "' manifestLocalPosition=" + FormatVector(manifest.localViewmodel.cameraLocalPosition) + " rootLocalEuler=" + FormatVector(viewmodelRoot.transform.localEulerAngles) + " manifestLocalEuler=" + FormatVector(manifest.localViewmodel.cameraLocalEuler) + " rootLocalScale=" + FormatVector(viewmodelRoot.transform.localScale) + " rootLossyScale=" + FormatVector(viewmodelRoot.transform.lossyScale) + " rootWorldPosition=" + FormatVector(viewmodelRoot.transform.position) + " cameraWorldPosition=" + FormatVector(((Object)(object)camera != (Object)null) ? ((Component)camera).transform.position : Vector3.zero) + " distanceToCamera=" + FormatFloat(value) + " forwardDot=" + FormatFloat(value2) + " rootViewport=" + FormatVector(value3) + ".")); } } private void BeginPostFrameRendererDiagnostics(Camera camera) { if (!((Object)(object)Plugin.Host == (Object)null) && context != null) { ((MonoBehaviour)Plugin.Host).StartCoroutine(PostFrameRendererDiagnosticsCoroutine(context.Handle, camera)); } } private IEnumerator PostFrameRendererDiagnosticsCoroutine(InteractionAnimationHandle handle, Camera camera) { yield return (object)new WaitForEndOfFrame(); if (context != null && !(context.Handle != handle) && !((Object)(object)viewmodelRoot == (Object)null)) { LogRendererDiagnostics(camera, "post_frame", "local_viewmodel.post_frame_renderer_diagnostics"); } } private void LogRendererDiagnostics(Camera camera) { LogRendererDiagnostics(camera, "start", "local_viewmodel.renderer_diagnostics"); } private void LogRendererDiagnostics(Camera camera, string phase, string eventName) { //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) //IL_00cf: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) if (context?.Logger == null || (Object)(object)viewmodelRoot == (Object)null) { return; } Renderer[] componentsInChildren = viewmodelRoot.GetComponentsInChildren(true); Plane[] array = (((Object)(object)camera != (Object)null) ? GeometryUtility.CalculateFrustumPlanes(camera) : null); context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] " + eventName + "_summary: " + $"handle={context.Handle} phase='{phase}' rendererCount={componentsInChildren.Length} camera='{SafeName((Object)(object)camera)}'.")); for (int i = 0; i < componentsInChildren.Length; i++) { Renderer val = componentsInChildren[i]; if (!((Object)(object)val == (Object)null)) { Bounds bounds = val.bounds; Vector3 val2 = (((Object)(object)camera != (Object)null) ? (((Bounds)(ref bounds)).center - ((Component)camera).transform.position) : Vector3.zero); float value = (((Object)(object)camera != (Object)null) ? ((Vector3)(ref val2)).magnitude : (-1f)); float value2 = (((Object)(object)camera != (Object)null && ((Vector3)(ref val2)).sqrMagnitude > 0.0001f) ? Vector3.Dot(((Component)camera).transform.forward, ((Vector3)(ref val2)).normalized) : 0f); Vector3 value3 = (((Object)(object)camera != (Object)null) ? camera.WorldToViewportPoint(((Bounds)(ref bounds)).center) : Vector3.zero); bool flag = array != null && GeometryUtility.TestPlanesAABB(array, bounds); bool flag2 = IsLayerInCullingMask(camera, ((Component)val).gameObject.layer); SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); Material[] sharedMaterials = GetSharedMaterials(val); context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] " + eventName + ": " + $"handle={context.Handle} phase='{phase}' index={i} total={componentsInChildren.Length} " + "renderer='" + GetTransformPath(((Component)val).transform) + "' name='" + ((Object)val).name + "' " + $"type='{((object)val).GetType().Name}' active={((Component)val).gameObject.activeSelf} " + $"activeInHierarchy={((Component)val).gameObject.activeInHierarchy} enabled={val.enabled} " + $"isVisible={val.isVisible} layer={((Component)val).gameObject.layer} " + $"cameraMaskIncludesLayer={flag2} inCameraFrustum={flag} " + "boundsCenter=" + FormatVector(((Bounds)(ref bounds)).center) + " boundsSize=" + FormatVector(((Bounds)(ref bounds)).size) + " distanceToCamera=" + FormatFloat(value) + " forwardDot=" + FormatFloat(value2) + " viewportCenter=" + FormatVector(value3) + " " + $"updateWhenOffscreen={(Object)(object)val3 != (Object)null && val3.updateWhenOffscreen} " + "rootBone='" + SafeName((Object)(object)(((Object)(object)val3 != (Object)null) ? val3.rootBone : null)) + "' " + $"sharedMaterialCount={sharedMaterials.Length}.")); LogRendererMaterials(val, i, sharedMaterials); } } } private void LogRendererMaterials(Renderer renderer, int rendererIndex, Material[] materials) { if (context?.Logger == null) { return; } if (materials.Length == 0) { context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.renderer_material: " + $"handle={context.Handle} rendererIndex={rendererIndex} materialIndex=-1 material=''.")); return; } for (int i = 0; i < materials.Length; i++) { Material val = materials[i]; Shader unityObject = (((Object)(object)val != (Object)null) ? val.shader : null); context.Logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.renderer_material: " + $"handle={context.Handle} rendererIndex={rendererIndex} materialIndex={i} " + "renderer='" + GetTransformPath(((Component)renderer).transform) + "' material='" + SafeName((Object)(object)val) + "' " + $"shader='{SafeName((Object)(object)unityObject)}' renderQueue={(((Object)(object)val != (Object)null) ? val.renderQueue : (-1))} " + "color=" + TryFormatMaterialColor(val) + ".")); } } private void ApplyViewmodelRendererVisibility(InteractionAnimationManifest manifest) { if ((Object)(object)viewmodelRoot == (Object)null || manifest.localViewmodel == null) { return; } Renderer[] componentsInChildren = viewmodelRoot.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string relativeTransformPath = GetRelativeTransformPath(viewmodelRoot.transform, ((Component)val).transform); if (ShouldHide(manifest.localViewmodel.prefabRenderersToHide, relativeTransformPath)) { val.enabled = false; } if (ShouldHide(manifest.localViewmodel.prefabRenderersToShow, relativeTransformPath)) { val.enabled = true; } } } } private void HideLiveFirstPersonRenderers() { if ((Object)(object)context?.Request?.Player == (Object)null || context.Manifest == null || !context.Manifest.localViewmodel.hideVanillaFirstPersonArms) { return; } Renderer thisPlayerModelArms = (Renderer)(object)context.Request.Player.thisPlayerModelArms; if (!((Object)(object)thisPlayerModelArms == (Object)null)) { hiddenRenderers.Add(RendererState.Capture(thisPlayerModelArms)); thisPlayerModelArms.enabled = false; ManualLogSource logger = context.Logger; if (logger != null) { logger.LogInfo((object)("[LCInteractionAnimationAPI] local_viewmodel.renderer_hidden: " + $"handle={context.Handle} renderer='{((Object)thisPlayerModelArms).name}'.")); } } } private void RestoreLiveFirstPersonRenderers() { for (int num = hiddenRenderers.Count - 1; num >= 0; num--) { hiddenRenderers[num].Restore(); } } private void DestroyViewmodel() { if ((Object)(object)viewmodelRoot != (Object)null) { Object.Destroy((Object)(object)viewmodelRoot); } viewmodelRoot = null; viewmodelAnimator = null; viewmodelController = null; } private void ReleaseViewmodelBundle() { if ((Object)(object)viewmodelBundle != (Object)null && ownsViewmodelBundle) { viewmodelBundle.Unload(false); } viewmodelBundle = null; ownsViewmodelBundle = false; } private void CleanupFailedStart() { RestoreLiveFirstPersonRenderers(); DestroyViewmodel(); ReleaseViewmodelBundle(); context = null; active = false; } private static bool ShouldHide(string[] rendererHints, string value) { if (rendererHints == null) { return false; } for (int i = 0; i < rendererHints.Length; i++) { if (string.Equals(rendererHints[i], value, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static bool TryFindChildRecursive(Transform root, string childName, out Transform child) { child = null; if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(childName)) { return false; } if (string.Equals(((Object)root).name, childName, StringComparison.OrdinalIgnoreCase)) { child = root; return true; } for (int i = 0; i < root.childCount; i++) { if (TryFindChildRecursive(root.GetChild(i), childName, out child)) { return true; } } return false; } private static bool TryResolveBundlePath(string bundleFileName, string assetRootPath, out string resolvedPath, out string reason) { return InteractionAnimationAssetPathResolver.TryResolveBundlePath(bundleFileName, assetRootPath, out resolvedPath, out reason); } private static string SafeObjectName(string value) { if (string.IsNullOrWhiteSpace(value)) { return "interaction"; } char[] array = value.ToCharArray(); for (int i = 0; i < array.Length; i++) { if (!char.IsLetterOrDigit(array[i]) && array[i] != '_' && array[i] != '-') { array[i] = '_'; } } return new string(array); } private static bool IsLayerInCullingMask(Camera camera, int layer) { if ((Object)(object)camera == (Object)null || layer < 0 || layer > 31) { return false; } return (camera.cullingMask & (1 << layer)) != 0; } private static Material[] GetSharedMaterials(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return Array.Empty(); } try { return renderer.sharedMaterials ?? Array.Empty(); } catch { return Array.Empty(); } } private static string TryFormatMaterialColor(Material material) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return ""; } try { return material.HasProperty("_Color") ? FormatColor(material.color) : ""; } catch { return ""; } } private static string GetRelativeTransformPath(Transform root, Transform transform) { if ((Object)(object)root == (Object)null || (Object)(object)transform == (Object)null) { return string.Empty; } if (root == transform) { return string.Empty; } List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null && val != root) { list.Add(((Object)val).name); val = val.parent; } if ((Object)(object)val == (Object)null) { return string.Empty; } list.Reverse(); return string.Join("/", list.ToArray()); } private static string GetTransformPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } List list = new List(); Transform val = transform; while ((Object)(object)val != (Object)null && list.Count < 48) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } private static string SafeName(Object unityObject) { if (!(unityObject != (Object)null)) { return ""; } return unityObject.name; } private static string FormatVector(Vector3 value) { //IL_0010: 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_003c: Unknown result type (might be due to invalid IL or missing references) return "(" + FormatFloat(value.x) + "," + FormatFloat(value.y) + "," + FormatFloat(value.z) + ")"; } private static string FormatVector(InteractionAnimationVector3 value) { return "(" + FormatFloat(value.x) + "," + FormatFloat(value.y) + "," + FormatFloat(value.z) + ")"; } private static string FormatColor(Color value) { //IL_0011: 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_003d: 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) return "(" + FormatFloat(value.r) + "," + FormatFloat(value.g) + "," + FormatFloat(value.b) + "," + FormatFloat(value.a) + ")"; } private static string FormatFloat(float value) { if (float.IsNaN(value)) { return "NaN"; } if (float.IsPositiveInfinity(value)) { return "Infinity"; } if (float.IsNegativeInfinity(value)) { return "-Infinity"; } return value.ToString("0.###", CultureInfo.InvariantCulture); } } internal static class PropAttachBoneResolver { internal static T Resolve(T root, InteractionAnimationManifest.PropManifest prop, Func findExactPath, Func findRecursiveName) where T : class { if (root == null || prop == null || string.IsNullOrWhiteSpace(prop.attachBonePath)) { return null; } if (!prop.useLegacyRecursiveAttachBoneLookup) { return findExactPath(root, prop.attachBonePath); } return findRecursiveName(root, prop.attachBonePath); } } internal static class StanceViewpointGuardMath { internal static bool HasSustainedMismatch(bool stanceChanged, bool exempt, float heightDeviation, float tolerance, float deltaSeconds, float requiredSeconds, ref float mismatchSeconds) { if (stanceChanged || exempt || heightDeviation <= tolerance) { mismatchSeconds = 0f; return false; } mismatchSeconds += Math.Max(0f, deltaSeconds); return mismatchSeconds >= Math.Max(0f, requiredSeconds); } } } namespace Y4NGZInteractions.InteractionAnimationApi.Authoring { [Serializable] public struct InteractionAnimationVector3 { public float x; public float y; public float z; public InteractionAnimationVector3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } internal Vector3 ToUnityVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } } [Serializable] public sealed class InteractionAnimationManifest { [Serializable] public sealed class LocalViewmodelManifest { public string bundleFileName = string.Empty; public string prefabAssetName = string.Empty; public string controllerAssetName = string.Empty; public string activeBool = string.Empty; public string enterTrigger = string.Empty; public string exitTrigger = string.Empty; public float exitSeconds; public string cameraAnchorPath = string.Empty; public InteractionAnimationVector3 cameraLocalPosition; public InteractionAnimationVector3 cameraLocalEuler; public InteractionAnimationVector3 localScale = new InteractionAnimationVector3(1f, 1f, 1f); public bool hideVanillaFirstPersonArms; public string[] prefabRenderersToHide = Array.Empty(); public string[] prefabRenderersToShow = Array.Empty(); } [Serializable] public sealed class BodyManifest { public bool enabled; public string bundleFileName = string.Empty; public string controllerAssetName = string.Empty; public string activeBool = string.Empty; public string enterTrigger = string.Empty; public string exitTrigger = string.Empty; public string fullBodyLayer = string.Empty; public string firstPersonArmsLayer = string.Empty; public float startLayerWeight = 1f; public float layerWeightRampSeconds; public float fullBodyLayerWeight = -1f; public float enterLayerFadeSeconds; public float naturalEndLayerFadeSeconds; public bool rebuildRigBuilders; public float exitSeconds; public string movementParameter = string.Empty; public bool preserveGameplayCamera = true; public bool stopOnGameplayCameraDisplacement = true; public bool stabilizeLocalCameraPosition; public bool localCameraOwnedExternally; public bool stopOnVanillaSpecialAnimation = true; public ClipPackManifest clipPack = new ClipPackManifest(); public PropManifest prop = new PropManifest(); } [Serializable] public sealed class PropManifest { [NonSerialized] internal bool useLegacyRecursiveAttachBoneLookup; public bool enabled; public string prefabAssetName = string.Empty; public string attachBonePath = string.Empty; public InteractionAnimationVector3 localPosition; public InteractionAnimationVector3 localEulerAngles; public float localScale = 1f; public float releaseSeconds; } [Serializable] public sealed class ClipPackManifest { public bool enabled; public string bundleFileName = string.Empty; public string bundleInternalName = string.Empty; public ClipOverrideManifest[] overrides = Array.Empty(); } [Serializable] public sealed class ClipOverrideManifest { public string slot = string.Empty; public string clip = string.Empty; } public int schemaVersion = 2; public string interactionId = string.Empty; public float durationSeconds; public string bundleInternalName = string.Empty; public LocalViewmodelManifest localViewmodel = new LocalViewmodelManifest(); public BodyManifest body = new BodyManifest(); public static bool TryParse(string json, out InteractionAnimationManifest manifest, out string reason) { InteractionAnimationValidationReport interactionAnimationValidationReport = InteractionAnimationManifestValidator.Parse(json, out manifest); reason = InteractionAnimationManifestValidator.GetFirstErrorCode(interactionAnimationValidationReport); return interactionAnimationValidationReport.IsValid; } } internal static class InteractionAnimationManifestValidator { private static readonly JsonSerializerSettings StrictSchema2Settings = new JsonSerializerSettings { MissingMemberHandling = (MissingMemberHandling)1, ObjectCreationHandling = (ObjectCreationHandling)2 }; internal static InteractionAnimationValidationReport Parse(string json, out InteractionAnimationManifest manifest) { //IL_0045: Expected O, but got Unknown //IL_0195: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Invalid comparison between Unknown and I4 manifest = null; List list = new List(); if (string.IsNullOrWhiteSpace(json)) { AddError(list, "manifest_json_empty", "$", "Manifest JSON is required."); return new InteractionAnimationValidationReport(list); } JObject val; try { val = JObject.Parse(json, new JsonLoadSettings { DuplicatePropertyNameHandling = (DuplicatePropertyNameHandling)2 }); } catch (JsonReaderException ex) { JsonReaderException ex2 = ex; AddError(list, "manifest_json_invalid", ToJsonPath(ex2.Path), "Manifest JSON is invalid: " + ((Exception)(object)ex2).Message); return new InteractionAnimationValidationReport(list); } int num = 1; JToken val2 = val["schemaVersion"]; if (val2 == null) { foreach (JProperty item in val.Properties()) { if (string.Equals(item.Name, "schemaVersion", StringComparison.OrdinalIgnoreCase)) { AddError(list, "manifest_unknown_field", "$." + item.Name, "Schema-2 field names are case-sensitive."); return new InteractionAnimationValidationReport(list); } } } if (val2 != null) { if ((int)val2.Type != 6) { AddError(list, "manifest_schema_version_invalid", "$.schemaVersion", "schemaVersion must be an integer."); return new InteractionAnimationValidationReport(list); } num = Extensions.Value((IEnumerable)val2); } try { switch (num) { case 1: manifest = LegacyInteractionAnimationMigration.Normalize(((JToken)val).ToObject()); list.Add(new InteractionAnimationValidationIssue("manifest_schema_1_migrated", "$.schemaVersion", "Schema 1 was accepted through the 1.x compatibility path; author schema 2 for new content.", InteractionAnimationValidationSeverity.Warning)); break; case 2: ValidateSchema2PropertyNames(val, list); if (list.Count == 0) { manifest = JsonConvert.DeserializeObject(json, StrictSchema2Settings); } break; default: AddError(list, "manifest_schema_version_unsupported", "$.schemaVersion", "Only schema versions 1 and 2 are supported."); break; } } catch (JsonSerializationException ex3) { JsonSerializationException ex4 = ex3; string code = ((((Exception)(object)ex4).Message.IndexOf("Could not find member", StringComparison.OrdinalIgnoreCase) >= 0) ? "manifest_unknown_field" : "manifest_json_invalid"); AddError(list, code, ToJsonPath(ex4.Path), "Manifest does not match its schema: " + ((Exception)(object)ex4).Message); } catch (Exception ex5) { AddError(list, "manifest_json_invalid", "$", "Manifest could not be read: " + ex5.Message); } if (manifest == null && list.Count == 0) { AddError(list, "manifest_json_returned_null", "$", "Manifest JSON produced no object."); } return new InteractionAnimationValidationReport(list); } internal static InteractionAnimationValidationReport Validate(string json, string expectedInteractionId, InteractionAnimationPresentationKind presentationKind, out InteractionAnimationManifest manifest) { InteractionAnimationValidationReport interactionAnimationValidationReport = Parse(json, out manifest); List issues = new List(interactionAnimationValidationReport.Issues); if (manifest != null && interactionAnimationValidationReport.IsValid) { ValidateNormalized(manifest, expectedInteractionId, presentationKind, issues); } return new InteractionAnimationValidationReport(issues); } internal static string GetFirstErrorCode(InteractionAnimationValidationReport report) { if (report == null) { return "validation_report_missing"; } for (int i = 0; i < report.Issues.Count; i++) { if (report.Issues[i].Severity == InteractionAnimationValidationSeverity.Error) { return report.Issues[i].Code; } } return string.Empty; } private static void ValidateSchema2PropertyNames(JObject root, IList issues) { ValidateProperties(root, "$", issues, "schemaVersion", "interactionId", "durationSeconds", "bundleInternalName", "localViewmodel", "body"); JToken obj = root["localViewmodel"]; JObject val = (JObject)(object)((obj is JObject) ? obj : null); if (val != null) { ValidateProperties(val, "$.localViewmodel", issues, "bundleFileName", "prefabAssetName", "controllerAssetName", "activeBool", "enterTrigger", "exitTrigger", "exitSeconds", "cameraAnchorPath", "cameraLocalPosition", "cameraLocalEuler", "localScale", "hideVanillaFirstPersonArms", "prefabRenderersToHide", "prefabRenderersToShow"); ValidateVectorProperties(val["cameraLocalPosition"], "$.localViewmodel.cameraLocalPosition", issues); ValidateVectorProperties(val["cameraLocalEuler"], "$.localViewmodel.cameraLocalEuler", issues); ValidateVectorProperties(val["localScale"], "$.localViewmodel.localScale", issues); } JToken obj2 = root["body"]; JObject val2 = (JObject)(object)((obj2 is JObject) ? obj2 : null); if (val2 == null) { return; } ValidateProperties(val2, "$.body", issues, "enabled", "bundleFileName", "controllerAssetName", "activeBool", "enterTrigger", "exitTrigger", "fullBodyLayer", "firstPersonArmsLayer", "startLayerWeight", "layerWeightRampSeconds", "fullBodyLayerWeight", "enterLayerFadeSeconds", "naturalEndLayerFadeSeconds", "rebuildRigBuilders", "exitSeconds", "movementParameter", "preserveGameplayCamera", "stopOnGameplayCameraDisplacement", "stabilizeLocalCameraPosition", "localCameraOwnedExternally", "stopOnVanillaSpecialAnimation", "clipPack", "prop"); JToken obj3 = val2["clipPack"]; JObject val3 = (JObject)(object)((obj3 is JObject) ? obj3 : null); if (val3 != null) { ValidateProperties(val3, "$.body.clipPack", issues, "enabled", "bundleFileName", "bundleInternalName", "overrides"); JToken obj4 = val3["overrides"]; JArray val4 = (JArray)(object)((obj4 is JArray) ? obj4 : null); if (val4 != null) { for (int i = 0; i < ((JContainer)val4).Count; i++) { JToken obj5 = val4[i]; JObject val5 = (JObject)(object)((obj5 is JObject) ? obj5 : null); if (val5 != null) { ValidateProperties(val5, "$.body.clipPack.overrides[" + i + "]", issues, "slot", "clip"); } } } } JToken obj6 = val2["prop"]; JObject val6 = (JObject)(object)((obj6 is JObject) ? obj6 : null); if (val6 != null) { ValidateProperties(val6, "$.body.prop", issues, "enabled", "prefabAssetName", "attachBonePath", "localPosition", "localEulerAngles", "localScale", "releaseSeconds"); ValidateVectorProperties(val6["localPosition"], "$.body.prop.localPosition", issues); ValidateVectorProperties(val6["localEulerAngles"], "$.body.prop.localEulerAngles", issues); } } private static void ValidateVectorProperties(JToken token, string path, IList issues) { JObject val = (JObject)(object)((token is JObject) ? token : null); if (val != null) { ValidateProperties(val, path, issues, "x", "y", "z"); } } private static void ValidateProperties(JObject value, string path, IList issues, params string[] allowedNames) { foreach (JProperty item in value.Properties()) { bool flag = false; for (int i = 0; i < allowedNames.Length; i++) { if (string.Equals(item.Name, allowedNames[i], StringComparison.Ordinal)) { flag = true; break; } } if (!flag) { AddError(issues, "manifest_unknown_field", path + "." + item.Name, "Schema-2 field names are exact and case-sensitive."); } } } private static void ValidateNormalized(InteractionAnimationManifest manifest, string expectedInteractionId, InteractionAnimationPresentationKind presentationKind, IList issues) { if (manifest.schemaVersion != 2) { AddError(issues, "manifest_schema_version_invalid", "$.schemaVersion", "The normalized schema version must be 2."); } RequireIdentifier(manifest.interactionId, "$.interactionId", "manifest_interaction_id_empty", issues); if (!string.IsNullOrWhiteSpace(expectedInteractionId) && !string.Equals(manifest.interactionId, expectedInteractionId, StringComparison.OrdinalIgnoreCase)) { AddError(issues, "manifest_interaction_id_mismatch", "$.interactionId", "The manifest interactionId must match its registered interaction id."); } ValidateNonNegativeFinite(manifest.durationSeconds, "$.durationSeconds", "manifest_duration_invalid", issues); switch (presentationKind) { case InteractionAnimationPresentationKind.DedicatedLocalViewmodel: ValidateLocalViewmodel(manifest.localViewmodel, issues); break; case InteractionAnimationPresentationKind.BodyWorld: ValidateBody(manifest.body, issues); break; default: AddError(issues, "presentation_kind_invalid", "$.presentationKind", "The presentation kind is not supported by the 1.0 API."); break; } } private static void ValidateLocalViewmodel(InteractionAnimationManifest.LocalViewmodelManifest viewmodel, IList issues) { if (viewmodel == null) { AddError(issues, "manifest_viewmodel_missing", "$.localViewmodel", "DedicatedLocalViewmodel requires a localViewmodel object."); return; } ValidateBundlePath(viewmodel.bundleFileName, "$.localViewmodel.bundleFileName", "manifest_viewmodel_bundle_file_invalid", issues); RequireAssetName(viewmodel.prefabAssetName, "$.localViewmodel.prefabAssetName", "manifest_viewmodel_prefab_asset_invalid", issues); RequireAssetName(viewmodel.controllerAssetName, "$.localViewmodel.controllerAssetName", "manifest_viewmodel_controller_asset_invalid", issues); RequireTransformPath(viewmodel.cameraAnchorPath, "$.localViewmodel.cameraAnchorPath", "manifest_viewmodel_camera_anchor_invalid", issues); ValidateNonNegativeFinite(viewmodel.exitSeconds, "$.localViewmodel.exitSeconds", "manifest_viewmodel_exit_seconds_invalid", issues); ValidateVector(viewmodel.cameraLocalPosition, "$.localViewmodel.cameraLocalPosition", requirePositive: false, issues); ValidateVector(viewmodel.cameraLocalEuler, "$.localViewmodel.cameraLocalEuler", requirePositive: false, issues); ValidateVector(viewmodel.localScale, "$.localViewmodel.localScale", requirePositive: true, issues); ValidateTransformPaths(viewmodel.prefabRenderersToHide, "$.localViewmodel.prefabRenderersToHide", issues); ValidateTransformPaths(viewmodel.prefabRenderersToShow, "$.localViewmodel.prefabRenderersToShow", issues); } private static void ValidateBody(InteractionAnimationManifest.BodyManifest body, IList issues) { if (body == null || !body.enabled) { AddError(issues, "manifest_body_disabled", "$.body.enabled", "BodyWorld requires body.enabled to be true."); return; } ValidateBundlePath(body.bundleFileName, "$.body.bundleFileName", "manifest_body_bundle_file_invalid", issues); RequireAssetName(body.controllerAssetName, "$.body.controllerAssetName", "manifest_body_controller_asset_invalid", issues); ValidateUnitWeight(body.startLayerWeight, "$.body.startLayerWeight", "manifest_body_start_layer_weight_invalid", issues); ValidateNonNegativeFinite(body.layerWeightRampSeconds, "$.body.layerWeightRampSeconds", "manifest_body_layer_ramp_invalid", issues); if (!IsFinite(body.fullBodyLayerWeight) || body.fullBodyLayerWeight > 1f) { AddError(issues, "manifest_body_full_body_weight_invalid", "$.body.fullBodyLayerWeight", "fullBodyLayerWeight must be negative for shared ramping or between 0 and 1."); } ValidateNonNegativeFinite(body.enterLayerFadeSeconds, "$.body.enterLayerFadeSeconds", "manifest_body_enter_fade_invalid", issues); ValidateNonNegativeFinite(body.naturalEndLayerFadeSeconds, "$.body.naturalEndLayerFadeSeconds", "manifest_body_natural_end_fade_invalid", issues); ValidateNonNegativeFinite(body.exitSeconds, "$.body.exitSeconds", "manifest_body_exit_seconds_invalid", issues); ValidateClipPack(body.clipPack, issues); ValidateProp(body.prop, issues); } private static void ValidateClipPack(InteractionAnimationManifest.ClipPackManifest clipPack, IList issues) { if (clipPack == null || !clipPack.enabled) { return; } ValidateBundlePath(clipPack.bundleFileName, "$.body.clipPack.bundleFileName", "manifest_clip_pack_bundle_file_invalid", issues); if (clipPack.overrides == null || clipPack.overrides.Length == 0) { AddError(issues, "manifest_clip_pack_overrides_empty", "$.body.clipPack.overrides", "An enabled clip pack requires at least one override."); return; } HashSet hashSet = new HashSet(StringComparer.Ordinal); for (int i = 0; i < clipPack.overrides.Length; i++) { string text = "$.body.clipPack.overrides[" + i + "]"; InteractionAnimationManifest.ClipOverrideManifest clipOverrideManifest = clipPack.overrides[i]; if (clipOverrideManifest == null) { AddError(issues, "manifest_clip_override_null", text, "Clip override is required."); continue; } RequireAssetName(clipOverrideManifest.slot, text + ".slot", "manifest_clip_override_slot_invalid", issues); RequireAssetName(clipOverrideManifest.clip, text + ".clip", "manifest_clip_override_asset_invalid", issues); if (!string.IsNullOrWhiteSpace(clipOverrideManifest.slot) && !hashSet.Add(clipOverrideManifest.slot)) { AddError(issues, "manifest_clip_override_slot_duplicate", text + ".slot", "Each controller slot may be overridden once."); } } } private static void ValidateProp(InteractionAnimationManifest.PropManifest prop, IList issues) { if (prop != null && prop.enabled) { RequireAssetName(prop.prefabAssetName, "$.body.prop.prefabAssetName", "manifest_prop_prefab_asset_invalid", issues); RequireTransformPath(prop.attachBonePath, "$.body.prop.attachBonePath", "manifest_prop_attach_bone_invalid", issues); ValidateVector(prop.localPosition, "$.body.prop.localPosition", requirePositive: false, issues); ValidateVector(prop.localEulerAngles, "$.body.prop.localEulerAngles", requirePositive: false, issues); if (!IsFinite(prop.localScale) || prop.localScale <= 0f) { AddError(issues, "manifest_prop_scale_invalid", "$.body.prop.localScale", "Prop scale must be finite and greater than zero."); } ValidateNonNegativeFinite(prop.releaseSeconds, "$.body.prop.releaseSeconds", "manifest_prop_release_seconds_invalid", issues); } } private static void ValidateTransformPaths(string[] paths, string basePath, IList issues) { if (paths == null) { AddError(issues, "manifest_transform_path_array_null", basePath, "Transform path arrays must be empty arrays instead of null."); return; } HashSet hashSet = new HashSet(StringComparer.Ordinal); for (int i = 0; i < paths.Length; i++) { string jsonPath = basePath + "[" + i + "]"; RequireTransformPath(paths[i], jsonPath, "manifest_transform_path_invalid", issues); if (!string.IsNullOrWhiteSpace(paths[i]) && !hashSet.Add(paths[i])) { issues.Add(new InteractionAnimationValidationIssue("manifest_transform_path_duplicate", jsonPath, "Duplicate transform paths are ignored.", InteractionAnimationValidationSeverity.Warning)); } } } private static void ValidateBundlePath(string value, string jsonPath, string code, IList issues) { if (string.IsNullOrWhiteSpace(value) || value != value.Trim() || Path.IsPathRooted(value) || value.IndexOf('\\') >= 0 || HasTraversal(value)) { AddError(issues, code, jsonPath, "Bundle paths must be trimmed, relative, slash-separated, and confined to the pack root."); } } private static void RequireIdentifier(string value, string jsonPath, string code, IList issues) { if (string.IsNullOrWhiteSpace(value) || value != value.Trim()) { AddError(issues, code, jsonPath, "A trimmed non-empty identifier is required."); } } private static void RequireAssetName(string value, string jsonPath, string code, IList issues) { if (string.IsNullOrWhiteSpace(value) || value != value.Trim() || HasTraversal(value)) { AddError(issues, code, jsonPath, "A trimmed non-empty asset name is required."); } } private static void RequireTransformPath(string value, string jsonPath, string code, IList issues) { if (string.IsNullOrWhiteSpace(value) || value != value.Trim() || value.StartsWith("/", StringComparison.Ordinal) || value.EndsWith("/", StringComparison.Ordinal) || value.IndexOf('\\') >= 0 || value.IndexOf("//", StringComparison.Ordinal) >= 0 || HasTraversal(value)) { AddError(issues, code, jsonPath, "A canonical prefab-relative transform path is required."); } } private static bool HasTraversal(string value) { if (string.IsNullOrEmpty(value)) { return false; } string[] array = value.Split('/'); for (int i = 0; i < array.Length; i++) { if (array[i] == "." || array[i] == "..") { return true; } } return false; } private static void ValidateVector(InteractionAnimationVector3 value, string jsonPath, bool requirePositive, IList issues) { bool flag = IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z); if (requirePositive) { flag &= value.x > 0f && value.y > 0f && value.z > 0f; } if (!flag) { AddError(issues, "manifest_vector_invalid", jsonPath, requirePositive ? "Vector components must be finite and greater than zero." : "Vector components must be finite."); } } private static void ValidateUnitWeight(float value, string jsonPath, string code, IList issues) { if (!IsFinite(value) || value < 0f || value > 1f) { AddError(issues, code, jsonPath, "Layer weight must be between 0 and 1."); } } private static void ValidateNonNegativeFinite(float value, string jsonPath, string code, IList issues) { if (!IsFinite(value) || value < 0f) { AddError(issues, code, jsonPath, "Value must be finite and non-negative."); } } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static string ToJsonPath(string path) { if (string.IsNullOrWhiteSpace(path)) { return "$"; } if (!path.StartsWith("[", StringComparison.Ordinal)) { return "$." + path; } return "$" + path; } private static void AddError(IList issues, string code, string jsonPath, string message) { issues.Add(new InteractionAnimationValidationIssue(code, jsonPath, message, InteractionAnimationValidationSeverity.Error)); } } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyInteractionAnimationManifest { [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyLocalViewmodelManifest { internal string bundleFileName = string.Empty; internal string prefab = string.Empty; internal string controller = string.Empty; internal string activeBool = string.Empty; internal string enterTrigger = string.Empty; internal string exitTrigger = string.Empty; internal float exitSeconds; internal string root = string.Empty; internal string cameraAnchor = "Y4NGZ_ViewmodelCameraAnchor"; internal InteractionAnimationVector3 cameraLocalPosition = new InteractionAnimationVector3(0f, -0.42f, 0.95f); internal InteractionAnimationVector3 cameraLocalEuler; internal InteractionAnimationVector3 localScale = new InteractionAnimationVector3(0.55f, 0.55f, 0.55f); internal string runtimeMaterialMode = string.Empty; internal string[] hideSourceRenderers = Array.Empty(); internal string[] visibleRenderers = Array.Empty(); } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacySocketManifest { internal string leftHand = string.Empty; internal string rightHand = string.Empty; internal string prop = string.Empty; internal string tablet = string.Empty; } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyBodyManifest { internal bool enabled; internal string bundleFileName = string.Empty; internal string controller = string.Empty; internal string controllerAssetName = string.Empty; internal string clip = string.Empty; internal string activeBool = string.Empty; internal string enterTrigger = string.Empty; internal string exitTrigger = string.Empty; internal string fullBodyLayer = string.Empty; internal string firstPersonArmsLayer = string.Empty; internal float startLayerWeight = 1f; internal float layerWeightRampSeconds; internal float fullBodyLayerWeight = -1f; internal bool scopedFirstPersonTransformRestore; internal bool stabilizeLocalCameraPosition; internal bool localCameraOwnedExternally; internal float enterLayerFadeSeconds; internal float naturalEndLayerFadeSeconds; internal bool suppressRigBuilders = true; internal string diagnosticVanillaOverrideClip = string.Empty; internal string overrideSlotPrefix = string.Empty; internal float exitSeconds; internal string movementParameter = string.Empty; internal LegacyClipPackManifest clipPack = new LegacyClipPackManifest(); internal LegacyPropManifest prop = new LegacyPropManifest(); } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyPropManifest { internal bool enabled; internal string prefabName = string.Empty; internal string attachBone = string.Empty; internal InteractionAnimationVector3 localPosition; internal InteractionAnimationVector3 localEulerAngles; internal float localScale = 1f; internal float releaseSeconds; } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyClipPackManifest { internal bool enabled; internal string bundleFileName = string.Empty; internal string bundleInternalName = string.Empty; internal LegacyClipOverrideManifest[] overrides = Array.Empty(); } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyClipOverrideManifest { internal string slot = string.Empty; internal string clip = string.Empty; } [Serializable] [JsonObject(/*Could not decode attribute arguments.*/)] internal sealed class LegacyValidationManifest { internal string generatedAt = string.Empty; internal string previewPixelCoverage = string.Empty; internal string meshTransfer = string.Empty; internal string socketNames = string.Empty; internal string cameraBounds = string.Empty; } internal int schemaVersion = 1; internal string interactionId = string.Empty; internal string displayName = string.Empty; internal float durationSeconds; internal float frameRate; internal string bundleInternalName = string.Empty; internal LegacyLocalViewmodelManifest localViewmodel = new LegacyLocalViewmodelManifest(); internal LegacySocketManifest sockets = new LegacySocketManifest(); internal string[] liveRenderersToHide = Array.Empty(); internal LegacyBodyManifest body = new LegacyBodyManifest(); internal LegacyValidationManifest validation = new LegacyValidationManifest(); internal bool exemptFromCameraDisplacementGuard; internal bool exemptFromSpecialAnimationAutoStop; } internal static class LegacyInteractionAnimationMigration { internal static InteractionAnimationManifest Normalize(LegacyInteractionAnimationManifest legacy) { legacy = legacy ?? new LegacyInteractionAnimationManifest(); LegacyInteractionAnimationManifest.LegacyLocalViewmodelManifest legacyLocalViewmodelManifest = legacy.localViewmodel ?? new LegacyInteractionAnimationManifest.LegacyLocalViewmodelManifest(); LegacyInteractionAnimationManifest.LegacyBodyManifest legacyBodyManifest = legacy.body ?? new LegacyInteractionAnimationManifest.LegacyBodyManifest(); LegacyInteractionAnimationManifest.LegacyClipPackManifest legacyClipPackManifest = legacyBodyManifest.clipPack ?? new LegacyInteractionAnimationManifest.LegacyClipPackManifest(); LegacyInteractionAnimationManifest.LegacyPropManifest legacyPropManifest = legacyBodyManifest.prop ?? new LegacyInteractionAnimationManifest.LegacyPropManifest(); return new InteractionAnimationManifest { schemaVersion = 2, interactionId = (legacy.interactionId ?? string.Empty), durationSeconds = legacy.durationSeconds, bundleInternalName = (legacy.bundleInternalName ?? string.Empty), localViewmodel = new InteractionAnimationManifest.LocalViewmodelManifest { bundleFileName = (legacyLocalViewmodelManifest.bundleFileName ?? string.Empty), prefabAssetName = (legacyLocalViewmodelManifest.prefab ?? string.Empty), controllerAssetName = (legacyLocalViewmodelManifest.controller ?? string.Empty), activeBool = (legacyLocalViewmodelManifest.activeBool ?? string.Empty), enterTrigger = (legacyLocalViewmodelManifest.enterTrigger ?? string.Empty), exitTrigger = (legacyLocalViewmodelManifest.exitTrigger ?? string.Empty), exitSeconds = legacyLocalViewmodelManifest.exitSeconds, cameraAnchorPath = (legacyLocalViewmodelManifest.cameraAnchor ?? string.Empty), cameraLocalPosition = legacyLocalViewmodelManifest.cameraLocalPosition, cameraLocalEuler = legacyLocalViewmodelManifest.cameraLocalEuler, localScale = legacyLocalViewmodelManifest.localScale, hideVanillaFirstPersonArms = ContainsLegacyArmHint(legacy.liveRenderersToHide), prefabRenderersToHide = (legacyLocalViewmodelManifest.hideSourceRenderers ?? Array.Empty()), prefabRenderersToShow = (legacyLocalViewmodelManifest.visibleRenderers ?? Array.Empty()) }, body = new InteractionAnimationManifest.BodyManifest { enabled = legacyBodyManifest.enabled, bundleFileName = (legacyBodyManifest.bundleFileName ?? string.Empty), controllerAssetName = ((!string.IsNullOrWhiteSpace(legacyBodyManifest.controllerAssetName)) ? legacyBodyManifest.controllerAssetName : (legacyBodyManifest.controller ?? string.Empty)), activeBool = (legacyBodyManifest.activeBool ?? string.Empty), enterTrigger = (legacyBodyManifest.enterTrigger ?? string.Empty), exitTrigger = (legacyBodyManifest.exitTrigger ?? string.Empty), fullBodyLayer = (legacyBodyManifest.fullBodyLayer ?? string.Empty), firstPersonArmsLayer = (legacyBodyManifest.firstPersonArmsLayer ?? string.Empty), startLayerWeight = legacyBodyManifest.startLayerWeight, layerWeightRampSeconds = legacyBodyManifest.layerWeightRampSeconds, fullBodyLayerWeight = legacyBodyManifest.fullBodyLayerWeight, enterLayerFadeSeconds = legacyBodyManifest.enterLayerFadeSeconds, naturalEndLayerFadeSeconds = legacyBodyManifest.naturalEndLayerFadeSeconds, rebuildRigBuilders = !legacyBodyManifest.suppressRigBuilders, exitSeconds = legacyBodyManifest.exitSeconds, movementParameter = (legacyBodyManifest.movementParameter ?? string.Empty), preserveGameplayCamera = !legacyBodyManifest.localCameraOwnedExternally, stopOnGameplayCameraDisplacement = !legacy.exemptFromCameraDisplacementGuard, stabilizeLocalCameraPosition = legacyBodyManifest.stabilizeLocalCameraPosition, localCameraOwnedExternally = legacyBodyManifest.localCameraOwnedExternally, stopOnVanillaSpecialAnimation = !legacy.exemptFromSpecialAnimationAutoStop, clipPack = new InteractionAnimationManifest.ClipPackManifest { enabled = legacyClipPackManifest.enabled, bundleFileName = (legacyClipPackManifest.bundleFileName ?? string.Empty), bundleInternalName = (legacyClipPackManifest.bundleInternalName ?? string.Empty), overrides = NormalizeOverrides(legacyClipPackManifest.overrides) }, prop = new InteractionAnimationManifest.PropManifest { useLegacyRecursiveAttachBoneLookup = true, enabled = legacyPropManifest.enabled, prefabAssetName = (legacyPropManifest.prefabName ?? string.Empty), attachBonePath = (legacyPropManifest.attachBone ?? string.Empty), localPosition = legacyPropManifest.localPosition, localEulerAngles = legacyPropManifest.localEulerAngles, localScale = legacyPropManifest.localScale, releaseSeconds = legacyPropManifest.releaseSeconds } } }; } private static InteractionAnimationManifest.ClipOverrideManifest[] NormalizeOverrides(LegacyInteractionAnimationManifest.LegacyClipOverrideManifest[] source) { if (source == null || source.Length == 0) { return Array.Empty(); } InteractionAnimationManifest.ClipOverrideManifest[] array = new InteractionAnimationManifest.ClipOverrideManifest[source.Length]; for (int i = 0; i < source.Length; i++) { LegacyInteractionAnimationManifest.LegacyClipOverrideManifest legacyClipOverrideManifest = source[i]; array[i] = new InteractionAnimationManifest.ClipOverrideManifest { slot = (legacyClipOverrideManifest?.slot ?? string.Empty), clip = (legacyClipOverrideManifest?.clip ?? string.Empty) }; } return array; } private static bool ContainsLegacyArmHint(string[] hints) { if (hints == null) { return false; } for (int i = 0; i < hints.Length; i++) { if (string.Equals(hints[i], "thisPlayerModelArms", StringComparison.OrdinalIgnoreCase) || string.Equals(hints[i], "lc_first_person_hands", StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } }