Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ItemShareFix v1.2.0
ItemShareFix/ItemShareFix.Core.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ItemShareFix.Core")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0")] [assembly: AssemblyProduct("ItemShareFix.Core")] [assembly: AssemblyTitle("ItemShareFix.Core")] [assembly: AssemblyVersion("1.2.0.0")] 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; } } } namespace ItemShareFix.Core { public sealed class AuthoritativeEligibilityMirror<TOwner, TOption> where TOwner : class where TOption : class { private sealed class Entry { public uint Request; public double NextRequest; public bool HasSnapshot; public WeakReference<TOwner> Owner { get; } public HashSet<TOption> Allowed { get; } = new HashSet<TOption>(); public HashSet<uint> Collectors { get; } = new HashSet<uint>(); public Entry(TOwner owner) { Owner = new WeakReference<TOwner>(owner); } } private readonly Dictionary<int, Entry> _entries = new Dictionary<int, Entry>(); private readonly List<int> _stale = new List<int>(); private uint _sequence; public int Count => _entries.Count; public uint Request(int id, TOwner owner, double now) { if (!_entries.TryGetValue(id, out Entry value) || !Matches(value, owner)) { value = (_entries[id] = new Entry(owner)); } if (now < value.NextRequest) { return 0u; } value.NextRequest = now + 1.0; if (value.Request != 0) { return value.Request; } if (++_sequence == 0) { _sequence++; } return value.Request = _sequence; } public bool Apply(int id, TOwner owner, uint request, IEnumerable<TOption> allowed, IEnumerable<uint>? collectors = null) { if (request == 0 || !_entries.TryGetValue(id, out Entry value) || !Matches(value, owner) || value.Request != request) { return false; } value.Allowed.Clear(); foreach (TOption item in allowed) { value.Allowed.Add(item); } value.Collectors.Clear(); if (collectors != null) { foreach (uint collector in collectors) { if (collector != 0) { value.Collectors.Add(collector); } } } value.HasSnapshot = true; value.Request = 0u; return true; } public bool Contains(int id, TOwner owner, TOption option) { if (_entries.TryGetValue(id, out Entry value) && Matches(value, owner)) { return value.Allowed.Contains(option); } return false; } public bool HasRetainedOptions(int id, TOwner owner) { if (_entries.TryGetValue(id, out Entry value) && Matches(value, owner) && value.HasSnapshot) { return value.Allowed.Count > 0; } return false; } public bool TryCollected(int id, TOwner owner, uint master, out bool collected) { collected = false; if (master == 0 || !_entries.TryGetValue(id, out Entry value) || !Matches(value, owner) || !value.HasSnapshot) { return false; } collected = value.Collectors.Contains(master); return true; } private static bool Matches(Entry entry, TOwner owner) { if (entry.Owner.TryGetTarget(out var target)) { return target == owner; } return false; } public void Prune(Func<TOwner, bool> live) { _stale.Clear(); foreach (KeyValuePair<int, Entry> entry in _entries) { if (!entry.Value.Owner.TryGetTarget(out var target) || !live(target)) { _stale.Add(entry.Key); } } foreach (int item in _stale) { _entries.Remove(item); } } public void Clear() { _entries.Clear(); _stale.Clear(); } } public static class BlockingModalLifecyclePolicy { public const string PauseScreenControllerTypeName = "RoR2.UI.PauseScreenController"; public const string SimpleDialogBoxTypeName = "RoR2.UI.SimpleDialogBox"; public const string PickupPickerPanelTypeName = "RoR2.UI.PickupPickerPanel"; public static bool IsKnownBlockingModalTypeName(string? typeName) { if (!(typeName == "RoR2.UI.PauseScreenController") && !(typeName == "RoR2.UI.SimpleDialogBox")) { return typeName == "RoR2.UI.PickupPickerPanel"; } return true; } public static bool ShouldSeedObservedCandidate(bool knownBlockingType, bool sceneObjectValid) { return knownBlockingType && sceneObjectValid; } public static bool ShouldAddObservedInstance(bool instanceAlreadyCached) { return !instanceAlreadyCached; } public static bool LifecycleSeedRequiresGlobalDiscovery(bool observedCandidateCached) { return !observedCandidateCached; } public static bool SuppressionStateChanged(bool previousSuppressed, bool currentSuppressed) { return previousSuppressed != currentSuppressed; } public static bool PreserveRareFallbackCadence(float fallbackSeconds) { return fallbackSeconds >= 5f; } } public sealed class ClaimLedger { private readonly Dictionary<ClaimKey, ClaimRecord> _records = new Dictionary<ClaimKey, ClaimRecord>(); private readonly Dictionary<HistoricalClaimKey, HistoricalClaimRecord> _history = new Dictionary<HistoricalClaimKey, HistoricalClaimRecord>(); public IReadOnlyCollection<ClaimRecord> Records => _records.Values; public IReadOnlyCollection<HistoricalClaimRecord> HistoricalRecords => _history.Values; public ClaimRecord Ensure(SharedPickupKey pickup, ParticipantKey participant, ParticipantState state, int stage) { if (!TryEnsure(pickup, participant, state, stage, out ClaimRecord record)) { throw new InvalidOperationException("Historical pickup barrier rejected participant generation: " + pickup.ToString() + "/" + participant); } return record; } public bool TryEnsure(SharedPickupKey pickup, ParticipantKey participant, ParticipantState state, int stage, out ClaimRecord record) { ClaimKey key = new ClaimKey(pickup, participant); if (_records.TryGetValue(key, out ClaimRecord value)) { record = value; return true; } if (IsHistoricallyBlocked(pickup, participant.StableUser)) { record = null; return false; } ClaimState claimState = ((state == ParticipantState.FullyDead) ? ClaimState.Deferred : ClaimState.Pending); if (state == ParticipantState.Disconnected) { claimState = ClaimState.CancelledDisconnected; } ClaimRecord claimRecord = new ClaimRecord(key, claimState, stage); if (claimState == ClaimState.CancelledDisconnected) { claimRecord.TerminalStage = stage; SetHistory(pickup, participant.StableUser, HistoricalClaimState.CancelledDisconnected, stage); } _records.Add(key, claimRecord); record = claimRecord; return true; } public bool TryGet(SharedPickupKey pickup, ParticipantKey participant, out ClaimRecord record) { return _records.TryGetValue(new ClaimKey(pickup, participant), out record); } public bool IsHistoricallyBlocked(SharedPickupKey pickup, StableUserKey stableUser) { return _history.ContainsKey(new HistoricalClaimKey(pickup, stableUser)); } public bool TryGetHistorical(SharedPickupKey pickup, StableUserKey stableUser, out HistoricalClaimRecord record) { return _history.TryGetValue(new HistoricalClaimKey(pickup, stableUser), out record); } public IReadOnlyList<HistoricalClaimRecord> HistoricalFor(StableUserKey stableUser) { return (from x in _history.Values where x.Key.StableUser.Equals(stableUser) orderby x.Key.Pickup.Value select x).ToArray(); } public bool MarkCollected(SharedPickupKey pickup, ParticipantKey participant, int stage) { if (!TryGet(pickup, participant, out ClaimRecord record)) { return false; } if (record.State != ClaimState.Pending) { return false; } record.State = ClaimState.Collected; record.TerminalStage = stage; SetHistory(pickup, participant.StableUser, HistoricalClaimState.Collected, stage); return true; } public int TransitionParticipant(ParticipantKey participant, ParticipantState from, ParticipantState to, int stage) { int num = 0; ClaimRecord[] array = _records.Values.Where((ClaimRecord x) => x.Key.Participant.Equals(participant)).ToArray(); foreach (ClaimRecord claimRecord in array) { switch (to) { case ParticipantState.Disconnected: if (claimRecord.State == ClaimState.Pending || claimRecord.State == ClaimState.Deferred) { claimRecord.State = ClaimState.CancelledDisconnected; claimRecord.TerminalStage = stage; SetHistory(claimRecord.Key.Pickup, participant.StableUser, HistoricalClaimState.CancelledDisconnected, stage); num++; } break; case ParticipantState.FullyDead: if (claimRecord.State == ClaimState.Pending) { claimRecord.State = ClaimState.Deferred; num++; } break; } } return num; } public bool MarkDeferredGranted(ClaimKey key, int stage) { if (!_records.TryGetValue(key, out ClaimRecord value)) { return false; } if (value.State != ClaimState.Deferred) { return false; } value.State = ClaimState.GrantedDeferred; value.TerminalStage = stage; SetHistory(value.Key.Pickup, value.Key.Participant.StableUser, HistoricalClaimState.GrantedDeferred, stage); return true; } public IReadOnlyList<ClaimRecord> DeferredFor(ParticipantKey participant, int beforeStage) { return (from x in _records.Values where x.Key.Participant.Equals(participant) && x.State == ClaimState.Deferred && x.CreatedStage < beforeStage orderby x.CreatedStage, x.Key.Pickup.Value select x).ToArray(); } public int TransferPickup(SharedPickupKey oldPickup, SharedPickupKey newPickup) { if (oldPickup.Equals(newPickup)) { return 0; } ClaimRecord[] array = _records.Values.Where((ClaimRecord x) => x.Key.Pickup.Equals(oldPickup)).ToArray(); HistoricalClaimRecord[] array2 = _history.Values.Where((HistoricalClaimRecord x) => x.Key.Pickup.Equals(oldPickup)).ToArray(); ClaimRecord[] array3 = array; foreach (ClaimRecord claimRecord in array3) { ClaimKey key = new ClaimKey(newPickup, claimRecord.Key.Participant); if (_records.ContainsKey(key)) { throw new InvalidOperationException("Transfer would create duplicate pickup/participant state: " + key); } } HistoricalClaimRecord[] array4 = array2; foreach (HistoricalClaimRecord historicalClaimRecord in array4) { HistoricalClaimKey key2 = new HistoricalClaimKey(newPickup, historicalClaimRecord.Key.StableUser); if (_history.TryGetValue(key2, out HistoricalClaimRecord value) && value.State != historicalClaimRecord.State) { throw new InvalidOperationException("Transfer would create conflicting historical pickup/stable-user state: " + key2); } } array3 = array; foreach (ClaimRecord claimRecord2 in array3) { ClaimKey key3 = claimRecord2.Key; ClaimKey key4 = new ClaimKey(newPickup, key3.Participant); _records.Remove(key3); claimRecord2.Key = key4; _records.Add(key4, claimRecord2); } array4 = array2; foreach (HistoricalClaimRecord historicalClaimRecord2 in array4) { HistoricalClaimKey key5 = historicalClaimRecord2.Key; HistoricalClaimKey key6 = new HistoricalClaimKey(newPickup, key5.StableUser); _history.Remove(key5); if (_history.TryGetValue(key6, out HistoricalClaimRecord value2)) { if (historicalClaimRecord2.Stage > value2.Stage) { value2.Stage = historicalClaimRecord2.Stage; } } else { historicalClaimRecord2.Key = key6; _history.Add(key6, historicalClaimRecord2); } } return array.Length; } public int OnStageTransition(int newStage) { int num = 0; KeyValuePair<ClaimKey, ClaimRecord>[] array = _records.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<ClaimKey, ClaimRecord> keyValuePair = array[i]; ClaimState state = keyValuePair.Value.State; if (state == ClaimState.Pending || state == ClaimState.Collected || state == ClaimState.CancelledDisconnected || state == ClaimState.GrantedDeferred) { _records.Remove(keyValuePair.Key); num++; } } _history.Clear(); return num; } public int Clear() { int result = _records.Count + _history.Count; _records.Clear(); _history.Clear(); return result; } public int RemoveTerminalOlderThan(int stageExclusive) { int num = 0; KeyValuePair<ClaimKey, ClaimRecord>[] array = _records.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<ClaimKey, ClaimRecord> keyValuePair = array[i]; int? terminalStage = keyValuePair.Value.TerminalStage; if (terminalStage.HasValue && terminalStage.Value < stageExclusive) { _records.Remove(keyValuePair.Key); num++; } } KeyValuePair<HistoricalClaimKey, HistoricalClaimRecord>[] array2 = _history.ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair<HistoricalClaimKey, HistoricalClaimRecord> keyValuePair2 = array2[i]; if (keyValuePair2.Value.Stage < stageExclusive) { _history.Remove(keyValuePair2.Key); num++; } } return num; } private void SetHistory(SharedPickupKey pickup, StableUserKey stableUser, HistoricalClaimState state, int stage) { HistoricalClaimKey key = new HistoricalClaimKey(pickup, stableUser); if (_history.TryGetValue(key, out HistoricalClaimRecord value)) { if (value.State != state) { if (value.State == HistoricalClaimState.Collected || value.State == HistoricalClaimState.GrantedDeferred) { return; } value.State = state; } if (stage > value.Stage) { value.Stage = stage; } } else { _history.Add(key, new HistoricalClaimRecord(key, state, stage)); } } } public enum CommandOptionPickupSource { None, NestedPickup, DirectCompatibilityFallback } public readonly struct CommandOptionPickupDecision<T> { public bool HasValue { get; } public T Value { get; } public CommandOptionPickupSource Source { get; } public bool ExactSource { get; } public bool Disagreement { get; } public CommandOptionPickupDecision(bool hasValue, T value, CommandOptionPickupSource source, bool exactSource, bool disagreement) { HasValue = hasValue; Value = value; Source = source; ExactSource = exactSource; Disagreement = disagreement; } } public static class CommandOptionSourcePolicy { public const string AuthoritativeSourceToken = "nested-pickup"; public const string FallbackSourceToken = "direct-fallback"; public const string UnresolvedSourceToken = "unresolved"; public static CommandOptionPickupDecision<T> Resolve<T>(bool nestedAvailable, T nestedValue, bool directAvailable, T directValue) { if (nestedAvailable) { bool disagreement = directAvailable && !EqualityComparer<T>.Default.Equals(nestedValue, directValue); return new CommandOptionPickupDecision<T>(hasValue: true, nestedValue, CommandOptionPickupSource.NestedPickup, exactSource: true, disagreement); } if (directAvailable) { return new CommandOptionPickupDecision<T>(hasValue: true, directValue, CommandOptionPickupSource.DirectCompatibilityFallback, exactSource: false, disagreement: false); } return new CommandOptionPickupDecision<T>(hasValue: false, default(T), CommandOptionPickupSource.None, exactSource: false, disagreement: false); } public static string SourceToken(CommandOptionPickupSource source) { return source switch { CommandOptionPickupSource.NestedPickup => "nested-pickup", CommandOptionPickupSource.DirectCompatibilityFallback => "direct-fallback", _ => "unresolved", }; } } public enum CommandShareabilityState { Unresolved, AllShareable, AllUnshareable, Mixed } public readonly struct CommandShareabilityDecision { public CommandShareabilityState State { get; } public bool MarkerEligible => State == CommandShareabilityState.AllShareable; public string DiagnosticToken => State switch { CommandShareabilityState.AllShareable => "all-shareable", CommandShareabilityState.AllUnshareable => "all-unshareable", CommandShareabilityState.Mixed => "mixed", _ => "unresolved", }; public string FilterReason => State switch { CommandShareabilityState.AllUnshareable => "upstream-not-shareable", CommandShareabilityState.Mixed => "mixed-shareability", CommandShareabilityState.Unresolved => "shareability-unresolved", _ => string.Empty, }; public CommandShareabilityDecision(CommandShareabilityState state) { State = state; } } public static class CommandShareabilityPolicy { public static CommandShareabilityDecision Evaluate(IReadOnlyList<bool?> optionShareability, IReadOnlyList<bool> excludedOptions) { if (optionShareability.Count != excludedOptions.Count) { return new CommandShareabilityDecision(CommandShareabilityState.Unresolved); } List<bool?> list = new List<bool?>(optionShareability.Count); bool flag = false; for (int i = 0; i < optionShareability.Count; i++) { if (excludedOptions[i]) { flag = true; } else { list.Add(optionShareability[i]); } } if (list.Count == 0 && flag) { return new CommandShareabilityDecision(CommandShareabilityState.AllUnshareable); } return Evaluate(list); } public static CommandShareabilityDecision Evaluate(IEnumerable<bool?>? optionShareability) { if (optionShareability == null) { return new CommandShareabilityDecision(CommandShareabilityState.Unresolved); } bool flag = false; bool flag2 = false; bool flag3 = false; foreach (bool? item in optionShareability) { flag = true; if (!item.HasValue) { return new CommandShareabilityDecision(CommandShareabilityState.Unresolved); } if (item.Value) { flag2 = true; } else { flag3 = true; } } if (!flag) { return new CommandShareabilityDecision(CommandShareabilityState.Unresolved); } if (flag2 && flag3) { return new CommandShareabilityDecision(CommandShareabilityState.Mixed); } if (flag2) { return new CommandShareabilityDecision(CommandShareabilityState.AllShareable); } return new CommandShareabilityDecision(CommandShareabilityState.AllUnshareable); } } public enum DiagnosticSeverity { Error, Warning, Info, Debug } public static class DiagnosticPolicy { public static bool Allows(bool enabled, string? level, DiagnosticSeverity severity) { if (!enabled) { return false; } DiagnosticSeverity diagnosticSeverity = ((!string.Equals(level, "Error", StringComparison.OrdinalIgnoreCase)) ? (string.Equals(level, "Warning", StringComparison.OrdinalIgnoreCase) ? DiagnosticSeverity.Warning : (string.Equals(level, "Debug", StringComparison.OrdinalIgnoreCase) ? DiagnosticSeverity.Debug : DiagnosticSeverity.Info)) : DiagnosticSeverity.Error); return severity <= diagnosticSeverity; } public static string ExactRemoteOperation(string? evidence) { if (string.IsNullOrEmpty(evidence)) { return "not-probed"; } int num = evidence.IndexOf("exactRemoteOperationPreset=", StringComparison.Ordinal); if (num < 0) { return "unavailable-or-not-probed"; } int start = num + "exactRemoteOperationPreset=".Length; if (Matches(evidence, start, "true")) { return "true"; } if (Matches(evidence, start, "false")) { return "false"; } return "unavailable-fail-closed"; } private static bool Matches(string evidence, int start, string value) { if (evidence.IndexOf(value, start, StringComparison.Ordinal) != start) { return false; } int num = start + value.Length; if (num != evidence.Length && evidence[num] != ';') { return char.IsWhiteSpace(evidence[num]); } return true; } } public enum NetworkDestroyDisposition { IgnoreStillAuthoritative, HoldForAuthoritativeConfirmation } public static class DisconnectConfirmationPolicy { public static bool AllowsImmediateCancelFromNetworkDestroy => false; public static bool UsesObjectNamePrefabOrBodyHeuristics => false; public static NetworkDestroyDisposition EvaluateNetworkDestroy(bool participantResolved, bool authoritativePresence) { if (!(participantResolved && authoritativePresence)) { return NetworkDestroyDisposition.HoldForAuthoritativeConfirmation; } return NetworkDestroyDisposition.IgnoreStillAuthoritative; } public static bool ShouldConfirmDisconnect(bool participantAbsentFromAuthoritativeControllerList, bool absenceGraceElapsed) { return participantAbsentFromAuthoritativeControllerList && absenceGraceElapsed; } } public enum DlcPickupKind { Other, Hallowed, Hex, Page } public readonly struct DlcSharingSettings { public bool Hallowed { get; } public bool Hex { get; } public bool Pages { get; } public DlcSharingSettings(bool hallowed, bool hex, bool pages) { Hallowed = hallowed; Hex = hex; Pages = pages; } public bool Allows(DlcPickupKind kind) { return kind switch { DlcPickupKind.Page => Pages, DlcPickupKind.Hex => Hex, DlcPickupKind.Hallowed => Hallowed, _ => false, }; } } public static class DlcPickupSharingPolicy { public static bool CanShare(DlcPickupKind kind, DlcSharingSettings settings, bool hidden, bool consumed, bool worldUnique, bool objectiveRelated, bool progressionExcluded, bool activePageSpell) { if (settings.Allows(kind) && !hidden && !consumed && !worldUnique && !objectiveRelated && !progressionExcluded) { return kind != DlcPickupKind.Page || activePageSpell; } return false; } } public sealed class SharedInteractionContext<T> where T : class { private sealed class Frame : IDisposable { private readonly SharedInteractionContext<T> _owner; private bool _disposed; public T? Key { get; } public bool AlreadyOwned { get; } public Frame(SharedInteractionContext<T> owner, T? key, bool alreadyOwned) { _owner = owner; Key = key; AlreadyOwned = alreadyOwned; } public void Dispose() { if (!_disposed) { if (_owner._frames.Count == 0 || _owner._frames.Peek() != this) { throw new InvalidOperationException("Shared pickup scope disposal order mismatch."); } _owner._frames.Pop(); _disposed = true; } } } private readonly Stack<Frame> _frames = new Stack<Frame>(); public IDisposable Enter(T? key, bool alreadyOwned) { Frame frame = new Frame(this, key, alreadyOwned); _frames.Push(frame); return frame; } public bool IsOwned(T key) { if (_frames.Count > 0 && _frames.Peek().AlreadyOwned) { return _frames.Peek().Key == key; } return false; } } public sealed class SharedOptionPolicy<T> where T : class { private readonly HashSet<T> _allowed = new HashSet<T>(); public IEnumerable<T> Allowed => _allowed; public void Clear() { _allowed.Clear(); } public bool Contains(T option) { return _allowed.Contains(option); } public void Observe(T option, bool alreadyShared, bool currentlyShareable) { if (currentlyShareable) { _allowed.Add(option); } else if (!alreadyShared) { _allowed.Remove(option); } } } public enum GenerationProbeState { NeverResolved, Resolved, Frozen } public enum UnsupportedProbeDisposition { NoOwnershipEstablished, FreezePreserveExistingState } public sealed class GenerationProbeGate { private ParticipantKey? _provenParticipant; public GenerationProbeState State { get; private set; } public bool HasProvenParticipant => _provenParticipant.HasValue; public ParticipantKey ProvenParticipant => _provenParticipant ?? throw new InvalidOperationException("No proven participant exists for this generation."); public bool CanCreateClaims => State == GenerationProbeState.Resolved; public bool CanUseHistoricalBarrier => HasProvenParticipant; public bool CanGrantDeferred(ParticipantState exactState) { if (State == GenerationProbeState.Resolved) { return exactState == ParticipantState.Alive; } return false; } public bool TryResolve(ParticipantKey participant) { if (_provenParticipant.HasValue && !_provenParticipant.Value.Equals(participant)) { return false; } _provenParticipant = participant; State = GenerationProbeState.Resolved; return true; } public UnsupportedProbeDisposition ObserveUnsupported() { if (!_provenParticipant.HasValue) { State = GenerationProbeState.NeverResolved; return UnsupportedProbeDisposition.NoOwnershipEstablished; } State = GenerationProbeState.Frozen; return UnsupportedProbeDisposition.FreezePreserveExistingState; } } public enum ImmediateGiveDecision { AllowUpstream, SuppressHistoricalBarrier, SuppressFullyDeadDeferred, SuppressExistingDeferredEntitlement } public static class ImmediateGivePolicy { public static ImmediateGiveDecision Decide(bool stableIdentityResolved, ParticipantState? participantState, bool deadPlayerDeferredItemsEnabled, bool historicalBarrierForCurrentPickup, bool deferredEntitlementReadyForCurrentPickup = false) { if (!stableIdentityResolved) { return ImmediateGiveDecision.AllowUpstream; } if (historicalBarrierForCurrentPickup) { return ImmediateGiveDecision.SuppressHistoricalBarrier; } if (deferredEntitlementReadyForCurrentPickup) { if (participantState.HasValue && participantState.Value == ParticipantState.FullyDead && deadPlayerDeferredItemsEnabled) { return ImmediateGiveDecision.SuppressFullyDeadDeferred; } return ImmediateGiveDecision.SuppressExistingDeferredEntitlement; } return ImmediateGiveDecision.AllowUpstream; } public static bool ShouldSuppress(bool stableIdentityResolved, ParticipantState? participantState, bool deadPlayerDeferredItemsEnabled, bool historicalBarrierForCurrentPickup, bool deferredEntitlementReadyForCurrentPickup = false) { return Decide(stableIdentityResolved, participantState, deadPlayerDeferredItemsEnabled, historicalBarrierForCurrentPickup, deferredEntitlementReadyForCurrentPickup) != ImmediateGiveDecision.AllowUpstream; } } public static class ItemShareActiveGatePolicy { public static bool ShouldCorrectIsDown(bool upstreamOriginalIsDown, bool authoritativeControllerPresent, bool exactGenerationProven, ParticipantState participantState) { if (upstreamOriginalIsDown && authoritativeControllerPresent && exactGenerationProven) { return participantState == ParticipantState.SupportDrone; } return false; } public static bool CorrectIsDown(bool upstreamOriginalIsDown, bool authoritativeControllerPresent, bool exactGenerationProven, ParticipantState participantState) { if (!ShouldCorrectIsDown(upstreamOriginalIsDown, authoritativeControllerPresent, exactGenerationProven, participantState)) { return upstreamOriginalIsDown; } return false; } public static bool CountsAsOutstandingCollector(bool authoritativeControllerPresent, ParticipantState participantState) { if (authoritativeControllerPresent) { if (participantState != ParticipantState.Alive) { return participantState == ParticipantState.SupportDrone; } return true; } return false; } public static bool IsDeadAutoShareTarget(bool upstreamOriginalIsDown, bool authoritativeControllerPresent, bool exactGenerationProven, ParticipantState participantState) { return CorrectIsDown(upstreamOriginalIsDown, authoritativeControllerPresent, exactGenerationProven, participantState); } } public readonly struct LocalCommandPresentationDecision { public bool AllLocalStateResolved { get; } public bool AnyLocalPending { get; } public bool SuppressWorldPresentation { get; } public LocalCommandPresentationDecision(bool allLocalStateResolved, bool anyLocalPending, bool suppressWorldPresentation) { AllLocalStateResolved = allLocalStateResolved; AnyLocalPending = anyLocalPending; SuppressWorldPresentation = suppressWorldPresentation; } } public static class LocalCommandPresentationPolicy { public static LocalCommandPresentationDecision Evaluate(IReadOnlyList<bool?> localPickedStates) { if (localPickedStates == null) { throw new ArgumentNullException("localPickedStates"); } if (localPickedStates.Count == 0) { return new LocalCommandPresentationDecision(allLocalStateResolved: false, anyLocalPending: false, suppressWorldPresentation: false); } bool flag = true; bool flag2 = false; for (int i = 0; i < localPickedStates.Count; i++) { bool? flag3 = localPickedStates[i]; if (!flag3.HasValue) { flag = false; } else if (!flag3.Value) { flag2 = true; } } bool suppressWorldPresentation = flag && !flag2; return new LocalCommandPresentationDecision(flag, flag2, suppressWorldPresentation); } } public static class LocalParticipantPresentationPolicy { public static ParticipantState Classify(bool masterAvailable, bool exactRemoteOperationSignal, bool bodyPresent) { if (!masterAvailable) { return ParticipantState.Disconnected; } if (exactRemoteOperationSignal) { return ParticipantState.SupportDrone; } if (bodyPresent) { return ParticipantState.Alive; } return ParticipantState.FullyDead; } } public static class LocalPickupSuppressionPolicy { public static bool AllowsAuthoritativePickupDestroy => false; public static bool AllowsSharedRootDisable => false; public static bool AllowsSharedColliderDisable => false; public static bool ShouldSuppressProcessVisual(bool featureEnabled, bool upstreamHideCollectedEnabled, int localParticipantCount, int collectedLocalParticipantCount) { if (featureEnabled && upstreamHideCollectedEnabled && localParticipantCount > 0) { return collectedLocalParticipantCount == localParticipantCount; } return false; } public static bool ShouldSuppressInteractor(bool featureEnabled, bool upstreamHideCollectedEnabled, bool shareablePickup, bool interactorIsLocal, bool interactorHasCollected) { return featureEnabled && upstreamHideCollectedEnabled && shareablePickup && interactorIsLocal && interactorHasCollected; } } public readonly struct MarkerExpansionCandidate { public long ClusterKey { get; } public int MemberCount { get; } public float DistanceMeters { get; } public float ReticleDistancePixels1080 { get; } public MarkerExpansionCandidate(long clusterKey, int memberCount, float distanceMeters, float reticleDistancePixels1080) { ClusterKey = clusterKey; MemberCount = Math.Max(0, memberCount); DistanceMeters = distanceMeters; ReticleDistancePixels1080 = reticleDistancePixels1080; } } public sealed class MarkerAdaptiveLodTracker { public const int DenseClusterMinimumMembers = 3; public const float FocusEnterPixels1080 = 72f; public const float FocusExitPixels1080 = 110f; public const float NearEnterMeters = 18f; public const float NearExitMeters = 22f; public const float UniqueNearestMarginMeters = 1f; public const double FocusAcquireDwellSeconds = 0.12; public const double NearAcquireDwellSeconds = 0.25; public const double ReleaseDwellSeconds = 0.2; private long? _expandedKey; private long? _pendingKey; private double _pendingSince; private bool _pendingRelease; public long? ExpandedKey => _expandedKey; public long? Update(IReadOnlyList<MarkerExpansionCandidate> candidates, double nowSeconds) { if (candidates == null) { throw new ArgumentNullException("candidates"); } if (double.IsNaN(nowSeconds) || double.IsInfinity(nowSeconds)) { nowSeconds = 0.0; } if (_expandedKey.HasValue && IsCurrentStillQualified(candidates, _expandedKey.Value)) { long? num = FindFocused(candidates, useExitForCurrent: true); if (!num.HasValue || num.Value == _expandedKey.Value) { ResetPending(); return _expandedKey; } } long? num2 = FindFocused(candidates, useExitForCurrent: false); if (num2.HasValue) { return AdvanceToward(num2.Value, nowSeconds, 0.12); } long? num3 = FindUniqueNearest(candidates); if (num3.HasValue) { return AdvanceToward(num3.Value, nowSeconds, 0.25); } if (!_expandedKey.HasValue) { ResetPending(); return null; } if (!_pendingRelease) { _pendingRelease = true; _pendingKey = null; _pendingSince = nowSeconds; return _expandedKey; } if (nowSeconds - _pendingSince < 0.2) { return _expandedKey; } _expandedKey = null; ResetPending(); return null; } public void Clear() { _expandedKey = null; ResetPending(); } private long? AdvanceToward(long desiredKey, double nowSeconds, double dwellSeconds) { _pendingRelease = false; if (_expandedKey.HasValue && _expandedKey.Value == desiredKey) { ResetPending(); return _expandedKey; } if (!_pendingKey.HasValue || _pendingKey.Value != desiredKey) { _pendingKey = desiredKey; _pendingSince = nowSeconds; return _expandedKey; } if (nowSeconds - _pendingSince < dwellSeconds) { return _expandedKey; } _expandedKey = desiredKey; ResetPending(); return _expandedKey; } private bool IsCurrentStillQualified(IReadOnlyList<MarkerExpansionCandidate> candidates, long key) { for (int i = 0; i < candidates.Count; i++) { MarkerExpansionCandidate markerExpansionCandidate = candidates[i]; if (markerExpansionCandidate.ClusterKey == key && markerExpansionCandidate.MemberCount >= 3) { if (!(markerExpansionCandidate.ReticleDistancePixels1080 <= 110f)) { return markerExpansionCandidate.DistanceMeters <= 22f; } return true; } } return false; } private long? FindFocused(IReadOnlyList<MarkerExpansionCandidate> candidates, bool useExitForCurrent) { float num = (useExitForCurrent ? 110f : 72f); bool flag = false; MarkerExpansionCandidate markerExpansionCandidate = default(MarkerExpansionCandidate); for (int i = 0; i < candidates.Count; i++) { MarkerExpansionCandidate markerExpansionCandidate2 = candidates[i]; if (markerExpansionCandidate2.MemberCount >= 3 && IsFiniteNonNegative(markerExpansionCandidate2.ReticleDistancePixels1080) && !(markerExpansionCandidate2.ReticleDistancePixels1080 > num) && (!flag || markerExpansionCandidate2.ReticleDistancePixels1080 < markerExpansionCandidate.ReticleDistancePixels1080 || (Math.Abs(markerExpansionCandidate2.ReticleDistancePixels1080 - markerExpansionCandidate.ReticleDistancePixels1080) <= 0.001f && (markerExpansionCandidate2.DistanceMeters < markerExpansionCandidate.DistanceMeters || (Math.Abs(markerExpansionCandidate2.DistanceMeters - markerExpansionCandidate.DistanceMeters) <= 0.001f && markerExpansionCandidate2.ClusterKey < markerExpansionCandidate.ClusterKey))))) { flag = true; markerExpansionCandidate = markerExpansionCandidate2; } } if (!flag) { return null; } return markerExpansionCandidate.ClusterKey; } private static long? FindUniqueNearest(IReadOnlyList<MarkerExpansionCandidate> candidates) { bool flag = false; MarkerExpansionCandidate markerExpansionCandidate = default(MarkerExpansionCandidate); float num = float.PositiveInfinity; for (int i = 0; i < candidates.Count; i++) { MarkerExpansionCandidate markerExpansionCandidate2 = candidates[i]; if (markerExpansionCandidate2.MemberCount < 3 || !IsFiniteNonNegative(markerExpansionCandidate2.DistanceMeters) || markerExpansionCandidate2.DistanceMeters > 18f) { continue; } if (!flag || markerExpansionCandidate2.DistanceMeters < markerExpansionCandidate.DistanceMeters || (Math.Abs(markerExpansionCandidate2.DistanceMeters - markerExpansionCandidate.DistanceMeters) <= 0.001f && markerExpansionCandidate2.ClusterKey < markerExpansionCandidate.ClusterKey)) { if (flag) { num = markerExpansionCandidate.DistanceMeters; } markerExpansionCandidate = markerExpansionCandidate2; flag = true; } else if (markerExpansionCandidate2.DistanceMeters < num) { num = markerExpansionCandidate2.DistanceMeters; } } if (!flag) { return null; } if (!float.IsPositiveInfinity(num) && num - markerExpansionCandidate.DistanceMeters < 1f) { return null; } return markerExpansionCandidate.ClusterKey; } private void ResetPending() { _pendingKey = null; _pendingRelease = false; _pendingSince = 0.0; } private static bool IsFiniteNonNegative(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value >= 0f; } return false; } } public enum MarkerCategorySortOrder { HighToLow, LowToHigh } public readonly struct MarkerCompactLayoutSlot { public int Row { get; } public int Column { get; } public int RowSize { get; } public float XUnits { get; } public float YUnits { get; } public MarkerCompactLayoutSlot(int row, int column, int rowSize, float xUnits, float yUnits) { Row = row; Column = column; RowSize = rowSize; XUnits = xUnits; YUnits = yUnits; } } public readonly struct MarkerCompactCellGeometry { public float BadgeSize { get; } public float CountWidth { get; } public float CountGap { get; } public float CellWidth { get; } public float HorizontalStride { get; } public float VerticalStride { get; } public MarkerCompactCellGeometry(float badgeSize, float countWidth, float countGap, float cellWidth, float horizontalStride, float verticalStride) { BadgeSize = badgeSize; CountWidth = countWidth; CountGap = countGap; CellWidth = cellWidth; HorizontalStride = horizontalStride; VerticalStride = verticalStride; } } public static class MarkerCategorySummaryPolicy { public const MarkerCategorySortOrder DefaultSortOrder = MarkerCategorySortOrder.HighToLow; public const float PyramidMaxVerticalOffsetUnits = 0.6f; public const float PyramidMinimumHorizontalSpacingFactor = 0.62f; public const int MaxCategories = 14; public static int DisplayPriority(MarkerSemanticCategory category) { return category switch { MarkerSemanticCategory.Tier3 => 110, MarkerSemanticCategory.Boss => 100, MarkerSemanticCategory.Lunar => 90, MarkerSemanticCategory.Void => 80, MarkerSemanticCategory.Tier2 => 70, MarkerSemanticCategory.Equipment => 60, MarkerSemanticCategory.LunarEquipment => 50, MarkerSemanticCategory.Tier1 => 40, MarkerSemanticCategory.CommandState => 30, MarkerSemanticCategory.Other => 20, MarkerSemanticCategory.Hallowed => 115, MarkerSemanticCategory.Hex => 35, MarkerSemanticCategory.Page => 85, _ => 10, }; } public static MarkerCompactCategoryBadge[] BuildCategoryEntries(IReadOnlyList<MarkerCategoryCount> composition, MarkerCategorySortOrder sortOrder) { if (composition == null) { throw new ArgumentNullException("composition"); } int num = 0; for (int i = 0; i < composition.Count; i++) { if (num >= 14) { break; } if (composition[i].Count > 0) { num++; } } MarkerCompactCategoryBadge[] array = new MarkerCompactCategoryBadge[num]; int num2 = 0; for (int j = 0; j < composition.Count; j++) { if (num2 >= array.Length) { break; } MarkerCategoryCount markerCategoryCount = composition[j]; if (markerCategoryCount.Count > 0) { array[num2++] = new MarkerCompactCategoryBadge(markerCategoryCount.Category, markerCategoryCount.Count, DisplayPriority(markerCategoryCount.Category)); } } for (int k = 1; k < array.Length; k++) { MarkerCompactCategoryBadge markerCompactCategoryBadge = array[k]; int num3 = k - 1; while (num3 >= 0 && Compare(markerCompactCategoryBadge, array[num3], sortOrder) < 0) { array[num3 + 1] = array[num3]; num3--; } array[num3 + 1] = markerCompactCategoryBadge; } return array; } public static float PyramidVerticalOffsetUnits(MarkerSemanticCategory category) { float num = ((float)DisplayPriority(category) - 10f) / 100f; if (num < 0f) { num = 0f; } if (num > 1f) { num = 1f; } return num * 0.6f; } public static float PyramidHorizontalSpacingFactor(int categoryCount) { if (categoryCount <= 3) { return 1f; } float num = 1f - (float)(categoryCount - 3) * 0.055f; if (!(num < 0.62f)) { return num; } return 0.62f; } public static float BuildCategoryGlyphSize(float screenWidth, float screenHeight, float markerScale, float indicatorSize, float fontSize) { float num = (IsFinitePositive(screenWidth) ? screenWidth : 1920f); float num2 = (IsFinitePositive(screenHeight) ? screenHeight : 1080f); float num3 = (IsFinitePositive(markerScale) ? markerScale : 1f); if (num3 < 0.75f) { num3 = 0.75f; } if (num3 > 1.25f) { num3 = 1.25f; } float num4 = Math.Min(num / 1920f, num2 / 1080f); if (!IsFinitePositive(num4)) { num4 = 1f; } float num5 = num4 * num3; float num6 = (IsFinitePositive(indicatorSize) ? indicatorSize : (24f * num5)); float num7 = (IsFinitePositive(fontSize) ? fontSize : (20f * num5)); return Math.Max(12f * num5, Math.Min(num6 * 0.58f, num7 * 0.78f)); } public static float BuildCompactLifetimeGroupGap(float screenWidth, float screenHeight, float markerScale, float indicatorSize, float fontSize) { float num = (IsFinitePositive(screenWidth) ? screenWidth : 1920f); float num2 = (IsFinitePositive(screenHeight) ? screenHeight : 1080f); float num3 = (IsFinitePositive(markerScale) ? markerScale : 1f); if (num3 < 0.75f) { num3 = 0.75f; } if (num3 > 1.25f) { num3 = 1.25f; } float num4 = Math.Min(num / 1920f, num2 / 1080f); if (!IsFinitePositive(num4)) { num4 = 1f; } float num5 = num4 * num3; float indicatorSize2 = (IsFinitePositive(indicatorSize) ? indicatorSize : (24f * num5)); float fontSize2 = (IsFinitePositive(fontSize) ? fontSize : (20f * num5)); float num6 = BuildCategoryGlyphSize(num, num2, num3, indicatorSize2, fontSize2); return Math.Max(4f * num5, num6 * 0.18f); } public static float BuildCompactCategoryCenterHorizontalStride(float screenWidth, float screenHeight, float markerScale, float indicatorSize, float fontSize, int categoryCount) { float num = (IsFinitePositive(screenWidth) ? screenWidth : 1920f); float num2 = (IsFinitePositive(screenHeight) ? screenHeight : 1080f); float num3 = (IsFinitePositive(markerScale) ? markerScale : 1f); if (num3 < 0.75f) { num3 = 0.75f; } if (num3 > 1.25f) { num3 = 1.25f; } float num4 = Math.Min(num / 1920f, num2 / 1080f); if (!IsFinitePositive(num4)) { num4 = 1f; } float num5 = num4 * num3; float indicatorSize2 = (IsFinitePositive(indicatorSize) ? indicatorSize : (24f * num5)); float fontSize2 = (IsFinitePositive(fontSize) ? fontSize : (20f * num5)); MarkerCompactCellGeometry markerCompactCellGeometry = BuildCompactCellGeometry(num, num2, num3, indicatorSize2, fontSize2, showCount: false); float num6 = BuildCompactLifetimeGroupGap(num, num2, num3, indicatorSize2, fontSize2); float num7 = Math.Max(4f * num5, markerCompactCellGeometry.BadgeSize * 0.18f); float num8 = markerCompactCellGeometry.HorizontalStride * PyramidHorizontalSpacingFactor(categoryCount); MarkerCompactLayoutSlot[] array = BuildCompactLayout(categoryCount); bool flag = false; for (int i = 0; i < array.Length; i++) { if (array[i].RowSize >= 3) { flag = true; break; } } if (!flag) { return num8; } float val = markerCompactCellGeometry.BadgeSize * 1.5f + num6 * 0.5f + num7; return Math.Max(num8, val); } public static float BuildCompactCategoryCenterVerticalStride(float screenWidth, float screenHeight, float markerScale, float indicatorSize, float fontSize) { return BuildCompactCellGeometry(screenWidth, screenHeight, markerScale, indicatorSize, fontSize, showCount: false).VerticalStride; } public static float BuildDetailedCategoryDistanceGap(float screenWidth, float screenHeight, float markerScale, float indicatorSize, float fontSize) { float num = (IsFinitePositive(screenWidth) ? screenWidth : 1920f); float num2 = (IsFinitePositive(screenHeight) ? screenHeight : 1080f); float num3 = (IsFinitePositive(markerScale) ? markerScale : 1f); if (num3 < 0.75f) { num3 = 0.75f; } if (num3 > 1.25f) { num3 = 1.25f; } float num4 = Math.Min(num / 1920f, num2 / 1080f); if (!IsFinitePositive(num4)) { num4 = 1f; } float num5 = num4 * num3; float indicatorSize2 = (IsFinitePositive(indicatorSize) ? indicatorSize : (24f * num5)); float num6 = (IsFinitePositive(fontSize) ? fontSize : (20f * num5)); float num7 = BuildCategoryGlyphSize(num, num2, num3, indicatorSize2, num6); float num8 = num6 * 1.18f; float num9 = Math.Max(num8, num7 + 2f * num5); return Math.Max(0f, num9 - (num7 + num8) * 0.5f); } public static float BuildCompactLifetimeGroupOffsetX(MarkerCompactLayoutSlot categorySlot, int groupOrdinal, int groupCount, float glyphSize, float lifetimeGroupGap) { int num = Math.Max(1, groupCount); int num2 = Math.Max(0, Math.Min(num - 1, groupOrdinal)); if (num == 1) { return 0f; } float num3 = (IsFinitePositive(glyphSize) ? glyphSize : 1f); float num4 = ((!float.IsNaN(lifetimeGroupGap) && !float.IsInfinity(lifetimeGroupGap) && lifetimeGroupGap > 0f) ? lifetimeGroupGap : 0f); float num5 = num3 + num4; float num6 = (float)(Math.Max(1, categorySlot.RowSize) - 1) * 0.5f; if (categorySlot.RowSize > 1 && (float)categorySlot.Column < num6) { return (float)(-num2) * num5; } if (categorySlot.RowSize > 1 && (float)categorySlot.Column > num6) { return (float)num2 * num5; } return ((float)num2 - (float)(num - 1) * 0.5f) * num5; } public static MarkerCompactCellGeometry BuildCompactCellGeometry(float screenWidth, float screenHeight, float markerScale, float indicatorSize, float fontSize, bool showCount) { float num = (IsFinitePositive(screenWidth) ? screenWidth : 1920f); float num2 = (IsFinitePositive(screenHeight) ? screenHeight : 1080f); float num3 = (IsFinitePositive(markerScale) ? markerScale : 1f); if (num3 < 0.75f) { num3 = 0.75f; } if (num3 > 1.25f) { num3 = 1.25f; } float num4 = Math.Min(num / 1920f, num2 / 1080f); if (!IsFinitePositive(num4)) { num4 = 1f; } float num5 = num4 * num3; float indicatorSize2 = (IsFinitePositive(indicatorSize) ? indicatorSize : (24f * num5)); float num6 = (IsFinitePositive(fontSize) ? fontSize : (20f * num5)); float num7 = BuildCategoryGlyphSize(num, num2, num3, indicatorSize2, num6); float num8 = (showCount ? Math.Max(24f * num5, num6 * 2.2f) : 0f); float num9 = (showCount ? Math.Max(5f * num5, num6 * 0.18f) : 0f); float num10 = num7 + num9 + num8; float num11 = Math.Max(10f * num5, num7 * 0.28f); float horizontalStride = num10 + num11; float verticalStride = Math.Max(num7 + 10f * num5, num6 * 1.45f); return new MarkerCompactCellGeometry(num7, num8, num9, num10, horizontalStride, verticalStride); } private static bool IsFinitePositive(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value > 0f; } return false; } public static MarkerCompactLayoutSlot[] BuildCompactLayout(int categoryCount) { int num = Math.Max(0, Math.Min(14, categoryCount)); if (num == 0) { return Array.Empty<MarkerCompactLayoutSlot>(); } int[] array = CompactRowPattern(num); MarkerCompactLayoutSlot[] array2 = new MarkerCompactLayoutSlot[num]; int num2 = 0; int num3 = array.Length; for (int i = 0; i < array.Length; i++) { int num4 = array[i]; float yUnits = (float)(num3 - 1) * 0.5f - (float)i; for (int j = 0; j < num4; j++) { if (num2 >= num) { break; } float xUnits = (float)j - (float)(num4 - 1) * 0.5f; array2[num2++] = new MarkerCompactLayoutSlot(i, j, num4, xUnits, yUnits); } } return array2; } private static int[] CompactRowPattern(int count) { return count switch { 1 => new int[1] { 1 }, 2 => new int[2] { 1, 1 }, 3 => new int[2] { 1, 2 }, 4 => new int[3] { 1, 2, 1 }, 5 => new int[3] { 1, 3, 1 }, 6 => new int[4] { 1, 2, 2, 1 }, 7 => new int[4] { 1, 2, 3, 1 }, 8 => new int[5] { 1, 2, 2, 2, 1 }, 9 => new int[5] { 1, 2, 3, 2, 1 }, 10 => new int[5] { 1, 2, 3, 3, 1 }, 12 => new int[6] { 1, 2, 3, 3, 2, 1 }, 13 => new int[6] { 1, 2, 3, 3, 3, 1 }, 14 => new int[6] { 1, 3, 3, 3, 3, 1 }, _ => new int[5] { 1, 3, 3, 3, 1 }, }; } private static int Compare(MarkerCompactCategoryBadge left, MarkerCompactCategoryBadge right, MarkerCategorySortOrder sortOrder) { int num = right.DisplayPriority.CompareTo(left.DisplayPriority); if (sortOrder == MarkerCategorySortOrder.LowToHigh) { num = -num; } if (num != 0) { return num; } int num2 = MarkerSemanticCategoryPolicy.StableOrder(left.Category).CompareTo(MarkerSemanticCategoryPolicy.StableOrder(right.Category)); if (sortOrder != MarkerCategorySortOrder.LowToHigh) { return num2; } return -num2; } } public enum MarkerClassKind { Unknown, Tier1, Tier2, Tier3, Boss, Lunar, Void, Equipment, LunarEquipment, Other, Hallowed, Hex, Page } public readonly struct CommandClassPresentation { public MarkerClassKind Kind { get; } public string Label { get; } public bool ExactClass { get; } public CommandClassPresentation(MarkerClassKind kind, string label, bool exactClass) { Kind = kind; Label = (string.IsNullOrWhiteSpace(label) ? "Item choice" : label); ExactClass = exactClass; } } public static class MarkerClassPolicy { public static bool UsesCatalogPickupBaseColor => true; public static bool UsesArtifactCommandName => false; public static string CommandChoiceSource => "PickupPickerController.options/PickupIndex"; public static string AuthoritativeCommandChoiceSource => "PickupPickerController.options/option.pickup.pickupIndex"; public static MarkerClassKind Classify(string? itemTierName, bool isEquipment, bool isLunarEquipment) { if (isEquipment) { if (!isLunarEquipment) { return MarkerClassKind.Equipment; } return MarkerClassKind.LunarEquipment; } string text = itemTierName ?? string.Empty; if (string.Equals(text, "Tier1", StringComparison.Ordinal)) { return MarkerClassKind.Tier1; } if (string.Equals(text, "Tier2", StringComparison.Ordinal)) { return MarkerClassKind.Tier2; } if (string.Equals(text, "Tier3", StringComparison.Ordinal)) { return MarkerClassKind.Tier3; } if (string.Equals(text, "Boss", StringComparison.Ordinal)) { return MarkerClassKind.Boss; } if (string.Equals(text, "Lunar", StringComparison.Ordinal)) { return MarkerClassKind.Lunar; } if (string.Equals(text, "Cursed", StringComparison.Ordinal)) { return MarkerClassKind.Hallowed; } if (string.Equals(text, "Hex", StringComparison.Ordinal)) { return MarkerClassKind.Hex; } if (string.Equals(text, "Page", StringComparison.Ordinal)) { return MarkerClassKind.Page; } if (text.StartsWith("Void", StringComparison.Ordinal)) { return MarkerClassKind.Void; } if (string.IsNullOrWhiteSpace(text) || string.Equals(text, "NoTier", StringComparison.Ordinal)) { return MarkerClassKind.Unknown; } return MarkerClassKind.Other; } public static string DiagnosticClassName(MarkerClassKind kind) { return kind switch { MarkerClassKind.Tier1 => "WHITE", MarkerClassKind.Tier2 => "GREEN", MarkerClassKind.Tier3 => "RED", MarkerClassKind.Boss => "YELLOW", MarkerClassKind.Lunar => "LUNAR_BLUE", MarkerClassKind.Void => "VOID_PURPLE", MarkerClassKind.Equipment => "EQUIPMENT", MarkerClassKind.LunarEquipment => "LUNAR_EQUIPMENT", MarkerClassKind.Other => "OTHER", MarkerClassKind.Hallowed => "HALLOWED", MarkerClassKind.Hex => "HEX", MarkerClassKind.Page => "PAGE", _ => "UNKNOWN", }; } public static string LocalizedClassLabel(MarkerClassKind kind, bool russian) { if (russian) { return kind switch { MarkerClassKind.Tier1 => "Белый", MarkerClassKind.Tier2 => "Зелёный", MarkerClassKind.Tier3 => "Красный", MarkerClassKind.Boss => "Жёлтый", MarkerClassKind.Lunar => "Синий", MarkerClassKind.Void => "Фиолетовый", MarkerClassKind.Equipment => "Снаряжение", MarkerClassKind.LunarEquipment => "Лунное снаряжение", _ => "Выбор предмета", }; } return kind switch { MarkerClassKind.Tier1 => "White", MarkerClassKind.Tier2 => "Green", MarkerClassKind.Tier3 => "Red", MarkerClassKind.Boss => "Yellow", MarkerClassKind.Lunar => "Blue", MarkerClassKind.Void => "Purple", MarkerClassKind.Equipment => "Equipment", MarkerClassKind.LunarEquipment => "Lunar equipment", _ => "Item choice", }; } public static CommandClassPresentation ResolveCommandClass(IEnumerable<MarkerClassKind>? choiceClasses, bool russian) { if (choiceClasses == null) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedClassLabel(MarkerClassKind.Unknown, russian), exactClass: false); } MarkerClassKind[] array = choiceClasses.ToArray(); if (array.Length == 0 || array.Any((MarkerClassKind x) => x == MarkerClassKind.Unknown)) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedClassLabel(MarkerClassKind.Unknown, russian), exactClass: false); } MarkerClassKind[] array2 = array.Distinct().ToArray(); if (array2.Length != 1) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedClassLabel(MarkerClassKind.Unknown, russian), exactClass: false); } MarkerClassKind markerClassKind = array2[0]; if (markerClassKind == MarkerClassKind.Other) { return new CommandClassPresentation(MarkerClassKind.Other, LocalizedClassLabel(MarkerClassKind.Other, russian), exactClass: false); } return new CommandClassPresentation(markerClassKind, LocalizedClassLabel(markerClassKind, russian), exactClass: true); } public static string LocalizedSemanticClassLabel(MarkerClassKind kind, bool russian) { if (russian) { return kind switch { MarkerClassKind.Tier1 => "Белый", MarkerClassKind.Tier2 => "Зелёный", MarkerClassKind.Tier3 => "Красный", MarkerClassKind.Boss => "Жёлтый", MarkerClassKind.Lunar => "Лунный", MarkerClassKind.Void => "Предмет Бездны", MarkerClassKind.Equipment => "Снаряжение", MarkerClassKind.LunarEquipment => "Лунное снаряжение", _ => "Выбор предмета", }; } return kind switch { MarkerClassKind.Tier1 => "White", MarkerClassKind.Tier2 => "Green", MarkerClassKind.Tier3 => "Red", MarkerClassKind.Boss => "Yellow", MarkerClassKind.Lunar => "Lunar", MarkerClassKind.Void => "Void", MarkerClassKind.Equipment => "Equipment", MarkerClassKind.LunarEquipment => "Lunar equipment", _ => "Item choice", }; } public static CommandClassPresentation ResolveCommandClassForPresentation(IEnumerable<MarkerClassKind>? choiceClasses, bool russian) { if (choiceClasses == null) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedSemanticClassLabel(MarkerClassKind.Unknown, russian), exactClass: false); } MarkerClassKind[] array = choiceClasses.ToArray(); if (array.Length == 0 || array.Any((MarkerClassKind x) => x == MarkerClassKind.Unknown)) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedSemanticClassLabel(MarkerClassKind.Unknown, russian), exactClass: false); } MarkerClassKind[] array2 = array.Distinct().ToArray(); if (array2.Length != 1) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedSemanticClassLabel(MarkerClassKind.Unknown, russian), exactClass: false); } MarkerClassKind markerClassKind = array2[0]; if (markerClassKind == MarkerClassKind.Other) { return new CommandClassPresentation(MarkerClassKind.Other, LocalizedSemanticClassLabel(MarkerClassKind.Other, russian), exactClass: false); } return new CommandClassPresentation(markerClassKind, LocalizedSemanticClassLabel(markerClassKind, russian), exactClass: true); } public static string LocalizedReadableClassLabel(MarkerClassKind kind, bool russian) { return LocalizedReadableClassLabel(kind, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static string LocalizedReadableClassLabel(MarkerClassKind kind, MarkerLanguage language) { return MarkerTextLocalization.ReadableClassLabel(kind, language); } public static CommandClassPresentation ResolveCommandClassForReadablePresentation(IEnumerable<MarkerClassKind>? choiceClasses, bool russian) { return ResolveCommandClassForReadablePresentation(choiceClasses, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static CommandClassPresentation ResolveCommandClassForReadablePresentation(IEnumerable<MarkerClassKind>? choiceClasses, MarkerLanguage language) { if (choiceClasses == null) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedReadableClassLabel(MarkerClassKind.Unknown, language), exactClass: false); } bool flag = false; MarkerClassKind markerClassKind = MarkerClassKind.Unknown; foreach (MarkerClassKind choiceClass in choiceClasses) { if (choiceClass == MarkerClassKind.Unknown) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedReadableClassLabel(MarkerClassKind.Unknown, language), exactClass: false); } if (!flag) { flag = true; markerClassKind = choiceClass; } else if (choiceClass != markerClassKind) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedReadableClassLabel(MarkerClassKind.Unknown, language), exactClass: false); } } if (!flag) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedReadableClassLabel(MarkerClassKind.Unknown, language), exactClass: false); } if (markerClassKind == MarkerClassKind.Other) { return new CommandClassPresentation(MarkerClassKind.Other, LocalizedReadableClassLabel(MarkerClassKind.Other, language), exactClass: false); } return new CommandClassPresentation(markerClassKind, LocalizedReadableClassLabel(markerClassKind, language), exactClass: true); } } public enum MarkerPresentationMode { Detailed, Compact } public enum MarkerCompactMixedStyle { NeutralSingleDiamond, CategoryDiamonds, CategoryDiamondPyramid } public enum MarkerCountRenderSource { None, TotalCountText, CategorySubcounts, DetailedCategoryRows } public enum MarkerPresentationGlyphKind { Diamond, Clock } public readonly struct MarkerPresentationSettings { public MarkerPresentationMode Mode { get; } public bool ShowDistance { get; } public float Scale { get; } public int DetailRows { get; } public bool ShowCategoryDiamond { get; } public bool ShowTierComposition { get; } public bool CompactShowCount { get; } public MarkerCompactMixedStyle CompactMixedStyle { get; } public MarkerCategorySortOrder CategorySortOrder { get; } public bool UseCategorySummaryPresentation { get; } public MarkerPresentationSettings(MarkerPresentationMode mode, bool showDistance, float scale, int detailRows) : this(mode, showDistance, scale, detailRows, showCategoryDiamond: true, showTierComposition: true, compactShowCount: true, MarkerCompactMixedStyle.NeutralSingleDiamond, MarkerCategorySortOrder.HighToLow, useCategorySummaryPresentation: false) { } public MarkerPresentationSettings(MarkerPresentationMode mode, bool showDistance, float scale, int detailRows, bool showCategoryDiamond, bool showTierComposition, bool compactShowCount, MarkerCompactMixedStyle compactMixedStyle) : this(mode, showDistance, scale, detailRows, showCategoryDiamond, showTierComposition, compactShowCount, compactMixedStyle, MarkerCategorySortOrder.HighToLow, useCategorySummaryPresentation: false) { } public MarkerPresentationSettings(MarkerPresentationMode mode, bool showDistance, float scale, int detailRows, bool showCategoryDiamond, bool showTierComposition, bool compactShowCount, MarkerCompactMixedStyle compactMixedStyle, MarkerCategorySortOrder categorySortOrder) : this(mode, showDistance, scale, detailRows, showCategoryDiamond, showTierComposition, compactShowCount, compactMixedStyle, categorySortOrder, useCategorySummaryPresentation: true) { } private MarkerPresentationSettings(MarkerPresentationMode mode, bool showDistance, float scale, int detailRows, bool showCategoryDiamond, bool showTierComposition, bool compactShowCount, MarkerCompactMixedStyle compactMixedStyle, MarkerCategorySortOrder categorySortOrder, bool useCategorySummaryPresentation) { Mode = mode; ShowDistance = showDistance; Scale = MarkerClusterPresentationPolicy.ClampMarkerScale(scale); DetailRows = MarkerClusterPresentationPolicy.ClampDetailRows(detailRows); ShowCategoryDiamond = showCategoryDiamond; ShowTierComposition = showTierComposition; CompactShowCount = compactShowCount; CompactMixedStyle = compactMixedStyle; CategorySortOrder = categorySortOrder; UseCategorySummaryPresentation = useCategorySummaryPresentation; } } public readonly struct MarkerCompactCategoryBadge { public MarkerSemanticCategory Category { get; } public int Count { get; } public int DisplayPriority { get; } public MarkerLifetimeKind Lifetime { get; } public MarkerPresentationGlyphKind GlyphKind { get; } public MarkerLifetimeIndicatorSpec LifetimeIndicator { get; } public float PyramidVerticalOffsetUnits => MarkerCategorySummaryPolicy.PyramidVerticalOffsetUnits(Category); public MarkerCompactCategoryBadge(MarkerSemanticCategory category, int count) : this(category, count, MarkerCategorySummaryPolicy.DisplayPriority(category), MarkerLifetimeKind.Permanent, MarkerPresentationGlyphKind.Diamond) { } public MarkerCompactCategoryBadge(MarkerSemanticCategory category, int count, int displayPriority) : this(category, count, displayPriority, MarkerLifetimeKind.Permanent, MarkerPresentationGlyphKind.Diamond) { } public MarkerCompactCategoryBadge(MarkerSemanticCategory category, int count, int displayPriority, MarkerLifetimeIndicatorSpec lifetimeIndicator) : this(category, count, displayPriority, lifetimeIndicator.Visible ? MarkerLifetimeKind.Temporary : MarkerLifetimeKind.Permanent, lifetimeIndicator.Visible ? MarkerPresentationGlyphKind.Clock : MarkerPresentationGlyphKind.Diamond) { } public MarkerCompactCategoryBadge(MarkerSemanticCategory category, int count, int displayPriority, MarkerLifetimeKind lifetime, MarkerPresentationGlyphKind glyphKind) { Category = category; Count = Math.Max(0, count); DisplayPriority = displayPriority; Lifetime = lifetime; GlyphKind = glyphKind; LifetimeIndicator = MarkerLifetimeIndicatorSpec.Hidden; } } public readonly struct MarkerDetailedItemRow { public string ItemIdentity { get; } public string LocalizedName { get; } public MarkerSemanticCategory Category { get; } public int Count { get; } public MarkerLifetimeKind Lifetime { get; } public MarkerPresentationGlyphKind GlyphKind { get; } public string DisplayLabel { get; } public MarkerLifetimeIndicatorSpec LifetimeIndicator { get; } public MarkerDetailedItemRow(string itemIdentity, string localizedName, MarkerSemanticCategory category, int count) : this(itemIdentity, localizedName, category, count, MarkerLifetimeKind.Permanent, localizedName) { } public MarkerDetailedItemRow(string itemIdentity, string localizedName, MarkerSemanticCategory category, int count, MarkerLifetimeKind lifetime, string displayLabel) { ItemIdentity = itemIdentity ?? string.Empty; LocalizedName = (string.IsNullOrWhiteSpace(localizedName) ? "Pickup" : localizedName); Category = category; Count = Math.Max(0, count); Lifetime = lifetime; GlyphKind = ((lifetime == MarkerLifetimeKind.Temporary) ? MarkerPresentationGlyphKind.Clock : MarkerPresentationGlyphKind.Diamond); DisplayLabel = (string.IsNullOrWhiteSpace(displayLabel) ? LocalizedName : displayLabel); LifetimeIndicator = MarkerLifetimePolicy.BuildIndicator(lifetime, (lifetime == MarkerLifetimeKind.Temporary) ? Count : 0, (lifetime == MarkerLifetimeKind.Mixed) ? Count : 0, (lifetime == MarkerLifetimeKind.Unknown) ? Count : 0, allowCount: false, showSingleCountWhenMixed: false); } } public sealed class MarkerClusterPresentationPlan { public string Text { get; } public IReadOnlyList<MarkerCompactCategoryBadge> CompactBadges { get; } public IReadOnlyList<MarkerCompactCategoryBadge> CategoryEntries => CompactBadges; public IReadOnlyList<MarkerDetailedItemRow> DetailedItemRows { get; } public int TotalCount { get; } public int ShownDetailRows { get; } public int OverflowPhysicalCount { get; } public bool Expanded { get; } public bool NeutralMainSemantic { get; } public MarkerCountRenderSource CountRenderSource { get; } public bool ShowMainDiamond { get; } public bool ShowDetailedCategoryRowDiamonds { get; } public bool ShowCompactCategoryDiamonds { get; } public MarkerSemanticCategory MainCategory { get; } public MarkerLifetimeIndicatorSpec LifetimeIndicator { get; private set; } public bool RenderCategorySubcounts => CountRenderSource == MarkerCountRenderSource.CategorySubcounts; public bool RenderTotalCount => CountRenderSource == MarkerCountRenderSource.TotalCountText; internal MarkerClusterPresentationPlan(string text, MarkerCompactCategoryBadge[] compactBadges, int totalCount, int shownDetailRows, int overflowPhysicalCount, bool expanded, bool neutralMainSemantic, MarkerCountRenderSource countRenderSource, bool showMainDiamond, bool showDetailedCategoryRowDiamonds, bool showCompactCategoryDiamonds, MarkerSemanticCategory mainCategory) : this(text, compactBadges, Array.Empty<MarkerDetailedItemRow>(), totalCount, shownDetailRows, overflowPhysicalCount, expanded, neutralMainSemantic, countRenderSource, showMainDiamond, showDetailedCategoryRowDiamonds, showCompactCategoryDiamonds, mainCategory) { } internal MarkerClusterPresentationPlan(string text, MarkerCompactCategoryBadge[] compactBadges, MarkerDetailedItemRow[] detailedItemRows, int totalCount, int shownDetailRows, int overflowPhysicalCount, bool expanded, bool neutralMainSemantic, MarkerCountRenderSource countRenderSource, bool showMainDiamond, bool showDetailedCategoryRowDiamonds, bool showCompactCategoryDiamonds, MarkerSemanticCategory mainCategory) { Text = text ?? string.Empty; CompactBadges = compactBadges ?? Array.Empty<MarkerCompactCategoryBadge>(); DetailedItemRows = detailedItemRows ?? Array.Empty<MarkerDetailedItemRow>(); TotalCount = Math.Max(0, totalCount); ShownDetailRows = Math.Max(0, shownDetailRows); OverflowPhysicalCount = Math.Max(0, overflowPhysicalCount); Expanded = expanded; NeutralMainSemantic = neutralMainSemantic; CountRenderSource = countRenderSource; ShowMainDiamond = showMainDiamond; ShowDetailedCategoryRowDiamonds = showDetailedCategoryRowDiamonds; ShowCompactCategoryDiamonds = showCompactCategoryDiamonds; MainCategory = mainCategory; LifetimeIndicator = MarkerLifetimeIndicatorSpec.Hidden; } internal void SetLifetimeIndicator(MarkerLifetimeIndicatorSpec lifetimeIndicator) { LifetimeIndicator = lifetimeIndicator; } } public static class MarkerClusterPresentationPolicy { public const int TOTAL_COUNT_RENDER_SLOTS_PER_PRESENTATION_NODE = 1; public const float MarkerScaleMin = 0.75f; public const float MarkerScaleMax = 1.25f; public const float MarkerScaleDefault = 1f; public const int MarkerDetailRowsMin = 1; public const int MarkerDetailRowsMax = 12; public const int MarkerDetailRowsDefault = 5; public const int DetailedCompositionLineCharacterBudget = 48; public const int MaxCompositionLines = 2; public const int MaxCompactCategoryBadges = 14; public const int MaxCompactLifetimePresentationGroups = 28; public const float DetailedItemLabelMaxWidth1080 = 420f; public const float DetailedItemLabelMinWidth1080 = 180f; public static float ClampMarkerScale(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { return 1f; } if (value < 0.75f) { return 0.75f; } if (!(value > 1.25f)) { return value; } return 1.25f; } public static int ClampDetailRows(int value) { if (value < 1) { return 1; } if (value <= 12) { return value; } return 12; } public static float BuildDetailedItemLabelWidthLimit(float screenWidth, float screenHeight, float markerScale) { float num = ((float.IsNaN(screenWidth) || float.IsInfinity(screenWidth) || screenWidth <= 0f) ? 1920f : screenWidth); float num2 = ((float.IsNaN(screenHeight) || float.IsInfinity(screenHeight) || screenHeight <= 0f) ? 1080f : screenHeight); float num3 = Math.Min(num / 1920f, num2 / 1080f); if (num3 <= 0f || float.IsNaN(num3) || float.IsInfinity(num3)) { num3 = 1f; } float num4 = ClampMarkerScale(markerScale); float val = 420f * num3 * num4; float val2 = 180f * num3 * num4; float val3 = num * 0.34f; return Math.Max(val2, Math.Min(val, val3)); } public static MarkerClusterPresentationPlan Build(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, bool expanded, bool russian) { return Build(cluster, settings, distanceMeters, expanded, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static MarkerClusterPresentationPlan Build(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, bool expanded, MarkerLanguage language) { if (cluster == null) { throw new ArgumentNullException("cluster"); } MarkerClusterPresentationPlan markerClusterPresentationPlan = ((!settings.UseCategorySummaryPresentation) ? ((settings.Mode == MarkerPresentationMode.Compact) ? BuildCompactLegacy(cluster, settings, distanceMeters, expanded, language) : BuildDetailedLegacy(cluster, settings, distanceMeters, expanded, language)) : ((settings.Mode == MarkerPresentationMode.Compact) ? BuildCompactCategoryPyramid(cluster, settings, distanceMeters, language) : BuildDetailedCategorySummary(cluster, settings, distanceMeters, language))); if ((settings.Mode == MarkerPresentationMode.Compact && !markerClusterPresentationPlan.ShowCompactCategoryDiamonds) || (settings.Mode == MarkerPresentationMode.Detailed && markerClusterPresentationPlan.DetailedItemRows.Count == 0 && !markerClusterPresentationPlan.ShowDetailedCategoryRowDiamonds)) { markerClusterPresentationPlan.SetLifetimeIndicator(BuildClusterLifetimeIndicator(cluster, settings.Mode == MarkerPresentationMode.Compact && settings.CompactShowCount, showSingleCountWhenMixed: true)); } return markerClusterPresentationPlan; } public static MarkerClusterPresentationPlan BuildOffscreen(int nearestDistanceMeters, int sectorTotalCount, bool showDistance, bool showTotalCount, bool russian) { return BuildOffscreen(nearestDistanceMeters, sectorTotalCount, showDistance, showTotalCount, MarkerTextLocalization.FromRussianCompatibility(russian), MarkerLifetimeKind.Permanent, 0, 0, 0); } public static MarkerClusterPresentationPlan BuildOffscreen(int nearestDistanceMeters, int sectorTotalCount, bool showDistance, bool showTotalCount, MarkerLanguage language) { return BuildOffscreen(nearestDistanceMeters, sectorTotalCount, showDistance, showTotalCount, language, MarkerLifetimeKind.Permanent, 0, 0, 0); } public static MarkerClusterPresentationPlan BuildOffscreen(int nearestDistanceMeters, int sectorTotalCount, bool showDistance, bool showTotalCount, bool russian, MarkerLifetimeKind lifetime, int temporaryPhysicalMembers, int mixedLifetimeMembers, int unknownLifetimeMembers) { return BuildOffscreen(nearestDistanceMeters, sectorTotalCount, showDistance, showTotalCount, MarkerTextLocalization.FromRussianCompatibility(russian), lifetime, temporaryPhysicalMembers, mixedLifetimeMembers, unknownLifetimeMembers); } public static MarkerClusterPresentationPlan BuildOffscreen(int nearestDistanceMeters, int sectorTotalCount, bool showDistance, bool showTotalCount, MarkerLanguage language, MarkerLifetimeKind lifetime, int temporaryPhysicalMembers, int mixedLifetimeMembers, int unknownLifetimeMembers) { StringBuilder stringBuilder = new StringBuilder(32); MarkerCountRenderSource countRenderSource = MarkerCountRenderSource.None; if (showTotalCount) { stringBuilder.Append('×').Append(Math.Max(0, sectorTotalCount).ToString(CultureInfo.InvariantCulture)); countRenderSource = MarkerCountRenderSource.TotalCountText; } if (showDistance) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(Math.Max(0, nearestDistanceMeters).ToString(CultureInfo.InvariantCulture)).Append(" ").Append(MarkerTextLocalization.DistanceUnit(language)); } MarkerClusterPresentationPlan markerClusterPresentationPlan = new MarkerClusterPresentationPlan(stringBuilder.ToString(), Array.Empty<MarkerCompactCategoryBadge>(), Math.Max(0, sectorTotalCount), 0, 0, expanded: false, neutralMainSemantic: true, countRenderSource, showMainDiamond: true, showDetailedCategoryRowDiamonds: false, showCompactCategoryDiamonds: false, MarkerSemanticCategory.Unknown); markerClusterPresentationPlan.SetLifetimeIndicator((lifetime == MarkerLifetimeKind.Temporary) ? MarkerLifetimePolicy.BuildIndicator(MarkerLifetimeKind.Temporary, temporaryPhysicalMembers, 0, 0, showTotalCount, showSingleCountWhenMixed: false) : MarkerLifetimeIndicatorSpec.Hidden); return markerClusterPresentationPlan; } public static string LocalizedCategoryPlural(MarkerSemanticCategory category, bool russian) { return LocalizedCategoryPlural(category, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static string LocalizedCategoryPlural(MarkerSemanticCategory category, MarkerLanguage language) { return MarkerTextLocalization.CategoryPlural(category, language); } public static string LocalizedCompositionWord(MarkerSemanticCategory category, bool russian) { return LocalizedCompositionWord(category, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static string LocalizedCompositionWord(MarkerSemanticCategory category, MarkerLanguage language) { return MarkerTextLocalization.CompositionLabel(category, language); } public static int CompositionCountSum(IReadOnlyList<MarkerCategoryCount> composition) { if (composition == null) { throw new ArgumentNullException("composition"); } int num = 0; for (int i = 0; i < composition.Count; i++) { num += Math.Max(0, composition[i].Count); } return num; } public static string LocalizedCategorySummaryLabel(MarkerSemanticCategory category, bool russian) { return LocalizedCategorySummaryLabel(category, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static string LocalizedCategorySummaryLabel(MarkerSemanticCategory category, MarkerLanguage language) { return MarkerTextLocalization.CategorySummaryLabel(category, language); } private static MarkerClusterPresentationPlan BuildDetailedCategorySummary(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, MarkerLanguage language) { if (!IsCommandChoiceCluster(cluster)) { return BuildDetailedOrdinaryItemSummary(cluster, settings, distanceMeters, language); } return BuildDetailedCommandCategorySummary(cluster, settings, distanceMeters, language); } private static MarkerClusterPresentationPlan BuildDetailedCommandCategorySummary(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, MarkerLanguage language) { StringBuilder stringBuilder = new StringBuilder(160); int totalCount = cluster.TotalCount; bool flag = cluster.IsMixedCategory || cluster.HomogeneousCategory == MarkerSemanticCategory.Unknown || cluster.HomogeneousCategory == MarkerSemanticCategory.CommandState; MarkerSemanticCategory mainCategory = (flag ? MarkerSemanticCategory.Unknown : cluster.HomogeneousCategory); MarkerCompactCategoryBadge[] array = BuildCategoryEntriesWithLifetime(cluster, settings.CategorySortOrder); if (totalCount <= 1 && IsTruthfulConcreteSingleAggregate(cluster)) { stringBuilder.Append(cluster.ItemRows[0].LocalizedName).Append(" ×").Append(totalCount.ToString(CultureInfo.InvariantCulture)); AppendDistance(stringBuilder, settings.ShowDistance, distanceMeters, language); return new MarkerClusterPresentationPlan(stringBuilder.ToString(), array, totalCount, 0, 0, expanded: false, flag, MarkerCountRenderSource.TotalCountText, settings.ShowCategoryDiamond, showDetailedCategoryRowDiamonds: false, showCompactCategoryDiamonds: false, mainCategory); } for (int i = 0; i < array.Length; i++) { if (i > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(LocalizedCategorySummaryLabel(array[i].Category, language)).Append(" ×").Append(array[i].Count.ToString(CultureInfo.InvariantCulture)); } AppendDistance(stringBuilder, settings.ShowDistance, distanceMeters, language); return new MarkerClusterPresentationPlan(stringBuilder.ToString(), array, totalCount, 0, 0, expanded: false, flag, MarkerCountRenderSource.DetailedCategoryRows, showMainDiamond: false, settings.ShowCategoryDiamond, showCompactCategoryDiamonds: false, mainCategory); } private static MarkerClusterPresentationPlan BuildDetailedOrdinaryItemSummary(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, MarkerLanguage language) { List<MarkerDetailedItemRow> list = new List<MarkerDetailedItemRow>(cluster.ItemRows.Count); for (int i = 0; i < cluster.ItemRows.Count; i++) { MarkerItemAggregate markerItemAggregate = cluster.ItemRows[i]; if (markerItemAggregate.Count > 0) { list.Add(new MarkerDetailedItemRow(markerItemAggregate.ItemIdentity, markerItemAggregate.LocalizedName, markerItemAggregate.Category, markerItemAggregate.Count, markerItemAggregate.Lifetime, MarkerLifetimePolicy.BuildDetailedItemDisplayName(string.IsNullOrWhiteSpace(markerItemAggregate.LocalizedName) ? MarkerTextLocalization.FallbackPickup(language) : markerItemAggregate.LocalizedName, markerItemAggregate.Lifetime, language == MarkerLanguage.Russian))); } } list.Sort((MarkerDetailedItemRow left, MarkerDetailedItemRow right) => CompareDetailedItems(left, right, settings.CategorySortOrder)); int num = Math.Min(settings.DetailRows, list.Count); int num2 = Math.Max(0, list.Count - num); StringBuilder stringBuilder = new StringBuilder(192); for (int num3 = 0; num3 < num; num3++) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(list[num3].DisplayLabel).Append(" ×").Append(list[num3].Count.ToString(CultureInfo.InvariantCulture)); } if (num2 > 0) { if (stringBuilder.Length > 0) { stringBuilder.Append('\n'); } stringBuilder.Append(BuildDetailedOverflowText(num2, language)); } AppendDistance(stringBuilder, settings.ShowDistance, distanceMeters, language); MarkerDetailedItemRow[] array = new MarkerDetailedItemRow[num]; for (int num4 = 0; num4 < num; num4++) { array[num4] = list[num4]; } bool flag = cluster.IsMixedCategory || cluster.HomogeneousCategory == MarkerSemanticCategory.Unknown; MarkerSemanticCategory mainCategory = (flag ? MarkerSemanticCategory.Unknown : cluster.HomogeneousCategory); return new MarkerClusterPresentationPlan(stringBuilder.ToString(), Array.Empty<MarkerCompactCategoryBadge>(), array, cluster.TotalCount, num, num2, expanded: false, flag, MarkerCountRenderSource.None, showMainDiamond: false, showDetailedCategoryRowDiamonds: false, showCompactCategoryDiamonds: false, mainCategory); } public static string BuildDetailedOverflowText(int hiddenDistinctTypes, bool russian) { return BuildDetailedOverflowText(hiddenDistinctTypes, MarkerTextLocalization.FromRussianCompatibility(russian)); } public static string BuildDetailedOverflowText(int hiddenDistinctTypes, MarkerLanguage language) { return MarkerTextLocalization.FormatMoreTypes(hiddenDistinctTypes, language); } public static string RussianDistinctTypeWord(int hiddenDistinctTypes) { return MarkerTextLocalization.RussianDistinctTypeWord(hiddenDistinctTypes); } private static int CompareDetailedItems(MarkerDetailedItemRow left, MarkerDetailedItemRow right, MarkerCategorySortOrder sortOrder) { int value = MarkerCategorySummaryPolicy.DisplayPriority(left.Category); int num = MarkerCategorySummaryPolicy.DisplayPriority(right.Category).CompareTo(value); if (sortOrder == MarkerCategorySortOrder.LowToHigh) { num = -num; } if (num != 0) { return num; } int num2 = string.Compare(left.LocalizedName, right.LocalizedName, StringComparison.Ordinal); if (num2 != 0) { return num2; } int num3 = string.Compare(left.ItemIdentity, right.ItemIdentity, StringComparison.Ordinal); if (num3 != 0) { return num3; } return MarkerLifetimePolicy.DetailedSortRank(left.Lifetime).CompareTo(MarkerLifetimePolicy.DetailedSortRank(right.Lifetime)); } private static bool IsCommandChoiceCluster(MarkerSemanticCluster cluster) { if (cluster.ItemRows.Count == 0) { return cluster.HomogeneousCategory == MarkerSemanticCategory.CommandState; } for (int i = 0; i < cluster.ItemRows.Count; i++) { if (!(cluster.ItemRows[i].ItemIdentity ?? string.Empty).StartsWith("COMMAND:", StringComparison.OrdinalIgnoreCase)) { return false; } } return true; } private static MarkerClusterPresentationPlan BuildCompactCategoryPyramid(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, MarkerLanguage language) { int totalCount = cluster.TotalCount; MarkerCompactCategoryBadge[] compactBadges = BuildCategoryEntriesWithLifetime(cluster, settings.CategorySortOrder); bool flag = cluster.IsMixedCategory || cluster.HomogeneousCategory == MarkerSemanticCategory.Unknown || cluster.HomogeneousCategory == MarkerSemanticCategory.CommandState; MarkerSemanticCategory mainCategory = (flag ? MarkerSemanticCategory.Unknown : cluster.HomogeneousCategory); StringBuilder stringBuilder = new StringBuilder(48); AppendDistance(stringBuilder, settings.ShowDistance, distanceMeters, language); return new MarkerClusterPresentationPlan(stringBuilder.ToString(), compactBadges, totalCount, 0, 0, expanded: false, flag, settings.CompactShowCount ? MarkerCountRenderSource.CategorySubcounts : MarkerCountRenderSource.None, showMainDiamond: false, showDetailedCategoryRowDiamonds: false, showCompactCategoryDiamonds: true, mainCategory); } private static MarkerClusterPresentationPlan BuildDetailedLegacy(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, bool expanded, MarkerLanguage language) { StringBuilder stringBuilder = new StringBuilder(192); int totalCount = cluster.TotalCount; bool flag = cluster.IsMixedCategory || cluster.HomogeneousCategory == MarkerSemanticCategory.Unknown || cluster.HomogeneousCategory == MarkerSemanticCategory.CommandState; MarkerSemanticCategory mainCategory = (flag ? MarkerSemanticCategory.Unknown : cluster.HomogeneousCategory); if (IsTruthfulConcreteSingleAggregate(cluster)) { stringBuilder.Append(cluster.ItemRows[0].LocalizedName).Append(" ×").Append(totalCount.ToString(CultureInfo.InvariantCulture)); } else if (cluster.IsHomogeneousCategory) { stringBuilder.Append(LocalizedCategoryPlural(cluster.HomogeneousCategory, language)).Append(" ×").Append(totalCount.ToString(CultureInfo.InvariantCulture)); } else { stringBuilder.Append(MarkerTextLocalization.GenericItems(language)).Append(" ×").Append(totalCount.ToString(CultureInfo.InvariantCulture)); if (settings.ShowTierComposition) { AppendDetailedComposition(stringBuilder, cluster.Composition, language); } } int shownRows = 0; int overflowPhysicalCount = 0; if (expanded && totalCount > 1) { AppendExpandedDetailRows(stringBuilder, cluster.ItemRows, settings.DetailRows, totalCount, language, out shownRows, out overflowPhysicalCount); } AppendDistance(stringBuilder, settings.ShowDistance, distanceMeters, language); return new MarkerClusterPresentationPlan(stringBuilder.ToString(), Array.Empty<MarkerCompactCategoryBadge>(), totalCount, shownRows, overflowPhysicalCount, expanded, flag, MarkerCountRenderSource.TotalCountText, settings.ShowCategoryDiamond, showDetailedCategoryRowDiamonds: false, showCompactCategoryDiamonds: false, mainCategory); } private static MarkerClusterPresentationPlan BuildCompactLegacy(MarkerSemanticCluster cluster, MarkerPresentationSettings settings, int distanceMeters, bool expanded, MarkerLanguage language) { int totalCount = cluster.TotalCount; MarkerCompactCategoryBadge[] compactBadges = BuildCategoryEntriesWithLifetime(cluster, MarkerCategorySortOrder.HighToLow, preserveCompositionOrder: true); bool flag = cluster.IsMixedCategory && settings.CompactMixedStyle == MarkerCompactMixedStyle.CategoryDiamonds; MarkerCountRenderSource markerCountRenderSource = ((!flag) ? (settings.CompactShowCount ? MarkerCountRenderSource.TotalCountText : MarkerCountRenderSource.None) : (settings.CompactShowCount ? MarkerCountRenderSource.CategorySubcounts : MarkerCountRenderSource.None)); StringBuilder stringBuilder = new StringBuilder(160); if (markerCountRenderSource == MarkerCountRenderSource.TotalCountText) { stringBuilder.Append('×').Append(totalCount.ToString(CultureInfo.InvariantCulture)); } int shownRows = 0; int overflowPhysicalCount = 0; if (expanded) { AppendExpandedDetailRows(stringBuilder, cluster.ItemRows, settings.DetailRows, totalCount, language, out shownRows, out overflowPhysicalCount); } AppendDistance(stringBuilder, settings.ShowDistance, distanceMeters, language); bool flag2 = cluster.IsMixedCategory || cluster.HomogeneousCategory == MarkerSemanticCategory.Unknown || cluster.HomogeneousCategory == MarkerSemanticCategory.CommandState; MarkerSemanticCategory mainCategory = (flag2 ? MarkerSemanticCategory.Unknown : cluster.HomogeneousCategory); return new MarkerClusterPresentationPlan(stringBuilder.ToString(), compactBadges, totalCount, shownRows, overflowPhysicalCount, expanded, flag2, markerCountRenderSource, !flag, showDetailedCategoryRowDiamonds: false, flag, mainCategory); } private static bool IsTruthfulConcreteSingleAggregate(MarkerSemanticCluster cluster) { if (cluster.ItemRows.Count != 1 || !cluster.IsHomogeneousCategory) { return false; } if (cluster.HomogeneousCategory == MarkerSemanticCategory.CommandState || cluster.HomogeneousCategory == MarkerSemanticCategory.Unknown) { return false; } string text = cluster.ItemRows[0].ItemIdentity ?? string.Empty; if (!text.StartsWith("COMMAND:", StringComparison.OrdinalIgnoreCase)) { return !text.StartsWith("UNKNOWN:", StringComparison.OrdinalIgnoreCase); } return false; } private static void AppendExpandedDetailRows(StringBuilder builder, IReadOnlyList<MarkerItemAggregate> itemRows, int requestedRows, int totalPhysicalCount, MarkerLanguage language, out int shownRows, out int overflowPhysicalCount) { int num = Math.Min(ClampDetailRows(requestedRows), 12); Span<int> span = stackalloc int[12]; for (int i = 0; i < span.Length; i++) { span[i] = -1; } int num2 = 0; for (int j = 0; j < itemRows.Count; j++) { MarkerItemAggregate left = itemRows[j]; if (left.Count <= 0) { continue; } int num3 = num2; for (int k = 0; k < num2; k++) { if (CompareExpandedDetailPriority(left, itemRows[span[k]]) < 0) { num3 = k; break; } } if (num3 < num) { if (num2 < num) { num2++; } for (int num4 = num2 - 1; num4 > num3; num4--) { span[num4] = span[num4 - 1]; } span[num3] = j; } } int num5 = 0; for (int l = 0; l < num2; l++) { MarkerItemAggregate markerItemAggregate = itemRows[span[l]]; if (builder.Length > 0) { builder.Append('\n'); } builder.Append(markerItemAggregate.LocalizedName); if (markerItemAggregate.Count > 1) { builder.Append(" ×").Append(markerItemAggregate.Count.ToString(CultureInfo.InvariantCulture)); } num5 += markerItemAggregate.Count; } shownRows = num2; overflowPhysicalCount = Math.Max(0, totalPhysicalCount - num5); if (overflowPhysicalCount > 0) { if (builder.Length > 0) { builder.Append('\n'); } builder.Append(MarkerTextLocalization.FormatPhysicalItems(overflowPhysicalCount, language)); } } private static int CompareExpandedDetailPriority(MarkerItemAggregate left, MarkerItemAggregate right) { int num = right.Count.CompareTo(left.Count); if (num != 0) { return num; } int num2 = MarkerSemanticCategoryPolicy.StableOrder(left.Category).CompareTo(MarkerSemanticCategoryPolicy.StableOrder(right.Category)); if (num2 != 0) { return num2; } int num3 = string.Compare(left.LocalizedName, right.LocalizedName, StringComparison.Ordinal); if (num3 != 0) { return num3; } return string.Compare(left.ItemIdentity, right.ItemIdentity, StringComparison.Ordinal); } private static void AppendDetailedComposition(StringBuilder builder, IReadOnlyList<MarkerCategoryCount> composition, MarkerLanguage language) { int num = 0; int num2 = 0; for (int i = 0; i < composition.Count; i++) { MarkerCategoryCount markerCategoryCount = composition[i]; if (markerCategoryCount.Count > 0) { string text = LocalizedCompositionWord(markerCategoryCount.Category, language) + " " + markerCategoryCount.Count.ToString(CultureInfo.InvariantCulture); int num3 = ((num != 0) ? 3 : 0); if (num > 0 && num + num3 + text.Length > 48 && num2 + 1 < 2) { builder.Append('\n'); num = 0; num2++; num3 = 0; } else if (num == 0) { builder.Append('\n'); } if (num > 0) { builder.Append(" · "); } builder.Append(text); num += num3 + text.Length; } } } private static MarkerCompactCategoryBadge[] BuildCategoryEntriesWithLifetime(MarkerSemanticCluster cluster, MarkerCategorySortOrder sortOrder, bool preserveCompositionOrder = false) { MarkerCompactCategoryBadge[] array; if (preserveCompositionOrder) { int num = 0; for (int i = 0; i < cluster.Composition.Count; i++) { if (num >= 14) { break; } if (cluster.Composition[i].Count > 0) { num++; } } array = new MarkerCompactCategoryBadge[num]; int num2 = 0; for (int j = 0; j < cluster.Composition.Count; j++) { if (num2 >= array.Length) { break; } MarkerCategoryCount markerCategoryCount = cluster.Composition[j]; if (markerCategoryCount.Count > 0) { array[num2++] = new MarkerCompactCategoryBadge(markerCategoryCount.Category, markerCategoryCount.Count, MarkerCategorySummaryPolicy.DisplayPriority(markerCategoryCount.Category)); } } } else { array = MarkerCategorySummaryPolicy.BuildCategoryEntries(cluster.Composition, sortOrder); } if (array.Length == 0) { return array; } List<MarkerCompactCategoryBadge> list = new List<MarkerCompactCategoryBadge>(Math.Min(28, array.Length * 2)); for (int k = 0; k < array.Length; k++) { if (list.Count >= 28) { break; } MarkerCompactCategoryBadge markerCompactCategoryBadge = array[k]; int num3 = 0; int num4 = 0; int num5 = 0; for (int l = 0; l < cluster.ItemRows.Count; l++) { MarkerItemAggregate markerItemAggregate = cluster.ItemRows[l]; if (markerItemAggregate.Category == markerCompactCategoryBadge.Category && markerItemAggregate.Count > 0) { switch (markerItemAggregate.Lifetime) { case MarkerLifetimeKind.Temporary: num3 += markerItemAggregate.Count; break; case MarkerLifetimeKind.Permanent: num4 += markerItemAggregate.Count; break; default: num5 += markerItemAggregate.Count; break; } } } int num6 = Math.Max(0, num4 + num5); if (num6 > 0 && list.Count < 28) { MarkerLifetimeKind lifetime = ((num5 != 0) ? MarkerLifetimeKind.Unknown : MarkerLifetimeKind.Permanent); list.Add(new MarkerCompactCategoryBadge(markerCompactCategoryBadge.Category, num6, markerCompactCategoryBadge.DisplayPriority, lifetime, MarkerPresentationGlyphKind.Diamond)); } if (num3 > 0 && list.Count < 28) { list.Add(new MarkerCompactCategoryBadge(markerCompactCategoryBadge.Category, num3, markerCompactCategoryBadge.DisplayPriority, MarkerLifetimeKind.Temporary, MarkerPresentationGlyphKind.Clock)); } } return list.ToArray(); } private static MarkerLifetimeIndicatorSpec BuildClusterLifetimeIndicator(MarkerSemanticCluster cluster, bool allowCount, bool showSingleCountWhenMixed) { return MarkerLifetimePolicy.BuildIndicator(cluster.LifetimeSummary, cluster.TemporaryPhysicalMemberCount, cluster.MixedLifetimeMemberCount, cluster.UnknownLifetimeMemberCount, allowCount, showSingleCountWhenMixed); } private static void AppendDistance(StringBuilder builder, bool showDistance, int distanceMeters, MarkerLanguage language) { if (showDistance) { if (builder.Length > 0) { builder.Append('\n'); } builder.Append(Math.Max(0, distanceMeters).ToString(CultureInfo.InvariantCulture)).Append(" ").Append(MarkerTextLocalization.DistanceUnit(language)); } } } public sealed class MarkerDenseAreaPresentationNode { public long StableKey { get; } public bool IsDenseSummary { get; } public IReadOnlyList<long> PhysicalClusterKeys { get; } public MarkerSemanticCluster PresentationCluster { get; } public MarkerWorldPoint WorldAnchor => PresentationCluster.WorldAnchor; public IReadOnlyList<long> MemberStableKeys => PresentationCluster.MemberStableKeys; public int TotalCount => PresentationCluster.TotalCount; public string MemberFingerprint => PresentationCluster.MemberFingerprint; internal MarkerDenseAreaPresentationNode(long stableKey, bool isDenseSummary, long[] physicalClusterKeys, MarkerSemanticCluster presentationCluster) { StableKey = stableKey; IsDenseSummary = isDenseSummary; PhysicalClusterKeys = physicalClusterKeys ?? Array.Empty<long>(); PresentationCluster = presentationCluster ?? throw new ArgumentNullException("presentationCluster"); } } public sealed class MarkerDenseAreaUpdate { public IReadOnlyList<MarkerDenseAreaPresentationNode> Nodes { get; } public bool MembershipChanged { get; } internal MarkerDenseAreaUpdate(IReadOnlyList<MarkerDenseAreaPresentationNode> nodes, bool membershipChanged) { Nodes = nodes; MembershipChanged = membershipChanged; } } public sealed class MarkerDenseAreaSummaryTracker { private readonly struct PairKey : IEquatable<PairKey> { public long A { get; } public long B { get; } public PairKey(long a, long b) { if (a <= b) { A = a; B = b; } else { A = b; B = a; } } public bool Equals(PairKey other) { if (A == other.A) { return B == other.B; } return false; } public override bool Equals(object? obj) { if (obj is PairKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (A.GetHashCode() * 397) ^ B.GetHashCode(); } } private sealed class PairState { public bool Linked; public bool Pending; public bool PendingTarget; public double PendingSince; } private sealed class PreviousDenseOwner { public long OwnerKey { get; } public long[] MemberKeys { get; } public PreviousDenseOwner(long ownerKey, long[] memberKeys) { OwnerKey = ownerKey; MemberKeys = memberKeys; } } private sealed class MutableAggregate { public string ItemIdentity { get; } public string LocalizedName { get; } public MarkerSemanticCategory Category { get; } public MarkerLifetimeKind Lifetime { get; } public int Count { get; set; } public MutableAggregate(string itemIdentity, string localizedName, MarkerSemanticCategory category, MarkerLifetimeKind lifetime) { ItemIdentity = itemIdentity; LocalizedName = localizedName; Category = category; Lifetime = lifetime; } } public const float MergeRadiusMeters = 12f; public const float SplitRadiusMeters = 16f; public const double ThresholdTransitionDwellSeconds = 0.35; public const int MinimumPhysicalClustersForSummary = 2; private readonly List<MarkerSemanticCluster> _orderedClusters = new List<MarkerSemanticCluster>(); private readonly Dictionary<PairKey, PairState> _pairStates = new Dictionary<PairKey, PairState>(); private readonly List<PairKey> _stalePairs = new List<PairKey>(); private readonly List<MarkerDenseAreaPresentationNode> _nodes = new List<MarkerDenseAreaPresentationNode>(); private readonly List<PreviousDenseOwner> _previousDenseOwners = new List<PreviousDenseOwner>(); private string _lastMembershipSignature = string.Empty; public IReadOnlyList<MarkerDenseAreaPresentationNode> Nodes => _nodes; public MarkerDenseAreaUpdate Update(IReadOnlyList<MarkerSemanticCluster> physicalClusters, double nowSeconds) { if (physicalClusters == null) { throw new ArgumentNullException("physicalClusters"); } if (double.IsNaN(nowSeconds) || double.IsInfinity(nowSeconds)) { nowSeconds = 0.0; } _orderedClusters.Clear(); for (int i = 0; i < physicalClusters.Count; i++) { if (physicalClusters[i] != null) { _orderedClusters.Add(physicalClusters[i]); } } _orderedClusters.Sort((MarkerSemanticCluster left, MarkerSemanticCluster right) => left.StableKey.CompareTo(right.StableKey)); ReconcileNewPairsImmediately(); AdvanceExistingPairs(nowSeconds); PrunePairStates(); List<MarkerDenseAreaPresentationNode> list = BuildPresentationNodes(); string text = BuildMembershipSignature(list); bool membershipChanged = !string.Equals(text, _lastMembershipSignature, StringComparison.Ordinal); _lastMembershipSignature = text; _nodes.Clear(); _nodes.AddRange(list); CapturePreviousDenseOwners(); return new MarkerDenseAreaUpdate(_nodes, membershipChanged); } public void Clear() { _orderedClusters.Clear(); _pairStates.Clear(); _stalePairs.Clear(); _nodes.Clear(); _previousDenseOwners.Clear(); _lastMembershipSignature = string.Empty; } private void ReconcileNewPairsImmediately() { float num = 144f; for (int i = 0; i < _orderedClusters.Count; i++) { for (int j = i + 1; j < _orderedClusters.Count; j++) { PairKey key = new PairKey(_orderedClusters[i].StableKey, _orderedClusters[j].StableKey); if (!_pairStates.ContainsKey(key)) { _pairStates[key] = new PairState { Linked = (MarkerWorldPoint.DistanceSquared(_
ItemShareFix/ItemShareFix.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemShareFix.Core; using Microsoft.CodeAnalysis; using RoR2; using RoR2.Networking; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ItemShareFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0")] [assembly: AssemblyProduct("ItemShareFix")] [assembly: AssemblyTitle("ItemShareFix")] [assembly: AssemblyVersion("1.2.0.0")] 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; } } } namespace ItemShareFix { internal enum C2HitchPhase { ClientSweep, ClientSweepPickupPresent, ClientRenderFrameMarkerBearing, NativeMarkerRender, EnsureCanvas, ResolveNativeTypography, GetOrCreateView, MeasureVisualFootprint, ServerBeginDistribution, ServerEnsureClaims, ServerSweepParticipantsPeriodic, ServerSweepParticipantsDistribution, ClientHudProbe, ClientCandidateBuild, ClientRendererCall, NativeSemanticBuild, NativeLayoutSolve, NativeApplyViews, NativePostRenderCleanup, ColdWarmupHudProbe, ColdWarmupNative, SemanticSignatureIndex, SemanticBuildWorldMembers, SemanticTrackerUpdate, SemanticDenseTrackerUpdate, SemanticClassification, SemanticExpansionLod, LayoutClusterFrameBuild, LayoutPlacementCandidateBuild, LayoutSingleMarkerPlacement, LayoutDirectionalAggregation, PresentationPlanBuild, ApplyTextStyle, ApplyGeometryLayout, ApplyActivation, LoadingNestedPrimer, CommandPickerDiscovery, CommandOptionResolution, CommandMarkerRegistryUpdate, CommandRenderInputConstruction, FirstMarkerActivationEndToEnd, Count } internal readonly struct C2HitchToken { public bool Active { get; } public C2HitchPhase Phase { get; } public long StartedTicks { get; } public int Frame { get; } public float UnscaledTime { get; } public int Gc0 { get; } public int Gc1 { get; } public int Gc2 { get; } public int MarkerCount { get; } public int PickupCount { get; } public int ParticipantCount { get; } public int ClaimCount { get; } public C2HitchToken(C2HitchPhase phase, long startedTicks, int frame, float unscaledTime, int gc0, int gc1, int gc2, int markerCount, int pickupCount, int participantCount, int claimCount) { Active = true; Phase = phase; StartedTicks = startedTicks; Frame = frame; UnscaledTime = unscaledTime; Gc0 = gc0; Gc1 = gc1; Gc2 = gc2; MarkerCount = markerCount; PickupCount = pickupCount; ParticipantCount = participantCount; ClaimCount = claimCount; } } internal static class C2HitchDiagnostics { private struct Sample { public C2HitchPhase Phase; public int Ordinal; public int Frame; public float UnscaledTime; public long ElapsedTicks; public bool ServerActive; public bool ClientActive; public int MarkerCountBefore; public int MarkerCountAfter; public int PickupCountBefore; public int PickupCountAfter; public int ParticipantCountBefore; public int ParticipantCountAfter; public int ClaimCountBefore; public int ClaimCountAfter; public int Gc0Delta; public int Gc1Delta; public int Gc2Delta; public int FirstMarkerFrame; } private const int MaxRecords = 64; private const float FlushDelaySeconds = 0.75f; private static readonly Sample[] Records = new Sample[64]; private static readonly int[] PhaseCounts = new int[41]; private static int _recordCount; private static int _flushedCount; private static int _firstMarkerFrame = -1; private static int _lastCaptureFrame = -1; private static float _nextFlushAt; private static bool _enabled; private static bool _captureSuppressed; public static void SetEnabled(bool enabled) { _enabled = enabled; } public static void SetCaptureSuppressed(bool suppressed) { _captureSuppressed = suppressed; } public static void MarkFirstMarkerFrame() { if (_enabled && !_captureSuppressed && _firstMarkerFrame < 0) { _firstMarkerFrame = Time.frameCount; } } public static C2HitchToken Begin(C2HitchPhase phase, int markerCount = -1, int pickupCount = -1, int participantCount = -1, int claimCount = -1) { if (!_enabled || _captureSuppressed) { return default(C2HitchToken); } if (phase < C2HitchPhase.ClientSweep || (int)phase >= PhaseCounts.Length) { return default(C2HitchToken); } if (PhaseCounts[(int)phase] >= MaxSamples(phase) || _recordCount >= 64) { return default(C2HitchToken); } return new C2HitchToken(phase, Stopwatch.GetTimestamp(), Time.frameCount, Time.unscaledTime, GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), markerCount, pickupCount, participantCount, claimCount); } public static void End(C2HitchToken token, int markerCount = -1, int pickupCount = -1, int participantCount = -1, int claimCount = -1) { if (token.Active && _recordCount < 64) { int phase = (int)token.Phase; if (phase >= 0 && phase < PhaseCounts.Length && PhaseCounts[phase] < MaxSamples(token.Phase)) { int ordinal = ++PhaseCounts[phase]; Records[_recordCount++] = new Sample { Phase = token.Phase, Ordinal = ordinal, Frame = token.Frame, UnscaledTime = token.UnscaledTime, ElapsedTicks = Stopwatch.GetTimestamp() - token.StartedTicks, ServerActive = NetworkServer.active, ClientActive = NetworkClient.active, MarkerCountBefore = token.MarkerCount, MarkerCountAfter = markerCount, PickupCountBefore = token.PickupCount, PickupCountAfter = pickupCount, ParticipantCountBefore = token.ParticipantCount, ParticipantCountAfter = participantCount, ClaimCountBefore = token.ClaimCount, ClaimCountAfter = claimCount, Gc0Delta = GC.CollectionCount(0) - token.Gc0, Gc1Delta = GC.CollectionCount(1) - token.Gc1, Gc2Delta = GC.CollectionCount(2) - token.Gc2, FirstMarkerFrame = _firstMarkerFrame }; _lastCaptureFrame = Time.frameCount; _nextFlushAt = Time.unscaledTime + 0.75f; } } } public static void FlushIfReady(ManualLogSource log) { if (_enabled && _flushedCount < _recordCount && Time.frameCount > _lastCaptureFrame + 2 && !(Time.unscaledTime < _nextFlushAt)) { for (int i = _flushedCount; i < _recordCount; i++) { Sample sample = Records[i]; double num = (double)sample.ElapsedTicks * 1000000.0 / (double)Stopwatch.Frequency; bool flag = sample.ServerActive && sample.ClientActive; log.LogInfo((object)("[ItemShareFix] ISF_C2_HITCH_DIAG phase=" + PhaseToken(sample.Phase) + " method=" + MethodToken(sample.Phase) + " context=" + ContextToken(sample.Phase) + " sample=" + ((sample.Ordinal == 1) ? "first" : "subsequent") + " ordinal=" + sample.Ordinal.ToString(CultureInfo.InvariantCulture) + " frame=" + sample.Frame.ToString(CultureInfo.InvariantCulture) + " time=" + sample.UnscaledTime.ToString("F6", CultureInfo.InvariantCulture) + " elapsed_us=" + num.ToString("F3", CultureInfo.InvariantCulture) + " host=" + (flag ? "true" : "false") + " server=" + (sample.ServerActive ? "true" : "false") + " client=" + (sample.ClientActive ? "true" : "false") + " markers_before=" + sample.MarkerCountBefore.ToString(CultureInfo.InvariantCulture) + " markers_after=" + sample.MarkerCountAfter.ToString(CultureInfo.InvariantCulture) + " pickups_before=" + sample.PickupCountBefore.ToString(CultureInfo.InvariantCulture) + " pickups_after=" + sample.PickupCountAfter.ToString(CultureInfo.InvariantCulture) + " participants_before=" + sample.ParticipantCountBefore.ToString(CultureInfo.InvariantCulture) + " participants_after=" + sample.ParticipantCountAfter.ToString(CultureInfo.InvariantCulture) + " claims_before=" + sample.ClaimCountBefore.ToString(CultureInfo.InvariantCulture) + " claims_after=" + sample.ClaimCountAfter.ToString(CultureInfo.InvariantCulture) + " gc0_delta=" + sample.Gc0Delta.ToString(CultureInfo.InvariantCulture) + " gc1_delta=" + sample.Gc1Delta.ToString(CultureInfo.InvariantCulture) + " gc2_delta=" + sample.Gc2Delta.ToString(CultureInfo.InvariantCulture) + " first_marker_frame=" + sample.FirstMarkerFrame.ToString(CultureInfo.InvariantCulture) + " same_first_marker_frame=" + ((sample.FirstMarkerFrame >= 0 && sample.Frame == sample.FirstMarkerFrame) ? "true" : "false"))); } _flushedCount = _recordCount; } } private static int MaxSamples(C2HitchPhase phase) { switch (phase) { case C2HitchPhase.EnsureCanvas: case C2HitchPhase.ResolveNativeTypography: return 1; case C2HitchPhase.SemanticSignatureIndex: case C2HitchPhase.SemanticBuildWorldMembers: case C2HitchPhase.SemanticTrackerUpdate: case C2HitchPhase.SemanticDenseTrackerUpdate: case C2HitchPhase.SemanticClassification: case C2HitchPhase.SemanticExpansionLod: case C2HitchPhase.LayoutClusterFrameBuild: case C2HitchPhase.LayoutPlacementCandidateBuild: case C2HitchPhase.LayoutSingleMarkerPlacement: case C2HitchPhase.LayoutDirectionalAggregation: case C2HitchPhase.PresentationPlanBuild: case C2HitchPhase.ApplyTextStyle: case C2HitchPhase.ApplyGeometryLayout: case C2HitchPhase.ApplyActivation: return 1; default: if (phase == C2HitchPhase.LoadingNestedPrimer) { return 1; } return 3; } } private static string PhaseToken(C2HitchPhase phase) { return phase switch { C2HitchPhase.ClientSweep => "CLIENT_SWEEP", C2HitchPhase.ClientSweepPickupPresent => "CLIENT_SWEEP", C2HitchPhase.ClientRenderFrameMarkerBearing => "CLIENT_RENDER_FRAME", C2HitchPhase.NativeMarkerRender => "NATIVE_MARKER_RENDER", C2HitchPhase.EnsureCanvas => "ENSURE_CANVAS", C2HitchPhase.ResolveNativeTypography => "RESOLVE_NATIVE_TYPOGRAPHY", C2HitchPhase.GetOrCreateView => "GET_OR_CREATE_VIEW", C2HitchPhase.MeasureVisualFootprint => "MEASURE_VISUAL_FOOTPRINT", C2HitchPhase.ServerBeginDistribution => "SERVER_BEGIN_DISTRIBUTION", C2HitchPhase.ServerEnsureClaims => "SERVER_ENSURE_CLAIMS", C2HitchPhase.ServerSweepParticipantsPeriodic => "SERVER_SWEEP_PARTICIPANTS", C2HitchPhase.ServerSweepParticipantsDistribution => "SERVER_SWEEP_PARTICIPANTS", C2HitchPhase.ClientHudProbe => "CLIENT_HUD_PROBE", C2HitchPhase.ClientCandidateBuild => "CLIENT_CANDIDATE_BUILD", C2HitchPhase.ClientRendererCall => "CLIENT_RENDERER_CALL", C2HitchPhase.NativeSemanticBuild => "NATIVE_SEMANTIC_BUILD", C2HitchPhase.NativeLayoutSolve => "NATIVE_LAYOUT_SOLVE", C2HitchPhase.NativeApplyViews => "NATIVE_APPLY_VIEWS", C2HitchPhase.NativePostRenderCleanup => "NATIVE_POST_RENDER_CLEANUP", C2HitchPhase.ColdWarmupHudProbe => "COLD_WARMUP_HUD_PROBE", C2HitchPhase.ColdWarmupNative => "COLD_WARMUP_NATIVE", C2HitchPhase.SemanticSignatureIndex => "SEMANTIC_SIGNATURE_INDEX", C2HitchPhase.SemanticBuildWorldMembers => "SEMANTIC_BUILD_WORLD_MEMBERS", C2HitchPhase.SemanticTrackerUpdate => "SEMANTIC_TRACKER_UPDATE", C2HitchPhase.SemanticDenseTrackerUpdate => "SEMANTIC_DENSE_TRACKER_UPDATE", C2HitchPhase.SemanticClassification => "SEMANTIC_CLASSIFICATION", C2HitchPhase.SemanticExpansionLod => "SEMANTIC_EXPANSION_LOD", C2HitchPhase.LayoutClusterFrameBuild => "LAYOUT_CLUSTER_FRAME_BUILD", C2HitchPhase.LayoutPlacementCandidateBuild => "LAYOUT_PLACEMENT_CANDIDATE_BUILD", C2HitchPhase.LayoutSingleMarkerPlacement => "LAYOUT_SINGLE_MARKER_PLACEMENT", C2HitchPhase.LayoutDirectionalAggregation => "LAYOUT_DIRECTIONAL_AGGREGATION", C2HitchPhase.PresentationPlanBuild => "PRESENTATION_PLAN_BUILD", C2HitchPhase.ApplyTextStyle => "APPLY_TEXT_STYLE", C2HitchPhase.ApplyGeometryLayout => "APPLY_GEOMETRY_LAYOUT", C2HitchPhase.ApplyActivation => "APPLY_ACTIVATION", C2HitchPhase.LoadingNestedPrimer => "LOADING_NESTED_PRIMER", C2HitchPhase.CommandPickerDiscovery => "COMMAND_PICKER_DISCOVERY", C2HitchPhase.CommandOptionResolution => "COMMAND_OPTION_RESOLUTION", C2HitchPhase.CommandMarkerRegistryUpdate => "COMMAND_MARKER_REGISTRY_UPDATE", C2HitchPhase.CommandRenderInputConstruction => "COMMAND_RENDER_INPUT_CONSTRUCTION", C2HitchPhase.FirstMarkerActivationEndToEnd => "FIRST_MARKER_ACTIVATION_END_TO_END", _ => "UNKNOWN", }; } private static string MethodToken(C2HitchPhase phase) { return phase switch { C2HitchPhase.ClientSweep => "ClientPresentationCoordinator.Sweep", C2HitchPhase.ClientSweepPickupPresent => "ClientPresentationCoordinator.Sweep", C2HitchPhase.ClientRenderFrameMarkerBearing => "ClientPresentationCoordinator.RenderFrame", C2HitchPhase.NativeMarkerRender => "NativeHudMarkerRenderer.Render", C2HitchPhase.EnsureCanvas => "NativeHudMarkerRenderer.EnsureCanvas", C2HitchPhase.ResolveNativeTypography => "NativeHudMarkerRenderer.ResolveNativeTypography", C2HitchPhase.GetOrCreateView => "NativeHudMarkerRenderer.GetOrCreateView", C2HitchPhase.MeasureVisualFootprint => "NativeHudMarkerRenderer.GetOrMeasureVisualFootprint", C2HitchPhase.ServerBeginDistribution => "ServerCoordinator.BeginDistribution", C2HitchPhase.ServerEnsureClaims => "ServerCoordinator.EnsureClaims", C2HitchPhase.ServerSweepParticipantsPeriodic => "ServerCoordinator.SweepParticipants", C2HitchPhase.ServerSweepParticipantsDistribution => "ServerCoordinator.SweepParticipants", C2HitchPhase.ClientHudProbe => "ClientPresentationCoordinator.RenderFrame.HudProbe", C2HitchPhase.ClientCandidateBuild => "ClientPresentationCoordinator.RenderFrame.BuildCandidates", C2HitchPhase.ClientRendererCall => "ClientPresentationCoordinator.RenderFrame.RendererCall", C2HitchPhase.NativeSemanticBuild => "NativeHudMarkerRenderer.Render.SemanticBuild", C2HitchPhase.NativeLayoutSolve => "NativeHudMarkerRenderer.Render.LayoutSolve", C2HitchPhase.NativeApplyViews => "NativeHudMarkerRenderer.Render.ApplyViews", C2HitchPhase.NativePostRenderCleanup => "NativeHudMarkerRenderer.Render.PostCleanup", C2HitchPhase.ColdWarmupHudProbe => "ClientPresentationCoordinator.AdvanceMarkerColdPathWarmup", C2HitchPhase.ColdWarmupNative => "NativeHudMarkerRenderer.WarmColdPathStep", C2HitchPhase.SemanticSignatureIndex => "NativeHudMarkerRenderer.Render.SemanticSignatureIndex", C2HitchPhase.SemanticBuildWorldMembers => "NativeHudMarkerRenderer.BuildWorldMembers", C2HitchPhase.SemanticTrackerUpdate => "MarkerWorldClusterTracker.Update", C2HitchPhase.SemanticDenseTrackerUpdate => "MarkerDenseAreaSummaryTracker.Update", C2HitchPhase.SemanticClassification => "NativeHudMarkerRenderer.ClassifyPresentationNodes", C2HitchPhase.SemanticExpansionLod => "NativeHudMarkerRenderer.BuildExpansionCandidates+MarkerAdaptiveLodTracker.Update", C2HitchPhase.LayoutClusterFrameBuild => "NativeHudMarkerRenderer.TryBuildCurrentClusterFrame", C2HitchPhase.LayoutPlacementCandidateBuild => "NativeHudMarkerRenderer.Render.PlacementCandidateBuild", C2HitchPhase.LayoutSingleMarkerPlacement => "NativeHudMarkerRenderer.ResolveCurrentPlacements.Single", C2HitchPhase.LayoutDirectionalAggregation => "MarkerDirectionalAggregationPolicy.Aggregate", C2HitchPhase.PresentationPlanBuild => "NativeHudMarkerRenderer.GetOrBuildPresentationPlan", C2HitchPhase.ApplyTextStyle => "NativeHudMarkerRenderer.ApplyView.TextStyle", C2HitchPhase.ApplyGeometryLayout => "NativeHudMarkerRenderer.ApplyView.GeometryLayout", C2HitchPhase.ApplyActivation => "NativeHudMarkerRenderer.ApplyView.Activation", C2HitchPhase.LoadingNestedPrimer => "NativeHudMarkerRenderer.PrimeNestedColdPathDuringInitialization", C2HitchPhase.CommandPickerDiscovery => "ClientPresentationCoordinator.Sweep.CommandPickerDiscovery", C2HitchPhase.CommandOptionResolution => "ClientPresentationCoordinator.Sweep.CommandOptionResolution", C2HitchPhase.CommandMarkerRegistryUpdate => "ClientPresentationCoordinator.Sweep.CommandMarkerRegistryUpdate", C2HitchPhase.CommandRenderInputConstruction => "ClientPresentationCoordinator.RenderFrame.CommandRenderInputConstruction", C2HitchPhase.FirstMarkerActivationEndToEnd => "ClientPresentationCoordinator.FirstMarkerEligibilityToRenderComplete", _ => "unknown", }; } private static string ContextToken(C2HitchPhase phase) { switch (phase) { default: switch (phase) { default: return "none"; case C2HitchPhase.ColdWarmupHudProbe: case C2HitchPhase.ColdWarmupNative: return "cold-prewarm"; case C2HitchPhase.LoadingNestedPrimer: return "plugin-initialization-noninteractive"; case C2HitchPhase.CommandPickerDiscovery: case C2HitchPhase.CommandOptionResolution: case C2HitchPhase.CommandMarkerRegistryUpdate: case C2HitchPhase.CommandRenderInputConstruction: case C2HitchPhase.FirstMarkerActivationEndToEnd: return "first-marker-activation"; } case C2HitchPhase.ClientRenderFrameMarkerBearing: case C2HitchPhase.NativeMarkerRender: case C2HitchPhase.ClientHudProbe: case C2HitchPhase.ClientCandidateBuild: case C2HitchPhase.ClientRendererCall: case C2HitchPhase.NativeSemanticBuild: case C2HitchPhase.NativeLayoutSolve: case C2HitchPhase.NativeApplyViews: case C2HitchPhase.NativePostRenderCleanup: case C2HitchPhase.SemanticSignatureIndex: case C2HitchPhase.SemanticBuildWorldMembers: case C2HitchPhase.SemanticTrackerUpdate: case C2HitchPhase.SemanticDenseTrackerUpdate: case C2HitchPhase.SemanticClassification: case C2HitchPhase.SemanticExpansionLod: case C2HitchPhase.LayoutClusterFrameBuild: case C2HitchPhase.LayoutPlacementCandidateBuild: case C2HitchPhase.LayoutSingleMarkerPlacement: case C2HitchPhase.LayoutDirectionalAggregation: case C2HitchPhase.PresentationPlanBuild: case C2HitchPhase.ApplyTextStyle: case C2HitchPhase.ApplyGeometryLayout: case C2HitchPhase.ApplyActivation: return "marker-bearing"; case C2HitchPhase.ClientSweepPickupPresent: return "pickup-present"; case C2HitchPhase.ServerSweepParticipantsPeriodic: return "periodic"; case C2HitchPhase.ServerSweepParticipantsDistribution: return "distribution"; } } } internal static class CommandOptionResolutionDiagnostics { private struct ActiveSample { public bool Active; public int Ordinal; public int Frame; public float UnscaledTime; public int PickerInstanceId; public long StartedTicks; public int Gc0; public int Gc1; public int Gc2; public long SnapshotTicks; public long SnapshotPreflightTicks; public long OptionEnumerationMemberResolutionTicks; public long PickupIndexSourceResolutionTicks; public long DedupFinalizationTicks; public long MetadataTicks; public long PickupMetadataClassificationTicks; public long UpstreamShareabilityTicks; public long PresentationFinalizationTicks; public int OptionsVisited; public int AvailableOptions; public int ResolvedPickupIndexes; public int ExactNestedAvailable; public int UnresolvedAvailable; public int DuplicatePickupCount; public int UpstreamShareabilityCalls; } private struct Sample { public int Ordinal; public int Frame; public float UnscaledTime; public int PickerInstanceId; public long ElapsedTicks; public long SnapshotTicks; public long SnapshotPreflightTicks; public long OptionEnumerationMemberResolutionTicks; public long PickupIndexSourceResolutionTicks; public long DedupFinalizationTicks; public long MetadataTicks; public long PickupMetadataClassificationTicks; public long UpstreamShareabilityTicks; public long PresentationFinalizationTicks; public int OptionsVisited; public int AvailableOptions; public int ResolvedPickupIndexes; public int ExactNestedAvailable; public int UnresolvedAvailable; public int DuplicatePickupCount; public int UpstreamShareabilityCalls; public int Gc0Delta; public int Gc1Delta; public int Gc2Delta; } private const int MaxSamples = 5; private const float FlushDelaySeconds = 0.75f; private static readonly Sample[] Records = new Sample[5]; private static ActiveSample _active; private static int _recordCount; private static int _flushedCount; private static int _lastCaptureFrame = -1; private static float _nextFlushAt; private static bool _enabled; internal static bool CaptureActive => _active.Active; internal static void SetEnabled(bool enabled) { _enabled = enabled; if (!enabled) { _active = default(ActiveSample); } } internal static void Begin(int pickerInstanceId) { if (_enabled && !_active.Active && _recordCount < 5) { _active = new ActiveSample { Active = true, Ordinal = _recordCount + 1, Frame = Time.frameCount, UnscaledTime = Time.unscaledTime, PickerInstanceId = pickerInstanceId, StartedTicks = Stopwatch.GetTimestamp(), Gc0 = GC.CollectionCount(0), Gc1 = GC.CollectionCount(1), Gc2 = GC.CollectionCount(2) }; } } internal static void RecordSnapshot(long totalTicks, long preflightTicks, long optionEnumerationMemberResolutionTicks, long pickupIndexSourceResolutionTicks, long dedupFinalizationTicks, int optionsVisited, int availableOptions, int resolvedPickupIndexes, int exactNestedAvailable, int unresolvedAvailable, int duplicatePickupCount) { if (_active.Active) { _active.SnapshotTicks = totalTicks; _active.SnapshotPreflightTicks = preflightTicks; _active.OptionEnumerationMemberResolutionTicks = optionEnumerationMemberResolutionTicks; _active.PickupIndexSourceResolutionTicks = pickupIndexSourceResolutionTicks; _active.DedupFinalizationTicks = dedupFinalizationTicks; _active.OptionsVisited = optionsVisited; _active.AvailableOptions = availableOptions; _active.ResolvedPickupIndexes = resolvedPickupIndexes; _active.ExactNestedAvailable = exactNestedAvailable; _active.UnresolvedAvailable = unresolvedAvailable; _active.DuplicatePickupCount = duplicatePickupCount; } } internal static void RecordMetadata(long totalTicks, long pickupMetadataClassificationTicks, long upstreamShareabilityTicks, long presentationFinalizationTicks, int upstreamShareabilityCalls) { if (_active.Active) { _active.MetadataTicks = totalTicks; _active.PickupMetadataClassificationTicks = pickupMetadataClassificationTicks; _active.UpstreamShareabilityTicks = upstreamShareabilityTicks; _active.PresentationFinalizationTicks = presentationFinalizationTicks; _active.UpstreamShareabilityCalls = upstreamShareabilityCalls; } } internal static void Complete() { if (_active.Active) { long timestamp = Stopwatch.GetTimestamp(); ActiveSample active = _active; Records[_recordCount++] = new Sample { Ordinal = active.Ordinal, Frame = active.Frame, UnscaledTime = active.UnscaledTime, PickerInstanceId = active.PickerInstanceId, ElapsedTicks = timestamp - active.StartedTicks, SnapshotTicks = active.SnapshotTicks, SnapshotPreflightTicks = active.SnapshotPreflightTicks, OptionEnumerationMemberResolutionTicks = active.OptionEnumerationMemberResolutionTicks, PickupIndexSourceResolutionTicks = active.PickupIndexSourceResolutionTicks, DedupFinalizationTicks = active.DedupFinalizationTicks, MetadataTicks = active.MetadataTicks, PickupMetadataClassificationTicks = active.PickupMetadataClassificationTicks, UpstreamShareabilityTicks = active.UpstreamShareabilityTicks, PresentationFinalizationTicks = active.PresentationFinalizationTicks, OptionsVisited = active.OptionsVisited, AvailableOptions = active.AvailableOptions, ResolvedPickupIndexes = active.ResolvedPickupIndexes, ExactNestedAvailable = active.ExactNestedAvailable, UnresolvedAvailable = active.UnresolvedAvailable, DuplicatePickupCount = active.DuplicatePickupCount, UpstreamShareabilityCalls = active.UpstreamShareabilityCalls, Gc0Delta = GC.CollectionCount(0) - active.Gc0, Gc1Delta = GC.CollectionCount(1) - active.Gc1, Gc2Delta = GC.CollectionCount(2) - active.Gc2 }; _active = default(ActiveSample); _lastCaptureFrame = Time.frameCount; _nextFlushAt = Time.unscaledTime + 0.75f; } } internal static void FlushIfReady(ManualLogSource log) { if (_enabled && _flushedCount < _recordCount && Time.frameCount > _lastCaptureFrame + 2 && !(Time.unscaledTime < _nextFlushAt)) { for (int i = _flushedCount; i < _recordCount; i++) { Sample sample = Records[i]; log.LogInfo((object)("[ItemShareFix] ISF_COMMAND_OPTION_PROFILE sample=" + ((sample.Ordinal == 1) ? "first" : "subsequent") + " ordinal=" + sample.Ordinal.ToString(CultureInfo.InvariantCulture) + " frame=" + sample.Frame.ToString(CultureInfo.InvariantCulture) + " time=" + sample.UnscaledTime.ToString("F6", CultureInfo.InvariantCulture) + " picker_instance_id=" + sample.PickerInstanceId.ToString(CultureInfo.InvariantCulture) + " elapsed_us=" + ToMicroseconds(sample.ElapsedTicks).ToString("F3", CultureInfo.InvariantCulture) + " snapshot_us=" + ToMicroseconds(sample.SnapshotTicks).ToString("F3", CultureInfo.InvariantCulture) + " snapshot_preflight_us=" + ToMicroseconds(sample.SnapshotPreflightTicks).ToString("F3", CultureInfo.InvariantCulture) + " option_enumeration_member_resolution_us=" + ToMicroseconds(sample.OptionEnumerationMemberResolutionTicks).ToString("F3", CultureInfo.InvariantCulture) + " pickup_index_source_resolution_us=" + ToMicroseconds(sample.PickupIndexSourceResolutionTicks).ToString("F3", CultureInfo.InvariantCulture) + " dedup_finalization_us=" + ToMicroseconds(sample.DedupFinalizationTicks).ToString("F3", CultureInfo.InvariantCulture) + " metadata_us=" + ToMicroseconds(sample.MetadataTicks).ToString("F3", CultureInfo.InvariantCulture) + " pickup_metadata_catalog_classification_us=" + ToMicroseconds(sample.PickupMetadataClassificationTicks).ToString("F3", CultureInfo.InvariantCulture) + " upstream_shareability_bridge_us=" + ToMicroseconds(sample.UpstreamShareabilityTicks).ToString("F3", CultureInfo.InvariantCulture) + " presentation_finalization_us=" + ToMicroseconds(sample.PresentationFinalizationTicks).ToString("F3", CultureInfo.InvariantCulture) + " options_visited=" + sample.OptionsVisited.ToString(CultureInfo.InvariantCulture) + " available_options=" + sample.AvailableOptions.ToString(CultureInfo.InvariantCulture) + " resolved_pickup_indexes=" + sample.ResolvedPickupIndexes.ToString(CultureInfo.InvariantCulture) + " exact_nested_available=" + sample.ExactNestedAvailable.ToString(CultureInfo.InvariantCulture) + " unresolved_available=" + sample.UnresolvedAvailable.ToString(CultureInfo.InvariantCulture) + " duplicate_pickups=" + sample.DuplicatePickupCount.ToString(CultureInfo.InvariantCulture) + " upstream_shareability_calls=" + sample.UpstreamShareabilityCalls.ToString(CultureInfo.InvariantCulture) + " gc0_delta=" + sample.Gc0Delta.ToString(CultureInfo.InvariantCulture) + " gc1_delta=" + sample.Gc1Delta.ToString(CultureInfo.InvariantCulture) + " gc2_delta=" + sample.Gc2Delta.ToString(CultureInfo.InvariantCulture))); } _flushedCount = _recordCount; } } private static double ToMicroseconds(long ticks) { return (double)ticks * 1000000.0 / (double)Stopwatch.Frequency; } } internal sealed class LocalPickupPresentationGate : MonoBehaviour { private readonly Dictionary<Renderer, bool> _renderers = new Dictionary<Renderer, bool>(); private readonly Dictionary<Light, bool> _lights = new Dictionary<Light, bool>(); private readonly Dictionary<Behaviour, bool> _visualBehaviours = new Dictionary<Behaviour, bool>(); private bool _hidden; public void ApplyHidden() { _hidden = true; RefreshAndApply(); } public void Restore() { _hidden = false; KeyValuePair<Renderer, bool>[] array = _renderers.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<Renderer, bool> keyValuePair = array[i]; if ((Object)(object)keyValuePair.Key != (Object)null) { keyValuePair.Key.forceRenderingOff = keyValuePair.Value; } } KeyValuePair<Light, bool>[] array2 = _lights.ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair<Light, bool> keyValuePair2 = array2[i]; if ((Object)(object)keyValuePair2.Key != (Object)null) { ((Behaviour)keyValuePair2.Key).enabled = keyValuePair2.Value; } } KeyValuePair<Behaviour, bool>[] array3 = _visualBehaviours.ToArray(); for (int i = 0; i < array3.Length; i++) { KeyValuePair<Behaviour, bool> keyValuePair3 = array3[i]; if ((Object)(object)keyValuePair3.Key != (Object)null) { keyValuePair3.Key.enabled = keyValuePair3.Value; } } _renderers.Clear(); _lights.Clear(); _visualBehaviours.Clear(); } public void RefreshAndApply() { if (!_hidden) { return; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (!_renderers.ContainsKey(val)) { _renderers[val] = val.forceRenderingOff; } val.forceRenderingOff = true; } } Light[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Light>(true); foreach (Light val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { if (!_lights.ContainsKey(val2)) { _lights[val2] = ((Behaviour)val2).enabled; } ((Behaviour)val2).enabled = false; } } Behaviour[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<Behaviour>(true); foreach (Behaviour val3 in componentsInChildren3) { if (!((Object)(object)val3 == (Object)null) && !(val3 is Light) && IsPresentationOnlyBehaviour(((object)val3).GetType().FullName ?? ((object)val3).GetType().Name)) { if (!_visualBehaviours.ContainsKey(val3)) { _visualBehaviours[val3] = val3.enabled; } val3.enabled = false; } } PruneDestroyed(); } private static bool IsPresentationOnlyBehaviour(string typeName) { if (typeName.IndexOf("Highlight", StringComparison.OrdinalIgnoreCase) < 0 && typeName.IndexOf("VisualEffect", StringComparison.OrdinalIgnoreCase) < 0) { return typeName.IndexOf("PickupDisplayGlow", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private void PruneDestroyed() { Renderer[] array = _renderers.Keys.Where((Renderer x) => (Object)(object)x == (Object)null).ToArray(); foreach (Renderer key in array) { _renderers.Remove(key); } Light[] array2 = _lights.Keys.Where((Light x) => (Object)(object)x == (Object)null).ToArray(); foreach (Light key2 in array2) { _lights.Remove(key2); } Behaviour[] array3 = _visualBehaviours.Keys.Where((Behaviour x) => (Object)(object)x == (Object)null).ToArray(); foreach (Behaviour key3 in array3) { _visualBehaviours.Remove(key3); } } private void OnDestroy() { if (_hidden) { Restore(); } } } internal sealed class LocalCommandPresentationGate : MonoBehaviour { private readonly Dictionary<Renderer, bool> _renderers = new Dictionary<Renderer, bool>(); private readonly Dictionary<Light, bool> _lights = new Dictionary<Light, bool>(); private readonly Dictionary<Behaviour, bool> _visualBehaviours = new Dictionary<Behaviour, bool>(); private bool _hidden; public bool IsHidden => _hidden; public void ApplyHidden() { _hidden = true; RefreshAndApply(); } public void Restore() { _hidden = false; KeyValuePair<Renderer, bool>[] array = _renderers.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<Renderer, bool> keyValuePair = array[i]; if ((Object)(object)keyValuePair.Key != (Object)null) { keyValuePair.Key.forceRenderingOff = keyValuePair.Value; } } KeyValuePair<Light, bool>[] array2 = _lights.ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair<Light, bool> keyValuePair2 = array2[i]; if ((Object)(object)keyValuePair2.Key != (Object)null) { ((Behaviour)keyValuePair2.Key).enabled = keyValuePair2.Value; } } KeyValuePair<Behaviour, bool>[] array3 = _visualBehaviours.ToArray(); for (int i = 0; i < array3.Length; i++) { KeyValuePair<Behaviour, bool> keyValuePair3 = array3[i]; if ((Object)(object)keyValuePair3.Key != (Object)null) { keyValuePair3.Key.enabled = keyValuePair3.Value; } } _renderers.Clear(); _lights.Clear(); _visualBehaviours.Clear(); } public void RefreshAndApply() { if (!_hidden) { return; } Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { if (!_renderers.ContainsKey(val)) { _renderers[val] = val.forceRenderingOff; } val.forceRenderingOff = true; } } Light[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Light>(true); foreach (Light val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null)) { if (!_lights.ContainsKey(val2)) { _lights[val2] = ((Behaviour)val2).enabled; } ((Behaviour)val2).enabled = false; } } Behaviour[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<Behaviour>(true); foreach (Behaviour val3 in componentsInChildren3) { if (!((Object)(object)val3 == (Object)null) && !(val3 is Light) && !(val3 is PickupPickerController) && !(val3 is NetworkBehaviour) && IsPresentationOnlyBehaviour(((object)val3).GetType().FullName ?? ((object)val3).GetType().Name)) { if (!_visualBehaviours.ContainsKey(val3)) { _visualBehaviours[val3] = val3.enabled; } val3.enabled = false; } } PruneDestroyed(); } private static bool IsPresentationOnlyBehaviour(string typeName) { if (typeName.IndexOf("Highlight", StringComparison.OrdinalIgnoreCase) < 0 && typeName.IndexOf("VisualEffect", StringComparison.OrdinalIgnoreCase) < 0) { return typeName.IndexOf("PickupDisplayGlow", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private void PruneDestroyed() { Renderer[] array = _renderers.Keys.Where((Renderer x) => (Object)(object)x == (Object)null).ToArray(); foreach (Renderer key in array) { _renderers.Remove(key); } Light[] array2 = _lights.Keys.Where((Light x) => (Object)(object)x == (Object)null).ToArray(); foreach (Light key2 in array2) { _lights.Remove(key2); } Behaviour[] array3 = _visualBehaviours.Keys.Where((Behaviour x) => (Object)(object)x == (Object)null).ToArray(); foreach (Behaviour key3 in array3) { _visualBehaviours.Remove(key3); } } private void OnDestroy() { if (_hidden) { Restore(); } } } internal sealed class PersonalPickupMarker { public int InstanceId { get; set; } public GenericPickupController Pickup { get; set; } public string Label { get; set; } = string.Empty; public string ItemSemanticKey { get; set; } = string.Empty; public string ClassName { get; set; } = "UNKNOWN"; public MarkerClassKind Kind { get; set; } public Color TextColor { get; set; } = Color.white; public MarkerLifetimeKind Lifetime { get; set; } } internal sealed class PersonalCommandMarker { public int InstanceId { get; set; } public PickupPickerController Picker { get; set; } public string Label { get; set; } = string.Empty; public string ItemSemanticKey { get; set; } = string.Empty; public string ClassName { get; set; } = "UNKNOWN"; public MarkerClassKind Kind { get; set; } public Color TextColor { get; set; } = Color.white; public MarkerLifetimeKind Lifetime { get; set; } = (MarkerLifetimeKind)3; } internal readonly struct MarkerRuntimeMetadata { public MarkerClassKind Kind { get; } public string ClassName { get; } public string Label { get; } public Color TextColor { get; } public bool ExactClass { get; } public MarkerRuntimeMetadata(MarkerClassKind kind, string className, string label, Color textColor, bool exactClass) { //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_0016: 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) Kind = kind; ClassName = className; Label = label; TextColor = textColor; ExactClass = exactClass; } } internal sealed class ClientPresentationCoordinator { private readonly PluginConfig _config; private readonly UpstreamBridge _upstream; private readonly ManualLogSource _log; private readonly Dictionary<int, LocalPickupPresentationGate> _gates = new Dictionary<int, LocalPickupPresentationGate>(); private readonly Dictionary<int, LocalCommandPresentationGate> _commandGates = new Dictionary<int, LocalCommandPresentationGate>(); private readonly Dictionary<int, bool> _localCommandGateDiagnosticState = new Dictionary<int, bool>(); private readonly Dictionary<int, string> _localPickupVisualDiagnosticState = new Dictionary<int, string>(); private readonly Dictionary<long, bool> _localPickupInteractionDiagnosticState = new Dictionary<long, bool>(); private readonly HashSet<int> _upstreamVisibilityGateObserved = new HashSet<int>(); private readonly List<PersonalPickupMarker> _markers = new List<PersonalPickupMarker>(); private readonly List<PersonalCommandMarker> _commandMarkers = new List<PersonalCommandMarker>(); private readonly List<PersonalPickupMarker> _nextOrdinaryMarkers = new List<PersonalPickupMarker>(64); private readonly List<PersonalCommandMarker> _nextCommandMarkers = new List<PersonalCommandMarker>(32); private readonly HashSet<int> _seenPickups = new HashSet<int>(); private readonly HashSet<int> _previousOrdinaryIds = new HashSet<int>(); private readonly HashSet<int> _seenCommandCandidateIds = new HashSet<int>(); private readonly HashSet<int> _previousCommandIds = new HashSet<int>(); private readonly List<int> _staleInstanceIds = new List<int>(); private readonly List<CharacterMaster> _localMasterBuffer = new List<CharacterMaster>(4); private ParticipantState[] _localStateBuffer = Array.Empty<ParticipantState>(); private bool[] _collectedBuffer = Array.Empty<bool>(); private bool?[] _localPickedStateBuffer = Array.Empty<bool?>(); private readonly PersonalMarkerRegistry _markerRegistry = new PersonalMarkerRegistry(96); private readonly HashSet<int> _ordinaryRenderLogged = new HashSet<int>(); private readonly Dictionary<int, string> _commandRemovalReasons = new Dictionary<int, string>(); private readonly HashSet<int> _commandOptionDisagreementLogged = new HashSet<int>(); private readonly HashSet<int> _commandLifetimeUnknownLogged = new HashSet<int>(); private readonly Dictionary<int, string> _commandShareabilityDiagnosticState = new Dictionary<int, string>(); private float _nextSweep; private int _lastStageToken = int.MinValue; private int _localMastersFrame = -1; private CharacterMaster[] _cachedLocalMasters = Array.Empty<CharacterMaster>(); private bool _refreshRequested; private int _upstreamNormalizationDepth; private readonly MarkerRuntimePerformanceCounters _performance = new MarkerRuntimePerformanceCounters(); private readonly NativeHudMarkerRenderer _hudRenderer; private readonly Dictionary<long, MarkerHudDiagnosticState> _markerProjectionDiagnosticState = new Dictionary<long, MarkerHudDiagnosticState>(); private readonly LocalHudPresentationProbe _localHudProbe; private readonly List<MarkerHudExclusionZone> _dynamicHudZones = new List<MarkerHudExclusionZone>(1); private readonly List<MarkerRenderInput> _renderInputs = new List<MarkerRenderInput>(96); private bool? _modalHudSuppressionDiagnosticState; private string _modalHudSuppressionReason = string.Empty; private bool? _messageHudDiagnosticState; private bool _hasMessageHudDiagnosticRect; private MarkerHudRect _messageHudDiagnosticRect; private Camera? _presentationCamera; private float _nextPresentationCameraRefresh; private float _nextPerformanceSummary; private int _lastPerformanceMarkerCount; private C2HitchToken _firstMarkerActivationTiming; public ClientPresentationCoordinator(PluginConfig config, UpstreamBridge upstream, ManualLogSource log) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown _config = config; _upstream = upstream; _log = log; C2HitchDiagnostics.SetEnabled(_config.DiagnosticInfoEnabled); CommandOptionResolutionDiagnostics.SetEnabled(_config.DiagnosticInfoEnabled); _localHudProbe = new LocalHudPresentationProbe(_performance); _localHudProbe.PrimeGlobalDiscoveryDuringInitialization(); _hudRenderer = new NativeHudMarkerRenderer(log, _performance, config); _hudRenderer.PrimeNativeTypographyDuringInitialization(); _hudRenderer.PrimeNestedColdPathDuringInitialization(); _config.MarkerPresentationSettingChanged += OnMarkerPresentationSettingChanged; _log.LogInfo((object)"ISF_MARKER_WORLD_CLUSTER_CONFIG merge=4.50 split=6.00 dwell=0.35 solve=0.20"); } private void OnMarkerPresentationSettingChanged(object? sender, EventArgs args) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) _hudRenderer.InvalidatePresentationSettings(_config.MarkerSettingsSnapshot(), _config.MarkerVisualSettingsSnapshot()); if (sender == _config.PersonalMarkersEnabled || sender == _config.HideMarkersInTrials) { if (!_config.PersonalMarkersEnabled.Value) { _hudRenderer.Clear(); } RequestRefresh(); } else if (sender == _config.ShareTemporaryItems || sender == _config.ShareHallowedItems || sender == _config.ShareHexItems || sender == _config.ShareNTormatPages) { RequestRefresh(); } } public void RecordUnityUpdate() { _performance.RecordUnityUpdate(); } public void RequestRefresh() { _refreshRequested = true; } private bool MarkersSuppressedInCurrentScene() { SceneDef val = (((Object)(object)SceneInfo.instance != (Object)null) ? SceneInfo.instance.sceneDef : null); return MarkerSceneVisibilityPolicy.ShouldSuppress(_config.HideMarkersInTrials.Value, (val != null) ? val.baseSceneName : null, val?.nameToken); } public void OnBlockingModalLifecycleObserved(Component component) { _localHudProbe.ObserveBlockingModalLifecycle(component); } public void OnHudLifecycleObserved(Component component) { _localHudProbe.ObserveHudLifecycle(component); } public void OnTmpSubMeshOnDisable(TMP_SubMeshUI subMesh) { _hudRenderer.ObserveTmpSubMeshOnDisable(subMesh); } public bool TryEvaluateLocalCollected(GenericPickupController pickup, out bool collectedByAllLocalParticipants) { collectedByAllLocalParticipants = false; if (!_config.Enabled.Value || !_config.PersonalPickupVisibilityRepairEnabled.Value || !_upstream.IsIndividualMode || !_upstream.HideCollectedOrbsEnabled || (Object)(object)pickup == (Object)null || KnownProgressionPickupCompatibility.IsExcluded(pickup) || !_upstream.IsShareable(pickup)) { return false; } CharacterMaster[] localMastersSnapshot = GetLocalMastersSnapshot(); if (localMastersSnapshot.Length == 0) { return false; } collectedByAllLocalParticipants = localMastersSnapshot.All((CharacterMaster master) => _upstream.HasCollected(pickup, master)); return true; } public bool ShouldSuppressLocalPickupInteraction(GenericPickupController pickup, Interactor interactor) { if (!_config.Enabled.Value || !_config.PersonalPickupVisibilityRepairEnabled.Value || !_upstream.IsIndividualMode || !_upstream.HideCollectedOrbsEnabled || (Object)(object)pickup == (Object)null || (Object)(object)interactor == (Object)null || KnownProgressionPickupCompatibility.IsExcluded(pickup)) { return false; } bool flag = _upstream.IsShareable(pickup); CharacterBody component = ((Component)interactor).GetComponent<CharacterBody>(); if ((Object)(object)component == (Object)null || (Object)(object)component.master == (Object)null) { return false; } CharacterMaster master = component.master; bool hasAuthority = ((NetworkBehaviour)master).hasAuthority; bool flag2 = hasAuthority && _upstream.HasCollected(pickup, master); bool flag3 = LocalPickupSuppressionPolicy.ShouldSuppressInteractor(true, true, flag, hasAuthority, flag2); if (hasAuthority) { LogLocalInteractionGateTransition(pickup, master, flag2, flag3); } return flag3; } public void OnUpstreamVisibilityApplied(GenericPickupController pickup) { if ((Object)(object)pickup == (Object)null || _upstreamNormalizationDepth > 0) { return; } int instanceID = ((Object)pickup).GetInstanceID(); if (!TryEvaluateLocalCollected(pickup, out var collectedByAllLocalParticipants)) { ReleaseGate(instanceID); RequestRefresh(); return; } if (!collectedByAllLocalParticipants) { ReleaseGate(instanceID); return; } NormalizeUpstreamForGate(pickup); if (!_gates.TryGetValue(instanceID, out LocalPickupPresentationGate value) || (Object)(object)value == (Object)null) { value = ((Component)pickup).gameObject.GetComponent<LocalPickupPresentationGate>() ?? ((Component)pickup).gameObject.AddComponent<LocalPickupPresentationGate>(); _gates[instanceID] = value; } value.ApplyHidden(); if (_config.DiagnosticInfoEnabled && _upstreamVisibilityGateObserved.Add(instanceID)) { LogInfo("ISF_C20_LOCAL_PICKUP_GATE pickup=" + instanceID.ToString(CultureInfo.InvariantCulture) + " localMaster=process localCollected=all visualSuppressed=true interactionSuppressed=participant-specific action=upstream-visibility-applied reason=all-local-collected"); } } public void Tick() { int num = CurrentStageToken(); if (num != _lastStageToken) { RestoreAll("stage-or-run-boundary"); _localHudProbe.InvalidateLifecycle(); _presentationCamera = null; _nextPresentationCameraRefresh = 0f; _lastStageToken = num; _refreshRequested = true; } if (_refreshRequested || !(Time.unscaledTime < _nextSweep)) { _refreshRequested = false; _nextSweep = Time.unscaledTime + Math.Max(0.08f, _config.PresentationSweepSeconds.Value); Sweep(); } } public void RenderFrame() { //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0291: 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_02dc: 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_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: 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_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_0458: 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_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_049e: 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_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) _performance.RecordRenderFrame(); C2HitchDiagnostics.SetEnabled(_config.DiagnosticInfoEnabled); CommandOptionResolutionDiagnostics.SetEnabled(_config.DiagnosticInfoEnabled); C2HitchDiagnostics.FlushIfReady(_log); CommandOptionResolutionDiagnostics.FlushIfReady(_log); bool flag = _config.Enabled.Value && _config.PersonalMarkersEnabled.Value && !MarkersSuppressedInCurrentScene() && (_markers.Count > 0 || _commandMarkers.Count > 0); if (!flag) { if (_lastPerformanceMarkerCount > 0) { EmitPerformanceSummary("marker-teardown", 0, force: true); } _lastPerformanceMarkerCount = 0; _hudRenderer.SetPresentationSuppressed(suppressed: false); _hudRenderer.Clear(); if (_config.Enabled.Value && _config.PersonalMarkersEnabled.Value && !MarkersSuppressedInCurrentScene()) { AdvanceMarkerColdPathWarmup(allowRefresh: true); } } else { if (!AdvanceMarkerColdPathWarmup(allowRefresh: false)) { return; } int num = _markers.Count + _commandMarkers.Count; C2HitchDiagnostics.MarkFirstMarkerFrame(); C2HitchToken token = C2HitchDiagnostics.Begin(C2HitchPhase.ClientRenderFrameMarkerBearing, num); try { _lastPerformanceMarkerCount = num; MaybeEmitPerformanceSummary(num); C2HitchToken token2 = C2HitchDiagnostics.Begin(C2HitchPhase.ClientHudProbe, num); try { string reason; bool flag2 = _localHudProbe.TryGetBlockingModalCached(out reason); if (!_modalHudSuppressionDiagnosticState.HasValue || _modalHudSuppressionDiagnosticState.Value != flag2 || (flag2 && !string.Equals(_modalHudSuppressionReason, reason, StringComparison.Ordinal))) { _modalHudSuppressionDiagnosticState = flag2; _modalHudSuppressionReason = reason; LogInfo("ISF_MARKER_HUD_SUPPRESS reason=" + (flag2 ? reason : "pause-menu") + " active=" + flag2); } _hudRenderer.SetPresentationSuppressed(flag2); if (!MarkerPresentationPolicy.ShouldRenderHudMarkers(flag, flag2)) { return; } _dynamicHudZones.Clear(); MarkerHudRect rect; bool flag3 = _localHudProbe.TryGetVisibleMessageHudRectCached(out rect); if (flag3) { _dynamicHudZones.Add(new MarkerHudExclusionZone("message-hud-runtime", ((MarkerHudRect)(ref rect)).Left, ((MarkerHudRect)(ref rect)).Right, ((MarkerHudRect)(ref rect)).Bottom, ((MarkerHudRect)(ref rect)).Top)); } bool flag4 = flag3 && (!_hasMessageHudDiagnosticRect || !SameDiagnosticRect(_messageHudDiagnosticRect, rect)); if (!_messageHudDiagnosticState.HasValue || _messageHudDiagnosticState.Value != flag3 || flag4) { _messageHudDiagnosticState = flag3; _hasMessageHudDiagnosticRect = flag3; _messageHudDiagnosticRect = rect; LogInfo("ISF_MARKER_MESSAGE_HUD active=" + flag3 + (flag3 ? (" rect=" + FormatMarkerRect(rect)) : string.Empty)); } } finally { C2HitchDiagnostics.End(token2, num); } Camera val = null; MarkerLanguage val2 = (MarkerLanguage)0; C2HitchToken token3 = C2HitchDiagnostics.Begin(C2HitchPhase.ClientCandidateBuild, num); try { val = GetPresentationCamera(); if ((Object)(object)val == (Object)null || !TryGetFiniteCameraPosition(val, out var cameraPosition)) { _hudRenderer.Clear(); return; } val2 = CurrentMarkerLanguage(); _renderInputs.Clear(); int num2 = 0; while (num2 < _markers.Count) { PersonalPickupMarker personalPickupMarker = _markers[num2]; if (!TryResolveOrdinaryMarkerTarget(personalPickupMarker.Pickup, out Vector3 worldPosition, out string invalidReason)) { RemoveOrdinaryMarkerNow(personalPickupMarker, invalidReason); continue; } if (!TryResolvePresentationDistance(cameraPosition, worldPosition, out int roundedDistanceMeters, out invalidReason)) { RemoveOrdinaryMarkerNow(personalPickupMarker, invalidReason); continue; } _renderInputs.Add(new MarkerRenderInput(new PersonalMarkerIdentity((PersonalMarkerKind)0, personalPickupMarker.InstanceId), worldPosition + Vector3.up * 1.2f, roundedDistanceMeters, PickupLabel(personalPickupMarker.Pickup, val2), personalPickupMarker.ItemSemanticKey, personalPickupMarker.ClassName, personalPickupMarker.Kind, personalPickupMarker.TextColor, ResolvePickupIcon(personalPickupMarker.Pickup), personalPickupMarker.Lifetime)); num2++; } C2HitchToken token4 = C2HitchDiagnostics.Begin(C2HitchPhase.CommandRenderInputConstruction, _commandMarkers.Count); try { int num3 = 0; while (num3 < _commandMarkers.Count) { PersonalCommandMarker personalCommandMarker = _commandMarkers[num3]; if (!TryResolveCommandMarkerTarget(personalCommandMarker.Picker, out Vector3 worldPosition2, out string invalidReason2)) { RemoveCommandMarkerNow(personalCommandMarker, invalidReason2); continue; } if (!TryResolvePresentationDistance(cameraPosition, worldPosition2, out int roundedDistanceMeters2, out invalidReason2)) { RemoveCommandMarkerNow(personalCommandMarker, invalidReason2); continue; } _renderInputs.Add(new MarkerRenderInput(new PersonalMarkerIdentity((PersonalMarkerKind)1, personalCommandMarker.InstanceId), worldPosition2 + Vector3.up * 1.35f, roundedDistanceMeters2, MarkerClassPolicy.LocalizedReadableClassLabel(personalCommandMarker.Kind, val2), personalCommandMarker.ItemSemanticKey, personalCommandMarker.ClassName, personalCommandMarker.Kind, personalCommandMarker.TextColor, null, personalCommandMarker.Lifetime)); num3++; } } finally { C2HitchDiagnostics.End(token4, _renderInputs.Count); } } finally { C2HitchDiagnostics.End(token3, _renderInputs.Count); } if ((Object)(object)val == (Object)null) { return; } C2HitchToken token5 = C2HitchDiagnostics.Begin(C2HitchPhase.ClientRendererCall, _renderInputs.Count); try { _hudRenderer.Render(val, _renderInputs, _config.MarkerSettingsSnapshot(), _config.MarkerVisualSettingsSnapshot(), val2, OnMarkerRendered, _dynamicHudZones); } finally { C2HitchDiagnostics.End(token5, _renderInputs.Count); if (_firstMarkerActivationTiming.Active) { C2HitchDiagnostics.End(_firstMarkerActivationTiming, _markers.Count + _commandMarkers.Count); _firstMarkerActivationTiming = default(C2HitchToken); } } } finally { C2HitchDiagnostics.End(token, _markers.Count + _commandMarkers.Count); } } } private bool AdvanceMarkerColdPathWarmup(bool allowRefresh) { if ((Object)(object)Run.instance == (Object)null || (Object)(object)GetPresentationCamera() == (Object)null) { return false; } C2HitchToken token = C2HitchDiagnostics.Begin(C2HitchPhase.ColdWarmupHudProbe, _markers.Count + _commandMarkers.Count); bool flag; try { flag = _localHudProbe.WarmColdPathStep(allowRefresh); } finally { C2HitchDiagnostics.End(token, _markers.Count + _commandMarkers.Count); } if (!flag) { return false; } C2HitchToken token2 = C2HitchDiagnostics.Begin(C2HitchPhase.ColdWarmupNative, _markers.Count + _commandMarkers.Count); try { return _hudRenderer.WarmColdPathStep(); } finally { C2HitchDiagnostics.End(token2, _markers.Count + _commandMarkers.Count); } } public void Dispose() { _config.MarkerPresentationSettingChanged -= OnMarkerPresentationSettingChanged; RestoreAll("external-or-plugin-teardown"); _hudRenderer.Dispose(); } public void RestoreAll() { RestoreAll("external-or-plugin-teardown"); } private void RestoreAll(string reason) { //IL_019a: Unknown result type (might be due to invalid IL or missing references) if (_markers.Count > 0 || _commandMarkers.Count > 0) { EmitPerformanceSummary(reason, 0, force: true); } _lastPerformanceMarkerCount = 0; LocalPickupPresentationGate[] array = _gates.Values.ToArray(); foreach (LocalPickupPresentationGate localPickupPresentationGate in array) { if (!((Object)(object)localPickupPresentationGate == (Object)null)) { localPickupPresentationGate.Restore(); Object.Destroy((Object)(object)localPickupPresentationGate); } } _gates.Clear(); LocalCommandPresentationGate[] array2 = _commandGates.Values.ToArray(); foreach (LocalCommandPresentationGate localCommandPresentationGate in array2) { if (!((Object)(object)localCommandPresentationGate == (Object)null)) { localCommandPresentationGate.Restore(); Object.Destroy((Object)(object)localCommandPresentationGate); } } _commandGates.Clear(); _localCommandGateDiagnosticState.Clear(); _localPickupVisualDiagnosticState.Clear(); _localPickupInteractionDiagnosticState.Clear(); _upstreamVisibilityGateObserved.Clear(); PersonalCommandMarker[] array3 = _commandMarkers.ToArray(); foreach (PersonalCommandMarker personalCommandMarker in array3) { LogCommandCleanup(personalCommandMarker.InstanceId, reason); } _markers.Clear(); _commandMarkers.Clear(); _markerRegistry.Clear(); _ordinaryRenderLogged.Clear(); _commandRemovalReasons.Clear(); _commandOptionDisagreementLogged.Clear(); _commandShareabilityDiagnosticState.Clear(); _markerProjectionDiagnosticState.Clear(); _modalHudSuppressionDiagnosticState = null; _modalHudSuppressionReason = string.Empty; _messageHudDiagnosticState = null; _hasMessageHudDiagnosticRect = false; _messageHudDiagnosticRect = default(MarkerHudRect); _localHudProbe.InvalidateLifecycle(); _presentationCamera = null; _nextPresentationCameraRefresh = 0f; _hudRenderer.SetPresentationSuppressed(suppressed: false); _hudRenderer.Clear(); } private unsafe void Sweep() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected I4, but got Unknown //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_012b: 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_0222: 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_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: 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_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Invalid comparison between Unknown and I4 //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_06c2: Unknown result type (might be due to invalid IL or missing references) //IL_06c7: Unknown result type (might be due to invalid IL or missing references) //IL_06cc: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0712: Unknown result type (might be due to invalid IL or missing references) //IL_07e1: Unknown result type (might be due to invalid IL or missing references) //IL_07fc: Unknown result type (might be due to invalid IL or missing references) //IL_0811: Unknown result type (might be due to invalid IL or missing references) //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_0ea7: Unknown result type (might be due to invalid IL or missing references) //IL_0eac: Unknown result type (might be due to invalid IL or missing references) //IL_0eb0: Unknown result type (might be due to invalid IL or missing references) //IL_085a: Unknown result type (might be due to invalid IL or missing references) //IL_0868: Unknown result type (might be due to invalid IL or missing references) //IL_086b: Invalid comparison between Unknown and I4 //IL_0ed7: Unknown result type (might be due to invalid IL or missing references) //IL_0edc: Unknown result type (might be due to invalid IL or missing references) //IL_0ebf: Unknown result type (might be due to invalid IL or missing references) //IL_0ec4: Unknown result type (might be due to invalid IL or missing references) //IL_0910: Unknown result type (might be due to invalid IL or missing references) //IL_0b10: Unknown result type (might be due to invalid IL or missing references) //IL_0b15: Unknown result type (might be due to invalid IL or missing references) //IL_0b2e: Unknown result type (might be due to invalid IL or missing references) //IL_0b31: Invalid comparison between Unknown and I4 //IL_0b3c: Unknown result type (might be due to invalid IL or missing references) //IL_0b3f: Invalid comparison between Unknown and I4 //IL_0a2a: Unknown result type (might be due to invalid IL or missing references) //IL_0ba1: Unknown result type (might be due to invalid IL or missing references) //IL_0bae: Unknown result type (might be due to invalid IL or missing references) //IL_0bb9: Unknown result type (might be due to invalid IL or missing references) //IL_0bcb: Unknown result type (might be due to invalid IL or missing references) //IL_0bce: Invalid comparison between Unknown and I4 //IL_0c6c: Unknown result type (might be due to invalid IL or missing references) //IL_0bd0: Unknown result type (might be due to invalid IL or missing references) //IL_0bd3: Invalid comparison between Unknown and I4 if (!_config.Enabled.Value || !_upstream.IsIndividualMode) { RestoreAll("feature-disabled-or-non-individual-mode"); return; } CharacterMaster[] localMastersSnapshot = GetLocalMastersSnapshot(); if (localMastersSnapshot.Length == 0) { RestoreAll("no-local-master"); return; } C2HitchDiagnostics.SetEnabled(_config.DiagnosticInfoEnabled); CommandOptionResolutionDiagnostics.SetEnabled(_config.DiagnosticInfoEnabled); bool flag = _config.PersonalMarkersEnabled.Value && !MarkersSuppressedInCurrentScene(); List<GenericPickupController> instancesList = InstanceTracker.GetInstancesList<GenericPickupController>(); C2HitchToken token = C2HitchDiagnostics.Begin(C2HitchPhase.ClientSweep, _markers.Count + _commandMarkers.Count, instancesList.Count); C2HitchToken token2 = ((instancesList.Count > 0) ? C2HitchDiagnostics.Begin(C2HitchPhase.ClientSweepPickupPresent, _markers.Count + _commandMarkers.Count, instancesList.Count) : default(C2HitchToken)); try { EnsureParticipantBuffers(localMastersSnapshot.Length); ParticipantState[] localStateBuffer = _localStateBuffer; for (int i = 0; i < localMastersSnapshot.Length; i++) { localStateBuffer[i] = (ParticipantState)(int)LocalParticipantResolver.ClassifyLocal(localMastersSnapshot[i]); } MarkerLanguage val = CurrentMarkerLanguage(); Camera presentationCamera = GetPresentationCamera(); Vector3 cameraPosition = default(Vector3); bool flag2 = (Object)(object)presentationCamera != (Object)null && TryGetFiniteCameraPosition(presentationCamera, out cameraPosition); _markerRegistry.BeginSweep(); _nextOrdinaryMarkers.Clear(); _seenPickups.Clear(); _previousOrdinaryIds.Clear(); for (int j = 0; j < _markers.Count; j++) { _previousOrdinaryIds.Add(_markers[j].InstanceId); } int num = 0; int roundedDistanceMeters; foreach (GenericPickupController item in instancesList) { if ((Object)(object)item == (Object)null) { continue; } int instanceID = ((Object)item).GetInstanceID(); Vector3 worldPosition; string invalidReason; if (KnownProgressionPickupCompatibility.IsExcluded(item)) { ReleaseGate(instanceID); _markerRegistry.Remove((PersonalMarkerKind)0, instanceID); _ordinaryRenderLogged.Remove(instanceID); } else if (!TryResolveOrdinaryMarkerTarget(item, out worldPosition, out invalidReason) || (flag2 && !TryResolvePresentationDistance(cameraPosition, worldPosition, out roundedDistanceMeters, out invalidReason))) { ReleaseGate(instanceID); _markerRegistry.Remove((PersonalMarkerKind)0, instanceID); _ordinaryRenderLogged.Remove(instanceID); if (_previousOrdinaryIds.Contains(instanceID)) { LogOrdinaryCleanup(instanceID, invalidReason); } } else { if (!_upstream.IsShareable(item)) { continue; } _seenPickups.Add(instanceID); bool[] collectedBuffer = _collectedBuffer; int num2 = 0; for (int k = 0; k < localMastersSnapshot.Length; k++) { if (collectedBuffer[k] = _upstream.HasCollected(item, localMastersSnapshot[k])) { num2++; } } bool flag3 = LocalPickupSuppressionPolicy.ShouldSuppressProcessVisual(_config.PersonalPickupVisibilityRepairEnabled.Value, _upstream.HideCollectedOrbsEnabled, collectedBuffer.Length, num2); if (flag3) { if (!_gates.TryGetValue(instanceID, out LocalPickupPresentationGate value) || (Object)(object)value == (Object)null) { NormalizeUpstreamForGate(item); value = ((Component)item).gameObject.GetComponent<LocalPickupPresentationGate>() ?? ((Component)item).gameObject.AddComponent<LocalPickupPresentationGate>(); _gates[instanceID] = value; } value.ApplyHidden(); } else { ReleaseGate(instanceID); } LogLocalVisualGateTransition(item, num2, collectedBuffer.Length, flag3); UniquePickup pickup = item.pickup; MarkerLifetimeKind val2 = MarkerLifetimePolicy.FromTemporaryFlag(((UniquePickup)(ref pickup)).isTempItem); if (flag && MarkerLifetimePolicy.IsMarkerEligible(val2, _config.ShareTemporaryItems.Value) && num < 64 && ShouldShowMarker(localStateBuffer, collectedBuffer)) { string text = MarkerPresentationPolicy.NormalizeLabel(PickupLabel(item, val), MarkerTextLocalization.FallbackSharedPickup(val)); MarkerRuntimeMetadata markerRuntimeMetadata = ResolvePickupMarkerMetadata(item.pickup.pickupIndex); if ((int)_markerRegistry.MarkPending((PersonalMarkerKind)0, instanceID, text) != 3) { _nextOrdinaryMarkers.Add(new PersonalPickupMarker { InstanceId = instanceID, Pickup = item, Label = text, ItemSemanticKey = PickupSemanticKey(item), ClassName = markerRuntimeMetadata.ClassName, Kind = markerRuntimeMetadata.Kind, TextColor = markerRuntimeMetadata.TextColor, Lifetime = val2 }); num++; } } } } _staleInstanceIds.Clear(); foreach (int key in _gates.Keys) { if (!_seenPickups.Contains(key)) { _staleInstanceIds.Add(key); } } for (int l = 0; l < _staleInstanceIds.Count; l++) { ReleaseGate(_staleInstanceIds[l]); } _nextCommandMarkers.Clear(); _seenCommandCandidateIds.Clear(); _commandRemovalReasons.Clear(); _previousCommandIds.Clear(); for (int m = 0; m < _commandMarkers.Count; m++) { _previousCommandIds.Add(_commandMarkers[m].InstanceId); } int num3 = 0; if (_upstream.ShareCommandPicksEnabled) { C2HitchToken token3 = C2HitchDiagnostics.Begin(C2HitchPhase.CommandPickerDiscovery, _markers.Count + _commandMarkers.Count); List<PickupPickerController> instancesList2 = InstanceTracker.GetInstancesList<PickupPickerController>(); C2HitchDiagnostics.End(token3, _markers.Count + _commandMarkers.Count, instancesList2.Count); foreach (PickupPickerController item2 in instancesList2) { if ((Object)(object)item2 == (Object)null) { continue; } int instanceID2 = ((Object)item2).GetInstanceID(); if (!_upstream.IsCommandCube(item2)) { ReleaseCommandGate(instanceID2, "classifier-false"); if (_previousCommandIds.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = "classifier-false"; } continue; } _seenCommandCandidateIds.Add(instanceID2); bool?[] localPickedStateBuffer = _localPickedStateBuffer; bool flag4 = false; bool flag5 = true; for (int n = 0; n < localMastersSnapshot.Length; n++) { if (!_upstream.TryHasCommandPicked(item2, localMastersSnapshot[n], out var picked)) { localPickedStateBuffer[n] = null; flag5 = false; continue; } localPickedStateBuffer[n] = picked; if (ProjectionPolicy.ShowPersonalMarker(true, localStateBuffer[n], picked, false)) { flag4 = true; } } LocalCommandPresentationDecision decision = LocalCommandPresentationPolicy.Evaluate((IReadOnlyList<bool?>)localPickedStateBuffer); ApplyLocalCommandPresentation(item2, decision); if (!flag) { if (_previousCommandIds.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = "markers-disabled"; } continue; } if (!TryResolveCommandMarkerTarget(item2, out Vector3 worldPosition2, out string invalidReason2) || (flag2 && !TryResolvePresentationDistance(cameraPosition, worldPosition2, out roundedDistanceMeters, out invalidReason2))) { _markerRegistry.Remove((PersonalMarkerKind)1, instanceID2); if (_previousCommandIds.Contains(instanceID2)) { LogCommandCleanup(instanceID2, invalidReason2); } continue; } bool flag6 = flag4 || flag5; if (num3 >= 32 || !MarkerPresentationPolicy.ShouldTrackCommandMarker(flag, _upstream.IsIndividualMode, _upstream.ShareCommandPicksEnabled, true, flag6, flag4)) { if (_previousCommandIds.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = (flag5 ? "local-completed" : "local-state-unresolved"); } continue; } C2HitchToken token4 = C2HitchDiagnostics.Begin(C2HitchPhase.CommandOptionResolution, _markers.Count + _commandMarkers.Count); CommandOptionResolutionDiagnostics.Begin(instanceID2); MarkerLifetimeKind val3 = (MarkerLifetimeKind)3; int num4 = 0; int num5 = 0; MarkerRuntimeMetadata markerRuntimeMetadata2; string optionSource; int resolvedOptionCount; bool sourceDisagreement; CommandShareabilityDecision shareability; try { _upstream.TryBuildCommandChoiceSnapshot(item2, out UpstreamBridge.CommandChoiceSnapshot snapshot); markerRuntimeMetadata2 = ResolveCommandMarkerMetadata(snapshot, val, out optionSource, out resolvedOptionCount, out sourceDisagreement, out shareability, item2); val3 = snapshot.Lifetime; num4 = snapshot.ExactNestedAvailableOptionCount; num5 = snapshot.UnresolvedAvailableOptionCount; } finally { CommandOptionResolutionDiagnostics.Complete(); C2HitchDiagnostics.End(token4, _markers.Count + _commandMarkers.Count); } string text2 = MarkerPresentationPolicy.NormalizeLabel(markerRuntimeMetadata2.Label, MarkerTextLocalization.FallbackCommandChoice(val)); if ((int)val3 == 3 && _commandLifetimeUnknownLogged.Add(instanceID2)) { LogInfo("ISF_COMMAND_LIFETIME pickerInstanceId=" + instanceID2.ToString(CultureInfo.InvariantCulture) + " lifetime=Unknown exactNestedAvailable=" + num4.ToString(CultureInfo.InvariantCulture) + " unresolvedAvailable=" + num5.ToString(CultureInfo.InvariantCulture) + " assertion=none"); } if (sourceDisagreement && _commandOptionDisagreementLogged.Add(instanceID2)) { LogInfo("ISF_COMMAND_OPTION_SOURCE_DISAGREEMENT pickerInstanceId=" + instanceID2.ToString(CultureInfo.InvariantCulture) + " nestedWins=True optionSource=" + optionSource); } if (!MarkerLifetimePolicy.IsMarkerEligible(val3, _config.ShareTemporaryItems.Value)) { _commandShareabilityDiagnosticState[instanceID2] = "temporary-sharing-disabled"; if (_previousCommandIds.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = "temporary-sharing-disabled"; } continue; } if (!((CommandShareabilityDecision)(ref shareability)).MarkerEligible) { string text3 = ((CommandShareabilityDecision)(ref shareability)).DiagnosticToken + ":" + ((CommandShareabilityDecision)(ref shareability)).FilterReason; if (!_commandShareabilityDiagnosticState.TryGetValue(instanceID2, out string value2) || !string.Equals(value2, text3, StringComparison.Ordinal)) { _commandShareabilityDiagnosticState[instanceID2] = text3; LogInfo("ISF_COMMAND_MARKER filtered pickerInstanceId=" + instanceID2.ToString(CultureInfo.InvariantCulture) + " optionSource=" + optionSource + " resolvedOptionCount=" + resolvedOptionCount.ToString(CultureInfo.InvariantCulture) + " class=" + markerRuntimeMetadata2.ClassName + " label=" + text2 + " color=" + ColorEvidence(markerRuntimeMetadata2.TextColor) + " shareability=" + ((CommandShareabilityDecision)(ref shareability)).DiagnosticToken + " reason=" + ((CommandShareabilityDecision)(ref shareability)).FilterReason); } if (_previousCommandIds.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = ((CommandShareabilityDecision)(ref shareability)).FilterReason; } continue; } _commandShareabilityDiagnosticState[instanceID2] = ((CommandShareabilityDecision)(ref shareability)).DiagnosticToken + ":eligible"; if (!_firstMarkerActivationTiming.Active) { _firstMarkerActivationTiming = C2HitchDiagnostics.Begin(C2HitchPhase.FirstMarkerActivationEndToEnd, _markers.Count + _commandMarkers.Count); } C2HitchToken token5 = C2HitchDiagnostics.Begin(C2HitchPhase.CommandMarkerRegistryUpdate, _markers.Count + _commandMarkers.Count); PersonalMarkerTransition val4 = _markerRegistry.MarkPending((PersonalMarkerKind)1, instanceID2, text2); C2HitchDiagnostics.End(token5, _markers.Count + _commandMarkers.Count + (((int)val4 == 1) ? 1 : 0)); if ((int)val4 == 3) { _firstMarkerActivationTiming = default(C2HitchToken); continue; } _nextCommandMarkers.Add(new PersonalCommandMarker { InstanceId = instanceID2, Picker = item2, Label = text2, ItemSemanticKey = "COMMAND:" + instanceID2.ToString(CultureInfo.InvariantCulture), ClassName = markerRuntimeMetadata2.ClassName, Kind = markerRuntimeMetadata2.Kind, TextColor = markerRuntimeMetadata2.TextColor, Lifetime = val3 }); num3++; if ((int)val4 == 1 || (int)val4 == 2) { string[] obj = new string[28] { "ISF_COMMAND_MARKER pending pickerInstanceId=", instanceID2.ToString(CultureInfo.InvariantCulture), " localPending=True providerHasState=", _upstream.HasPickerProviderState(item2).ToString(), " discovery=InstanceTracker optionSource=", optionSource, " resolvedOptionCount=", resolvedOptionCount.ToString(CultureInfo.InvariantCulture), " class=", markerRuntimeMetadata2.ClassName, " label=", text2, " color=", ColorEvidence(markerRuntimeMetadata2.TextColor), " style=", MarkerPresentationPolicy.NativeHudStyleToken, " renderer=canvas-tmp-ui-graphic fontSize=", null, null, null, null, null, null, null, null, null, null, null }; roundedDistanceMeters = MarkerPresentationPolicy.BuildNativeHudFontSize(Screen.height); obj[17] = roundedDistanceMeters.ToString(CultureInfo.InvariantCulture); obj[18] = " shareability="; obj[19] = ((CommandShareabilityDecision)(ref shareability)).DiagnosticToken; obj[20] = " exactClass="; obj[21] = markerRuntimeMetadata2.ExactClass.ToString(); obj[22] = " lifetime="; obj[23] = ((object)(*(MarkerLifetimeKind*)(&val3))/*cast due to .constrained prefix*/).ToString(); obj[24] = " lifetimeExactNested="; obj[25] = num4.ToString(CultureInfo.InvariantCulture); obj[26] = " lifetimeUnresolved="; obj[27] = num5.ToString(CultureInfo.InvariantCulture); LogInfo(string.Concat(obj)); } } } _staleInstanceIds.Clear(); foreach (int key2 in _commandGates.Keys) { if (!_seenCommandCandidateIds.Contains(key2)) { _staleInstanceIds.Add(key2); } } for (int num6 = 0; num6 < _staleInstanceIds.Count; num6++) { ReleaseCommandGate(_staleInstanceIds[num6], "picker-destroyed-stale-or-sharing-disabled"); } _staleInstanceIds.Clear(); foreach (int key3 in _commandShareabilityDiagnosticState.Keys) { if (!_seenCommandCandidateIds.Contains(key3)) { _staleInstanceIds.Add(key3); } } for (int num7 = 0; num7 < _staleInstanceIds.Count; num7++) { _commandShareabilityDiagnosticState.Remove(_staleInstanceIds[num7]); } _commandLifetimeUnknownLogged.RemoveWhere((int x) => !_seenCommandCandidateIds.Contains(x)); foreach (PersonalMarkerDescriptor item3 in _markerRegistry.EndSweep()) { PersonalMarkerIdentity identity = item3.Identity; if ((int)((PersonalMarkerIdentity)(ref identity)).Kind == 0) { HashSet<int> ordinaryRenderLogged = _ordinaryRenderLogged; identity = item3.Identity; ordinaryRenderLogged.Remove(((PersonalMarkerIdentity)(ref identity)).InstanceId); } else { identity = item3.Identity; int instanceId = ((PersonalMarkerIdentity)(ref identity)).InstanceId; string value3; string reason = (_commandRemovalReasons.TryGetValue(instanceId, out value3) ? value3 : "destroyed-or-untracked"); LogCommandCleanup(instanceId, reason); } } _markers.Clear(); _markers.AddRange(_nextOrdinaryMarkers); _commandMarkers.Clear(); _commandMarkers.AddRange(_nextCommandMarkers); } finally { C2HitchDiagnostics.End(token, _markers.Count + _commandMarkers.Count, instancesList.Count); C2HitchDiagnostics.End(token2, _markers.Count + _commandMarkers.Count, instancesList.Count); } } private unsafe void OnMarkerRendered(MarkerRenderDiagnostic diagnostic) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0094: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_010c: 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_0237: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) if (!_config.DiagnosticInfoEnabled) { return; } PersonalMarkerIdentity identity = diagnostic.Input.Identity; MarkerHudPlacement placement = diagnostic.Placement; MarkerHudMode mode = ((MarkerHudPlacement)(ref placement)).Mode; MarkerHudEdge edge = ((MarkerHudPlacement)(ref placement)).Edge; int laneSlot = ((MarkerHudPlacement)(ref placement)).LaneSlot; int railSlot = ((MarkerHudPlacement)(ref placement)).RailSlot; bool hudRelocated = ((MarkerHudPlacement)(ref placement)).HudRelocated; bool messageHudRelocated = ((MarkerHudPlacement)(ref placement)).MessageHudRelocated; bool collisionRelocated = ((MarkerHudPlacement)(ref placement)).CollisionRelocated; bool usedMeasurementFallback = diagnostic.UsedMeasurementFallback; float labelPreferredWidth = diagnostic.LabelPreferredWidth; MarkerHudVisualFootprint footprint = diagnostic.Footprint; MarkerHudDiagnosticState val = MarkerRuntimeHotPathPolicy.BuildHudDiagnosticState(mode, edge, laneSlot, railSlot, hudRelocated, messageHudRelocated, collisionRelocated, usedMeasurementFallback, labelPreferredWidth, ((MarkerHudVisualFootprint)(ref footprint)).Width); MarkerHudDiagnosticState value; bool flag = !_markerProjectionDiagnosticState.TryGetValue(diagnostic.ClusterKey, out value) || !((MarkerHudDiagnosticState)(ref value)).Equals(val); if (flag) { _markerProjectionDiagnosticState[diagnostic.ClusterKey] = val; } bool flag2 = (int)((PersonalMarkerIdentity)(ref identity)).Kind == 0 && _ordinaryRenderLogged.Add(((PersonalMarkerIdentity)(ref identity)).InstanceId); if (flag || flag2) { string text = (((int)((MarkerHudPlacement)(ref placement)).Mode == 0) ? "onscreen" : "edge"); string text2 = FormatEdge(((MarkerHudPlacement)(ref placement)).Edge); if (flag) { MarkerHudRect finalRect = ((MarkerHudPlacement)(ref placement)).FinalRect; string[] obj = new string[39] { "ISF_MARKER_HUD clusterKey=", diagnostic.ClusterKey.ToString(CultureInfo.InvariantCulture), " fingerprint=", diagnostic.MemberFingerprint, " total=", diagnostic.ClusterTotal.ToString(CultureInfo.InvariantCulture), " representative=", ((object)(*(PersonalMarkerIdentity*)(&identity))/*cast due to .constrained prefix*/).ToString(), " mode=", text, " semantic=", diagnostic.SemanticText.Replace("\n", " | "), " edge=", text2, " stackSlot=", ((MarkerHudPlacement)(ref placement)).StackSlot.ToString(CultureInfo.InvariantCulture), " laneSlot=", ((MarkerHudPlacement)(ref placement)).LaneSlot.ToString(CultureInfo.InvariantCulture), " railSlot=", ((MarkerHudPlacement)(ref placement)).RailSlot.ToString(CultureInfo.InvariantCulture), " rect=", FormatMarkerRect(finalRect), " hudRelocated=", ((MarkerHudPlacement)(ref placement)).HudRelocated.ToString(), " messageHudRelocated=", ((MarkerHudPlacement)(ref placement)).MessageHudRelocated.ToString(), " collisionRelocated=", ((MarkerHudPlacement)(ref placement)).CollisionRelocated.ToString(), " anchorDisplacement=", MarkerHudNavigationPolicy.OnScreenAnchorDisplacement(diagnostic.SourceProjection, placement).ToString("F1", CultureInfo.InvariantCulture), " anchorDisplacementBound=", MarkerHudNavigationPolicy.GetMaxOnScreenAnchorDisplacement(diagnostic.Footprint, (float)Screen.width, (float)Screen.height).ToString("F1", CultureInfo.InvariantCulture), " labelPreferredWidth=", diagnostic.LabelPreferredWidth.ToString("F1", CultureInfo.InvariantCulture), " footprintWidth=", null, null, null, null }; footprint = diagnostic.Footprint; obj[35] = ((MarkerHudVisualFootprint)(ref footprint)).Width.ToString("F1", CultureInfo.InvariantCulture); obj[36] = " measurementFallback="; obj[37] = diagnostic.UsedMeasurementFallback.ToString(); obj[38] = " semanticModel=world-space-cluster renderer=canvas-tmp-ui-graphic"; LogInfo(string.Concat(obj)); } if (flag2) { LogInfo("ISF_MARKER_RENDER ordinary pickupInstanceId=" + ((PersonalMarkerIdentity)(ref identity)).InstanceId.ToString(CultureInfo.InvariantCulture) + " clusterKey=" + diagnostic.ClusterKey.ToString(CultureInfo.InvariantCulture) + " fingerprint=" + diagnostic.MemberFingerprint + " total=" + diagnostic.ClusterTotal.ToString(CultureInfo.InvariantCulture) + " indicatorSource=" + MarkerPresentationPolicy.IndicatorAssetSourceToken + " style=" + MarkerPresentationPolicy.NativeHudStyleToken + " renderer=canvas-tmp-ui-graphic mode=" + text + " edge=" + text2); } } } private static string FormatEdge(MarkerHudEdge edge) { //IL_0000: 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_0018: Expected I4, but got Unknown return (edge - 1) switch { 0 => "left", 1 => "right", 2 => "top", 3 => "bottom", _ => "none", }; } private static bool SameDiagnosticRect(MarkerHudRect left, MarkerHudRect right) { if (Math.Abs(((MarkerHudRect)(ref left)).Left - ((MarkerHudRect)(ref right)).Left) < 0.5f && Math.Abs(((MarkerHudRect)(ref left)).Right - ((MarkerHudRect)(ref right)).Right) < 0.5f && Math.Abs(((MarkerHudRect)(ref left)).Bottom - ((MarkerHudRect)(ref right)).Bottom) < 0.5f) { return Math.Abs(((MarkerHudRect)(ref left)).Top - ((MarkerHudRect)(ref right)).Top) < 0.5f; } return false; } private static string FormatMarkerRect(MarkerHudRect rect) { return ((MarkerHudRect)(ref rect)).Left.ToString("F1", CultureInfo.InvariantCulture) + "," + ((MarkerHudRect)(ref rect)).Bottom.ToString("F1", CultureInfo.InvariantCulture) + "," + ((MarkerHudRect)(ref rect)).Right.ToString("F1", CultureInfo.InvariantCulture) + "," + ((MarkerHudRect)(ref rect)).Top.ToString("F1", CultureInfo.InvariantCulture); } private static bool ShouldShowMarker(ParticipantState[] localStates, bool[] collected) { for (int i = 0; i < localStates.Length; i++) { if (ProjectionPolicy.ShowPersonalMarker(true, localStates[i], collected[i], false)) { return true; } } return false; } private CharacterMaster[] GetLocalMastersSnapshot() { if (_localMastersFrame == Time.frameCount) { return _cachedLocalMasters; } _localMastersFrame = Time.frameCount; LocalParticipantResolver.FillLocalMasters(_localMasterBuffer); if (_cachedLocalMasters.Length != _localMasterBuffer.Count) { _cachedLocalMasters = (CharacterMaster[])(object)new CharacterMaster[_localMasterBuffer.Count]; } for (int i = 0; i < _localMasterBuffer.Count; i++) { _cachedLocalMasters[i] = _localMasterBuffer[i]; } return _cachedLocalMasters; } private void EnsureParticipantBuffers(int count) { if (_localStateBuffer.Length != count) { _localStateBuffer = (ParticipantState[])(object)new ParticipantState[count]; } if (_collectedBuffer.Length != count) { _collectedBuffer = new bool[count]; } if (_localPickedStateBuffer.Length != count) { _localPickedStateBuffer = new bool?[count]; } } private void NormalizeUpstreamForGate(GenericPickupController pickup) { try { _upstreamNormalizationDepth++; _upstream.NormalizeUpstreamVisualSubtree(pickup); } finally { _upstreamNormalizationDepth--; } } private void ReleaseGate(int instanceId) { if (_gates.TryGetValue(instanceId, out LocalPickupPresentationGate value)) { if ((Object)(object)value != (Object)null) { value.Restore(); Object.Destroy((Object)(object)value); } _gates.Remove(instanceId); } } private void ApplyLocalCommandPresentation(PickupPickerController picker, LocalCommandPresentationDecision decision) { int instanceID = ((Object)picker).GetInstanceID(); if (((LocalCommandPresentationDecision)(ref decision)).SuppressWorldPresentation) { if (!_commandGates.TryGetValue(instanceID, out LocalCommandPresentationGate value) || (Object)(object)value == (Object)null) { value = ((Component)picker).gameObject.GetComponent<LocalCommandPresentationGate>() ?? ((Component)picker).gameObject.AddComponent<LocalCommandPresentationGate>(); _commandGates[instanceID] = value; } value.ApplyHidden(); LogLocalCommandGateTransition(instanceID, visualSuppressed: true, "all-local-completed"); } else { string reason = ((!((LocalCommandPresentationDecision)(ref decision)).AllLocalStateResolved) ? "local-state-unresolved" : (((LocalCommandPresentationDecision)(ref decision)).AnyLocalPending ? "local-participant-pending" : "not-all-local-completed")); ReleaseCommandGate(instanceID, reason); } } private void ReleaseCommandGate(int instanceId, string reason) { LocalCommandPresentationGate value; bool num = _commandGates.TryGetValue(instanceId, out value); if (num) { if ((Object)(object)value != (Object)null) { value.Restore(); Object.Destroy((Object)(object)value); } _commandGates.Remove(instanceId); } bool value2; bool flag = _localCommandGateDiagnosticState.TryGetValue(instanceId, out value2) && value2; if (num || flag) { LogLocalCommandGateTransition(instanceId, visualSuppressed: false, reason); } } private void LogLocalCommandGateTransition(int instanceId, bool visualSuppressed, string reason) { if (_config.DiagnosticInfoEnabled && (!_localCommandGateDiagnosticState.TryGetValue(instanceId, out var value) || value != visualSuppressed)) { _localCommandGateDiagnosticState[instanceId] = visualSuppressed; LogInfo("ISF_C20_LOCAL_COMMAND_GATE picker=" + instanceId.ToString(CultureInfo.InvariantCulture) + " allLocalCompleted=" + visualSuppressed.ToString().ToLowerInvariant() + " visualSuppressed=" + visualSuppressed.ToString().ToLowerInvariant() + " reason=" + reason); } } private void LogLocalVisualGateTransition(GenericPickupController pickup, int collectedCount, int localCount, bool visualSuppressed) { if (_config.DiagnosticInfoEnabled && !((Object)(object)pickup == (Object)null)) { string text = collectedCount.ToString(CultureInfo.InvariantCulture) + "/" + localCount.ToString(CultureInfo.InvariantCulture) + ":" + visualSuppressed; int instanceID = ((Object)pickup).GetInstanceID(); if (!_localPickupVisualDiagnosticState.TryGetValue(instanceID, out string value) || !string.Equals(value, text, StringComparison.Ordinal)) { _localPickupVisualDiagnosticState[instanceID] = text; LogInfo("ISF_C20_LOCAL_PICKUP_GATE pickup=" + instanceID.ToString(CultureInfo.InvariantCulture) + " localMaster=process localCollected=" + collectedCount.ToString(CultureInfo.InvariantCulture) + "/" + localCount.ToString(CultureInfo.InvariantCulture) + " visualSuppressed=" + visualSuppressed.ToString().ToLowerInvariant() + " interactionSuppressed=participant-specific action=visual-state reason=" + (visualSuppressed ? "all-local-collected" : "local-participant-still-needs-pickup")); } } } private void LogLocalInteractionGateTransition(GenericPickupController pickup, CharacterMaster master, bool collected, bool interactionSuppressed) { //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) if (_config.DiagnosticInfoEnabled && !((Object)(object)pickup == (Object)null) && !((Object)(object)master == (Object)null)) { int instanceID = ((Object)pickup).GetInstanceID(); int instanceID2 = ((Object)master).GetInstanceID(); long key = (long)(((ulong)(uint)instanceID << 32) | (uint)instanceID2); if (!_localPickupInteractionDiagnosticState.TryGetValue(key, out var value) || value != interactionSuppressed) { _localPickupInteractionDiagnosticState[key] = interactionSuppressed; string[] obj = new string[12] { "ISF_C20_LOCAL_PICKUP_GATE pickup=", instanceID.ToString(CultureInfo.InvariantCulture), " localMaster=masterNetId=", null, null, null, null, null, null, null, null, null }; NetworkInstanceId netId = ((NetworkBehaviour)master).netId; obj[3] = ((NetworkInstanceId)(ref netId)).Value.ToString(CultureInfo.InvariantCulture); obj[4] = " localCollected="; obj[5] = collected.ToString().ToLowerInvariant(); obj[6] = " visualSuppressed="; obj[7] = _gates.ContainsKey(instanceID).ToString().ToLowerInvariant(); obj[8] = " interactionSuppressed="; obj[9] = interactionSuppressed.ToString().ToLowerInvariant(); obj[10] = " action=interactability-state reason="; obj[11] = (interactionSuppressed ? "local-collector-already-collected" : "local-participant-not-collected"); LogInfo(string.Concat(obj)); } } } private static bool TryGetFiniteCameraPosition(Camera camera, out Vector3 cameraPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) cameraPosition = default(Vector3); try { cameraPosition = ((Component)camera).transform.position; return MarkerPresentationPolicy.AreCoordinatesFinite(cameraPosition.x, cameraPosition.y, cameraPosition.z); } catch { return false; } } private static bool TryResolveOrdinaryMarkerTarget(GenericPickupController pickup, out Vector3 worldPosition, out string invalidReason) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) worldPosition = default(Vector3); invalidReason = string.Empty; if ((Object)(object)pickup == (Object)null) { invalidReason = "destroyed-or-missing"; return false; } try { if ((Object)(object)((Component)pickup).gameObject == (Object)null || !((Component)pickup).gameObject.activeInHierarchy) { invalidReason = "inactive-or-removed"; return false; } if (PickupCatalog.GetPickupDef(pickup.pickup.pickupIndex) == null) { invalidReason = "pickup-def-unresolved"; return false; } worldPosition = ((Component)pickup).transform.position; invalidReason = MarkerPresentationPolicy.ValidateWorldPosition(worldPosition.x, worldPosition.y, worldPosition.z); return string.IsNullOrEmpty(invalidReason); } catch { invalidReason = "target-resolution-failed"; return false; } } private static bool TryResolveCommandMarkerTarget(PickupPickerController picker, out Vector3 worldPosition, out string invalidReason) { //IL_0001: 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) worldPosition = default(Vector3); invalidReason = string.Empty; if ((Object)(object)picker == (Object)null) { invalidReason = "destroyed-or-missing"; return false; } try { if ((Object)(object)((Component)picker).gameObject == (Object)null || !((Component)picker).gameObject.activeInHierarchy) { invalidReason = "inactive-or-removed"; return false; } worldPosition = ((Component)picker).transform.position; invalidReason = MarkerPresentationPolicy.ValidateWorldPosition(worldPosition.x, worldPosition.y, worldPosition.z); return string.IsNullOrEmpty(invalidReason); } catch { invalidReason = "target-resolution-failed"; return false; } } private static bool TryResolvePresentationDistance(Vector3 cameraPosition, Vector3 worldPosition, out int roundedDistanceMeters, out string invalidReason) { //IL_000a: 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) roundedDistanceMeters = 0; invalidReason = string.Empty; float num = Vector3.Distance(cameraPosition, worldPosition); invalidReason = MarkerPresentationPolicy.ValidatePresentationDistance(num); if (!string.IsNullOrEmpty(invalidReason)) { return false; } roundedDistanceMeters = Mathf.Max(0, Mathf.RoundToInt(num)); return true; } private void RemoveOrdinaryMarkerNow(PersonalPickupMarker marker, string reason) { _markers.Remove(marker); _markerR