using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Auuueser.ScanValue.Configuration; using Auuueser.ScanValue.Core.Configuration; using Auuueser.ScanValue.Core.Domain; using Auuueser.ScanValue.Core.Localization; using Auuueser.ScanValue.Game; using Auuueser.ScanValue.Localization; using Auuueser.ScanValue.Presentation; using Auuueser.ScanValue.Runtime; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Rendering; 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("ScanValue")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+dc2e2945334d0124669ecf1cd91a828da6fa9e8b")] [assembly: AssemblyProduct("ScanValue")] [assembly: AssemblyTitle("ScanValue")] [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 Auuueser.ScanValue { [BepInPlugin("com.auuueser.lethalcompany.scanvalue", "ScanValue", "0.0.1")] [BepInProcess("Lethal Company.exe")] public sealed class Plugin : BaseUnityPlugin { private ScanValueRuntime? runtime; private bool applicationQuitting; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ConfigLanguage language = ChineseProjectLanguageDetector.Detect(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); if (ConfigLanguageFileMigrator.Normalize(((BaseUnityPlugin)this).Config.ConfigFilePath, language, ((BaseUnityPlugin)this).Logger)) { ((BaseUnityPlugin)this).Config.Reload(); } ModConfig config = ModConfig.Bind(((BaseUnityPlugin)this).Config, language); runtime = ScanValueRuntime.Start(config, ((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ScanValue 0.0.1 loaded."); } private void OnDestroy() { if (!applicationQuitting && Application.isPlaying) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"ScanValue received early OnDestroy while the application is still running; preserving runtime."); } else { DisposeRuntime(); } } private void OnApplicationQuit() { applicationQuitting = true; DisposeRuntime(); } private void DisposeRuntime() { runtime?.Dispose(); runtime = null; } } internal static class PluginInfo { public const string PluginGuid = "com.auuueser.lethalcompany.scanvalue"; public const string PluginName = "ScanValue"; public const string PluginVersion = "0.0.1"; } } namespace Auuueser.ScanValue.Runtime { internal sealed class ScanValueRuntime : IDisposable { private static GameObject? runtimeObject; private static ScrapVisibilityController? runtimeController; private static ScrapObjectRegistry? registry; private static ScrapObjectPatcher? patcher; private static VanillaScanPatcher? scanPatcher; private static ScrapPricePresenter? presenter; private static ScrapHighlightPresenter? highlightPresenter; private static ScrapItemNameLocalizer? nameLocalizer; private readonly GameObject host; private bool disposed; private ScanValueRuntime(GameObject host) { this.host = host; } public static ScanValueRuntime Start(ModConfig config, ManualLogSource logger) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)runtimeObject == (Object)null) { runtimeObject = new GameObject("ScanValue.Runtime"); ((Object)runtimeObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)runtimeObject); } else if (!runtimeObject.activeSelf) { runtimeObject.SetActive(true); } if (nameLocalizer == null) { nameLocalizer = ScrapItemNameLocalizer.Load(logger); } if (registry == null) { registry = new ScrapObjectRegistry(logger, nameLocalizer); } if (presenter == null) { presenter = new ScrapPricePresenter(runtimeObject.transform, nameLocalizer); } if (highlightPresenter == null) { highlightPresenter = new ScrapHighlightPresenter(); } if (patcher == null) { patcher = new ScrapObjectPatcher(registry, logger, ReapplyHighlightVisibility); } runtimeController = runtimeObject.GetComponent(); if ((Object)(object)runtimeController == (Object)null) { runtimeController = runtimeObject.AddComponent(); } runtimeController.Initialize(config, logger, registry, presenter, highlightPresenter, new LocalPlayerProvider()); if (scanPatcher == null) { scanPatcher = new VanillaScanPatcher(runtimeController, logger); } runtimeController.SetEnabled(enabled: true); logger.LogInfo((object)"Runtime controller active."); return new ScanValueRuntime(runtimeObject); } private static void ReapplyHighlightVisibility(GrabbableObject item) { if (registry != null && highlightPresenter != null && registry.TryGet(item, out TrackedScrapItem tracked)) { runtimeController?.MarkVanillaScanVisualStateDirty(); if (item.isHeld || item.isHeldByEnemy || item.isPocketed || item.deactivated || item.itemUsedUp) { highlightPresenter.Hide(tracked); } else { highlightPresenter.ReapplyVisibilityState(tracked); } } } public void Dispose() { if (!disposed) { disposed = true; patcher?.Dispose(); patcher = null; scanPatcher?.Dispose(); scanPatcher = null; registry?.Clear(); registry = null; nameLocalizer = null; highlightPresenter?.HideAll(); highlightPresenter = null; presenter = null; runtimeController = null; if ((Object)(object)host != (Object)null) { Object.Destroy((Object)(object)host); } if ((Object)(object)runtimeObject == (Object)(object)host) { runtimeObject = null; } } } } internal sealed class ScrapDiagnostics { private readonly ManualLogSource logger; private float nextLogTime; public ScrapDiagnostics(ManualLogSource logger) { this.logger = logger; } public void LogNoCameraIfDue(ScrapDebugOptions debug, int registered, string reason) { if (ShouldLog(debug)) { logger.LogInfo((object)$"ScanValue diagnostics: camera=none registered={registered} reason={reason}"); } } public void LogScanIfDue(ScrapDebugOptions debug, Camera camera, ScrapDiagnosticCounters counters) { if (ShouldLog(debug)) { logger.LogInfo((object)($"ScanValue diagnostics: camera={((Object)camera).name} registered={counters.Registered} alive={counters.Alive} candidates={counters.Candidates} shown={counters.Shown} " + $"hiddenNoValue={counters.HiddenNoValue} hiddenState={counters.HiddenState} hiddenDistance={counters.HiddenDistance} hiddenBudget={counters.HiddenBudget} hiddenOverlap={counters.HiddenOverlap} " + $"poolActive={counters.PoolActive} poolIdle={counters.PoolIdle} testLabel={counters.TestLabel}")); } } private bool ShouldLog(ScrapDebugOptions debug) { if (!debug.ShouldLogDiagnostics || Time.realtimeSinceStartup < nextLogTime) { return false; } nextLogTime = Time.realtimeSinceStartup + debug.LogIntervalSeconds; return true; } } internal struct ScrapDiagnosticCounters { public int Registered; public int Alive; public int Candidates; public int Shown; public int HiddenNoValue; public int HiddenState; public int HiddenDistance; public int HiddenBudget; public int HiddenOverlap; public int PoolActive; public int PoolIdle; public bool TestLabel; } internal sealed class ScrapVisibilityController : MonoBehaviour { private const int VisualPrewarmBatchSize = 4; private const int LayoutCandidateMargin = 24; private const int HighlightPrewarmBatchSize = 2; private const int HighlightPrewarmCandidateChecks = 16; private ModConfig config; private ManualLogSource logger; private ScrapObjectRegistry registry; private ScrapPricePresenter presenter; private ScrapHighlightPresenter highlightPresenter; private LocalPlayerProvider localPlayerProvider; private ScrapDiagnostics diagnostics; private ScrapVisibilityRules rules; private ScrapVisibilityRules highlightRules; private readonly ScrapLabelLayoutResolver layoutResolver = new ScrapLabelLayoutResolver(ScrapLabelLayoutOptions.Default); private readonly List preLayoutItems = new List(128); private readonly List preLayoutDistanceSquares = new List(128); private readonly List preLayoutWasVisible = new List(128); private readonly List layoutItems = new List(128); private readonly List layoutCandidates = new List(128); private readonly List layoutPlacements = new List(128); private readonly List layoutAnchors = new List(128); private readonly List visibleVanillaScanItems = new List(32); private readonly List incomingVanillaScanItems = new List(32); private int settingsVersion = -1; private float nextRefreshTime; private float nextPrewarmTime; private float nextDebugHeartbeatLogTime; private int nextHighlightPrewarmIndex; private bool vanillaScanHighlightRefreshRequired = true; private bool initialized; public bool ShouldSuppressVanillaScanElements { get { if (initialized) { return config.Current.Visibility.Enabled; } return false; } } public bool ShouldOptimizeVanillaScan { get { if (initialized) { return config.Current.ScanPerformance.OptimizeVanillaScan; } return false; } } public void Initialize(ModConfig config, ManualLogSource logger, ScrapObjectRegistry registry, ScrapPricePresenter presenter, ScrapHighlightPresenter highlightPresenter, LocalPlayerProvider localPlayerProvider) { this.config = config; this.logger = logger; this.registry = registry; this.presenter = presenter; this.highlightPresenter = highlightPresenter; this.localPlayerProvider = localPlayerProvider; diagnostics = new ScrapDiagnostics(logger); initialized = true; RefreshSettingsIfNeeded(); } public void SetEnabled(bool enabled) { ((Component)this).gameObject.SetActive(enabled); } public void MarkVanillaScanVisualStateDirty() { if (initialized) { vanillaScanHighlightRefreshRequired = true; nextRefreshTime = 0f; } } public void SetVisibleVanillaScanNodes(Dictionary scanNodes) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return; } if (scanNodes == null) { ClearVisibleVanillaScanNodes(); return; } ModSettings current = config.Current; if (!current.Visibility.Enabled || (int)current.Visibility.ActivationMode != 0) { ClearVisibleVanillaScanNodes(); highlightPresenter.HideAll(); return; } incomingVanillaScanItems.Clear(); bool flag = false; foreach (KeyValuePair scanNode in scanNodes) { ScanNodeProperties value = scanNode.Value; if (!((Object)(object)value == (Object)null) && value.nodeType == 2 && registry.TryGetByScanNode(value, out TrackedScrapItem tracked) && TryApplyScanNodeValue(value, tracked, out var valueChanged)) { if (valueChanged) { flag = true; } incomingVanillaScanItems.Add(tracked); } } bool num = !VanillaScanItemsMatch(); if (num) { visibleVanillaScanItems.Clear(); visibleVanillaScanItems.AddRange(incomingVanillaScanItems); nextRefreshTime = 0f; vanillaScanHighlightRefreshRequired = true; } if (flag) { nextRefreshTime = 0f; } if (num || flag || vanillaScanHighlightRefreshRequired) { RefreshHighlightedVanillaScanItems(current, incomingVanillaScanItems); vanillaScanHighlightRefreshRequired = false; } } public void ClearVisibleVanillaScanNodes() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return; } highlightPresenter.HideAll(); if (visibleVanillaScanItems.Count != 0) { visibleVanillaScanItems.Clear(); nextRefreshTime = 0f; if ((int)config.Current.Visibility.ActivationMode == 0) { presenter.HideScrapLabels(); } } } private void Update() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_0191: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return; } config.ReloadIfChangedOnDisk(Time.realtimeSinceStartup); RefreshSettingsIfNeeded(); ModSettings current = config.Current; if (!current.Visibility.Enabled) { highlightPresenter.HideAll(); presenter.HideAll(); LogDebugHeartbeatIfDue(current, null); return; } bool flag = (int)current.Visibility.ActivationMode == 0; PrewarmScanVisualCachesIfDue(current, flag); if (flag && visibleVanillaScanItems.Count == 0 && !current.Debug.ShouldShowCameraTestLabel && !current.Debug.ShouldLogDiagnostics) { highlightPresenter.HideAll(); presenter.HideDebugTestLabel(); presenter.HideScrapLabels(); return; } if (!localPlayerProvider.TryGet(out Vector3 playerPosition, out Camera playerCamera, out string failureReason)) { highlightPresenter.HideAll(); presenter.HideDebugTestLabel(); presenter.HideAll(); diagnostics.LogNoCameraIfDue(current.Debug, registry.Count, failureReason); LogDebugHeartbeatIfDue(current, null); return; } if (current.Debug.ShouldShowCameraTestLabel) { presenter.ShowDebugTestLabel(playerCamera); } else { presenter.HideDebugTestLabel(); } LogDebugHeartbeatIfDue(current, playerCamera); if (flag && visibleVanillaScanItems.Count == 0) { highlightPresenter.HideAll(); presenter.HideScrapLabels(); } else if (!(Time.unscaledTime < nextRefreshTime)) { nextRefreshTime = Time.unscaledTime + current.Visibility.UpdateIntervalSeconds; RefreshVisibleLabels(current, playerPosition, playerCamera, flag); } } private void RefreshSettingsIfNeeded() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0081: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) if (settingsVersion == config.SettingsVersion) { return; } settingsVersion = config.SettingsVersion; rules = new ScrapVisibilityRules(config.Current.Visibility, config.Current.Debug); highlightRules = new ScrapVisibilityRules(config.Current.Visibility, ScrapDebugOptions.Disabled); ScrapLabelLayoutResolver obj = layoutResolver; ScrapItemNameOptions itemNames = config.Current.ItemNames; obj.UpdateOptions(ScrapLabelLayoutOptions.ForItemNames(((ScrapItemNameOptions)(ref itemNames)).ShowItemNames)); registry.SetDebugOptions(config.Current.Debug.Enabled && config.Current.Debug.LogRegistrations, config.Current.Debug.Enabled && config.Current.Debug.ShowZeroValueItems); presenter.ApplyStyle(config.Current); highlightPresenter.ApplyStyle(config.Current); vanillaScanHighlightRefreshRequired = true; if (config.Current.Visibility.Enabled) { ScrapHighlightOptions highlight = config.Current.Highlight; if (((ScrapHighlightOptions)(ref highlight)).Enabled && (int)config.Current.Visibility.ActivationMode == 0) { goto IL_0192; } } visibleVanillaScanItems.Clear(); highlightPresenter.HideAll(); goto IL_0192; IL_0192: nextRefreshTime = 0f; nextPrewarmTime = 0f; if (config.Current.Debug.ShouldLogDiagnostics) { logger.LogInfo((object)"ScanValue settings reloaded."); } } private void LogDebugHeartbeatIfDue(ModSettings settings, Camera? camera) { ScrapDebugOptions debug = settings.Debug; if (debug.ShouldLogDiagnostics && !(Time.unscaledTime < nextDebugHeartbeatLogTime)) { nextDebugHeartbeatLogTime = Time.unscaledTime + debug.LogIntervalSeconds; string arg = (((Object)(object)camera != (Object)null) ? ((Object)camera).name : "none"); logger.LogInfo((object)($"ScanValue debug heartbeat: enabled={settings.Visibility.Enabled} camera='{arg}' registered={registry.Count} " + $"active={presenter.ActiveCount} testLabel={presenter.DebugTestLabelVisible}")); } } private void PrewarmScanVisualCachesIfDue(ModSettings settings, bool usesVanillaScanNodes) { if (usesVanillaScanNodes && visibleVanillaScanItems.Count == 0 && !(Time.unscaledTime < nextPrewarmTime)) { nextPrewarmTime = Time.unscaledTime + settings.Visibility.UpdateIntervalSeconds; presenter.Prewarm(settings.Visibility.MaxVisibleLabels, 4); PrewarmHighlightProxies(settings, 2); } } private void PrewarmHighlightProxies(ModSettings settings, int maxCreatedCount) { //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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) ScrapHighlightOptions highlight = settings.Highlight; if (!((ScrapHighlightOptions)(ref highlight)).Enabled || registry.Count == 0 || maxCreatedCount <= 0) { return; } int num = ((registry.Count < 16) ? registry.Count : 16); int num2 = 0; for (int i = 0; i < num; i++) { if (num2 >= maxCreatedCount) { break; } if (nextHighlightPrewarmIndex >= registry.Count) { nextHighlightPrewarmIndex = 0; } TrackedScrapItem trackedScrapItem = registry[nextHighlightPrewarmIndex]; nextHighlightPrewarmIndex++; if (trackedScrapItem.IsAlive) { ScrapItemSnapshot val = CreateVanillaScanSnapshot(trackedScrapItem); if (highlightRules.ShouldShowVanillaScanned(val) && highlightPresenter.Prewarm(trackedScrapItem, settings)) { num2++; } } } } private void RefreshVisibleLabels(ModSettings settings, Vector3 playerPosition, Camera playerCamera, bool usesVanillaScanNodes) { //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) preLayoutItems.Clear(); preLayoutDistanceSquares.Clear(); preLayoutWasVisible.Clear(); layoutItems.Clear(); layoutCandidates.Clear(); layoutAnchors.Clear(); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; ScrapDebugOptions debug = settings.Debug; bool shouldLogDiagnostics = debug.ShouldLogDiagnostics; int num8 = settings.Visibility.MaxVisibleLabels + 24; int index = -1; presenter.BeginFrame(); int num9 = (usesVanillaScanNodes ? visibleVanillaScanItems.Count : registry.Count); for (int i = 0; i < num9; i++) { TrackedScrapItem trackedScrapItem = (usesVanillaScanNodes ? visibleVanillaScanItems[i] : registry[i]); if (!trackedScrapItem.IsAlive) { continue; } num2++; GrabbableObject item = trackedScrapItem.Item; Vector3 val = trackedScrapItem.Transform.position - playerPosition; int num10 = (usesVanillaScanNodes ? trackedScrapItem.ScrapValue : item.scrapValue); bool flag = usesVanillaScanNodes && trackedScrapItem.HasUnknownValue; ScrapItemSnapshot val2 = CreateItemSnapshot(trackedScrapItem, flag ? 1 : num10, ((Vector3)(ref val)).sqrMagnitude); if (!(usesVanillaScanNodes ? rules.ShouldShowVanillaScanned(val2) : rules.ShouldShow(val2))) { if (shouldLogDiagnostics) { if (((ScrapItemSnapshot)(ref val2)).ScrapValue <= 0 && !debug.ShowZeroValueItems) { num3++; } else if (((ScrapItemSnapshot)(ref val2)).IsDeactivated || ((ScrapItemSnapshot)(ref val2)).IsUsedUp || ((((ScrapItemSnapshot)(ref val2)).IsHeld || ((ScrapItemSnapshot)(ref val2)).IsHeldByEnemy || ((ScrapItemSnapshot)(ref val2)).IsPocketed) && !debug.ShowHeldItems)) { num4++; } else { num5++; } } continue; } if (!usesVanillaScanNodes) { trackedScrapItem.RefreshValue(num10); } bool flag2 = presenter.IsActive(trackedScrapItem); if (preLayoutItems.Count < num8) { AddPreLayoutCandidate(trackedScrapItem, ((ScrapItemSnapshot)(ref val2)).DistanceSquaredToPlayer, flag2); if (preLayoutItems.Count == num8) { index = FindLowestPreLayoutPriorityIndex(); } continue; } num6++; ScrapLabelPreCandidate val3 = new ScrapLabelPreCandidate(trackedScrapItem.RegistrationId, ((ScrapItemSnapshot)(ref val2)).DistanceSquaredToPlayer, trackedScrapItem.ScrapValue, flag2); ScrapLabelPreCandidate val4 = CreatePreLayoutCandidate(index); if (ScrapLabelPreCandidatePriority.IsHigherPriority(val3, val4)) { ReplacePreLayoutCandidate(index, trackedScrapItem, ((ScrapItemSnapshot)(ref val2)).DistanceSquaredToPlayer, flag2); index = FindLowestPreLayoutPriorityIndex(); } } for (int j = 0; j < preLayoutItems.Count; j++) { TrackedScrapItem trackedScrapItem2 = preLayoutItems[j]; Vector3 labelAnchor = trackedScrapItem2.GetLabelAnchor(settings.HeightOffset); Vector3 val5 = playerCamera.WorldToScreenPoint(labelAnchor); if (val5.z <= 0f) { num5++; continue; } layoutItems.Add(trackedScrapItem2); layoutAnchors.Add(labelAnchor); layoutCandidates.Add(new ScrapLabelCandidate(trackedScrapItem2.RegistrationId, val5.x, val5.y, val5.z, trackedScrapItem2.ScrapValue, preLayoutWasVisible[j])); } layoutResolver.ResolveInto((IReadOnlyList)layoutCandidates, settings.Visibility.MaxVisibleLabels, layoutPlacements); for (int k = 0; k < layoutPlacements.Count; k++) { ScrapLabelPlacement placement = layoutPlacements[k]; if (!((ScrapLabelPlacement)(ref placement)).IsVisible) { num7++; continue; } Vector3 worldPosition = presenter.ResolvePlacedWorldPosition(playerCamera, layoutAnchors[k], placement); presenter.Show(layoutItems[k], worldPosition, playerCamera, settings); num++; } presenter.EndFrame(); diagnostics.LogScanIfDue(debug, playerCamera, new ScrapDiagnosticCounters { Registered = registry.Count, Alive = num2, Candidates = layoutCandidates.Count, Shown = num, HiddenNoValue = num3, HiddenState = num4, HiddenDistance = num5, HiddenBudget = num6, HiddenOverlap = num7, PoolActive = presenter.ActiveCount, PoolIdle = presenter.IdleCount, TestLabel = presenter.DebugTestLabelVisible }); } private void RefreshHighlightedVanillaScanItems(ModSettings settings, IReadOnlyList sourceItems) { //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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) ScrapHighlightOptions highlight = settings.Highlight; if (!((ScrapHighlightOptions)(ref highlight)).Enabled) { highlightPresenter.HideAll(); return; } highlightPresenter.BeginFrame(); int count = sourceItems.Count; highlight = settings.Highlight; int num; if (count >= ((ScrapHighlightOptions)(ref highlight)).MaxHighlightedItems) { highlight = settings.Highlight; num = ((ScrapHighlightOptions)(ref highlight)).MaxHighlightedItems; } else { num = sourceItems.Count; } int num2 = num; for (int i = 0; i < num2; i++) { TrackedScrapItem trackedScrapItem = sourceItems[i]; if (trackedScrapItem.IsAlive) { ScrapItemSnapshot val = CreateVanillaScanSnapshot(trackedScrapItem); if (highlightRules.ShouldShowVanillaScanned(val)) { highlightPresenter.Show(trackedScrapItem); } } } highlightPresenter.EndFrame(); } private static ScrapItemSnapshot CreateVanillaScanSnapshot(TrackedScrapItem tracked) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) return CreateItemSnapshot(tracked, tracked.HasUnknownValue ? 1 : tracked.ScrapValue, 0f); } private static ScrapItemSnapshot CreateItemSnapshot(TrackedScrapItem tracked, int scrapValue, float distanceSquaredToPlayer) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) GrabbableObject item = tracked.Item; return new ScrapItemSnapshot(scrapValue, distanceSquaredToPlayer, item.isHeld, item.isHeldByEnemy, item.deactivated, item.isPocketed, item.itemUsedUp); } private void AddPreLayoutCandidate(TrackedScrapItem tracked, float distanceSquaredToPlayer, bool wasVisible) { preLayoutItems.Add(tracked); preLayoutDistanceSquares.Add(distanceSquaredToPlayer); preLayoutWasVisible.Add(wasVisible); } private static bool TryApplyScanNodeValue(ScanNodeProperties scanNode, TrackedScrapItem tracked, out bool valueChanged) { valueChanged = false; if (ScrapScanValueText.HasUnknownValue(scanNode.subText)) { valueChanged = !tracked.HasUnknownValue; tracked.RefreshUnknownValue(); return true; } if (!TryResolveKnownScanNodeValue(scanNode, tracked, out var scrapValue)) { return false; } valueChanged = tracked.HasUnknownValue || tracked.ScrapValue != scrapValue; tracked.RefreshValue(scrapValue); return true; } private static bool TryResolveKnownScanNodeValue(ScanNodeProperties scanNode, TrackedScrapItem tracked, out int scrapValue) { scrapValue = 0; if (scanNode.scrapValue > 0) { scrapValue = scanNode.scrapValue; return true; } if (ScrapScanValueText.TryParseKnownValue(scanNode.subText, ref scrapValue)) { return true; } if (tracked.Item.scrapValue > 0) { scrapValue = tracked.Item.scrapValue; return true; } scrapValue = scanNode.scrapValue; return true; } private bool VanillaScanItemsMatch() { if (visibleVanillaScanItems.Count != incomingVanillaScanItems.Count) { return false; } for (int i = 0; i < visibleVanillaScanItems.Count; i++) { if (visibleVanillaScanItems[i] != incomingVanillaScanItems[i]) { return false; } } return true; } private void ReplacePreLayoutCandidate(int index, TrackedScrapItem tracked, float distanceSquaredToPlayer, bool wasVisible) { preLayoutItems[index] = tracked; preLayoutDistanceSquares[index] = distanceSquaredToPlayer; preLayoutWasVisible[index] = wasVisible; } private int FindLowestPreLayoutPriorityIndex() { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) int num = 0; ScrapLabelPreCandidate val = CreatePreLayoutCandidate(num); for (int i = 1; i < preLayoutItems.Count; i++) { ScrapLabelPreCandidate val2 = CreatePreLayoutCandidate(i); if (ScrapLabelPreCandidatePriority.Compare(val2, val) > 0) { num = i; val = val2; } } return num; } private ScrapLabelPreCandidate CreatePreLayoutCandidate(int index) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) TrackedScrapItem trackedScrapItem = preLayoutItems[index]; return new ScrapLabelPreCandidate(trackedScrapItem.RegistrationId, preLayoutDistanceSquares[index], trackedScrapItem.ScrapValue, preLayoutWasVisible[index]); } } } namespace Auuueser.ScanValue.Presentation { internal static class ScrapHighlightMaterialFactory { public static Material Create(ScrapHighlightStyle style) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_005f: Expected O, but got Unknown Material val = new Material(Shader.Find("HDRP/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Hidden/Internal-Colored")) { name = "ScanValue.ScanHighlight", hideFlags = (HideFlags)61, renderQueue = 3000 }; Apply(val, style); return val; } public static void Apply(Material material, ScrapHighlightStyle style) { //IL_0008: 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_002c: Unknown result type (might be due to invalid IL or missing references) material.SetColor("_Color", style.Color); material.SetColor("_BaseColor", style.Color); material.SetColor("_UnlitColor", style.Color); material.SetInt("_Cull", 1); material.SetInt("_CullMode", 1); material.SetInt("_SrcBlend", 5); material.SetInt("_DstBlend", 10); material.SetInt("_ZWrite", 0); material.SetFloat("_SurfaceType", 1f); material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); } } internal sealed class ScrapHighlightPresenter { private readonly Dictionary activeViews = new Dictionary(128); private readonly Dictionary cachedViews = new Dictionary(128); private readonly Dictionary tierMaterials = new Dictionary(6); private readonly List staleItems = new List(128); private ScrapHighlightStyle style = new ScrapHighlightStyle(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)212, (byte)71, (byte)89)), 0.035f); private Material? fallbackMaterial; private ModSettings? currentSettings; private int frameId; public int CachedCount => cachedViews.Count; public void ApplyStyle(ModSettings settings) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) currentSettings = settings; style = ScrapHighlightStyle.FromSettings(settings); if (fallbackMaterial == null) { fallbackMaterial = ScrapHighlightMaterialFactory.Create(style); } ScrapHighlightMaterialFactory.Apply(fallbackMaterial, style); foreach (KeyValuePair tierMaterial in tierMaterials) { ScrapHighlightMaterialFactory.Apply(tierMaterial.Value, CreateTierStyle(tierMaterial.Key, settings)); } foreach (KeyValuePair cachedView in cachedViews) { ScrapHighlightView value = cachedView.Value; value.ApplyStyle(style); value.ApplyMaterial(ResolveMaterial(cachedView.Key, settings)); } } public void BeginFrame() { frameId++; } public void Show(TrackedScrapItem item) { Material sharedMaterial = ((currentSettings != null) ? ResolveMaterial(item, currentSettings) : GetOrCreateFallbackMaterial()); if (!cachedViews.TryGetValue(item, out ScrapHighlightView value)) { value = ScrapHighlightView.Create(item, sharedMaterial, style); cachedViews.Add(item, value); } else { value.ApplyMaterial(sharedMaterial); } activeViews[item] = value; value.FrameTouched = frameId; value.SetVisible(value: true); } public bool Prewarm(TrackedScrapItem item, ModSettings settings) { if (item == null || !item.IsAlive) { return false; } if (cachedViews.ContainsKey(item)) { return false; } Material sharedMaterial = ResolveMaterial(item, settings); ScrapHighlightView value = ScrapHighlightView.Create(item, sharedMaterial, style); cachedViews.Add(item, value); return true; } public void EndFrame() { staleItems.Clear(); foreach (KeyValuePair activeView in activeViews) { if (activeView.Value.FrameTouched != frameId) { staleItems.Add(activeView.Key); } } for (int i = 0; i < staleItems.Count; i++) { TrackedScrapItem key = staleItems[i]; if (activeViews.TryGetValue(key, out ScrapHighlightView value)) { activeViews.Remove(key); value.SetVisible(value: false); } } } public void HideAll() { if (activeViews.Count == 0) { return; } foreach (ScrapHighlightView value in activeViews.Values) { value.SetVisible(value: false); } activeViews.Clear(); } public void Hide(TrackedScrapItem item) { if (activeViews.TryGetValue(item, out ScrapHighlightView value)) { activeViews.Remove(item); value.SetVisible(value: false); } else if (cachedViews.TryGetValue(item, out value)) { value.SetVisible(value: false); } } public void ReapplyVisibilityState(TrackedScrapItem item) { if (cachedViews.TryGetValue(item, out ScrapHighlightView value)) { value.ReapplyVisibilityState(); } } private Material ResolveMaterial(TrackedScrapItem item, ModSettings settings) { //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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ScrapValueColorOptions valueColors = settings.ValueColors; if (!((ScrapValueColorOptions)(ref valueColors)).Enabled) { return GetOrCreateFallbackMaterial(); } ScrapValueColorTier tier = ScrapValueVisualColorResolver.ResolveTier(item, settings); return GetOrCreateTierMaterial(tier, CreateTierStyle(tier, settings)); } private Material GetOrCreateFallbackMaterial() { if (fallbackMaterial == null) { fallbackMaterial = ScrapHighlightMaterialFactory.Create(style); } return fallbackMaterial; } private Material GetOrCreateTierMaterial(ScrapValueColorTier tier, ScrapHighlightStyle tierStyle) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (tierMaterials.TryGetValue(tier, out Material value)) { return value; } value = ScrapHighlightMaterialFactory.Create(tierStyle); tierMaterials.Add(tier, value); return value; } private static ScrapHighlightStyle CreateTierStyle(ScrapValueColorTier tier, ModSettings settings) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) Color color = ScrapValueVisualColorResolver.ResolveHighlightColor(tier, settings); ScrapHighlightOptions highlight = settings.Highlight; return new ScrapHighlightStyle(color, ((ScrapHighlightOptions)(ref highlight)).Width); } } internal readonly struct ScrapHighlightStyle { public Color Color { get; } public float Width { get; } public ScrapHighlightStyle(Color color, float width) { //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) Color = color; Width = width; } public static ScrapHighlightStyle FromSettings(ModSettings settings) { //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_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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Color highlightColor = settings.HighlightColor; ScrapHighlightOptions highlight = settings.Highlight; highlightColor.a = ((ScrapHighlightOptions)(ref highlight)).Alpha; Color color = highlightColor; highlight = settings.Highlight; return new ScrapHighlightStyle(color, ((ScrapHighlightOptions)(ref highlight)).Width); } } internal sealed class ScrapHighlightView { private const string ProxyName = "ScanValue.ScanHighlightProxy"; private readonly List proxyObjects = new List(8); private readonly List proxyRenderers = new List(8); private readonly List proxyMaterialSlots = new List(8); private readonly List proxyTransforms = new List(8); private Material? currentMaterial; private bool visible; public int FrameTouched { get; set; } private ScrapHighlightView() { } public static ScrapHighlightView Create(TrackedScrapItem item, Material sharedMaterial, ScrapHighlightStyle style) { ScrapHighlightView scrapHighlightView = new ScrapHighlightView(); Renderer[] renderers = item.Renderers; foreach (Renderer val in renderers) { if ((Object)(object)val == (Object)null) { continue; } MeshRenderer val2 = (MeshRenderer)(object)((val is MeshRenderer) ? val : null); if (val2 != null) { scrapHighlightView.AddMeshProxy(val2, sharedMaterial); continue; } SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); if (val3 != null) { scrapHighlightView.AddSkinnedProxy(val3, sharedMaterial); } } scrapHighlightView.ApplyStyle(style); scrapHighlightView.ApplyMaterial(sharedMaterial); scrapHighlightView.SetVisible(value: false); return scrapHighlightView; } public void ApplyStyle(ScrapHighlightStyle style) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Vector3 localScale = Vector3.one * (1f + style.Width); for (int i = 0; i < proxyTransforms.Count; i++) { Transform val = proxyTransforms[i]; if ((Object)(object)val != (Object)null) { val.localScale = localScale; } } } public void ApplyMaterial(Material sharedMaterial) { if ((Object)(object)currentMaterial == (Object)(object)sharedMaterial) { return; } currentMaterial = sharedMaterial; for (int i = 0; i < proxyRenderers.Count; i++) { Renderer val = proxyRenderers[i]; if (!((Object)(object)val == (Object)null)) { Material[] array = proxyMaterialSlots[i]; for (int j = 0; j < array.Length; j++) { array[j] = sharedMaterial; } val.sharedMaterials = array; } } } public void SetVisible(bool value) { if (!(visible && value)) { visible = value; ReapplyVisibilityState(); } } public void ReapplyVisibilityState() { for (int i = 0; i < proxyRenderers.Count; i++) { GameObject val = proxyObjects[i]; if ((Object)(object)val != (Object)null && val.activeSelf != visible) { val.SetActive(visible); } Renderer val2 = proxyRenderers[i]; if ((Object)(object)val2 != (Object)null) { val2.enabled = visible; } } } private void AddMeshProxy(MeshRenderer source, Material sharedMaterial) { MeshFilter component = ((Component)source).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) { GameObject obj = CreateProxyObject(((Component)source).transform); obj.AddComponent().sharedMesh = component.sharedMesh; MeshRenderer val = obj.AddComponent(); Material[] materialSlots = ConfigureRenderer((Renderer)(object)source, (Renderer)(object)val, sharedMaterial); AddProxy((Renderer)(object)val, materialSlots); } } private void AddSkinnedProxy(SkinnedMeshRenderer source, Material sharedMaterial) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source.sharedMesh == (Object)null)) { SkinnedMeshRenderer val = CreateProxyObject(((Component)source).transform).AddComponent(); val.sharedMesh = source.sharedMesh; val.bones = source.bones; val.rootBone = source.rootBone; ((Renderer)val).localBounds = ((Renderer)source).localBounds; val.updateWhenOffscreen = source.updateWhenOffscreen; Material[] materialSlots = ConfigureRenderer((Renderer)(object)source, (Renderer)(object)val, sharedMaterial); AddProxy((Renderer)(object)val, materialSlots); } } private static GameObject CreateProxyObject(Transform source) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown GameObject val = new GameObject("ScanValue.ScanHighlightProxy"); val.transform.SetParent(source, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.layer = ((Component)source).gameObject.layer; val.tag = "DoNotSet"; val.SetActive(false); return val; } private static Material[] ConfigureRenderer(Renderer source, Renderer target, Material sharedMaterial) { Material[] result = (target.sharedMaterials = CreateSharedMaterials(source.sharedMaterials.Length, sharedMaterial)); target.shadowCastingMode = (ShadowCastingMode)0; target.receiveShadows = false; target.enabled = false; return result; } private void AddProxy(Renderer renderer, Material[] materialSlots) { proxyObjects.Add(((Component)renderer).gameObject); proxyRenderers.Add(renderer); proxyMaterialSlots.Add(materialSlots); proxyTransforms.Add(((Component)renderer).transform); } private static Material[] CreateSharedMaterials(int count, Material sharedMaterial) { Material[] array = (Material[])(object)new Material[(count <= 0) ? 1 : count]; for (int i = 0; i < array.Length; i++) { array[i] = sharedMaterial; } return array; } } internal sealed class ScrapPriceBillboard : MonoBehaviour { private Camera? targetCamera; public void SetCamera(Camera? camera) { targetCamera = camera; } private void LateUpdate() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)targetCamera == (Object)null)) { Vector3 forward = ((Component)targetCamera).transform.forward; Vector3 up = ((Component)targetCamera).transform.up; if (!(forward == Vector3.zero) && !(up == Vector3.zero)) { ((Component)this).transform.rotation = Quaternion.LookRotation(forward, up); } } } } internal sealed class ScrapPricePresenter { private readonly Transform parent; private readonly ScrapItemNameLocalizer nameLocalizer; private readonly Dictionary activeViews = new Dictionary(128); private readonly List staleItems = new List(128); private readonly Stack pool = new Stack(128); private ScrapPriceStyle style = new ScrapPriceStyle(0.18f, 3.5f, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)212, (byte)71, byte.MaxValue)), Color32.op_Implicit(new Color32((byte)16, (byte)16, (byte)16, byte.MaxValue)), 0.25f); private ScrapPriceView? debugTestLabel; private int frameId; public int ActiveCount => activeViews.Count; public int IdleCount => pool.Count; public bool DebugTestLabelVisible => debugTestLabel != null; public ScrapPricePresenter(Transform parent, ScrapItemNameLocalizer nameLocalizer) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) this.parent = parent; this.nameLocalizer = nameLocalizer; } public void ApplyStyle(ModSettings settings) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) style = ScrapPriceStyle.FromSettings(settings); foreach (KeyValuePair activeView in activeViews) { ScrapPriceView value = activeView.Value; value.ApplyStyle(style); value.ApplyValueColor(ScrapValueVisualColorResolver.ResolveLabelColor(activeView.Key, settings)); } foreach (ScrapPriceView item in pool) { item.ApplyStyle(style); item.ApplyValueColor(style.LabelColor); } if (debugTestLabel != null) { debugTestLabel.ApplyStyle(style); debugTestLabel.ApplyValueColor(style.LabelColor); } } public void BeginFrame() { frameId++; } public bool IsActive(TrackedScrapItem item) { return activeViews.ContainsKey(item); } public void Show(TrackedScrapItem item, Vector3 worldPosition, Camera camera, ModSettings settings) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (!activeViews.TryGetValue(item, out ScrapPriceView value)) { value = Rent(); activeViews.Add(item, value); } value.FrameTouched = frameId; value.ApplyValueColor(ScrapValueVisualColorResolver.ResolveLabelColor(item, settings)); string itemName = nameLocalizer.ResolveDisplayName(item, settings); if (item.ValueTextOverride != null) { value.SetNameAndValue(itemName, item.ValueTextOverride); } else { value.SetNameAndValue(itemName, item.ScrapValue); } value.SetWorldPosition(worldPosition, camera); value.SetVisible(visible: true); } public void ShowDebugTestLabel(Camera camera) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (debugTestLabel == null) { debugTestLabel = Rent(); } Vector3 worldPosition = ((Component)camera).transform.position + ((Component)camera).transform.forward * 2.25f - ((Component)camera).transform.up * 0.35f; debugTestLabel.FrameTouched = frameId; debugTestLabel.ApplyValueColor(style.LabelColor); debugTestLabel.SetText("$TEST"); debugTestLabel.SetWorldPosition(worldPosition, camera); debugTestLabel.SetVisible(visible: true); } public void HideDebugTestLabel() { if (debugTestLabel != null) { Return(debugTestLabel); debugTestLabel = null; } } public Vector3 ResolvePlacedWorldPosition(Camera camera, Vector3 anchor, ScrapLabelPlacement placement) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Vector3 val = camera.WorldToScreenPoint(anchor); return camera.ScreenToWorldPoint(new Vector3(((ScrapLabelPlacement)(ref placement)).ScreenX, ((ScrapLabelPlacement)(ref placement)).ScreenY, val.z)); } public void EndFrame() { staleItems.Clear(); foreach (KeyValuePair activeView in activeViews) { if (activeView.Value.FrameTouched != frameId) { staleItems.Add(activeView.Key); } } for (int i = 0; i < staleItems.Count; i++) { TrackedScrapItem key = staleItems[i]; ScrapPriceView view = activeViews[key]; activeViews.Remove(key); Return(view); } } public void HideAll() { HideDebugTestLabel(); HideScrapLabels(); } public void HideScrapLabels() { if (activeViews.Count == 0) { return; } staleItems.Clear(); foreach (TrackedScrapItem key2 in activeViews.Keys) { staleItems.Add(key2); } for (int i = 0; i < staleItems.Count; i++) { TrackedScrapItem key = staleItems[i]; ScrapPriceView view = activeViews[key]; activeViews.Remove(key); Return(view); } } public void Prewarm(int targetCount, int maxCreatedCount) { if (targetCount <= 0 || maxCreatedCount <= 0) { return; } for (int i = 0; i < maxCreatedCount; i++) { if (pool.Count >= targetCount) { break; } ScrapPriceView scrapPriceView = ScrapPriceView.Create(parent, style); scrapPriceView.SetVisible(visible: false); pool.Push(scrapPriceView); } } private ScrapPriceView Rent() { if (pool.Count > 0) { return pool.Pop(); } return ScrapPriceView.Create(parent, style); } private void Return(ScrapPriceView view) { view.SetVisible(visible: false); pool.Push(view); } } internal sealed class ScrapPriceStyle { public float WorldScale { get; } public float FontSize { get; } public Color LabelColor { get; } public Color OutlineColor { get; } public float OutlineWidth { get; } public ScrapPriceStyle(float worldScale, float fontSize, Color labelColor, Color outlineColor, float outlineWidth) { //IL_0015: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) WorldScale = worldScale; FontSize = fontSize; LabelColor = labelColor; OutlineColor = outlineColor; OutlineWidth = outlineWidth; } public static ScrapPriceStyle FromSettings(ModSettings settings) { //IL_000d: 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) return new ScrapPriceStyle(settings.WorldScale, settings.FontSize, settings.LabelColor, settings.OutlineColor, settings.OutlineWidth); } } internal sealed class ScrapPriceView { private const float PriceOnlyWidth = 240f; private const float PriceOnlyHeight = 72f; private const float NamedWidth = 300f; private const float NamedHeight = 112f; private const float WorldScaleMultiplier = 0.02f; private const float FontSizeMultiplier = 12f; private const float NameFontSizeMultiplier = 4.8f; private static readonly Vector3 ParkedWorldPosition = new Vector3(0f, -10000f, 0f); private static TMP_FontAsset? resolvedDefaultTextFont; private static TMP_FontAsset? resolvedChineseFallbackFont; private static bool defaultTextFontResolved; private static bool chineseFallbackFontResolved; private readonly GameObject gameObject; private readonly RectTransform root; private readonly RectTransform nameRect; private readonly RectTransform valueRect; private readonly TextMeshProUGUI nameText; private readonly TextMeshProUGUI valueText; private readonly TextMeshProUGUI anchorMarker; private readonly Canvas worldCanvas; private readonly ScrapPriceBillboard billboard; private Camera? lastAppliedCanvasCamera; private string? lastNameText; private string? lastValueText; private int lastValueNumber; private bool lastValueWasNumeric; private bool lastHasName; private bool layoutApplied; private Color lastValueColor; private bool valueColorApplied; private bool visible; private ScrapPriceStyle currentStyle; public int FrameTouched { get; set; } private ScrapPriceView(GameObject gameObject, RectTransform root, RectTransform nameRect, RectTransform valueRect, TextMeshProUGUI nameText, TextMeshProUGUI valueText, TextMeshProUGUI anchorMarker, Canvas worldCanvas, ScrapPriceBillboard billboard) { this.gameObject = gameObject; this.root = root; this.nameRect = nameRect; this.valueRect = valueRect; this.nameText = nameText; this.valueText = valueText; this.anchorMarker = anchorMarker; this.worldCanvas = worldCanvas; this.billboard = billboard; } public static ScrapPriceView Create(Transform parent, ScrapPriceStyle style) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00a4: Expected O, but got Unknown //IL_00a4: Expected O, but got Unknown GameObject val = new GameObject("ScrapValueLabel"); val.transform.SetParent(parent, false); ScrapPriceBillboard scrapPriceBillboard = val.AddComponent(); RectTransform parent2 = val.AddComponent(); Canvas val2 = val.AddComponent(); val2.renderMode = (RenderMode)2; val2.overrideSorting = true; val2.sortingOrder = 600; val.AddComponent(); TextMeshProUGUI val3 = CreateText((Transform)(object)parent2, "NameText", useChineseFallback: true); TextMeshProUGUI val4 = CreateText((Transform)(object)parent2, "PriceText", useChineseFallback: false); TextMeshProUGUI val5 = CreateAnchorMarker((Transform)(object)parent2); SetLayerRecursively(val, ((Component)parent).gameObject.layer); ScrapPriceView scrapPriceView = new ScrapPriceView(val, parent2, (RectTransform)((TMP_Text)val3).transform, (RectTransform)((TMP_Text)val4).transform, val3, val4, val5, val2, scrapPriceBillboard); scrapPriceView.ApplyStyle(style); scrapPriceView.SetVisible(visible: false); return scrapPriceView; } private static TextMeshProUGUI CreateText(Transform parent, string objectName, bool useChineseFallback) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; val.AddComponent(); TextMeshProUGUI obj2 = val.AddComponent(); ((TMP_Text)obj2).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj2).enableWordWrapping = false; ((TMP_Text)obj2).richText = false; ((Graphic)obj2).raycastTarget = false; ((TMP_Text)obj2).overflowMode = (TextOverflowModes)0; ((TMP_Text)obj2).enableAutoSizing = true; ((TMP_Text)obj2).fontStyle = (FontStyles)1; ApplyTextFont(obj2, useChineseFallback); return obj2; } private static TextMeshProUGUI CreateAnchorMarker(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0070: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("AnchorMarker"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.sizeDelta = new Vector2(28f, 18f); obj.anchoredPosition = new Vector2(0f, -4f); val.AddComponent(); TextMeshProUGUI obj2 = val.AddComponent(); ((Object)obj2).name = "AnchorMarker"; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj2).enableWordWrapping = false; ((TMP_Text)obj2).richText = false; ((Graphic)obj2).raycastTarget = false; ((TMP_Text)obj2).text = "v"; ApplyTextFont(obj2, useChineseFallback: false); return obj2; } public void ApplyStyle(ScrapPriceStyle style) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) currentStyle = style; ((Transform)root).localScale = Vector3.one * (style.WorldScale * 0.02f); float num = style.FontSize * 12f; ((TMP_Text)valueText).fontSize = num; ((TMP_Text)valueText).fontSizeMin = Mathf.Max(8f, num * 0.55f); ((TMP_Text)valueText).fontSizeMax = num; ((TMP_Text)valueText).outlineColor = Color32.op_Implicit(style.OutlineColor); ((TMP_Text)valueText).outlineWidth = style.OutlineWidth; float num2 = style.FontSize * 4.8f; ((TMP_Text)nameText).fontSize = num2; ((TMP_Text)nameText).fontSizeMin = Mathf.Max(7f, num2 * 0.55f); ((TMP_Text)nameText).fontSizeMax = num2; ((TMP_Text)nameText).outlineColor = Color32.op_Implicit(style.OutlineColor); ((TMP_Text)nameText).outlineWidth = style.OutlineWidth; ((TMP_Text)anchorMarker).fontSize = style.FontSize * 5f; ((TMP_Text)anchorMarker).outlineColor = Color32.op_Implicit(style.OutlineColor); ((TMP_Text)anchorMarker).outlineWidth = style.OutlineWidth; ApplyValueColor(style.LabelColor, force: true); ApplyTextLayout(lastHasName); } public void ApplyValueColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ApplyValueColor(color, force: false); } private static void ApplyTextFont(TextMeshProUGUI text, bool useChineseFallback) { TMP_FontAsset val = (useChineseFallback ? (ResolveChineseFallbackFont() ?? ResolveDefaultTextFont()) : ResolveDefaultTextFont()); if ((Object)(object)val != (Object)null) { ((TMP_Text)text).font = val; } } private static TMP_FontAsset? ResolveDefaultTextFont() { if (defaultTextFontResolved) { return resolvedDefaultTextFont; } defaultTextFontResolved = true; resolvedDefaultTextFont = TMP_Settings.defaultFontAsset; if ((Object)(object)resolvedDefaultTextFont != (Object)null) { return resolvedDefaultTextFont; } Font builtinResource = Resources.GetBuiltinResource("Arial.ttf"); if ((Object)(object)builtinResource != (Object)null) { resolvedDefaultTextFont = TMP_FontAsset.CreateFontAsset(builtinResource); } return resolvedDefaultTextFont; } private static TMP_FontAsset? ResolveChineseFallbackFont() { if (chineseFallbackFontResolved) { return resolvedChineseFallbackFont; } chineseFallbackFontResolved = true; List fallbackFontAssets = TMP_Settings.fallbackFontAssets; if (fallbackFontAssets == null) { return null; } for (int i = 0; i < fallbackFontAssets.Count; i++) { TMP_FontAsset val = fallbackFontAssets[i]; string text = (((Object)(object)val != (Object)null) ? ((Object)val).name : string.Empty); if (text.IndexOf("V81TestChn", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("zh-cn", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("tmp-font", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("NotoSansSC", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("SourceHan", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Chinese", StringComparison.OrdinalIgnoreCase) >= 0) { resolvedChineseFallbackFont = val; return resolvedChineseFallbackFont; } } return resolvedChineseFallbackFont; } public void SetValue(int value) { SetNameAndValue(null, value); } public void SetNameAndValue(string? itemName, int value) { bool flag = !string.IsNullOrWhiteSpace(itemName); ApplyTextLayout(flag); SetNameText(flag ? itemName : null); SetValueText(value); } public void SetNameAndValue(string? itemName, string value) { bool flag = !string.IsNullOrWhiteSpace(itemName); ApplyTextLayout(flag); SetNameText(flag ? itemName : null); lastValueWasNumeric = false; SetValueText(value); } public void SetText(string value) { ApplyTextLayout(hasName: false); SetNameText(null); lastValueWasNumeric = false; SetValueText(value); } public void SetWorldPosition(Vector3 worldPosition, Camera camera) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ((Transform)root).position = worldPosition; ApplyCanvasCamera(camera); } public void SetVisible(bool visible) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (this.visible != visible || !gameObject.activeSelf || (!visible && !(((Transform)root).position == ParkedWorldPosition))) { this.visible = visible; if (!gameObject.activeSelf) { gameObject.SetActive(true); } ((Behaviour)billboard).enabled = visible; if (!visible) { billboard.SetCamera(null); ((Transform)root).position = ParkedWorldPosition; } } } private void ApplyTextLayout(bool hasName) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) if (currentStyle != null && (!layoutApplied || lastHasName != hasName)) { layoutApplied = true; lastHasName = hasName; root.sizeDelta = (hasName ? new Vector2(300f, 112f) : new Vector2(240f, 72f)); ((Component)nameText).gameObject.SetActive(hasName); if (hasName) { nameRect.anchorMin = new Vector2(0f, 0.56f); nameRect.anchorMax = new Vector2(1f, 1f); nameRect.offsetMin = Vector2.zero; nameRect.offsetMax = Vector2.zero; valueRect.anchorMin = new Vector2(0f, 0.04f); valueRect.anchorMax = new Vector2(1f, 0.7f); } else { valueRect.anchorMin = Vector2.zero; valueRect.anchorMax = Vector2.one; } valueRect.offsetMin = Vector2.zero; valueRect.offsetMax = Vector2.zero; } } private void SetNameText(string? value) { if (!(lastNameText == value)) { lastNameText = value; ((TMP_Text)nameText).text = value ?? string.Empty; } } private void SetValueText(int value) { if (!lastValueWasNumeric || lastValueNumber != value) { lastValueWasNumeric = true; lastValueNumber = value; SetValueText(ScrapPriceText.Format(value)); } } private void SetValueText(string value) { if (!(lastValueText == value)) { lastValueText = value; ((TMP_Text)valueText).text = value; } } private void ApplyValueColor(Color color, bool force) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (force || !valueColorApplied || !(lastValueColor == color)) { valueColorApplied = true; lastValueColor = color; ((Graphic)valueText).color = color; ((Graphic)nameText).color = color; ((Graphic)anchorMarker).color = color; } } private void ApplyCanvasCamera(Camera camera) { billboard.SetCamera(camera); if (!((Object)(object)lastAppliedCanvasCamera == (Object)(object)camera) || !((Object)(object)worldCanvas.worldCamera == (Object)(object)camera)) { worldCanvas.worldCamera = camera; lastAppliedCanvasCamera = camera; } } private static void SetLayerRecursively(GameObject target, int layer) { target.layer = layer; Transform transform = target.transform; for (int i = 0; i < transform.childCount; i++) { SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer); } } } internal static class ScrapValueVisualColorResolver { public static Color ResolveLabelColor(TrackedScrapItem item, ModSettings settings) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Color result = ResolveBaseColor(item, settings, settings.LabelColor); result.a = settings.LabelColor.a; return result; } public static Color ResolveHighlightColor(TrackedScrapItem item, ModSettings settings) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Color result = ResolveBaseColor(item, settings, settings.HighlightColor); ScrapHighlightOptions highlight = settings.Highlight; result.a = ((ScrapHighlightOptions)(ref highlight)).Alpha; return result; } public static Color ResolveHighlightColor(ScrapValueColorTier tier, ModSettings settings) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Color result = ResolveBaseColor(tier, settings, settings.HighlightColor); ScrapHighlightOptions highlight = settings.Highlight; result.a = ((ScrapHighlightOptions)(ref highlight)).Alpha; return result; } public static ScrapValueColorTier ResolveTier(TrackedScrapItem item, ModSettings settings) { //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_0015: Unknown result type (might be due to invalid IL or missing references) ScrapValueColorOptions valueColors = settings.ValueColors; return ((ScrapValueColorOptions)(ref valueColors)).ResolveTier(item.HasUnknownValue, item.ScrapValue); } private static Color ResolveBaseColor(TrackedScrapItem item, ModSettings settings, Color fallback) { //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_0014: 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_001b: 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) ScrapValueColorOptions valueColors = settings.ValueColors; if (!((ScrapValueColorOptions)(ref valueColors)).Enabled) { return fallback; } return ResolveBaseColor(ResolveTier(item, settings), settings, fallback); } private static Color ResolveBaseColor(ScrapValueColorTier tier, ModSettings settings, Color fallback) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected I4, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0069: Unknown result type (might be due to invalid IL or missing references) ScrapValueColorOptions valueColors = settings.ValueColors; if (!((ScrapValueColorOptions)(ref valueColors)).Enabled) { return fallback; } return (Color)((int)tier switch { 0 => settings.UnknownValueColor, 1 => settings.LowValueColor, 2 => settings.MediumValueColor, 3 => settings.HighValueColor, 4 => settings.VeryHighValueColor, 5 => settings.JackpotValueColor, _ => fallback, }); } } } namespace Auuueser.ScanValue.Localization { internal static class ChineseProjectResourceLocator { public static IReadOnlyList FindDictionaryFiles(ManualLogSource logger) { List result = new List(8); foreach (string item in FindChineseProjectPluginDirectories(logger)) { AddIfActive(result, Path.Combine(item, "V81TestChn", "translations-clean", "zh-CN.runtime.json")); AddIfActive(result, Path.Combine(item, "translations-clean", "zh-CN.runtime.json")); AddCfgDirectory(result, Path.Combine(item, "V81TestChn", "translations-clean", "cfg", "zh-CN")); AddCfgDirectory(result, Path.Combine(item, "translations-clean", "cfg", "zh-CN")); AddCfgDirectory(result, Path.Combine(item, "V81TestChn", "translations-clean", "split", "cfg", "zh-CN")); AddCfgDirectory(result, Path.Combine(item, "translations-clean", "split", "cfg", "zh-CN")); } return result; } private static IEnumerable FindChineseProjectPluginDirectories(ManualLogSource logger) { foreach (KeyValuePair pluginInfo in Chainloader.PluginInfos) { PluginInfo value = pluginInfo.Value; if (((value != null) ? value.Metadata : null) != null && ChineseProjectDetection.IsChineseProjectPlugin(value.Metadata.GUID, value.Metadata.Name, value.Location)) { string directoryName = Path.GetDirectoryName(value.Location); if (!string.IsNullOrEmpty(directoryName)) { yield return directoryName; } } } foreach (string item in FindChineseProjectManifestPaths(logger)) { string directoryName2 = Path.GetDirectoryName(item); if (!string.IsNullOrEmpty(directoryName2)) { yield return directoryName2; } } } private static IEnumerable FindChineseProjectManifestPaths(ManualLogSource logger) { if (!Directory.Exists(Paths.PluginPath)) { yield break; } IEnumerable enumerable; try { enumerable = Directory.EnumerateFiles(Paths.PluginPath, "manifest.json", SearchOption.AllDirectories); } catch (Exception ex) { logger.LogWarning((object)("Could not inspect plugin manifests for item-name dictionaries: " + ex.Message)); yield break; } foreach (string item in enumerable) { string text; try { text = File.ReadAllText(item); } catch { continue; } if (ChineseProjectDetection.ContainsChineseProjectManifestText(text)) { yield return item; } } } private static void AddCfgDirectory(List result, string directory) { if (!Directory.Exists(directory)) { return; } foreach (string item in Directory.EnumerateFiles(directory, "*.cfg", SearchOption.TopDirectoryOnly)) { AddIfActive(result, item); } } private static void AddIfActive(List result, string path) { if (File.Exists(path) && ScrapNameDictionaryFiles.IsActiveDictionaryFile(path) && !result.Contains(path)) { result.Add(path); } } } internal sealed class ScrapItemNameLocalizer { private readonly ManualLogSource logger; private readonly ScrapNameTranslationMap translations = new ScrapNameTranslationMap(); private readonly bool chineseProjectDetected; public bool HasChineseDictionary => translations.HasEntries; private ScrapItemNameLocalizer(ManualLogSource logger, bool chineseProjectDetected) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown this.logger = logger; this.chineseProjectDetected = chineseProjectDetected; } public static ScrapItemNameLocalizer Load(ManualLogSource logger) { IReadOnlyList readOnlyList = ChineseProjectResourceLocator.FindDictionaryFiles(logger); ScrapItemNameLocalizer scrapItemNameLocalizer = new ScrapItemNameLocalizer(logger, readOnlyList.Count > 0); for (int i = 0; i < readOnlyList.Count; i++) { scrapItemNameLocalizer.LoadFile(readOnlyList[i]); } if (scrapItemNameLocalizer.translations.HasEntries) { logger.LogInfo((object)$"ScanValue loaded {scrapItemNameLocalizer.translations.Count} item-name translations from {readOnlyList.Count} active LC Chinese Project resource(s)."); } return scrapItemNameLocalizer; } public ScrapItemResolvedNames ResolveNames(string currentItemName) { if (string.IsNullOrWhiteSpace(currentItemName)) { return new ScrapItemResolvedNames(string.Empty, string.Empty); } string text = translations.ToEnglish(currentItemName); string text2 = translations.ToChinese(text); if (string.Equals(text2, text, StringComparison.Ordinal)) { text2 = translations.ToChinese(currentItemName); } return new ScrapItemResolvedNames(text, text2); } public string? ResolveDisplayName(TrackedScrapItem item, ModSettings settings) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 ScrapItemNameOptions itemNames = settings.ItemNames; if (!((ScrapItemNameOptions)(ref itemNames)).ShowItemNames) { return null; } itemNames = settings.ItemNames; ScrapItemNameLanguage language = ((ScrapItemNameOptions)(ref itemNames)).Language; if ((int)language != 1) { if ((int)language == 2) { return NonEmptyOrFallback(item.EnglishName, item.ChineseName); } return ShouldUseChinese() ? NonEmptyOrFallback(item.ChineseName, item.EnglishName) : NonEmptyOrFallback(item.EnglishName, item.ChineseName); } return NonEmptyOrFallback(item.ChineseName, item.EnglishName); } private bool ShouldUseChinese() { if (chineseProjectDetected) { return translations.HasEntries; } return false; } private void LoadFile(string path) { try { string text = File.ReadAllText(path); if (string.Equals(Path.GetFileName(path), "zh-CN.runtime.json", StringComparison.OrdinalIgnoreCase)) { ScrapNameDictionaryParser.AddRuntimeJson(translations, text); } else { ScrapNameDictionaryParser.AddCfg(translations, text); } } catch (Exception ex) { logger.LogWarning((object)("ScanValue could not load item-name dictionary '" + path + "': " + ex.Message)); } } private static string? NonEmptyOrFallback(string primary, string fallback) { if (!string.IsNullOrWhiteSpace(primary)) { return primary; } if (!string.IsNullOrWhiteSpace(fallback)) { return fallback; } return null; } } internal readonly struct ScrapItemResolvedNames { public string EnglishName { get; } public string ChineseName { get; } public ScrapItemResolvedNames(string englishName, string chineseName) { EnglishName = englishName; ChineseName = chineseName; } } } namespace Auuueser.ScanValue.Game { internal sealed class LocalPlayerProvider { public bool TryGet(out Vector3 playerPosition, out Camera playerCamera, out string failureReason) { //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_003f: 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_00af: Unknown result type (might be due to invalid IL or missing references) playerPosition = Vector3.zero; playerCamera = null; failureReason = string.Empty; PlayerControllerB val = ResolveLocalPlayer(); if ((Object)(object)val == (Object)null) { failureReason = "No local player"; return false; } StartOfRound instance = StartOfRound.Instance; if (TryUseCamera(val.gameplayCamera, ((Component)val).transform.position, out playerPosition, out playerCamera)) { return true; } if ((Object)(object)instance != (Object)null && (Object)(object)instance.activeCamera != (Object)null && TryUseCamera(instance.activeCamera, ((Component)instance.activeCamera).transform.position, out playerPosition, out playerCamera)) { return true; } if ((Object)(object)instance != (Object)null && (Object)(object)instance.spectateCamera != (Object)null && TryUseCamera(instance.spectateCamera, ((Component)instance.spectateCamera).transform.position, out playerPosition, out playerCamera)) { return true; } failureReason = "No usable camera"; return false; } private static PlayerControllerB? ResolveLocalPlayer() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.localPlayerController != (Object)null) { return instance.localPlayerController; } HUDManager instance2 = HUDManager.Instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.localPlayer != (Object)null) { return instance2.localPlayer; } GameNetworkManager instance3 = GameNetworkManager.Instance; if (!((Object)(object)instance3 != (Object)null)) { return null; } return instance3.localPlayerController; } private static bool TryUseCamera(Camera? camera, Vector3 distanceCenter, out Vector3 playerPosition, out Camera playerCamera) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)camera != (Object)null && ((Behaviour)camera).isActiveAndEnabled) { playerPosition = distanceCenter; playerCamera = camera; return true; } playerPosition = Vector3.zero; playerCamera = null; return false; } } internal static class ScrapObjectHooks { private static ScrapObjectRegistry? registry; private static ManualLogSource? logger; private static Action? meshVisibilityReapplier; public static void Initialize(ScrapObjectRegistry activeRegistry, ManualLogSource activeLogger, Action activeMeshVisibilityReapplier) { registry = activeRegistry; logger = activeLogger; meshVisibilityReapplier = activeMeshVisibilityReapplier; } public static void Clear(ScrapObjectRegistry activeRegistry) { if (registry == activeRegistry) { registry = null; logger = null; meshVisibilityReapplier = null; } } public static void AfterGrabbableStart(GrabbableObject __instance) { registry?.Register(__instance); } public static void BeforeGrabbableDestroy(GrabbableObject __instance) { registry?.Unregister(__instance); } public static void AfterSetScrapValue(GrabbableObject __instance) { registry?.RefreshValue(__instance); } public static void AfterDestroyObjectInHand(GrabbableObject __instance) { registry?.Unregister(__instance); } public static void AfterEnableItemMeshes(GrabbableObject __instance) { meshVisibilityReapplier?.Invoke(__instance); } public static void LogPatchFailure(string methodName) { ManualLogSource? obj = logger; if (obj != null) { obj.LogWarning((object)("Could not patch GrabbableObject." + methodName + "; scrap value labels may miss late-spawned items.")); } } } internal sealed class ScrapObjectMarker : MonoBehaviour { public ScrapObjectRegistry? Registry { get; private set; } public TrackedScrapItem? TrackedItem { get; private set; } public void Initialize(ScrapObjectRegistry registry, TrackedScrapItem trackedItem) { Registry = registry; TrackedItem = trackedItem; } public void ClearRegistration() { Registry = null; TrackedItem = null; } private void OnDestroy() { Registry?.UnregisterMarker(this); } } internal sealed class ScrapObjectPatcher : IDisposable { private readonly Harmony harmony; private readonly ScrapObjectRegistry registry; private readonly ManualLogSource logger; private int patchedCount; private bool disposed; public ScrapObjectPatcher(ScrapObjectRegistry registry, ManualLogSource logger, Action meshVisibilityReapplier) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown this.registry = registry; this.logger = logger; harmony = new Harmony("com.auuueser.lethalcompany.scanvalue"); ScrapObjectHooks.Initialize(registry, logger, meshVisibilityReapplier); Patch("Start", null, "AfterGrabbableStart"); Patch("OnDestroy", "BeforeGrabbableDestroy"); Patch("SetScrapValue", null, "AfterSetScrapValue"); Patch("DestroyObjectInHand", null, "AfterDestroyObjectInHand"); Patch("EnableItemMeshes", null, "AfterEnableItemMeshes"); this.logger.LogInfo((object)$"ScanValue patched {patchedCount} GrabbableObject methods."); } public void Dispose() { if (!disposed) { disposed = true; harmony.UnpatchSelf(); ScrapObjectHooks.Clear(registry); } } private void Patch(string originalName, string? prefixName = null, string? postfixName = null) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(GrabbableObject), originalName, (Type[])null, (Type[])null); if (methodInfo == null) { ScrapObjectHooks.LogPatchFailure(originalName); return; } HarmonyMethod val = CreateHarmonyMethod(prefixName); HarmonyMethod val2 = CreateHarmonyMethod(postfixName); harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); patchedCount++; } private static HarmonyMethod? CreateHarmonyMethod(string? methodName) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if (methodName == null) { return null; } MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ScrapObjectHooks), methodName, (Type[])null, (Type[])null); if (!(methodInfo == null)) { return new HarmonyMethod(methodInfo); } return null; } } internal sealed class ScrapObjectRegistry { private readonly ManualLogSource logger; private readonly ScrapItemNameLocalizer nameLocalizer; private readonly List items = new List(256); private readonly Dictionary scanNodeLookup = new Dictionary(256); private bool debugRegistrations; private bool debugTrackZeroValueItems; private int nextRegistrationId; public int Count => items.Count; public TrackedScrapItem this[int index] => items[index]; public ScrapObjectRegistry(ManualLogSource logger, ScrapItemNameLocalizer nameLocalizer) { this.logger = logger; this.nameLocalizer = nameLocalizer; } public void SetDebugOptions(bool logRegistrations, bool trackZeroValueItems) { debugRegistrations = logRegistrations; debugTrackZeroValueItems = trackZeroValueItems; } public void Register(GrabbableObject item) { if (!ShouldTrack(item)) { return; } ScrapObjectMarker component = ((Component)item).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.Registry == this && component.TrackedItem != null) { component.TrackedItem.RefreshValue(item.scrapValue); UpdateScanNode(component.TrackedItem, FindScanNode(item)); component.TrackedItem.RefreshNames(nameLocalizer.ResolveNames(GetItemName(item))); return; } component = ((Component)item).gameObject.AddComponent(); ScanNodeProperties scanNode = FindScanNode(item); TrackedScrapItem trackedScrapItem = new TrackedScrapItem(item, ((Component)item).transform, item.scrapValue, scanNode, FindRenderers(item), component, items.Count, nextRegistrationId++, nameLocalizer.ResolveNames(GetItemName(item))); component.Initialize(this, trackedScrapItem); items.Add(trackedScrapItem); AddScanNodeLookup(trackedScrapItem); if (debugRegistrations) { logger.LogInfo((object)$"ScanValue registered '{item.itemProperties.itemName}' value={item.scrapValue} count={items.Count}."); } } public void RefreshValue(GrabbableObject item) { if ((Object)(object)item == (Object)null) { return; } ScrapObjectMarker component = ((Component)item).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.Registry == this && component.TrackedItem != null) { if (!ShouldTrack(item)) { UnregisterMarker(component); return; } component.TrackedItem.RefreshValue(item.scrapValue); UpdateScanNode(component.TrackedItem, FindScanNode(item)); component.TrackedItem.RefreshNames(nameLocalizer.ResolveNames(GetItemName(item))); } else { Register(item); } } public void Unregister(GrabbableObject item) { if (!((Object)(object)item == (Object)null)) { ScrapObjectMarker component = ((Component)item).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { UnregisterMarker(component); } } } public void UnregisterMarker(ScrapObjectMarker marker) { if (marker.Registry == this && marker.TrackedItem != null) { RemoveAt(marker.TrackedItem.Index); marker.ClearRegistration(); } } public void Clear() { for (int num = items.Count - 1; num >= 0; num--) { items[num].Marker.ClearRegistration(); } items.Clear(); scanNodeLookup.Clear(); } public bool TryGetByScanNode(ScanNodeProperties? scanNode, out TrackedScrapItem tracked) { if ((Object)(object)scanNode != (Object)null && scanNodeLookup.TryGetValue(scanNode, out tracked)) { return true; } tracked = null; return false; } public bool TryGet(GrabbableObject item, out TrackedScrapItem tracked) { if ((Object)(object)item != (Object)null) { ScrapObjectMarker component = ((Component)item).gameObject.GetComponent(); if ((Object)(object)component != (Object)null && component.Registry == this && component.TrackedItem != null) { tracked = component.TrackedItem; return true; } } tracked = null; return false; } private bool ShouldTrack(GrabbableObject item) { if ((Object)(object)item == (Object)null || (Object)(object)item.itemProperties == (Object)null) { return false; } if (!item.itemProperties.isScrap && item.scrapValue <= 0) { return debugTrackZeroValueItems; } return true; } private static string GetItemName(GrabbableObject item) { string text = (((Object)(object)item.itemProperties != (Object)null) ? item.itemProperties.itemName : null); if (!string.IsNullOrWhiteSpace(text)) { return text; } return ((Object)item).name; } private static ScanNodeProperties? FindScanNode(GrabbableObject item) { return ((Component)item).GetComponentInChildren(true); } private static Renderer[] FindRenderers(GrabbableObject item) { if (!((Object)(object)item != (Object)null)) { return Array.Empty(); } return ((Component)item).GetComponentsInChildren(true); } private void UpdateScanNode(TrackedScrapItem tracked, ScanNodeProperties? scanNode) { if (!((Object)(object)tracked.ScanNode == (Object)(object)scanNode)) { RemoveScanNodeLookup(tracked); tracked.RefreshScanNode(scanNode); AddScanNodeLookup(tracked); } } private void AddScanNodeLookup(TrackedScrapItem tracked) { if ((Object)(object)tracked.ScanNode != (Object)null) { scanNodeLookup[tracked.ScanNode] = tracked; } } private void RemoveScanNodeLookup(TrackedScrapItem tracked) { if (!((Object)(object)tracked.ScanNode == (Object)null) && scanNodeLookup.TryGetValue(tracked.ScanNode, out TrackedScrapItem value) && value == tracked) { scanNodeLookup.Remove(tracked.ScanNode); } } private void RemoveAt(int index) { if (index < 0 || index >= items.Count) { logger.LogDebug((object)$"Ignoring stale scrap registry index {index}."); return; } int num = items.Count - 1; RemoveScanNodeLookup(items[index]); if (index != num) { TrackedScrapItem trackedScrapItem = items[num]; trackedScrapItem.Index = index; items[index] = trackedScrapItem; } items.RemoveAt(num); } } internal sealed class TrackedScrapItem { private const float MinimumRendererTopClearance = 0.18f; private const float MaximumRendererTopClearance = 0.35f; public GrabbableObject Item { get; } public Transform Transform { get; } public int ScrapValue { get; private set; } public string? ValueTextOverride { get; private set; } public bool HasUnknownValue => ValueTextOverride != null; public ScanNodeProperties? ScanNode { get; private set; } public Renderer[] Renderers { get; } public ScrapObjectMarker Marker { get; } public int Index { get; set; } public int RegistrationId { get; } public string EnglishName { get; private set; } public string ChineseName { get; private set; } public bool IsAlive { get { if ((Object)(object)Item != (Object)null) { return (Object)(object)Transform != (Object)null; } return false; } } public TrackedScrapItem(GrabbableObject item, Transform transform, int scrapValue, ScanNodeProperties? scanNode, Renderer[] renderers, ScrapObjectMarker marker, int index, int registrationId, ScrapItemResolvedNames names) { Item = item; Transform = transform; ScrapValue = scrapValue; ScanNode = scanNode; Renderers = renderers; Marker = marker; Index = index; RegistrationId = registrationId; EnglishName = names.EnglishName; ChineseName = names.ChineseName; } public Vector3 GetLabelAnchor(float heightOffset) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Transform.position + Vector3.up * heightOffset; if (!TryGetRendererBounds(out var combinedBounds)) { return val; } float num = Mathf.Clamp(heightOffset * 0.25f, 0.18f, 0.35f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(((Bounds)(ref combinedBounds)).center.x, ((Bounds)(ref combinedBounds)).max.y + num, ((Bounds)(ref combinedBounds)).center.z); if (!(val2.y > val.y)) { return val; } return val2; } public void RefreshValue(int value) { ScrapValue = value; ValueTextOverride = null; } public void RefreshUnknownValue() { ScrapValue = 0; ValueTextOverride = "???"; } public void RefreshScanNode(ScanNodeProperties? scanNode) { ScanNode = scanNode; } public void RefreshNames(ScrapItemResolvedNames names) { EnglishName = names.EnglishName; ChineseName = names.ChineseName; } private bool TryGetRendererBounds(out Bounds combinedBounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) combinedBounds = default(Bounds); bool flag = false; for (int i = 0; i < Renderers.Length; i++) { Renderer val = Renderers[i]; if ((Object)(object)val == (Object)null || !val.enabled || !((Component)val).gameObject.activeInHierarchy) { continue; } Bounds bounds = val.bounds; if (!IsFinite(((Bounds)(ref bounds)).center) || !IsFinite(((Bounds)(ref bounds)).extents)) { continue; } Vector3 extents = ((Bounds)(ref bounds)).extents; if (!(((Vector3)(ref extents)).sqrMagnitude <= 0.0001f)) { if (!flag) { combinedBounds = bounds; flag = true; } else { ((Bounds)(ref combinedBounds)).Encapsulate(bounds); } } } return flag; } private static bool IsFinite(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFinite(value.x) && IsFinite(value.y)) { return IsFinite(value.z); } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } } internal static class VanillaScanHooks { private static ScrapVisibilityController? controller; private static ManualLogSource? logger; public static void Initialize(ScrapVisibilityController activeController, ManualLogSource activeLogger) { controller = activeController; logger = activeLogger; } public static void Clear(ScrapVisibilityController activeController) { if ((Object)(object)controller == (Object)(object)activeController) { controller = null; logger = null; VanillaScanPerformanceOptimizer.Clear(); } } public static void AfterStart(HUDManager __instance) { ScrapVisibilityController? scrapVisibilityController = controller; if (scrapVisibilityController != null && scrapVisibilityController.ShouldOptimizeVanillaScan) { VanillaScanPerformanceOptimizer.Prewarm(__instance); } } public static bool BeforeUpdateScanNodes(HUDManager __instance, PlayerControllerB playerScript, RaycastHit[] ___scanNodesHit, RectTransform[] ___scanElements, Dictionary ___scanNodes, List ___nodesOnScreen, Terminal ___terminalScript, ref float ___updateScanInterval, ref int ___scannedScrapNum, ref int ___totalScrapScanned, ref int ___totalScrapScannedDisplayNum, ref float ___addToDisplayTotalInterval, float ___playerPingingScan) { ScrapVisibilityController? scrapVisibilityController = controller; if (scrapVisibilityController == null || !scrapVisibilityController.ShouldOptimizeVanillaScan) { return true; } try { VanillaScanPerformanceOptimizer.UpdateScanNodesOptimized(__instance, playerScript, ___scanNodesHit, ___scanElements, ___scanNodes, ___nodesOnScreen, ___terminalScript, ref ___updateScanInterval, ref ___scannedScrapNum, ref ___totalScrapScanned, ref ___totalScrapScannedDisplayNum, ref ___addToDisplayTotalInterval, ___playerPingingScan, controller?.ShouldSuppressVanillaScanElements ?? false); return false; } catch (Exception ex) { ManualLogSource? obj = logger; if (obj != null) { obj.LogWarning((object)("ScanValue vanilla scan optimizer failed; falling back to vanilla scan update. " + ex.Message)); } return true; } } public static void AfterUpdateScanNodes(Dictionary ___scanNodes, RectTransform[] ___scanElements) { controller?.SetVisibleVanillaScanNodes(___scanNodes); ScrapVisibilityController? scrapVisibilityController = controller; if (scrapVisibilityController != null && scrapVisibilityController.ShouldSuppressVanillaScanElements) { SuppressVanillaScrapScanElements(___scanNodes, ___scanElements); } } public static void AfterDisableAllScanElements(HUDManager __instance) { controller?.ClearVisibleVanillaScanNodes(); ScrapVisibilityController? scrapVisibilityController = controller; if (scrapVisibilityController != null && scrapVisibilityController.ShouldOptimizeVanillaScan) { VanillaScanPerformanceOptimizer.ParkAll(__instance); } } public static void LogPatchFailure(string methodName) { ManualLogSource? obj = logger; if (obj != null) { obj.LogWarning((object)("Could not patch HUDManager." + methodName + "; vanilla-scan scrap labels may not mirror the scan UI.")); } } private static void SuppressVanillaScrapScanElements(Dictionary scanNodes, RectTransform[] scanElements) { if (scanNodes == null || scanElements == null) { return; } foreach (RectTransform val in scanElements) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeSelf && scanNodes.TryGetValue(val, out ScanNodeProperties value) && !((Object)(object)value == (Object)null) && value.nodeType == 2) { HideVanillaScanElement(val); } } } private static void HideVanillaScanElement(RectTransform scanElement) { ScrapVisibilityController? scrapVisibilityController = controller; if (scrapVisibilityController != null && scrapVisibilityController.ShouldOptimizeVanillaScan) { VanillaScanPerformanceOptimizer.ParkElement(scanElement); } else { ((Component)scanElement).gameObject.SetActive(false); } } } internal sealed class VanillaScanPatcher : IDisposable { private const string StartMethodName = "Start"; private const string UpdateScanNodesMethodName = "UpdateScanNodes"; private const string DisableAllScanElementsMethodName = "DisableAllScanElements"; private readonly Harmony harmony; private readonly ScrapVisibilityController controller; private bool disposed; public VanillaScanPatcher(ScrapVisibilityController controller, ManualLogSource logger) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown this.controller = controller; harmony = new Harmony("com.auuueser.lethalcompany.scanvalue.scan"); VanillaScanHooks.Initialize(controller, logger); Patch("Start", "AfterStart"); PatchUpdateScanNodes(); Patch("DisableAllScanElements", "AfterDisableAllScanElements"); logger.LogInfo((object)"ScanValue patched HUDManager scan nodes and vanilla scan performance."); } public void Dispose() { if (!disposed) { disposed = true; harmony.UnpatchSelf(); VanillaScanHooks.Clear(controller); } } private static MethodInfo RequiredHook(string methodName) { return AccessTools.DeclaredMethod(typeof(VanillaScanHooks), methodName, (Type[])null, (Type[])null) ?? throw new MissingMethodException(typeof(VanillaScanHooks).FullName, methodName); } private void Patch(string originalName, string postfixName) { Patch(originalName, null, postfixName); } private void PatchUpdateScanNodes() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown Patch("UpdateScanNodes", new HarmonyMethod(RequiredHook("BeforeUpdateScanNodes")), "AfterUpdateScanNodes"); } private void Patch(string originalName, HarmonyMethod? prefix, string postfixName) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(HUDManager), originalName, (Type[])null, (Type[])null); if (methodInfo == null) { VanillaScanHooks.LogPatchFailure(originalName); return; } HarmonyMethod val = new HarmonyMethod(RequiredHook(postfixName)); harmony.Patch((MethodBase)methodInfo, prefix, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } internal static class VanillaScanPerformanceOptimizer { private sealed class HudScanCache { private RectTransform[]? scanElements; private ScanElementCache[] elements = Array.Empty(); public HashSet NodesOnScreenSet { get; } = new HashSet(); public HashSet AssignedNodesSet { get; } = new HashSet(); public void Refresh(RectTransform[] currentScanElements) { if (scanElements != currentScanElements || elements.Length != currentScanElements.Length) { scanElements = currentScanElements; elements = new ScanElementCache[currentScanElements.Length]; for (int i = 0; i < currentScanElements.Length; i++) { elements[i] = new ScanElementCache(currentScanElements[i]); } } } public ScanElementCache Get(int index, RectTransform scanElement) { ScanElementCache scanElementCache = elements[index]; if ((Object)(object)scanElementCache.Element == (Object)(object)scanElement) { return scanElementCache; } scanElementCache = new ScanElementCache(scanElement); elements[index] = scanElementCache; return scanElementCache; } public void PrewarmTextMeshes() { for (int i = 0; i < elements.Length; i++) { TextMeshProUGUI[] textComponents = elements[i].TextComponents; foreach (TextMeshProUGUI val in textComponents) { if (!((Object)(object)val == (Object)null)) { string text = ((TMP_Text)val).text; ((TMP_Text)val).text = "Value: $0123456789???"; ((TMP_Text)val).ForceMeshUpdate(true, false); ((TMP_Text)val).text = text; ((TMP_Text)val).ForceMeshUpdate(true, false); } } } } public void ResetNodeState() { for (int i = 0; i < elements.Length; i++) { elements[i].LastNode = null; } } } private sealed class ScanElementCache { public RectTransform Element { get; } public Animator? Animator { get; } public TextMeshProUGUI[] TextComponents { get; } public ScanNodeProperties? LastNode { get; set; } public string LastHeader { get; set; } = string.Empty; public string LastSubText { get; set; } = string.Empty; public ScanElementCache(RectTransform element) { Element = element; if ((Object)(object)element == (Object)null) { TextComponents = Array.Empty(); return; } Animator = ((Component)element).GetComponent(); TextComponents = ((Component)element).GetComponentsInChildren(true); } } private const int ScanNodeLayerMask = 4194304; private const int ScanLineOfSightMask = 134217984; private const float AssignScanIntervalSeconds = 0.25f; private const string WarmupText = "Value: $0123456789???"; private static readonly Vector3 ParkedScanElementPosition = new Vector3(-400f, 0f, 0f); private static readonly Dictionary Caches = new Dictionary(2); public static void Clear() { Caches.Clear(); } public static void Prewarm(HUDManager hud) { if (!((Object)(object)hud == (Object)null) && hud.scanElements != null) { GetOrCreateCache(hud, hud.scanElements).PrewarmTextMeshes(); ParkElements(hud.scanElements); } } public static void ParkAll(HUDManager hud) { if (!((Object)(object)hud == (Object)null) && hud.scanElements != null) { GetOrCreateCache(hud, hud.scanElements).ResetNodeState(); ParkElements(hud.scanElements); } } public static void ParkElement(RectTransform element) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)element == (Object)null) && (!((Component)element).gameObject.activeSelf || !(((Transform)element).position == ParkedScanElementPosition))) { ((Transform)element).position = ParkedScanElementPosition; if (!((Component)element).gameObject.activeSelf) { ((Component)element).gameObject.SetActive(true); } } } public static void UpdateScanNodesOptimized(HUDManager hud, PlayerControllerB playerScript, RaycastHit[] scanNodesHit, RectTransform[] scanElements, Dictionary scanNodes, List nodesOnScreen, Terminal terminalScript, ref float updateScanInterval, ref int scannedScrapNum, ref int totalScrapScanned, ref int totalScrapScannedDisplayNum, ref float addToDisplayTotalInterval, float playerPingingScan, bool suppressScrapScanElements) { //IL_018b: 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) //IL_0195: 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_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hud == (Object)null || (Object)(object)playerScript == (Object)null || scanNodesHit == null || scanElements == null || scanNodes == null || nodesOnScreen == null) { return; } HudScanCache orCreateCache = GetOrCreateCache(hud, scanElements); if (updateScanInterval <= 0f) { updateScanInterval = 0.25f; AssignNewNodesOptimized(orCreateCache, playerScript, scanNodesHit, scanElements, scanNodes, nodesOnScreen, ref scannedScrapNum, ref totalScrapScanned, playerPingingScan); } updateScanInterval -= Time.deltaTime; bool flag = false; bool flag2 = false; for (int i = 0; i < scanElements.Length; i++) { RectTransform val = scanElements[i]; if ((Object)(object)val == (Object)null) { continue; } if (scanNodes.Count == 0 || !scanNodes.TryGetValue(val, out ScanNodeProperties value) || (Object)(object)value == (Object)null) { orCreateCache.Get(i, val).LastNode = null; scanNodes.Remove(val); ParkElement(val); continue; } if (NodeIsNotVisible(val, value, scanNodes, orCreateCache.NodesOnScreenSet, ref totalScrapScanned)) { orCreateCache.Get(i, val).LastNode = null; continue; } ScanElementCache scanElementCache = orCreateCache.Get(i, val); if (value.nodeType == 2) { flag = true; if (suppressScrapScanElements) { scanElementCache.LastNode = null; ParkElement(val); continue; } } if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } if ((Object)(object)scanElementCache.LastNode != (Object)(object)value) { scanElementCache.LastNode = value; Animator? animator = scanElementCache.Animator; if (animator != null) { animator.SetInteger("colorNumber", value.nodeType); } AttemptScanNewCreature(hud, terminalScript, value.creatureScanID); } SetTextIfChanged(scanElementCache, value); Vector3 val2 = playerScript.gameplayCamera.WorldToViewportPoint(((Component)value).transform.position); if (val2.x > 1f || val2.x < 0f || val2.y > 1f || val2.y < 0f) { ParkElement(val); continue; } if (!flag2) { hud.playerScreenRectTransform.GetWorldCorners(hud.playerScreenCorners); flag2 = true; } ((Transform)val).position = ResolveScanElementPosition(hud, val2); } if (!flag) { totalScrapScanned = 0; totalScrapScannedDisplayNum = 0; addToDisplayTotalInterval = 0.35f; } hud.scanInfoAnimator.SetBool("display", scannedScrapNum >= 2 && flag); } private static void AssignNewNodesOptimized(HudScanCache cache, PlayerControllerB playerScript, RaycastHit[] scanNodesHit, RectTransform[] scanElements, Dictionary scanNodes, List nodesOnScreen, ref int scannedScrapNum, ref int totalScrapScanned, float playerPingingScan) { //IL_000d: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)playerScript.gameplayCamera).transform; int num = Physics.SphereCastNonAlloc(new Ray(transform.position + transform.forward * 20f, transform.forward), 20f, scanNodesHit, 80f, 4194304); if (num > scanElements.Length) { num = scanElements.Length; } nodesOnScreen.Clear(); cache.NodesOnScreenSet.Clear(); cache.AssignedNodesSet.Clear(); foreach (KeyValuePair scanNode in scanNodes) { if ((Object)(object)scanNode.Value != (Object)null) { cache.AssignedNodesSet.Add(scanNode.Value); } } scannedScrapNum = 0; ScanNodeProperties val = default(ScanNodeProperties); for (int i = 0; i < num; i++) { Transform transform2 = ((RaycastHit)(ref scanNodesHit[i])).transform; if (!((Object)(object)transform2 == (Object)null) && ((Component)transform2).TryGetComponent(ref val) && MeetsScanNodeRequirements(val, playerScript)) { if (val.nodeType == 2) { scannedScrapNum++; } if (cache.NodesOnScreenSet.Add(val)) { nodesOnScreen.Add(val); } if (playerPingingScan >= 0f) { AssignNodeToUIElement(val, scanElements, scanNodes, cache.AssignedNodesSet, ref totalScrapScanned); } } } } private static bool MeetsScanNodeRequirements(ScanNodeProperties node, PlayerControllerB playerScript) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)node == (Object)null) { return false; } Vector3 val = ((Component)playerScript).transform.position - ((Component)node).transform.position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; int num = node.maxRange * node.maxRange; int num2 = node.minRange * node.minRange; if (sqrMagnitude >= (float)num || sqrMagnitude <= (float)num2) { return false; } Vector3 val2 = playerScript.gameplayCamera.WorldToViewportPoint(((Component)node).transform.position); if (val2.z <= 0f || val2.x > 1f || val2.x < 0f || val2.y > 1f || val2.y < 0f) { return false; } if (!node.requiresLineOfSight) { return true; } return !Physics.Linecast(((Component)playerScript.gameplayCamera).transform.position, ((Component)node).transform.position, 134217984, (QueryTriggerInteraction)1); } private static bool NodeIsNotVisible(RectTransform scanElement, ScanNodeProperties node, Dictionary scanNodes, HashSet nodesOnScreenSet, ref int totalScrapScanned) { if (nodesOnScreenSet.Contains(node)) { return false; } if (node.nodeType == 2) { totalScrapScanned = Mathf.Clamp(totalScrapScanned - node.scrapValue, 0, 100000); } ParkElement(scanElement); scanNodes.Remove(scanElement); return true; } private static void AssignNodeToUIElement(ScanNodeProperties node, RectTransform[] scanElements, Dictionary scanNodes, HashSet assignedNodesSet, ref int totalScrapScanned) { if (!assignedNodesSet.Add(node)) { return; } foreach (RectTransform val in scanElements) { if (!((Object)(object)val == (Object)null) && !scanNodes.ContainsKey(val)) { scanNodes.Add(val, node); if (node.nodeType == 2) { totalScrapScanned += node.scrapValue; } break; } } } private static void AttemptScanNewCreature(HUDManager hud, Terminal terminalScript, int enemyID) { if (enemyID != -1 && !((Object)(object)terminalScript == (Object)null) && !terminalScript.scannedEnemyIDs.Contains(enemyID)) { hud.ScanNewCreatureServerRpc(enemyID); } } private static Vector3 ResolveScanElementPosition(HUDManager hud, Vector3 viewport) { //IL_0053: 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_0065: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector3[] playerScreenCorners = hud.playerScreenCorners; if (!IngamePlayerSettings.Instance.flipCamera) { return Vector3.Lerp(Vector3.Lerp(playerScreenCorners[0], playerScreenCorners[3], viewport.x), Vector3.Lerp(playerScreenCorners[1], playerScreenCorners[2], viewport.x), viewport.y); } return Vector3.Lerp(Vector3.Lerp(playerScreenCorners[3], playerScreenCorners[0], viewport.x), Vector3.Lerp(playerScreenCorners[2], playerScreenCorners[1], viewport.x), viewport.y); } private static void SetTextIfChanged(ScanElementCache cache, ScanNodeProperties node) { TextMeshProUGUI[] textComponents = cache.TextComponents; if (textComponents.Length > 1) { string text = node.headerText ?? string.Empty; if (!string.Equals(cache.LastHeader, text, StringComparison.Ordinal)) { cache.LastHeader = text; ((TMP_Text)textComponents[0]).text = text; } string text2 = node.subText ?? string.Empty; if (!string.Equals(cache.LastSubText, text2, StringComparison.Ordinal)) { cache.LastSubText = text2; ((TMP_Text)textComponents[1]).text = text2; } } } private static HudScanCache GetOrCreateCache(HUDManager hud, RectTransform[] scanElements) { if (!Caches.TryGetValue(hud, out HudScanCache value)) { value = new HudScanCache(); Caches.Add(hud, value); } value.Refresh(scanElements); return value; } private static void ParkElements(RectTransform[] scanElements) { for (int i = 0; i < scanElements.Length; i++) { ParkElement(scanElements[i]); } } } } namespace Auuueser.ScanValue.Configuration { internal static class ChineseProjectLanguageDetector { public static ConfigLanguage Detect(ConfigFile config, ManualLogSource logger) { if (!DetectLoadedPlugin(logger) && !DetectExistingConfig(config, logger) && !DetectManifestNearConfig(config, logger)) { return (ConfigLanguage)0; } return (ConfigLanguage)1; } private static bool DetectLoadedPlugin(ManualLogSource logger) { foreach (KeyValuePair pluginInfo in Chainloader.PluginInfos) { PluginInfo value = pluginInfo.Value; if (value != null && value.Metadata != null && ChineseProjectDetection.IsChineseProjectPlugin(value.Metadata.GUID, value.Metadata.Name, value.Location)) { logger.LogInfo((object)("LC Chinese Project detected from plugin '" + value.Metadata.GUID + "'. Using Chinese config text.")); return true; } } return false; } private static bool DetectExistingConfig(ConfigFile config, ManualLogSource logger) { if (!File.Exists(config.ConfigFilePath)) { return false; } try { if (!ChineseProjectDetection.ContainsChineseConfigSections(File.ReadAllText(config.ConfigFilePath))) { return false; } logger.LogInfo((object)"Existing Chinese config sections detected. Using Chinese config text."); return true; } catch (Exception ex) { logger.LogWarning((object)("Could not inspect existing config language: " + ex.Message)); return false; } } private static bool DetectManifestNearConfig(ConfigFile config, ManualLogSource logger) { string directoryName = Path.GetDirectoryName(config.ConfigFilePath); if (string.IsNullOrEmpty(directoryName)) { return false; } DirectoryInfo parent = Directory.GetParent(directoryName); if (parent == null) { return false; } string path = Path.Combine(parent.FullName, "plugins"); if (!Directory.Exists(path)) { return false; } try { foreach (string item in Directory.EnumerateFiles(path, "manifest.json", SearchOption.AllDirectories)) { if (ChineseProjectDetection.ContainsChineseProjectManifestText(File.ReadAllText(item))) { logger.LogInfo((object)("LC Chinese Project manifest detected at '" + item + "'. Using Chinese config text.")); return true; } } } catch (Exception ex) { logger.LogWarning((object)("Could not inspect plugin manifests for config language: " + ex.Message)); } return false; } } internal static class ConfigLanguageFileMigrator { private readonly struct ValueId : IEquatable { private readonly int sectionIndex; private readonly string key; public ValueId(int sectionIndex, string key) { this.sectionIndex = sectionIndex; this.key = key; } public bool Equals(ValueId other) { if (sectionIndex == other.sectionIndex) { return string.Equals(key, other.key, StringComparison.Ordinal); } return false; } public override bool Equals(object? obj) { if (obj is ValueId other) { return Equals(other); } return false; } public override int GetHashCode() { return (sectionIndex * 397) ^ StringComparer.Ordinal.GetHashCode(key); } } private readonly struct CapturedValue { public string Value { get; } public int Priority { get; } public CapturedValue(string value, int priority) { Value = value; Priority = priority; } } private sealed class SectionMap { public string EnglishHeader { get; } public string ChineseHeader { get; } public string[] Keys { get; } public SectionMap(string englishName, string chineseName, string[] keys) { EnglishHeader = "[" + englishName + "]"; ChineseHeader = "[" + chineseName + "]"; Keys = keys; } public string GetHeader(ConfigLanguage language) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)language != 1) { return EnglishHeader; } return ChineseHeader; } public bool IsHeaderLanguage(string line, ConfigLanguage language) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)language != 1) { return string.Equals(line, EnglishHeader, StringComparison.OrdinalIgnoreCase); } return string.Equals(line, ChineseHeader, StringComparison.OrdinalIgnoreCase); } public bool MatchesHeader(string line) { if (!string.Equals(line, EnglishHeader, StringComparison.OrdinalIgnoreCase)) { return string.Equals(line, ChineseHeader, StringComparison.OrdinalIgnoreCase); } return true; } public bool ContainsKey(string key) { for (int i = 0; i < Keys.Length; i++) { if (string.Equals(Keys[i], key, StringComparison.Ordinal)) { return true; } } return false; } } private static readonly UTF8Encoding Utf8NoBom = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); private static readonly SectionMap[] Sections = new SectionMap[6] { new SectionMap("General", "通用", new string[1] { "Enabled" }), new SectionMap("Visibility", "可见性", new string[4] { "RevealRadius", "ActivationMode", "ScanRevealDurationSeconds", "MaxVisibleLabels" }), new SectionMap("Performance", "性能", new string[2] { "UpdateIntervalSeconds", "OptimizeVanillaScan" }), new SectionMap("Label", "标签", new string[8] { "HeightOffset", "WorldScale", "FontSize", "LabelColor", "OutlineColor", "OutlineWidth", "ShowItemNames", "ItemNameLanguage" }), new SectionMap("Highlight", "高光", new string[5] { "EnableScanHighlight", "HighlightColor", "HighlightAlpha", "HighlightWidth", "MaxHighlightedItems" }), new SectionMap("Debug", "调试", new string[7] { "Enabled", "DiagnosticsEnabled", "ShowHeldItems", "ShowZeroValueItems", "LogRegistrations", "ShowCameraTestLabel", "LogIntervalSeconds" }) }; public static bool Normalize(string configFilePath, ConfigLanguage language, ManualLogSource logger) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(configFilePath) || !File.Exists(configFilePath)) { return false; } string text; try { text = File.ReadAllText(configFilePath, Encoding.UTF8); } catch (Exception ex) { logger.LogWarning((object)("Could not inspect ScanValue config language: " + ex.Message)); return false; } if (!ShouldNormalize(text, language)) { return false; } Dictionary dictionary = CaptureValues(text, language); if (dictionary.Count == 0) { return false; } string contents = BuildTargetLanguageConfig(dictionary, language); try { File.WriteAllText(configFilePath, contents, Utf8NoBom); logger.LogInfo((object)$"ScanValue config language normalized to {language}; known values were preserved."); return true; } catch (Exception ex2) { logger.LogWarning((object)("Could not normalize ScanValue config language: " + ex2.Message)); return false; } } private static bool ShouldNormalize(string text, ConfigLanguage language) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 for (int i = 0; i < Sections.Length; i++) { SectionMap sectionMap = Sections[i]; string header = (((int)language == 1) ? sectionMap.EnglishHeader : sectionMap.ChineseHeader); if (ContainsHeader(text, header)) { return true; } } return false; } private static Dictionary CaptureValues(string text, ConfigLanguage language) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(64); SectionMap sectionMap = null; int sectionIndex = -1; int num = 0; string[] array = text.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n'); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.Length == 0 || text3.StartsWith("#", StringComparison.Ordinal)) { continue; } int num2 = FindSectionIndex(text3); if (num2 >= 0) { sectionIndex = num2; sectionMap = Sections[num2]; num = (sectionMap.IsHeaderLanguage(text3, language) ? 1 : 0); } else { if (sectionMap == null) { continue; } int num3 = text2.IndexOf('='); if (num3 <= 0) { continue; } string key = text2.Substring(0, num3).Trim(); if (sectionMap.ContainsKey(key)) { string value = text2.Substring(num3 + 1).Trim(); ValueId key2 = new ValueId(sectionIndex, key); if (!dictionary.TryGetValue(key2, out var value2) || num >= value2.Priority) { dictionary[key2] = new CapturedValue(value, num); } } } } return dictionary; } private static string BuildTargetLanguageConfig(Dictionary values, ConfigLanguage language) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(1024); for (int i = 0; i < Sections.Length; i++) { SectionMap sectionMap = Sections[i]; stringBuilder.AppendLine(sectionMap.GetHeader(language)); for (int j = 0; j < sectionMap.Keys.Length; j++) { string text = sectionMap.Keys[j]; if (values.TryGetValue(new ValueId(i, text), out var value)) { stringBuilder.Append(text).Append(" = ").AppendLine(value.Value); } } stringBuilder.AppendLine(); } return stringBuilder.ToString(); } private static bool ContainsHeader(string text, string header) { return text.IndexOf("[" + header + "]", StringComparison.OrdinalIgnoreCase) >= 0; } private static int FindSectionIndex(string line) { for (int i = 0; i < Sections.Length; i++) { if (Sections[i].MatchesHeader(line)) { return i; } } return -1; } } internal sealed class ModConfig { private const float ConfigFilePollInterval = 0.5f; private readonly ConfigFile configFile; private readonly string configFilePath; private readonly ConfigEntry enabled; private readonly ConfigEntry revealRadius; private readonly ConfigEntry activationMode; private readonly ConfigEntry scanRevealDurationSeconds; private readonly ConfigEntry updateIntervalSeconds; private readonly ConfigEntry optimizeVanillaScan; private readonly ConfigEntry maxVisibleLabels; private readonly ConfigEntry heightOffset; private readonly ConfigEntry worldScale; private readonly ConfigEntry fontSize; private readonly ConfigEntry labelColor; private readonly ConfigEntry outlineColor; private readonly ConfigEntry outlineWidth; private readonly ConfigEntry highlightEnabled; private readonly ConfigEntry highlightColor; private readonly ConfigEntry highlightAlpha; private readonly ConfigEntry highlightWidth; private readonly ConfigEntry maxHighlightedItems; private readonly ConfigEntry valueBasedColorsEnabled; private readonly ConfigEntry lowValueMax; private readonly ConfigEntry mediumValueMax; private readonly ConfigEntry highValueMax; private readonly ConfigEntry veryHighValueMax; private readonly ConfigEntry unknownValueColor; private readonly ConfigEntry lowValueColor; private readonly ConfigEntry mediumValueColor; private readonly ConfigEntry highValueColor; private readonly ConfigEntry veryHighValueColor; private readonly ConfigEntry jackpotValueColor; private readonly ConfigEntry showItemNames; private readonly ConfigEntry itemNameLanguage; private readonly ConfigEntry debugEnabled; private readonly ConfigEntry debugDiagnosticsEnabled; private readonly ConfigEntry debugShowHeldItems; private readonly ConfigEntry debugShowZeroValueItems; private readonly ConfigEntry debugLogRegistrations; private readonly ConfigEntry debugShowCameraTestLabel; private readonly ConfigEntry debugLogIntervalSeconds; private DateTime lastConfigWriteTimeUtc; private float nextConfigFilePollTime; public ConfigLanguage Language { get; } public ConfigTexts Texts { get; } public ModSettings Current { get; private set; } public int SettingsVersion { get; private set; } private ModConfig(ConfigFile configFile, ConfigLanguage language, ConfigEntry enabled, ConfigEntry revealRadius, ConfigEntry activationMode, ConfigEntry scanRevealDurationSeconds, ConfigEntry updateIntervalSeconds, ConfigEntry optimizeVanillaScan, ConfigEntry maxVisibleLabels, ConfigEntry heightOffset, ConfigEntry worldScale, ConfigEntry fontSize, ConfigEntry labelColor, ConfigEntry outlineColor, ConfigEntry outlineWidth, ConfigEntry showItemNames, ConfigEntry itemNameLanguage, ConfigEntry highlightEnabled, ConfigEntry highlightColor, ConfigEntry highlightAlpha, ConfigEntry highlightWidth, ConfigEntry maxHighlightedItems, ConfigEntry valueBasedColorsEnabled, ConfigEntry lowValueMax, ConfigEntry mediumValueMax, ConfigEntry highValueMax, ConfigEntry veryHighValueMax, ConfigEntry unknownValueColor, ConfigEntry lowValueColor, ConfigEntry mediumValueColor, ConfigEntry highValueColor, ConfigEntry veryHighValueColor, ConfigEntry jackpotValueColor, ConfigEntry debugEnabled, ConfigEntry debugDiagnosticsEnabled, ConfigEntry debugShowHeldItems, ConfigEntry debugShowZeroValueItems, ConfigEntry debugLogRegistrations, ConfigEntry debugShowCameraTestLabel, ConfigEntry debugLogIntervalSeconds) { //IL_001a: 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_0021: Unknown result type (might be due to invalid IL or missing references) this.configFile = configFile; configFilePath = configFile.ConfigFilePath; Language = language; Texts = ConfigTextCatalog.Get(language); this.enabled = enabled; this.revealRadius = revealRadius; this.activationMode = activationMode; this.scanRevealDurationSeconds = scanRevealDurationSeconds; this.updateIntervalSeconds = updateIntervalSeconds; this.optimizeVanillaScan = optimizeVanillaScan; this.maxVisibleLabels = maxVisibleLabels; this.heightOffset = heightOffset; this.worldScale = worldScale; this.fontSize = fontSize; this.labelColor = labelColor; this.outlineColor = outlineColor; this.outlineWidth = outlineWidth; this.showItemNames = showItemNames; this.itemNameLanguage = itemNameLanguage; this.highlightEnabled = highlightEnabled; this.highlightColor = highlightColor; this.highlightAlpha = highlightAlpha; this.highlightWidth = highlightWidth; this.maxHighlightedItems = maxHighlightedItems; this.valueBasedColorsEnabled = valueBasedColorsEnabled; this.lowValueMax = lowValueMax; this.mediumValueMax = mediumValueMax; this.highValueMax = highValueMax; this.veryHighValueMax = veryHighValueMax; this.unknownValueColor = unknownValueColor; this.lowValueColor = lowValueColor; this.mediumValueColor = mediumValueColor; this.highValueColor = highValueColor; this.veryHighValueColor = veryHighValueColor; this.jackpotValueColor = jackpotValueColor; this.debugEnabled = debugEnabled; this.debugDiagnosticsEnabled = debugDiagnosticsEnabled; this.debugShowHeldItems = debugShowHeldItems; this.debugShowZeroValueItems = debugShowZeroValueItems; this.debugLogRegistrations = debugLogRegistrations; this.debugShowCameraTestLabel = debugShowCameraTestLabel; this.debugLogIntervalSeconds = debugLogIntervalSeconds; Reload(); SubscribeChanges(); configFile.Save(); RefreshLastWriteTime(); } public static ModConfig Bind(ConfigFile config, ConfigLanguage language) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) ConfigTexts val = ConfigTextCatalog.Get(language); return new ModConfig(config, language, config.Bind(val.GeneralSection, "Enabled", true, val.EnabledDescription), config.Bind(val.VisibilitySection, "RevealRadius", 12f, val.RevealRadiusDescription), config.Bind(val.VisibilitySection, "ActivationMode", "VanillaScan", val.ActivationModeDescription), config.Bind(val.VisibilitySection, "ScanRevealDurationSeconds", 10f, val.ScanRevealDurationSecondsDescription), config.Bind(val.PerformanceSection, "UpdateIntervalSeconds", 0.12f, val.UpdateIntervalSecondsDescription), config.Bind(val.PerformanceSection, "OptimizeVanillaScan", true, val.OptimizeVanillaScanDescription), config.Bind(val.VisibilitySection, "MaxVisibleLabels", 64, val.MaxVisibleLabelsDescription), config.Bind(val.LabelSection, "HeightOffset", 0.85f, val.HeightOffsetDescription), config.Bind(val.LabelSection, "WorldScale", 0.18f, val.WorldScaleDescription), config.Bind(val.LabelSection, "FontSize", 3.5f, val.FontSizeDescription), config.Bind(val.LabelSection, "LabelColor", "#FFD447", val.LabelColorDescription), config.Bind(val.LabelSection, "OutlineColor", "#101010", val.OutlineColorDescription), config.Bind(val.LabelSection, "OutlineWidth", 0.25f, val.OutlineWidthDescription), config.Bind(val.LabelSection, "ShowItemNames", true, val.ShowItemNamesDescription), config.Bind(val.LabelSection, "ItemNameLanguage", "Auto", val.ItemNameLanguageDescription), config.Bind(val.HighlightSection, "EnableScanHighlight", true, val.HighlightEnabledDescription), config.Bind(val.HighlightSection, "HighlightColor", "#FFD447", val.HighlightColorDescription), config.Bind(val.HighlightSection, "HighlightAlpha", 0.35f, val.HighlightAlphaDescription), config.Bind(val.HighlightSection, "HighlightWidth", 0.035f, val.HighlightWidthDescription), config.Bind(val.HighlightSection, "MaxHighlightedItems", 64, val.MaxHighlightedItemsDescription), config.Bind(val.HighlightSection, "EnableValueBasedColors", true, val.ValueBasedColorsEnabledDescription), config.Bind(val.HighlightSection, "LowValueMax", 39, val.LowValueMaxDescription), config.Bind(val.HighlightSection, "MediumValueMax", 79, val.MediumValueMaxDescription), config.Bind(val.HighlightSection, "HighValueMax", 119, val.HighValueMaxDescription), config.Bind(val.HighlightSection, "VeryHighValueMax", 169, val.VeryHighValueMaxDescription), config.Bind(val.HighlightSection, "UnknownValueColor", "#FFD447", val.UnknownValueColorDescription), config.Bind(val.HighlightSection, "LowValueColor", "#7EC8FF", val.LowValueColorDescription), config.Bind(val.HighlightSection, "MediumValueColor", "#FFD447", val.MediumValueColorDescription), config.Bind(val.HighlightSection, "HighValueColor", "#FF9F1C", val.HighValueColorDescription), config.Bind(val.HighlightSection, "VeryHighValueColor", "#FF5A36", val.VeryHighValueColorDescription), config.Bind(val.HighlightSection, "JackpotValueColor", "#FF3FD4", val.JackpotValueColorDescription), config.Bind(val.DebugSection, "Enabled", false, val.DebugEnabledDescription), config.Bind(val.DebugSection, "DiagnosticsEnabled", false, val.DebugDiagnosticsEnabledDescription), config.Bind(val.DebugSection, "ShowHeldItems", false, val.DebugShowHeldItemsDescription), config.Bind(val.DebugSection, "ShowZeroValueItems", false, val.DebugShowZeroValueItemsDescription), config.Bind(val.DebugSection, "LogRegistrations", false, val.DebugLogRegistrationsDescription), config.Bind(val.DebugSection, "ShowCameraTestLabel", false, val.DebugShowCameraTestLabelDescription), config.Bind(val.DebugSection, "LogIntervalSeconds", 3f, val.DebugLogIntervalSecondsDescription)); } public void ReloadIfChangedOnDisk(float currentTime) { if (!(currentTime < nextConfigFilePollTime) && File.Exists(configFilePath)) { nextConfigFilePollTime = currentTime + 0.5f; if (!(File.GetLastWriteTimeUtc(configFilePath) <= lastConfigWriteTimeUtc)) { configFile.Reload(); RefreshLastWriteTime(); } } } private void Reload() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_020a: 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_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) Current = new ModSettings(ScrapVisibilityOptions.Create(enabled.Value, revealRadius.Value, updateIntervalSeconds.Value, maxVisibleLabels.Value, activationMode.Value, scanRevealDurationSeconds.Value), ClampFinite(heightOffset.Value, 0.1f, 4f), ClampFinite(worldScale.Value, 0.03f, 1f), ClampFinite(fontSize.Value, 0.5f, 12f), ParseColor(labelColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)212, (byte)71, byte.MaxValue))), ParseColor(outlineColor.Value, Color32.op_Implicit(new Color32((byte)16, (byte)16, (byte)16, byte.MaxValue))), ClampFinite(outlineWidth.Value, 0f, 0.5f), ParseColor(highlightColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)212, (byte)71, byte.MaxValue))), ScrapHighlightOptions.Create(highlightEnabled.Value, highlightAlpha.Value, highlightWidth.Value, maxHighlightedItems.Value), ScrapValueColorOptions.Create(valueBasedColorsEnabled.Value, lowValueMax.Value, mediumValueMax.Value, highValueMax.Value, veryHighValueMax.Value), ParseColor(unknownValueColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)212, (byte)71, byte.MaxValue))), ParseColor(lowValueColor.Value, Color32.op_Implicit(new Color32((byte)126, (byte)200, byte.MaxValue, byte.MaxValue))), ParseColor(mediumValueColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)212, (byte)71, byte.MaxValue))), ParseColor(highValueColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)159, (byte)28, byte.MaxValue))), ParseColor(veryHighValueColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)90, (byte)54, byte.MaxValue))), ParseColor(jackpotValueColor.Value, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)63, (byte)212, byte.MaxValue))), ScrapItemNameOptions.Create(showItemNames.Value, itemNameLanguage.Value), ScrapScanPerformanceOptions.Create(optimizeVanillaScan.Value), ScrapDebugOptions.Create(debugEnabled.Value, debugDiagnosticsEnabled.Value, debugShowHeldItems.Value, debugShowZeroValueItems.Value, debugLogRegistrations.Value, debugShowCameraTestLabel.Value, debugLogIntervalSeconds.Value)); SettingsVersion++; } private void SubscribeChanges() { configFile.SettingChanged += HandleSettingChanged; configFile.ConfigReloaded += HandleConfigReloaded; } private void HandleSettingChanged(object sender, SettingChangedEventArgs args) { Reload(); RefreshLastWriteTime(); } private void HandleConfigReloaded(object sender, EventArgs args) { Reload(); RefreshLastWriteTime(); } private void RefreshLastWriteTime() { if (File.Exists(configFilePath)) { lastConfigWriteTimeUtc = File.GetLastWriteTimeUtc(configFilePath); } } private static float ClampFinite(float value, float min, float max) { if (float.IsNaN(value) || float.IsInfinity(value)) { return min; } if (value < min) { return min; } if (value > max) { return max; } return value; } private static Color ParseColor(string value, Color fallback) { //IL_0014: 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) Color result = default(Color); if (!string.IsNullOrWhiteSpace(value) && ColorUtility.TryParseHtmlString(value, ref result)) { return result; } return fallback; } } internal sealed class ModSettings { public ScrapVisibilityOptions Visibility { get; } public float HeightOffset { get; } public float WorldScale { get; } public float FontSize { get; } public Color LabelColor { get; } public Color OutlineColor { get; } public float OutlineWidth { get; } public Color HighlightColor { get; } public ScrapHighlightOptions Highlight { get; } public ScrapValueColorOptions ValueColors { get; } public Color UnknownValueColor { get; } public Color LowValueColor { get; } public Color MediumValueColor { get; } public Color HighValueColor { get; } public Color VeryHighValueColor { get; } public Color JackpotValueColor { get; } public ScrapItemNameOptions ItemNames { get; } public ScrapScanPerformanceOptions ScanPerformance { get; } public ScrapDebugOptions Debug { get; } public ModSettings(ScrapVisibilityOptions visibility, float heightOffset, float worldScale, float fontSize, Color labelColor, Color outlineColor, float outlineWidth, Color highlightColor, ScrapHighlightOptions highlight, ScrapValueColorOptions valueColors, Color unknownValueColor, Color lowValueColor, Color mediumValueColor, Color highValueColor, Color veryHighValueColor, Color jackpotValueColor, ScrapItemNameOptions itemNames, ScrapScanPerformanceOptions scanPerformance, ScrapDebugOptions debug) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) Visibility = visibility; HeightOffset = heightOffset; WorldScale = worldScale; FontSize = fontSize; LabelColor = labelColor; OutlineColor = outlineColor; OutlineWidth = outlineWidth; HighlightColor = highlightColor; Highlight = highlight; ValueColors = valueColors; UnknownValueColor = unknownValueColor; LowValueColor = lowValueColor; MediumValueColor = mediumValueColor; HighValueColor = highValueColor; VeryHighValueColor = veryHighValueColor; JackpotValueColor = jackpotValueColor; ItemNames = itemNames; ScanPerformance = scanPerformance; Debug = debug; } } }