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.0.0
plugins/ItemShareFix/ItemShareFix.Core.dll
Decompiled 8 hours 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.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ItemShareFix.Core")] [assembly: AssemblyTitle("ItemShareFix.Core")] [assembly: AssemblyVersion("1.0.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 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(IEnumerable<bool?>? optionShareability) { if (optionShareability == null) { return new CommandShareabilityDecision(CommandShareabilityState.Unresolved); } bool?[] array = optionShareability.ToArray(); if (array.Length == 0 || array.Any((bool? x) => !x.HasValue)) { return new CommandShareabilityDecision(CommandShareabilityState.Unresolved); } bool flag = array.Any((bool? x) => x == true); bool flag2 = array.Any((bool? x) => x == false); if (flag && flag2) { return new CommandShareabilityDecision(CommandShareabilityState.Mixed); } if (flag) { return new CommandShareabilityDecision(CommandShareabilityState.AllShareable); } return new CommandShareabilityDecision(CommandShareabilityState.AllUnshareable); } } 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 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 = 11; 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, _ => 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 >= 11) { 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(11, 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 }, _ => 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 } 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 (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", _ => "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); } MarkerClassKind[] array = choiceClasses.ToArray(); if (array.Length == 0 || array.Any((MarkerClassKind x) => x == MarkerClassKind.Unknown)) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedReadableClassLabel(MarkerClassKind.Unknown, language), exactClass: false); } MarkerClassKind[] array2 = array.Distinct().ToArray(); if (array2.Length != 1) { return new CommandClassPresentation(MarkerClassKind.Unknown, LocalizedReadableClassLabel(MarkerClassKind.Unknown, language), exactClass: false); } MarkerClassKind markerClassKind = array2[0]; 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 = 11; public const int MaxCompactLifetimePresentationGroups = 22; 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 >= 11) { 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(22, array.Length * 2)); for (int k = 0; k < array.Length; k++) { if (list.Count >= 22) { 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 < 22) { 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 < 22) { 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 AppendLifetimeSummary(StringBuilder builder, MarkerSemanticCluster cluster, bool showTemporaryCount, bool russian) { string value = MarkerLifetimePolicy.BuildSummaryLine(cluster.LifetimeSummary, cluster.TemporaryPhysicalMemberCount, showTemporaryCount, russian); if (!string.IsNullOrEmpty(value)) { if (builder.Length > 0) { builder.Append('\n'); } builder.Append(value); } } 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(_orderedClusters[i].WorldAnchor, _orderedClusters[j].WorldAnchor) <= num) }; } } } } private void AdvanceExistingPairs(double nowSeconds) { float num = 144f; float num2 = 256f; foreach (KeyValuePair<PairKey, PairState> pairState in _pairStates) { MarkerSemanticCluster markerSemanticCluster = FindCluster(pairState.Key.A); MarkerSemanticCluster markerSemanticCluster2 = FindCluster(pairState.Key.B); if (markerSemanticCluster == null || markerSemanticCluster2 == null) { continue; } float num3 = MarkerWorldPoint.DistanceSquared(markerSemanticCluster.WorldAnchor, markerSemanticCluster2.WorldAnchor); PairState value = pairState.Value; if (value.Linked) { if (num3 <= num2) { value.Pending = false; } else { AdvancePending(value, target: false, nowSeconds); } } else if (num3 >= num) { value.Pending = false; } else { AdvancePending(value, target: true, nowSeconds); } } } private static void AdvancePending(PairState state, bool target, double nowSeconds) { if (!state.Pending || state.PendingTarget != target) { state.Pending = true; state.PendingTarget = target; state.PendingSince = nowSeconds; } else if (!(nowSeconds - state.PendingSince < 0.35)) { state.Linked = target; state.Pending = false; } } private void PrunePairStates() { _stalePairs.Clear(); foreach (PairKey key in _pairStates.Keys) { if (FindCluster(key.A) == null || FindCluster(key.B) == null) { _stalePairs.Add(key); } } for (int i = 0; i < _stalePairs.Count; i++) { _pairStates.Remove(_stalePairs[i]); } } private MarkerSemanticCluster? FindCluster(long key) { int num = 0; int num2 = _orderedClusters.Count - 1; while (num <= num2) { int num3 = num + (num2 - num >> 1); long stableKey = _orderedClusters[num3].StableKey; if (stableKey == key) { return _orderedClusters[num3]; } if (stableKey < key) { num = num3 + 1; } else { num2 = num3 - 1; } } return null; } private List<MarkerDenseAreaPresentationNode> BuildPresentationNodes() { List<MarkerDenseAreaPresentationNode> list = new List<MarkerDenseAreaPresentationNode>(_orderedClusters.Count); if (_orderedClusters.Count == 0) { return list; } int[] array = new int[_orderedClusters.Count]; for (int i = 0; i < array.Length; i++) { array[i] = i; } foreach (KeyValuePair<PairKey, PairState> pairState in _pairStates) { if (pairState.Value.Linked) { int num = IndexOfCluster(pairState.Key.A); int num2 = IndexOfCluster(pairState.Key.B); if (num >= 0 && num2 >= 0) { Union(array, num, num2); } } } Dictionary<int, List<MarkerSemanticCluster>> dictionary = new Dictionary<int, List<MarkerSemanticCluster>>(); for (int j = 0; j < _orderedClusters.Count; j++) { int key = Find(array, j); if (!dictionary.TryGetValue(key, out var value)) { value = new List<MarkerSemanticCluster>(); dictionary.Add(key, value); } value.Add(_orderedClusters[j]); } HashSet<long> claimedPreviousOwners = new HashSet<long>(); foreach (List<MarkerSemanticCluster> value2 in dictionary.Values) { value2.Sort((MarkerSemanticCluster left, MarkerSemanticCluster right) => left.StableKey.CompareTo(right.StableKey)); long[] memberKeys = CollectMemberKeys(value2); if (value2.Count < 2) { if (TryClaimPreviousOwnerKey(memberKeys, claimedPreviousOwners, out var ownerKey)) { MarkerSemanticCluster presentationCluster = BuildSummaryCluster(ownerKey, value2, memberKeys); list.Add(new MarkerDenseAreaPresentationNode(ownerKey, isDenseSummary: true, new long[1] { value2[0].StableKey }, presentationCluster)); } else { MarkerSemanticCluster markerSemanticCluster = value2[0]; list.Add(new MarkerDenseAreaPresentationNode(markerSemanticCluster.StableKey, isDenseSummary: false, new long[1] { markerSemanticCluster.StableKey }, markerSemanticCluster)); } } else { long num3 = ResolvePersistentOwnerKey(memberKeys, claimedPreviousOwners); MarkerSemanticCluster presentationCluster2 = BuildSummaryCluster(num3, value2, memberKeys); long[] array2 = new long[value2.Count]; for (int num4 = 0; num4 < value2.Count; num4++) { array2[num4] = value2[num4].StableKey; } list.Add(new MarkerDenseAreaPresentationNode(num3, isDenseSummary: true, array2, presentationCluster2)); } } list.Sort((MarkerDenseAreaPresentationNode left, MarkerDenseAreaPresentationNode right) => left.StableKey.CompareTo(right.StableKey)); return list; } private long ResolvePersistentOwnerKey(long[] memberKeys, HashSet<long> claimedPreviousOwners) { if (TryClaimPreviousOwnerKey(memberKeys, claimedPreviousOwners, out var ownerKey)) { return ownerKey; } long num = -MarkerWorldClusterTracker.StableClusterKey(memberKeys); if (num == 0L || num == long.MinValue) { num = -1L; } claimedPreviousOwners.Add(num); return num; } private bool TryClaimPreviousOwnerKey(long[] memberKeys, HashSet<long> claimedPreviousOwners, out long ownerKey) { long num = 0L; int num2 = 0; for (int i = 0; i < _previousDenseOwners.Count; i++) { PreviousDenseOwner previousDenseOwner = _previousDenseOwners[i]; if (!claimedPreviousOwners.Contains(previousDenseOwner.OwnerKey)) { int num3 = CountOverlap(previousDenseOwner.MemberKeys, memberKeys); if (num3 > num2 || (num3 == num2 && num3 > 0 && previousDenseOwner.OwnerKey < num)) { num2 = num3; num = previousDenseOwner.OwnerKey; } } } if (num2 > 0) { claimedPreviousOwners.Add(num); ownerKey = num; return true; } ownerKey = 0L; return false; } private static MarkerSemanticCluster BuildSummaryCluster(long ownerKey, IReadOnlyList<MarkerSemanticCluster> clusters, long[] memberKeys) { Dictionary<MarkerSemanticCategory, int> dictionary = new Dictionary<MarkerSemanticCategory, int>(); Dictionary<MarkerItemLifetimeKey, MutableAggregate> dictionary2 = new Dictionary<MarkerItemLifetimeKey, MutableAggregate>(); double num = 0.0; double num2 = 0.0; double num3 = 0.0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; for (int i = 0; i < clusters.Count; i++) { MarkerSemanticCluster markerSemanticCluster = clusters[i]; int num8 = Math.Max(1, markerSemanticCluster.TotalCount); num += (double)(markerSemanticCluster.WorldAnchor.X * (float)num8); num2 += (double)(markerSemanticCluster.WorldAnchor.Y * (float)num8); num3 += (double)(markerSemanticCluster.WorldAnchor.Z * (float)num8); num4 += num8; num5 += markerSemanticCluster.TemporaryPhysicalMemberCount; num6 += markerSemanticCluster.MixedLifetimeMemberCount; num7 += markerSemanticCluster.UnknownLifetimeMemberCount; for (int j = 0; j < markerSemanticCluster.Composition.Count; j++) { MarkerCategoryCount markerCategoryCount = markerSemanticCluster.Composition[j]; dictionary.TryGetValue(markerCategoryCount.Category, out var value); dictionary[markerCategoryCount.Category] = value + markerCategoryCount.Count; } for (int k = 0; k < markerSemanticCluster.ItemRows.Count; k++) { MarkerItemAggregate markerItemAggregate = markerSemanticCluster.ItemRows[k]; MarkerItemLifetimeKey key = new MarkerItemLifetimeKey(markerItemAggregate.ItemIdentity, markerItemAggregate.Lifetime); if (!dictionary2.TryGetValue(key, out var value2)) { value2 = new MutableAggregate(markerItemAggregate.ItemIdentity, markerItemAggregate.LocalizedName, markerItemAggregate.Category, markerItemAggregate.Lifetime); dictionary2.Add(key, value2); } value2.Count += markerItemAggregate.Count; } } List<MarkerCategoryCount> list = new List<MarkerCategoryCount>(dictionary.Count); foreach (KeyValuePair<MarkerSemanticCategory, int> item in dictionary) { list.Add(new MarkerCategoryCount(item.Key, item.Value)); } list.Sort((MarkerCategoryCount left, MarkerCategoryCount right) => MarkerSemanticCategoryPolicy.StableOrder(left.Category).CompareTo(MarkerSemanticCategoryPolicy.StableOrder(right.Category))); List<MarkerItemAggregate> list2 = new List<MarkerItemAggregate>(dictionary2.Count); foreach (MutableAggregate value3 in dictionary2.Values) { list2.Add(new MarkerItemAggregate(value3.ItemIdentity, value
plugins/ItemShareFix/ItemShareFix.dll
Decompiled 8 hours 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.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemShareFix.Core; using Microsoft.CodeAnalysis; using RoR2; 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.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ItemShareFix")] [assembly: AssemblyTitle("ItemShareFix")] [assembly: AssemblyVersion("1.0.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 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 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; public ClientPresentationCoordinator(PluginConfig config, UpstreamBridge upstream, ManualLogSource log) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown _config = config; _upstream = upstream; _log = log; _localHudProbe = new LocalHudPresentationProbe(_performance); _hudRenderer = new NativeHudMarkerRenderer(log, _performance); _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) { if (!_config.PersonalMarkersEnabled.Value) { _hudRenderer.Clear(); } RequestRefresh(); } else if (sender == _config.ShareTemporaryItems) { RequestRefresh(); } } public void RecordUnityUpdate() { _performance.RecordUnityUpdate(); } public void RequestRefresh() { _refreshRequested = true; } public void OnBlockingModalLifecycleObserved(Component component) { _localHudProbe.ObserveBlockingModalLifecycle(component); } 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 || !_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) { 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.DiagnosticLogging.Value && _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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0433: 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_0377: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: 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_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: 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_03e8: Unknown result type (might be due to invalid IL or missing references) _performance.RecordRenderFrame(); bool flag = _config.Enabled.Value && _config.PersonalMarkersEnabled.Value && (_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(); return; } MaybeEmitPerformanceSummary(_lastPerformanceMarkerCount = _markers.Count + _commandMarkers.Count); string reason; bool flag2 = _localHudProbe.TryGetBlockingModal(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.TryGetVisibleMessageHudRect(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)); } Camera presentationCamera = GetPresentationCamera(); if ((Object)(object)presentationCamera == (Object)null || !TryGetFiniteCameraPosition(presentationCamera, out var cameraPosition)) { _hudRenderer.Clear(); return; } MarkerLanguage val = CurrentMarkerLanguage(); _renderInputs.Clear(); int num = 0; while (num < _markers.Count) { PersonalPickupMarker personalPickupMarker = _markers[num]; 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, val), personalPickupMarker.ItemSemanticKey, personalPickupMarker.ClassName, personalPickupMarker.Kind, personalPickupMarker.TextColor, ResolvePickupIcon(personalPickupMarker.Pickup), personalPickupMarker.Lifetime)); num++; } int num2 = 0; while (num2 < _commandMarkers.Count) { PersonalCommandMarker personalCommandMarker = _commandMarkers[num2]; 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, val), personalCommandMarker.ItemSemanticKey, personalCommandMarker.ClassName, personalCommandMarker.Kind, personalCommandMarker.TextColor, null, personalCommandMarker.Lifetime)); num2++; } _hudRenderer.Render(presentationCamera, _renderInputs, _config.MarkerSettingsSnapshot(), _config.MarkerVisualSettingsSnapshot(), val, OnMarkerRendered, _dynamicHudZones); } 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Invalid comparison between Unknown and I4 //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_0596: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Unknown result type (might be due to invalid IL or missing references) //IL_0c2b: Unknown result type (might be due to invalid IL or missing references) //IL_0c30: Unknown result type (might be due to invalid IL or missing references) //IL_0c34: Unknown result type (might be due to invalid IL or missing references) //IL_0c5b: Unknown result type (might be due to invalid IL or missing references) //IL_0c60: Unknown result type (might be due to invalid IL or missing references) //IL_0c43: Unknown result type (might be due to invalid IL or missing references) //IL_0c48: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_069f: Unknown result type (might be due to invalid IL or missing references) //IL_06b0: Unknown result type (might be due to invalid IL or missing references) //IL_06d3: Unknown result type (might be due to invalid IL or missing references) //IL_06e0: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Invalid comparison between Unknown and I4 //IL_0788: Unknown result type (might be due to invalid IL or missing references) //IL_092b: Unknown result type (might be due to invalid IL or missing references) //IL_0930: Unknown result type (might be due to invalid IL or missing references) //IL_0932: Unknown result type (might be due to invalid IL or missing references) //IL_0935: Invalid comparison between Unknown and I4 //IL_0985: Unknown result type (might be due to invalid IL or missing references) //IL_0992: Unknown result type (might be due to invalid IL or missing references) //IL_099d: Unknown result type (might be due to invalid IL or missing references) //IL_09af: Unknown result type (might be due to invalid IL or missing references) //IL_09b2: Invalid comparison between Unknown and I4 //IL_089e: Unknown result type (might be due to invalid IL or missing references) //IL_0a50: Unknown result type (might be due to invalid IL or missing references) //IL_09b4: Unknown result type (might be due to invalid IL or missing references) //IL_09b7: 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; } ParticipantState[] array = localMastersSnapshot.Select(LocalParticipantResolver.ClassifyLocal).ToArray(); MarkerLanguage val = CurrentMarkerLanguage(); Camera presentationCamera = GetPresentationCamera(); Vector3 cameraPosition = default(Vector3); bool flag = (Object)(object)presentationCamera != (Object)null && TryGetFiniteCameraPosition(presentationCamera, out cameraPosition); _markerRegistry.BeginSweep(); List<PersonalPickupMarker> list = new List<PersonalPickupMarker>(); HashSet<int> seenPickups = new HashSet<int>(); HashSet<int> hashSet = new HashSet<int>(_markers.Select((PersonalPickupMarker x) => x.InstanceId)); int num = 0; int roundedDistanceMeters; foreach (GenericPickupController pickup in InstanceTracker.GetInstancesList<GenericPickupController>()) { if ((Object)(object)pickup == (Object)null) { continue; } int instanceID = ((Object)pickup).GetInstanceID(); if (!TryResolveOrdinaryMarkerTarget(pickup, out Vector3 worldPosition, out string invalidReason) || (flag && !TryResolvePresentationDistance(cameraPosition, worldPosition, out roundedDistanceMeters, out invalidReason))) { ReleaseGate(instanceID); _markerRegistry.Remove((PersonalMarkerKind)0, instanceID); _ordinaryRenderLogged.Remove(instanceID); if (hashSet.Contains(instanceID)) { LogOrdinaryCleanup(instanceID, invalidReason); } } else { if (!_upstream.IsShareable(pickup)) { continue; } seenPickups.Add(instanceID); bool[] array2 = localMastersSnapshot.Select((CharacterMaster master) => _upstream.HasCollected(pickup, master)).ToArray(); int num2 = array2.Count((bool result) => result); bool flag2 = LocalPickupSuppressionPolicy.ShouldSuppressProcessVisual(_config.PersonalPickupVisibilityRepairEnabled.Value, _upstream.HideCollectedOrbsEnabled, array2.Length, num2); if (flag2) { if (!_gates.TryGetValue(instanceID, out LocalPickupPresentationGate value) || (Object)(object)value == (Object)null) { NormalizeUpstreamForGate(pickup); value = ((Component)pickup).gameObject.GetComponent<LocalPickupPresentationGate>() ?? ((Component)pickup).gameObject.AddComponent<LocalPickupPresentationGate>(); _gates[instanceID] = value; } value.ApplyHidden(); } else { ReleaseGate(instanceID); } LogLocalVisualGateTransition(pickup, num2, array2.Length, flag2); UniquePickup pickup2 = pickup.pickup; MarkerLifetimeKind val2 = MarkerLifetimePolicy.FromTemporaryFlag(((UniquePickup)(ref pickup2)).isTempItem); if (_config.PersonalMarkersEnabled.Value && MarkerLifetimePolicy.IsMarkerEligible(val2, _config.ShareTemporaryItems.Value) && num < 64 && ShouldShowMarker(array, array2)) { string text = MarkerPresentationPolicy.NormalizeLabel(PickupLabel(pickup, val), MarkerTextLocalization.FallbackSharedPickup(val)); MarkerRuntimeMetadata markerRuntimeMetadata = ResolvePickupMarkerMetadata(pickup.pickup.pickupIndex); if ((int)_markerRegistry.MarkPending((PersonalMarkerKind)0, instanceID, text) != 3) { list.Add(new PersonalPickupMarker { InstanceId = instanceID, Pickup = pickup, Label = text, ItemSemanticKey = PickupSemanticKey(pickup), ClassName = markerRuntimeMetadata.ClassName, Kind = markerRuntimeMetadata.Kind, TextColor = markerRuntimeMetadata.TextColor, Lifetime = val2 }); num++; } } } } int[] array3 = _gates.Keys.Where((int x) => !seenPickups.Contains(x)).ToArray(); for (roundedDistanceMeters = 0; roundedDistanceMeters < array3.Length; roundedDistanceMeters++) { int instanceId = array3[roundedDistanceMeters]; ReleaseGate(instanceId); } List<PersonalCommandMarker> list2 = new List<PersonalCommandMarker>(); HashSet<int> seenCommandCandidateIds = new HashSet<int>(); _commandRemovalReasons.Clear(); HashSet<int> hashSet2 = new HashSet<int>(_commandMarkers.Select((PersonalCommandMarker x) => x.InstanceId)); int num3 = 0; if (_upstream.ShareCommandPicksEnabled) { foreach (PickupPickerController instances in InstanceTracker.GetInstancesList<PickupPickerController>()) { if ((Object)(object)instances == (Object)null) { continue; } int instanceID2 = ((Object)instances).GetInstanceID(); if (!_upstream.IsCommandCube(instances)) { ReleaseCommandGate(instanceID2, "classifier-false"); if (hashSet2.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = "classifier-false"; } continue; } seenCommandCandidateIds.Add(instanceID2); bool?[] array4 = new bool?[localMastersSnapshot.Length]; bool flag3 = false; bool flag4 = true; for (int num4 = 0; num4 < localMastersSnapshot.Length; num4++) { if (!_upstream.TryHasCommandPicked(instances, localMastersSnapshot[num4], out var picked)) { array4[num4] = null; flag4 = false; continue; } array4[num4] = picked; if (ProjectionPolicy.ShowPersonalMarker(true, array[num4], picked, false)) { flag3 = true; } } LocalCommandPresentationDecision decision = LocalCommandPresentationPolicy.Evaluate((IReadOnlyList<bool?>)array4); ApplyLocalCommandPresentation(instances, decision); if (!_config.PersonalMarkersEnabled.Value) { if (hashSet2.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = "markers-disabled"; } continue; } if (!TryResolveCommandMarkerTarget(instances, out Vector3 worldPosition2, out string invalidReason2) || (flag && !TryResolvePresentationDistance(cameraPosition, worldPosition2, out roundedDistanceMeters, out invalidReason2))) { _markerRegistry.Remove((PersonalMarkerKind)1, instanceID2); if (hashSet2.Contains(instanceID2)) { LogCommandCleanup(instanceID2, invalidReason2); } continue; } bool flag5 = flag3 || flag4; if (num3 >= 32 || !MarkerPresentationPolicy.ShouldTrackCommandMarker(_config.PersonalMarkersEnabled.Value, _upstream.IsIndividualMode, _upstream.ShareCommandPicksEnabled, true, flag5, flag3)) { if (hashSet2.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = (flag4 ? "local-completed" : "local-state-unresolved"); } continue; } string optionSource; int resolvedOptionCount; bool sourceDisagreement; CommandShareabilityDecision shareability; MarkerRuntimeMetadata markerRuntimeMetadata2 = ResolveCommandMarkerMetadata(instances, val, out optionSource, out resolvedOptionCount, out sourceDisagreement, out shareability); MarkerLifetimeKind lifetime = (MarkerLifetimeKind)3; int exactNestedAvailableOptionCount = 0; int unresolvedAvailableOptionCount = 0; _upstream.TryGetCommandChoiceLifetime(instances, out lifetime, out exactNestedAvailableOptionCount, out unresolvedAvailableOptionCount); string text2 = MarkerPresentationPolicy.NormalizeLabel(markerRuntimeMetadata2.Label, MarkerTextLocalization.FallbackCommandChoice(val)); if ((int)lifetime == 3 && _commandLifetimeUnknownLogged.Add(instanceID2)) { LogInfo("ISF_COMMAND_LIFETIME pickerInstanceId=" + instanceID2.ToString(CultureInfo.InvariantCulture) + " lifetime=Unknown exactNestedAvailable=" + exactNestedAvailableOptionCount.ToString(CultureInfo.InvariantCulture) + " unresolvedAvailable=" + unresolvedAvailableOptionCount.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(lifetime, _config.ShareTemporaryItems.Value)) { _commandShareabilityDiagnosticState[instanceID2] = "temporary-sharing-disabled"; if (hashSet2.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 (hashSet2.Contains(instanceID2)) { _commandRemovalReasons[instanceID2] = ((CommandShareabilityDecision)(ref shareability)).FilterReason; } continue; } _commandShareabilityDiagnosticState[instanceID2] = ((CommandShareabilityDecision)(ref shareability)).DiagnosticToken + ":eligible"; PersonalMarkerTransition val3 = _markerRegistry.MarkPending((PersonalMarkerKind)1, instanceID2, text2); if ((int)val3 != 3) { list2.Add(new PersonalCommandMarker { InstanceId = instanceID2, Picker = instances, Label = text2, ItemSemanticKey = "COMMAND:" + instanceID2.ToString(CultureInfo.InvariantCulture), ClassName = markerRuntimeMetadata2.ClassName, Kind = markerRuntimeMetadata2.Kind, TextColor = markerRuntimeMetadata2.TextColor, Lifetime = lifetime }); num3++; if ((int)val3 == 1 || (int)val3 == 2) { string[] obj = new string[28] { "ISF_COMMAND_MARKER pending pickerInstanceId=", instanceID2.ToString(CultureInfo.InvariantCulture), " localPending=True providerHasState=", _upstream.HasPickerProviderState(instances).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*)(&lifetime))/*cast due to .constrained prefix*/).ToString(); obj[24] = " lifetimeExactNested="; obj[25] = exactNestedAvailableOptionCount.ToString(CultureInfo.InvariantCulture); obj[26] = " lifetimeUnresolved="; obj[27] = unresolvedAvailableOptionCount.ToString(CultureInfo.InvariantCulture); LogInfo(string.Concat(obj)); } } } } array3 = _commandGates.Keys.Where((int x) => !seenCommandCandidateIds.Contains(x)).ToArray(); foreach (int instanceId2 in array3) { ReleaseCommandGate(instanceId2, "picker-destroyed-stale-or-sharing-disabled"); } array3 = _commandShareabilityDiagnosticState.Keys.Where((int x) => !seenCommandCandidateIds.Contains(x)).ToArray(); foreach (int key in array3) { _commandShareabilityDiagnosticState.Remove(key); } _commandLifetimeUnknownLogged.RemoveWhere((int x) => !seenCommandCandidateIds.Contains(x)); foreach (PersonalMarkerDescriptor item in _markerRegistry.EndSweep()) { PersonalMarkerIdentity identity = item.Identity; if ((int)((PersonalMarkerIdentity)(ref identity)).Kind == 0) { HashSet<int> ordinaryRenderLogged = _ordinaryRenderLogged; identity = item.Identity; ordinaryRenderLogged.Remove(((PersonalMarkerIdentity)(ref identity)).InstanceId); } else { identity = item.Identity; int instanceId3 = ((PersonalMarkerIdentity)(ref identity)).InstanceId; string value3; string reason = (_commandRemovalReasons.TryGetValue(instanceId3, out value3) ? value3 : "destroyed-or-untracked"); LogCommandCleanup(instanceId3, reason); } } _markers.Clear(); _markers.AddRange(list); _commandMarkers.Clear(); _commandMarkers.AddRange(list2); } private unsafe void OnMarkerRendered(MarkerRenderDiagnostic diagnostic) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) 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; _cachedLocalMasters = (from x in LocalParticipantResolver.GetLocalMasters() where (Object)(object)x != (Object)null select x).ToArray(); return _cachedLocalMasters; } 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.DiagnosticLogging.Value && (!_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.DiagnosticLogging.Value && !((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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (_config.DiagnosticLogging.Value && !((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); _markerRegistry.Remove((PersonalMarkerKind)0, marker.InstanceId); _ordinaryRenderLogged.Remove(marker.InstanceId); ReleaseGate(marker.InstanceId); LogOrdinaryCleanup(marker.InstanceId, reason); } private void RemoveCommandMarkerNow(PersonalCommandMarker marker, string reason) { _commandMarkers.Remove(marker); _markerRegistry.Remove((PersonalMarkerKind)1, marker.InstanceId); _commandShareabilityDiagnosticState.Remove(marker.InstanceId); LogCommandCleanup(marker.InstanceId, reason); } private void LogOrdinaryCleanup(int instanceId, string reason) { LogInfo("ISF_MARKER_CLEANUP ordinary pickupInstanceId=" + instanceId.ToString(CultureInfo.InvariantCulture) + " reason=" + reason); } private static Sprite? ResolvePickupIcon(GenericPickupController pickup) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { return PickupCatalog.GetPickupDef(pickup.pickup.pickupIndex)?.iconSprite; } catch { return null; } } private unsafe static string PickupSemanticKey(GenericPickupController pickup) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) try { PickupIndex pickupIndex = pickup.pickup.pickupIndex; PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex); if (pickupDef != null && !string.IsNullOrWhiteSpace(pickupDef.nameToken)) { return "PICKUP:" + pickupDef.nameToken; } return "PICKUP_INDEX:" + ((object)(*(PickupIndex*)(&pickupIndex))/*cast due to .constrained prefix*/).ToString(); } catch { return "PICKUP_INSTANCE:" + ((Object)pickup).GetInstanceID().ToString(CultureInfo.InvariantCulture); } } private static string PickupLabel(GenericPickupController pickup, MarkerLanguage language) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) try { PickupDef pickupDef = PickupCatalog.GetPickupDef(pickup.pickup.pickupIndex); if (pickupDef != null && !string.IsNullOrEmpty(pickupDef.nameToken)) { string text = Language.GetString(pickupDef.nameToken); if (!string.IsNullOrWhiteSpace(text) && !string.Equals(text, pickupDef.nameToken, StringComparison.Ordinal)) { return text; } } } catch { } return MarkerTextLocalization.FallbackSharedPickup(language); } private MarkerRuntimeMetadata ResolveCommandMarkerMetadata(PickupPickerController picker, MarkerLanguage language, out string optionSource, out int resolvedOptionCount, out bool sourceDisagreement, out CommandShareabilityDecision shareability) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Invalid comparison between Unknown and I4 //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) optionSource = "unresolved"; resolvedOptionCount = 0; sourceDisagreement = false; shareability = CommandShareabilityPolicy.Evaluate((IEnumerable<bool?>)Array.Empty<bool?>()); if (!_upstream.TryGetCommandChoicePickupIndexes(picker, out PickupIndex[] pickupIndexes, out optionSource, out bool exactSource, out sourceDisagreement) || pickupIndexes.Length == 0) { CommandClassPresentation val = MarkerClassPolicy.ResolveCommandClassForReadablePresentation((IEnumerable<MarkerClassKind>)Array.Empty<MarkerClassKind>(), language); return new MarkerRuntimeMetadata(((CommandClassPresentation)(ref val)).Kind, MarkerClassPolicy.DiagnosticClassName(((CommandClassPresentation)(ref val)).Kind), ((CommandClassPresentation)(ref val)).Label, Color.white, exactClass: false); } resolvedOptionCount = pickupIndexes.Length; List<MarkerRuntimeMetadata> list = new List<MarkerRuntimeMetadata>(pickupIndexes.Length); List<bool?> list2 = new List<bool?>(pickupIndexes.Length); PickupIndex[] array = pickupIndexes; for (int i = 0; i < array.Length; i++) { PickupDef pickupDef = PickupCatalog.GetPickupDef(array[i]); if (pickupDef == null) { list.Add(UnknownPickupMetadata()); list2.Add(null); } else { list.Add(ResolvePickupMarkerMetadata(pickupDef)); list2.Add(_upstream.TryIsShareable(pickupDef, out var shareable) ? new bool?(shareable) : ((bool?)null)); } } shareability = (exactSource ? CommandShareabilityPolicy.Evaluate((IEnumerable<bool?>)list2) : CommandShareabilityPolicy.Evaluate((IEnumerable<bool?>)Array.Empty<bool?>())); CommandClassPresentation classPresentation = MarkerClassPolicy.ResolveCommandClassForReadablePresentation(list.Select((MarkerRuntimeMetadata x) => x.Kind), language); if (!((CommandClassPresentation)(ref classPresentation)).ExactClass) { Color textColor = (((int)((CommandClassPresentation)(ref classPresentation)).Kind == 9 && list.Count > 0) ? list[0].TextColor : Color.white); return new MarkerRuntimeMetadata(((CommandClassPresentation)(ref classPresentation)).Kind, MarkerClassPolicy.DiagnosticClassName(((CommandClassPresentation)(ref classPresentation)).Kind), ((CommandClassPresentation)(ref classPresentation)).Label, textColor, exactClass: false); } MarkerRuntimeMetadata[] array2 = list.Where((MarkerRuntimeMetadata x) => x.Kind == ((CommandClassPresentation)(ref classPresentation)).Kind).ToArray(); Color textColor2 = ((array2.Length != 0) ? array2[0].TextColor : Color.white); return new MarkerRuntimeMetadata(((CommandClassPresentation)(ref classPresentation)).Kind, MarkerClassPolicy.DiagnosticClassName(((CommandClassPresentation)(ref classPresentation)).Kind), ((CommandClassPresentation)(ref classPresentation)).Label, textColor2, exactSource); } private static MarkerRuntimeMetadata ResolvePickupMarkerMetadata(PickupIndex pickupIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) try { PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex); return (pickupDef != null) ? ResolvePickupMarkerMetadata(pickupDef) : UnknownPickupMetadata(); } catch { return UnknownPickupMetadata(); } } private static MarkerRuntimeMetadata ResolvePickupMarkerMetadata(PickupDef def) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) try { bool flag = (int)def.equipmentIndex != -1; bool flag2 = false; if (flag) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(def.equipmentIndex); flag2 = (Object)(object)equipmentDef != (Object)null && equipmentDef.isLunar; } MarkerClassKind val = MarkerClassPolicy.Classify(((object)Unsafe.As<ItemTier, ItemTier>(ref def.itemTier)/*cast due to .constrained prefix*/).ToString(), flag, flag2); return new MarkerRuntimeMetadata(val, MarkerClassPolicy.DiagnosticClassName(val), string.Empty, SanitizeMarkerColor(def.baseColor), (int)val > 0); } catch { return UnknownPickupMetadata(); } } private static MarkerRuntimeMetadata UnknownPickupMetadata() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new MarkerRuntimeMetadata((MarkerClassKind)0, MarkerClassPolicy.DiagnosticClassName((MarkerClassKind)0), string.Empty, Color.white, exactClass: false); } private static Color SanitizeMarkerColor(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) if (float.IsNaN(color.r) || float.IsInfinity(color.r) || float.IsNaN(color.g) || float.IsInfinity(color.g) || float.IsNaN(color.b) || float.IsInfinity(color.b) || color.a <= 0.01f) { return Color.white; } color.a = 1f; return color; } private static string ColorEvidence(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(SanitizeMarkerColor(color)); } private static MarkerLanguage CurrentMarkerLanguage() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) try { return MarkerTextLocalization.ResolveLanguage(Language.currentLanguageName); } catch { return (MarkerLanguage)0; } } private void LogCommandCleanup(int instanceId, string reason) { LogInfo("ISF_COMMAND_MARKER cleanup pickerInstanceId=" + instanceId.ToString(CultureInfo.InvariantCulture) + " reason=" + reason); } private Camera? GetPresentationCamera() { float unscaledTime = Time.unscaledTime; if ((Object)(object)_presentationCamera != (Object)null && (Object)(object)((Component)_presentationCamera).gameObject != (Object)null && ((Component)_presentationCamera).gameObject.activeInHierarchy && unscaledTime < _nextPresentationCameraRefresh) { return _presentationCamera; } _nextPresentationCameraRefresh = unscaledTime + 2f; try { _presentationCamera = Camera.main; } catch { _presentationCamera = null; } return _presentationCamera; } private void MaybeEmitPerformanceSummary(int markerCount) { if (_config.DiagnosticLogging.Value) { float unscaledTime = Time.unscaledTime; if (!(unscaledTime < _nextPerformanceSummary)) { _nextPerformanceSummary = unscaledTime + 5f; EmitPerformanceSummary("periodic", markerCount, force: false); } } } private void EmitPerformanceSummary(string reason, int markerCount, bool force) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (_config.DiagnosticLogging.Value || force) { MarkerRuntimePerformanceSnapshot val = _performance.Snapshot(); _log.LogInfo((object)("[ItemShareFix] ISF_MARKER_PERF_SUMMARY reason=" + reason + " markers=" + markerCount.ToString(CultureInfo.InvariantCulture) + " updates=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).UnityUpdateCalls.ToString(CultureInfo.InvariantCulture) + " renderFrames=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).RenderFrameCalls.ToString(CultureInfo.InvariantCulture) + " fullSolves=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).FullPlacementSolves.ToString(CultureInfo.InvariantCulture) + " singleFast=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).SingleMarkerFastPathCalls.ToString(CultureInfo.InvariantCulture) + " globalHudDiscovery=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).GlobalHudDiscoveries.ToString(CultureInfo.InvariantCulture) + " tmpMeasures=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).TmpPreferredMeasurements.ToString(CultureInfo.InvariantCulture) + " uiWrites=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).UiLayoutWrites.ToString(CultureInfo.InvariantCulture) + " diagnostics=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).DiagnosticRecords.ToString(CultureInfo.InvariantCulture) + " heavyMsTotal=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).HeavySolveMilliseconds.ToString("F3", CultureInfo.InvariantCulture) + " heavyMsMax=" + ((MarkerRuntimePerformanceSnapshot)(ref val)).MaxHeavySolveMilliseconds.ToString("F3", CultureInfo.InvariantCulture))); } } private void LogInfo(string message) { if (_config.DiagnosticLogging.Value) { _performance.RecordDiagnosticRecord(); _log.LogInfo((object)("[ItemShareFix] " + message)); } } private static int CurrentStageToken() { Run instance = Run.instance; if ((Object)(object)instance == (Object)null) { return -1; } object member = ParticipantIdentityResolver.GetMember(instance, "stageClearCount"); try { return (member != null) ? Convert.ToInt32(member, CultureInfo.InvariantCulture) : 0; } catch { return 0; } } } internal sealed class CompatibilityResult { public bool Supported { get; set; } public string Reason { get; set; } = string.Empty; public Assembly? ItemShareAssembly { get; set; } public Assembly? PickupShareApiAssembly { get; set; } public MethodInfo? DisconnectMethod { get; set; } } internal static class CompatibilityGuard { internal const string ExpectedItemShareSha256 = "48C25FE558CB095B2AC73836BE0563EBFDCD1C481AF9263D9D3740618F160F38"; internal const string ExpectedPickupShareApiSha256 = "5EF4AC9457DB29BDA76C5DB110914EA14720ADE65DC6D5E48359B3DF8DED7F1D"; public static CompatibilityResult Probe(ManualLogSource log) { try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => string.Equals(x.GetName().Name, "ItemShare", StringComparison.Ordinal)); if (assembly == null) { return Fail("ItemShare assembly is not loaded."); } if (assembly.GetName().Version?.ToString() != "1.7.1.0") { return Fail("Unsupported ItemShare assembly version: " + assembly.GetName().Version); } string text = HashAssembly(assembly); if (!string.Equals(text, "48C25FE558CB095B2AC73836BE0563EBFDCD1C481AF9263D9D3740618F160F38", StringComparison.OrdinalIgnoreCase)) { return Fail("ItemShare.dll SHA-256 mismatch: " + text); } Assembly assembly2 = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly x) => string.Equals(x.GetName().Name, "PickupShareApi", StringComparison.Ordinal)); if (assembly2 == null) { return Fail("PickupShareApi assembly is not loaded."); } if (assembly2.GetName().Version?.ToString() != "1.0.0.0") { return Fail("Unsupported PickupShareApi assembly version: " + assembly2.GetName().Version); } string text2 = HashAssembly(assembly2); if (!string.Equals(text2, "5EF4AC9457DB29BDA76C5DB110914EA14720ADE65DC6D5E48359B3DF8DED7F1D", StringComparison.OrdinalIgnoreCase)) { return Fail("PickupShareApi.dll SHA-256 mismatch: " + text2); } Type type = assembly2.GetType("PickupShare.PickupShareApi", throwOnError: false); object obj = type?.GetProperty("ApiVersion", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); if (obj == null) { obj = type?.GetField("ApiVersion", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); } if (Convert.ToInt32(obj, CultureInfo.InvariantCulture) != 1) { return Fail("PickupShareApi contract is not ApiVersion 1."); } Type type2 = assembly.GetType("ItemShare.ItemSharePlugin", throwOnError: false); Type type3 = assembly.GetType("ItemShare.ClientPickMirror", throwOnError: false); Type type4 = assembly.GetType("ItemShare.ItemShareStateProvider", throwOnError: false); Type type5 = assembly2.GetType("PickupShare.PickupClassifier", throwOnError: false); if (type2 == null || type3 == null || type4 == null || type5 == null) { return Fail("Required exact ItemShare 1.7.1 / PickupShareApi 1.0.0 types are missing."); } string[] array = new string[7] { "Claims", "Distributed", "Choices", "_mode", "_hideCollectedOrbs", "_shareToDead", "_shareCommandPicks" }; foreach (string text3 in array) { if (type2.GetField(text3, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) == null) { return Fail("Required ItemShare field missing: " + text3); } } (string, int, Type)[] array2 = new(string, int, Type)[11] { ("OnAttemptGrant", 3, typeof(void)), ("GrantIndividual", 5, typeof(void)), ("GrantInstant", 5, typeof(void)), ("GiveDirect", 3, typeof(bool)), ("IsDown", 1, typeof(bool)), ("OnPickupSelected", 3, typeof(void)), ("IsShareable", 1, typeof(bool)), ("BroadcastOrbState", 2, typeof(void)), ("ApplyOrbVisibility", 2, typeof(void)), ("LocalPlayersHaveTaken", 1, typeof(bool)), ("RefreshOrbVisibility", 0, typeof(void)) }; for (int num = 0; num < array2.Length; num++) { (string Name, int ParameterCount, Type ReturnType) shape = array2[num]; if ((from x in type2.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where string.Equals(x.Name, shape.Name, StringComparison.Ordinal) && x.GetParameters().Length == shape.ParameterCount && x.ReturnType == shape.ReturnType select x).ToArray().Length != 1) { return Fail("Required ItemShare method shape mismatch: " + shape.Name + "/" + shape.ParameterCount + " -> " + shape.ReturnType.Name); } } if (!HasExactOriginalDelegateHookShape(type2.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Single((MethodInfo x) => string.Equals(x.Name, "OnAttemptGrant", StringComparison.Ordinal) && x.GetParameters().Length == 3 && x.ReturnType == typeof(void)), typeof(GenericPickupController), typeof(CharacterBody))) { return Fail("ItemShare OnAttemptGrant exact orig/self/body delegate shape mismatch."); } if (!HasExactOriginalDelegateHookShape(type2.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Single((MethodInfo x) => string.Equals(x.Name, "OnPickupSelected", StringComparison.Ordinal) && x.GetParameters().Length == 3 && x.ReturnType == typeof(void)), typeof(PickupPickerController), typeof(int))) { return Fail("ItemShare OnPickupSelected exact orig/self/choiceIndex delegate shape mismatch."); } if (type4.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).SingleOrDefault((MethodInfo x) => string.Equals(x.Name, "TransferOrbState", StringComparison.Ordinal) && x.GetParameters().Length == 2 && x.ReturnType == typeof(bool)) == null) { return Fail("ItemShare provider TransferOrbState(int,int)->bool private shape missing."); } array = new string[2] { "Orbs", "Cubes" }; foreach (string text4 in array) { if (type3.GetField(text4, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) == null) { return Fail("ItemShare ClientPickMirror." + text4 + " private shape missing."); } } MethodInfo method = type5.GetMethod("IsCommandCube", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(PickupPickerController) }, null); if (method == null || method.ReturnType != typeof(bool)) { return Fail("PickupShareApi PickupClassifier.IsCommandCube(PickupPickerController)->bool shape missing."); } MethodInfo methodInfo = type?.GetMethod("HasPickerState", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); if (methodInfo == null || methodInfo.ReturnType != typeof(bool)) { return Fail("PickupShareApi HasPickerState(int)->bool public shape missing."); } if (typeof(PickupPickerController).GetField("options", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null) { return Fail("RoR2 PickupPickerController.options exact choice-data field missing."); } FieldInfo fieldInfo = typeof(PickupPickerController).GetNestedType("Option", BindingFlags.Public | BindingFlags.NonPublic)?.GetField("pickup", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (fieldInfo == null || fieldInfo.FieldType != typeof(UniquePickup)) { return Fail("RoR2 PickupPickerController.Option.pickup : UniquePickup exact field missing."); } PropertyInfo property = typeof(UniquePickup).GetProperty("isTempItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || property.PropertyType != typeof(bool) || property.GetIndexParameters().Length != 0) { return Fail("RoR2 UniquePickup.isTempItem : bool exact property missing."); } object obj2 = type?.GetProperty("HasProvider", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); string text5 = type?.GetProperty("ProviderName", BindingFlags.Static | BindingFlags.Public)?.GetValue(null)?.ToString(); if (!(obj2 is bool) || !(bool)obj2) { return Fail("PickupShareApi has no registered provider; ItemShare must remain the sole provider."); } if (string.IsNullOrEmpty(text5) || !text5.StartsWith("ItemShare", StringComparison.Ordinal)) { return Fail("PickupShareApi provider is not ItemShare: " + (text5 ?? "<null>")); } Assembly assembly3 = typeof(Run).Assembly; if (!HasStableNetworkUserIdShape(assembly3, out string reason)) { return Fail("Stable NetworkUserId identity shape unsupported: " + reason); } Type type6 = assembly3.GetType("RoR2.LocalUserManager", throwOnError: false); if (type6 == null) { return Fail("RoR2.LocalUserManager type missing."); } if ((MemberInfo?)(((object)type6.GetProperty("readOnlyLocalUsersList", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)type6.GetField("readOnlyLocalUsersList", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))) == null) { return Fail("RoR2.LocalUserManager.readOnlyLocalUsersList shape missing; personal visibility cannot safely resolve local identity."); } MethodInfo methodInfo2 = FindDisconnectMethod(assembly3); if (methodInfo2 == null) { return Fail("No supported network-destroy observation callback shape was found (NetworkUser/PlayerCharacterMasterController OnNetworkDestroy). DisconnectCleanup must fail closed."); } log.LogInfo((object)("[ItemShareFix] compatibility guard PASS: exact ItemShare 1.7.1 + PickupShareApi 1.0.0 / API 1 + Command picker shapes; disconnect candidate hook=" + methodInfo2.DeclaringType?.FullName + "." + methodInfo2.Name)); return new CompatibilityResult { Supported = true, Reason = "Exact baseline and private shapes verified.", ItemShareAssembly = assembly, PickupShareApiAssembly = assembly2, DisconnectMethod = methodInfo2 }; } catch (Exception ex) { return Fail("Compatibility probe exception: " + ex); } } private static bool HasExactOriginalDelegateHookShape(MethodInfo hookMethod, Type selfType, Type payloadType) { ParameterInfo[] parameters = hookMethod.GetParameters(); if (parameters.Length != 3 || parameters[1].ParameterType != selfType || parameters[2].ParameterType != payloadType) { return false; } Type parameterType = parameters[0].ParameterType; if (!typeof(Delegate).IsAssignableFrom(parameterType)) { return false; } MethodInfo method = parameterType.GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public); if (method == null || method.ReturnType != typeof(void)) { return false; } ParameterInfo[] parameters2 = method.GetParameters(); if (parameters2.Length == 2 && parameters2[0].ParameterType == selfType) { return parameters2[1].ParameterType == payloadType; } return false; } private static bool HasStableNetworkUserIdShape(Assembly ror2Assembly, out string reason) { reason = string.Empty; Type type = ror2Assembly.GetType("RoR2.NetworkUser", throwOnError: false); Type type2 = ror2Assembly.GetType("RoR2.NetworkUserId", throwOnError: false); Type platformIdType = ror2Assembly.GetType("RoR2.PlatformID", throwOnError: false); if (type == null || type2 == null || platformIdType == null) { reason = "NetworkUser/NetworkUserId/PlatformID type missing"; return false; } PropertyInfo property = type.GetProperty("id", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field = type.GetField("id", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (((property != null) ? property.PropertyType : field?.FieldType) != type2) { reason = "NetworkUser.id is missing or not RoR2.NetworkUserId"; return false; } if ((from x in type2.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where (x is FieldInfo fieldInfo && fieldInfo.FieldType == platformIdType) || (x is PropertyInfo propertyInfo && propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.PropertyType == platformIdType) select x).ToArray().Length == 0) { reason = "NetworkUserId has no PlatformID member"; return false; } if ((from x in type2.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where (x is FieldInfo fieldInfo && fieldInfo.FieldType == typeof(byte)) || (x is PropertyInfo propertyInfo && propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.PropertyType == typeof(byte)) select x).ToArray().Length == 0) { reason = "NetworkUserId has no byte player-controller slot member"; return false; } PropertyInfo? property2 = platformIdType.GetProperty("value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = platformIdType.GetField("value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property2 == null && field2 == null) { reason = "PlatformID.value missing"; return false; } return true; } private static MethodInfo? FindDisconnectMethod(Assembly ror2Assembly) { string[] array = new string[2] { "RoR2.NetworkUser", "RoR2.PlayerCharacterMasterController" }; foreach (string name in array) { MethodInfo methodInfo = ror2Assembly.GetType(name, throwOnError: false)?.GetMethod("OnNetworkDestroy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (methodInfo != null && methodInfo.GetParameters().Length == 0) { return methodInfo; } } return null; } private static string HashAssembly(Assembly assembly) { string location = assembly.Location; if (string.IsNullOrEmpty(location) || !File.Exists(location)) { throw new InvalidOperationException("Assembly has no hashable on-disk location: " + assembly.FullName); } using FileStream inputStream = File.OpenRead(location); using SHA256 sHA = SHA256.Create(); return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", string.Empty); } private static CompatibilityResult Fail(string reason) { return new CompatibilityResult { Supported = false, Reason = reason }; } } [BepInPlugin("com.itemsharefix", "ItemShareFix", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class ItemShareFixPlugin : BaseUnityPlugin { public const string PluginGuid = "com.itemsharefix"; public const string PluginName = "ItemShareFix"; public const string PluginVersion = "1.0.0"; private Harmony? _harmony; private PluginConfig? _config; private ServerCoordinator? _server; private ClientPresentationCoordinator? _presentation; private bool _active; private int _riskOfOptionsLocalizationWarmupFrames; private void Awake() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown _config = new PluginConfig(((BaseUnityPlugin)this).Config); if (!_config.Enabled.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ItemShareFix] disabled by configuration."); return; } CompatibilityResult compatibilityResult = CompatibilityGuard.Probe(((BaseUnityPlugin)this).Logger); if (!compatibilityResult.Supported) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ItemShareFix] FAIL-CLOSED: " + compatibilityResult.Reason)); ((Behaviour)this).enabled = false; return; } try { if (RemoteOperationProbe.TryVerifyRuntimeShape(out string evidence)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[ItemShareFix] Remote Operation runtime shape PASS: " + evidence)); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[ItemShareFix] Remote Operation runtime shape unavailable; Support Drone classification will fail closed: " + evidence)); } UpstreamBridge upstream = new UpstreamBridge(compatibilityResult.ItemShareAssembly, compatibilityResult.PickupShareApiAssembly, ((BaseUnityPlugin)this).Logger); _server = new ServerCoordinator(_config, upstream, ((BaseUnityPlugin)this).Logger); _presentation = new ClientPresentationCoordinator(_config, upstream, ((BaseUnityPlugin)this).Logger); _harmony = new Harmony("com.itemsharefix"); RuntimePatches.Install(_harmony, compatibilityResult, _server, _presentation); _active = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[ItemShareFix] world-space marker clustering active: adaptive LOD, Detailed default / Compact optional presentation, HUD/modal suppression enabled. Gameplay/share ownership remains unchanged."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[ItemShareFix] initialization failed closed: " + ex)); try { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } _presentation?.RestoreAll(); _active = false; ((Behaviour)this).enabled = false; } } private void FixedUpdate() { if (_active && _config != null) { if (!_config.Enabled.Value) { _presentation?.RestoreAll(); return; } _server?.Tick(); _presentation?.Tick(); } } private void Update() { if (_config != null) { if (_riskOfOptionsLocalizationWarmupFrames < 3) { _riskOfOptionsLocalizationWarmupFrames++; } if (_riskOfOptionsLocalizationWarmupFrames >= 3) { OptionalRiskOfOptionsIntegration.TryRegister(_config, ((BaseUnityPlugin)this).Logger); OptionalRiskOfOptionsIntegration.TryRefreshLocalization(((BaseUnityPlugin)this).Logger); } } if (_active && _presentation != null) { _presentation.RecordUnityUpdate(); _presentation.RenderFrame(); } } private void OnDestroy() { _active = false; try { _presentation?.Dispose(); } catch { } try { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } } internal sealed class LocalHudPresentationProbe { private sealed class MessageHudCandidate { public RectTransform Root { get; } public TMP_Text[] Texts { get; } public Selectable[] Selectables { get; } public Vector3[] Corners { get; } = (Vector3[])(object)new Vector3[4]; public MessageHudCandidate(RectTransform root) { Root = root; Texts = ((Component)root).GetComponentsInChildren<TMP_Text>(true); Selectables = ((Component)root).GetComponentsInChildren<Selectable>(true); } } internal static readonly string[] BlockingModalTypeNames = new string[3] { "RoR2.UI.PauseScreenController", "RoR2.UI.SimpleDialogBox", "RoR2.UI.PickupPickerPanel" }; private static readonly string[] MessageHudTypeNames = new string[3] { "RoR2.UI.ChatBox", "RoR2.UI.ChatBoxController", "RoR2.UI.HUDChat" }; private readonly Type[] _blockingModalTypes; private readonly Type[] _messageHudTypes; private readonly Type? _hudType; private readonly MarkerRuntimePerformanceCounters _performance; private readonly List<Component> _blockingModalComponents = new List<Component>(); private readonly HashSet<int> _blockingModalIds = new HashSet<int>(); private readonly List<MessageHudCandidate> _messageHudRoots = new List<MessageHudCandidate>(); private readonly HashSet<int> _messageRootIds = new HashSet<int>(); private float _nextBlockingDiscovery; private float _nextMessageDiscovery; private bool _blockingLifecycleInvalidated = true; private bool _messageLifecycleInvalidated = true; private bool _lastPauseSignal; public LocalHudPresentationProbe(MarkerRuntimePerformanceCounters performance) { _performance = performance ?? throw new ArgumentNullException("performance"); Assembly assembly = typeof(Run).Assembly; _blockingModalTypes = ResolveComponentTypes(assembly, BlockingModalTypeNames); _messageHudTypes = ResolveComponentTypes(assembly, MessageHudTypeNames); Type type