using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using BoneHub.Api; using BoneHub.Avatars; using BoneHub.Compatibility; using BoneHub.Configuration; using BoneHub.Downloads; using BoneHub.Installation; using BoneHub.Interaction; using BoneHub.Mod; using BoneHub.Models; using BoneHub.Persistence; using BoneLib; using BoneLib.BoneMenu; using Il2CppCysharp.Threading.Tasks; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Bonelab.SaveData; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Forklift.Model; using Il2CppSLZ.Marrow.SaveData; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.VRMK; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(BoneHubMod), "WristHub", "2.0.1", "WristHub contributors", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("WristHub")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.1.0")] [assembly: AssemblyInformationalVersion("2.0.1")] [assembly: AssemblyProduct("WristHub")] [assembly: AssemblyTitle("WristHub")] [assembly: AssemblyVersion("2.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BoneHub.Mod { internal sealed class BoneHubAvatarBrowser : IDisposable { private sealed class TouchButton { public Transform Space { get; init; } public GameObject Root { get; init; } public Image Panel { get; init; } public TMP_Text Label { get; init; } public Vector3 Center { get; init; } public Vector3 Half { get; init; } public Action Action { get; init; } public TouchDebounce Debounce { get; } = new TouchDebounce(); public bool IsAlive { get { try { return (Object)(object)Root != (Object)null && (Object)(object)Space != (Object)null && (Object)(object)Panel != (Object)null && (Object)(object)Label != (Object)null; } catch { return false; } } } public bool Contains(Vector3 worldPoint) { //IL_0033: 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_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_0044: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0081: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)Root == (Object)null || (Object)(object)Space == (Object)null || !Root.activeInHierarchy) { return false; } Vector3 val = Space.InverseTransformPoint(worldPoint) - Center; return Mathf.Abs(val.x) <= Half.x && Mathf.Abs(val.y) <= Half.y && Mathf.Abs(val.z) <= Half.z; } catch { return false; } } } private sealed class PackRow { public TouchButton Button { get; init; } public TouchButton DeleteButton { get; init; } public RawImage Artwork { get; init; } public TMP_Text Name { get; init; } public TMP_Text Creator { get; init; } public TMP_Text State { get; init; } public string Identity { get; set; } = string.Empty; public int Generation { get; set; } public bool IsAlive { get { if (Button.IsAlive && DeleteButton.IsAlive && (Object)(object)Artwork != (Object)null && (Object)(object)Name != (Object)null && (Object)(object)Creator != (Object)null) { return (Object)(object)State != (Object)null; } return false; } } } private const float ChestRadius = 0.22f; private static readonly Color Glass = new Color(0.012f, 0.027f, 0.04f, 1f); private static readonly Color Surface = new Color(0.025f, 0.075f, 0.105f, 0.96f); private static readonly Color Cyan = new Color(0.2f, 0.9f, 1f, 1f); private static readonly Color DimCyan = new Color(0.055f, 0.25f, 0.32f, 1f); private static readonly Color Green = new Color(0.32f, 0.9f, 0.62f, 1f); private static readonly Color Red = new Color(1f, 0.38f, 0.46f, 1f); private readonly BoneHubService _service; private readonly BoneHubRuntime _runtime; private readonly BoneHubThumbnailCache _thumbnails; private readonly ConcurrentQueue _mainThread; private readonly BoneHubPreferences _preferences; private readonly bool _constrainedRendering; private readonly Instance _log; private readonly LobbyAvatarSharingBridge _sharing; private readonly List _buttons = new List(); private readonly Dictionary _touchCaptures = new Dictionary(); private readonly HashSet _activeProbeIds = new HashSet(); private readonly List _staleCaptureIds = new List(2); private readonly Dictionary _onlineMods = new Dictionary(); private readonly Dictionary _jobs = new Dictionary(); private readonly Dictionary> _downloadBatches = new Dictionary>(); private readonly Dictionary _previewMetrics = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _previewRoutes = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _rigValidations = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly HashSet _startingDownloads = new HashSet(); private readonly BoneHubFingertipProbeProvider _fingertips = new BoneHubFingertipProbeProvider(); private readonly TabletKeyboardBuffer _keyboard = new TabletKeyboardBuffer(); private readonly LookAwayDismissal _promptDismissal = new LookAwayDismissal(); private readonly FocusedResultCursor _cursor = new FocusedResultCursor(); private readonly FourRowPageCursor _packCursor = new FourRowPageCursor(); private readonly PresentationGeneration _artworkGeneration = new PresentationGeneration(); private readonly ErrorLogThrottle _runtimeErrorThrottle = new ErrorLogThrottle(); private readonly SurfaceInputRearmGate _inputRearm = new SurfaceInputRearmGate(0.1); private readonly InstalledPackFocus _installedFocus = new InstalledPackFocus(); private readonly BoneHubForearmProjectionAnchorProvider _projectionAnchors = new BoneHubForearmProjectionAnchorProvider(); private readonly List _packRows = new List(); private readonly Action _projectionTickAction; private readonly Action _projectionRecoveryAction; private readonly Action _touchTickAction; private readonly Action _touchRecoveryAction; private readonly Action _installationFocusTickAction; private readonly Action _previewTickAction; private readonly Action _previewRecoveryAction; private readonly Action _downloadTickAction; private readonly Action _sharingTickAction; private IReadOnlyList _entries = Array.Empty(); private IReadOnlyList _mergedEntries = Array.Empty(); private IReadOnlyList _onlineEntries = Array.Empty(); private IReadOnlyList _packs = Array.Empty(); private GameObject? _root; private GameObject? _launcher; private GameObject? _hub; private GameObject? _browser; private GameObject? _canvasRoot; private GameObject? _packPage; private GameObject? _detailPage; private GameObject? _optionsPage; private GameObject? _keyboardPage; private GameObject? _deletePage; private CanvasGroup? _canvasGroup; private TMP_Text? _packTitle; private TMP_Text? _packStatus; private TMP_Text? _packPosition; private TMP_Text? _packSearchText; private TMP_Text? _sortText; private TMP_Text? _wristText; private TMP_Text? _scaleText; private TMP_Text? _motionText; private TMP_Text? _startingViewText; private TMP_Text? _scopeText; private TMP_Text? _deleteTitle; private TMP_Text? _deleteDetails; private TMP_Text? _keyboardText; private TMP_Text? _keyboardShiftText; private TMP_Text? _searchText; private TMP_Text? _positionText; private TMP_Text? _selectedName; private TMP_Text? _creatorText; private TMP_Text? _modText; private TMP_Text? _statusText; private TMP_Text? _heightText; private GameObject? _heightRuler; private GameObject? _progressRoot; private RectTransform? _progressFill; private TMP_Text? _progressText; private TMP_Text? _actionLabel; private Image? _actionPanel; private TouchButton? _trashButton; private RawImage? _centralArtwork; private Texture2D? _placeholderTexture; private Texture2D? _roundedTexture; private Sprite? _roundedSprite; private BoneHubForearmProjection? _hologramProjection; private TouchButton? _actionButton; private GameObject? _previewShell; private GameObject? _previewFallback; private GameObject? _previewModel; private readonly List _ownedPreviewMeshes = new List(); private BoneHubAvatar? _previewAvatar; private BoneHubAvatar? _pendingPreviewAvatar; private string _loadedPreviewBarcode = string.Empty; private string _requestedPreviewBarcode = string.Empty; private float _previewLoadAt; private bool _previewReady; private bool _previewInteractionReady; private AvatarPreviewVisualSource _previewVisualSource; private bool _previewHeld; private Hand? _dragHand; private bool _dragIsLeft; private bool _dragUsesPinch; private Vector3 _dragLocalOffset; private Quaternion _dragRotationOffset = Quaternion.identity; private float _dragTrackingLostAt = -1f; private bool _previewReturning; private float _returnStarted; private Vector3 _returnFrom; private Quaternion _returnRotation; private int _previewGeneration; private int _searchGeneration; private string _query = string.Empty; private bool _downloadsOnly; private string _selectedIdentity = string.Empty; private string _trashConfirmIdentity = string.Empty; private bool _deleteReturnToPackPage; private bool _trashInProgress; private long? _selectedPackId; private AvatarPackSort _packSort; private AvatarBrowseScope _scope; private AvatarBrowseScope _scopeBeforeSearch; private Guid _progressJobId; private double _displayedProgress; private double _targetProgress; private int _lastProgressPercent = -1; private AvatarDownloadState? _lastProgressState; private AvatarBrowserViewState _viewState = (AvatarBrowserViewState)2; private AvatarBrowserViewState _viewStateBeforeKeyboard = (AvatarBrowserViewState)2; private bool _disposed; private bool _wasPlayerDead; private AvatarSharingState _sharingState; private BoneHubAvatar? _pendingSharingAvatar; private ModIoSharingMetadata? _pendingSharingMetadata; private string _sharingRetryBarcode = string.Empty; private float _nextSharingCheckAt; private float _sharingDeadline; private bool _sharingRefreshRequested; public bool IsOpen { get { if ((Object)(object)_browser != (Object)null) { return _browser.activeSelf; } return false; } } public bool IsLauncherOpen { get { if ((Object)(object)_root != (Object)null) { return _root.activeSelf; } return false; } } public string Query => _query; public event Action? Closed; public BoneHubAvatarBrowser(BoneHubService service, BoneHubRuntime runtime, BoneHubThumbnailCache thumbnails, ConcurrentQueue mainThread, BoneHubPreferences preferences, bool constrainedRendering, Instance log, LobbyAvatarSharingBridge? sharing = null) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) _service = service; _runtime = runtime; _thumbnails = thumbnails; _mainThread = mainThread; _preferences = preferences; _constrainedRendering = constrainedRendering; _log = log; _sharing = sharing ?? new LobbyAvatarSharingBridge(log); _projectionTickAction = TickProjectionStage; _projectionRecoveryAction = RecoverProjectionStage; _touchTickAction = TickTouchStage; _touchRecoveryAction = ResetTouchButtons; _installationFocusTickAction = UpdateInstalledPackFocus; _previewTickAction = ProcessPendingPreview; _previewRecoveryAction = RecoverPreviewStage; _downloadTickAction = UpdateDownloadProgress; _sharingTickAction = TickSharingRegistration; } public void OpenLauncher() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) EnsureBuilt(); if (!((Object)(object)_root == (Object)null) && !((Object)(object)_launcher == (Object)null) && !((Object)(object)_browser == (Object)null)) { FollowWrist(immediate: true); _root.SetActive(true); _launcher.SetActive(true); if ((Object)(object)_hub != (Object)null) { _hub.SetActive(false); } _browser.SetActive(false); _viewState = (AvatarBrowserViewState)0; _promptDismissal.Reset(); RefreshEntries(); RequireInputRearm(); } } public void Open() { //IL_0080: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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) OpenLauncher(); if (!((Object)(object)_launcher == (Object)null) && !((Object)(object)_browser == (Object)null)) { _launcher.SetActive(false); if ((Object)(object)_hub != (Object)null) { _hub.SetActive(false); } _browser.SetActive(true); StartHologramProjection(); _query = string.Empty; _downloadsOnly = false; _selectedPackId = null; _scope = AvatarBrowseStartup.Resolve(_preferences.AvatarBrowserStartupMode, _preferences.LastAvatarBrowseScope); _scopeBeforeSearch = _scope; _viewState = (AvatarBrowserViewState)2; RememberScope(); RefreshEntries(); ShowScopePage(); } } public void OpenSearch() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) OpenLauncher(); if (!((Object)(object)_launcher == (Object)null) && !((Object)(object)_browser == (Object)null)) { _launcher.SetActive(false); if ((Object)(object)_hub != (Object)null) { _hub.SetActive(false); } _browser.SetActive(true); StartHologramProjection(); _selectedPackId = null; _scope = AvatarBrowseStartup.Resolve(_preferences.AvatarBrowserStartupMode, _preferences.LastAvatarBrowseScope); _scopeBeforeSearch = _scope; RefreshEntries(); OpenKeyboard(); } } public void Close() { if (_previewHeld) { EndPreviewDrag(equipIfAtChest: false); } ResetTouchButtons(); ResetTrashConfirmation(); CancelPendingSharingRegistration(); if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } if ((Object)(object)_browser != (Object)null) { _browser.SetActive(false); } if ((Object)(object)_launcher != (Object)null) { _launcher.SetActive(false); } if ((Object)(object)_hub != (Object)null) { _hub.SetActive(false); } if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } _hologramProjection?.Hide(); _artworkGeneration.Next(); _previewGeneration++; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _promptDismissal.Reset(); this.Closed?.Invoke(); } public void SetQuery(string value) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_canvasGroup != (Object)null) { _canvasGroup.alpha = 1f; } if ((Object)(object)_root != (Object)null) { _root.SetActive(true); } if ((Object)(object)_launcher != (Object)null) { _launcher.SetActive(false); } if ((Object)(object)_hub != (Object)null) { _hub.SetActive(false); } if ((Object)(object)_browser != (Object)null) { _browser.SetActive(true); } _query = value?.Trim() ?? string.Empty; _downloadsOnly = false; _onlineEntries = Array.Empty(); _viewState = (AvatarBrowserViewState)((_query.Length == 0) ? 2 : 6); _log.Msg($"Avatar search submitted ({_query.Length} characters). Query text is not logged."); RefreshEntries(); if (_query.Length == 0) { ShowScopePage(); } else { _scope = (AvatarBrowseScope)0; _selectedPackId = null; RefreshEntries(); ShowDetailPage(); } int generation = ++_searchGeneration; if (_query.Length != 0 && _service.ModIoReady) { SetStatus("Searching BONELAB mod.io…", Cyan); SearchOnlineAsync(_query, generation); } } public void Refresh() { RefreshEntries(); RefreshVisiblePage(); } public void Select(string identity) { AvatarEntry val = ((IEnumerable)_entries).FirstOrDefault((Func)((AvatarEntry item) => string.Equals(item.Identity, identity, StringComparison.OrdinalIgnoreCase))); if (!(val == (AvatarEntry)null)) { _selectedIdentity = val.Identity; _cursor.Keep(_entries.Count, IndexOf(val.Identity)); ShowDetailPage(); RefreshSelection(val); } } public void OnDownloadChanged(DownloadJob job) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00c6: Invalid comparison between Unknown and I4 //IL_013c: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected I4, but got Unknown //IL_0160: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) _jobs[job.Mod.Id] = job; DownloadState state = job.State; if (state - 5 <= 2) { _startingDownloads.Remove(job.Mod.Id); } if ((int)job.State == 5 && _installedFocus.Active && _installedFocus.ModId == job.Mod.Id) { InstalledPackFocus installedFocus = _installedFocus; long id = job.Mod.Id; double num = Time.unscaledTime; InstalledModRecord result = job.Result; installedFocus.MarkDownloaded(id, num, (IEnumerable)((result != null) ? result.InstalledDirectories : null), 12.0); _log.Msg("Downloaded root pack completed; waiting for its runtime avatar crates."); } else { state = job.State; bool flag = state - 6 <= 1; if (flag && _installedFocus.ModId == job.Mod.Id) { _installedFocus.Clear(); } } RefreshEntries(); AvatarEntry? obj = Selected(); if (((obj != null) ? new long?(obj.ModId) : ((long?)null)) == job.Mod.Id) { state = job.State; _viewState = (AvatarBrowserViewState)((state - 5) switch { 1 => 10, 0 => 9, 2 => 7, _ => 8, }); RefreshVisiblePage(); } } public void OnRuntimeStatusChanged(string status) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) GameObject? browser = _browser; if (browser != null && browser.activeSelf && !string.IsNullOrWhiteSpace(status)) { bool flag = status.Contains("failed", StringComparison.OrdinalIgnoreCase) || status.Contains("could not", StringComparison.OrdinalIgnoreCase) || status.Contains("rejected", StringComparison.OrdinalIgnoreCase); SetStatus(status, flag ? Red : (status.Contains("sharing", StringComparison.OrdinalIgnoreCase) ? Cyan : Green)); } } public void OnAvatarsChanged(long modId, IReadOnlyList avatars) { //IL_0062: 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) _previewMetrics.Clear(); _previewRoutes.Clear(); _rigValidations.Clear(); if (avatars.Any((BoneHubAvatar avatar) => string.Equals(avatar.Barcode, _loadedPreviewBarcode, StringComparison.OrdinalIgnoreCase))) { _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _previewReady = false; _previewInteractionReady = false; _previewVisualSource = (AvatarPreviewVisualSource)0; } _fingertips.Invalidate(); _projectionAnchors.Invalidate(); _hologramProjection?.BeginTrackingGrace(); RefreshEntries(); if (_installedFocus.TryBind(modId, avatars.Select((BoneHubAvatar avatar) => avatar.Barcode))) { _selectedPackId = modId; _query = string.Empty; _onlineEntries = Array.Empty(); _downloadsOnly = false; IReadOnlyList avatars2 = _runtime.GetAvatars(modId); _entries = ((avatars2.Count > 0) ? avatars2 : avatars).Select((BoneHubAvatar avatar) => avatar.ToEntry()).OrderBy((AvatarEntry entry) => entry.AvatarName, StringComparer.OrdinalIgnoreCase).ToArray(); _selectedIdentity = _entries.First((AvatarEntry entry) => string.Equals(entry.Barcode, _installedFocus.SelectedBarcode, StringComparison.OrdinalIgnoreCase)).Identity; _cursor.Keep(_entries.Count, IndexOf(_selectedIdentity)); ShowDetailPage(); SetStatus("Downloaded - ready to equip", Green); _log.Msg($"Downloaded avatar pack bound to {avatars.Count} runtime crate{((avatars.Count == 1) ? string.Empty : "s")}; Equip is ready."); return; } if (avatars.Count > 0) { AvatarEntry? obj = Selected(); if (obj != null && obj.ModId == modId) { AvatarEntry? obj2 = Selected(); if (string.IsNullOrWhiteSpace((obj2 != null) ? obj2.Barcode : null)) { _selectedIdentity = avatars[0].ToEntry().Identity; RefreshEntries(); } } } RefreshVisiblePage(); } public void OnSceneChanged() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) _fingertips.Invalidate(); _projectionAnchors.Invalidate(); _hologramProjection?.BeginTrackingGrace(); ResetTouchButtons(); if ((Object)(object)_root == (Object)null) { return; } bool reportRecovery = PreviewShellRecovery.RequiresRebuild((Object)(object)_previewShell != (Object)null, (Object)(object)_previewFallback != (Object)null); if (EnsurePreviewShell(reportRecovery)) { ClearPreviewModel(); _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _previewReady = false; _previewInteractionReady = false; _previewVisualSource = (AvatarPreviewVisualSource)0; GameObject? browser = _browser; if (browser != null && browser.activeSelf) { RefreshFocusedResult(); } } } public void Tick() { _hologramProjection?.Tick(_preferences.ReducedMotion); if (IsLocalPlayerDead()) { if (!_wasPlayerDead && IsLauncherOpen) { _log.Msg("WristHub closed because the local player died."); Close(); } _wasPlayerDead = true; return; } _wasPlayerDead = false; if (IsLauncherOpen && !((Object)(object)Player.Head == (Object)null)) { RunGuarded("projection", _projectionTickAction, _projectionRecoveryAction); RunGuarded("touch", _touchTickAction, _touchRecoveryAction); RunGuarded("installation-focus", _installationFocusTickAction); RunGuarded("preview", _previewTickAction, _previewRecoveryAction); RunGuarded("download", _downloadTickAction); RunGuarded("sharing", _sharingTickAction, CancelPendingSharingRegistration); } } private void TickProjectionStage() { FollowWrist(); UpdateHologramProjection(); } private void RecoverProjectionStage() { _projectionAnchors.Invalidate(); _hologramProjection?.BeginTrackingGrace(); } private void TickTouchStage() { UpdatePushPromptVisibility(); PollButtons(); } private void RecoverPreviewStage() { EndPreviewDrag(equipIfAtChest: false); } public void LateTick() { if (!IsLauncherOpen || (Object)(object)Player.Head == (Object)null) { return; } try { UpdatePreview(); } catch (Exception ex) { string text = "late-drag|" + ex.GetType().FullName; if (_runtimeErrorThrottle.ShouldLog(text, (double)Environment.TickCount64 / 1000.0, 5.0)) { _log.Error($"WristHub preview drag recovered: {ex}"); } EndPreviewDrag(equipIfAtChest: false); } } private void RunGuarded(string subsystem, Action action, Action? recover = null) { try { action(); } catch (Exception ex) { string text = ex.StackTrace?.Split('\n').FirstOrDefault()?.Trim() ?? "no-stack"; string text2 = subsystem + "|" + ex.GetType().FullName + "|" + text; if (_runtimeErrorThrottle.ShouldLog(text2, (double)Environment.TickCount64 / 1000.0, 5.0)) { _log.Error($"WristHub {subsystem} update recovered (repeats suppressed): {ex}"); } try { recover?.Invoke(); } catch { } } } public void Dispose() { if (!_disposed) { _disposed = true; _searchGeneration++; ResetUiReferences(destroyOwnedObjects: true); } } private void EnsureBuilt() { if (!((Object)(object)_root != (Object)null)) { ResetUiReferences(destroyOwnedObjects: true); BuildTablet(); } } private void ResetUiReferences(bool destroyOwnedObjects) { foreach (PackRow packRow in _packRows) { packRow.Generation++; } ResetTouchButtons(); _buttons.Clear(); _packRows.Clear(); _touchCaptures.Clear(); _activeProbeIds.Clear(); _staleCaptureIds.Clear(); _artworkGeneration.Next(); _previewGeneration++; if (destroyOwnedObjects) { try { if ((Object)(object)_previewModel != (Object)null) { Object.Destroy((Object)(object)_previewModel); } } catch { } foreach (Mesh ownedPreviewMesh in _ownedPreviewMeshes) { try { if ((Object)(object)ownedPreviewMesh != (Object)null) { Object.Destroy((Object)(object)ownedPreviewMesh); } } catch { } } try { if ((Object)(object)_previewShell != (Object)null) { Object.Destroy((Object)(object)_previewShell); } } catch { } try { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } catch { } try { if ((Object)(object)_placeholderTexture != (Object)null) { Object.Destroy((Object)(object)_placeholderTexture); } } catch { } try { if ((Object)(object)_roundedSprite != (Object)null) { Object.Destroy((Object)(object)_roundedSprite); } } catch { } try { if ((Object)(object)_roundedTexture != (Object)null) { Object.Destroy((Object)(object)_roundedTexture); } } catch { } try { _hologramProjection?.Dispose(); } catch { } } _ownedPreviewMeshes.Clear(); _hologramProjection = null; _root = null; _launcher = null; _hub = null; _browser = null; _canvasRoot = null; _packPage = null; _detailPage = null; _optionsPage = null; _keyboardPage = null; _deletePage = null; _canvasGroup = null; _packTitle = null; _packStatus = null; _packPosition = null; _packSearchText = null; _sortText = null; _wristText = null; _scaleText = null; _motionText = null; _startingViewText = null; _scopeText = null; _deleteTitle = null; _deleteDetails = null; _keyboardText = null; _keyboardShiftText = null; _searchText = null; _positionText = null; _selectedName = null; _creatorText = null; _modText = null; _statusText = null; _heightText = null; _heightRuler = null; _progressRoot = null; _progressFill = null; _progressText = null; _actionLabel = null; _actionPanel = null; _trashButton = null; _centralArtwork = null; _placeholderTexture = null; _roundedTexture = null; _roundedSprite = null; _actionButton = null; _previewShell = null; _previewFallback = null; _previewModel = null; _previewAvatar = null; _pendingPreviewAvatar = null; _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _previewReady = false; _previewInteractionReady = false; _previewHeld = false; _dragHand = null; _previewReturning = false; CancelPendingSharingRegistration(); } private void BuildTablet() { //IL_0034: 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_0063: 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_0092: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00e9: 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_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_0164: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: 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_0444: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Expected O, but got Unknown //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_0542: Unknown result type (might be due to invalid IL or missing references) //IL_0556: Unknown result type (might be due to invalid IL or missing references) //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Expected O, but got Unknown //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_064f: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06af: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_071b: Unknown result type (might be due to invalid IL or missing references) //IL_0720: Unknown result type (might be due to invalid IL or missing references) //IL_0767: Unknown result type (might be due to invalid IL or missing references) //IL_077b: Unknown result type (might be due to invalid IL or missing references) //IL_0780: Unknown result type (might be due to invalid IL or missing references) //IL_07c7: Unknown result type (might be due to invalid IL or missing references) //IL_07db: Unknown result type (might be due to invalid IL or missing references) //IL_07e0: Unknown result type (might be due to invalid IL or missing references) //IL_083f: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_0858: Unknown result type (might be due to invalid IL or missing references) //IL_0899: Unknown result type (might be due to invalid IL or missing references) //IL_08a3: Unknown result type (might be due to invalid IL or missing references) //IL_08e3: Unknown result type (might be due to invalid IL or missing references) //IL_08f7: Unknown result type (might be due to invalid IL or missing references) //IL_08fc: Unknown result type (might be due to invalid IL or missing references) //IL_093d: Unknown result type (might be due to invalid IL or missing references) //IL_095b: Unknown result type (might be due to invalid IL or missing references) //IL_0976: Unknown result type (might be due to invalid IL or missing references) //IL_0980: Expected O, but got Unknown //IL_09c1: Unknown result type (might be due to invalid IL or missing references) //IL_09da: Unknown result type (might be due to invalid IL or missing references) //IL_0a10: Unknown result type (might be due to invalid IL or missing references) //IL_0a24: Unknown result type (might be due to invalid IL or missing references) //IL_0a29: Unknown result type (might be due to invalid IL or missing references) //IL_0a70: Unknown result type (might be due to invalid IL or missing references) //IL_0a84: Unknown result type (might be due to invalid IL or missing references) //IL_0a89: Unknown result type (might be due to invalid IL or missing references) //IL_0ade: Unknown result type (might be due to invalid IL or missing references) //IL_0af2: Unknown result type (might be due to invalid IL or missing references) //IL_0af7: Unknown result type (might be due to invalid IL or missing references) //IL_0b3e: Unknown result type (might be due to invalid IL or missing references) //IL_0b52: Unknown result type (might be due to invalid IL or missing references) //IL_0b57: Unknown result type (might be due to invalid IL or missing references) //IL_0b9d: Unknown result type (might be due to invalid IL or missing references) //IL_0ba2: Unknown result type (might be due to invalid IL or missing references) //IL_0ba7: Unknown result type (might be due to invalid IL or missing references) //IL_0bac: Unknown result type (might be due to invalid IL or missing references) //IL_0bb1: Unknown result type (might be due to invalid IL or missing references) //IL_0be9: Unknown result type (might be due to invalid IL or missing references) //IL_0bee: Unknown result type (might be due to invalid IL or missing references) //IL_0bf3: Unknown result type (might be due to invalid IL or missing references) //IL_0bf8: Unknown result type (might be due to invalid IL or missing references) //IL_0bfd: Unknown result type (might be due to invalid IL or missing references) //IL_0c35: Unknown result type (might be due to invalid IL or missing references) //IL_0c3a: Unknown result type (might be due to invalid IL or missing references) //IL_0c3f: Unknown result type (might be due to invalid IL or missing references) //IL_0c44: Unknown result type (might be due to invalid IL or missing references) //IL_0c49: Unknown result type (might be due to invalid IL or missing references) //IL_0c76: Unknown result type (might be due to invalid IL or missing references) //IL_0c8f: Unknown result type (might be due to invalid IL or missing references) //IL_0cbf: Unknown result type (might be due to invalid IL or missing references) //IL_0cca: Unknown result type (might be due to invalid IL or missing references) //IL_0cf6: Unknown result type (might be due to invalid IL or missing references) //IL_0d0f: Unknown result type (might be due to invalid IL or missing references) //IL_0d3f: Unknown result type (might be due to invalid IL or missing references) //IL_0d49: Unknown result type (might be due to invalid IL or missing references) //IL_0d83: Unknown result type (might be due to invalid IL or missing references) //IL_0d8d: Unknown result type (might be due to invalid IL or missing references) //IL_0dc7: Unknown result type (might be due to invalid IL or missing references) //IL_0de5: Unknown result type (might be due to invalid IL or missing references) //IL_0e1f: Unknown result type (might be due to invalid IL or missing references) //IL_0e29: Unknown result type (might be due to invalid IL or missing references) //IL_0e69: Unknown result type (might be due to invalid IL or missing references) //IL_0e73: Unknown result type (might be due to invalid IL or missing references) //IL_0ea5: Unknown result type (might be due to invalid IL or missing references) //IL_0eaa: Unknown result type (might be due to invalid IL or missing references) //IL_0eaf: Unknown result type (might be due to invalid IL or missing references) //IL_0eb4: Unknown result type (might be due to invalid IL or missing references) //IL_0eb9: Unknown result type (might be due to invalid IL or missing references) //IL_0f18: Unknown result type (might be due to invalid IL or missing references) //IL_0f1d: Unknown result type (might be due to invalid IL or missing references) //IL_0f22: Unknown result type (might be due to invalid IL or missing references) //IL_0f27: Unknown result type (might be due to invalid IL or missing references) //IL_0f2c: Unknown result type (might be due to invalid IL or missing references) _roundedTexture = CreateRoundedTexture(); _roundedSprite = Sprite.Create(_roundedTexture, new Rect(0f, 0f, (float)((Texture)_roundedTexture).width, (float)((Texture)_roundedTexture).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(16f, 16f, 16f, 16f)); ((Object)_roundedSprite).name = "WristHub Rounded UI Sprite"; _root = new GameObject("[WristHub] Wrist Avatar Browser"); Object.DontDestroyOnLoad((Object)(object)_root); BuildHologramProjection(); _launcher = new GameObject("Push Prompt"); _launcher.transform.SetParent(_root.transform, false); _launcher.transform.localPosition = new Vector3(0f, -0.085f, 0f); CreatePanel(_launcher.transform, "Push Prompt Glass", Vector3.zero, new Vector3(0.15f, 0.07f, 0.006f), Glass, (PrimitiveType)3); GameObject val = CreateCanvas(_launcher.transform, "Push Prompt UI", 150f, 70f, 0.007f); CreateButton(_launcher.transform, val.transform, "PUSH ME", Vector3.forward * 0.007f, new Vector3(0.13f, 0.05f, 0.014f), Cyan, ShowHub, 24f); _hub = new GameObject("WristHub Module Hub"); _hub.transform.SetParent(_root.transform, false); CreatePanel(_hub.transform, "Hub Glass", Vector3.zero, new Vector3(0.25f, 0.164f, 0.008f), Glass, (PrimitiveType)3); GameObject val2 = CreateCanvas(_hub.transform, "Hub UI", 250f, 164f, 0.009f); CreateText(val2.transform, "WRISTHUB", new TabletRect(-62f, 64f, 100f, 22f), 19f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1); CreateButton(_hub.transform, val2.transform, "X", new Vector3(0.108f, 0.064f, 0.008f), new Vector3(0.026f, 0.026f, 0.014f), Red, Close, 19f); CreateButton(_hub.transform, val2.transform, "AVATARS", new Vector3(0f, 0.027f, 0.008f), new Vector3(0.214f, 0.038f, 0.014f), Cyan, Open, 19f); CreateButton(_hub.transform, val2.transform, "SEARCH AVATARS", new Vector3(0f, -0.02f, 0.008f), new Vector3(0.214f, 0.038f, 0.014f), DimCyan, OpenSearch, 18f); TouchButton touchButton = CreateButton(_hub.transform, val2.transform, "MORE COMING SOON", new Vector3(0f, -0.066f, 0.008f), new Vector3(0.214f, 0.032f, 0.014f), new Color(0.06f, 0.1f, 0.12f, 1f), delegate { }, 14f); ((Graphic)touchButton.Label).color = new Color(0.45f, 0.55f, 0.6f, 1f); _buttons.Remove(touchButton); _hub.SetActive(false); _placeholderTexture = CreatePlaceholderTexture(); _browser = new GameObject("Avatar Browser Tablet 34x21cm"); _browser.transform.SetParent(_root.transform, false); CreatePanel(_browser.transform, "Tablet Shadow", new Vector3(0.006f, -0.007f, -0.006f), new Vector3(0.35f, 0.22f, 0.009f), new Color(0f, 0f, 0f, 0.7f), (PrimitiveType)3); CreatePanel(_browser.transform, "Tablet Bezel", Vector3.zero, new Vector3(0.34f, 0.21f, 0.01f), Glass, (PrimitiveType)3); _canvasRoot = CreateCanvas(_browser.transform, "WristHub Tablet Canvas", 340f, 210f, 0.006f); _canvasGroup = _canvasRoot.AddComponent(); ((Graphic)CreateRawImage(_canvasRoot.transform, "WristHub Background", AvatarTabletLayout.Tablet, BoneHubTheme.Background ?? _placeholderTexture, Color.white)).raycastTarget = false; ((Graphic)CreateImage(_canvasRoot.transform, "Calm Dark Overlay", AvatarTabletLayout.Tablet, new Color(0.005f, 0.024f, 0.038f, 0.72f))).raycastTarget = false; _packPage = new GameObject("Mod Pack Library Page"); _packPage.transform.SetParent(_canvasRoot.transform, false); _packTitle = CreateText(_packPage.transform, "GROUPS", new TabletRect(92f, 83f, 64f, 25f), 15f, Color.white, (TextAlignmentOptions)514, (FontStyles)1); CreateButton(_browser.transform, _packPage.transform, "BACK", new Vector3(-0.145f, 0.083f, 0.007f), new Vector3(0.042f, 0.028f, 0.014f), DimCyan, BackFromPackPage, 9f); TouchButton touchButton2 = CreateButton(_browser.transform, _packPage.transform, "SEARCH", new Vector3(-0.09f, 0.083f, 0.007f), new Vector3(0.064f, 0.028f, 0.014f), DimCyan, OpenKeyboard, 11f); _packSearchText = touchButton2.Label; CreateButton(_browser.transform, _packPage.transform, "ALL", new Vector3(-0.034f, 0.083f, 0.007f), new Vector3(0.046f, 0.028f, 0.014f), Cyan, ShowAllAvatars, 12f); CreateButton(_browser.transform, _packPage.transform, "OPTIONS", new Vector3(0.025f, 0.083f, 0.007f), new Vector3(0.068f, 0.028f, 0.014f), DimCyan, ShowOptionsPage, 9f); CreateButton(_browser.transform, _packPage.transform, "X", new Vector3(0.148f, 0.083f, 0.007f), new Vector3(0.026f, 0.028f, 0.014f), Red, Close, 19f); for (int num = 0; num < 4; num++) { CreatePackRow(num); } CreateButton(_browser.transform, _packPage.transform, "<", new Vector3(-0.135f, -0.091f, 0.007f), new Vector3(0.05f, 0.026f, 0.014f), DimCyan, delegate { MovePackPage(-1); }, 22f); _packPosition = CreateText(_packPage.transform, "1 / 1", new TabletRect(0f, -91f, 90f, 24f), 14f, Cyan, (TextAlignmentOptions)514, (FontStyles)1); CreateButton(_browser.transform, _packPage.transform, ">", new Vector3(0.135f, -0.091f, 0.007f), new Vector3(0.05f, 0.026f, 0.014f), DimCyan, delegate { MovePackPage(1); }, 22f); _packStatus = CreateText(_packPage.transform, string.Empty, new TabletRect(0f, -72f, 250f, 10f), 11f, new Color(0.7f, 0.82f, 0.88f, 1f), (TextAlignmentOptions)514, (FontStyles)0); _detailPage = new GameObject("Focused Avatar Page"); _detailPage.transform.SetParent(_canvasRoot.transform, false); CreateImage(_detailPage.transform, "Header", new TabletRect(0f, 82f, 324f, 34f), new Color(0.02f, 0.09f, 0.13f, 0.96f)); CreateButton(_browser.transform, _detailPage.transform, "BACK", new Vector3(-0.145f, 0.083f, 0.007f), new Vector3(0.042f, 0.028f, 0.014f), DimCyan, BackFromDetailPage, 9f); TouchButton touchButton3 = CreateButton(_browser.transform, _detailPage.transform, "SEARCH", new Vector3(-0.09f, 0.083f, 0.007f), new Vector3(0.064f, 0.028f, 0.014f), DimCyan, OpenKeyboard, 11f); _searchText = touchButton3.Label; CreateButton(_browser.transform, _detailPage.transform, "OPTIONS", new Vector3(-0.027f, 0.083f, 0.007f), new Vector3(0.058f, 0.028f, 0.014f), DimCyan, ShowOptionsPage, 8f); TouchButton touchButton4 = CreateButton(_browser.transform, _detailPage.transform, "ALL", new Vector3(0.048f, 0.083f, 0.007f), new Vector3(0.088f, 0.028f, 0.014f), Cyan, ToggleScopeOrDownloads, 10f); _scopeText = touchButton4.Label; CreateButton(_browser.transform, _detailPage.transform, "X", PixelCenter(AvatarTabletLayout.Close), PixelSize(AvatarTabletLayout.Close), Red, Close, 21f); CreateButton(_browser.transform, _detailPage.transform, "<", PixelCenter(AvatarTabletLayout.Previous), PixelSize(AvatarTabletLayout.Previous), DimCyan, delegate { MoveFocused(-1); }, 30f); CreateButton(_browser.transform, _detailPage.transform, ">", PixelCenter(AvatarTabletLayout.Next), PixelSize(AvatarTabletLayout.Next), DimCyan, delegate { MoveFocused(1); }, 30f); CreateImage(_detailPage.transform, "Preview Well", AvatarTabletLayout.Artwork, new Color(0.018f, 0.07f, 0.095f, 0.94f)); _centralArtwork = CreateRawImage(_detailPage.transform, "Selected Artwork", new TabletRect(-66f, -4f, 116f, 120f), _placeholderTexture, Color.white); ((Graphic)_centralArtwork).raycastTarget = false; CreateImage(_detailPage.transform, "Details Surface", AvatarTabletLayout.Details, new Color(0.02f, 0.065f, 0.09f, 0.94f)); _selectedName = CreateText(_detailPage.transform, "Select an avatar", new TabletRect(65f, 45f, 112f, 32f), 18f, Color.white, (TextAlignmentOptions)257, (FontStyles)1); _creatorText = CreateText(_detailPage.transform, string.Empty, new TabletRect(65f, 22f, 112f, 16f), 12f, Cyan, (TextAlignmentOptions)4097, (FontStyles)0); _modText = CreateText(_detailPage.transform, string.Empty, new TabletRect(65f, 3f, 112f, 20f), 11f, new Color(0.72f, 0.82f, 0.88f, 1f), (TextAlignmentOptions)257, (FontStyles)0); _positionText = CreateText(_detailPage.transform, "0 / 0", new TabletRect(65f, -18f, 112f, 16f), 12f, Cyan, (TextAlignmentOptions)4097, (FontStyles)1); CreateTabletHeightRuler(); _statusText = CreateText(_detailPage.transform, "Ready", new TabletRect(65f, -42f, 112f, 26f), 12f, Cyan, (TextAlignmentOptions)257, (FontStyles)1); _actionButton = CreateButton(_browser.transform, _detailPage.transform, "EQUIP", PixelCenter(AvatarTabletLayout.Action), PixelSize(AvatarTabletLayout.Action), Cyan, ActivateSelected, 18f); _actionLabel = _actionButton.Label; _actionPanel = _actionButton.Panel; _trashButton = CreateButton(_browser.transform, _detailPage.transform, "DELETE PACK", PixelCenter(AvatarTabletLayout.Trash), PixelSize(AvatarTabletLayout.Trash), Red, ShowDeleteConfirmation, 8f); ((Object)_trashButton.Root).name = "Trash Avatar Pack"; CreateTabletProgressBar(); BuildOptionsPage(); BuildKeyboardPage(); BuildDeletePage(); _packPage.SetActive(true); _detailPage.SetActive(false); GameObject? optionsPage = _optionsPage; if (optionsPage != null) { optionsPage.SetActive(false); } GameObject? keyboardPage = _keyboardPage; if (keyboardPage != null) { keyboardPage.SetActive(false); } GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } _browser.SetActive(false); CreatePreviewShell(); _root.SetActive(false); } private void BuildHologramProjection() { if (_hologramProjection == null) { _hologramProjection = new BoneHubForearmProjection(_log); } } private void StartHologramProjection() { if (!_preferences.HologramEffects) { if ((Object)(object)_canvasGroup != (Object)null) { _canvasGroup.alpha = 1f; } _hologramProjection?.Hide(immediate: true); } else { if ((Object)(object)_canvasGroup != (Object)null) { _canvasGroup.alpha = (_preferences.ReducedMotion ? 1f : 0.35f); } _hologramProjection?.Show(); } } private void UpdateHologramProjection() { //IL_0082: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) if (_hologramProjection == null) { return; } GameObject? browser = _browser; object obj; if (browser == null || !browser.activeSelf) { GameObject? hub = _hub; obj = ((hub != null && hub.activeSelf) ? _hub.transform : null); } else { obj = _browser.transform; } Transform val = (Transform)obj; if (!_preferences.HologramEffects) { if ((Object)(object)_canvasGroup != (Object)null) { _canvasGroup.alpha = 1f; } if ((Object)(object)val != (Object)null) { val.localPosition = Vector3.zero; val.localScale = Vector3.one; } _hologramProjection.Hide(immediate: true); return; } if ((Object)(object)val == (Object)null) { _hologramProjection.Hide(); return; } float heightRatio = AvatarUiScaleMath.ResolveMenuScale(CurrentPlayerHeight()); if (!_projectionAnchors.TryGet(_preferences.UseLeftWrist, heightRatio, out var anchor)) { _hologramProjection.BeginTrackingGrace(); _hologramProjection.UpdateTrackingLost(); return; } _hologramProjection.UpdatePose(anchor, val, _preferences.ReducedMotion, _preferences.HologramBrightness); float num = (_preferences.ReducedMotion ? 1f : _hologramProjection.RevealProgress); if ((Object)(object)_canvasGroup != (Object)null) { _canvasGroup.alpha = Mathf.Lerp(0.35f, 1f, num); } val.localPosition = new Vector3(0f, -0.004f * (1f - num), 0f); val.localScale = Vector3.one * Mathf.Lerp(0.985f, 1f, num); } private void BuildDeletePage() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_006e: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_015c: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: 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) if (!((Object)(object)_browser == (Object)null) && !((Object)(object)_canvasRoot == (Object)null)) { _deletePage = new GameObject("Delete Pack Confirmation Page"); _deletePage.transform.SetParent(_canvasRoot.transform, false); CreateImage(_deletePage.transform, "Delete Header", new TabletRect(0f, 76f, 310f, 38f), new Color(0.3f, 0.035f, 0.055f, 0.98f)); _deleteTitle = CreateText(_deletePage.transform, "DELETE AVATAR PACK?", new TabletRect(0f, 76f, 280f, 28f), 20f, Color.white, (TextAlignmentOptions)514, (FontStyles)1); _deleteDetails = CreateText(_deletePage.transform, string.Empty, new TabletRect(0f, 15f, 280f, 72f), 15f, Color.white, (TextAlignmentOptions)514, (FontStyles)0); CreateText(_deletePage.transform, "Locked packs finish safely on the next BONELAB launch. Undo stays available.", new TabletRect(0f, -37f, 280f, 34f), 11f, new Color(0.75f, 0.82f, 0.86f, 1f), (TextAlignmentOptions)514, (FontStyles)0); CreateButton(_browser.transform, _deletePage.transform, "CANCEL", new Vector3(-0.082f, -0.077f, 0.007f), new Vector3(0.13f, 0.038f, 0.014f), DimCyan, CancelDelete, 16f); CreateButton(_browser.transform, _deletePage.transform, "DELETE PACK", new Vector3(0.082f, -0.077f, 0.007f), new Vector3(0.13f, 0.038f, 0.014f), Red, TrashSelected, 16f); _deletePage.SetActive(false); } } private void ShowHub() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_launcher != (Object)null) { _launcher.SetActive(false); } if ((Object)(object)_hub != (Object)null) { _hub.SetActive(true); } if ((Object)(object)_browser != (Object)null) { _browser.SetActive(false); } _viewState = (AvatarBrowserViewState)1; StartHologramProjection(); ResetTouchButtons(); RequireInputRearm(); _log.Msg("WristHub wrist module hub opened."); } private void CreatePackRow(int index) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_0146: 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_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: 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_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_browser == (Object)null) && !((Object)(object)_packPage == (Object)null) && !((Object)(object)_placeholderTexture == (Object)null)) { float num = 50f - (float)index * 34f; TouchButton touchButton = CreateButton(_browser.transform, _packPage.transform, string.Empty, new Vector3(-0.036f, num / 1000f, 0.007f), new Vector3(0.228f, 0.03f, 0.014f), Surface, delegate { OpenPackRow(index); }, 1f); RawImage artwork = CreateRawImage(touchButton.Root.transform, $"Pack {index + 1} Artwork", new TabletRect(-96f, 0f, 26f, 24f), _placeholderTexture, Color.white); TMP_Text name = CreateText(touchButton.Root.transform, string.Empty, new TabletRect(-28f, 5f, 104f, 13f), 12f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1); TMP_Text creator = CreateText(touchButton.Root.transform, string.Empty, new TabletRect(-24f, -7f, 112f, 10f), 9f, new Color(0.65f, 0.8f, 0.86f, 1f), (TextAlignmentOptions)4097, (FontStyles)0); TMP_Text state = CreateText(touchButton.Root.transform, string.Empty, new TabletRect(78f, 0f, 54f, 18f), 9f, Cyan, (TextAlignmentOptions)4100, (FontStyles)1); TouchButton deleteButton = CreateButton(_browser.transform, _packPage.transform, "DELETE", new Vector3(0.125f, num / 1000f, 0.007f), new Vector3(0.052f, 0.03f, 0.014f), Red, delegate { ShowDeleteConfirmationForPack(index); }, 8f); _packRows.Add(new PackRow { Button = touchButton, DeleteButton = deleteButton, Artwork = artwork, Name = name, Creator = creator, State = state }); } } private void BuildOptionsPage() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_006d: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0177: 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_01cb: 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_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_025b: 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_0274: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0313: 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_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_0403: 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_041c: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_browser == (Object)null) && !((Object)(object)_canvasRoot == (Object)null)) { _optionsPage = new GameObject("WristHub Options Page"); _optionsPage.transform.SetParent(_canvasRoot.transform, false); CreateText(_optionsPage.transform, "SETTINGS", new TabletRect(-92f, 82f, 112f, 28f), 18f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1); CreateButton(_browser.transform, _optionsPage.transform, "BACK", new Vector3(0.108f, 0.082f, 0.007f), new Vector3(0.064f, 0.028f, 0.014f), DimCyan, ShowScopePage, 12f); CreateButton(_browser.transform, _optionsPage.transform, "X", new Vector3(0.151f, 0.082f, 0.007f), new Vector3(0.026f, 0.028f, 0.014f), Red, Close, 19f); _startingViewText = CreateText(_optionsPage.transform, string.Empty, new TabletRect(-58f, 49f, 194f, 20f), 13f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1); CreateButton(_browser.transform, _optionsPage.transform, "CHANGE", new Vector3(0.112f, 0.049f, 0.007f), new Vector3(0.072f, 0.026f, 0.014f), Cyan, CycleStartingView, 10f); _sortText = CreateText(_optionsPage.transform, string.Empty, new TabletRect(-58f, 19f, 194f, 20f), 13f, Color.white, (TextAlignmentOptions)4097, (FontStyles)0); CreateButton(_browser.transform, _optionsPage.transform, "CHANGE", new Vector3(0.112f, 0.019f, 0.007f), new Vector3(0.072f, 0.026f, 0.014f), DimCyan, CyclePackSort, 10f); _wristText = CreateText(_optionsPage.transform, string.Empty, new TabletRect(-58f, -11f, 194f, 20f), 13f, Color.white, (TextAlignmentOptions)4097, (FontStyles)0); CreateButton(_browser.transform, _optionsPage.transform, "SWITCH", new Vector3(0.112f, -0.011f, 0.007f), new Vector3(0.072f, 0.026f, 0.014f), DimCyan, ToggleWrist, 10f); _scaleText = CreateText(_optionsPage.transform, string.Empty, new TabletRect(-58f, -41f, 194f, 20f), 13f, Color.white, (TextAlignmentOptions)4097, (FontStyles)0); CreateButton(_browser.transform, _optionsPage.transform, "-", new Vector3(0.086f, -0.041f, 0.007f), new Vector3(0.036f, 0.026f, 0.014f), DimCyan, delegate { ChangeScale(-0.1f); }, 18f); CreateButton(_browser.transform, _optionsPage.transform, "+", new Vector3(0.138f, -0.041f, 0.007f), new Vector3(0.036f, 0.026f, 0.014f), DimCyan, delegate { ChangeScale(0.1f); }, 18f); _motionText = CreateText(_optionsPage.transform, string.Empty, new TabletRect(-58f, -71f, 194f, 20f), 13f, Color.white, (TextAlignmentOptions)4097, (FontStyles)0); CreateButton(_browser.transform, _optionsPage.transform, "TOGGLE", new Vector3(0.112f, -0.071f, 0.007f), new Vector3(0.072f, 0.026f, 0.014f), DimCyan, ToggleMotion, 10f); RefreshOptionLabels(); } } private void BuildKeyboardPage() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_006d: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_0112: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_025d: 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_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_browser == (Object)null) && !((Object)(object)_canvasRoot == (Object)null)) { _keyboardPage = new GameObject("WristHub Tablet Keyboard"); _keyboardPage.transform.SetParent(_canvasRoot.transform, false); CreateText(_keyboardPage.transform, "SEARCH AVATARS", new TabletRect(-70f, 84f, 180f, 24f), 17f, Color.white, (TextAlignmentOptions)4097, (FontStyles)1); CreateButton(_browser.transform, _keyboardPage.transform, "X", new Vector3(0.151f, 0.084f, 0.007f), new Vector3(0.026f, 0.026f, 0.014f), Red, CancelKeyboard, 19f); CreateImage(_keyboardPage.transform, "Search Input", new TabletRect(-35f, 55f, 236f, 30f), Surface); _keyboardText = CreateText(_keyboardPage.transform, "Type an avatar name", new TabletRect(-35f, 55f, 218f, 24f), 15f, Color.white, (TextAlignmentOptions)4097, (FontStyles)0); CreateButton(_browser.transform, _keyboardPage.transform, "SEARCH", new Vector3(0.125f, 0.055f, 0.007f), new Vector3(0.064f, 0.03f, 0.014f), Cyan, SubmitKeyboard, 10f); CreateKeyboardRow("QWERTYUIOP", -135f, 24f, 27f, 3f); CreateKeyboardRow("ASDFGHJKL", -120f, -6f, 27f, 3f); CreateKeyboardRow("ZXCVBNM", -105f, -36f, 27f, 3f); TouchButton touchButton = CreateButton(_browser.transform, _keyboardPage.transform, "SHIFT", new Vector3(-0.139f, -0.074f, 0.007f), new Vector3(0.052f, 0.026f, 0.014f), DimCyan, ToggleKeyboardShift, 10f); _keyboardShiftText = touchButton.Label; CreateButton(_browser.transform, _keyboardPage.transform, "SPACE", new Vector3(-0.073f, -0.074f, 0.007f), new Vector3(0.072f, 0.026f, 0.014f), DimCyan, AppendKeyboardSpace, 10f); CreateButton(_browser.transform, _keyboardPage.transform, "BACK", new Vector3(0f, -0.074f, 0.007f), new Vector3(0.062f, 0.026f, 0.014f), DimCyan, BackspaceKeyboard, 10f); CreateButton(_browser.transform, _keyboardPage.transform, "CLEAR", new Vector3(0.061f, -0.074f, 0.007f), new Vector3(0.05f, 0.026f, 0.014f), DimCyan, ClearKeyboard, 9f); _keyboardPage.SetActive(false); } } private void CreateKeyboardRow(string keys, float startX, float y, float width, float gap) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_browser == (Object)null || (Object)(object)_keyboardPage == (Object)null) { return; } for (int i = 0; i < keys.Length; i++) { char key = keys[i]; float num = startX + (float)i * (width + gap); CreateButton(_browser.transform, _keyboardPage.transform, key.ToString(), new Vector3(num / 1000f, y / 1000f, 0.007f), new Vector3(width / 1000f, 0.026f, 0.014f), DimCyan, delegate { AppendKeyboardCharacter(key); }, 12f); } } private void HandlePackSearch() { //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_0019: 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_001d: Invalid comparison between Unknown and I4 bool flag = _query.Length > 0; if (!flag) { AvatarBrowserViewState viewState = _viewState; bool flag2 = viewState - 6 <= 1; flag = flag2; } if (flag) { OpenKeyboard(); } else { OpenSearchPage(); } } private void OpenSearchPage() { OpenKeyboard(); } private void BackFromPackPage() { //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_0019: 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_001d: Invalid comparison between Unknown and I4 //IL_0055: Unknown result type (might be due to invalid IL or missing references) bool flag = _query.Length > 0; if (!flag) { AvatarBrowserViewState viewState = _viewState; bool flag2 = viewState - 6 <= 1; flag = flag2; } if (flag) { _query = string.Empty; _downloadsOnly = false; _onlineEntries = Array.Empty(); _selectedPackId = null; _viewState = (AvatarBrowserViewState)2; RefreshEntries(); ShowPackPage(); } else { ShowHub(); } } private void BackFromDetailPage() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 //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_0045: Unknown result type (might be due to invalid IL or missing references) if (_query.Length > 0) { _query = string.Empty; _downloadsOnly = false; _onlineEntries = Array.Empty(); _scope = _scopeBeforeSearch; _selectedPackId = null; _viewState = (AvatarBrowserViewState)2; RefreshEntries(); ShowScopePage(); } else if ((int)_scope == 1 && _selectedPackId.HasValue) { ShowPackPage(); } else { ShowHub(); } } private void ShowScopePage() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)_scope == 1) { ShowPackPage(); } else { ShowAllAvatars(); } } private void ShowAllAvatars() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) _scope = (AvatarBrowseScope)0; _selectedPackId = null; RememberScope(); RefreshEntries(); if (!_entries.Any((AvatarEntry entry) => entry.Identity == _selectedIdentity)) { AvatarEntry? obj = _entries.FirstOrDefault(); _selectedIdentity = ((obj != null) ? obj.Identity : null) ?? string.Empty; } _cursor.Keep(_entries.Count, IndexOf(_selectedIdentity)); ShowDetailPage(); } private void ShowGroups() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) _scope = (AvatarBrowseScope)1; _selectedPackId = null; RememberScope(); ShowPackPage(); } private void ToggleBrowseScope() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)_scope == 0) { ShowGroups(); } else { ShowAllAvatars(); } } private void ToggleScopeOrDownloads() { if (_query.Length == 0) { ToggleBrowseScope(); return; } _downloadsOnly = !_downloadsOnly; _selectedPackId = null; RefreshEntries(); AvatarEntry? obj = _entries.FirstOrDefault(); _selectedIdentity = ((obj != null) ? obj.Identity : null) ?? string.Empty; _cursor.Reset(_entries.Count); RefreshFocusedResult(); _log.Msg(_downloadsOnly ? $"Downloadable search section opened with {_entries.Count} results." : $"All search results reopened with {_entries.Count} results."); } private void RememberScope() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (_query.Length <= 0) { _preferences.LastAvatarBrowseScope = _scope; SavePreferences(); } } private void ShowPackPage() { if (!((Object)(object)_browser == (Object)null) && _browser.activeSelf && !_previewHeld) { GameObject? packPage = _packPage; if (packPage != null) { packPage.SetActive(true); } GameObject? detailPage = _detailPage; if (detailPage != null) { detailPage.SetActive(false); } GameObject? optionsPage = _optionsPage; if (optionsPage != null) { optionsPage.SetActive(false); } GameObject? keyboardPage = _keyboardPage; if (keyboardPage != null) { keyboardPage.SetActive(false); } GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } _previewGeneration++; _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; ClearPreviewModel(); if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } RefreshEntries(); RefreshPackRows(); RequireInputRearm(); } } private void ShowDetailPage() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Invalid comparison between Unknown and I4 //IL_0085: 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) if (!((Object)(object)_browser == (Object)null) && _browser.activeSelf) { GameObject? packPage = _packPage; if (packPage != null) { packPage.SetActive(false); } GameObject? detailPage = _detailPage; if (detailPage != null) { detailPage.SetActive(true); } GameObject? optionsPage = _optionsPage; if (optionsPage != null) { optionsPage.SetActive(false); } GameObject? keyboardPage = _keyboardPage; if (keyboardPage != null) { keyboardPage.SetActive(false); } GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } if (_query.Length == 0) { _viewState = (AvatarBrowserViewState)3; } else if ((int)_viewState != 6) { _viewState = (AvatarBrowserViewState)7; } RefreshFocusedResult(); RequireInputRearm(); } } private void ShowOptionsPage() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) GameObject? packPage = _packPage; if (packPage != null) { packPage.SetActive(false); } GameObject? detailPage = _detailPage; if (detailPage != null) { detailPage.SetActive(false); } GameObject? optionsPage = _optionsPage; if (optionsPage != null) { optionsPage.SetActive(true); } GameObject? keyboardPage = _keyboardPage; if (keyboardPage != null) { keyboardPage.SetActive(false); } GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } _previewGeneration++; _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; ClearPreviewModel(); if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } _viewState = (AvatarBrowserViewState)4; RefreshOptionLabels(); RequireInputRearm(); } private void RefreshVisiblePage() { if ((Object)(object)_detailPage != (Object)null && _detailPage.activeSelf) { RefreshFocusedResult(); } else if ((Object)(object)_packPage != (Object)null && _packPage.activeSelf) { RefreshPackRows(); } else if ((Object)(object)_optionsPage != (Object)null && _optionsPage.activeSelf) { RefreshOptionLabels(); } } private void RefreshPackRows() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0060: Invalid comparison between Unknown and I4 //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Invalid comparison between Unknown and I4 //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Invalid comparison between Unknown and I4 //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0402: 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) if ((Object)(object)_packPage == (Object)null || !_packPage.activeSelf || (Object)(object)_placeholderTexture == (Object)null) { return; } _packCursor.Keep(_packs.Count); bool flag = _query.Length > 0; if (!flag) { AvatarBrowserViewState viewState = _viewState; bool flag2 = viewState - 6 <= 1; flag = flag2; } bool flag3 = flag; if ((Object)(object)_packTitle != (Object)null) { _packTitle.text = ((_query.Length > 0) ? "RESULTS" : "GROUPS"); } if ((Object)(object)_packSearchText != (Object)null) { _packSearchText.text = "SEARCH"; } if ((Object)(object)_packPosition != (Object)null) { _packPosition.text = _packCursor.PositionText; } if ((Object)(object)_packStatus != (Object)null) { _packStatus.text = ((flag3 && _query.Length == 0) ? "Touch the search field, type, and submit to search automatically" : (((int)_viewState == 6 && _query.Length > 0) ? "Searching BONELAB mod.io..." : ((_packs.Count != 0) ? $"{_packs.Count} pack{((_packs.Count == 1) ? string.Empty : "s")} - touch a row to open" : ((_query.Length == 0) ? "No installed avatar packs found" : "No matching avatars found")))); } int num = _packCursor.Page * 4; int num2 = Math.Min(4, _packRows.Count); for (int i = 0; i < num2; i++) { PackRow row = _packRows[i]; if (!row.IsAlive) { continue; } row.Generation++; int num3 = num + i; if (num3 >= _packs.Count) { row.Identity = string.Empty; row.Button.Root.SetActive(false); row.DeleteButton.Root.SetActive(false); continue; } AvatarPackEntry pack = _packs[num3]; row.Identity = pack.Identity; row.Button.Root.SetActive(true); row.DeleteButton.Root.SetActive(pack.Installed && pack.AvatarCount > 0); row.Name.text = pack.Name; row.Creator.text = "By " + pack.Creator; row.State.text = (pack.Installed ? $"{pack.AvatarCount} AVATAR{((pack.AvatarCount == 1) ? string.Empty : "S")}" : CardStatus(pack.Avatars[0])); ((Graphic)row.State).color = (((int)pack.DownloadState == 5) ? Red : (pack.Installed ? Green : Cyan)); row.Artwork.texture = (Texture)(object)_placeholderTexture; int generation = row.Generation; if (string.IsNullOrWhiteSpace(pack.ThumbnailUrl)) { continue; } _thumbnails.Load(pack.ThumbnailUrl, delegate(Texture2D texture) { if (!_disposed && row.IsAlive && row.Generation == generation && row.Identity == pack.Identity && (Object)(object)texture != (Object)null) { row.Artwork.texture = (Texture)(object)texture; } }); } } private void OpenPackRow(int slot) { int num = _packCursor.Page * 4 + slot; if (num >= 0 && num < _packs.Count) { AvatarPackEntry val = _packs[num]; _selectedPackId = val.ModId; _entries = val.Avatars; AvatarEntry? obj = _entries.FirstOrDefault(); _selectedIdentity = ((obj != null) ? obj.Identity : null) ?? string.Empty; _cursor.Reset(_entries.Count); _log.Msg($"Avatar pack opened ({val.AvatarCount} installed avatars). Pack name is not logged."); ShowDetailPage(); } } private void ShowDeleteConfirmationForPack(int slot) { int num = _packCursor.Page * 4 + slot; if (num >= 0 && num < _packs.Count) { AvatarPackEntry val = _packs[num]; AvatarEntry val2 = ((IEnumerable)val.Avatars).FirstOrDefault((Func)((AvatarEntry entry) => entry.Installed && !string.IsNullOrWhiteSpace(entry.Barcode))); if (!(val2 == (AvatarEntry)null)) { _selectedPackId = val.ModId; _entries = val.Avatars; _selectedIdentity = val2.Identity; _cursor.Reset(_entries.Count); _deleteReturnToPackPage = true; ShowDeleteConfirmation(); } } } private void MovePackPage(int direction) { _packCursor.Move(direction); RefreshPackRows(); } private void SetPackSort(AvatarPackSort sort) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _packSort = sort; _selectedPackId = null; RefreshEntries(); ShowPackPage(); } private void CyclePackSort() { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_001b: 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_0019: Unknown result type (might be due to invalid IL or missing references) AvatarPackSort packSort = _packSort; AvatarPackSort packSort2 = (((int)packSort == 0) ? ((AvatarPackSort)1) : (((int)packSort != 1) ? ((AvatarPackSort)0) : ((AvatarPackSort)2))); SetPackSort(packSort2); ShowOptionsPage(); } private void CycleStartingView() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_001e: 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_0019: Invalid comparison between Unknown and I4 //IL_0028: 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_0026: Unknown result type (might be due to invalid IL or missing references) BoneHubPreferences preferences = _preferences; BrowserStartupMode avatarBrowserStartupMode = _preferences.AvatarBrowserStartupMode; BrowserStartupMode avatarBrowserStartupMode2 = (((int)avatarBrowserStartupMode == 1) ? ((BrowserStartupMode)2) : (((int)avatarBrowserStartupMode != 2) ? ((BrowserStartupMode)1) : ((BrowserStartupMode)0))); preferences.AvatarBrowserStartupMode = avatarBrowserStartupMode2; RefreshOptionLabels(); SavePreferences(); } private void ToggleWrist() { _preferences.UseLeftWrist = !_preferences.UseLeftWrist; _fingertips.Invalidate(); FollowWrist(immediate: true); RefreshOptionLabels(); SavePreferences(); } private void ChangeScale(float amount) { _preferences.WatchScale = Mathf.Clamp(_preferences.WatchScale + amount, 0.65f, 1.6f); FollowWrist(immediate: true); RefreshOptionLabels(); SavePreferences(); } private void ToggleMotion() { _preferences.ReducedMotion = !_preferences.ReducedMotion; RefreshOptionLabels(); SavePreferences(); } private void RefreshOptionLabels() { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0026: Invalid comparison between Unknown and I4 if ((Object)(object)_startingViewText != (Object)null) { TMP_Text startingViewText = _startingViewText; BrowserStartupMode avatarBrowserStartupMode = _preferences.AvatarBrowserStartupMode; string text = (((int)avatarBrowserStartupMode == 0) ? "Remember last" : (((int)avatarBrowserStartupMode != 2) ? "All avatars" : "Groups")); startingViewText.text = "Starting view: " + text; } if ((Object)(object)_sortText != (Object)null) { _sortText.text = "Library order: " + (((int)_packSort == 0) ? "Recent" : ((object)Unsafe.As(ref _packSort)/*cast due to .constrained prefix*/).ToString()); } if ((Object)(object)_wristText != (Object)null) { _wristText.text = "Wrist: " + (_preferences.UseLeftWrist ? "Left" : "Right"); } if ((Object)(object)_scaleText != (Object)null) { _scaleText.text = $"UI scale: {_preferences.WatchScale:0.0}x"; } if ((Object)(object)_motionText != (Object)null) { _motionText.text = "Reduced motion: " + (_preferences.ReducedMotion ? "On" : "Off"); } } private void SavePreferences() { SavePreferencesGuardedAsync(); } private async Task SavePreferencesGuardedAsync() { try { await _service.SavePreferencesAsync(default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); } catch (Exception ex) { Exception exception = ex; _mainThread.Enqueue(delegate { _log.Error("Could not save WristHub tablet options: " + exception.Message); }); } } private void CreateTabletHeightRuler() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_00f8: 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_00fe: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_detailPage == (Object)null)) { _heightRuler = new GameObject("Avatar Height Ruler"); _heightRuler.transform.SetParent(_detailPage.transform, false); CreateImage(_heightRuler.transform, "Ruler Line", new TabletRect(-10f, -2f, 2f, 108f), DimCyan); TabletRect bounds = default(TabletRect); for (int i = 0; i < 7; i++) { float num = -56f + (float)i * 18f; Transform transform = _heightRuler.transform; bool flag = ((i == 0 || i == 6) ? true : false); float num2 = (flag ? (-15f) : (-14f)); float num3 = num; bool flag2 = ((i == 0 || i == 6) ? true : false); ((TabletRect)(ref bounds))..ctor(num2, num3, flag2 ? 12f : 8f, 2f); bool flag3 = ((i == 0 || i == 6) ? true : false); CreateImage(transform, "Ruler Tick", bounds, flag3 ? Cyan : DimCyan); } _heightText = CreateText(_heightRuler.transform, "Height after download", new TabletRect(-66f, -72f, 116f, 16f), 10f, Cyan, (TextAlignmentOptions)514, (FontStyles)1); } } private void CreateTabletProgressBar() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //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_0052: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_011f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_detailPage == (Object)null)) { _progressRoot = new GameObject("Download Progress Capsule"); _progressRoot.transform.SetParent(_detailPage.transform, false); TabletRect progress = AvatarTabletLayout.Progress; CreateImage(_progressRoot.transform, "Progress Track", progress, new Color(0.025f, 0.105f, 0.145f, 0.98f)); Image val = CreateImage(_progressRoot.transform, "Progress Fill", new TabletRect(((TabletRect)(ref progress)).Left + 0.25f, ((TabletRect)(ref progress)).Y, 0.5f, ((TabletRect)(ref progress)).Height), new Color(Cyan.r, Cyan.g, Cyan.b, 0.82f)); _progressFill = ((Graphic)val).rectTransform; _progressText = CreateText(_progressRoot.transform, string.Empty, new TabletRect(((TabletRect)(ref progress)).X, ((TabletRect)(ref progress)).Y, ((TabletRect)(ref progress)).Width - 8f, ((TabletRect)(ref progress)).Height), 8.5f, Color.white, (TextAlignmentOptions)514, (FontStyles)1); _progressRoot.SetActive(false); } } private void RefreshEntries() { //IL_007e: 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) AvatarEntry[] array = (from avatar in _runtime.GetAllAvatars() select avatar.ToEntry()).ToArray(); IEnumerable enumerable = ((IEnumerable)_onlineEntries).Select((Func)delegate(AvatarEntry entry) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (_runtime.IsModInstalled(entry.ModId)) { AvatarEntry obj = entry.$(); obj.set_Installed(true); obj.set_DownloadState((AvatarDownloadState)4); return obj; } DownloadJob value; return (!_jobs.TryGetValue(entry.ModId, out value)) ? entry : entry.WithDownload(Map(value.State), value.Progress, value.Error); }); _mergedEntries = AvatarLibrary.Merge((IEnumerable)array, enumerable, _query, (IEnumerable)_service.RecentlyEquippedAvatarBarcodes); _packs = AvatarPackLibrary.Group((IEnumerable)_mergedEntries, (IEnumerable)_service.RecentlyEquippedAvatarBarcodes, _packSort); AvatarPackEntry val = (_selectedPackId.HasValue ? ((IEnumerable)_packs).FirstOrDefault((Func)((AvatarPackEntry pack) => pack.ModId == _selectedPackId.Value)) : null); AvatarEntry[] array2 = (_selectedPackId.HasValue ? (from avatar in _runtime.GetAvatars(_selectedPackId.Value) select avatar.ToEntry()).OrderBy((AvatarEntry entry) => entry.AvatarName, StringComparer.OrdinalIgnoreCase).ToArray() : Array.Empty()); if (val == (AvatarPackEntry)null && array2.Length != 0) { val = AvatarPackLibrary.Group((IEnumerable)array2, (IEnumerable)_service.RecentlyEquippedAvatarBarcodes, _packSort).FirstOrDefault(); } IReadOnlyList readOnlyList = (IReadOnlyList)((_query.Length > 0 && _downloadsOnly) ? ((IEnumerable)AvatarLibrary.Downloadable((IEnumerable)_mergedEntries)) : ((IEnumerable)_mergedEntries)); object entries; if (array2.Length == 0) { entries = ((val != null) ? val.Avatars : null) ?? readOnlyList; } else { IReadOnlyList readOnlyList2 = array2; entries = readOnlyList2; } _entries = (IReadOnlyList)entries; if (_entries.Count == 0) { _selectedIdentity = string.Empty; } else if (!_entries.Any((AvatarEntry entry) => entry.Identity == _selectedIdentity)) { _selectedIdentity = _entries[0].Identity; } _cursor.Keep(_entries.Count, IndexOf(_selectedIdentity)); if ((Object)(object)_searchText != (Object)null) { _searchText.text = "SEARCH"; } } private void RefreshFocusedResult() { //IL_005d: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Invalid comparison between Unknown and I4 //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Invalid comparison between Unknown and I4 //IL_0277: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_browser == (Object)null || !_browser.activeSelf) { return; } if ((Object)(object)_searchText != (Object)null) { _searchText.text = "SEARCH"; } if ((Object)(object)_scopeText != (Object)null) { _scopeText.text = ((_query.Length <= 0) ? (((int)_scope == 0) ? "ALL AVATARS" : "GROUPS") : (_downloadsOnly ? "ALL RESULTS" : "DOWNLOADS")); } if ((Object)(object)_positionText != (Object)null) { _positionText.text = _cursor.PositionText; } AvatarEntry val = Selected(); if (val != (AvatarEntry)null) { if (_actionButton != null) { _actionButton.Root.SetActive(true); } RefreshSelection(val); return; } _artworkGeneration.Next(); _previewGeneration++; _previewAvatar = null; _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _previewReady = false; _previewInteractionReady = false; _previewVisualSource = (AvatarPreviewVisualSource)0; ClearPreviewModel(); if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } if ((Object)(object)_centralArtwork != (Object)null) { ((Component)_centralArtwork).gameObject.SetActive(true); _centralArtwork.texture = (Texture)(object)_placeholderTexture; } if ((Object)(object)_selectedName != (Object)null) { _selectedName.text = (((int)_viewState == 6) ? "Searching..." : (_downloadsOnly ? "No downloads found" : "No avatars found")); } if ((Object)(object)_creatorText != (Object)null) { _creatorText.text = string.Empty; } if ((Object)(object)_modText != (Object)null) { _modText.text = string.Empty; } if ((Object)(object)_heightText != (Object)null) { _heightText.text = "Height unavailable"; } if (_actionButton != null) { _actionButton.Root.SetActive(false); } if (_trashButton != null) { _trashButton.Root.SetActive(false); } ResetTrashConfirmation(); SetStatus(((int)_viewState == 6) ? "Searching BONELAB mod.io..." : (_downloadsOnly ? "No downloadable matches" : "Try another search"), Cyan); SetProgressVisible(visible: false); } private void RefreshSelection(AvatarEntry entry) { //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Invalid comparison between Unknown and I4 //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Invalid comparison between Unknown and I4 //IL_01b3: 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_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Invalid comparison between Unknown and I4 //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Invalid comparison between Unknown and I4 //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Invalid comparison between Unknown and I4 //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Invalid comparison between Unknown and I4 //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Invalid comparison between Unknown and I4 //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Invalid comparison between Unknown and I4 //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: 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_0544: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Invalid comparison between Unknown and I4 //IL_03ee: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_selectedName == (Object)null || (Object)(object)_creatorText == (Object)null || (Object)(object)_modText == (Object)null || (Object)(object)_actionLabel == (Object)null || (Object)(object)_actionPanel == (Object)null || _actionButton == null) { return; } _selectedName.text = entry.AvatarName; _creatorText.text = "By " + entry.Creator; _modText.text = entry.ModName; if (!string.Equals(_trashConfirmIdentity, entry.Identity, StringComparison.OrdinalIgnoreCase)) { ResetTrashConfirmation(); } if (_trashButton != null) { _trashButton.Root.SetActive(entry.Installed); } if ((Object)(object)_positionText != (Object)null) { _positionText.text = _cursor.PositionText; } _previewAvatar = (string.IsNullOrWhiteSpace(entry.Barcode) ? null : _runtime.FindAvatar(entry.Barcode)); if (_previewAvatar != null) { if (PreviewShellRecovery.ShouldSchedule(_previewAvatar.Barcode, _loadedPreviewBarcode, _requestedPreviewBarcode)) { SchedulePreview(_previewAvatar); } SetHeight(_previewMetrics.TryGetValue(_previewAvatar.Barcode, out var value) ? ((AvatarPreviewMetrics)(ref value)).GameDisplayText : "Measuring…", ((AvatarPreviewMetrics)(ref value)).Valid ? Green : Cyan); if (!_previewReady && _jobs.TryGetValue(entry.ModId, out DownloadJob value2) && (int)value2.State == 5) { ConfigureProgress(entry); } else { SetProgressVisible(visible: false); } bool flag = string.Equals(_pendingSharingAvatar?.Barcode, _previewAvatar.Barcode, StringComparison.OrdinalIgnoreCase); bool flag2 = string.Equals(_sharingRetryBarcode, _previewAvatar.Barcode, StringComparison.OrdinalIgnoreCase); _actionLabel.text = (flag2 ? "RESCAN" : (flag ? "WAIT" : "EQUIP")); ((Graphic)_actionPanel).color = Green; if (_rigValidations.TryGetValue(_previewAvatar.Barcode, out var value3) && !((AvatarRigValidationResult)(ref value3)).CanEquip) { _actionLabel.text = "BROKEN"; ((Graphic)_actionPanel).color = Red; SetStatus("BROKEN AVATAR - CANNOT EQUIP", Red); } else if (flag2) { SetStatus("SHARING NOT READY - touch RESCAN", Red); } else if (flag) { SetStatus("Registering avatar pack with Fusion...", Cyan); } else if (!_previewReady) { SetStatus("Preparing preview", Cyan); } else if (_previewInteractionReady) { InstalledModRecord? obj = ((IEnumerable)_service.Installed).FirstOrDefault((Func)((InstalledModRecord item) => item.ModId == entry.ModId)); ModIoSharingMetadata val = ((obj != null) ? obj.Sharing : null); AvatarPlatformAvailability val2 = default(AvatarPlatformAvailability); ((AvatarPlatformAvailability)(ref val2))..ctor((val != null) ? val.WindowsFileId : ((long?)null), (val != null) ? val.AndroidFileId : ((long?)null)); if (((AvatarPlatformAvailability)(ref val2)).IsLimited) { SetStatus(((AvatarPlatformAvailability)(ref val2)).Badge + " - unsupported peers may see PolyBlank", new Color(1f, 0.72f, 0.28f, 1f)); } else { SetStatus(((((AvatarPlatformAvailability)(ref val2)).HasWindows && ((AvatarPlatformAvailability)(ref val2)).HasAndroid) ? (((AvatarPlatformAvailability)(ref val2)).Badge + " - ") : string.Empty) + (((int)_previewVisualSource == 1) ? "Ready - grip, pinch, or equip" : "3D preview ready - grip, pinch, or equip"), Green); } } else { SetStatus("Preview limited - Equip is still available", Cyan); } } else { if (_trashButton != null) { _trashButton.Root.SetActive(false); } ShowArtwork(entry); AvatarDownloadState downloadState = entry.DownloadState; bool flag3 = downloadState - 1 <= 2; bool flag4 = flag3; bool flag5 = entry.Installed || (int)entry.DownloadState == 4; _actionLabel.text = (flag4 ? "CANCEL" : (((int)entry.DownloadState == 5) ? "RETRY" : ((flag5 && (int)_installedFocus.State == 4) ? "RESCAN" : (flag5 ? "PREPARING" : "DOWNLOAD")))); ((Graphic)_actionPanel).color = (((int)entry.DownloadState == 5) ? Red : Cyan); SetStatus((!flag5) ? (flag4 ? string.Empty : DownloadStatus(entry)) : (((int)_installedFocus.State == 4) ? "Installed pack needs a pallet rescan" : "Preparing installed avatar pack"), ((int)entry.DownloadState == 5) ? Red : Cyan); SetHeight("Game height after download", Cyan); ConfigureProgress(entry); } } private void ShowArtwork(AvatarEntry entry) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) _previewGeneration++; _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _previewReady = false; _previewInteractionReady = false; _previewVisualSource = (AvatarPreviewVisualSource)0; ClearPreviewModel(); if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } if ((Object)(object)_centralArtwork == (Object)null) { return; } ((Component)_centralArtwork).gameObject.SetActive(true); _centralArtwork.texture = (Texture)(object)_placeholderTexture; int generation = _artworkGeneration.Next(); if (string.IsNullOrWhiteSpace(entry.ThumbnailUrl)) { return; } _thumbnails.Load(entry.ThumbnailUrl, delegate(Texture2D texture) { if (!_disposed && _artworkGeneration.IsCurrent(generation)) { AvatarEntry? obj = Selected(); if (((obj != null) ? obj.Identity : null) == entry.Identity && (Object)(object)_centralArtwork != (Object)null) { _centralArtwork.texture = (Texture)(object)texture; } } }); } private void ActivateSelected() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 //IL_012b: 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_010c: Unknown result type (might be due to invalid IL or missing references) AvatarEntry val = Selected(); if (val == (AvatarEntry)null) { return; } if (_previewAvatar != null) { EquipWithSharingReady(_previewAvatar); return; } if (val.Installed || (int)val.DownloadState == 4) { RetryInstalledPack(val.ModId); return; } DownloadJob value; bool flag = _jobs.TryGetValue(val.ModId, out value); if (flag) { DownloadState state = value.State; bool flag2 = (int)state <= 4; flag = flag2; } if (flag) { if (_downloadBatches.TryGetValue(val.ModId, out IReadOnlyList value2)) { foreach (Guid item in value2) { _service.CancelDownload(item); } return; } _service.CancelDownload(value.Id); } else if (!_startingDownloads.Contains(val.ModId)) { if (!_onlineMods.TryGetValue(val.ModId, out ModIoMod value3)) { SetStatus("This online result is unavailable. Search again.", Red); return; } _startingDownloads.Add(val.ModId); _viewState = (AvatarBrowserViewState)8; SetStatus(string.Empty, Cyan); ConfigureProgress(val); StartDownloadAsync(value3); } } private void ShowDeleteConfirmation() { AvatarEntry val = Selected(); if (!(val == (AvatarEntry)null) && val.Installed && !_trashInProgress) { bool flag = _runtime.IsWearingPack(val.ModId); GameObject? packPage = _packPage; if (packPage == null || !packPage.activeSelf) { _deleteReturnToPackPage = false; } _trashConfirmIdentity = val.Identity; GameObject? packPage2 = _packPage; if (packPage2 != null) { packPage2.SetActive(false); } GameObject? detailPage = _detailPage; if (detailPage != null) { detailPage.SetActive(false); } GameObject? optionsPage = _optionsPage; if (optionsPage != null) { optionsPage.SetActive(false); } GameObject? keyboardPage = _keyboardPage; if (keyboardPage != null) { keyboardPage.SetActive(false); } GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(true); } if ((Object)(object)_deleteTitle != (Object)null) { _deleteTitle.text = "DELETE PACK?"; } if ((Object)(object)_deleteDetails != (Object)null) { int count = _runtime.GetAvatars(val.ModId).Count; bool flag2 = _sharing.IsSubscribed(val.ModId); _deleteDetails.text = $"{val.ModName}\n{count} avatar{((count == 1) ? string.Empty : "s")} will be removed" + (flag2 ? "\nThis also unsubscribes it from mod.io." : string.Empty) + (flag ? "\nYou are wearing this pack. WristHub will switch to PolyBlank first." : string.Empty); } ClearPreviewModel(); if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } ResetTouchButtons(); RequireInputRearm(); _log.Msg($"Delete confirmation opened for an installed pack (active={flag})."); } } private void CancelDelete() { _trashConfirmIdentity = string.Empty; GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } if (_deleteReturnToPackPage) { ShowPackPage(); } else { ShowDetailPage(); } } private void SetDeleteStatus(string value, Color color) { //IL_003d: 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) GameObject? packPage = _packPage; if (packPage != null && packPage.activeSelf && (Object)(object)_packStatus != (Object)null) { _packStatus.text = value; ((Graphic)_packStatus).color = color; } else { SetStatus(value, color); } } private void ReturnFromDelete(string message, Color color) { //IL_004f: 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) GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } if (_deleteReturnToPackPage) { ShowPackPage(); if ((Object)(object)_packStatus != (Object)null) { _packStatus.text = message; ((Graphic)_packStatus).color = color; } } else { ShowDetailPage(); SetStatus(message, color); } } private void TrashSelected() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) AvatarEntry entry = Selected(); if (entry == (AvatarEntry)null || !entry.Installed || _trashInProgress) { return; } if (!string.Equals(_trashConfirmIdentity, entry.Identity, StringComparison.OrdinalIgnoreCase)) { ShowDetailPage(); SetStatus("The selected pack changed. Touch Delete Pack again.", Red); return; } if (_runtime.IsWearingPack(entry.ModId)) { _trashInProgress = true; if ((Object)(object)_deleteTitle != (Object)null) { _deleteTitle.text = "SWITCHING AVATAR..."; } if ((Object)(object)_deleteDetails != (Object)null) { _deleteDetails.text = "Switching to BONELAB's PolyBlank so this pack can be removed safely."; } _log.Msg("Delete is switching away from the active avatar pack before removal."); _runtime.LeavePackForDeletion(entry.ModId, delegate(bool success, string? error) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) _trashInProgress = false; if (!success) { _log.Warning("Delete could not leave the active pack: " + Readable(error ?? "Unknown failure")); ReturnFromDelete("Delete paused: " + Readable(error ?? "Could not switch avatars"), Red); } else { _log.Msg("Safe avatar is active; continuing pack deletion."); TrashSelected(); } }); return; } IReadOnlyList directories = _runtime.GetPackDirectories(entry.ModId); if (directories.Count == 0) { InstalledModRecord val = ((IEnumerable)_service.Installed).FirstOrDefault((Func)((InstalledModRecord item) => item.ModId == entry.ModId)); IReadOnlyList readOnlyList; if (val != null) { IReadOnlyList installedDirectories = val.InstalledDirectories; readOnlyList = installedDirectories; } else { IReadOnlyList installedDirectories = Array.Empty(); readOnlyList = installedDirectories; } directories = readOnlyList; } if (directories.Count == 0) { if ((Object)(object)_deleteDetails != (Object)null) { _deleteDetails.text = "This pack's local folder could not be identified.\nNothing was deleted."; } _log.Warning("Delete was blocked because no local pack folder matched the selected mod ID."); return; } _trashInProgress = true; if ((Object)(object)_deleteTitle != (Object)null) { _deleteTitle.text = "REMOVING PACK..."; } long modId = entry.ModId; string modName = entry.ModName; bool subscribed = _sharing.IsSubscribed(modId); string[] removedBarcodes = (from avatar in _runtime.GetAvatars(modId) select avatar.Barcode).ToArray(); if (subscribed && !_sharing.Unsubscribe(modId)) { _trashInProgress = false; CancelDelete(); SetStatus("Could not unsubscribe this pack. Nothing was deleted.", Red); _log.Warning("Delete was cancelled because ModioModNetworker could not unsubscribe the pack."); return; } _log.Msg($"Pack deletion started with {directories.Count} local folder{((directories.Count == 1) ? string.Empty : "s")}."); Task.Run(async delegate { try { await _service.UninstallSubscribedAsync(modId, modName, directories, subscribed, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); await _service.ForgetAvatarBarcodesAsync((IEnumerable)removedBarcodes, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) _trashInProgress = false; _selectedIdentity = string.Empty; ResetTrashConfirmation(); _runtime.ForgetAvatars(removedBarcodes); string[] array = removedBarcodes; foreach (string key in array) { _previewMetrics.Remove(key); _previewRoutes.Remove(key); } _runtime.RemovePack(modId); _sharing.RequestRefresh(immediate: true); GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } RefreshEntries(); ShowScopePage(); SetStatus("Avatar pack removed. Undo is available in BoneMenu.", Green); _log.Msg("Avatar pack deletion completed and the local library refresh was requested."); }); } catch (Exception ex) { Exception exception = ex; if ((exception is UnauthorizedAccessException || exception is IOException) ? true : false) { try { await _service.QueueDeletionAsync(modId, modName, directories, subscribed, (IEnumerable)removedBarcodes, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) _trashInProgress = false; _selectedIdentity = string.Empty; ResetTrashConfirmation(); _runtime.ForgetAvatars(removedBarcodes); _runtime.SetPendingDeletions(_service.PendingDeletionModIds); string[] array = removedBarcodes; foreach (string key in array) { _previewMetrics.Remove(key); _previewRoutes.Remove(key); } _sharing.RequestRefresh(immediate: true); GameObject? deletePage = _deletePage; if (deletePage != null) { deletePage.SetActive(false); } RefreshEntries(); ShowScopePage(); SetStatus("Pack queued for deletion - restart BONELAB once", Green); _log.Msg("Locked avatar pack was hidden and queued for deletion during the next startup."); }); return; } catch (Exception ex2) { Exception ex3 = ex2; Exception queueError = ex3; if (subscribed) { _sharing.Subscribe(modId); } _mainThread.Enqueue(delegate { //IL_0055: Unknown result type (might be due to invalid IL or missing references) _trashInProgress = false; ResetTrashConfirmation(); ReturnFromDelete("Delete failed: " + Readable(queueError.Message), Red); _log.Warning("Avatar pack could not be queued after a file lock: " + Readable(queueError.Message)); }); return; } } if (subscribed) { _sharing.Subscribe(modId); } _mainThread.Enqueue(delegate { //IL_0046: Unknown result type (might be due to invalid IL or missing references) _trashInProgress = false; ResetTrashConfirmation(); ReturnFromDelete("Delete failed: " + Readable(exception.Message), Red); _log.Warning("Avatar pack deletion rolled back: " + Readable(exception.Message)); }); } }); } private void ResetTrashConfirmation() { _trashConfirmIdentity = string.Empty; if (_trashButton != null) { _trashButton.Label.text = "DELETE PACK"; } } private void UpdateInstalledPackFocus() { //IL_0017: 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) if (_installedFocus.UpdateTimeout((double)Time.unscaledTime)) { _viewState = (AvatarBrowserViewState)10; RefreshEntries(); RefreshFocusedResult(); SetStatus("Installed pack was not loaded. Touch RESCAN.", Red); _log.Warning("An installed avatar pack timed out before a runtime crate became equip-ready."); } } private void RetryInstalledPack(long modId) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) IReadOnlyList avatars = _runtime.GetAvatars(modId); if (avatars.Count > 0) { if (!_installedFocus.Active || _installedFocus.ModId != modId) { _installedFocus.Begin(modId, (double)Time.unscaledTime, (IEnumerable)null, 45.0); } OnAvatarsChanged(modId, avatars); return; } if (!_installedFocus.Active || _installedFocus.ModId != modId) { _installedFocus.Begin(modId, (double)Time.unscaledTime, (IEnumerable)null, 45.0); } else { _installedFocus.Retry((double)Time.unscaledTime, 45.0); } _selectedPackId = modId; _viewState = (AvatarBrowserViewState)9; bool flag = _runtime.RetryInstallation(modId); if (!flag) { _runtime.RefreshLocalLibrary(); } RefreshEntries(); RefreshFocusedResult(); SetStatus(flag ? "Rescanning installed avatar pack..." : "Refreshing installed avatar library...", Cyan); _log.Msg("Targeted installed-pack rescan requested for equip handoff."); } private async Task StartDownloadAsync(ModIoMod mod) { try { _installedFocus.BeginDownload(mod.Id); _log.Msg("Download started with a dedicated root-pack equip handoff."); IReadOnlyList jobs = await _service.InstallWithDependenciesAsync(mod, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { foreach (DownloadJob item in jobs) { _jobs[item.Mod.Id] = item; } _downloadBatches[mod.Id] = jobs.Select((DownloadJob job) => job.Id).ToArray(); _startingDownloads.Remove(mod.Id); RefreshEntries(); RefreshFocusedResult(); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (_installedFocus.ModId == mod.Id) { _installedFocus.Clear(); } _startingDownloads.Remove(mod.Id); SetStatus(Readable(exception.Message), Red); }); } } private async Task SearchOnlineAsync(string query, int generation) { try { ModIoPage page = await _service.SearchAsync(new ModSearchRequest(query, "Avatar", (string)null, (ModSort)0, 0, 100), default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { //IL_00f4: 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) if (!_disposed && generation == _searchGeneration) { _onlineMods.Clear(); foreach (ModIoMod datum in page.Data) { _onlineMods[datum.Id] = datum; } _onlineEntries = page.Data.Select((ModIoMod mod) => AvatarEntry.FromOnline(mod, _runtime.IsModInstalled(mod.Id))).ToArray(); _viewState = (AvatarBrowserViewState)7; RefreshEntries(); ShowDetailPage(); _log.Msg($"Avatar search completed with {_entries.Count} merged results."); SetStatus((_entries.Count == 0) ? "No avatars found" : $"{_entries.Count} avatar result{((_entries.Count == 1) ? string.Empty : "s")}", Cyan); } }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!_disposed && generation == _searchGeneration) { _viewState = (AvatarBrowserViewState)10; SetStatus(Readable(exception.Message), Red); } }); } } private void CreatePreviewShell() { EnsurePreviewShell(reportRecovery: false); } private bool EnsurePreviewShell(bool reportRecovery) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (!PreviewShellRecovery.RequiresRebuild((Object)(object)_previewShell != (Object)null, (Object)(object)_previewFallback != (Object)null)) { return true; } try { try { if ((Object)(object)_previewShell != (Object)null) { Object.Destroy((Object)(object)_previewShell); } } catch { } _previewShell = new GameObject("[WristHub] Grabbable Avatar Preview"); Object.DontDestroyOnLoad((Object)(object)_previewShell); _previewShell.SetActive(false); _previewFallback = CreateSilhouette(_previewShell.transform); PlacePreviewImmediately(); if (reportRecovery) { _log.Msg("WristHub restored its 3D preview shell after a scene or Fusion rig transition."); } return (Object)(object)_previewFallback != (Object)null; } catch (Exception ex) { _previewShell = null; _previewFallback = null; string text = "preview-shell|" + ex.GetType().FullName; if (_runtimeErrorThrottle.ShouldLog(text, (double)Environment.TickCount64 / 1000.0, 5.0)) { _log.Error($"WristHub could not restore the 3D preview shell: {ex}"); } return false; } } private void LoadPreview(BoneHubAvatar avatar) { //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_0099: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown if (!EnsurePreviewShell(reportRecovery: true)) { _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _previewReady = true; _previewInteractionReady = false; SetStatus("Preview unavailable - use Equip", Red); return; } int generation = ++_previewGeneration; _viewState = (AvatarBrowserViewState)9; _loadedPreviewBarcode = avatar.Barcode; _previewReady = false; _previewInteractionReady = false; _previewVisualSource = (AvatarPreviewVisualSource)0; ClearPreviewModel(); if ((Object)(object)_centralArtwork != (Object)null) { ((Component)_centralArtwork).gameObject.SetActive(false); } if ((Object)(object)_previewShell == (Object)null || (Object)(object)_previewFallback == (Object)null) { return; } _previewShell.SetActive(IsOpen); _previewFallback.SetActive(true); PlacePreviewImmediately(); try { AvatarCrate crate = ((CrateReferenceT)new AvatarCrateReference(avatar.Barcode)).Crate; if ((Object)(object)crate == (Object)null) { FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, (AvatarPreviewHeightSource)0, interactionReady: false, "The avatar crate is unavailable."); return; } LoadNativePreviewPlaceholder(crate, avatar, generation); ((CrateT)(object)crate).LoadAsset(Action.op_Implicit((Action)delegate(GameObject prefab) { _mainThread.Enqueue(delegate { //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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_02b9: Invalid comparison between Unknown and I4 //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: 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_02fb: Unknown result type (might be due to invalid IL or missing references) if (_disposed || (Object)(object)prefab == (Object)null || generation != _previewGeneration || (Object)(object)_previewShell == (Object)null) { return; } try { AvatarRigValidationResult value = BoneHubAvatarRigValidator.Validate(prefab); _rigValidations[avatar.Barcode] = value; if (!((AvatarRigValidationResult)(ref value)).CanEquip) { _log.Msg("A malformed avatar was blocked before BONELAB ArtRig: " + Readable(((AvatarRigValidationResult)(ref value)).Reason)); } float realtimeSinceStartup = Time.realtimeSinceStartup; RenderOnlyPreviewResult fullColorResult = BoneHubRenderOnlyPreviewBuilder.Build(prefab, _previewShell.transform, _constrainedRendering); float num = Time.realtimeSinceStartup - realtimeSinceStartup; if (num > 0.5f) { _log.Msg($"A full-color preview took {num:0.00}s to prepare; the native placeholder remained available."); } AvatarPreviewMetrics value2 = default(AvatarPreviewMetrics); ((AvatarPreviewMetrics)(ref value2))..ctor(avatar.Barcode, fullColorResult.VisualHeightMeters, AvatarPreviewMath.IsUsableHeight(fullColorResult.VisualHeightMeters)); _previewMetrics[avatar.Barcode] = value2; AvatarEntry? obj = Selected(); if (((obj != null) ? obj.Barcode : null) == avatar.Barcode) { SetHeight(((AvatarPreviewMetrics)(ref value2)).GameDisplayText, ((AvatarPreviewMetrics)(ref value2)).Valid ? Green : Red); } if (!fullColorResult.Valid || (Object)(object)fullColorResult.Root == (Object)null) { _log.Msg($"Full-color preview unavailable (declared {fullColorResult.DeclaredRendererCount}, usable {fullColorResult.RendererCount}): {Readable(fullColorResult.Error ?? "unsafe preview data")}"); if ((int)_previewVisualSource == 2 && (Object)(object)_previewModel != (Object)null) { FinishPreviewPreparation(avatar, _previewVisualSource, fullColorResult.HeightSource, interactionReady: true, null); } else { LoadNativePreviewFallback(crate, avatar, generation, fullColorResult); } } else { ClearPreviewModel(); _previewModel = fullColorResult.Root; _ownedPreviewMeshes.AddRange(fullColorResult.OwnedMeshes.Where((Mesh mesh) => (Object)(object)mesh != (Object)null)); _previewFallback.SetActive(false); FinishPreviewPreparation(avatar, fullColorResult.VisualSource, fullColorResult.HeightSource, fullColorResult.InteractionReady, null); } } catch (Exception ex2) { _previewMetrics[avatar.Barcode] = new AvatarPreviewMetrics(avatar.Barcode, 0f, false); AvatarEntry? obj2 = Selected(); if (((obj2 != null) ? obj2.Barcode : null) == avatar.Barcode) { SetHeight("Height unavailable", Red); } FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, (AvatarPreviewHeightSource)0, interactionReady: false, ex2.Message); _log.Msg("Avatar preview fallback used: " + ex2.Message); } }); })); } catch (Exception ex) { _previewMetrics[avatar.Barcode] = new AvatarPreviewMetrics(avatar.Barcode, 0f, false); SetHeight("Height unavailable", Red); FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, (AvatarPreviewHeightSource)0, interactionReady: false, ex.Message); _log.Msg("Avatar preview could not load: " + ex.Message); } } private void LoadNativePreviewPlaceholder(AvatarCrate crate, BoneHubAvatar avatar, int generation) { try { MarrowAssetT previewMesh = ((GameObjectCrate)crate).PreviewMesh; GameObject? previewFallback = _previewFallback; object obj; if (previewFallback == null) { obj = null; } else { Renderer componentInChildren = previewFallback.GetComponentInChildren(true); obj = ((componentInChildren != null) ? componentInChildren.sharedMaterial : null); } Material material = (Material)obj; if ((MarrowAsset)(object)previewMesh == (MarrowAsset)null || (Object)(object)material == (Object)null || (Object)(object)_previewShell == (Object)null) { return; } previewMesh.LoadAsset(Action.op_Implicit((Action)delegate(Mesh mesh) { _mainThread.Enqueue(delegate { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_0101: 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_018e: Unknown result type (might be due to invalid IL or missing references) if (!_disposed && !((Object)(object)mesh == (Object)null) && generation == _previewGeneration && !((Object)(object)_previewShell == (Object)null) && (int)_previewVisualSource != 1 && !((Object)(object)_previewModel != (Object)null)) { RenderOnlyPreviewResult renderOnlyPreviewResult = BoneHubRenderOnlyPreviewBuilder.BuildNativePreview(mesh, material, _previewShell.transform, _constrainedRendering, 0f, (AvatarPreviewHeightSource)0, 0, null); if (renderOnlyPreviewResult.Valid && !((Object)(object)renderOnlyPreviewResult.Root == (Object)null)) { _previewModel = renderOnlyPreviewResult.Root; _previewVisualSource = (AvatarPreviewVisualSource)2; _previewInteractionReady = renderOnlyPreviewResult.InteractionReady; if ((Object)(object)_previewFallback != (Object)null) { _previewFallback.SetActive(false); } AvatarEntry? obj3 = Selected(); if (((obj3 != null) ? obj3.Barcode : null) == avatar.Barcode) { SetHeight("Reading game height...", Cyan); } SetStatus("Preparing full-color preview...", Cyan); } } }); })); } catch { } } private void LoadNativePreviewFallback(AvatarCrate crate, BoneHubAvatar avatar, int generation, RenderOnlyPreviewResult fullColorResult) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) try { MarrowAssetT previewMesh = ((GameObjectCrate)crate).PreviewMesh; GameObject? previewFallback = _previewFallback; object obj; if (previewFallback == null) { obj = null; } else { Renderer componentInChildren = previewFallback.GetComponentInChildren(true); obj = ((componentInChildren != null) ? componentInChildren.sharedMaterial : null); } Material fallbackMaterial = (Material)obj; if ((MarrowAsset)(object)previewMesh == (MarrowAsset)null || (Object)(object)fallbackMaterial == (Object)null) { FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, fullColorResult.HeightSource, interactionReady: false, fullColorResult.Error ?? "The native preview mesh is unavailable."); return; } previewMesh.LoadAsset(Action.op_Implicit((Action)delegate(Mesh mesh) { _mainThread.Enqueue(delegate { //IL_00da: 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_010d: Invalid comparison between Unknown and I4 //IL_0078: 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_01f4: 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_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) if (!_disposed && generation == _previewGeneration && !((Object)(object)_previewShell == (Object)null)) { if ((Object)(object)mesh == (Object)null) { FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, fullColorResult.HeightSource, interactionReady: false, "The native preview mesh did not load."); } else { RenderOnlyPreviewResult renderOnlyPreviewResult = BoneHubRenderOnlyPreviewBuilder.BuildNativePreview(mesh, fallbackMaterial, _previewShell.transform, _constrainedRendering, fullColorResult.VisualHeightMeters, fullColorResult.HeightSource, fullColorResult.DeclaredRendererCount, fullColorResult.Error); bool flag = (int)renderOnlyPreviewResult.HeightSource != 3 && AvatarPreviewMath.IsUsableHeight(renderOnlyPreviewResult.VisualHeightMeters); AvatarPreviewMetrics value = default(AvatarPreviewMetrics); ((AvatarPreviewMetrics)(ref value))..ctor(avatar.Barcode, renderOnlyPreviewResult.VisualHeightMeters, flag); _previewMetrics[avatar.Barcode] = value; AvatarEntry? obj2 = Selected(); if (((obj2 != null) ? obj2.Barcode : null) == avatar.Barcode) { SetHeight(((AvatarPreviewMetrics)(ref value)).GameDisplayText, ((AvatarPreviewMetrics)(ref value)).Valid ? Green : Red); } if (!renderOnlyPreviewResult.Valid || (Object)(object)renderOnlyPreviewResult.Root == (Object)null) { FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, renderOnlyPreviewResult.HeightSource, interactionReady: false, renderOnlyPreviewResult.Error); } else { _previewModel = renderOnlyPreviewResult.Root; if ((Object)(object)_previewFallback != (Object)null) { _previewFallback.SetActive(false); } FinishPreviewPreparation(avatar, renderOnlyPreviewResult.VisualSource, renderOnlyPreviewResult.HeightSource, renderOnlyPreviewResult.InteractionReady, null); } } } }); })); } catch (Exception ex) { FinishPreviewPreparation(avatar, (AvatarPreviewVisualSource)0, fullColorResult.HeightSource, interactionReady: false, ex.Message); } } private void SchedulePreview(BoneHubAvatar avatar) { //IL_0087: 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) if (!EnsurePreviewShell(reportRecovery: true)) { _loadedPreviewBarcode = string.Empty; _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; _previewReady = true; _previewInteractionReady = false; SetStatus("Preview unavailable - use Equip", Red); return; } _previewGeneration++; _requestedPreviewBarcode = avatar.Barcode; _pendingPreviewAvatar = avatar; _previewLoadAt = Time.unscaledTime + 0.2f; _previewReady = false; _previewInteractionReady = false; _previewVisualSource = (AvatarPreviewVisualSource)0; ClearPreviewModel(); if ((Object)(object)_centralArtwork != (Object)null) { ((Component)_centralArtwork).gameObject.SetActive(false); } if ((Object)(object)_previewShell == (Object)null || (Object)(object)_previewFallback == (Object)null) { _requestedPreviewBarcode = string.Empty; _pendingPreviewAvatar = null; } else { _previewShell.SetActive(IsOpen); _previewFallback.SetActive(true); PlacePreviewImmediately(); } } private void ProcessPendingPreview() { if (!(_pendingPreviewAvatar == null) && !(Time.unscaledTime < _previewLoadAt)) { BoneHubAvatar pendingPreviewAvatar = _pendingPreviewAvatar; _pendingPreviewAvatar = null; AvatarEntry? obj = Selected(); if (((obj != null) ? obj.Barcode : null) != pendingPreviewAvatar.Barcode) { _requestedPreviewBarcode = string.Empty; } else { LoadPreview(pendingPreviewAvatar); } } } private void FinishPreviewPreparation(BoneHubAvatar avatar, AvatarPreviewVisualSource visualSource, AvatarPreviewHeightSource heightSource, bool interactionReady, string? error) { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Invalid comparison between Unknown and I4 //IL_00c5: 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_00e5: Unknown result type (might be due to invalid IL or missing references) _previewReady = true; _previewVisualSource = visualSource; AvatarRigValidationResult value; bool flag = !_rigValidations.TryGetValue(avatar.Barcode, out value) || ((AvatarRigValidationResult)(ref value)).CanEquip; _previewInteractionReady = interactionReady && flag; _previewRoutes[avatar.Barcode] = new AvatarPreviewRouteMetadata(visualSource, heightSource, interactionReady); _viewState = (AvatarBrowserViewState)7; SetProgressVisible(visible: false); AvatarEntry? obj = Selected(); if (((obj != null) ? obj.Barcode : null) != avatar.Barcode) { return; } if (!flag) { if ((Object)(object)_actionLabel != (Object)null) { _actionLabel.text = "BROKEN"; } if ((Object)(object)_actionPanel != (Object)null) { ((Graphic)_actionPanel).color = Red; } SetStatus("BROKEN AVATAR - CANNOT EQUIP", Red); } else if (interactionReady) { SetStatus(((int)visualSource == 1) ? "Ready - grip, pinch, or equip" : "3D preview ready - grip, pinch, or equip", Green); } else { SetStatus("Preview unavailable - use Equip", Red); _log.Msg("Avatar preview unavailable: " + Readable(error ?? "No safe 3D preview source was available.")); } } private void ConfigureProgress(AvatarEntry entry) { //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_003c: 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_0041: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 bool flag = _startingDownloads.Contains(entry.ModId); DownloadJob value; bool flag2 = _jobs.TryGetValue(entry.ModId, out value); bool flag3 = flag; if (!flag3) { bool flag4 = flag2; if (flag4) { DownloadState state = value.State; bool flag5 = state - 6 <= 1; flag4 = !flag5; } flag3 = flag4; } bool flag6 = flag3; SetProgressVisible(flag6); if (!flag6) { return; } if (flag2 && value != null) { if (_progressJobId != value.Id) { _progressJobId = value.Id; _displayedProgress = 0.0; _targetProgress = 0.0; } _targetProgress = (((int)value.State == 5) ? 1.0 : Math.Max(_targetProgress, value.Progress)); } else if (flag) { _progressJobId = Guid.Empty; _displayedProgress = 0.0; _targetProgress = 0.0; } UpdateProgressText(entry); } private void UpdateDownloadProgress() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) if (!((Object)(object)_progressRoot == (Object)null) && _progressRoot.activeSelf && !((Object)(object)_progressFill == (Object)null)) { _displayedProgress = (_preferences.ReducedMotion ? _targetProgress : DownloadPresentationMath.Smooth(_displayedProgress, _targetProgress, (double)Time.unscaledDeltaTime, 8.0)); TabletRect progress = AvatarTabletLayout.Progress; float num = ((TabletRect)(ref progress)).Width * (float)_displayedProgress; _progressFill.sizeDelta = new Vector2(Mathf.Max(0.5f, num), ((TabletRect)(ref progress)).Height); _progressFill.anchoredPosition = new Vector2(((TabletRect)(ref progress)).Left + num * 0.5f, ((TabletRect)(ref progress)).Y); AvatarEntry val = Selected(); if (val != (AvatarEntry)null) { UpdateProgressText(val); } } } private void UpdateProgressText(AvatarEntry entry) { //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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected I4, but got Unknown //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_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_01e1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_progressText == (Object)null)) { int num = Mathf.Clamp(Mathf.RoundToInt((float)_displayedProgress * 100f), 0, 100); if (_lastProgressPercent != num || _lastProgressState != (AvatarDownloadState?)entry.DownloadState) { _lastProgressPercent = num; _lastProgressState = entry.DownloadState; TMP_Text progressText = _progressText; AvatarDownloadState downloadState = entry.DownloadState; progressText.text = (downloadState - 1) switch { 0 => "QUEUED", 1 => $"DOWNLOADING {num}%", 2 => $"INSTALLING {num}%", 3 => "100% PREPARING PREVIEW", 4 => $"FAILED {num}%", 5 => $"CANCELLED {num}%", _ => _startingDownloads.Contains(entry.ModId) ? "PREPARING DOWNLOAD" : $"{num}%", }; ((Graphic)_progressText).color = Color.white; } } } private void SetProgressVisible(bool visible) { if ((Object)(object)_progressRoot != (Object)null) { _progressRoot.SetActive(visible); } if (!visible) { _lastProgressPercent = -1; _lastProgressState = null; } } private void UpdatePreview() { //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: 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_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0156: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_028e: 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_0298: 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_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_previewShell == (Object)null || !_previewShell.activeSelf || (Object)(object)_root == (Object)null) { return; } IReadOnlyList probes = _fingertips.GetProbes(); if (_previewHeld) { BoneHubFingertipProbe probe = default(BoneHubFingertipProbe); for (int i = 0; i < probes.Count; i++) { BoneHubFingertipProbe boneHubFingertipProbe = probes[i]; if (boneHubFingertipProbe.IsLeft == _dragIsLeft) { probe = boneHubFingertipProbe; break; } } if ((Object)(object)probe.Hand == (Object)null) { if (_dragTrackingLostAt < 0f) { _dragTrackingLostAt = Time.unscaledTime; } if (!(Time.unscaledTime - _dragTrackingLostAt <= 0.18f)) { EndPreviewDrag(equipIfAtChest: false); } return; } _dragTrackingLostAt = -1f; Vector3 position; Quaternion rotation; if (!PreviewInputActive(probe, alreadyDragging: true, _dragUsesPinch)) { EndPreviewDrag(equipIfAtChest: true); } else if (!probe.TryGetDragAnchor(_dragUsesPinch, out position, out rotation)) { if (_dragTrackingLostAt < 0f) { _dragTrackingLostAt = Time.unscaledTime; } if (Time.unscaledTime - _dragTrackingLostAt > 0.18f) { EndPreviewDrag(equipIfAtChest: false); } } else { _previewShell.transform.position = position + rotation * _dragLocalOffset; _previewShell.transform.rotation = rotation * _dragRotationOffset; bool flag = Vector3.Distance(_previewShell.transform.position, ChestPosition()) <= ChestInteractionRadius(); SetStatus(flag ? "Release to equip" : "Pull to your chest", flag ? Green : Cyan); } return; } if (_previewInteractionReady && _previewAvatar != null && !_previewReturning) { for (int j = 0; j < probes.Count; j++) { BoneHubFingertipProbe probe2 = probes[j]; bool num = ControllerGripActive(probe2, alreadyDragging: false); bool flag2 = !num && probe2.HasTrackedFingers && PreviewDragMath.PinchActive(probe2.PinchDistance, false, 0.03f, 0.045f); if ((num || flag2) && PreviewContains(probe2.Position) && probe2.TryGetDragAnchor(flag2, out var position2, out var rotation2)) { _previewHeld = true; _dragHand = probe2.Hand; _dragIsLeft = probe2.IsLeft; _dragUsesPinch = flag2; Vector3 val = Quaternion.Inverse(rotation2) * (_previewShell.transform.position - position2); Vector3 vector = PreviewDragMath.LimitAnchorOffset(new Vector3(val.x, val.y, val.z), flag2 ? 0.06f : 0.085f); _dragLocalOffset = new Vector3(vector.X, vector.Y, vector.Z); _dragRotationOffset = Quaternion.Inverse(rotation2) * _previewShell.transform.rotation; _dragTrackingLostAt = -1f; Pulse(probe2.Hand); SetStatus("Move the avatar to your chest", Cyan); return; } } } Vector3 val2 = PreviewSlot(); Quaternion rotation3 = _root.transform.rotation; if (_previewReturning) { float num2 = Mathf.Clamp01((Time.unscaledTime - _returnStarted) / 0.28f); float num3 = num2 * num2 * (3f - 2f * num2); _previewShell.transform.position = Vector3.Lerp(_returnFrom, val2, num3); _previewShell.transform.rotation = Quaternion.Slerp(_returnRotation, rotation3, num3); if (num2 >= 1f) { _previewReturning = false; } } else { _previewShell.transform.SetPositionAndRotation(val2, rotation3); } } private bool PreviewContains(Vector3 worldPosition) { //IL_001b: 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_0021: 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_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_previewShell == (Object)null) { return false; } Vector3 val = _previewShell.transform.InverseTransformPoint(worldPosition); return PreviewDragMath.IsInside(new Vector3(val.x, val.y, val.z), new Vector3(0.08f, 0.115f, 0.075f)); } private static bool ControllerGripActive(BoneHubFingertipProbe probe, bool alreadyDragging) { try { return (Object)(object)probe.Hand.Controller != (Object)null && PreviewDragMath.GripActive(probe.Hand.Controller.GetGripForce(), alreadyDragging, 0.62f, 0.28f); } catch { return false; } } private static bool PreviewInputActive(BoneHubFingertipProbe probe, bool alreadyDragging, bool usePinch) { if (!usePinch) { return ControllerGripActive(probe, alreadyDragging); } if (probe.HasTrackedFingers) { return PreviewDragMath.PinchActive(probe.PinchDistance, alreadyDragging, 0.03f, 0.045f); } return false; } private void EndPreviewDrag(bool equipIfAtChest) { //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_00b3: 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) //IL_00c9: 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) if (_previewHeld && !((Object)(object)_previewShell == (Object)null)) { Hand dragHand = _dragHand; bool num = equipIfAtChest && _previewAvatar != null && Vector3.Distance(_previewShell.transform.position, ChestPosition()) <= ChestInteractionRadius(); _previewHeld = false; _dragHand = null; _dragUsesPinch = false; _dragTrackingLostAt = -1f; if (num) { EquipWithSharingReady(_previewAvatar); } if ((Object)(object)dragHand != (Object)null) { Pulse(dragHand); } _previewReturning = true; _returnStarted = Time.unscaledTime; _returnFrom = _previewShell.transform.position; _returnRotation = _previewShell.transform.rotation; } } private void EquipWithSharingReady(BoneHubAvatar avatar) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) if (_rigValidations.TryGetValue(avatar.Barcode, out var value) && !((AvatarRigValidationResult)(ref value)).CanEquip) { SetStatus("BROKEN AVATAR - CANNOT EQUIP", Red); if ((Object)(object)_actionLabel != (Object)null) { _actionLabel.text = "BROKEN"; } return; } InstalledModRecord? obj = ((IEnumerable)_service.Installed).FirstOrDefault((Func)((InstalledModRecord item) => item.ModId == avatar.ModId)); ModIoSharingMetadata val = ((obj != null) ? obj.Sharing : null); if (!_runtime.FusionSessionActive || val == null || val.PalletBarcodes.Count == 0) { CancelPendingSharingRegistration(); _sharingRetryBarcode = string.Empty; _runtime.Equip(avatar); return; } if (!_sharing.Available) { _sharingState = (AvatarSharingState)5; _sharingRetryBarcode = avatar.Barcode; SetStatus("SHARING NOT READY - ModioModNetworker is missing", Red); RefreshSelection(avatar.ToEntry()); return; } if (_sharing.IsRegistered(val.PalletBarcodes, val.ModId)) { CancelPendingSharingRegistration(); _sharingRetryBarcode = string.Empty; AvatarPlatformAvailability val2 = new AvatarPlatformAvailability(val.WindowsFileId, val.AndroidFileId); _sharingState = (AvatarSharingState)(((AvatarPlatformAvailability)(ref val2)).IsLimited ? 4 : 2); _runtime.Equip(avatar); return; } _sharingState = (AvatarSharingState)1; _sharingRetryBarcode = string.Empty; _pendingSharingAvatar = avatar; _pendingSharingMetadata = val; _nextSharingCheckAt = 0f; _sharingDeadline = Time.unscaledTime + 20f; _sharingRefreshRequested = false; SetStatus("Registering avatar pack with Fusion...", Cyan); if ((Object)(object)_actionLabel != (Object)null) { _actionLabel.text = "WAIT"; } } private void TickSharingRegistration() { //IL_009b: 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_00ae: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) BoneHubAvatar pendingSharingAvatar = _pendingSharingAvatar; ModIoSharingMetadata pendingSharingMetadata = _pendingSharingMetadata; if (pendingSharingAvatar == null || pendingSharingMetadata == null) { return; } AvatarEntry? obj = Selected(); if (!string.Equals((obj != null) ? obj.Barcode : null, pendingSharingAvatar.Barcode, StringComparison.OrdinalIgnoreCase)) { CancelPendingSharingRegistration(); } else { if (Time.unscaledTime < _nextSharingCheckAt) { return; } _nextSharingCheckAt = Time.unscaledTime + 0.25f; if (_sharing.IsRegistered(pendingSharingMetadata.PalletBarcodes, pendingSharingMetadata.ModId)) { CancelPendingSharingRegistration(); _sharingRetryBarcode = string.Empty; AvatarPlatformAvailability val = new AvatarPlatformAvailability(pendingSharingMetadata.WindowsFileId, pendingSharingMetadata.AndroidFileId); _sharingState = (AvatarSharingState)(((AvatarPlatformAvailability)(ref val)).IsLimited ? 4 : 2); SetStatus("Sharing ready - equipping avatar", Green); if ((Object)(object)_actionLabel != (Object)null) { _actionLabel.text = "EQUIP"; } _log.Msg("The selected avatar pallet is registered; Fusion equip is continuing through its normal sender."); _runtime.Equip(pendingSharingAvatar); return; } if (!_sharingRefreshRequested && !_sharing.RegistrationRefreshBusy) { _sharingRefreshRequested = true; _sharing.RequestRefresh(immediate: true); } if (_sharing.RegistrationRefreshBusy) { _sharingDeadline = Math.Max(_sharingDeadline, Time.unscaledTime + 2f); } else if (!(Time.unscaledTime < _sharingDeadline)) { CancelPendingSharingRegistration(); _sharingState = (AvatarSharingState)5; _sharingRetryBarcode = pendingSharingAvatar.Barcode; SetStatus("SHARING NOT READY - touch RESCAN", Red); if ((Object)(object)_actionLabel != (Object)null) { _actionLabel.text = "RESCAN"; } _log.Warning("Fusion equip was paused because the exact pallet was not registered by ModioModNetworker."); } } } private void CancelPendingSharingRegistration() { _pendingSharingAvatar = null; _pendingSharingMetadata = null; _nextSharingCheckAt = 0f; _sharingDeadline = 0f; _sharingRefreshRequested = false; } private void FollowWrist(bool immediate = false) { //IL_0071: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_00d3: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f7: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0177: 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_0180: 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_01a7: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && !((Object)(object)Player.Head == (Object)null)) { Hand obj = (_preferences.UseLeftWrist ? Player.LeftHand : Player.RightHand); Transform val = ((obj != null) ? ((Component)obj).transform : null); if (!((Object)(object)val == (Object)null)) { float num = AvatarUiScaleMath.ResolveMenuScale(CurrentPlayerHeight()); Vector3 val2 = (_preferences.UseLeftWrist ? (-1f) : 1f) * val.right; Vector3 val3 = val.position + Vector3.up * (0.12f * num) + val2 * ((_preferences.OutwardOffset + 0.09f) * num) + val.forward * (_preferences.FingerOffset * num); Vector3 val4 = Player.Head.position - val3; Quaternion val5 = Quaternion.LookRotation(-((Vector3)(ref val4)).normalized, Vector3.up); float num2 = (_preferences.ReducedMotion ? 30f : 13f); float num3 = (immediate ? 1f : (1f - Mathf.Exp((0f - num2) * Time.unscaledDeltaTime))); _root.transform.position = Vector3.Lerp(_root.transform.position, val3, num3); _root.transform.rotation = Quaternion.Slerp(_root.transform.rotation, val5, num3); _root.transform.localScale = Vector3.one * (_preferences.WatchScale * num); } } } private static float CurrentPlayerHeight() { try { RigManager rigManager = Player.RigManager; float? obj; if (rigManager == null) { obj = null; } else { Avatar avatar = rigManager.avatar; obj = ((avatar != null) ? new float?(avatar.height) : ((float?)null)); } float? num = obj; float valueOrDefault = num.GetValueOrDefault(); return AvatarPreviewMath.IsUsableHeight(valueOrDefault) ? valueOrDefault : 1.75f; } catch { return 1.75f; } } private static bool IsLocalPlayerDead() { try { RigManager rigManager = Player.RigManager; Health val = ((rigManager != null) ? rigManager.health : null); return (Object)(object)val != (Object)null && (!val.alive || val.deathIsImminent); } catch { return false; } } private void UpdatePushPromptVisibility() { //IL_0001: 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_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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if ((int)_viewState != 0 || (Object)(object)_launcher == (Object)null || !_launcher.activeSelf || (Object)(object)Player.Head == (Object)null) { _promptDismissal.Reset(); return; } Vector3 val = _launcher.transform.position - Player.Head.position; float magnitude = ((Vector3)(ref val)).magnitude; float num = AvatarUiScaleMath.ResolveMenuScale(CurrentPlayerHeight()); bool flag = magnitude >= 0.08f * num && magnitude <= 0.9f * num && magnitude > 0.01f && Vector3.Dot(Player.Head.forward, val / magnitude) >= 0.75f; if (_promptDismissal.Update(flag, (double)Time.unscaledDeltaTime, 0.35)) { Close(); } } private void PollButtons() { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) for (int num = _buttons.Count - 1; num >= 0; num--) { if (!_buttons[num].IsAlive) { _buttons.RemoveAt(num); } } IReadOnlyList probes = _fingertips.GetProbes(); if (_inputRearm.Required) { bool flag = false; for (int i = 0; i < probes.Count; i++) { if (flag) { break; } BoneHubFingertipProbe boneHubFingertipProbe = probes[i]; if ((Object)(object)boneHubFingertipProbe.Hand == (Object)null) { continue; } for (int j = 0; j < _buttons.Count; j++) { if (_buttons[j].Contains(boneHubFingertipProbe.Position)) { flag = true; break; } } } if (!_inputRearm.CanInteract(flag, (double)Time.unscaledTime)) { return; } } _activeProbeIds.Clear(); for (int k = 0; k < probes.Count; k++) { BoneHubFingertipProbe boneHubFingertipProbe2 = probes[k]; if ((Object)(object)boneHubFingertipProbe2.Hand == (Object)null) { continue; } int instanceID = ((Object)boneHubFingertipProbe2.Hand).GetInstanceID(); _activeProbeIds.Add(instanceID); if (_touchCaptures.TryGetValue(instanceID, out TouchButton value)) { if (!value.Contains(boneHubFingertipProbe2.Position)) { ReleaseTouchCapture(instanceID, value); } continue; } TouchButton touchButton = null; float num2 = float.MaxValue; for (int l = 0; l < _buttons.Count; l++) { TouchButton touchButton2 = _buttons[l]; if (touchButton2.Contains(boneHubFingertipProbe2.Position)) { float num3 = TouchDistanceScore(touchButton2, boneHubFingertipProbe2.Position); if (!(num3 >= num2)) { num2 = num3; touchButton = touchButton2; } } } if (touchButton != null && touchButton.Debounce.Update(true)) { _touchCaptures[instanceID] = touchButton; Transform transform = ((Component)touchButton.Panel).transform; transform.localPosition += Vector3.forward * 0.003f; Pulse(boneHubFingertipProbe2.Hand); touchButton.Action(); if (_inputRearm.Required) { break; } } } _staleCaptureIds.Clear(); foreach (KeyValuePair touchCapture in _touchCaptures) { if (!_activeProbeIds.Contains(touchCapture.Key)) { _staleCaptureIds.Add(touchCapture.Key); } } foreach (int staleCaptureId in _staleCaptureIds) { if (_touchCaptures.TryGetValue(staleCaptureId, out TouchButton value2)) { ReleaseTouchCapture(staleCaptureId, value2); } } } private static float TouchDistanceScore(TouchButton button, Vector3 worldPosition) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0054: 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) try { if ((Object)(object)button.Space == (Object)null) { return float.MaxValue; } Vector3 val = button.Space.InverseTransformPoint(worldPosition) - button.Center; float num = val.x / Mathf.Max(button.Half.x, 0.0001f); float num2 = val.y / Mathf.Max(button.Half.y, 0.0001f); float num3 = val.z / Mathf.Max(button.Half.z, 0.0001f); return num * num + num2 * num2 + num3 * num3; } catch { return float.MaxValue; } } private void ReleaseTouchCapture(int probeId, TouchButton button) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_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) _touchCaptures.Remove(probeId); if (!button.Debounce.Latched) { return; } button.Debounce.Update(false); try { if ((Object)(object)button.Panel != (Object)null) { Transform transform = ((Component)button.Panel).transform; transform.localPosition -= Vector3.forward * 0.003f; } } catch { } } private void ResetTouchButtons() { //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_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) foreach (TouchButton button in _buttons) { if (!button.Debounce.Latched) { continue; } button.Debounce.Update(false); try { if ((Object)(object)button.Panel != (Object)null) { Transform transform = ((Component)button.Panel).transform; transform.localPosition -= Vector3.forward * 0.003f; } } catch { } } _touchCaptures.Clear(); } private void RequireInputRearm() { ResetTouchButtons(); _inputRearm.Require(); } private void OpenKeyboard() { //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_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_00b1: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_browser == (Object)null) && !((Object)(object)_keyboardPage == (Object)null)) { if (_query.Length == 0) { _scopeBeforeSearch = _scope; } _viewStateBeforeKeyboard = _viewState; _keyboard.Set(_query); _keyboardPage.SetActive(true); GameObject? packPage = _packPage; if (packPage != null) { packPage.SetActive(false); } GameObject? detailPage = _detailPage; if (detailPage != null) { detailPage.SetActive(false); } GameObject? optionsPage = _optionsPage; if (optionsPage != null) { optionsPage.SetActive(false); } if ((Object)(object)_previewShell != (Object)null) { _previewShell.SetActive(false); } _viewState = (AvatarBrowserViewState)5; RefreshKeyboardText(); RequireInputRearm(); _log.Msg("WristHub tablet keyboard opened for avatar search."); } } private void AppendKeyboardCharacter(char character) { _keyboard.Append(character); RefreshKeyboardText(); } private void AppendKeyboardSpace() { _keyboard.AppendSpace(); RefreshKeyboardText(); } private void BackspaceKeyboard() { _keyboard.Backspace(); RefreshKeyboardText(); } private void ClearKeyboard() { _keyboard.Clear(); RefreshKeyboardText(); } private void ToggleKeyboardShift() { _keyboard.ToggleShift(); RefreshKeyboardText(); } private void RefreshKeyboardText() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_keyboardText != (Object)null) { _keyboardText.text = ((_keyboard.Value.Length == 0) ? "Type an avatar name" : _keyboard.VisibleValue(36)); ((Graphic)_keyboardText).color = (Color)((_keyboard.Value.Length == 0) ? new Color(0.55f, 0.68f, 0.74f, 1f) : Color.white); } if ((Object)(object)_keyboardShiftText != (Object)null) { _keyboardShiftText.text = (_keyboard.Shifted ? "SHIFT ON" : "SHIFT"); } } private void SubmitKeyboard() { //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) string text = _keyboard.Value.Trim(); if (text.Length == 0) { _scope = _scopeBeforeSearch; } SetQuery(text); } private void CancelKeyboard() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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: Invalid comparison between Unknown and I4 GameObject? keyboardPage = _keyboardPage; if (keyboardPage != null) { keyboardPage.SetActive(false); } _viewState = _viewStateBeforeKeyboard; if ((int)_viewStateBeforeKeyboard == 0) { ShowHub(); return; } if ((int)_viewStateBeforeKeyboard == 3) { ShowDetailPage(); return; } ShowScopePage(); _log.Msg("WristHub tablet keyboard cancelled."); } private void MoveFocused(int direction) { //IL_0045: 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) if (_entries.Count == 0) { return; } try { ResetTrashConfirmation(); int index = _cursor.Move(direction); _selectedIdentity = _entries[index].Identity; RefreshFocusedResult(); } catch (Exception value) { _viewState = (AvatarBrowserViewState)10; SetStatus("Could not change avatar. Try again.", Red); _log.Error($"Avatar paging failed: {value}"); } } private AvatarEntry? Selected() { return ((IEnumerable)_entries).FirstOrDefault((Func)((AvatarEntry entry) => entry.Identity == _selectedIdentity)); } private int IndexOf(string identity) { for (int i = 0; i < _entries.Count; i++) { if (string.Equals(_entries[i].Identity, identity, StringComparison.OrdinalIgnoreCase)) { return i; } } return 0; } private Vector3 PreviewSlot() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { return _root.transform.TransformPoint(new Vector3(-0.06f, -0.006f, -0.03f)); } return Vector3.zero; } private static Vector3 ChestPosition() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) if ((Object)(object)Player.Head == (Object)null) { return Vector3.zero; } float num = AvatarUiScaleMath.ResolveMenuScale(CurrentPlayerHeight()); return Player.Head.position - Vector3.up * (0.34f * num) + Player.Head.forward * (0.05f * num); } private float ChestInteractionRadius() { return 0.22f * _preferences.EquipZoneScale * AvatarUiScaleMath.ResolveMenuScale(CurrentPlayerHeight()); } private void PlacePreviewImmediately() { //IL_0029: 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)_previewShell == (Object)null) && !((Object)(object)_root == (Object)null)) { _previewShell.transform.SetPositionAndRotation(PreviewSlot(), _root.transform.rotation); } } private void ClearPreviewModel() { if ((Object)(object)_previewModel != (Object)null) { Object.Destroy((Object)(object)_previewModel); } _previewModel = null; foreach (Mesh ownedPreviewMesh in _ownedPreviewMeshes) { if ((Object)(object)ownedPreviewMesh != (Object)null) { Object.Destroy((Object)(object)ownedPreviewMesh); } } _ownedPreviewMeshes.Clear(); if ((Object)(object)_previewFallback != (Object)null) { _previewFallback.SetActive(true); } } private void SetHeight(string value, Color color) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_005d: 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_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_heightText != (Object)null) { _heightText.text = value; ((Graphic)_heightText).color = color; } if ((Object)(object)_heightRuler == (Object)null) { return; } foreach (Graphic componentsInChild in _heightRuler.GetComponentsInChildren(true)) { componentsInChild.color = ((color == Green) ? Green : ((color == Red) ? Red : DimCyan)); } } private GameObject CreateSilhouette(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_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_0056: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_0102: 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_0114: Expected O, but got Unknown GameObject val = new GameObject("Clean Avatar Silhouette"); val.transform.SetParent(parent, false); CreatePanel(val.transform, "Head", new Vector3(0f, 0.06f, 0f), new Vector3(0.043f, 0.043f, 0.025f), Cyan, (PrimitiveType)0); CreatePanel(val.transform, "Body", new Vector3(0f, 0f, 0f), new Vector3(0.07f, 0.08f, 0.028f), DimCyan, (PrimitiveType)3); CreatePanel(val.transform, "Leg L", new Vector3(-0.02f, -0.065f, 0f), new Vector3(0.022f, 0.06f, 0.02f), DimCyan, (PrimitiveType)3); CreatePanel(val.transform, "Leg R", new Vector3(0.02f, -0.065f, 0f), new Vector3(0.022f, 0.06f, 0.02f), DimCyan, (PrimitiveType)3); return val; } private TouchButton CreateButton(Transform space, Transform visualParent, string label, Vector3 center, Vector3 size, Color color, Action action, float fontSize) { //IL_0002: 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_0010: 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_0033: Expected O, but got Unknown //IL_0042: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00e9: 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) //IL_0123: 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_0138: 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_015c: Unknown result type (might be due to invalid IL or missing references) ((Vector3)(ref center))..ctor(center.x, center.y, 0f - Mathf.Abs(center.z)); GameObject val = new GameObject("Button - " + label); val.transform.SetParent(visualParent, false); TabletRect bounds = default(TabletRect); ((TabletRect)(ref bounds))..ctor(center.x * 1000f, center.y * 1000f, size.x * 1000f, size.y * 1000f); Image val2 = val.AddComponent(); if ((Object)(object)_roundedSprite != (Object)null) { val2.sprite = _roundedSprite; val2.type = (Type)1; } ((Graphic)val2).color = color; ((Graphic)val2).raycastTarget = false; SetRect(((Graphic)val2).rectTransform, bounds); TMP_Text label2 = CreateText(val.transform, label, new TabletRect(0f, 0f, ((TabletRect)(ref bounds)).Width - 8f, ((TabletRect)(ref bounds)).Height - 4f), fontSize, Color.white, (TextAlignmentOptions)514, (FontStyles)1); TouchButton touchButton = new TouchButton { Space = space, Root = val, Panel = val2, Label = label2, Center = center, Half = new Vector3(size.x * 0.55f, size.y * 0.6f, Mathf.Max(0.009f, size.z * 0.65f)), Action = action }; _buttons.Add(touchButton); return touchButton; } private static GameObject CreateCanvas(Transform parent, string name, float width, float height, float z) { //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_0013: 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_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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0073: 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_0086: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = new Vector3(0f, 0f, 0f - Mathf.Abs(z)); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.001f; Canvas obj = val.AddComponent(); obj.renderMode = (RenderMode)2; obj.sortingOrder = 100; val.GetComponent().sizeDelta = new Vector2(width, height); return val; } private Image CreateImage(Transform parent, string name, TabletRect bounds, Color color) { //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_003b: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); Image val2 = val.AddComponent(); if ((Object)(object)_roundedSprite != (Object)null) { val2.sprite = _roundedSprite; val2.type = (Type)1; } ((Graphic)val2).color = color; ((Graphic)val2).raycastTarget = false; SetRect(((Graphic)val2).rectTransform, bounds); return val2; } private static RawImage CreateRawImage(Transform parent, string name, TabletRect bounds, Texture2D texture, Color color) { //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_0020: 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_0053: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RawImage obj = val.AddComponent(); obj.texture = (Texture)(object)texture; ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; obj.uvRect = new Rect(0f, 0f, 1f, 1f); SetRect(((Graphic)obj).rectTransform, bounds); return obj; } private static TMP_Text CreateText(Transform parent, string value, TabletRect bounds, float fontSize, Color color, TextAlignmentOptions alignment, FontStyles style = (FontStyles)0) { //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_006f: 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_007f: 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) GameObject val = new GameObject("Text - " + value); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent(); if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null) { ((TMP_Text)val2).font = TMP_Settings.defaultFontAsset; } ((TMP_Text)val2).text = value; ((TMP_Text)val2).fontSize = fontSize; ((TMP_Text)val2).enableAutoSizing = true; ((TMP_Text)val2).fontSizeMax = fontSize; ((TMP_Text)val2).fontSizeMin = Mathf.Max(7f, fontSize * 0.55f); ((TMP_Text)val2).fontStyle = style; ((Graphic)val2).color = color; ((TMP_Text)val2).alignment = alignment; ((TMP_Text)val2).enableWordWrapping = ((TabletRect)(ref bounds)).Height >= fontSize * 1.55f; ((TMP_Text)val2).overflowMode = (TextOverflowModes)3; ((Graphic)val2).raycastTarget = false; SetRect(((TMP_Text)val2).rectTransform, bounds); return (TMP_Text)(object)val2; } private static void SetRect(RectTransform rect, TabletRect bounds) { //IL_000b: 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_0035: 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_0067: 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) rect.anchorMin = new Vector2(0.5f, 0.5f); rect.anchorMax = new Vector2(0.5f, 0.5f); rect.pivot = new Vector2(0.5f, 0.5f); rect.anchoredPosition = new Vector2(((TabletRect)(ref bounds)).X, ((TabletRect)(ref bounds)).Y); rect.sizeDelta = new Vector2(((TabletRect)(ref bounds)).Width, ((TabletRect)(ref bounds)).Height); ((Transform)rect).localScale = Vector3.one; ((Transform)rect).localRotation = Quaternion.identity; } private static Vector3 PixelCenter(TabletRect rect) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) return new Vector3(((TabletRect)(ref rect)).X / 1000f, ((TabletRect)(ref rect)).Y / 1000f, 0.007f); } private static Vector3 PixelSize(TabletRect rect) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) return new Vector3(((TabletRect)(ref rect)).Width / 1000f, ((TabletRect)(ref rect)).Height / 1000f, 0.014f); } private static Texture2D CreatePlaceholderTexture() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_00bd: 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_00be: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = "WristHub Permanent Avatar Placeholder", hideFlags = (HideFlags)32 }; Color[] array = (Color[])(object)new Color[4096]; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.02f, 0.075f, 0.105f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.18f, 0.72f, 0.82f, 1f); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { bool flag = (j - 32) * (j - 32) + (i - 45) * (i - 45) <= 64; bool flag2 = j >= 22 && j <= 42 && i >= 16 && i <= 37; array[i * 64 + j] = ((flag || flag2) ? val3 : val2); } } val.SetPixels(Il2CppStructArray.op_Implicit(array)); val.Apply(false, true); return val; } private static Texture2D CreateRoundedTexture() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_00fb: 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) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = "WristHub Rounded Rectangle", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)32 }; Color[] array = (Color[])(object)new Color[4096]; float num = 32f; float num2 = num - 14f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num3 = Mathf.Abs((float)j + 0.5f - num) - num2; float num4 = Mathf.Abs((float)i + 0.5f - num) - num2; float num5 = Mathf.Sqrt(Mathf.Max(num3, 0f) * Mathf.Max(num3, 0f) + Mathf.Max(num4, 0f) * Mathf.Max(num4, 0f)) + Mathf.Min(Mathf.Max(num3, num4), 0f) - 14f; float num6 = Mathf.Clamp01(0.5f - num5); array[i * 64 + j] = new Color(1f, 1f, 1f, num6); } } val.SetPixels(Il2CppStructArray.op_Implicit(array)); val.Apply(false, true); return val; } private static Renderer CreatePanel(Transform parent, string name, Vector3 position, Vector3 scale, Color color, PrimitiveType primitive = (PrimitiveType)3) { //IL_0000: 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_002d: 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_005f: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive(primitive); ((Object)obj).name = name; obj.transform.SetParent(parent, false); obj.transform.localPosition = position; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = scale; Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = obj.GetComponent(); SetColor(component2, color); return component2; } private static void SetColor(Renderer renderer, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0013: 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) MaterialPropertyBlock val = new MaterialPropertyBlock(); renderer.GetPropertyBlock(val); val.SetColor("_Color", color); val.SetColor("_BaseColor", color); renderer.SetPropertyBlock(val); } private static void SetTexture(Renderer renderer, Texture2D texture) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown MaterialPropertyBlock val = new MaterialPropertyBlock(); renderer.GetPropertyBlock(val); val.SetTexture("_MainTex", (Texture)(object)texture); val.SetTexture("_BaseMap", (Texture)(object)texture); renderer.SetPropertyBlock(val); } private void SetStatus(string value, Color color) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_statusText == (Object)null)) { _statusText.text = (string.IsNullOrWhiteSpace(value) ? "Ready" : value.Trim()); ((Graphic)_statusText).color = color; } } private void Pulse(Hand hand) { if (!_preferences.HapticsEnabled) { return; } try { BaseController obj = (((Object)(object)hand == (Object)(object)Player.LeftHand) ? Player.LeftController : Player.RightController); if (obj != null) { Haptor haptor = obj.haptor; if (haptor != null) { haptor.Haptic_Tap(); } } } catch (Exception ex) { _log.Msg("Touch haptic skipped: " + ex.Message); } } private static AvatarDownloadState Map(DownloadState state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected I4, but got Unknown //IL_0029: 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_0031: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) switch ((int)state) { case 0: case 1: return (AvatarDownloadState)1; case 2: case 3: return (AvatarDownloadState)2; case 4: return (AvatarDownloadState)3; case 5: return (AvatarDownloadState)4; case 6: return (AvatarDownloadState)5; case 7: return (AvatarDownloadState)6; default: return (AvatarDownloadState)0; } } private static string CardStatus(AvatarEntry entry) { //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_0027: Expected I4, but got Unknown AvatarDownloadState downloadState = entry.DownloadState; return (downloadState - 1) switch { 0 => "QUEUED", 1 => $"{Math.Round(entry.DownloadProgress * 100.0)}%", 2 => "INSTALLING", 4 => "RETRY", 5 => "CANCELLED", _ => entry.Installed ? "INSTALLED" : "ONLINE", }; } private static bool IsEffectRenderer(Renderer renderer) { return !AvatarPreviewMath.IsVisualRendererType(((object)renderer).GetType().Name); } private static string DownloadStatus(AvatarEntry entry) { //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_0027: Expected I4, but got Unknown AvatarDownloadState downloadState = entry.DownloadState; return (downloadState - 1) switch { 0 => string.Empty, 1 => string.Empty, 2 => string.Empty, 3 => "Preparing installed avatar pack", 4 => Readable(entry.Status ?? "Download failed"), 5 => "Download cancelled", _ => entry.Compatible ? "Available on mod.io" : "Not compatible", }; } private static string Readable(string value) { if (!string.IsNullOrWhiteSpace(value)) { return value.Replace('\r', ' ').Replace('\n', ' ').Trim(); } return "Something went wrong. Try again."; } private static string Short(string value, int length) { string text = (string.IsNullOrWhiteSpace(value) ? "Unknown" : value.Trim()); if (text.Length > length) { return text.Substring(0, Math.Max(1, length - 1)) + "…"; } return text; } } internal static class BoneHubAvatarRigValidator { private static readonly string[] EssentialArtTransforms = new string[17] { "artHips", "artSpine", "artChest", "artNeck", "artHead", "artUpperArmLf", "artLowerArmLf", "artHandLf", "artUpperArmRt", "artLowerArmRt", "artHandRt", "artUpperLegLf", "artLowerLegLf", "artFootLf", "artUpperLegRt", "artLowerLegRt", "artFootRt" }; public static AvatarRigValidationResult Validate(GameObject prefab) { //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_021f: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: 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) try { if ((Object)(object)prefab == (Object)null) { return AvatarRigValidationResult.Reject("The avatar asset did not load."); } Avatar val = prefab.GetComponent() ?? ((IEnumerable)prefab.GetComponentsInChildren(true)).FirstOrDefault((Func)((Avatar candidate) => (Object)(object)candidate != (Object)null)); if ((Object)(object)val == (Object)null) { return AvatarRigValidationResult.Reject("A BONELAB Avatar definition is missing."); } List list = new List(4); if (!float.IsFinite(val.height) || !AvatarPreviewMath.IsUsableHeight(val.height)) { list.Add("Height metadata is unavailable"); } bool? flag = ReadBoolean(val, "PreComputed", "preComputed", "precomputed", "_preComputed"); if (flag.HasValue && !flag.Value) { list.Add("Runtime precompute flag is false"); } if (CountValid((IEnumerable?)val.bodyMeshes) + CountValid((IEnumerable?)val.headMeshes) + CountValid((IEnumerable?)val.hairMeshes) == 0) { list.Add("Declared preview renderers are unavailable"); } int num = 0; bool flag2 = true; string[] essentialArtTransforms = EssentialArtTransforms; foreach (string name in essentialArtTransforms) { object obj = ReadMember(val, name); if (obj != null) { num++; Transform val2 = (Transform)((obj is Transform) ? obj : null); if (val2 == null || (Object)(object)val2 == (Object)null || !IsInside(val2, prefab.transform)) { flag2 = false; } } } if (!flag2) { list.Add("Some reflected ArtTransforms could not be verified"); } if (num < EssentialArtTransforms.Length) { Animator val3 = ((IEnumerable)prefab.GetComponentsInChildren(true)).FirstOrDefault((Func)((Animator candidate) => (Object)(object)candidate != (Object)null && candidate.isHuman)); if ((Object)(object)val3 == (Object)null || !HasEssentialHumanoidBones(val3, prefab.transform)) { list.Add("The complete humanoid rig could not be verified through IL2CPP"); } } return (list.Count == 0) ? AvatarRigValidationResult.Ready() : AvatarRigValidationResult.Allow(string.Join("; ", list)); } catch (Exception ex) { return AvatarRigValidationResult.Allow("Rig preflight was unavailable: " + ex.GetType().Name); } } private static int CountValid(IEnumerable? renderers) { return renderers?.Count((SkinnedMeshRenderer renderer) => (Object)(object)renderer != (Object)null && (Object)(object)renderer.sharedMesh != (Object)null) ?? 0; } private static bool HasEssentialHumanoidBones(Animator animator, Transform root) { //IL_001a: 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) HumanBodyBones[] array = new HumanBodyBones[17]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); HumanBodyBones[] array2 = (HumanBodyBones[])(object)array; foreach (HumanBodyBones val in array2) { Transform boneTransform = animator.GetBoneTransform(val); if ((Object)(object)boneTransform == (Object)null || !IsInside(boneTransform, root)) { return false; } } return true; } private static bool IsInside(Transform candidate, Transform root) { Transform val = candidate; while ((Object)(object)val != (Object)null) { if ((Object)(object)val == (Object)(object)root) { return true; } val = val.parent; } return false; } private static bool? ReadBoolean(object value, params string[] names) { foreach (string name in names) { object obj = ReadMember(value, name); if (obj is bool) { return (bool)obj; } } return null; } private static object? ReadMember(object value, string name) { Type type = value.GetType(); object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value); if (obj == null) { PropertyInfo? property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property == null) { return null; } obj = property.GetValue(value); } return obj; } } internal readonly record struct BoneHubFingertipProbe(Hand Hand, Vector3 Position, Vector3 ThumbPosition, bool HasTrackedFingers, bool IsLeft, Vector3 GripAnchorPosition, Quaternion GripAnchorRotation, bool GripAnchorTracked, Vector3 PinchPosition, Quaternion PinchRotation) { public float PinchDistance => Vector3.Distance(Position, ThumbPosition); public bool TryGetDragAnchor(bool pinch, out Vector3 position, out Quaternion rotation) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_001c: 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_0042: 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) position = (pinch ? PinchPosition : GripAnchorPosition); rotation = (pinch ? PinchRotation : GripAnchorRotation); if ((pinch ? HasTrackedFingers : GripAnchorTracked) && IsFinite(position)) { return IsFinite(rotation); } 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 (float.IsFinite(value.x) && float.IsFinite(value.y)) { return float.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 (float.IsFinite(value.x) && float.IsFinite(value.y) && float.IsFinite(value.z)) { return float.IsFinite(value.w); } return false; } } internal sealed class BoneHubFingertipProbeProvider { private readonly List _probes = new List(2); private Transform? _leftIntermediate; private Transform? _leftDistal; private Transform? _leftThumbIntermediate; private Transform? _leftThumbDistal; private Transform? _rightIntermediate; private Transform? _rightDistal; private Transform? _rightThumbIntermediate; private Transform? _rightThumbDistal; private float _nextResolveTime; private int _rigInstanceId; private int _leftHandInstanceId; private int _rightHandInstanceId; private int _lastProbeFrame = -1; public IReadOnlyList GetProbes() { if (_lastProbeFrame == Time.frameCount) { return _probes; } _lastProbeFrame = Time.frameCount; RefreshRigIdentity(); if (Time.unscaledTime >= _nextResolveTime || ((Object)(object)_leftDistal == (Object)null && (Object)(object)_rightDistal == (Object)null)) { ResolveBones(); } _probes.Clear(); AddProbe(Player.LeftHand, isLeft: true, _leftIntermediate, _leftDistal, _leftThumbIntermediate, _leftThumbDistal, _probes); AddProbe(Player.RightHand, isLeft: false, _rightIntermediate, _rightDistal, _rightThumbIntermediate, _rightThumbDistal, _probes); return _probes; } public void Invalidate() { ClearBones(); _rigInstanceId = 0; _leftHandInstanceId = 0; _rightHandInstanceId = 0; _lastProbeFrame = -1; } private void ClearBones() { _leftIntermediate = null; _leftDistal = null; _leftThumbIntermediate = null; _leftThumbDistal = null; _rightIntermediate = null; _rightDistal = null; _rightThumbIntermediate = null; _rightThumbDistal = null; _nextResolveTime = 0f; } private void RefreshRigIdentity() { int num = SafeInstanceId((Object?)(object)Player.RigManager); int num2 = SafeInstanceId((Object?)(object)Player.LeftHand); int num3 = SafeInstanceId((Object?)(object)Player.RightHand); if (num != _rigInstanceId || num2 != _leftHandInstanceId || num3 != _rightHandInstanceId) { ClearBones(); _rigInstanceId = num; _leftHandInstanceId = num2; _rightHandInstanceId = num3; } } private static int SafeInstanceId(Object? value) { try { return (!(value == (Object)null)) ? value.GetInstanceID() : 0; } catch { return 0; } } private void ResolveBones() { _nextResolveTime = Time.unscaledTime + 1f; try { RigManager rigManager = Player.RigManager; Animator val = ((rigManager != null) ? ((IEnumerable)((Component)rigManager).GetComponentsInChildren(true)).FirstOrDefault((Func)((Animator candidate) => (Object)(object)candidate != (Object)null && candidate.isHuman && (Object)(object)candidate.GetBoneTransform((HumanBodyBones)29) != (Object)null)) : null); if (!((Object)(object)val == (Object)null)) { _leftIntermediate = val.GetBoneTransform((HumanBodyBones)28); _leftDistal = val.GetBoneTransform((HumanBodyBones)29); _leftThumbIntermediate = val.GetBoneTransform((HumanBodyBones)25); _leftThumbDistal = val.GetBoneTransform((HumanBodyBones)26); _rightIntermediate = val.GetBoneTransform((HumanBodyBones)43); _rightDistal = val.GetBoneTransform((HumanBodyBones)44); _rightThumbIntermediate = val.GetBoneTransform((HumanBodyBones)40); _rightThumbDistal = val.GetBoneTransform((HumanBodyBones)41); } } catch { Invalidate(); _nextResolveTime = Time.unscaledTime + 1f; } } private static void AddProbe(Hand? hand, bool isLeft, Transform? intermediate, Transform? distal, Transform? thumbIntermediate, Transform? thumbDistal, ICollection probes) { //IL_009d: 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_00b5: 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_00d2: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_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_01b1: 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_01d0: 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) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hand == (Object)null) { return; } Transform transform = ((Component)hand).transform; bool flag = false; try { if ((Object)(object)hand.Controller != (Object)null && (Object)(object)((Component)hand.Controller).transform != (Object)null) { transform = ((Component)hand.Controller).transform; flag = true; } } catch { } Transform val = ((Component)hand).transform; bool gripAnchorTracked = (Object)(object)val != (Object)null; try { if ((Object)(object)hand.palmPositionTransform != (Object)null) { val = hand.palmPositionTransform; gripAnchorTracked = true; } else if (flag) { val = transform; gripAnchorTracked = true; } } catch { val = transform; gripAnchorTracked = flag; } if ((Object)(object)distal == (Object)null || !((Component)distal).gameObject.activeInHierarchy) { Transform val2 = transform; Vector3 vector = FingertipProbeMath.ControllerTip(new Vector3(val2.position.x, val2.position.y, val2.position.z), new Vector3(val2.forward.x, val2.forward.y, val2.forward.z), 0.075f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(vector.X, vector.Y, vector.Z); probes.Add(new BoneHubFingertipProbe(hand, val3, val3, HasTrackedFingers: false, isLeft, val.position, val.rotation, gripAnchorTracked, val.position, val.rotation)); } else { Vector3 val4 = Extrapolate(intermediate, distal, ((Component)hand).transform.forward); Vector3 val5 = (((Object)(object)thumbDistal != (Object)null && ((Component)thumbDistal).gameObject.activeInHierarchy) ? Extrapolate(thumbIntermediate, thumbDistal, ((Component)hand).transform.forward) : ((thumbDistal != null) ? thumbDistal.position : (val4 + ((Component)hand).transform.right * 0.05f))); Vector3 pinchPosition = Vector3.Lerp(val4, val5, 0.5f); probes.Add(new BoneHubFingertipProbe(hand, val4, val5, (Object)(object)thumbDistal != (Object)null, isLeft, val.position, val.rotation, gripAnchorTracked, pinchPosition, ((Component)hand).transform.rotation)); } } private static Vector3 Extrapolate(Transform? intermediate, Transform distal, Vector3 fallbackForward) { //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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_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) if ((Object)(object)intermediate == (Object)null) { return distal.position + fallbackForward * 0.015f; } Vector3 vector = FingertipProbeMath.Extrapolate(new Vector3(intermediate.position.x, intermediate.position.y, intermediate.position.z), new Vector3(distal.position.x, distal.position.y, distal.position.z), 0.65f); return new Vector3(vector.X, vector.Y, vector.Z); } } internal enum BoneHubProjectionState { Charging, Expanding, Projecting, Revealing, Stable, Collapsing, TrackingGrace, Hidden } internal sealed class BoneHubForearmProjection : IDisposable { private const float ChargeEnd = 0.1f; private const float ExpandEnd = 0.24f; private const float ProjectEnd = 0.38f; private const float RevealEnd = 0.56f; private const float CollapseSeconds = 0.18f; private const float TrackingHoldSeconds = 0.2f; private const float TrackingFadeSeconds = 0.24f; private static readonly Color Cyan = new Color(0.04f, 0.72f, 1f, 1f); private static readonly float[] TetherOffsets = new float[3] { -0.29f, 0f, 0.29f }; private readonly Instance _log; private readonly MaterialPropertyBlock _block = new MaterialPropertyBlock(); private readonly Renderer[] _rings = (Renderer[])(object)new Renderer[2]; private readonly Renderer[] _tethers = (Renderer[])(object)new Renderer[TetherOffsets.Length]; private readonly Renderer[] _pulses = (Renderer[])(object)new Renderer[TetherOffsets.Length]; private readonly List _ownedMeshes = new List(5); private GameObject? _root; private Renderer? _emitterGlow; private Renderer? _emitterCore; private Renderer? _ticks; private Renderer? _revealEdge; private Material? _material; private float _shownAt; private float _collapseStartedAt; private float _trackingLostAt = -1f; private float _lastBrightness = 1f; private Vector3 _smoothedEmitter; private Vector3 _smoothedNormal = Vector3.up; private bool _hasSmoothedAnchor; private bool _loggedFailure; private bool _disposing; public BoneHubProjectionState State { get; private set; } = BoneHubProjectionState.Hidden; public float RevealProgress { get; private set; } = 1f; public BoneHubForearmProjection(Instance log) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //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) _log = log; } public void Show() { EnsureBuilt(); if (!((Object)(object)_root == (Object)null)) { _shownAt = Time.unscaledTime; _trackingLostAt = -1f; _collapseStartedAt = -1f; RevealProgress = 0f; State = BoneHubProjectionState.Charging; _root.SetActive(true); } } public void UpdatePose(BoneHubForearmProjectionAnchor anchor, Transform tablet, bool reducedMotion, float brightness) { //IL_00e2: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_0118: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) EnsureBuilt(); if ((Object)(object)_root == (Object)null || (Object)(object)_emitterCore == (Object)null || (Object)(object)tablet == (Object)null) { return; } bool flag = !_root.activeSelf; if (!flag) { BoneHubProjectionState state = State; bool flag2 = ((state == BoneHubProjectionState.Collapsing || state == BoneHubProjectionState.Hidden) ? true : false); flag = flag2; } if (flag) { Show(); } _trackingLostAt = -1f; _lastBrightness = Mathf.Clamp(brightness, 0.25f, 2f); float num = 1f - Mathf.Exp(-20f * Mathf.Max(0f, Time.unscaledDeltaTime)); if (!_hasSmoothedAnchor) { _smoothedEmitter = anchor.EmitterPosition; _smoothedNormal = SafeNormal(anchor.SurfaceNormal, Vector3.up); _hasSmoothedAnchor = true; } else { _smoothedEmitter = Vector3.Lerp(_smoothedEmitter, anchor.EmitterPosition, num); Vector3 val = Vector3.Slerp(_smoothedNormal, SafeNormal(anchor.SurfaceNormal, _smoothedNormal), num); _smoothedNormal = ((Vector3)(ref val)).normalized; } float num2 = MaxAxis(tablet.lossyScale); float num3 = Vector3.Distance(tablet.position - tablet.forward * (0.008f * num2), _smoothedEmitter); float num4 = Mathf.Max(0.24f, 0.82f * num2); if (!float.IsFinite(num3) || num3 < 0.025f || num3 > num4) { BeginTrackingGrace(); UpdateTrackingLost(); return; } float num5 = Mathf.Max(0f, Time.unscaledTime - _shownAt); if (reducedMotion) { RevealProgress = 1f; State = BoneHubProjectionState.Stable; } else { RevealProgress = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((num5 - 0.24f) / 0.32f)); State = ((!(num5 < 0.1f)) ? ((num5 < 0.24f) ? BoneHubProjectionState.Expanding : ((num5 < 0.38f) ? BoneHubProjectionState.Projecting : ((num5 < 0.56f) ? BoneHubProjectionState.Revealing : BoneHubProjectionState.Stable))) : BoneHubProjectionState.Charging); } ApplyGeometry(_smoothedEmitter, _smoothedNormal, tablet, num2, num5, reducedMotion, _lastBrightness); } public void BeginTrackingGrace() { if (State != BoneHubProjectionState.Hidden) { if (_trackingLostAt < 0f) { _trackingLostAt = Time.unscaledTime; } State = BoneHubProjectionState.TrackingGrace; } } public void UpdateTrackingLost() { if ((Object)(object)_root == (Object)null || !_root.activeSelf) { return; } BeginTrackingGrace(); float num = Time.unscaledTime - _trackingLostAt; if (!(num <= 0.2f)) { float num2 = 1f - Mathf.Clamp01((num - 0.2f) / 0.24f); SetAllAlpha(num2 * _lastBrightness); if (num2 <= 0f) { Hide(immediate: true); } } } public void Hide(bool immediate = false) { if (!((Object)(object)_root == (Object)null)) { if (immediate || !_root.activeSelf) { _root.SetActive(false); _hasSmoothedAnchor = false; _trackingLostAt = -1f; State = BoneHubProjectionState.Hidden; RevealProgress = 1f; } else if (State != BoneHubProjectionState.Collapsing) { _collapseStartedAt = Time.unscaledTime; State = BoneHubProjectionState.Collapsing; } } } public void Tick(bool reducedMotion) { if (State == BoneHubProjectionState.Collapsing && !((Object)(object)_root == (Object)null)) { float num = (reducedMotion ? 1f : Mathf.Clamp01((Time.unscaledTime - _collapseStartedAt) / 0.18f)); SetAllAlpha((1f - Mathf.SmoothStep(0f, 1f, num)) * _lastBrightness); if (num >= 1f) { Hide(immediate: true); } } } public void Dispose() { _disposing = true; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } foreach (Mesh ownedMesh in _ownedMeshes) { if ((Object)(object)ownedMesh != (Object)null) { Object.Destroy((Object)(object)ownedMesh); } } if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } _ownedMeshes.Clear(); _root = null; _material = null; State = BoneHubProjectionState.Hidden; RevealProgress = 1f; _disposing = false; } private void ApplyGeometry(Vector3 emitterPosition, Vector3 surfaceNormal, Transform tablet, float tabletScale, float elapsed, bool reducedMotion, float brightness) { //IL_00fe: 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_0104: 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_010d: 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_0139: 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_013c: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_0129: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: 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) //IL_01e8: 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_0204: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: 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_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_029e: 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_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: 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_02bd: 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_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Unknown result type (might be due to invalid IL or missing references) //IL_0562: 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_056d: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04be: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_emitterGlow == (Object)null || (Object)(object)_emitterCore == (Object)null || (Object)(object)_ticks == (Object)null || (Object)(object)_revealEdge == (Object)null) { return; } float num = (reducedMotion ? 1f : Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(elapsed / 0.1f))); float num2 = (reducedMotion ? 1f : Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((elapsed - 0.05f) / 0.19f))); float num3 = (reducedMotion ? 1f : Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((elapsed - 0.1f) / 0.28f))); bool flag = State == BoneHubProjectionState.Stable; float num4 = ((reducedMotion || flag) ? 0f : (Mathf.Sin(elapsed * 16f) * 0.035f)); float num5 = Mathf.Max(0.007f, 0.013f * tabletScale); Vector3 val = Vector3.ProjectOnPlane(tablet.up, surfaceNormal); Vector3 normalized = ((Vector3)(ref val)).normalized; if (((Vector3)(ref normalized)).sqrMagnitude < 0.01f) { val = Vector3.ProjectOnPlane(tablet.right, surfaceNormal); normalized = ((Vector3)(ref val)).normalized; } Quaternion val2 = Quaternion.LookRotation(surfaceNormal, normalized); Vector3 val3 = emitterPosition + surfaceNormal * (0.0008f * tabletScale); ((Component)_emitterGlow).transform.SetPositionAndRotation(val3, val2); ((Component)_emitterGlow).transform.localScale = Vector3.one * num5 * (1.6f + num4); SetAlpha(_emitterGlow, (flag ? 0.16f : 0.32f) * num * brightness); ((Component)_emitterCore).transform.SetPositionAndRotation(val3 + surfaceNormal * (0.0004f * tabletScale), val2); ((Component)_emitterCore).transform.localScale = Vector3.one * num5 * (0.5f + num * 0.24f + num4); SetAlpha(_emitterCore, (flag ? 0.48f : 0.82f) * num * brightness); for (int i = 0; i < _rings.Length; i++) { Renderer val4 = _rings[i]; float num6 = ((i == 0) ? 1f : (-1f)); float num7 = (reducedMotion ? 0f : (elapsed * (13f + (float)i * 8f) * num6)); float num8 = num5 * (1.25f + (float)i * 0.54f) * (0.72f + num2 * 0.28f); ((Component)val4).transform.SetPositionAndRotation(val3 + surfaceNormal * (0.0006f * (float)(i + 1) * tabletScale), val2 * Quaternion.AngleAxis(num7, Vector3.forward)); ((Component)val4).transform.localScale = new Vector3(num8, num8, 1f); SetAlpha(val4, (flag ? (0.15f - (float)i * 0.025f) : (0.34f - (float)i * 0.05f)) * num2 * brightness); } ((Component)_ticks).transform.SetPositionAndRotation(val3 + surfaceNormal * (0.001f * tabletScale), val2); ((Component)_ticks).transform.localScale = Vector3.one * num5 * 2f * (0.75f + num2 * 0.25f); SetAlpha(_ticks, (flag ? 0.1f : 0.24f) * num2 * brightness); Vector3 val5 = tablet.position - tablet.forward * (0.009f * tabletScale); float num9 = 0.34f * tabletScale; float num10 = 0.2f * tabletScale; for (int j = 0; j < _tethers.Length; j++) { Vector3 val6 = val5 + tablet.right * (TetherOffsets[j] * num9) - tablet.up * (0.46f * num10); PlaceTether(_tethers[j], val3, val6, tablet, tabletScale, num3, (flag ? 0.018f : 0.07f) * brightness); Renderer val7 = _pulses[j]; bool flag2 = !reducedMotion && !flag && num3 > 0.05f; ((Component)val7).gameObject.SetActive(flag2); if (flag2) { float num11 = Mathf.Repeat(elapsed * 2.2f + (float)j * 0.27f, 1f); ((Component)val7).transform.SetPositionAndRotation(Vector3.Lerp(val3, val6, num11), tablet.rotation); ((Component)val7).transform.localScale = Vector3.one * (0.0026f * tabletScale); SetAlpha(val7, Mathf.Sin(num11 * (float)Math.PI) * 0.5f * brightness); } } bool flag3 = !reducedMotion && State == BoneHubProjectionState.Revealing; ((Component)_revealEdge).gameObject.SetActive(flag3); if (flag3) { ((Component)_revealEdge).transform.SetPositionAndRotation(val5 + tablet.right * Mathf.Lerp((0f - num9) * 0.49f, num9 * 0.49f, RevealProgress), tablet.rotation); ((Component)_revealEdge).transform.localScale = new Vector3(0.0012f * tabletScale, num10 * 0.9f, 1f); SetAlpha(_revealEdge, Mathf.Sin(RevealProgress * (float)Math.PI) * 0.78f * brightness); } } private void PlaceTether(Renderer tether, Vector3 start, Vector3 target, Transform tablet, float tabletScale, float reveal, float alpha) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0049: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target - start; float magnitude = ((Vector3)(ref val)).magnitude; if (!float.IsFinite(magnitude) || magnitude < 0.02f || reveal <= 0.01f) { ((Component)tether).gameObject.SetActive(false); return; } ((Component)tether).gameObject.SetActive(true); Vector3 val2 = val / magnitude; Vector3 val3 = Vector3.ProjectOnPlane(-tablet.forward, val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; if (((Vector3)(ref normalized)).sqrMagnitude < 0.01f) { val3 = Vector3.Cross(val2, tablet.right); normalized = ((Vector3)(ref val3)).normalized; } ((Component)tether).transform.SetPositionAndRotation(start, Quaternion.LookRotation(normalized, val2)); ((Component)tether).transform.localScale = new Vector3(0.001f * tabletScale, magnitude * reveal, 1f); SetAlpha(tether, alpha * reveal); } private void SetAllAlpha(float multiplier) { if ((Object)(object)_emitterGlow != (Object)null) { SetAlpha(_emitterGlow, 0.16f * multiplier); } if ((Object)(object)_emitterCore != (Object)null) { SetAlpha(_emitterCore, 0.48f * multiplier); } if ((Object)(object)_ticks != (Object)null) { SetAlpha(_ticks, 0.1f * multiplier); } Renderer[] rings = _rings; foreach (Renderer val in rings) { if ((Object)(object)val != (Object)null) { SetAlpha(val, 0.13f * multiplier); } } rings = _tethers; foreach (Renderer val2 in rings) { if ((Object)(object)val2 != (Object)null) { SetAlpha(val2, 0.018f * multiplier); } } rings = _pulses; foreach (Renderer val3 in rings) { if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(false); } } if ((Object)(object)_revealEdge != (Object)null) { ((Component)_revealEdge).gameObject.SetActive(false); } } private void EnsureBuilt() { //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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00ca: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown if ((Object)(object)_root != (Object)null || _disposing) { return; } try { Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Transparent") ?? Shader.Find("Legacy Shaders/Particles/Alpha Blended") ?? Shader.Find("Standard"); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("No compatible hologram shader was available."); } _material = new Material(val) { name = "WristHub Shared Clean Projection", renderQueue = 3100 }; Color val2 = default(Color); ((Color)(ref val2))..ctor(Cyan.r, Cyan.g, Cyan.b, 0.25f); if (_material.HasProperty("_Color")) { _material.SetColor("_Color", val2); } if (_material.HasProperty("_TintColor")) { _material.SetColor("_TintColor", val2); } if (_material.HasProperty("_Cull")) { _material.SetInt("_Cull", 0); } _root = new GameObject("[WristHub] Clean Projection"); Object.DontDestroyOnLoad((Object)(object)_root); _root.SetActive(false); Mesh mesh = Own(CreateSoftDiscMesh(40)); Mesh mesh2 = Own(CreateDiscMesh(32)); Mesh mesh3 = Own(CreateSegmentedRingMesh(36, 0.91f, 0.28f)); Mesh mesh4 = Own(CreateTickMesh(28)); Mesh mesh5 = Own(CreateLineMesh()); Mesh mesh6 = Own(CreateQuadMesh()); _emitterGlow = CreateRenderer("Soft Wrist Glow", mesh); _emitterCore = CreateRenderer("Emitter Core", mesh2); for (int i = 0; i < _rings.Length; i++) { _rings[i] = CreateRenderer("Energy Ring " + i, mesh3); } _ticks = CreateRenderer("Emitter Ticks", mesh4); for (int j = 0; j < _tethers.Length; j++) { _tethers[j] = CreateRenderer("Fine Light Tether " + j, mesh5); _pulses[j] = CreateRenderer("Traveling Light " + j, mesh); ((Component)_pulses[j]).gameObject.SetActive(false); } _revealEdge = CreateRenderer("Tablet Reveal Edge", mesh6); ((Component)_revealEdge).gameObject.SetActive(false); } catch (Exception ex) { if (!_loggedFailure) { _loggedFailure = true; _log.Warning("Clean wrist projection disabled: " + ex.Message); } Dispose(); } } private Mesh Own(Mesh mesh) { _ownedMeshes.Add(mesh); return mesh; } private Renderer CreateRenderer(string name, Mesh mesh) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || (Object)(object)_material == (Object)null) { throw new InvalidOperationException("Projection pool is unavailable."); } GameObject val = new GameObject(name); val.transform.SetParent(_root.transform, false); val.AddComponent().sharedMesh = mesh; MeshRenderer obj = val.AddComponent(); ((Renderer)obj).sharedMaterial = _material; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return (Renderer)(object)obj; } private void SetAlpha(Renderer renderer, float alpha) { //IL_0041: 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_0063: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(Cyan.r, Cyan.g, Cyan.b, Mathf.Clamp01(alpha)); _block.Clear(); _block.SetColor("_Color", val); _block.SetColor("_BaseColor", val); _block.SetColor("_TintColor", val); renderer.SetPropertyBlock(_block); } private static Vector3 SafeNormal(Vector3 value, Vector3 fallback) { //IL_0000: 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_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_0039: Unknown result type (might be due to invalid IL or missing references) if (!float.IsFinite(value.x) || !float.IsFinite(value.y) || !float.IsFinite(value.z) || !(((Vector3)(ref value)).sqrMagnitude > 0.001f)) { return fallback; } return ((Vector3)(ref value)).normalized; } private static float MaxAxis(Vector3 value) { //IL_0008: 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_0024: Unknown result type (might be due to invalid IL or missing references) return Mathf.Max(new float[3] { Mathf.Abs(value.x), Mathf.Abs(value.y), Mathf.Abs(value.z) }); } private static Mesh CreateSoftDiscMesh(int segments) { //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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[segments + 1]; Color[] array2 = (Color[])(object)new Color[segments + 1]; int[] array3 = new int[segments * 3]; array2[0] = Color.white; for (int i = 0; i < segments; i++) { float num = (float)i / (float)segments * (float)Math.PI * 2f; array[i + 1] = new Vector3(Mathf.Cos(num), Mathf.Sin(num), 0f); array2[i + 1] = new Color(1f, 1f, 1f, 0f); array3[i * 3] = 0; array3[i * 3 + 1] = i + 1; array3[i * 3 + 2] = (i + 1) % segments + 1; } Mesh obj = FinalizeMesh("WristHub Soft Glow", array, array3); obj.colors = Il2CppStructArray.op_Implicit(array2); return obj; } private static Mesh CreateDiscMesh(int segments) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3[] array = (Vector3[])(object)new Vector3[segments + 1]; int[] array2 = new int[segments * 3]; array[0] = Vector3.zero; for (int i = 0; i < segments; i++) { float num = (float)i / (float)segments * (float)Math.PI * 2f; array[i + 1] = new Vector3(Mathf.Cos(num), Mathf.Sin(num), 0f); array2[i * 3] = 0; array2[i * 3 + 1] = i + 1; array2[i * 3 + 2] = (i + 1) % segments + 1; } return FinalizeMesh("WristHub Emitter Core", array, array2); } private static Mesh CreateSegmentedRingMesh(int segments, float innerRatio, float gapRatio) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[segments * 4]; int[] array2 = new int[segments * 6]; Vector3 val = default(Vector3); Vector3 val2 = default(Vector3); for (int i = 0; i < segments; i++) { float num = ((float)i + gapRatio * 0.5f) / (float)segments * (float)Math.PI * 2f; float num2 = ((float)i + 1f - gapRatio * 0.5f) / (float)segments * (float)Math.PI * 2f; ((Vector3)(ref val))..ctor(Mathf.Cos(num), Mathf.Sin(num)); ((Vector3)(ref val2))..ctor(Mathf.Cos(num2), Mathf.Sin(num2)); int num3 = i * 4; array[num3] = val; array[num3 + 1] = val2; array[num3 + 2] = val2 * innerRatio; array[num3 + 3] = val * innerRatio; int num4 = i * 6; array2[num4] = num3; array2[num4 + 1] = num3 + 1; array2[num4 + 2] = num3 + 2; array2[num4 + 3] = num3; array2[num4 + 4] = num3 + 2; array2[num4 + 5] = num3 + 3; } return FinalizeMesh("WristHub Thin Segmented Ring", array, array2); } private static Mesh CreateTickMesh(int ticks) { //IL_0040: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00ba: 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_00c3: 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_00d7: 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_00e0: 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_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_00f8: 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_0101: 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_010a: 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) Vector3[] array = (Vector3[])(object)new Vector3[ticks * 4]; int[] array2 = new int[ticks * 6]; Vector3 val = default(Vector3); Vector3 val2 = default(Vector3); for (int i = 0; i < ticks; i++) { float num = (float)i / (float)ticks * (float)Math.PI * 2f; ((Vector3)(ref val))..ctor(Mathf.Cos(num), Mathf.Sin(num)); ((Vector3)(ref val2))..ctor(0f - val.y, val.x); float num2 = ((i % 4 == 0) ? 1.08f : 1.03f); float num3 = ((i % 4 == 0) ? 0.9f : 0.95f); float num4 = ((i % 4 == 0) ? 0.01f : 0.006f); int num5 = i * 4; array[num5] = val * num2 + val2 * num4; array[num5 + 1] = val * num2 - val2 * num4; array[num5 + 2] = val * num3 - val2 * num4; array[num5 + 3] = val * num3 + val2 * num4; int num6 = i * 6; array2[num6] = num5; array2[num6 + 1] = num5 + 1; array2[num6 + 2] = num5 + 2; array2[num6 + 3] = num5; array2[num6 + 4] = num5 + 2; array2[num6 + 5] = num5 + 3; } return FinalizeMesh("WristHub Restrained Ticks", array, array2); } private static Mesh CreateLineMesh() { //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_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_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_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) return FinalizeMesh("WristHub Fine Tether", (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, 0f), new Vector3(0.5f, 0f), new Vector3(0.5f, 1f), new Vector3(-0.5f, 1f) }, new int[6] { 0, 1, 2, 0, 2, 3 }); } private static Mesh CreateQuadMesh() { //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_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_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_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) return FinalizeMesh("WristHub Reveal Edge", (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, -0.5f), new Vector3(0.5f, -0.5f), new Vector3(0.5f, 0.5f), new Vector3(-0.5f, 0.5f) }, new int[6] { 0, 1, 2, 0, 2, 3 }); } private static Mesh FinalizeMesh(string name, Vector3[] vertices, int[] triangles) { //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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown int[] array = new int[triangles.Length * 2]; Array.Copy(triangles, array, triangles.Length); for (int i = 0; i < triangles.Length; i += 3) { int num = triangles.Length + i; array[num] = triangles[i]; array[num + 1] = triangles[i + 2]; array[num + 2] = triangles[i + 1]; } Mesh val = new Mesh { name = name, vertices = Il2CppStructArray.op_Implicit(vertices), triangles = Il2CppStructArray.op_Implicit(array) }; val.RecalculateBounds(); return val; } } internal readonly record struct BoneHubForearmProjectionAnchor(bool IsLeft, Transform Source, Vector3 EmitterPosition, Vector3 SurfaceNormal, Vector3 ArmDirection, bool UsesForearm); internal sealed class BoneHubForearmProjectionAnchorProvider { private Transform? _leftForearm; private Transform? _leftHandBone; private Transform? _rightForearm; private Transform? _rightHandBone; private int _rigId; private int _leftHandId; private int _rightHandId; private int _animatorId; private Animator? _animator; private float _nextResolveAt; public bool TryGet(bool left, float heightRatio, out BoneHubForearmProjectionAnchor anchor) { //IL_00e1: 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) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0147: 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_011d: 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_012f: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_0199: 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_01b9: 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_01c5: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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) anchor = default(BoneHubForearmProjectionAnchor); RefreshIdentity(); if (Time.unscaledTime >= _nextResolveAt || (Object)(object)_animator == (Object)null || (left ? ((Object)(object)_leftForearm == (Object)null) : ((Object)(object)_rightForearm == (Object)null))) { ResolveBones(); } Transform val = (left ? _leftForearm : _rightForearm); Transform val2 = (left ? _leftHandBone : _rightHandBone); Hand obj = (left ? Player.LeftHand : Player.RightHand); Transform val3 = ((obj != null) ? ((Component)obj).transform : null); Transform val4 = (((Object)(object)val != (Object)null) ? val : (((Object)(object)val2 != (Object)null) ? val2 : val3)); if ((Object)(object)val4 == (Object)null) { return false; } float num = Mathf.Max(0.05f, heightRatio); bool flag = (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null; Vector3 val5; Vector3 val6; if (!flag) { val5 = val4.forward; } else { val6 = val2.position - val.position; val5 = ((Vector3)(ref val6)).normalized; } Vector3 val7 = val5; if (((Vector3)(ref val7)).sqrMagnitude < 0.01f) { val7 = val4.forward; } Vector3 val8 = (flag ? Vector3.Lerp(val.position, val2.position, 0.83f) : (val4.position - val4.forward * (0.025f * num))); Vector3 val9 = (((Object)(object)Player.Head == (Object)null) ? val4.up : (Player.Head.position - val8)); val6 = Vector3.ProjectOnPlane(val9, val7); Vector3 val10 = ((Vector3)(ref val6)).normalized; if (((Vector3)(ref val10)).sqrMagnitude < 0.01f) { val10 = val4.up; } if (Vector3.Dot(val10, val9) < 0f) { val10 = -val10; } Vector3 emitterPosition = val8 + val10 * (0.012f * num); anchor = new BoneHubForearmProjectionAnchor(left, val4, emitterPosition, val10, val7, flag); return true; } public void Invalidate() { _leftForearm = null; _leftHandBone = null; _rightForearm = null; _rightHandBone = null; _rigId = 0; _leftHandId = 0; _rightHandId = 0; _animatorId = 0; _animator = null; _nextResolveAt = 0f; } private void RefreshIdentity() { int num = SafeId((Object?)(object)Player.RigManager); int num2 = SafeId((Object?)(object)Player.LeftHand); int num3 = SafeId((Object?)(object)Player.RightHand); if (num != _rigId || num2 != _leftHandId || num3 != _rightHandId) { Invalidate(); _rigId = num; _leftHandId = num2; _rightHandId = num3; } } private void ResolveBones() { _nextResolveAt = Time.unscaledTime + 1f; try { Animator val = FindAnimator(); if (!((Object)(object)val == (Object)null)) { _animator = val; _animatorId = SafeId((Object?)(object)val); _leftForearm = val.GetBoneTransform((HumanBodyBones)15); _leftHandBone = val.GetBoneTransform((HumanBodyBones)17); _rightForearm = val.GetBoneTransform((HumanBodyBones)16); _rightHandBone = val.GetBoneTransform((HumanBodyBones)18); } } catch { _leftForearm = null; _leftHandBone = null; _rightForearm = null; _rightHandBone = null; _nextResolveAt = Time.unscaledTime + 1f; } } private static int SafeId(Object? value) { try { return (!(value == (Object)null)) ? value.GetInstanceID() : 0; } catch { return 0; } } private static Animator? FindAnimator() { try { RigManager rigManager = Player.RigManager; return (rigManager != null) ? ((IEnumerable)((Component)rigManager).GetComponentsInChildren(true)).FirstOrDefault((Func)((Animator candidate) => (Object)(object)candidate != (Object)null && candidate.isHuman && (Object)(object)candidate.GetBoneTransform((HumanBodyBones)15) != (Object)null)) : null; } catch { return null; } } } public sealed class BoneHubMod : MelonMod { private sealed class PendingFusionAnnouncement { public BoneHubAvatar Avatar { get; } public ModIoSharingMetadata Sharing { get; } public double NextPollAt { get; set; } public double NextRefreshAt { get; set; } public double AvatarMismatchSince { get; set; } = -1.0; public double WaitingSince { get; } public bool WaitingReported { get; set; } public bool NetworkerMissingReported { get; set; } public PendingFusionAnnouncement(BoneHubAvatar avatar, ModIoSharingMetadata sharing, double waitingSince) { Avatar = avatar; Sharing = sharing; WaitingSince = waitingSince; } } private readonly ConcurrentQueue _mainThread = new ConcurrentQueue(); private readonly ErrorLogThrottle _uiErrorThrottle = new ErrorLogThrottle(); private BoneHubService? _service; private BoneHubMenu? _menu; private BoneHubWristWatch? _watch; private BoneHubRuntime? _runtime; private BoneHubAvatarBrowser? _browser; private BoneHubThumbnailCache? _thumbnails; private LobbyAvatarSharingBridge? _sharing; private PendingFusionAnnouncement? _pendingFusionAnnouncement; public override void OnInitializeMelon() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown try { BoneHubOptions val = CreateOptions(); ModIoClient val2 = new ModIoClient(val, (HttpClient)null); DownloadManager val3 = new DownloadManager((IModIoClient)(object)val2, new SafeModInstaller(val), val); _service = new BoneHubService((IModIoClient)(object)val2, val3, val); _service.DownloadChanged += delegate(DownloadJob job) { _mainThread.Enqueue(delegate { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 _menu?.OnDownloadChanged(job); _watch?.OnDownloadChanged(job); _browser?.OnDownloadChanged(job); if ((int)job.State == 5 && job.Result != null) { _runtime?.LoadInstallation(job.Result); _sharing?.RequestRefresh(immediate: true); ModIoSharingMetadata sharing = job.Result.Sharing; if (!string.IsNullOrWhiteSpace((sharing != null) ? sharing.Warning : null)) { ((MelonBase)this).LoggerInstance.Msg("Warning: " + job.Result.Sharing.Warning); } } }); }; _service.InstalledChanged += delegate { _mainThread.Enqueue(delegate { _runtime?.SetPendingDeletions(_service.PendingDeletionModIds); _runtime?.RegisterInstalled(_service.Installed); _browser?.Refresh(); _menu?.OnInstalledChanged(); }); }; _service.InitializeAsync(default(CancellationToken)).GetAwaiter().GetResult(); PendingDeletionProcessResult result = _service.ProcessPendingDeletionsAsync(default(CancellationToken)).GetAwaiter().GetResult(); if (result.Completed > 0) { ((MelonBase)this).LoggerInstance.Msg($"Finished {result.Completed} queued avatar-pack deletion{((result.Completed == 1) ? string.Empty : "s")} before Asset Warehouse startup."); } if (result.Remaining > 0) { ((MelonBase)this).LoggerInstance.Warning($"{result.Remaining} queued avatar-pack deletion{((result.Remaining == 1) ? string.Empty : "s")} could not finish yet: " + string.Join("; ", result.Problems.Take(3))); } BoneHubTheme.Initialize(((MelonBase)this).LoggerInstance); _sharing = new LobbyAvatarSharingBridge(((MelonBase)this).LoggerInstance); _runtime = new BoneHubRuntime(_mainThread, val.ModsDirectory, ((MelonBase)this).LoggerInstance); _runtime.RequestAvatarRestore(_service.LastEquippedAvatarBarcode); _thumbnails = new BoneHubThumbnailCache(Path.Combine(val.DataDirectory, "cache", "thumbnails"), _mainThread, ((MelonBase)this).LoggerInstance); _browser = new BoneHubAvatarBrowser(_service, _runtime, _thumbnails, _mainThread, _service.Preferences, val.ConstrainedRendering, ((MelonBase)this).LoggerInstance, _sharing); _watch = new BoneHubWristWatch(_browser.OpenLauncher, () => _browser.IsLauncherOpen, _service.Preferences, ((MelonBase)this).LoggerInstance); _browser.Closed += _watch.RequireLookAway; _runtime.SetPendingDeletions(_service.PendingDeletionModIds); _runtime.RegisterInstalled(_service.Installed); _runtime.AvatarsChanged += delegate(long modId, IReadOnlyList avatars) { _browser?.OnAvatarsChanged(modId, avatars); _menu?.OnAvatarsChanged(modId, avatars); }; _runtime.EquipFinished += delegate(BoneHubAvatar avatar, bool success, string? error) { _menu?.OnEquipFinished(avatar, success, error); if (!success) { if (_pendingFusionAnnouncement != null && string.Equals(_pendingFusionAnnouncement.Avatar.Barcode, avatar.Barcode, StringComparison.OrdinalIgnoreCase)) { _pendingFusionAnnouncement = null; } } else { InstalledModRecord? obj = ((IEnumerable)_service.Installed).FirstOrDefault((Func)((InstalledModRecord item) => item.ModId == avatar.ModId)); ModIoSharingMetadata sharing = ((obj != null) ? obj.Sharing : null); BeginFusionAnnouncement(avatar, sharing); Task.Run(async delegate { await _service.MarkAvatarEquippedAsync(avatar.Barcode, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { _browser?.Refresh(); }); }); } }; _runtime.StatusChanged += delegate(string status) { _watch?.SetStatus(status); _menu?.OnRuntimeStatusChanged(status); _browser?.OnRuntimeStatusChanged(status); }; _menu = new BoneHubMenu(_service, _mainThread, _watch, _runtime, _browser, _thumbnails, val.PlatformDisplayName, ((MelonBase)this).LoggerInstance, _sharing); _menu.Create(); _sharing.RequestRefresh(immediate: true); Task.Run(async delegate { int repaired = await _service.RepairSharingRegistrationsAsync(default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); if (repaired > 0) { _mainThread.Enqueue(delegate { _sharing?.RequestRefresh(immediate: true); ((MelonBase)this).LoggerInstance.Msg($"Repaired Fusion sharing registration for {repaired} WristHub download{((repaired == 1) ? string.Empty : "s")}."); }); } }); ((MelonBase)this).LoggerInstance.Msg("WristHub 2.0.1 BETA initialized for " + val.PlatformDisplayName + ". Look at the wrist reactor for 1.5 seconds, then touch PUSH ME."); } catch (Exception value) { ((MelonBase)this).LoggerInstance.Error($"WristHub could not initialize: {value}"); } } public override void OnUpdate() { for (int i = 0; i < 32; i++) { if (!_mainThread.TryDequeue(out Action result)) { break; } try { result(); } catch (Exception ex) { string text = ex.GetType().FullName + "|" + ex.StackTrace?.Split('\n').FirstOrDefault(); if (_uiErrorThrottle.ShouldLog(text, (double)Environment.TickCount64 / 1000.0, 5.0)) { ((MelonBase)this).LoggerInstance.Error($"WristHub UI action failed (repeated copies are suppressed): {ex}"); } } } _watch?.Tick(); _menu?.Tick(); _runtime?.Tick(); TickFusionAnnouncement(); _browser?.Tick(); _browser?.LateTick(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { _runtime?.OnSceneChanged(); _browser?.OnSceneChanged(); _watch?.Recenter(); if (_pendingFusionAnnouncement != null) { _pendingFusionAnnouncement.NextPollAt = 0.0; _pendingFusionAnnouncement.NextRefreshAt = 0.0; _pendingFusionAnnouncement.AvatarMismatchSince = -1.0; } } public override void OnDeinitializeMelon() { _pendingFusionAnnouncement = null; _browser?.Dispose(); _watch?.Dispose(); _menu?.Dispose(); _runtime?.Dispose(); BoneHubService? service = _service; if (service != null) { service.Dispose(); } } private void BeginFusionAnnouncement(BoneHubAvatar avatar, ModIoSharingMetadata? sharing) { _pendingFusionAnnouncement = null; if (sharing != null && sharing.PalletBarcodes.Count > 0 && sharing.ModId > 0 && _sharing != null && _runtime != null) { double num = (double)Environment.TickCount64 / 1000.0; _pendingFusionAnnouncement = new PendingFusionAnnouncement(avatar, sharing, num) { NextPollAt = 0.0, NextRefreshAt = num + 5.0 }; if (!_sharing.IsRegistered(sharing.PalletBarcodes, sharing.ModId) && !_sharing.RegistrationRefreshBusy) { _sharing.RequestRefresh(immediate: true); } if (_runtime.FusionSessionActive) { _runtime.ReportSharingStatus("Equipped " + avatar.Title + " - multiplayer sharing preparing."); } } } private void TickFusionAnnouncement() { PendingFusionAnnouncement pendingFusionAnnouncement = _pendingFusionAnnouncement; if (pendingFusionAnnouncement == null || _sharing == null || _runtime == null) { return; } double num = (double)Environment.TickCount64 / 1000.0; if (!_runtime.IsCurrentAvatar(pendingFusionAnnouncement.Avatar.Barcode)) { if (pendingFusionAnnouncement.AvatarMismatchSince < 0.0) { pendingFusionAnnouncement.AvatarMismatchSince = num; } if (num - pendingFusionAnnouncement.AvatarMismatchSince >= 12.0) { _pendingFusionAnnouncement = null; } return; } pendingFusionAnnouncement.AvatarMismatchSince = -1.0; if (!_runtime.FusionSessionActive || num < pendingFusionAnnouncement.NextPollAt) { return; } pendingFusionAnnouncement.NextPollAt = num + 0.5; if (!_sharing.Available) { if (!pendingFusionAnnouncement.NetworkerMissingReported) { pendingFusionAnnouncement.NetworkerMissingReported = true; _runtime.ReportSharingStatus("Equipped locally - ModioModNetworker is required for peer downloads."); } } else if (!_sharing.IsRegistered(pendingFusionAnnouncement.Sharing.PalletBarcodes, pendingFusionAnnouncement.Sharing.ModId)) { if (num >= pendingFusionAnnouncement.NextRefreshAt && !_sharing.RegistrationRefreshBusy) { _sharing.RequestRefresh(immediate: true); pendingFusionAnnouncement.NextRefreshAt = num + 5.0; } if (!pendingFusionAnnouncement.WaitingReported && num - pendingFusionAnnouncement.WaitingSince >= 30.0) { pendingFusionAnnouncement.WaitingReported = true; _runtime.ReportSharingStatus("Equipped locally - multiplayer sharing is still preparing."); ((MelonBase)this).LoggerInstance.Msg("WristHub is still waiting for Fusion and ModioModNetworker registration; background retry remains active."); } } else { if (!_sharing.LobbyReadyToAnnounce) { return; } if (_sharing.IsLocalAvatarAnnounced(pendingFusionAnnouncement.Sharing.ModId)) { _runtime.ReportSharingStatus("Equipped " + pendingFusionAnnouncement.Avatar.Title + " - multiplayer sharing ready."); ((MelonBase)this).LoggerInstance.Msg("Fusion recorded the equipped WristHub avatar through its normal sender."); _pendingFusionAnnouncement = null; return; } if (_runtime.ResendCurrentAvatarToFusion(pendingFusionAnnouncement.Avatar.Barcode, out string error)) { _runtime.ReportSharingStatus("Equipped " + pendingFusionAnnouncement.Avatar.Title + " - shared with the Fusion lobby."); ((MelonBase)this).LoggerInstance.Msg("WristHub re-announced the equipped avatar once through Fusion's official sender after Networker registration completed."); } else { _runtime.ReportSharingStatus("Equipped locally - multiplayer sharing could not finish: " + error); ((MelonBase)this).LoggerInstance.Msg("Warning: Fusion avatar re-announcement was unavailable: " + error); } _pendingFusionAnnouncement = null; } } private static BoneHubOptions CreateOptions() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00d0: 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_00fa: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown BoneHubPlatformProfile val = BoneHubPlatformProfile.Detect((int)Application.platform == 11); string text = Application.persistentDataPath; if (string.IsNullOrWhiteSpace(text)) { string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); text = Path.Combine(folderPath, "AppData", "LocalLow", "Stress Level Zero", "BONELAB"); } string text2 = Path.Combine(MelonEnvironment.UserDataDirectory, "WristHub"); string text3 = Path.Combine(MelonEnvironment.UserDataDirectory, "BoneHub"); if (!TryMigrateLegacyData(text3, text2)) { text2 = text3; } Directory.CreateDirectory(text2); string text4 = Environment.GetEnvironmentVariable("WRISTHUB_MODIO_API_KEY") ?? Environment.GetEnvironmentVariable("BONEHUB_MODIO_API_KEY") ?? ReadApiKeyFile(text2); BoneHubOptions val2 = new BoneHubOptions { ApiKey = text4.Trim() }; val2.set_ApiKeyFilePath(Path.Combine(text2, "modio-api-key.txt")); val2.set_HostedServiceBaseUrl(Environment.GetEnvironmentVariable("WRISTHUB_SERVICE_URL") ?? "https://wristhub-api.wristhub.workers.dev/v1"); val2.set_ModsDirectory(Path.Combine(text, "Mods")); val2.set_DataDirectory(text2); val2.set_TargetPlatform(val.ModIoHeader); val2.set_CompatiblePlatforms(val.CompatibleModIoPlatforms); val2.set_PlatformDisplayName(val.DisplayName); val2.set_MaximumDownloadBytes(val.MaximumDownloadBytes); val2.set_MaximumExtractedBytes(val.MaximumExtractedBytes); val2.set_ConstrainedRendering(val.ConstrainedRendering); return val2; } private static string ReadApiKeyFile(string dataDirectory) { string path = Path.Combine(dataDirectory, "modio-api-key.txt"); if (File.Exists(path)) { string text = File.ReadAllText(path).Trim(); if (!BoneHubOptions.IsValidApiKey(text)) { return string.Empty; } return text; } File.WriteAllText(path, "PASTE_YOUR_32_CHARACTER_MOD_IO_API_KEY_HERE"); return string.Empty; } private static bool TryMigrateLegacyData(string legacyDirectory, string targetDirectory) { if (!Directory.Exists(legacyDirectory)) { return true; } try { Directory.CreateDirectory(targetDirectory); foreach (string item in Directory.EnumerateFiles(legacyDirectory, "*", SearchOption.AllDirectories)) { string relativePath = Path.GetRelativePath(legacyDirectory, item); string text = Path.Combine(targetDirectory, relativePath); string directoryName = Path.GetDirectoryName(text); if (!string.IsNullOrWhiteSpace(directoryName)) { Directory.CreateDirectory(directoryName); } if (!File.Exists(text)) { File.Copy(item, text, overwrite: false); } } return !File.Exists(Path.Combine(legacyDirectory, "state.json")) || File.Exists(Path.Combine(targetDirectory, "state.json")); } catch { return false; } } } internal sealed class BoneHubMenu : IDisposable { private readonly BoneHubService _service; private readonly ConcurrentQueue _mainThread; private readonly BoneHubWristWatch _watch; private readonly BoneHubRuntime _runtime; private readonly BoneHubAvatarBrowser _browser; private readonly string _platformName; private readonly Instance _log; private readonly BoneHubThumbnailCache _thumbnails; private readonly LobbyAvatarSharingBridge _sharing; private Page? _root; private Page? _home; private Page? _discover; private Page? _setup; private Page? _results; private Page? _downloads; private Page? _installed; private Page? _favorites; private Page? _updates; private readonly Dictionary _jobs = new Dictionary(); private readonly List _jobOrder = new List(); private readonly List _installedDetailPages = new List(); private readonly Dictionary _maintenanceStatus = new Dictionary(); private readonly HashSet _projectAfterInstall = new HashSet(); private IReadOnlyList _availableUpdates = Array.Empty(); private string _runtimeStatus = "Asset Warehouse initializing"; private string _query = string.Empty; private string _creator = string.Empty; private bool _avatarsOnly = true; private ModSort _sort; private ModSearchRequest? _lastSearch; public BoneHubMenu(BoneHubService service, ConcurrentQueue mainThread, BoneHubWristWatch watch, BoneHubRuntime runtime, BoneHubAvatarBrowser browser, BoneHubThumbnailCache thumbnails, string platformName, Instance log, LobbyAvatarSharingBridge? sharing = null) { _service = service; _mainThread = mainThread; _watch = watch; _runtime = runtime; _browser = browser; _platformName = platformName; _log = log; _thumbnails = thumbnails; _sharing = sharing ?? new LobbyAvatarSharingBridge(log); } public void Open() { if (!_service.ModIoReady && _setup != null) { Menu.OpenPage(_setup); } else if (_home != null) { Menu.OpenPage(_home); } else if (_root != null) { Menu.OpenPage(_root); } } public void OpenDiscover() { _browser.OpenSearch(); } public void OpenInstalled() { _browser.Open(); } public void OpenDownloads() { RebuildDownloads(); if (_downloads != null) { Menu.OpenPage(_downloads); } } public void Create() { //IL_001f: 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_0082: 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_00e5: 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_0150: 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_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0266: 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_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_033c: 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) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06fa: Unknown result type (might be due to invalid IL or missing references) //IL_073b: Unknown result type (might be due to invalid IL or missing references) //IL_077c: Unknown result type (might be due to invalid IL or missing references) //IL_07a9: Unknown result type (might be due to invalid IL or missing references) //IL_07d5: Unknown result type (might be due to invalid IL or missing references) //IL_080f: Unknown result type (might be due to invalid IL or missing references) //IL_083b: Unknown result type (might be due to invalid IL or missing references) //IL_0872: Unknown result type (might be due to invalid IL or missing references) //IL_08a9: Unknown result type (might be due to invalid IL or missing references) //IL_08e0: Unknown result type (might be due to invalid IL or missing references) //IL_0926: Unknown result type (might be due to invalid IL or missing references) //IL_096c: Unknown result type (might be due to invalid IL or missing references) //IL_09b2: Unknown result type (might be due to invalid IL or missing references) //IL_09f3: Unknown result type (might be due to invalid IL or missing references) CreateSimpleMenu(); if (_root != null) { return; } _root = BoneHubTheme.Style(Page.Root.CreatePage(BoneHubTheme.Brand("WristHub // Holo Link"), BoneHubTheme.Cyan, 0, true), showLogo: true, 0.91f); _home = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("◈", "Home"), BoneHubTheme.Cyan, 0, true), showLogo: true); Page val = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("⚙", "Settings"), BoneHubTheme.Violet, 0, true)); _setup = BoneHubTheme.Style(val.CreatePage(BoneHubTheme.PageTitle("◇", "mod.io Setup"), BoneHubTheme.Amber, 0, true)); RebuildSetup(); _discover = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("⌕", "Search"), BoneHubTheme.Cyan, 0, true)); _discover.CreateFunction(BoneHubTheme.Brand("Find a BONELAB avatar"), Color.white, (Action)delegate { }); _discover.CreateString(BoneHubTheme.Label("Name", "Type an avatar name"), BoneHubTheme.Cyan, _query, (Action)delegate(string value) { _query = value?.Trim() ?? string.Empty; }); _discover.CreateString(BoneHubTheme.Label("Creator", "Optional"), BoneHubTheme.Blue, _creator, (Action)delegate(string value) { _creator = value?.Trim() ?? string.Empty; }); _discover.CreateBool(BoneHubTheme.Label("Avatars only", "Recommended"), BoneHubTheme.Blue, _avatarsOnly, (Action)delegate(bool value) { _avatarsOnly = value; }); _discover.CreateEnum(BoneHubTheme.Label("Sort", "Choose order"), BoneHubTheme.Violet, (Enum)(object)_sort, (Action)delegate(Enum value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) _sort = (ModSort)(object)value; }); _discover.CreateFunction(BoneHubTheme.PrimaryAction("Search avatars"), BoneHubTheme.Cyan, (Action)RunSearch); _discover.CreateFunction(BoneHubTheme.SecondaryAction("View trending"), BoneHubTheme.Blue, (Action)delegate { //IL_000d: Unknown result type (might be due to invalid IL or missing references) _query = string.Empty; _sort = (ModSort)0; RunSearch(); }); _discover.CreateFunction(BoneHubTheme.SecondaryAction("Browse new releases"), BoneHubTheme.Violet, (Action)delegate { //IL_000d: Unknown result type (might be due to invalid IL or missing references) _query = string.Empty; _sort = (ModSort)1; RunSearch(); }); _results = BoneHubTheme.Style(_discover.CreatePage(BoneHubTheme.PageTitle("◫", "Results"), BoneHubTheme.Blue, 0, true)); _results.CreateFunction(BoneHubTheme.Status("Ready to search", "7891A7"), BoneHubTheme.Muted, (Action)delegate { }); _downloads = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("↓", "Downloads"), BoneHubTheme.Cyan, 0, true)); RebuildDownloads(); _installed = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("✓", "My Avatars"), BoneHubTheme.Green, 0, true)); RebuildInstalled(); _updates = BoneHubTheme.Style(_installed.CreatePage(BoneHubTheme.PageTitle("↻", "Updates"), BoneHubTheme.Blue, 0, true)); RebuildUpdateCenter(); _favorites = BoneHubTheme.Style(_discover.CreatePage(BoneHubTheme.PageTitle("★", "Saved"), BoneHubTheme.Amber, 0, true)); RebuildFavoritesLoading(); LoadFavorites(); val.CreateFunction(BoneHubTheme.Brand("Simple controls"), Color.white, (Action)delegate { }); val.CreateFunction(BoneHubTheme.Status(_service.ModIoReady ? "mod.io connected" : "mod.io setup required", _service.ModIoReady ? "59E6A7" : "FFC970"), _service.ModIoReady ? BoneHubTheme.Green : BoneHubTheme.Amber, (Action)delegate { if (_setup != null) { Menu.OpenPage(_setup); } }); val.CreateFunction(BoneHubTheme.Label("Platform", _platformName), BoneHubTheme.Blue, (Action)delegate { }); val.CreateFunction(BoneHubTheme.Label("Cache", "30 min · offline fallback"), BoneHubTheme.Cyan, (Action)delegate { }); val.CreateFunction(BoneHubTheme.Label("Installer", "Verified safe mode"), BoneHubTheme.Green, (Action)delegate { }); val.CreateFunction(BoneHubTheme.Label("Fusion", _runtime.FusionStatus), BoneHubTheme.Green, (Action)delegate { }); val.CreateFunction(BoneHubTheme.Label("Performance", "Tablet previews use no Marrow grips"), BoneHubTheme.Blue, (Action)delegate { }); val.CreateEnum(BoneHubTheme.Label("Comfort preset", "Apply a complete layout preset"), BoneHubTheme.Violet, (Enum)(object)_service.Preferences.ComfortPreset, (Action)delegate(Enum value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ApplyComfortPreset((BoneHubComfortPreset)(object)value); }); val.CreateBool(BoneHubTheme.Label("Wrist watch", "Enabled"), BoneHubTheme.Cyan, _watch.Enabled, (Action)delegate(bool value) { _watch.Enabled = value; SavePreferences(); }); val.CreateBool(BoneHubTheme.Label("Gesture", "Raise + look to open"), BoneHubTheme.Blue, _watch.RaiseToOpen, (Action)delegate(bool value) { _watch.RaiseToOpen = value; SavePreferences(); }); val.CreateBool(BoneHubTheme.Label("Wrist", "Use left hand"), BoneHubTheme.Cyan, _watch.UseLeftWrist, (Action)delegate(bool value) { _watch.UseLeftWrist = value; SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Watch size", "Scale"), BoneHubTheme.Blue, _watch.WatchScale, 0.05f, 0.65f, 1.6f, (Action)delegate(float value) { _watch.WatchScale = value; SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Gaze hold", "1.5 seconds"), BoneHubTheme.Violet, _watch.DwellSeconds, 0.25f, 1.5f, 1.5f, (Action)delegate(float value) { _watch.DwellSeconds = value; SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Wrist height", "Outward offset"), BoneHubTheme.Cyan, _watch.OutwardOffset, 0.002f, 0.015f, 0.06f, (Action)delegate(float value) { _watch.OutwardOffset = value; SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Wrist position", "Finger offset"), BoneHubTheme.Blue, _watch.FingerOffset, 0.002f, -0.055f, 0.025f, (Action)delegate(float value) { _watch.FingerOffset = value; SavePreferences(); }); val.CreateBool(BoneHubTheme.Label("Motion", "Reduced"), BoneHubTheme.Violet, _watch.ReducedMotion, (Action)delegate(bool value) { _watch.ReducedMotion = value; _browser.Refresh(); SavePreferences(); }); val.CreateFunction(BoneHubTheme.SecondaryAction("Recenter wrist watch"), BoneHubTheme.Cyan, (Action)_watch.Recenter); val.CreateFunction(BoneHubTheme.Label("Instant equip", "Patch 6 guarded runtime"), BoneHubTheme.Green, (Action)delegate { }); val.CreateFunction(BoneHubTheme.Label("Avatar Browser", "Safe grip or pinch controls"), BoneHubTheme.Cyan, (Action)_browser.Open); val.CreateBool(BoneHubTheme.Label("Hologram effects", "Scan lines and energy rings"), BoneHubTheme.Cyan, _service.Preferences.HologramEffects, (Action)delegate(bool value) { _service.Preferences.HologramEffects = value; _browser.Refresh(); SavePreferences(); }); val.CreateBool(BoneHubTheme.Label("Controller feedback", "Haptics"), BoneHubTheme.Blue, _service.Preferences.HapticsEnabled, (Action)delegate(bool value) { _service.Preferences.HapticsEnabled = value; SavePreferences(); }); val.CreateBool(BoneHubTheme.Label("Wardrobe audio", "Spatial UI sounds"), BoneHubTheme.Violet, _service.Preferences.SoundsEnabled, (Action)delegate(bool value) { _service.Preferences.SoundsEnabled = value; SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Projection distance", "Meters from headset"), BoneHubTheme.Cyan, _service.Preferences.CarouselDistance, 0.05f, 0.45f, 0.95f, (Action)delegate(float value) { _service.Preferences.CarouselDistance = value; _browser.Refresh(); SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Projection size", "Avatar and rack scale"), BoneHubTheme.Blue, _service.Preferences.HologramScale, 0.05f, 0.7f, 1.4f, (Action)delegate(float value) { _service.Preferences.HologramScale = value; _browser.Refresh(); SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Equip zone", "Chest target size"), BoneHubTheme.Violet, _service.Preferences.EquipZoneScale, 0.05f, 0.7f, 1.6f, (Action)delegate(float value) { _service.Preferences.EquipZoneScale = value; _browser.Refresh(); SavePreferences(); }); val.CreateFloat(BoneHubTheme.Label("Hologram glow", "Brightness"), BoneHubTheme.Cyan, _service.Preferences.HologramBrightness, 0.05f, 0.35f, 1.5f, (Action)delegate(float value) { _service.Preferences.HologramBrightness = value; _browser.Refresh(); SavePreferences(); }); val.CreateFunction(BoneHubTheme.SecondaryAction("Reset hologram comfort settings"), BoneHubTheme.Muted, (Action)ResetHologramPreferences); RebuildHome(); } private void CreateSimpleMenu() { //IL_0010: 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_0069: 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_00c7: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0220: 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_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: 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_032b: Unknown result type (might be due to invalid IL or missing references) _root = BoneHubTheme.Style(Page.Root.CreatePage(BoneHubTheme.Brand("WristHub // Avatar Browser"), BoneHubTheme.Cyan, 0, true), showLogo: true, 0.91f); _root.CreateFunction(BoneHubTheme.PrimaryAction("Open Avatar Browser"), BoneHubTheme.Cyan, (Action)delegate { _browser.Open(); }); _downloads = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("↓", "Downloads"), BoneHubTheme.Blue, 0, true)); RebuildDownloads(); Page obj = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("⚙", "Settings"), BoneHubTheme.Violet, 0, true)); obj.CreateBool(BoneHubTheme.Label("Wrist launcher", "Enabled"), BoneHubTheme.Cyan, _watch.Enabled, (Action)delegate(bool value) { _watch.Enabled = value; SavePreferences(); }); obj.CreateBool(BoneHubTheme.Label("Activation", "Look at wrist for 1.5 seconds"), BoneHubTheme.Blue, _watch.RaiseToOpen, (Action)delegate(bool value) { _watch.RaiseToOpen = value; SavePreferences(); }); obj.CreateBool(BoneHubTheme.Label("Wrist side", "Use left wrist"), BoneHubTheme.Cyan, _watch.UseLeftWrist, (Action)delegate(bool value) { _watch.UseLeftWrist = value; SavePreferences(); }); obj.CreateFloat(BoneHubTheme.Label("UI scale", "Wrist and browser"), BoneHubTheme.Blue, _watch.WatchScale, 0.05f, 0.65f, 1.6f, (Action)delegate(float value) { _watch.WatchScale = value; SavePreferences(); }); obj.CreateFloat(BoneHubTheme.Label("Wrist height", "Outward offset"), BoneHubTheme.Cyan, _watch.OutwardOffset, 0.002f, 0.015f, 0.06f, (Action)delegate(float value) { _watch.OutwardOffset = value; SavePreferences(); }); obj.CreateFloat(BoneHubTheme.Label("Wrist position", "Finger offset"), BoneHubTheme.Blue, _watch.FingerOffset, 0.002f, -0.055f, 0.025f, (Action)delegate(float value) { _watch.FingerOffset = value; SavePreferences(); }); obj.CreateBool(BoneHubTheme.Label("Reduced motion", "Simpler transitions"), BoneHubTheme.Violet, _watch.ReducedMotion, (Action)delegate(bool value) { _watch.ReducedMotion = value; SavePreferences(); }); obj.CreateBool(BoneHubTheme.Label("Touch haptics", "One pulse per press"), BoneHubTheme.Blue, _service.Preferences.HapticsEnabled, (Action)delegate(bool value) { _service.Preferences.HapticsEnabled = value; SavePreferences(); }); obj.CreateFloat(BoneHubTheme.Label("Equip zone", "Chest target size"), BoneHubTheme.Cyan, _service.Preferences.EquipZoneScale, 0.05f, 0.7f, 1.6f, (Action)delegate(float value) { _service.Preferences.EquipZoneScale = value; SavePreferences(); }); obj.CreateFunction(BoneHubTheme.SecondaryAction("Reattach wrist UI"), BoneHubTheme.Cyan, (Action)_watch.Recenter); _setup = BoneHubTheme.Style(_root.CreatePage(BoneHubTheme.PageTitle("◇", "mod.io Setup"), BoneHubTheme.Amber, 0, true)); RebuildSetup(); _discover = BoneHubTheme.Style(_root.CreatePage("Avatar Search Keyboard", BoneHubTheme.Cyan, 0, false)); } private void RebuildHome() { //IL_0035: 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_00a9: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) if (_home == null) { return; } _home.RemoveAll(); int count = _runtime.GetAllAvatars().Count; _home.CreateFunction(BoneHubTheme.Brand("Suit up without leaving VR"), Color.white, (Action)delegate { }); _home.CreateFunction(BoneHubTheme.Status(_service.ModIoReady ? "Ready" : "Finish mod.io setup", _service.ModIoReady ? "59E6A7" : "FFC970"), _service.ModIoReady ? BoneHubTheme.Green : BoneHubTheme.Amber, (Action)delegate { if (_setup != null) { Menu.OpenPage(_setup); } }); _home.CreateFunction(BoneHubTheme.Label("Wrist link", "Look 1.5 sec · touch PUSH ME"), BoneHubTheme.Cyan, (Action)delegate { }); _home.CreateFunction(BoneHubTheme.Label("Avatar library", $"{count} ready"), BoneHubTheme.Blue, (Action)delegate { }); _home.CreateFunction(BoneHubTheme.Label("Multiplayer", _runtime.FusionStatus), BoneHubTheme.Green, (Action)delegate { }); _home.CreateFunction(BoneHubTheme.Hint("WristHub 1.2.4 - Avatar Tablet"), BoneHubTheme.Muted, (Action)delegate { }); _home.CreateFunction(BoneHubTheme.PrimaryAction("My avatars"), BoneHubTheme.Green, (Action)OpenInstalled); _home.CreateFunction(BoneHubTheme.PrimaryAction("Search mod.io"), BoneHubTheme.Cyan, (Action)OpenDiscover); _home.CreateFunction(BoneHubTheme.SecondaryAction("Downloads"), BoneHubTheme.Blue, (Action)OpenDownloads); } private void RebuildSetup(string? status = null, bool error = false) { //IL_0024: 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_0098: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: 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) if (_setup == null) { return; } _setup.RemoveAll(); _setup.CreateFunction(BoneHubTheme.Brand("mod.io connection"), Color.white, (Action)delegate { }); _setup.CreateFunction(BoneHubTheme.Status(_service.ModIoReady ? "Connected" : "One-time setup", _service.ModIoReady ? "59E6A7" : "FFC970"), _service.ModIoReady ? BoneHubTheme.Green : BoneHubTheme.Amber, (Action)delegate { }); _setup.CreateFunction(BoneHubTheme.Body("Online search works automatically. A personal read-only mod.io key can be saved locally as an optional backup."), Color.white, (Action)delegate { }); _setup.CreateString(BoneHubTheme.Label("API key", "Input is saved locally"), BoneHubTheme.Cyan, string.Empty, (Action)SaveApiKey); _setup.CreateFunction(BoneHubTheme.Hint("File · " + Truncate(_service.ApiKeyFilePath, 52)), BoneHubTheme.Muted, (Action)delegate { }); if (!string.IsNullOrWhiteSpace(status)) { _setup.CreateFunction(BoneHubTheme.Status(status, error ? "FF6B82" : "59E6A7"), error ? BoneHubTheme.Danger : BoneHubTheme.Green, (Action)delegate { }); } if (_service.ModIoReady && _discover != null) { _setup.CreateFunction(BoneHubTheme.PrimaryAction("Continue to Discover"), BoneHubTheme.Cyan, (Action)delegate { Menu.OpenPage(_discover); }); } } private void SaveApiKey(string value) { RebuildSetup("Saving securely…"); Task.Run(async delegate { try { await _service.ConfigureApiKeyAsync(value, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { _watch.SetStatus("MOD.IO CONNECTED", error: false, success: true); RebuildSetup("API key saved · restart not required"); RebuildHome(); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { RebuildSetup(Truncate(exception.Message, 48), error: true); }); } }); } private void RunSearch() { RunSearch(0); } private void RunSearch(int offset) { //IL_005e: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_0158: Expected O, but got Unknown if (!_service.ModIoReady) { RebuildSetup("Add an API key before searching", error: true); if (_setup != null) { Menu.OpenPage(_setup); } } else { if (_results == null) { return; } _results.RemoveAll(); _results.CreateFunction(BoneHubTheme.Brand("Searching mod.io"), Color.white, (Action)delegate { }); _results.CreateFunction(BoneHubTheme.Status("Finding the best matches", "FFC970"), BoneHubTheme.Amber, (Action)delegate { }); _results.CreateFunction(BoneHubTheme.ProgressBar(0.35), BoneHubTheme.Cyan, (Action)delegate { }); Menu.OpenPage(_results); ModSearchRequest request = new ModSearchRequest(_query, _avatarsOnly ? "Avatar" : null, string.IsNullOrWhiteSpace(_creator) ? null : _creator, _sort, Math.Max(0, offset), 20); _lastSearch = request; _log.Msg($"Searching the BONELAB mod.io catalog (query length {request.Query?.Length ?? 0}, offset {request.Offset})."); Task.Run(async delegate { try { ModIoPage page = await _service.SearchAsync(request, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { ShowResults(page); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { ShowError(exception.Message); }); } }); } } private void ShowResults(ModIoPage page) { //IL_0178: 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_01b2: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_07d6: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0812: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0487: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_0784: Unknown result type (might be due to invalid IL or missing references) //IL_0726: Unknown result type (might be due to invalid IL or missing references) //IL_06fd: Unknown result type (might be due to invalid IL or missing references) if (_results == null) { return; } _log.Msg($"WristHub search returned {page.Data.Count} visible results out of {page.ResultTotal} matches."); _results.RemoveAll(); if (page.Data.Count == 0) { _results.CreateFunction(BoneHubTheme.Brand("Search complete"), Color.white, (Action)delegate { }); _results.CreateFunction(BoneHubTheme.Status("No matches found", "7891A7"), BoneHubTheme.Muted, (Action)delegate { }); _results.CreateFunction(BoneHubTheme.Hint("Try a shorter name or a different creator."), BoneHubTheme.Muted, (Action)delegate { }); return; } _results.CreateFunction(BoneHubTheme.Brand($"{page.ResultTotal} matches"), Color.white, (Action)delegate { }); _results.CreateFunction(BoneHubTheme.PrimaryAction("Open results on wrist tablet"), BoneHubTheme.Cyan, (Action)delegate { _browser.Open(); _browser.SetQuery(_query); }); int num; if (page.ResultOffset < 0) { ModSearchRequest? lastSearch = _lastSearch; num = ((lastSearch != null) ? lastSearch.Offset : 0); } else { num = page.ResultOffset; } int currentOffset = num; int num2; if (page.ResultLimit <= 0) { ModSearchRequest? lastSearch2 = _lastSearch; num2 = ((lastSearch2 != null) ? lastSearch2.Limit : 20); } else { num2 = page.ResultLimit; } int pageSize = num2; int value = currentOffset / Math.Max(1, pageSize) + 1; int value2 = Math.Max(1, (int)Math.Ceiling((double)page.ResultTotal / (double)Math.Max(1, pageSize))); _results.CreateFunction(BoneHubTheme.Hint($"Page {value} of {value2}"), BoneHubTheme.Muted, (Action)delegate { }); foreach (ModIoMod mod in page.Data) { bool flag = _service.IsInstalled(mod.Id); string text = (flag ? "" : ""); string text2 = BoneHubTheme.Escape(Truncate(mod.Name, 25)); Page details = BoneHubTheme.Style(_results.CreatePage(text + " " + text2 + "", flag ? BoneHubTheme.Green : BoneHubTheme.Cyan, 0, true)); _thumbnails.Load(mod.Logo.Thumbnail, delegate(Texture2D texture) { details.Logo = texture; }); details.CreateFunction(BoneHubTheme.Brand(flag ? "Installed" : "mod.io"), Color.white, (Action)delegate { }); details.CreateFunction(BoneHubTheme.Label("TITLE", Truncate(mod.Name, 34)), Color.white, (Action)delegate { }); details.CreateFunction(BoneHubTheme.Label("CREATOR", Truncate(mod.Author.DisplayName, 30)), BoneHubTheme.Blue, (Action)delegate { }); details.CreateFunction(BoneHubTheme.Label("DOWNLOADS", BoneHubTheme.CompactNumber(mod.Stats.DownloadsTotal)), BoneHubTheme.Cyan, (Action)delegate { }); details.CreateFunction(BoneHubTheme.Stars(mod.Stats.Rating), BoneHubTheme.Amber, (Action)delegate { }); if (mod.Tags.Count > 0) { details.CreateFunction(BoneHubTheme.Label("TAGS", string.Join(" / ", from tag in mod.Tags.Take(3) select tag.Name)), BoneHubTheme.Violet, (Action)delegate { }); } details.CreateFunction(BoneHubTheme.Body(Truncate(mod.Summary, 52)), Color.white, (Action)delegate { }); bool favorite = _service.IsFavorite(mod.Id); details.CreateFunction(BoneHubTheme.SecondaryAction(favorite ? "Remove from favorites" : "Save to favorites"), BoneHubTheme.Amber, (Action)delegate { ToggleFavorite(mod.Id, !favorite); }); if (flag) { IReadOnlyList avatars = _runtime.GetAvatars(mod.Id); if (avatars.Count > 0) { BoneHubAvatar firstAvatar = avatars[0]; details.CreateFunction(BoneHubTheme.PrimaryAction("Open installed avatars"), BoneHubTheme.Cyan, (Action)delegate { OpenAvatar(firstAvatar); }); } details.CreateFunction(BoneHubTheme.SecondaryAction("Check for update"), BoneHubTheme.Blue, (Action)delegate { CheckForUpdate(mod.Id); }); } else { details.CreateFunction(BoneHubTheme.PrimaryAction("Download + project"), BoneHubTheme.Green, (Action)delegate { QueueInstall(mod, projectAfterInstall: true); }); details.CreateFunction(BoneHubTheme.SecondaryAction("Download only"), BoneHubTheme.Blue, (Action)delegate { QueueInstall(mod, projectAfterInstall: false); }); } } if (currentOffset > 0) { _results.CreateFunction(BoneHubTheme.SecondaryAction("Previous page"), BoneHubTheme.Blue, (Action)delegate { RunSearch(Math.Max(0, currentOffset - pageSize)); }); } if (currentOffset + pageSize < page.ResultTotal) { _results.CreateFunction(BoneHubTheme.PrimaryAction("Next page"), BoneHubTheme.Cyan, (Action)delegate { RunSearch(currentOffset + pageSize); }); } } private void ShowError(string message) { //IL_0027: 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_00be: Unknown result type (might be due to invalid IL or missing references) Page? results = _results; if (results != null) { results.RemoveAll(); } Page? results2 = _results; if (results2 != null) { results2.CreateFunction(BoneHubTheme.Brand("Connection issue"), Color.white, (Action)delegate { }); } Page? results3 = _results; if (results3 != null) { results3.CreateFunction(BoneHubTheme.Status("Search failed", "FF6B82"), BoneHubTheme.Danger, (Action)delegate { }); } Page? results4 = _results; if (results4 != null) { results4.CreateFunction("" + BoneHubTheme.Escape(Truncate(message, 58)) + "", BoneHubTheme.Danger, (Action)delegate { }); } _log.Error(message); } private void ToggleFavorite(long modId, bool favorite) { Task.Run(async delegate { try { await _service.SetFavoriteAsync(modId, favorite, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(LoadFavorites); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { _log.Error("Could not update favorites: " + exception.Message); }); } }); } private void RebuildFavoritesLoading() { //IL_0024: 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) if (_favorites != null) { _favorites.RemoveAll(); _favorites.CreateFunction(BoneHubTheme.Brand("Your collection"), Color.white, (Action)delegate { }); _favorites.CreateFunction(BoneHubTheme.Status("Loading saved mods", "FFC970"), BoneHubTheme.Amber, (Action)delegate { }); } } private void LoadFavorites() { if (_favorites == null) { return; } RebuildFavoritesLoading(); Task.Run(async delegate { try { IReadOnlyList favorites = await _service.GetFavoriteModsAsync(default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { ShowFavorites(favorites); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { //IL_0033: 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_00c3: 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) if (_favorites != null) { _favorites.RemoveAll(); _favorites.CreateFunction(BoneHubTheme.Brand("Your collection"), Color.white, (Action)delegate { }); _favorites.CreateFunction(BoneHubTheme.Status("Could not refresh favorites", "FF6B82"), BoneHubTheme.Danger, (Action)delegate { }); _favorites.CreateFunction(BoneHubTheme.Hint(Truncate(exception.Message, 48)), BoneHubTheme.Danger, (Action)delegate { }); _favorites.CreateFunction(BoneHubTheme.SecondaryAction("Try again"), BoneHubTheme.Cyan, (Action)LoadFavorites); } }); } }); } private void ShowFavorites(IReadOnlyList favorites) { //IL_0024: 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_00ce: 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_01de: 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_0290: Unknown result type (might be due to invalid IL or missing references) if (_favorites == null) { return; } _favorites.RemoveAll(); _favorites.CreateFunction(BoneHubTheme.Brand("Your collection"), Color.white, (Action)delegate { }); _favorites.CreateFunction(BoneHubTheme.Label("Saved", $"{favorites.Count} mods"), BoneHubTheme.Amber, (Action)delegate { }); if (favorites.Count == 0) { _favorites.CreateFunction(BoneHubTheme.Status("Nothing saved yet", "7891A7"), BoneHubTheme.Muted, (Action)delegate { }); _favorites.CreateFunction(BoneHubTheme.Hint("Save a mod from any result page."), BoneHubTheme.Muted, (Action)delegate { }); return; } foreach (ModIoMod item in favorites.Take(10)) { ModIoMod selectedMod = item; string value = (_service.IsInstalled(item.Id) ? "Update" : "Download"); _favorites.CreateFunction($"{BoneHubTheme.Escape(Truncate(item.Name, 25))} {value}", BoneHubTheme.Amber, (Action)delegate { QueueInstall(selectedMod, projectAfterInstall: true); }); _favorites.CreateFunction(BoneHubTheme.SecondaryAction("Remove " + Truncate(item.Name, 22)), BoneHubTheme.Muted, (Action)delegate { ToggleFavorite(selectedMod.Id, favorite: false); }); } if (favorites.Count > 10) { _favorites.CreateFunction(BoneHubTheme.Hint($"Showing 10 of {favorites.Count} saved mods."), BoneHubTheme.Muted, (Action)delegate { }); } } public void OnDownloadChanged(DownloadJob job) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 if (!_jobs.ContainsKey(job.Id)) { _jobOrder.Add(job.Id); } _jobs[job.Id] = job; RebuildDownloads(); if ((int)job.State == 5) { RebuildInstalled(); } } public void OnInstalledChanged() { _runtime.RegisterInstalled(_service.Installed); RebuildInstalled(); } public void OnAvatarsChanged(long modId, IReadOnlyList avatars) { int count = _runtime.GetAllAvatars().Count; _runtimeStatus = ((count == 0) ? "No downloaded avatar crates found" : $"{count} downloaded avatar{((count == 1) ? string.Empty : "s")} ready"); if (_projectAfterInstall.Remove(modId)) { if (avatars.Count > 0) { _runtimeStatus = "Projecting " + avatars[0].Title; _watch.SetStatus("HOLOGRAM READY", error: false, success: true); OpenAvatar(avatars[0]); } else { _runtimeStatus = "Installed, but no avatar crate was found"; _watch.SetStatus("NO AVATAR FOUND", error: true); } } RebuildInstalled(); RebuildHome(); } private void QueueInstall(ModIoMod mod, bool projectAfterInstall) { if (!_service.ModIoReady) { RebuildSetup("Add an API key before downloading", error: true); if (_setup != null) { Menu.OpenPage(_setup); } return; } if (projectAfterInstall) { _projectAfterInstall.Add(mod.Id); } _watch.SetStatus("RESOLVING DEPENDENCIES"); Task.Run(async delegate { try { IReadOnlyList jobs = await _service.InstallWithDependenciesAsync(mod, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { _watch.SetStatus((jobs.Count > 1) ? $"QUEUED {jobs.Count} MODS" : "DOWNLOAD QUEUED"); _log.Msg($"Queued {mod.Name} with {Math.Max(0, jobs.Count - 1)} dependencies."); RebuildDownloads(); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { _projectAfterInstall.Remove(mod.Id); _watch.SetStatus("INSTALL PLAN FAILED", error: true); ShowError(exception.Message); }); } }); } private void RebuildUpdateCenter(string? status = null) { //IL_0024: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0216: 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) if (_updates == null) { return; } _updates.RemoveAll(); _updates.CreateFunction(BoneHubTheme.Brand("Verified updates"), Color.white, (Action)delegate { }); _updates.CreateFunction(BoneHubTheme.Status(status ?? "Ready to scan", "7891A7"), BoneHubTheme.Muted, (Action)delegate { }); foreach (ModUpdateInfo item in _availableUpdates.Where((ModUpdateInfo item) => item.UpdateAvailable)) { _updates.CreateFunction(BoneHubTheme.Label(Truncate(item.Mod.Name, 28), $"file {item.InstalledFileId} → {item.LatestFileId}"), BoneHubTheme.Blue, (Action)delegate { }); } int num = _availableUpdates.Count((ModUpdateInfo item) => item.UpdateAvailable); if (num > 0) { _updates.CreateFunction(BoneHubTheme.PrimaryAction($"Install {num} reviewed update{((num == 1) ? string.Empty : "s")}"), BoneHubTheme.Green, (Action)InstallReviewedUpdates); } _updates.CreateFunction(BoneHubTheme.SecondaryAction("Scan installed library"), BoneHubTheme.Cyan, (Action)ScanForUpdates); } private void ScanForUpdates() { if (!_service.ModIoReady) { RebuildSetup("Add an API key before checking updates", error: true); if (_setup != null) { Menu.OpenPage(_setup); } return; } RebuildUpdateCenter("Scanning platform-compatible files…"); Task.Run(async delegate { try { IReadOnlyList updates = await _service.CheckAllUpdatesAsync(default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { _availableUpdates = updates; int num = updates.Count((ModUpdateInfo item) => item.UpdateAvailable); RebuildUpdateCenter((num == 0) ? "Everything is current" : $"{num} update{((num == 1) ? string.Empty : "s")} ready for review"); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { RebuildUpdateCenter("Scan failed · " + Truncate(exception.Message, 40)); }); } }); } private void InstallReviewedUpdates() { ModUpdateInfo[] updates = _availableUpdates.Where((ModUpdateInfo item) => item.UpdateAvailable).ToArray(); RebuildUpdateCenter($"Queueing {updates.Length} reviewed updates…"); Task.Run(async delegate { try { ModUpdateInfo[] array = updates; foreach (ModUpdateInfo val in array) { await _service.InstallWithDependenciesAsync(val.Mod, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); } _mainThread.Enqueue(delegate { RebuildUpdateCenter("Reviewed updates queued"); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { RebuildUpdateCenter("Queue failed · " + Truncate(exception.Message, 40)); }); } }); } public void OnEquipFinished(BoneHubAvatar avatar, bool success, string? error) { _runtimeStatus = (success ? ("Equipped " + avatar.Title) : (error ?? ("Could not equip " + avatar.Title))); _watch.SetStatus(_runtimeStatus, !success, success); RebuildInstalled(); } public void OnRuntimeStatusChanged(string status) { _runtimeStatus = status; RebuildInstalled(); } private void RebuildDownloads() { //IL_0024: 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_00aa: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected I4, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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_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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected I4, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: 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_02db: 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_02e0: Invalid comparison between Unknown and I4 //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) if (_downloads == null) { return; } _downloads.RemoveAll(); _downloads.CreateFunction(BoneHubTheme.Brand("Transfer queue"), Color.white, (Action)delegate { }); if (_jobOrder.Count == 0) { _downloads.CreateFunction(BoneHubTheme.Status("Queue is empty", "7891A7"), BoneHubTheme.Muted, (Action)delegate { }); _downloads.CreateFunction(BoneHubTheme.Hint("Downloads continue quietly while you play."), BoneHubTheme.Muted, (Action)delegate { }); return; } foreach (Guid item in _jobOrder.AsEnumerable().Reverse().Take(6)) { DownloadJob val = _jobs[item]; int value = (int)Math.Round(val.Progress * 100.0); DownloadState state = val.State; Color val2 = (Color)((state - 5) switch { 0 => BoneHubTheme.Green, 1 => BoneHubTheme.Danger, 2 => BoneHubTheme.Muted, _ => BoneHubTheme.Cyan, }); state = val.State; string value2 = (state - 5) switch { 0 => "59E6A7", 1 => "FF6B82", 2 => "7891A7", _ => "57E9FF", }; _downloads.CreateFunction($"{BoneHubTheme.Escape(Truncate(val.Mod.Name, 26))} {val.State} · {value}%", val2, (Action)delegate { }); _downloads.CreateFunction($"{BoneHubTheme.ProgressBar(val.Progress)} {value}%", val2, (Action)delegate { }); state = val.State; if (state - 5 > 2) { Guid jobId = val.Id; _downloads.CreateFunction(BoneHubTheme.SecondaryAction("Cancel transfer"), BoneHubTheme.Muted, (Action)delegate { _service.CancelDownload(jobId); }); } if (!string.IsNullOrWhiteSpace(val.Error)) { _downloads.CreateFunction("" + BoneHubTheme.Escape(Truncate(val.Error, 50)) + "", BoneHubTheme.Danger, (Action)delegate { }); } } } private void RebuildInstalled() { //IL_0091: 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_00f2: 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_0280: 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_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0888: Unknown result type (might be due to invalid IL or missing references) //IL_0814: 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_084e: 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_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_064f: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06e2: Unknown result type (might be due to invalid IL or missing references) //IL_0704: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_077f: Unknown result type (might be due to invalid IL or missing references) //IL_07b3: Unknown result type (might be due to invalid IL or missing references) if (_installed == null) { return; } Page[] array = _installedDetailPages.ToArray(); foreach (Page val in array) { try { _installed.RemovePage(val); } catch { } } _installedDetailPages.Clear(); _installed.RemoveAll(); IReadOnlyList allAvatars = _runtime.GetAllAvatars(); _installed.CreateFunction(BoneHubTheme.Brand($"{allAvatars.Count} avatars ready"), Color.white, (Action)delegate { }); _installed.CreateFunction(BoneHubTheme.Status(_runtimeStatus, _runtime.WarehouseReady ? "59E6A7" : "FFC970"), _runtime.WarehouseReady ? BoneHubTheme.Green : BoneHubTheme.Amber, (Action)delegate { }); if (allAvatars.Count > 0) { _installed.CreateFunction(BoneHubTheme.PrimaryAction("Open Avatar Browser"), BoneHubTheme.Cyan, (Action)_browser.Open); foreach (BoneHubAvatar item2 in allAvatars.Take(18)) { BoneHubAvatar selectedAvatar = item2; _installed.CreateFunction(BoneHubTheme.SecondaryAction(Truncate(item2.Title, 29)), BoneHubTheme.Blue, (Action)delegate { OpenAvatar(selectedAvatar); }); } if (allAvatars.Count > 18) { _installed.CreateFunction(BoneHubTheme.Hint($"Open Avatar Browser to browse all {allAvatars.Count} avatars."), BoneHubTheme.Muted, (Action)delegate { }); } } TrashedModRecord lastTrashed = _service.LastTrashed; if (lastTrashed != null) { _installed.CreateFunction(BoneHubTheme.SecondaryAction("Undo uninstall · " + Truncate(lastTrashed.Mod.Name, 24)), BoneHubTheme.Amber, (Action)UndoLastUninstall); } foreach (InstalledModRecord item in _service.Installed.OrderBy((InstalledModRecord record) => record.Name).Take(20)) { InstalledModHealth val2 = _service.VerifyInstalled(item.ModId); string text = (val2.Healthy ? "●" : "●"); Page val3 = BoneHubTheme.Style(_installed.CreatePage(text + " " + BoneHubTheme.Escape(Truncate(item.Name, 27)) + "", val2.Healthy ? BoneHubTheme.Green : BoneHubTheme.Danger, 0, true)); _installedDetailPages.Add(val3); val3.CreateFunction(BoneHubTheme.Brand("Installed content"), Color.white, (Action)delegate { }); val3.CreateFunction(BoneHubTheme.Label("Version", string.IsNullOrWhiteSpace(item.Version) ? "Unknown" : item.Version), BoneHubTheme.Blue, (Action)delegate { }); val3.CreateFunction(BoneHubTheme.Status(val2.Healthy ? "Installation verified" : "Repair recommended", val2.Healthy ? "59E6A7" : "FF6B82"), val2.Healthy ? BoneHubTheme.Green : BoneHubTheme.Danger, (Action)delegate { }); foreach (string item3 in val2.Problems.Take(3)) { val3.CreateFunction(BoneHubTheme.Hint(item3), BoneHubTheme.Danger, (Action)delegate { }); } if (_maintenanceStatus.TryGetValue(item.ModId, out string value)) { val3.CreateFunction(BoneHubTheme.Hint(value), BoneHubTheme.Amber, (Action)delegate { }); } IReadOnlyList avatars = _runtime.GetAvatars(item.ModId); if (avatars.Count > 0) { val3.CreateFunction(BoneHubTheme.Section($"Avatars · {avatars.Count}"), BoneHubTheme.Cyan, (Action)delegate { }); foreach (BoneHubAvatar item4 in avatars.Take(12)) { BoneHubAvatar selectedAvatar2 = item4; val3.CreateFunction(BoneHubTheme.PrimaryAction("Open " + Truncate(item4.Title, 23)), BoneHubTheme.Cyan, (Action)delegate { OpenAvatar(selectedAvatar2); }); } } else { val3.CreateFunction(BoneHubTheme.Hint("No loaded avatar crates are associated with this pallet yet."), BoneHubTheme.Muted, (Action)delegate { }); } val3.CreateFunction(BoneHubTheme.SecondaryAction("Check for update"), BoneHubTheme.Blue, (Action)delegate { CheckForUpdate(item.ModId); }); val3.CreateFunction(BoneHubTheme.SecondaryAction(val2.Healthy ? "Reinstall or update" : "Repair installation"), BoneHubTheme.Green, (Action)delegate { RepairOrUpdate(item.ModId); }); Page obj2 = BoneHubTheme.Style(val3.CreatePage(BoneHubTheme.PageTitle("!", "Move to WristHub Trash"), BoneHubTheme.Danger, 0, true)); obj2.CreateFunction(BoneHubTheme.Brand("Recoverable uninstall"), Color.white, (Action)delegate { }); obj2.CreateFunction(BoneHubTheme.Body(item.Name + " will be moved out of BONELAB's active Mods folder."), Color.white, (Action)delegate { }); obj2.CreateFunction(BoneHubTheme.Hint("You can restore the most recent uninstall from Installed."), BoneHubTheme.Muted, (Action)delegate { }); obj2.CreateFunction(BoneHubTheme.PrimaryAction("Confirm uninstall"), BoneHubTheme.Danger, (Action)delegate { Uninstall(item.ModId); }); } if (_service.Installed.Count == 0 && allAvatars.Count == 0) { _installed.CreateFunction(BoneHubTheme.Status("Library is empty", "7891A7"), BoneHubTheme.Muted, (Action)delegate { }); _installed.CreateFunction(BoneHubTheme.SecondaryAction("Discover your first avatar"), BoneHubTheme.Cyan, (Action)OpenDiscover); } else if (_service.Installed.Count == 0) { _installed.CreateFunction(BoneHubTheme.Hint("Existing BONELAB avatars are ready above. WristHub management actions appear for new WristHub downloads."), BoneHubTheme.Muted, (Action)delegate { }); } } private void CheckForUpdate(long modId) { _maintenanceStatus[modId] = "Checking mod.io for an update…"; RebuildInstalled(); Task.Run(async delegate { try { ModUpdateInfo result = await _service.CheckForUpdateAsync(modId, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { _maintenanceStatus[modId] = (result.UpdateAvailable ? "Update available · choose Reinstall or update" : "You have the latest live file"); RebuildInstalled(); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { _maintenanceStatus[modId] = "Update check failed · " + Truncate(exception.Message, 42); RebuildInstalled(); }); } }); } private void RepairOrUpdate(long modId) { _maintenanceStatus[modId] = "Preparing a verified replacement…"; RebuildInstalled(); Task.Run(async delegate { try { await _service.RepairOrUpdateAsync(modId, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _mainThread.Enqueue(delegate { _maintenanceStatus[modId] = "Repair or update queued"; RebuildInstalled(); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { _maintenanceStatus[modId] = "Could not queue repair · " + Truncate(exception.Message, 40); RebuildInstalled(); }); } }); } private void Uninstall(long modId) { _maintenanceStatus[modId] = "Moving content to WristHub Trash…"; Task.Run(async delegate { bool subscribed = _sharing.IsSubscribed(modId); try { if (subscribed && !_sharing.Unsubscribe(modId)) { throw new InvalidOperationException("Could not unsubscribe this mod. Nothing was deleted."); } InstalledModRecord val = ((IEnumerable)_service.Installed).FirstOrDefault((Func)((InstalledModRecord item) => item.ModId == modId)); await _service.UninstallSubscribedAsync(modId, (val != null) ? val.Name : null, (IReadOnlyList)((val != null) ? val.InstalledDirectories : null), subscribed, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); _sharing.RequestRefresh(immediate: true); _mainThread.Enqueue(delegate { _maintenanceStatus.Remove(modId); _runtimeStatus = "Mod moved to WristHub Trash"; RebuildInstalled(); if (_installed != null) { Menu.OpenPage(_installed); } }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; if (subscribed) { _sharing.Subscribe(modId); } _mainThread.Enqueue(delegate { _maintenanceStatus[modId] = "Uninstall failed · " + Truncate(exception.Message, 42); RebuildInstalled(); }); } }); } private void UndoLastUninstall() { _runtimeStatus = "Restoring the last uninstalled mod…"; RebuildInstalled(); Task.Run(async delegate { TrashedModRecord lastTrashed = _service.LastTrashed; bool wasSubscribed = lastTrashed != null && lastTrashed.WasSubscribed; try { InstalledModRecord restored = await _service.UndoLastUninstallAsync(default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); if (wasSubscribed) { _sharing.Subscribe(restored.ModId); } _sharing.RequestRefresh(immediate: true); _mainThread.Enqueue(delegate { _runtimeStatus = "Restored " + restored.Name; RebuildInstalled(); }); } catch (Exception ex) { Exception ex2 = ex; Exception exception = ex2; _mainThread.Enqueue(delegate { _runtimeStatus = "Restore failed · " + Truncate(exception.Message, 44); RebuildInstalled(); }); } }); } private void ResetHologramPreferences() { _service.Preferences.HologramEffects = true; _service.Preferences.HapticsEnabled = true; _service.Preferences.SoundsEnabled = true; _service.Preferences.CarouselDistance = 0.62f; _service.Preferences.HologramScale = 1f; _service.Preferences.EquipZoneScale = 1f; _service.Preferences.HologramBrightness = 1f; _browser.Refresh(); SavePreferences(); } private void ApplyComfortPreset(BoneHubComfortPreset preset) { //IL_000b: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown _service.Preferences.ComfortPreset = preset; switch (preset - 1) { case 0: _watch.WatchScale = 1.15f; _watch.DwellSeconds = 3f; _service.Preferences.CarouselDistance = 0.54f; _service.Preferences.HologramScale = 1.12f; _service.Preferences.EquipZoneScale = 1.35f; break; case 1: _watch.WatchScale = 1.28f; _watch.DwellSeconds = 3f; _service.Preferences.CarouselDistance = 0.58f; _service.Preferences.HologramScale = 1.25f; _service.Preferences.EquipZoneScale = 1.55f; _service.Preferences.HologramBrightness = 1.2f; break; case 2: _watch.ReducedMotion = true; _service.Preferences.HologramEffects = false; _service.Preferences.CarouselDistance = 0.58f; _service.Preferences.EquipZoneScale = 1.3f; break; default: _watch.WatchScale = 1f; _watch.DwellSeconds = 3f; _watch.ReducedMotion = false; _service.Preferences.HologramEffects = true; _service.Preferences.CarouselDistance = 0.62f; _service.Preferences.HologramScale = 1f; _service.Preferences.EquipZoneScale = 1f; _service.Preferences.HologramBrightness = 1f; break; } _browser.Refresh(); _watch.Recenter(); SavePreferences(); } private void SavePreferences() { SavePreferencesGuardedAsync(); } private async Task SavePreferencesGuardedAsync() { try { await _service.SavePreferencesAsync(default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false); } catch (Exception ex) { _log.Error("Could not save WristHub preferences: " + ex.Message); } } private static string Truncate(string value, int length) { if (!string.IsNullOrWhiteSpace(value)) { if (value.Length > length) { return value.Substring(0, length - 1) + "…"; } return value; } return "(none)"; } private void OpenAvatar(BoneHubAvatar avatar) { _browser.Open(); _browser.Select(avatar.ToEntry().Identity); } public void Tick() { } public void Dispose() { _thumbnails.Dispose(); } } internal readonly record struct RenderOnlyPreviewResult(GameObject? Root, Bounds Bounds, float VisualHeightMeters, AvatarPreviewVisualSource VisualSource, AvatarPreviewHeightSource HeightSource, int DeclaredRendererCount, int RendererCount, int VertexCount, IReadOnlyList OwnedMeshes, string? Error) { public bool Valid { get { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Root != (Object)null && (int)VisualSource != 0) { return string.IsNullOrWhiteSpace(Error); } return false; } } public bool InteractionReady { get { if (Valid) { return RendererCount > 0; } return false; } } [CompilerGenerated] public void Deconstruct(out GameObject? Root, out Bounds Bounds, out float VisualHeightMeters, out AvatarPreviewVisualSource VisualSource, out AvatarPreviewHeightSource HeightSource, out int DeclaredRendererCount, out int RendererCount, out int VertexCount, out IReadOnlyList OwnedMeshes, out string? Error) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown Root = this.Root; Bounds = this.Bounds; VisualHeightMeters = this.VisualHeightMeters; VisualSource = (AvatarPreviewVisualSource)(int)this.VisualSource; HeightSource = (AvatarPreviewHeightSource)(int)this.HeightSource; DeclaredRendererCount = this.DeclaredRendererCount; RendererCount = this.RendererCount; VertexCount = this.VertexCount; OwnedMeshes = this.OwnedMeshes; Error = this.Error; } } internal static class BoneHubRenderOnlyPreviewBuilder { public static RenderOnlyPreviewResult Build(GameObject prefab, Transform parent, bool constrained) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: 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_02bd: 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_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_02f6: 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) int num = (constrained ? 24 : 64); int num2 = (constrained ? 350000 : 1250000); int num3 = (constrained ? 512 : 2048); int num4 = (constrained ? 48 : 128); GameObject val = null; int declaredRendererCount = 0; int num5 = 0; int num6 = 0; float num7 = 0f; AvatarPreviewHeightSource heightSource = (AvatarPreviewHeightSource)0; List list = new List(); try { Avatar component = prefab.GetComponent(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("The crate did not expose a BONELAB avatar definition."); } try { num7 = component.height; } catch { num7 = 0f; } if (AvatarPreviewMath.IsUsableHeight(num7)) { heightSource = (AvatarPreviewHeightSource)1; } List bodyRenderers; List list2 = CollectDeclaredRenderers(component, prefab.transform, out declaredRendererCount, out bodyRenderers); num5 = list2.Count; if (num5 == 0) { throw new InvalidOperationException("The avatar definition did not expose usable body, head, or hair renderers."); } if (num5 > num) { throw new InvalidOperationException("The avatar is too complex for a wrist preview."); } int length = prefab.GetComponentsInChildren(true).Length; if (length == 0 || length > num3) { throw new InvalidOperationException("The avatar transform hierarchy exceeds the safe preview budget."); } int num8 = 0; foreach (Renderer item in list2) { Mesh val2 = RendererMesh(item); if (!((Object)(object)val2 == (Object)null)) { num6 += Math.Max(0, val2.vertexCount); num8 += ((IEnumerable)item.sharedMaterials).Count((Material material) => (Object)(object)material != (Object)null); if (num6 > num2) { throw new InvalidOperationException("The avatar exceeds the safe preview vertex budget."); } if (num8 > num4) { throw new InvalidOperationException("The avatar exceeds the safe preview material budget."); } } } if (num6 == 0 || num8 == 0) { throw new InvalidOperationException("The avatar has no usable mesh and material data."); } val = new GameObject("Sanitized Full-Color Avatar Preview"); val.transform.SetParent(parent, false); val.SetActive(false); Dictionary transforms = new Dictionary(); CloneTransform(prefab.transform, val.transform, transforms, copyLocalTransform: false); Dictionary copied = CopyRenderers(list2, transforms); Renderer[] array = ((IEnumerable)val.GetComponentsInChildren(true)).Where((Renderer renderer) => (Object)(object)renderer != (Object)null && renderer.enabled).ToArray(); if (array.Length == 0) { throw new InvalidOperationException("The sanitized preview did not contain a visible mesh."); } val.SetActive(true); Renderer value; Renderer[] array2 = (from renderer in bodyRenderers select (!copied.TryGetValue(((Object)renderer).GetInstanceID(), out value)) ? null : value into renderer where (Object)(object)renderer != (Object)null select renderer).Cast().ToArray(); if (array2.Length == 0) { array2 = array; } Bounds bounds = ApplyNormalizedLayout(val.transform, array2, parent); AvatarResolvedHeight val3 = AvatarPreviewMath.ResolveHeight(num7, ((Bounds)(ref bounds)).size.y, 0f); heightSource = ((AvatarResolvedHeight)(ref val3)).Source; if (!((AvatarResolvedHeight)(ref val3)).Valid || !AvatarPreviewMath.IsSafePreview(((AvatarResolvedHeight)(ref val3)).Meters, num5, num6, constrained)) { throw new InvalidOperationException("The avatar reported invalid or unbounded preview dimensions."); } return new RenderOnlyPreviewResult(val, bounds, ((AvatarResolvedHeight)(ref val3)).Meters, (AvatarPreviewVisualSource)1, heightSource, declaredRendererCount, array.Length, num6, list, null); } catch (Exception ex) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } foreach (Mesh item2 in list) { if ((Object)(object)item2 != (Object)null) { Object.Destroy((Object)(object)item2); } } return new RenderOnlyPreviewResult(null, default(Bounds), num7, (AvatarPreviewVisualSource)0, heightSource, declaredRendererCount, num5, num6, Array.Empty(), ex.Message); } } public static RenderOnlyPreviewResult BuildNativePreview(Mesh mesh, Material material, Transform parent, bool constrained, float preferredHeightMeters, AvatarPreviewHeightSource preferredHeightSource, int declaredRendererCount, string? fullColorError) { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_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_0041: 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_005d: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00cc: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_013f: 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) GameObject val = null; try { int num = (constrained ? 350000 : 1250000); if ((Object)(object)mesh == (Object)null || mesh.vertexCount <= 0 || mesh.vertexCount > num) { throw new InvalidOperationException("The native preview mesh is missing or exceeds the safe preview budget."); } Bounds bounds = mesh.bounds; if (IsFinite(((Bounds)(ref bounds)).center) && IsFinite(((Bounds)(ref bounds)).size)) { Vector3 size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude < 1E-06f)) { AvatarResolvedHeight val2 = (AvatarResolvedHeight)(AvatarPreviewMath.IsUsableHeight(preferredHeightMeters) ? new AvatarResolvedHeight(preferredHeightMeters, preferredHeightSource) : AvatarPreviewMath.ResolveHeight(0f, 0f, ((Bounds)(ref bounds)).size.y)); if (!((AvatarResolvedHeight)(ref val2)).Valid) { throw new InvalidOperationException("The native preview mesh height is unavailable."); } val = new GameObject("BONELAB Native Avatar Preview Mesh"); val.transform.SetParent(parent, false); val.SetActive(false); GameObject val3 = new GameObject("Native Preview Visual"); val3.transform.SetParent(val.transform, false); val3.AddComponent().sharedMesh = mesh; MeshRenderer val4 = val3.AddComponent(); ((Renderer)val4).sharedMaterial = material; ((Renderer)val4).enabled = true; val.SetActive(true); ApplyNormalizedLayout(val.transform, (IReadOnlyList)(object)new Renderer[1] { (Renderer)val4 }, parent); return new RenderOnlyPreviewResult(val, bounds, ((AvatarResolvedHeight)(ref val2)).Meters, (AvatarPreviewVisualSource)2, ((AvatarResolvedHeight)(ref val2)).Source, declaredRendererCount, 1, mesh.vertexCount, Array.Empty(), null); } } throw new InvalidOperationException("The native preview mesh did not report usable bounds."); } catch (Exception ex) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } string error = (string.IsNullOrWhiteSpace(fullColorError) ? ex.Message : (fullColorError + " Native fallback: " + ex.Message)); return new RenderOnlyPreviewResult(null, default(Bounds), preferredHeightMeters, (AvatarPreviewVisualSource)0, preferredHeightSource, declaredRendererCount, 0, (!((Object)(object)mesh == (Object)null)) ? mesh.vertexCount : 0, Array.Empty(), error); } } private static List CollectDeclaredRenderers(Avatar avatar, Transform prefabRoot, out int declaredRendererCount, out List bodyRenderers) { List result = new List(); bodyRenderers = new List(); HashSet instanceIds = new HashSet(); declaredRendererCount = 0; AddDeclared((IEnumerable?)avatar.bodyMeshes, prefabRoot, result, instanceIds, ref declaredRendererCount, bodyRenderers); AddDeclared((IEnumerable?)avatar.headMeshes, prefabRoot, result, instanceIds, ref declaredRendererCount, bodyRenderers); AddDeclared((IEnumerable?)avatar.hairMeshes, prefabRoot, result, instanceIds, ref declaredRendererCount); return result; } private static void AddDeclared(IEnumerable? declared, Transform prefabRoot, ICollection result, ISet instanceIds, ref int declaredRendererCount, ICollection? category = null) { if (declared == null) { return; } foreach (SkinnedMeshRenderer item in declared) { if (!((Object)(object)item == (Object)null)) { declaredRendererCount++; if (!((Object)(object)item.sharedMesh == (Object)null) && IsInside(((Component)item).transform, prefabRoot) && HasValidBones(item, prefabRoot) && instanceIds.Add(((Object)item).GetInstanceID())) { result.Add((Renderer)(object)item); category?.Add((Renderer)(object)item); } } } } private static bool HasValidBones(SkinnedMeshRenderer renderer, Transform prefabRoot) { if ((Object)(object)renderer.rootBone != (Object)null && !IsInside(renderer.rootBone, prefabRoot)) { return false; } Il2CppReferenceArray bones = renderer.bones; for (int i = 0; i < ((Il2CppArrayBase)(object)bones).Length; i++) { if ((Object)(object)((Il2CppArrayBase)(object)bones)[i] == (Object)null || !IsInside(((Il2CppArrayBase)(object)bones)[i], prefabRoot)) { return false; } } return true; } private static bool IsInside(Transform candidate, Transform root) { Transform val = candidate; while ((Object)(object)val != (Object)null) { if ((Object)(object)val == (Object)(object)root) { return true; } val = val.parent; } return false; } private static Mesh? RendererMesh(Renderer renderer) { SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (val == null) { MeshFilter component = ((Component)renderer).GetComponent(); if (component == null) { return null; } return component.sharedMesh; } return val.sharedMesh; } 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 (float.IsFinite(value.x) && float.IsFinite(value.y)) { return float.IsFinite(value.z); } return false; } private static Transform CloneTransform(Transform source, Transform parent, IDictionary transforms, bool copyLocalTransform = true) { //IL_0010: 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_0027: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Transform transform = new GameObject("Preview Mesh - " + ((Object)source).name).transform; transform.SetParent(parent, false); transform.localPosition = (copyLocalTransform ? source.localPosition : Vector3.zero); transform.localRotation = (copyLocalTransform ? source.localRotation : Quaternion.identity); transform.localScale = (copyLocalTransform ? source.localScale : Vector3.one); transforms[source] = transform; for (int i = 0; i < source.childCount; i++) { CloneTransform(source.GetChild(i), transform, transforms); } return transform; } private static Bounds ApplyNormalizedLayout(Transform previewRoot, IReadOnlyList renderers, Transform previewSpace) { //IL_0001: 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_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_003a: 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_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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00b5: 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_00d2: 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_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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) previewRoot.localPosition = Vector3.zero; previewRoot.localRotation = Quaternion.Euler(0f, 180f, 0f); previewRoot.localScale = Vector3.one; Bounds result = MeasureRenderedBounds(renderers, previewSpace); if (IsFinite(((Bounds)(ref result)).center) && IsFinite(((Bounds)(ref result)).size)) { Vector3 size = ((Bounds)(ref result)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 1E-06f) && !(((Bounds)(ref result)).size.y <= 0.0001f) && !(((Bounds)(ref result)).size.y > 10000f)) { AvatarPreviewPlacement val = AvatarPreviewMath.FitBounds(new Vector3(((Bounds)(ref result)).center.x, ((Bounds)(ref result)).center.y, ((Bounds)(ref result)).center.z), new Vector3(((Bounds)(ref result)).size.x, ((Bounds)(ref result)).size.y, ((Bounds)(ref result)).size.z)); if (!((AvatarPreviewPlacement)(ref val)).Valid) { throw new InvalidOperationException("The copied avatar could not be normalized."); } previewRoot.localScale = Vector3.one * ((AvatarPreviewPlacement)(ref val)).UniformScale; for (int i = 0; i < 3; i++) { Bounds val2 = MeasureRenderedBounds(renderers, previewSpace); if (!IsFinite(((Bounds)(ref val2)).center) || !IsFinite(((Bounds)(ref val2)).size) || ((Bounds)(ref val2)).size.y <= 0.0001f) { throw new InvalidOperationException("The normalized avatar bounds became invalid."); } float num = 0.16f / ((Bounds)(ref val2)).size.y; if (!float.IsFinite(num) || num <= 0f || num > 1000f) { throw new InvalidOperationException("The avatar required an unsafe preview correction."); } previewRoot.localScale *= num; val2 = MeasureRenderedBounds(renderers, previewSpace); previewRoot.localPosition -= ((Bounds)(ref val2)).center; } return result; } } throw new InvalidOperationException("The copied avatar did not report usable rendered bounds."); } private static Bounds MeasureRenderedBounds(IEnumerable renderers, Transform space) { //IL_0004: 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_003e: 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_004f: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b8: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00cb: 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) bool flag = false; Bounds result = default(Bounds); foreach (Renderer renderer in renderers) { if ((Object)(object)renderer == (Object)null || !renderer.enabled) { continue; } Bounds bounds = renderer.bounds; if (!IsFinite(((Bounds)(ref bounds)).center) || !IsFinite(((Bounds)(ref bounds)).size)) { continue; } Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude < 1E-06f) { continue; } Vector3 center = ((Bounds)(ref bounds)).center; Vector3 extents = ((Bounds)(ref bounds)).extents; for (int i = -1; i <= 1; i += 2) { for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { Vector3 val = center + Vector3.Scale(extents, new Vector3((float)i, (float)j, (float)k)); Vector3 val2 = space.InverseTransformPoint(val); if (!flag) { result = new Bounds(val2, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val2); } } } } } if (!flag) { throw new InvalidOperationException("The copied avatar has no visible rendered bounds."); } return result; } private static Dictionary CopyRenderers(IEnumerable sourceRenderers, IReadOnlyDictionary transforms) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); foreach (Renderer sourceRenderer in sourceRenderers) { if (!transforms.TryGetValue(((Component)sourceRenderer).transform, out Transform value)) { continue; } MeshRenderer val = (MeshRenderer)(object)((sourceRenderer is MeshRenderer) ? sourceRenderer : null); if (val != null) { MeshFilter component = ((Component)val).GetComponent(); if (!((Object)(object)((component != null) ? component.sharedMesh : null) == (Object)null)) { ((Component)value).gameObject.AddComponent().sharedMesh = component.sharedMesh; MeshRenderer val2 = ((Component)value).gameObject.AddComponent(); ((Renderer)val2).sharedMaterials = ((Renderer)val).sharedMaterials; ((Renderer)val2).enabled = true; dictionary[((Object)sourceRenderer).GetInstanceID()] = (Renderer)(object)val2; } continue; } SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((sourceRenderer is SkinnedMeshRenderer) ? sourceRenderer : null); if (val3 != null && !((Object)(object)val3.sharedMesh == (Object)null)) { SkinnedMeshRenderer val4 = ((Component)value).gameObject.AddComponent(); val4.sharedMesh = val3.sharedMesh; ((Renderer)val4).sharedMaterials = ((Renderer)val3).sharedMaterials; ((Renderer)val4).localBounds = ((Renderer)val3).localBounds; val4.updateWhenOffscreen = true; ((Renderer)val4).enabled = true; Il2CppReferenceArray bones = val3.bones; Il2CppReferenceArray val5 = new Il2CppReferenceArray((long)((Il2CppArrayBase)(object)bones).Length); for (int i = 0; i < ((Il2CppArrayBase)(object)bones).Length; i++) { ((Il2CppArrayBase)(object)val5)[i] = (((Object)(object)((Il2CppArrayBase)(object)bones)[i] != (Object)null && transforms.TryGetValue(((Il2CppArrayBase)(object)bones)[i], out Transform value2)) ? value2 : value); } val4.bones = val5; if ((Object)(object)val3.rootBone != (Object)null && transforms.TryGetValue(val3.rootBone, out Transform value3)) { val4.rootBone = value3; } for (int j = 0; j < val3.sharedMesh.blendShapeCount; j++) { val4.SetBlendShapeWeight(j, val3.GetBlendShapeWeight(j)); } dictionary[((Object)sourceRenderer).GetInstanceID()] = (Renderer)(object)val4; } } return dictionary; } } internal sealed record BoneHubAvatar(long ModId, string Barcode, string Title, string ModName, string Author, string Description, string ThumbnailUrl) { public AvatarEntry ToEntry() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown return new AvatarEntry(ModId, Barcode, Title, ModName, Author, Description, ThumbnailUrl, true, true, (AvatarDownloadState)4, 0.0, (string)null); } } internal sealed class BoneHubRuntime : IDisposable { private sealed record PendingLoad(long ModId, IReadOnlyList Directories); private sealed record PendingEquip(BoneHubAvatar Avatar, string? PreviousBarcode, float Deadline); private sealed record PendingPackExit(long ModId, float Deadline, Action Completed); private const string SafeDeletionAvatarBarcode = "c3534c5a-94b2-40a4-912a-24a8506f6c79"; private readonly ConcurrentQueue _mainThread; private readonly string _modsRoot; private readonly Instance _log; private readonly Queue _loads = new Queue(); private readonly Dictionary> _installedDirectories = new Dictionary>(); private readonly Dictionary> _discoveredDirectories = new Dictionary>(); private readonly Dictionary> _avatars = new Dictionary>(); private readonly HashSet _quarantinedAvatars = new HashSet(StringComparer.OrdinalIgnoreCase); private readonly HashSet _suppressedModIds = new HashSet(); private readonly LibraryRefreshGate _libraryRefresh = new LibraryRefreshGate(); private readonly FusionCompatibilityBridge _fusion = new FusionCompatibilityBridge((Func>)null); private PendingLoad? _activeLoad; private List _activePallets = new List(); private int _activePalletIndex; private bool _initialScanComplete; private bool _equipping; private PendingEquip? _pendingEquip; private PendingPackExit? _pendingPackExit; private string? _lastFusionStatus; private string _restoreBarcode = string.Empty; private bool _restoreAttempted; private float _restoreNotBefore; private float _nativeSaveWaitDeadline; private bool _nativePersistenceActive; private int _rigInstanceId; private float _nextFusionStatusCheck; private float _nextRigIdentityCheck; private float _nextEquipVerification; private PullCordDevice? _bodyLogEffectSource; private int _bodyLogEffectRigId; private bool _bodyLogEffectMissingLogged; public bool WarehouseReady => AssetWarehouse.ready; public bool FusionSessionActive => _fusion.SessionActive; public string FusionStatus => _fusion.Status; public event Action>? AvatarsChanged; public event Action? EquipFinished; public event Action? StatusChanged; public BoneHubRuntime(ConcurrentQueue mainThread, string modsDirectory, Instance log) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown _mainThread = mainThread; _modsRoot = NormalizeDirectory(modsDirectory); _log = log; } public void RegisterInstalled(IEnumerable installed) { InstalledModRecord[] array = installed.ToArray(); HashSet activeIds = array.Select((InstalledModRecord mod) => mod.ModId).ToHashSet(); long[] array2 = _installedDirectories.Keys.Where((long id) => !activeIds.Contains(id)).ToArray(); foreach (long num2 in array2) { _installedDirectories.Remove(num2); if (_avatars.TryGetValue(num2, out List value)) { foreach (BoneHubAvatar item in value) { _quarantinedAvatars.Remove(item.Barcode); } } _avatars.Remove(num2); this.AvatarsChanged?.Invoke(num2, Array.Empty()); } InstalledModRecord[] array3 = array; foreach (InstalledModRecord val in array3) { string[] array4 = val.InstalledDirectories.Where((string path) => !string.IsNullOrWhiteSpace(path)).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); IReadOnlyList value2; bool flag = !_installedDirectories.TryGetValue(val.ModId, out value2) || !SameDirectories(value2, array4); _installedDirectories[val.ModId] = array4; _suppressedModIds.Remove(val.ModId); if (_initialScanComplete && flag) { QueuePackLoad(val.ModId, array4); } } } public void SetPendingDeletions(IEnumerable modIds) { _suppressedModIds.Clear(); foreach (long modId in modIds) { _suppressedModIds.Add(modId); } foreach (long suppressedModId in _suppressedModIds) { _installedDirectories.Remove(suppressedModId); _discoveredDirectories.Remove(suppressedModId); if (_avatars.Remove(suppressedModId)) { this.AvatarsChanged?.Invoke(suppressedModId, Array.Empty()); } } } public void LoadInstallation(InstalledModRecord installed) { string[] array = installed.InstalledDirectories.ToArray(); _installedDirectories[installed.ModId] = array; _suppressedModIds.Remove(installed.ModId); QueuePackLoad(installed.ModId, array); this.StatusChanged?.Invoke("Preparing " + installed.Name + " for live use…"); } public bool RetryInstallation(long modId) { if (!_installedDirectories.TryGetValue(modId, out IReadOnlyList value) || value.Count == 0) { return false; } PendingLoad? activeLoad = _activeLoad; if (((object)activeLoad != null && activeLoad.ModId == modId) || _loads.Any((PendingLoad load) => load.ModId == modId)) { return true; } QueuePackLoad(modId, value); this.StatusChanged?.Invoke("Preparing the installed avatar pack again..."); return true; } public IReadOnlyList GetAvatars(long modId) { if (!_avatars.TryGetValue(modId, out List value)) { return Array.Empty(); } return value.ToArray(); } public IReadOnlyList GetAllAvatars() { return (from @group in _avatars.Values.SelectMany((List avatars) => avatars).GroupBy((BoneHubAvatar avatar) => avatar.Barcode, StringComparer.OrdinalIgnoreCase) select @group.First()).OrderBy((BoneHubAvatar avatar) => avatar.Title, StringComparer.OrdinalIgnoreCase).ToArray(); } public bool IsModInstalled(long modId) { if (_avatars.TryGetValue(modId, out List value)) { return value.Count > 0; } return false; } public bool IsWearingPack(long modId) { RigManager rigManager = Player.RigManager; object obj; if (rigManager == null) { obj = null; } else { AvatarCrateReference avatarCrate = rigManager.AvatarCrate; if (avatarCrate == null) { obj = null; } else { Barcode barcode = ((ScannableReference)avatarCrate).Barcode; obj = ((barcode != null) ? barcode.ID : null); } } string barcode2 = (string)obj; if (string.IsNullOrWhiteSpace(barcode2) && (!TryReadNativeSavedAvatar(out barcode2) || string.IsNullOrWhiteSpace(barcode2))) { return false; } return GetAvatars(modId).Any((BoneHubAvatar avatar) => string.Equals(avatar.Barcode, barcode2, StringComparison.OrdinalIgnoreCase)); } public void LeavePackForDeletion(long modId, Action completed) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown if (!IsWearingPack(modId)) { completed(arg1: true, null); return; } if (_equipping || _pendingPackExit != null) { completed(arg1: false, "Another avatar change is already running."); return; } if (!AssetWarehouse.ready || (Object)(object)Player.RigManager == (Object)null) { completed(arg1: false, "The player rig is not ready to switch away from this pack."); return; } try { AvatarCrateReference val = new AvatarCrateReference("c3534c5a-94b2-40a4-912a-24a8506f6c79"); if ((Object)(object)((CrateReferenceT)(object)val).Crate == (Object)null) { completed(arg1: false, "BONELAB's safe PolyBlank avatar is unavailable."); return; } _equipping = true; _pendingPackExit = new PendingPackExit(modId, Time.unscaledTime + 4f, completed); this.StatusChanged?.Invoke("Switching to PolyBlank before deleting the active pack..."); string text = null; if (_fusion.SessionActive && _fusion.TrySwapAvatar("c3534c5a-94b2-40a4-912a-24a8506f6c79", ref text)) { return; } if (_fusion.SessionActive && !string.IsNullOrWhiteSpace(text)) { _log.Msg("Fusion safe-avatar switch fell back to BONELAB: " + text); } Player.RigManager.SwapAvatarCrate(((ScannableReference)val).Barcode, true, Action.op_Implicit((Action)delegate(bool success) { _mainThread.Enqueue(delegate { if (!success && !(_pendingPackExit == null)) { FinishPackExit(success: false, "BONELAB could not switch to PolyBlank. Nothing was deleted."); } }); })); } catch (Exception ex) { _equipping = false; _pendingPackExit = null; completed(arg1: false, "Could not switch avatars safely: " + ex.Message); } } public bool IsCurrentAvatar(string barcode) { if (string.IsNullOrWhiteSpace(barcode)) { return false; } try { RigManager rigManager = Player.RigManager; object a; if (rigManager == null) { a = null; } else { AvatarCrateReference avatarCrate = rigManager.AvatarCrate; if (avatarCrate == null) { a = null; } else { Barcode barcode2 = ((ScannableReference)avatarCrate).Barcode; a = ((barcode2 != null) ? barcode2.ID : null); } } return string.Equals((string?)a, barcode, StringComparison.OrdinalIgnoreCase) && _fusion.IsAvatarSynchronized(barcode); } catch { return false; } } public bool ResendCurrentAvatarToFusion(string barcode, out string? error) { if (!IsCurrentAvatar(barcode)) { error = "The equipped avatar changed before multiplayer sharing became ready."; return false; } return _fusion.TryResendCurrentAvatar(barcode, ref error); } public void ReportSharingStatus(string status) { if (!string.IsNullOrWhiteSpace(status)) { this.StatusChanged?.Invoke(status); } } public IReadOnlyList GetPackDirectories(long modId) { if (_installedDirectories.TryGetValue(modId, out IReadOnlyList value)) { return value.ToArray(); } if (_discoveredDirectories.TryGetValue(modId, out IReadOnlyList value2) && value2.Count > 0) { return value2.ToArray(); } return DiscoverPackDirectories(modId); } public void RefreshLocalLibrary() { _libraryRefresh.Request((double)Time.unscaledTime, 0.35); _restoreNotBefore = Time.unscaledTime + 0.75f; } public void RemovePack(long modId) { bool flag = _installedDirectories.Remove(modId); flag |= _discoveredDirectories.Remove(modId); PendingLoad? activeLoad = _activeLoad; if ((object)activeLoad != null && activeLoad.ModId == modId) { _activeLoad = null; } PendingLoad[] array = _loads.Where((PendingLoad load) => load.ModId != modId).ToArray(); _loads.Clear(); PendingLoad[] array2 = array; foreach (PendingLoad item in array2) { _loads.Enqueue(item); } if (_avatars.TryGetValue(modId, out List value)) { foreach (BoneHubAvatar item2 in value) { _quarantinedAvatars.Remove(item2.Barcode); } } if (flag | _avatars.Remove(modId)) { this.AvatarsChanged?.Invoke(modId, Array.Empty()); } } public BoneHubAvatar? FindAvatar(string barcode) { return GetAllAvatars().FirstOrDefault((BoneHubAvatar avatar) => string.Equals(avatar.Barcode, barcode, StringComparison.OrdinalIgnoreCase)); } public void RequestAvatarRestore(string barcode) { _restoreBarcode = barcode?.Trim() ?? string.Empty; _restoreAttempted = _restoreBarcode.Length == 0; _restoreNotBefore = Time.unscaledTime + 0.75f; _nativeSaveWaitDeadline = Time.unscaledTime + 10f; _nativePersistenceActive = false; } public void OnSceneChanged() { if (!_nativePersistenceActive && _restoreBarcode.Length != 0) { _restoreAttempted = false; _restoreNotBefore = Time.unscaledTime + 1f; _nativeSaveWaitDeadline = Time.unscaledTime + 10f; _fusion.ForceRefresh(); } } public void ForgetAvatars(IEnumerable barcodes) { string[] array = barcodes.Where((string barcode) => !string.IsNullOrWhiteSpace(barcode)).ToArray(); string[] array2 = array; foreach (string item in array2) { _quarantinedAvatars.Remove(item); } if (array.Any((string barcode) => string.Equals(barcode, _restoreBarcode, StringComparison.OrdinalIgnoreCase))) { _restoreBarcode = string.Empty; _restoreAttempted = true; } } public void Tick() { UpdateFusionStatus(); TrackLocalRig(); VerifyPendingPackExit(); VerifyPendingEquip(); if (!AssetWarehouse.ready) { return; } if (_libraryRefresh.TryConsume((double)Time.unscaledTime)) { _initialScanComplete = true; ScanLocalLibrary(); int count = GetAllAvatars().Count; this.StatusChanged?.Invoke((count == 0) ? "Asset Warehouse ready; no downloaded avatars found." : $"{count} downloaded avatar{((count == 1) ? string.Empty : "s")} ready."); } TryRestoreAvatar(); if ((object)_activeLoad == null && _loads.Count > 0) { _activeLoad = _loads.Dequeue(); _activePallets = _activeLoad.Directories.SelectMany((string directory) => PalletManifestLocator.FindAll(directory, SearchOption.TopDirectoryOnly)).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); _activePalletIndex = 0; LoadNextPallet(); } } private void VerifyPendingPackExit() { PendingPackExit pendingPackExit = _pendingPackExit; if ((object)pendingPackExit == null) { return; } try { RigManager rigManager = Player.RigManager; object a; if (rigManager == null) { a = null; } else { AvatarCrateReference avatarCrate = rigManager.AvatarCrate; if (avatarCrate == null) { a = null; } else { Barcode barcode = ((ScannableReference)avatarCrate).Barcode; a = ((barcode != null) ? barcode.ID : null); } } bool num = string.Equals((string?)a, "c3534c5a-94b2-40a4-912a-24a8506f6c79", StringComparison.OrdinalIgnoreCase); bool flag = !_fusion.SessionActive || _fusion.IsAvatarSynchronized("c3534c5a-94b2-40a4-912a-24a8506f6c79"); if (num && flag) { _restoreBarcode = "c3534c5a-94b2-40a4-912a-24a8506f6c79"; _restoreAttempted = true; _nativePersistenceActive = TryPersistNativeAvatar("c3534c5a-94b2-40a4-912a-24a8506f6c79", out string error); if (!_nativePersistenceActive) { _log.Warning("PolyBlank was equipped before deletion, but BONELAB could not save it: " + error); } FinishPackExit(success: true, null); } else if (!(Time.unscaledTime < pendingPackExit.Deadline)) { FinishPackExit(success: false, "Timed out while switching to PolyBlank. Nothing was deleted."); } } catch (Exception ex) { FinishPackExit(success: false, "Could not confirm the safe avatar: " + ex.Message); } } private void FinishPackExit(bool success, string? error) { PendingPackExit pendingPackExit = _pendingPackExit; _pendingPackExit = null; _equipping = false; if (!(pendingPackExit == null)) { pendingPackExit.Completed(success, error); } } public void Equip(BoneHubAvatar avatar) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown try { if (_equipping) { this.EquipFinished?.Invoke(avatar, arg2: false, "Another avatar change is already running."); return; } if (_quarantinedAvatars.Contains(avatar.Barcode)) { string text = "BONELAB previously rejected this avatar. Reload its pallet before trying again."; this.EquipFinished?.Invoke(avatar, arg2: false, text); this.StatusChanged?.Invoke(text); return; } string text2 = default(string); if (!_fusion.CanEquip(avatar.Barcode, ref text2)) { this.EquipFinished?.Invoke(avatar, arg2: false, text2); this.StatusChanged?.Invoke(text2 ?? "Fusion blocked that avatar change."); return; } if (!AssetWarehouse.ready || (Object)(object)Player.RigManager == (Object)null) { this.EquipFinished?.Invoke(avatar, arg2: false, "The player rig or Asset Warehouse is not ready."); return; } AvatarCrateReference crate = new AvatarCrateReference(avatar.Barcode); if ((Object)(object)((CrateReferenceT)(object)crate).Crate == (Object)null) { this.EquipFinished?.Invoke(avatar, arg2: false, "That avatar is not loaded in the Asset Warehouse."); return; } _equipping = true; this.StatusChanged?.Invoke("Checking avatar rig..."); ((CrateT)(object)((CrateReferenceT)(object)crate).Crate).LoadAsset(Action.op_Implicit((Action)delegate(GameObject prefab) { _mainThread.Enqueue(delegate { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { _equipping = false; _quarantinedAvatars.Add(avatar.Barcode); this.StatusChanged?.Invoke("BROKEN AVATAR - CANNOT EQUIP"); this.EquipFinished?.Invoke(avatar, arg2: false, "The avatar asset did not load for validation."); } else { AvatarRigValidationResult val = BoneHubAvatarRigValidator.Validate(prefab); if (!((AvatarRigValidationResult)(ref val)).CanEquip) { _equipping = false; _quarantinedAvatars.Add(avatar.Barcode); this.StatusChanged?.Invoke("BROKEN AVATAR - CANNOT EQUIP"); this.EquipFinished?.Invoke(avatar, arg2: false, ((AvatarRigValidationResult)(ref val)).Reason); _log.Warning("WristHub blocked a malformed avatar before BONELAB ArtRig: " + ((AvatarRigValidationResult)(ref val)).Reason); } else { _equipping = false; StartValidatedEquip(avatar, crate); } } }); })); } catch (Exception ex) { _equipping = false; _log.Error("Avatar swap could not start: " + ex.Message); this.EquipFinished?.Invoke(avatar, arg2: false, ex.Message); } } private void StartValidatedEquip(BoneHubAvatar avatar, AvatarCrateReference crate) { try { if (_equipping || (Object)(object)Player.RigManager == (Object)null) { this.EquipFinished?.Invoke(avatar, arg2: false, "The player rig changed while the avatar was being checked."); return; } AvatarCrateReference avatarCrate = Player.RigManager.AvatarCrate; object obj; if (avatarCrate == null) { obj = null; } else { Barcode barcode = ((ScannableReference)avatarCrate).Barcode; obj = ((barcode != null) ? barcode.ID : null); } string previousBarcode = (string)obj; string text = null; if (_fusion.SessionActive && _fusion.TrySwapAvatar(avatar.Barcode, ref text)) { _equipping = true; _pendingEquip = new PendingEquip(avatar, previousBarcode, Time.unscaledTime + 4f); this.StatusChanged?.Invoke("Broadcasting " + avatar.Title + " through Fusion..."); return; } if (_fusion.SessionActive && !string.IsNullOrWhiteSpace(text)) { _log.Msg("Fusion avatar broadcast fell back to BONELAB's guarded swap: " + text); } _equipping = true; this.StatusChanged?.Invoke("Equipping " + avatar.Title + "..."); Player.RigManager.SwapAvatarCrate(((ScannableReference)crate).Barcode, true, Action.op_Implicit((Action)delegate(bool success) { _mainThread.Enqueue(delegate { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown _equipping = false; if (!success && !string.IsNullOrWhiteSpace(previousBarcode) && previousBarcode != avatar.Barcode) { try { Player.RigManager.SwapAvatarCrate(new Barcode(previousBarcode), true, (Action)null); } catch (Exception ex2) { _log.Error("Avatar rollback failed: " + ex2.Message); } } if (!success) { _quarantinedAvatars.Add(avatar.Barcode); this.StatusChanged?.Invoke("Could not equip " + avatar.Title + "; restored the previous avatar."); this.EquipFinished?.Invoke(avatar, arg2: false, "BONELAB rejected the avatar swap."); } else { _equipping = true; _pendingEquip = new PendingEquip(avatar, previousBarcode, Time.unscaledTime + 1.25f); this.StatusChanged?.Invoke(_fusion.SessionActive ? ("Confirming " + avatar.Title + " with Fusion...") : ("Confirming " + avatar.Title + "...")); } }); })); } catch (Exception ex) { _equipping = false; _log.Error("Avatar swap could not start after validation: " + ex.Message); this.EquipFinished?.Invoke(avatar, arg2: false, ex.Message); } } private void TryRestoreAvatar() { //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_005b: 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_008e: Invalid comparison between Unknown and I4 if (_restoreAttempted || !_initialScanComplete || _equipping || (Object)(object)Player.RigManager == (Object)null || Time.unscaledTime < _restoreNotBefore) { return; } string barcode; AvatarRestoreDecision val = AvatarRestorePolicy.Decide(TryReadNativeSavedAvatar(out barcode), Time.unscaledTime >= _nativeSaveWaitDeadline, _restoreBarcode); if ((int)val == 1) { return; } if ((int)val == 0) { _nativePersistenceActive = true; _restoreAttempted = true; if (!string.IsNullOrWhiteSpace(barcode)) { _restoreBarcode = barcode; } _log.Msg("BONELAB's native avatar save owns scene restoration; no WristHub swap was needed."); return; } if ((int)val == 3) { _restoreAttempted = true; return; } AvatarCrateReference avatarCrate = Player.RigManager.AvatarCrate; object a; if (avatarCrate == null) { a = null; } else { Barcode barcode2 = ((ScannableReference)avatarCrate).Barcode; a = ((barcode2 != null) ? barcode2.ID : null); } if (string.Equals((string?)a, _restoreBarcode, StringComparison.OrdinalIgnoreCase)) { _restoreAttempted = true; _log.Msg("The previously equipped WristHub avatar was already active."); return; } BoneHubAvatar boneHubAvatar = FindAvatar(_restoreBarcode); if (boneHubAvatar == null) { _restoreAttempted = true; _log.Msg("The previously equipped WristHub avatar is no longer installed; BONELAB's current avatar was kept."); } else { _restoreAttempted = true; _log.Msg("Restoring the previously equipped WristHub avatar."); Equip(boneHubAvatar); } } private void VerifyPendingEquip() { //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown PendingEquip pendingEquip = _pendingEquip; if ((object)pendingEquip == null || Time.unscaledTime < _nextEquipVerification) { return; } _nextEquipVerification = Time.unscaledTime + 0.1f; try { RigManager rigManager = Player.RigManager; object a; if (rigManager == null) { a = null; } else { AvatarCrateReference avatarCrate = rigManager.AvatarCrate; if (avatarCrate == null) { a = null; } else { Barcode barcode = ((ScannableReference)avatarCrate).Barcode; a = ((barcode != null) ? barcode.ID : null); } } bool num = string.Equals((string?)a, pendingEquip.Avatar.Barcode, StringComparison.OrdinalIgnoreCase); bool flag = _fusion.IsAvatarSynchronized(pendingEquip.Avatar.Barcode); if (num && flag) { _pendingEquip = null; _equipping = false; _restoreBarcode = pendingEquip.Avatar.Barcode; _restoreAttempted = true; _nativePersistenceActive = TryPersistNativeAvatar(pendingEquip.Avatar.Barcode, out string error); if (!_nativePersistenceActive) { _log.Warning("BONELAB avatar persistence was unavailable; WristHub fallback remains active: " + error); } PlayNativeAvatarChangeEffect(); string obj = (_fusion.SessionActive ? ("Equipped " + pendingEquip.Avatar.Title + " · Fusion synchronized.") : ("Equipped " + pendingEquip.Avatar.Title + ".")); this.StatusChanged?.Invoke(obj); this.EquipFinished?.Invoke(pendingEquip.Avatar, arg2: true, null); } else { if (Time.unscaledTime < pendingEquip.Deadline) { return; } _pendingEquip = null; _equipping = false; if (!_fusion.SessionActive && !string.IsNullOrWhiteSpace(pendingEquip.PreviousBarcode)) { try { RigManager rigManager2 = Player.RigManager; if (rigManager2 != null) { rigManager2.SwapAvatarCrate(new Barcode(pendingEquip.PreviousBarcode), true, (Action)null); } } catch (Exception ex) { _log.Error("Avatar verification rollback failed: " + ex.Message); } } string text = (_fusion.SessionActive ? "Fusion did not accept that avatar. Check the lobby's custom-avatar permission and active gamemode overrides." : "The avatar swap did not remain active; the previous avatar was restored."); this.StatusChanged?.Invoke(text); this.EquipFinished?.Invoke(pendingEquip.Avatar, arg2: false, text); } } catch (Exception ex2) { _pendingEquip = null; _equipping = false; _log.Error("Avatar verification failed: " + ex2.Message); this.EquipFinished?.Invoke(pendingEquip.Avatar, arg2: false, ex2.Message); } } private void UpdateFusionStatus() { if (!(Time.unscaledTime < _nextFusionStatusCheck)) { _nextFusionStatusCheck = Time.unscaledTime + 1f; string status = _fusion.Status; if (!string.Equals(status, _lastFusionStatus, StringComparison.Ordinal)) { _lastFusionStatus = status; this.StatusChanged?.Invoke(status); } } } private void TrackLocalRig() { if (Time.unscaledTime < _nextRigIdentityCheck) { return; } _nextRigIdentityCheck = Time.unscaledTime + 0.25f; int num = 0; try { num = ((!((Object)(object)Player.RigManager == (Object)null)) ? ((Object)Player.RigManager).GetInstanceID() : 0); } catch { } if (num != 0 && num != _rigInstanceId) { _rigInstanceId = num; _bodyLogEffectSource = null; _bodyLogEffectRigId = 0; _bodyLogEffectMissingLogged = false; if (!_nativePersistenceActive && _restoreBarcode.Length != 0) { _restoreAttempted = false; _restoreNotBefore = Time.unscaledTime + 1f; _nativeSaveWaitDeadline = Time.unscaledTime + 10f; _fusion.ForceRefresh(); _log.Msg("WristHub detected a new local rig; native avatar save detection was queued before any fallback."); } } } private void PlayNativeAvatarChangeEffect() { try { RigManager rig = Player.RigManager; if ((Object)(object)rig == (Object)null) { return; } int instanceID = ((Object)rig).GetInstanceID(); if ((Object)(object)_bodyLogEffectSource == (Object)null || _bodyLogEffectRigId != instanceID) { _bodyLogEffectSource = ((IEnumerable)((Component)rig).GetComponentsInChildren(true)).FirstOrDefault((Func)((PullCordDevice device) => (Object)(object)device != (Object)null && ((Object)(object)device.rm == (Object)null || (Object)(object)device.rm == (Object)(object)rig))); _bodyLogEffectRigId = instanceID; } if ((Object)(object)_bodyLogEffectSource == (Object)null) { if (!_bodyLogEffectMissingLogged) { _bodyLogEffectMissingLogged = true; _log.Msg("BONELAB's BodyLog effect source is unavailable on this rig; the avatar equip still completed."); } } else { _bodyLogEffectSource.PlayAvatarParticleEffects(); _bodyLogEffectMissingLogged = false; } } catch (Exception ex) { if (!_bodyLogEffectMissingLogged) { _bodyLogEffectMissingLogged = true; _log.Warning("BONELAB's avatar-change effect could not play: " + ex.Message); } } } private static bool TryReadNativeSavedAvatar(out string barcode) { barcode = string.Empty; try { Save activeSave = DataManager.ActiveSave; PlayerSettings val = ((activeSave != null) ? activeSave.PlayerSettings : null); if (val == null) { return false; } barcode = val.CurrentAvatar?.Trim() ?? string.Empty; return true; } catch { return false; } } private static bool TryPersistNativeAvatar(string barcode, out string? error) { error = null; try { Save activeSave = DataManager.ActiveSave; PlayerSettings val = ((activeSave != null) ? activeSave.PlayerSettings : null); if (val == null) { error = "The active BONELAB player profile is not ready."; return false; } string currentAvatar = val.CurrentAvatar; val.CurrentAvatar = barcode; if (DataManager.TrySaveActiveSave((SaveFlags)0)) { return true; } val.CurrentAvatar = currentAvatar; error = "BONELAB declined to save the active player profile."; return false; } catch (Exception ex) { error = ex.Message; return false; } } private void LoadNextPallet() { if ((object)_activeLoad == null) { return; } if (_activePalletIndex >= _activePallets.Count) { PendingLoad activeLoad = _activeLoad; _activeLoad = null; ScanMod(activeLoad.ModId, activeLoad.Directories); this.StatusChanged?.Invoke((GetAvatars(activeLoad.ModId).Count > 0) ? "Avatar catalog refreshed." : "Installed safely; no avatar crates were found in this pallet."); return; } string palletPath = _activePallets[_activePalletIndex++]; try { UniTask val = AssetWarehouse.Instance.LoadPalletFromFolderAsync(palletPath, true, (string)null, (ModListing)null); Awaiter awaiter = val.GetAwaiter(); awaiter.OnCompleted((Action)delegate { _mainThread.Enqueue(delegate { try { awaiter.GetResult(); } catch (Exception ex2) { _log.Error("Could not live-load " + palletPath + ": " + ex2.Message); } LoadNextPallet(); }); }); } catch (Exception ex) { _log.Error("Could not schedule live pallet load: " + ex.Message); LoadNextPallet(); } } private void QueuePackLoad(long modId, IReadOnlyList directories) { if (directories.Count != 0) { PendingLoad? activeLoad = _activeLoad; if (((object)activeLoad == null || activeLoad.ModId != modId) && !_loads.Any((PendingLoad load) => load.ModId == modId)) { _loads.Enqueue(new PendingLoad(modId, directories)); } } } private static bool SameDirectories(IReadOnlyList left, IReadOnlyList right) { if (left.Count == right.Count) { return left.ToHashSet(StringComparer.OrdinalIgnoreCase).SetEquals(right); } return false; } private void ScanMod(long modId, IReadOnlyList directories) { try { if (_suppressedModIds.Contains(modId)) { _avatars.Remove(modId); this.AvatarsChanged?.Invoke(modId, Array.Empty()); return; } string[] source = directories.Select(NormalizeDirectory).ToArray(); Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); Enumerator enumerator = AssetWarehouse.Instance.GetPalletManifests().GetEnumerator(); while (enumerator.MoveNext()) { PalletManifest current = enumerator.Current; if (current == null || (Object)(object)current.Pallet == (Object)null || string.IsNullOrWhiteSpace(current.PalletPath)) { continue; } string manifestPath = Path.GetFullPath(current.PalletPath); if (!File.Exists(manifestPath) || !source.Any((string directory) => IsInside(manifestPath, directory))) { continue; } LocalModMetadata val = LocalModMetadata.Read(source.FirstOrDefault((string directory) => IsInside(manifestPath, directory)) ?? Path.GetDirectoryName(manifestPath) ?? _modsRoot); long modId2 = ((modId > 0) ? modId : val.ModId); Enumerator enumerator2 = current.Pallet.Crates.GetEnumerator(); while (enumerator2.MoveNext()) { AvatarCrate val2 = ((Il2CppObjectBase)enumerator2.Current).TryCast(); if ((Object)(object)val2 == (Object)null) { continue; } Barcode barcode = ((Scannable)val2).Barcode; if (!string.IsNullOrWhiteSpace((barcode != null) ? barcode.ID : null)) { string iD = ((Scannable)val2).Barcode.ID; string iD2 = ((Scannable)val2).Barcode.ID; string title = ((Scannable)val2).Title ?? "Unnamed avatar"; string modName = val.ModName; object author; if (!string.IsNullOrWhiteSpace(val.Creator)) { author = val.Creator; } else { Pallet pallet = ((Crate)val2).Pallet; author = ((pallet != null) ? pallet.Author : null) ?? "Unknown creator"; } dictionary[iD] = new BoneHubAvatar(modId2, iD2, title, modName, (string)author, ((Scannable)val2).Description ?? val.Summary, val.ThumbnailUrl); } } } _avatars[modId] = dictionary.Values.OrderBy((BoneHubAvatar avatar) => avatar.Title).ToList(); foreach (string key in dictionary.Keys) { _quarantinedAvatars.Remove(key); } this.AvatarsChanged?.Invoke(modId, _avatars[modId].ToArray()); } catch (Exception ex) { _log.Error($"Avatar discovery failed for mod {modId}: {ex.Message}"); } } private void ScanLocalLibrary() { try { Dictionary> dictionary = new Dictionary>(); Dictionary> dictionary2 = new Dictionary>(); Enumerator enumerator = AssetWarehouse.Instance.GetPalletManifests().GetEnumerator(); while (enumerator.MoveNext()) { PalletManifest current = enumerator.Current; if (current == null || (Object)(object)current.Pallet == (Object)null || string.IsNullOrWhiteSpace(current.PalletPath)) { continue; } string fullPath = Path.GetFullPath(current.PalletPath); if (!File.Exists(fullPath) || !IsInside(fullPath, _modsRoot)) { continue; } string text = ResolvePackageRoot(fullPath); LocalModMetadata val = LocalModMetadata.Read(text); if (_suppressedModIds.Contains(val.ModId)) { continue; } if (!dictionary2.TryGetValue(val.ModId, out var value)) { value = new HashSet(StringComparer.OrdinalIgnoreCase); dictionary2[val.ModId] = value; } value.Add(text); if (!dictionary.TryGetValue(val.ModId, out var value2)) { value2 = new Dictionary(StringComparer.OrdinalIgnoreCase); dictionary[val.ModId] = value2; } Enumerator enumerator2 = current.Pallet.Crates.GetEnumerator(); while (enumerator2.MoveNext()) { AvatarCrate val2 = ((Il2CppObjectBase)enumerator2.Current).TryCast(); if ((Object)(object)val2 == (Object)null) { continue; } Barcode barcode = ((Scannable)val2).Barcode; if (!string.IsNullOrWhiteSpace((barcode != null) ? barcode.ID : null)) { Dictionary dictionary3 = value2; string iD = ((Scannable)val2).Barcode.ID; long modId = val.ModId; string iD2 = ((Scannable)val2).Barcode.ID; string title = ((Scannable)val2).Title ?? "Unnamed avatar"; string modName = val.ModName; object author; if (!string.IsNullOrWhiteSpace(val.Creator)) { author = val.Creator; } else { Pallet pallet = ((Crate)val2).Pallet; author = ((pallet != null) ? pallet.Author : null) ?? "Unknown creator"; } dictionary3[iD] = new BoneHubAvatar(modId, iD2, title, modName, (string)author, ((Scannable)val2).Description ?? val.Summary, val.ThumbnailUrl); } } } long[] array = _avatars.Keys.Where((long id) => !_installedDirectories.ContainsKey(id)).ToArray(); foreach (long key in array) { _avatars.Remove(key); } foreach (KeyValuePair> item in dictionary) { _avatars[item.Key] = item.Value.Values.OrderBy((BoneHubAvatar avatar) => avatar.Title, StringComparer.OrdinalIgnoreCase).ToList(); foreach (string key2 in item.Value.Keys) { _quarantinedAvatars.Remove(key2); } } _discoveredDirectories.Clear(); foreach (KeyValuePair> item2 in dictionary2) { _discoveredDirectories[item2.Key] = item2.Value.ToArray(); } this.AvatarsChanged?.Invoke(long.MinValue, Array.Empty()); _log.Msg($"WristHub indexed {dictionary.Values.Sum((Dictionary group) => group.Count)} downloaded avatar crates across {dictionary.Count} BONELAB mods."); } catch (Exception ex) { _log.Error("Downloaded avatar discovery failed: " + ex.Message); } } private string ResolvePackageRoot(string manifestPath) { string text = Path.GetRelativePath(_modsRoot, manifestPath).Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).FirstOrDefault((string part) => !string.IsNullOrWhiteSpace(part) && part != "."); if (!string.IsNullOrWhiteSpace(text)) { return Path.Combine(_modsRoot, text); } return Path.GetDirectoryName(manifestPath) ?? _modsRoot; } private IReadOnlyList DiscoverPackDirectories(long modId) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); try { Enumerator enumerator = AssetWarehouse.Instance.GetPalletManifests().GetEnumerator(); while (enumerator.MoveNext()) { PalletManifest current = enumerator.Current; if ((Object)(object)((current != null) ? current.Pallet : null) == (Object)null || string.IsNullOrWhiteSpace(current.PalletPath)) { continue; } string fullPath = Path.GetFullPath(current.PalletPath); if (File.Exists(fullPath) && IsInside(fullPath, _modsRoot)) { string text = ResolvePackageRoot(fullPath); if (LocalModMetadata.Read(text).ModId == modId) { hashSet.Add(text); } } } } catch (Exception ex) { _log.Warning("Pack-folder discovery failed for deletion: " + ex.Message); } if (hashSet.Count > 0) { _discoveredDirectories[modId] = hashSet.ToArray(); } return hashSet.ToArray(); } private static bool IsInside(string path, string root) { string text = Path.GetFullPath(path).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); string text2 = NormalizeDirectory(root); if (!string.Equals(text, text2, StringComparison.OrdinalIgnoreCase)) { return text.StartsWith(text2 + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase); } return true; } private static string NormalizeDirectory(string path) { return Path.GetFullPath(path).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); } public void Dispose() { _pendingEquip = null; _pendingPackExit = null; _loads.Clear(); _avatars.Clear(); _quarantinedAvatars.Clear(); _suppressedModIds.Clear(); _installedDirectories.Clear(); } } internal static class BoneHubTheme { public static readonly Color Cyan = new Color(0.34f, 0.91f, 1f); public static readonly Color Blue = new Color(0.42f, 0.66f, 1f); public static readonly Color Violet = new Color(0.66f, 0.55f, 0.98f); public static readonly Color Green = new Color(0.35f, 0.9f, 0.66f); public static readonly Color Amber = new Color(1f, 0.79f, 0.44f); public static readonly Color Muted = new Color(0.47f, 0.57f, 0.66f); public static readonly Color Danger = new Color(1f, 0.42f, 0.52f); private static Texture2D? _background; private static Texture2D? _logo; public static Texture2D? Background => _background; public static void Initialize(Instance log) { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); _background = LoadTexture(executingAssembly, "WristHub.Assets.Background.png", "WristHub Background"); _logo = LoadTexture(executingAssembly, "WristHub.Assets.Logo.png", "WristHub Logo"); } catch (Exception ex) { log.Error("WristHub visual assets could not be loaded; using the color theme: " + ex.Message); } } public static Page Style(Page page, bool showLogo = false, float opacity = 0.88f) { if (_background != null) { page.Background = _background; } if (showLogo && _logo != null) { page.Logo = _logo; } page.BackgroundOpacity = opacity; page.ElementSpacing = 48f; return page; } public static string Brand(string subtitle) { return "BONEHUB " + Escape(subtitle).ToUpperInvariant() + ""; } public static string PageTitle(string symbol, string title) { return $"{Escape(symbol)} {Escape(title)}"; } public static string Section(string title) { return "" + Escape(title).ToUpperInvariant() + ""; } public static string Label(string name, string value) { return $"{Escape(name).ToUpperInvariant()} {Escape(value)}"; } public static string Status(string label, string colorHex) { return $" {Escape(label)} "; } public static string PrimaryAction(string label) { return " " + Escape(label) + " → "; } public static string SecondaryAction(string label) { return "" + Escape(label) + " ›"; } public static string Hint(string label) { return "" + Escape(label) + ""; } public static string Body(string value) { return "" + Escape(value) + ""; } public static string Stars(double rating) { int num = Math.Clamp((int)Math.Round(rating), 0, 5); return $"{new string('★', num)}{new string('★', 5 - num)} {rating:0.0}"; } public static string ProgressBar(double progress, int segments = 12) { int num = Math.Clamp((int)Math.Round(progress * (double)segments), 0, segments); return $"{new string('■', num)}{new string('■', segments - num)}"; } public static string CompactNumber(long value) { if (value < 1000000) { if (value >= 1000) { return $"{(double)value / 1000.0:0.#}K"; } return value.ToString("N0"); } return $"{(double)value / 1000000.0:0.#}M"; } public static string Escape(string? value) { return (value ?? string.Empty).Replace("&", "&", StringComparison.Ordinal).Replace("<", "<", StringComparison.Ordinal).Replace(">", ">", StringComparison.Ordinal); } private static Texture2D LoadTexture(Assembly assembly, string resourceName, string textureName) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0072: Expected O, but got Unknown using Stream stream = assembly.GetManifestResourceStream(resourceName) ?? throw new InvalidOperationException("Missing embedded resource " + resourceName + "."); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = textureName, hideFlags = (HideFlags)32 }; if (!ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(memoryStream.ToArray()), true)) { throw new InvalidDataException("Unity could not decode " + resourceName + "."); } return val; } } internal sealed class BoneHubThumbnailCache : IDisposable { private const int MaximumBytes = 2097152; private const int MaximumMemoryEntries = 32; private const int MaximumDiskEntries = 96; private readonly string _directory; private readonly ConcurrentQueue _mainThread; private readonly Instance _log; private readonly HttpClient _http = new HttpClient { Timeout = TimeSpan.FromSeconds(20.0) }; private readonly Dictionary _memory = new Dictionary(StringComparer.Ordinal); private readonly Dictionary>> _loading = new Dictionary>>(StringComparer.Ordinal); private readonly Dictionary _uris = new Dictionary(StringComparer.Ordinal); private readonly HashSet _decodeRetried = new HashSet(StringComparer.Ordinal); private readonly Queue _memoryOrder = new Queue(); private readonly object _sync = new object(); private readonly CancellationTokenSource _shutdown = new CancellationTokenSource(); private int _disposed; public BoneHubThumbnailCache(string directory, ConcurrentQueue mainThread, Instance log) { _directory = Path.GetFullPath(directory); _mainThread = mainThread; _log = log; _http.DefaultRequestHeaders.UserAgent.ParseAdd("WristHub/2.0.1"); try { Directory.CreateDirectory(_directory); PruneDiskCache(); } catch (Exception ex) { _log.Msg("Thumbnail disk cache is unavailable: " + ex.Message); } } public void Load(string url, Action completed) { if (Volatile.Read(in _disposed) != 0 || !Uri.TryCreate(url, UriKind.Absolute, out Uri result) || result.Scheme != Uri.UriSchemeHttps) { return; } string key = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(result.AbsoluteUri))).ToLowerInvariant(); lock (_sync) { if (_memory.TryGetValue(key, out Texture2D value)) { completed(value); return; } if (_loading.TryGetValue(key, out List> value2)) { value2.Add(completed); return; } _loading[key] = new List> { completed }; _uris[key] = result; } LoadAsync(result, key, _shutdown.Token); } private async Task LoadAsync(Uri uri, string key, CancellationToken cancellationToken) { try { string path = Path.Combine(_directory, key + ".image"); byte[] bytes; if (File.Exists(path)) { try { long length = new FileInfo(path).Length; if ((length <= 0 || length > 2097152) ? true : false) { throw new InvalidDataException("Cached thumbnail size is invalid."); } bytes = await File.ReadAllBytesAsync(path, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); File.SetLastWriteTimeUtc(path, DateTime.UtcNow); } catch when (!cancellationToken.IsCancellationRequested) { try { File.Delete(path); } catch { } bytes = await DownloadAsync(uri, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); await SaveAsync(path, bytes, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } } else { bytes = await DownloadAsync(uri, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); await SaveAsync(path, bytes, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } if (Volatile.Read(in _disposed) == 0) { _mainThread.Enqueue(delegate { Decode(key, bytes); }); } } catch (OperationCanceledException) { } catch (Exception ex2) { _log.Msg("Thumbnail was skipped: " + ex2.Message); lock (_sync) { _loading.Remove(key); _uris.Remove(key); _decodeRetried.Remove(key); } } } private async Task DownloadAsync(Uri uri, CancellationToken cancellationToken) { using HttpResponseMessage response = await _http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); response.EnsureSuccessStatusCode(); if (response.Content.Headers.ContentLength > 2097152) { throw new InvalidDataException("Thumbnail exceeds WristHub's 2 MB limit."); } byte[] obj = await response.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); int num = obj.Length; if ((num <= 0 || num > 2097152) ? true : false) { throw new InvalidDataException("Thumbnail data is empty or too large."); } return obj; } private async Task SaveAsync(string path, byte[] bytes, CancellationToken cancellationToken) { Directory.CreateDirectory(_directory); await File.WriteAllBytesAsync(path + ".tmp", bytes, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); File.Move(path + ".tmp", path, overwrite: true); } private void Decode(string key, byte[] bytes) { //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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if (Volatile.Read(in _disposed) != 0) { return; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = "WristHub Thumbnail " + key.Substring(0, 8), hideFlags = (HideFlags)32 }; if (!ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(bytes), true)) { throw new InvalidDataException("Unity could not decode this thumbnail."); } Action[] array; lock (_sync) { array = (_loading.Remove(key, out List> value) ? value.ToArray() : Array.Empty>()); _uris.Remove(key); _decodeRetried.Remove(key); _memory[key] = val; _memoryOrder.Enqueue(key); while (_memoryOrder.Count > 32) { string key2 = _memoryOrder.Dequeue(); if (_memory.Remove(key2, out Texture2D value2)) { Object.Destroy((Object)(object)value2); } } } if (Volatile.Read(in _disposed) != 0) { return; } Action[] array2 = array; foreach (Action action in array2) { try { action(val); } catch (Exception ex) { _log.Msg("Thumbnail UI callback was skipped: " + ex.Message); } } } catch (Exception ex2) { Uri uri = null; lock (_sync) { if (_uris.TryGetValue(key, out Uri value3) && _decodeRetried.Add(key)) { uri = value3; } else { _loading.Remove(key); _uris.Remove(key); _decodeRetried.Remove(key); } } try { File.Delete(Path.Combine(_directory, key + ".image")); } catch { } if (uri != null && Volatile.Read(in _disposed) == 0) { _log.Msg("A corrupt thumbnail cache entry was discarded and will be downloaded again."); LoadAsync(uri, key, _shutdown.Token); } else { _log.Msg("Thumbnail decode was skipped: " + ex2.Message); } } } private void PruneDiskCache() { foreach (FileInfo item in (from file in new DirectoryInfo(_directory).EnumerateFiles("*.image") orderby file.LastWriteTimeUtc descending select file).Skip(96)) { try { item.Delete(); } catch { } } foreach (string item2 in Directory.EnumerateFiles(_directory, "*.tmp")) { try { File.Delete(item2); } catch { } } } public void Dispose() { if (Interlocked.Exchange(ref _disposed, 1) != 0) { return; } _shutdown.Cancel(); _shutdown.Dispose(); _http.Dispose(); lock (_sync) { foreach (Texture2D value in _memory.Values) { Object.Destroy((Object)(object)value); } } _memory.Clear(); lock (_sync) { _loading.Clear(); } _uris.Clear(); _decodeRetried.Clear(); } } internal sealed class BoneHubWristWatch : IDisposable { private const float MaximumViewDistance = 0.8f; private readonly Action _openLauncher; private readonly Func _displayOpen; private readonly BoneHubPreferences _preferences; private readonly Instance _log; private readonly WristRearmGate _rearm = new WristRearmGate(); private readonly List _ring = new List(); private readonly MaterialPropertyBlock _propertyBlock = new MaterialPropertyBlock(); private GameObject? _root; private Transform? _attachedHand; private Renderer? _reactor; private float _observedFor; private bool _attachErrorLogged; private bool _ringVisible; private int _ringLitCount = -1; private Color _reactorColor = new Color(0.2f, 0.9f, 1f); public bool Enabled { get { return _preferences.WatchEnabled; } set { _preferences.WatchEnabled = value; } } public bool RaiseToOpen { get { return _preferences.RaiseToOpen; } set { _preferences.RaiseToOpen = value; } } public bool UseLeftWrist { get { return _preferences.UseLeftWrist; } set { _preferences.UseLeftWrist = value; Recenter(); } } public float WatchScale { get { return _preferences.WatchScale; } set { _preferences.WatchScale = Mathf.Clamp(value, 0.65f, 1.6f); } } public float DwellSeconds { get { return 1.5f; } set { _preferences.DwellSeconds = 1.5f; } } public float OutwardOffset { get { return _preferences.OutwardOffset; } set { _preferences.OutwardOffset = Mathf.Clamp(value, 0.015f, 0.06f); } } public float FingerOffset { get { return _preferences.FingerOffset; } set { _preferences.FingerOffset = Mathf.Clamp(value, -0.055f, 0.025f); } } public bool ReducedMotion { get { return _preferences.ReducedMotion; } set { _preferences.ReducedMotion = value; } } public BoneHubWristWatch(Action openLauncher, Func displayOpen, BoneHubPreferences preferences, Instance log) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //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) _openLauncher = openLauncher; _displayOpen = displayOpen; _preferences = preferences; _log = log; _preferences.DwellSeconds = 1.5f; } public void Tick() { if (!Enabled) { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } ResetProgress(); return; } if ((Object)(object)Player.Head == (Object)null) { Detach(); return; } try { Hand val = (UseLeftWrist ? Player.LeftHand : Player.RightHand); if ((Object)(object)val == (Object)null) { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } ResetProgress(); return; } if ((Object)(object)_root == (Object)null || (Object)(object)_attachedHand != (Object)(object)((Component)val).transform) { Attach(((Component)val).transform); } if (!((Object)(object)_root == (Object)null)) { _root.SetActive(true); SolvePose(((Component)val).transform); Observe(Player.Head); } } catch (Exception ex) { if (!_attachErrorLogged) { _attachErrorLogged = true; _log.Error("WristHub wrist launcher could not attach: " + ex.Message); } Detach(); } } public void RequireLookAway() { _rearm.RequireLookAway(); ResetProgress(); } public void OnDownloadChanged(DownloadJob job) { //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: Invalid comparison between Unknown and I4 //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0055: 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_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_0071: 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) DownloadState state = job.State; Color reactorColor = (((int)state == 5) ? new Color(0.32f, 0.9f, 0.62f) : (((int)state != 6) ? new Color(0.2f, 0.9f, 1f) : new Color(1f, 0.38f, 0.46f))); _reactorColor = reactorColor; if ((Object)(object)_reactor != (Object)null) { SetColor(_reactor, _reactorColor); } } public void SetStatus(string status, bool error = false, bool success = false) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0062: Unknown result type (might be due to invalid IL or missing references) _reactorColor = (error ? new Color(1f, 0.38f, 0.46f) : (success ? new Color(0.32f, 0.9f, 0.62f) : new Color(0.2f, 0.9f, 1f))); if ((Object)(object)_reactor != (Object)null) { SetColor(_reactor, _reactorColor); } } public void Recenter() { Detach(); ResetProgress(); } public void Dispose() { Detach(); } private void Attach(Transform hand) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0053: 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_007b: 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_00a1: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0134: 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_0194: 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_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) Detach(); _attachedHand = hand; _root = new GameObject(UseLeftWrist ? "[WristHub] Left Wrist Reactor" : "[WristHub] Right Wrist Reactor"); _root.transform.SetParent(hand, true); CreatePart("Strap", new Vector3(0f, -0.006f, 0f), new Vector3(0.052f, 0.007f, 0.105f), new Color(0.01f, 0.018f, 0.027f), (PrimitiveType)3); CreatePart("Dark Face", Vector3.zero, new Vector3(0.07f, 0.012f, 0.058f), new Color(0.018f, 0.038f, 0.052f), (PrimitiveType)3); CreatePart("Glass", new Vector3(0f, 0.008f, 0f), new Vector3(0.064f, 0.003f, 0.052f), new Color(0.025f, 0.08f, 0.1f), (PrimitiveType)3); _reactor = CreatePart("Reactor", new Vector3(0f, 0.011f, 0f), new Vector3(0.012f, 0.0025f, 0.012f), _reactorColor, (PrimitiveType)2); _ring.Clear(); for (int i = 0; i < 48; i++) { float num = (float)i / 48f * (float)Math.PI * 2f; Renderer val = CreatePart("Flat Gaze Ring", new Vector3(Mathf.Sin(num) * 0.035f, 0.013f, Mathf.Cos(num) * 0.035f), new Vector3(0.006f, 0.00045f, 0.0012f), new Color(0.055f, 0.2f, 0.25f), (PrimitiveType)3); ((Component)val).transform.localRotation = Quaternion.Euler(0f, (0f - num) * 57.29578f, 0f); ((Component)val).gameObject.SetActive(false); _ring.Add(val); } _ringVisible = true; _ringLitCount = -1; SetRing(-1f); SolvePose(hand); _attachErrorLogged = false; _log.Msg("WristHub text-free wrist launcher attached. Continuous gaze opens it in 1.5 seconds."); } private void Observe(Transform head) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0101: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || !RaiseToOpen || _displayOpen()) { SetRing(-1f); ResetProgress(); return; } Vector3 val = _root.transform.position - head.position; float magnitude = ((Vector3)(ref val)).magnitude; float num = CurrentHeightRatio(); bool flag = magnitude >= 0.1f * num && magnitude <= 0.8f * num && magnitude > 0.01f && Vector3.Dot(head.forward, val / magnitude) >= 0.86f; if (_rearm.RequiresLookAway) { _rearm.Update(flag, (double)Time.unscaledDeltaTime); SetRing(-1f); return; } if (!flag) { ResetProgress(); SetRing(-1f); return; } _observedFor += Time.unscaledDeltaTime; WristActivationState val2 = WristActivationMath.Evaluate((double)_observedFor, (double)DwellSeconds); SetRing((float)((WristActivationState)(ref val2)).RingProgress); if (((WristActivationState)(ref val2)).Activate) { _rearm.RequireLookAway(); SetRing(-1f); _openLauncher(); } } private void SolvePose(Transform hand) { //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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0061: 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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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) if (!((Object)(object)_root == (Object)null)) { float num = CurrentHeightRatio(); Vector3 val = (UseLeftWrist ? (-1f) : 1f) * hand.right; Quaternion val2 = Quaternion.FromToRotation(hand.up, val); Quaternion val3 = Quaternion.AngleAxis(UseLeftWrist ? 8f : (-8f), hand.up); _root.transform.SetPositionAndRotation(hand.position + val * (OutwardOffset * num) + hand.forward * (FingerOffset * num), val3 * val2 * hand.rotation); _root.transform.localScale = Vector3.one * (WatchScale * num); } } private static float CurrentHeightRatio() { try { RigManager rigManager = Player.RigManager; float? obj; if (rigManager == null) { obj = null; } else { Avatar avatar = rigManager.avatar; obj = ((avatar != null) ? new float?(avatar.height) : ((float?)null)); } float? num = obj; return AvatarUiScaleMath.ResolveMenuScale(num.GetValueOrDefault()); } catch { return 1f; } } private Renderer CreatePart(string name, Vector3 position, Vector3 scale, Color color, PrimitiveType primitive = (PrimitiveType)3) { //IL_0019: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { throw new InvalidOperationException("Watch root is unavailable."); } GameObject obj = GameObject.CreatePrimitive(primitive); ((Object)obj).name = name; obj.transform.SetParent(_root.transform, false); obj.transform.localPosition = position; obj.transform.localScale = scale; Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = obj.GetComponent(); SetColor(component2, color); return component2; } private void SetRing(float progress) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) bool flag = progress >= 0f; int num = Mathf.CeilToInt(Mathf.Clamp01(progress) * (float)_ring.Count); if (flag == _ringVisible && (!flag || num == _ringLitCount)) { return; } bool flag2 = flag != _ringVisible; int ringLitCount = _ringLitCount; for (int i = 0; i < _ring.Count; i++) { Renderer val = _ring[i]; if (flag2) { ((Component)val).gameObject.SetActive(flag); } if (flag) { bool flag3 = i < ringLitCount; bool flag4 = i < num; if (flag2 || flag3 != flag4) { SetColor(val, flag4 ? new Color(0.2f, 0.9f, 1f) : new Color(0.055f, 0.2f, 0.25f)); } } } _ringVisible = flag; _ringLitCount = num; } private void SetColor(Renderer renderer, Color color) { //IL_0022: 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) _propertyBlock.Clear(); renderer.GetPropertyBlock(_propertyBlock); _propertyBlock.SetColor("_Color", color); _propertyBlock.SetColor("_BaseColor", color); renderer.SetPropertyBlock(_propertyBlock); } private void ResetProgress() { _observedFor = 0f; } private void Detach() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _attachedHand = null; _reactor = null; _ring.Clear(); _ringVisible = false; _ringLitCount = -1; ResetProgress(); } } internal sealed class LobbyAvatarSharingBridge { private readonly Instance _log; private Assembly? _assembly; private bool _reportedMissing; private float _nextRefresh; public bool Available => ResolveAssembly() != null; public bool LobbyReadyToAnnounce { get { try { return ReadStaticBoolean(ResolveAssembly()?.GetType("ModioModNetworker.MainClass"), "confirmedHostHasIt"); } catch { return false; } } } public bool RegistrationRefreshBusy { get { try { Type type = ResolveAssembly()?.GetType("ModioModNetworker.MainClass"); return ReadStaticBoolean(type, "handlingInstalled") || ReadStaticBoolean(type, "refreshInstalledModsRequested"); } catch { return false; } } } public LobbyAvatarSharingBridge(Instance log) { _log = log; } public void RequestRefresh(bool immediate = false) { float num = (float)Environment.TickCount64 / 1000f; if (!immediate && num < _nextRefresh) { return; } _nextRefresh = num + 1f; try { ((ResolveAssembly()?.GetType("ModioModNetworker.MainClass"))?.GetMethod("RequestInstallCheck", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null))?.Invoke(null, new object[1] { immediate ? 0f : 0.25f }); } catch (Exception ex) { _log.Msg("Warning: Fusion mod registration refresh failed: " + ex.Message); } } public bool IsRegistered(IEnumerable palletBarcodes) { HashSet hashSet = palletBarcodes.Where((string value) => !string.IsNullOrWhiteSpace(value)).ToHashSet(StringComparer.OrdinalIgnoreCase); if (hashSet.Count == 0) { return false; } try { foreach (object item in SnapshotItems((ResolveAssembly()?.GetType("ModioModNetworker.MainClass"))?.GetField("InstalledModInfos", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null))) { if (item != null) { string text = ReadString(item, "palletBarcode") ?? ReadString(item, "PalletBarcode"); if (text != null && hashSet.Contains(text)) { return true; } } } } catch { } return false; } public bool IsRegistered(IEnumerable palletBarcodes, long modId) { HashSet hashSet = palletBarcodes.Where((string value) => !string.IsNullOrWhiteSpace(value)).ToHashSet(StringComparer.OrdinalIgnoreCase); if (hashSet.Count == 0 || modId <= 0) { return false; } try { foreach (object item in SnapshotItems((ResolveAssembly()?.GetType("ModioModNetworker.MainClass"))?.GetField("InstalledModInfos", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null))) { if (item == null) { continue; } string text = ReadString(item, "palletBarcode") ?? ReadString(item, "PalletBarcode"); if (text != null && hashSet.Contains(text)) { object obj = ReadMember(item, "ModInfo"); if (string.Equals((obj == null) ? null : ReadString(obj, "numericalId"), modId.ToString(), StringComparison.OrdinalIgnoreCase)) { return true; } } } } catch { } return false; } public bool IsSubscribed(long modId) { try { if (!((ResolveAssembly()?.GetType("ModioModNetworker.MainClass"))?.GetField("subscribedModIoNumericalIds", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is IEnumerable enumerable)) { return false; } foreach (object item in enumerable) { if (string.Equals(item?.ToString(), modId.ToString(), StringComparison.OrdinalIgnoreCase)) { return true; } } } catch { } return false; } public bool IsLocalAvatarAnnounced(long modId) { try { if (!((ResolveAssembly()?.GetType("ModioModNetworker.ModlistMessage"))?.GetField("avatarMods", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is IDictionary dictionary)) { return false; } Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly candidate) => candidate.GetName().Name?.Equals("LabFusion", StringComparison.OrdinalIgnoreCase) ?? false)?.GetType("LabFusion.Player.PlayerIDManager"); object obj = type?.GetProperty("LocalID", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) ?? type?.GetField("LocalID", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj == null || !dictionary.Contains(obj)) { return false; } object obj2 = dictionary[obj]; return string.Equals((obj2 == null) ? null : ReadString(obj2, "numericalId"), modId.ToString(), StringComparison.OrdinalIgnoreCase); } catch { return false; } } public bool Unsubscribe(long modId) { return InvokeManager("UnSubscribe", modId.ToString()); } public bool Subscribe(long modId) { return InvokeManager("Subscribe", modId.ToString()); } private bool InvokeManager(string name, string modId) { try { Type type = ResolveAssembly()?.GetType("ModioModNetworker.ModFileManager"); MethodInfo methodInfo = type?.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo candidate) => candidate.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && candidate.GetParameters().Length == 1); if (methodInfo == null) { return false; } object obj = (methodInfo.IsStatic ? null : Activator.CreateInstance(type)); object obj2 = ((methodInfo.GetParameters()[0].ParameterType == typeof(long)) ? ((object)long.Parse(modId)) : modId); methodInfo.Invoke(obj, new object[1] { obj2 }); return true; } catch (Exception ex) { _log.Msg("Warning: Fusion subscription " + name + " failed: " + ex.Message); return false; } } private Assembly? ResolveAssembly() { if (_assembly != null) { return _assembly; } _assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.GetName().Name?.Equals("ModioModNetworker", StringComparison.OrdinalIgnoreCase) ?? false); if (_assembly == null && !_reportedMissing) { _reportedMissing = true; _log.Msg("Warning: ModioModNetworker is not loaded. Local installs work, but Fusion auto-download sharing is unavailable."); } return _assembly; } private static string? ReadString(object value, string name) { Type type = value.GetType(); object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value)?.ToString(); if (obj == null) { PropertyInfo? property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property == null) { return null; } object? value2 = property.GetValue(value); if (value2 == null) { return null; } obj = value2.ToString(); } return (string?)obj; } private static object? ReadMember(object value, string name) { Type type = value.GetType(); object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value); if (obj == null) { PropertyInfo? property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property == null) { return null; } obj = property.GetValue(value); } return obj; } private static IReadOnlyList SnapshotItems(object? value) { if (value == null) { return Array.Empty(); } if (value is IList list) { for (int i = 0; i < 2; i++) { try { int count = list.Count; object[] array = new object[count]; for (int j = 0; j < count; j++) { array[j] = list[j]; } return array; } catch (ArgumentOutOfRangeException) { } } return Array.Empty(); } if (!(value is IEnumerable source)) { return Array.Empty(); } try { return source.Cast().ToArray(); } catch (InvalidOperationException) { return Array.Empty(); } } private static bool ReadStaticBoolean(Type? type, string name) { if (type == null) { return false; } object obj = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) ?? type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } }