using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Jotunn; using Jotunn.Managers; using Microsoft.CodeAnalysis; using TheConcernedCat.ConcernedTeamster.Adapters; using TheConcernedCat.ConcernedTeamster.Domain; using TheConcernedCat.ConcernedTeamster.Domain.Authority; using TheConcernedCat.ConcernedTeamster.Domain.Brake; using TheConcernedCat.ConcernedTeamster.Domain.Capabilities; using TheConcernedCat.ConcernedTeamster.Domain.Cargo; using TheConcernedCat.ConcernedTeamster.Domain.Cartographer; using TheConcernedCat.ConcernedTeamster.Domain.Carts; using TheConcernedCat.ConcernedTeamster.Domain.Compatibility; using TheConcernedCat.ConcernedTeamster.Domain.Config; using TheConcernedCat.ConcernedTeamster.Domain.Diagnostics; using TheConcernedCat.ConcernedTeamster.Domain.Load; using TheConcernedCat.ConcernedTeamster.Domain.Localization; using TheConcernedCat.ConcernedTeamster.Domain.Net; using TheConcernedCat.ConcernedTeamster.Domain.Onboarding; using TheConcernedCat.ConcernedTeamster.Domain.Profiles; using TheConcernedCat.ConcernedTeamster.Domain.Risk; using TheConcernedCat.ConcernedTeamster.Domain.RoadQuality; using TheConcernedCat.ConcernedTeamster.Domain.Routes; using TheConcernedCat.ConcernedTeamster.Domain.Support; using TheConcernedCat.ConcernedTeamster.Domain.Terrain; using TheConcernedCat.ConcernedTeamster.Domain.Trips; using TheConcernedCat.ConcernedTeamster.Domain.Ui; using TheConcernedCat.ConcernedTeamster.Domain.Warnings; using TheConcernedCat.ConcernedTeamster.Ui; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("The Concerned Cat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2026 Eren Cansunar")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+0575bf436e7a4914371658c2e700c7cc93063d43")] [assembly: AssemblyProduct("Concerned Teamster")] [assembly: AssemblyTitle("TheConcernedCat.ConcernedTeamster")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Weakened/ConcernedCatMods")] [assembly: AssemblyVersion("1.0.1.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 TheConcernedCat.ConcernedTeamster { [BepInPlugin("com.theconcernedcat.valheim.concernedteamster", "Concerned Teamster", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.theconcernedcat.valheim.concernedteamster"; public const string PluginName = "Concerned Teamster"; public const string PluginVersion = "1.0.1"; private bool _cartographerProbePending; private bool _compatibilityProbePending; private readonly LogTailRecorder _logTail = new LogTailRecorder(); private void Awake() { _logTail.Attach(((BaseUnityPlugin)this).Logger); TeamsterSettings teamsterSettings = TeamsterSettings.Bind(((BaseUnityPlugin)this).Config); ApplyConfigSchemaMigrationIfNeeded(teamsterSettings); ApplyProfileIfChanged(teamsterSettings); LocalizationFiles.Initialize(((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Concerned Teamster 1.0.1 loaded"); LogEnvironmentBanner(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Effective config: " + $"Enabled={teamsterSettings.Enabled.Value}, " + $"DebugLogging={teamsterSettings.DebugLogging.Value}.")); LogCartCapability(teamsterSettings); ArmTelemetry(teamsterSettings); _cartographerProbePending = teamsterSettings.Enabled.Value; _compatibilityProbePending = true; } private void Update() { if (_cartographerProbePending) { _cartographerProbePending = false; CartographerCapability.EnsureProbed(((BaseUnityPlugin)this).Logger); } if (_compatibilityProbePending) { _compatibilityProbePending = false; CompatibilityAdapter.EnsureProbed(((BaseUnityPlugin)this).Logger); } } private void ApplyConfigSchemaMigrationIfNeeded(TeamsterSettings settings) { ConfigSchemaMigration.Plan plan = ConfigSchemaMigration.Decide(settings.SchemaVersion.Value); if (plan.LogMessage != null) { if (plan.IsFromANewerVersion) { ((BaseUnityPlugin)this).Logger.LogWarning((object)plan.LogMessage); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)plan.LogMessage); } } if (plan.NeedsMigration) { settings.SchemaVersion.Value = 1; } } private void ApplyProfileIfChanged(TeamsterSettings settings) { ConfigProfile value = settings.ActiveProfile.Value; ConfigProfile value2 = settings.LastAppliedProfile.Value; if (ProfileTransition.ShouldApply(value, value2)) { ProfileValues profileValues = ConfigProfileCatalog.Resolve(value); settings.PanelWarningsEnabled.Value = profileValues.PanelWarningsEnabled; settings.HudWarningHintsEnabled.Value = profileValues.HudWarningHintsEnabled; settings.TripsEnabled.Value = profileValues.TripsEnabled; settings.RiskLookaheadPoints.Value = profileValues.RiskLookaheadPoints; settings.LastAppliedProfile.Value = value; ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Config profile '{value}' applied (was '{value2}'): " + $"warnings={profileValues.PanelWarningsEnabled}, HUD hint={profileValues.HudWarningHintsEnabled}, " + $"trips={profileValues.TripsEnabled}, risk lookahead={profileValues.RiskLookaheadPoints}. " + "Brake.Enabled is never changed by a profile switch — it stays opt-in.")); } } private void ArmTelemetry(TeamsterSettings settings) { if (!settings.Enabled.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Concerned Teamster is disabled by config; no cart observation runs."); } else if (CartAdapter.CapabilityEnabled) { LoadModel loadModel = LoadCalibratedModel(); RiskModel riskModel = LoadDescentModel(); CartTelemetryPump cartTelemetryPump = ((Component)this).gameObject.AddComponent(); TelemetrySamplerOptions telemetrySamplerOptions = cartTelemetryPump.Initialize(settings, ((BaseUnityPlugin)this).Logger, loadModel, riskModel); ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Cart telemetry sampler armed: interval {telemetrySamplerOptions.SampleIntervalSeconds:0.##} s, " + $"radius {telemetrySamplerOptions.SearchRadiusMeters:0.#} m, {telemetrySamplerOptions.MaxCartsPerTick} carts/tick, " + $"{telemetrySamplerOptions.MaxTrackedCarts} tracked max, evict after {telemetrySamplerOptions.EvictAfterSeconds:0.#} s.")); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Warnings: panel " + (settings.PanelWarningsEnabled.Value ? "on" : "off") + ", HUD hint " + (settings.HudWarningHintsEnabled.Value ? "on" : "off") + $", steep-climb caution at {settings.SteepGradeCautionPercent.Value:0.#}% " + $"(exit −{3f:0.#}%, " + $"fall hold {4.0:0.#} s).")); ((Component)this).gameObject.AddComponent().Initialize(settings, ((BaseUnityPlugin)this).Logger, cartTelemetryPump, ResolveInformationalVersion(), _logTail); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Cart Status panel armed: visible Cart button at the right screen edge while in a world, " + $"UI scale {UiScaleOptions.Clamp(settings.UiScale.Value):0.##}.")); } } private LoadModel? LoadCalibratedModel() { LoadCalibrationData loadCalibrationData = LoadCalibrationSource.TryLoadEmbedded(); if (loadCalibrationData == null || loadCalibrationData.DataVersion <= 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Load calibration data missing or unreadable; load advice stays off, all telemetry keeps working."); return null; } ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Load calibration v{loadCalibrationData.DataVersion} loaded: {loadCalibrationData.Rows.Count} rows " + $"({loadCalibrationData.MeasuredRowCount} measured) for game {loadCalibrationData.GameVersion}; " + ((loadCalibrationData.Errors.Count == 0) ? "no parse errors." : $"{loadCalibrationData.Errors.Count} malformed line(s) skipped."))); return new LoadModel(loadCalibrationData); } private RiskModel? LoadDescentModel() { DescentCalibrationData descentCalibrationData = DescentCalibrationSource.TryLoadEmbedded(); if (descentCalibrationData == null || descentCalibrationData.DataVersion <= 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Descent calibration data missing or unreadable; descent risk stays Unknown, all telemetry keeps working."); return null; } ((BaseUnityPlugin)this).Logger.LogInfo((object)($"Descent calibration v{descentCalibrationData.DataVersion} loaded: {descentCalibrationData.Rows.Count} rows " + $"({descentCalibrationData.MeasuredRowCount} measured) for game {descentCalibrationData.GameVersion}; " + ((descentCalibrationData.Errors.Count == 0) ? "no parse errors." : $"{descentCalibrationData.Errors.Count} malformed line(s) skipped."))); return new RiskModel(descentCalibrationData); } private void LogCartCapability(TeamsterSettings settings) { GameCapabilityReport gameCapabilityReport = CartAdapter.ProbeCapability(); if (gameCapabilityReport.Enabled) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Cart telemetry capability ENABLED: {gameCapabilityReport.VerifiedMembers.Count} game members verified."); if (settings.DebugLogging.Value) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Verified cart members: " + string.Join(", ", gameCapabilityReport.VerifiedMembers))); } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Cart telemetry capability DISABLED: missing " + string.Join(", ", gameCapabilityReport.MissingMembers) + ". A Valheim update likely changed cart internals; cart features stay off until a Concerned Teamster update, and everything else keeps working.")); } } private void LogEnvironmentBanner() { string bepInExVersion = "unknown"; string jotunnVersion = "unknown"; string unityVersion = "unknown"; try { bepInExVersion = typeof(BaseUnityPlugin).Assembly.GetName().Version?.ToString() ?? "unknown"; jotunnVersion = typeof(Main).Assembly.GetName().Version?.ToString() ?? "unknown"; unityVersion = Application.unityVersion; } catch { } ((BaseUnityPlugin)this).Logger.LogInfo((object)EnvironmentBanner.Compose("ConcernedTeamster@" + ResolveInformationalVersion(), GameVersionResolver.Resolve(), unityVersion, bepInExVersion, jotunnVersion)); } private static string ResolveInformationalVersion() { try { return typeof(Plugin).Assembly.GetCustomAttribute()?.InformationalVersion ?? "1.0.1"; } catch { return "1.0.1"; } } } internal sealed class TeamsterSettings { public ConfigEntry Enabled { get; } public ConfigEntry DebugLogging { get; } public ConfigEntry SampleIntervalSeconds { get; } public ConfigEntry SearchRadiusMeters { get; } public ConfigEntry MaxCartsPerTick { get; } public ConfigEntry MaxTrackedCarts { get; } public ConfigEntry PanelShortcut { get; } public ConfigEntry PanelWarningsEnabled { get; } public ConfigEntry HudWarningHintsEnabled { get; } public ConfigEntry SteepGradeCautionPercent { get; } public ConfigEntry RiskLookaheadPoints { get; } public ConfigEntry BrakeEnabled { get; } public ConfigEntry TripsEnabled { get; } public ConfigEntry TripRecordSpacingSeconds { get; } public ConfigEntry TripMaxSamplesPerTrip { get; } public ConfigEntry TripMaxTripsRetained { get; } public ConfigEntry UiScale { get; } public ConfigEntry OnboardingDismissed { get; } public ConfigEntry ActiveProfile { get; } public ConfigEntry LastAppliedProfile { get; } public ConfigEntry SchemaVersion { get; } private TeamsterSettings(ConfigEntry enabled, ConfigEntry debugLogging, ConfigEntry sampleIntervalSeconds, ConfigEntry searchRadiusMeters, ConfigEntry maxCartsPerTick, ConfigEntry maxTrackedCarts, ConfigEntry panelShortcut, ConfigEntry panelWarningsEnabled, ConfigEntry hudWarningHintsEnabled, ConfigEntry steepGradeCautionPercent, ConfigEntry riskLookaheadPoints, ConfigEntry brakeEnabled, ConfigEntry tripsEnabled, ConfigEntry tripRecordSpacingSeconds, ConfigEntry tripMaxSamplesPerTrip, ConfigEntry tripMaxTripsRetained, ConfigEntry uiScale, ConfigEntry onboardingDismissed, ConfigEntry activeProfile, ConfigEntry lastAppliedProfile, ConfigEntry schemaVersion) { Enabled = enabled; DebugLogging = debugLogging; SampleIntervalSeconds = sampleIntervalSeconds; SearchRadiusMeters = searchRadiusMeters; MaxCartsPerTick = maxCartsPerTick; MaxTrackedCarts = maxTrackedCarts; PanelShortcut = panelShortcut; PanelWarningsEnabled = panelWarningsEnabled; HudWarningHintsEnabled = hudWarningHintsEnabled; SteepGradeCautionPercent = steepGradeCautionPercent; RiskLookaheadPoints = riskLookaheadPoints; BrakeEnabled = brakeEnabled; TripsEnabled = tripsEnabled; TripRecordSpacingSeconds = tripRecordSpacingSeconds; TripMaxSamplesPerTrip = tripMaxSamplesPerTrip; TripMaxTripsRetained = tripMaxTripsRetained; UiScale = uiScale; OnboardingDismissed = onboardingDismissed; ActiveProfile = activeProfile; LastAppliedProfile = lastAppliedProfile; SchemaVersion = schemaVersion; } public static TeamsterSettings Bind(ConfigFile config) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown return new TeamsterSettings(config.Bind("General", "Enabled", true, "Master switch for Concerned Teamster cart telemetry features. Disabling leaves carts fully vanilla; the mod never changes cart physics by default either way."), config.Bind("Diagnostics", "DebugLogging", false, "Write diagnostic messages for Teamster feature development. Never enables per-frame logging."), config.Bind("Telemetry", "SampleIntervalSeconds", 0.5f, new ConfigDescription("Seconds between cart telemetry samples. Read-only observation of nearby carts; between samples the cost is one comparison per frame.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 10f), Array.Empty())), config.Bind("Telemetry", "SearchRadiusMeters", 30f, new ConfigDescription("Carts farther than this from you are not observed.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 100f), Array.Empty())), config.Bind("Telemetry", "MaxCartsPerTick", 2, new ConfigDescription("Hard budget of carts examined per telemetry tick.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 8), Array.Empty())), config.Bind("Telemetry", "MaxTrackedCarts", 8, new ConfigDescription("Hard cap of carts kept in the telemetry table at once.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 32), Array.Empty())), config.Bind("Ui", "PanelShortcut", KeyboardShortcut.Empty, "Optional keyboard accelerator that toggles the Cart Status panel. The visible Cart button is always the primary path; leave empty for no shortcut."), config.Bind("Warnings", "PanelWarningsEnabled", true, "Show load/grade warnings in the Cart Status panel."), config.Bind("Warnings", "HudWarningHintsEnabled", false, "Also show the current warning as a small HUD hint under the Cart button while pulling. Off by default: the panel is the primary surface and HUD space is precious; enable if you haul with the panel closed."), config.Bind("Warnings", "SteepGradeCautionPercent", 18f, new ConfigDescription("Smoothed climbing grade (percent) that raises the steep-climb caution. Exit hysteresis and anti-flicker hold are fixed so no configuration can make warnings spam.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 60f), Array.Empty())), config.Bind("Risk", "LookaheadPoints", 3, new ConfigDescription("Terrain samples taken ahead of the pulled cart (4 m apart) to rate the upcoming descent. 0 disables lookahead. Each sample is one bounded ground-height read per telemetry tick.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 5), Array.Empty())), config.Bind("Brake", "Enabled", true, "The parking brake feature: a visible button that freezes a parked cart you control until you release it. Explicit per-use, always reversible, never saved into the world, and it releases itself on detach distance, world exit, shutdown, or any capability loss. Disable to remove the button entirely."), config.Bind("Trips", "Enabled", true, "Record hauling trips (position, grade, speed, load while you pull) into Teamster's own per-world sidecar file under BepInEx/config. Never touches Valheim saves; delete the sidecar folder to erase all history."), config.Bind("Trips", "RecordSpacingSeconds", 1f, new ConfigDescription("Seconds between recorded trip samples while pulling.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 10f), Array.Empty())), config.Bind("Trips", "MaxSamplesPerTrip", 600, new ConfigDescription("Hard cap of samples in one trip; longer hauls split into segments.", (AcceptableValueBase)(object)new AcceptableValueRange(50, 5000), Array.Empty())), config.Bind("Trips", "MaxTripsRetained", 50, new ConfigDescription("Retention: how many trips each world's sidecar keeps; the oldest are pruned first.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 500), Array.Empty())), config.Bind("Ui", "Scale", 1f, new ConfigDescription("Uniform size of every Teamster panel, button, and font. 1.0 is the default size; takes effect the next time a panel opens (or on world enter for the always-visible Cart button), not live on an already-open panel.", (AcceptableValueBase)(object)new AcceptableValueRange(0.8f, 1.3f), Array.Empty())), config.Bind("Onboarding", "Dismissed", false, "Set automatically once you dismiss the first-run hint pointing at the Cart button. Set back to false to see the hint again."), config.Bind("General", "Profile", ConfigProfile.Standard, "A documented settings preset: Minimal (telemetry only, warnings/HUD hints/trips off), Standard (Teamster's normal defaults), or EverythingObservational (every read-only feature on). The parking brake stays off in every profile — enable Brake.Enabled yourself if you want it. Changing this re-applies the preset's values once, on the next load; your own edits to individual settings are never overwritten again until you change this value to something else."), config.Bind("General", "LastAppliedProfile", ConfigProfile.Standard, "Internal bookkeeping — do not edit. Records which profile was last applied so a restart with no Profile change never re-applies it."), config.Bind("Internal", "ConfigSchemaVersion", 0, "Internal bookkeeping — do not edit. Tracks which version of Teamster's config schema this file was last written by, so a future update can migrate safely.")); } } } namespace TheConcernedCat.ConcernedTeamster.Ui { internal sealed class CargoManifestPanel { private const float PanelWidth = 420f; private const float PanelHeight = 470f; private const float RowHeight = 24f; private const int VisibleRowCount = 12; private const double ViewTickSeconds = 1.0; private readonly ManualLogSource _log; private readonly Func _uiScale; private readonly CargoManifestTracker _tracker = new CargoManifestTracker(); private bool _failed; private GameObject? _panel; private InputField? _filter; private Text?[] _rows = Array.Empty(); private Text? _message; private Text? _overflow; private Text? _total; private Text? _freshness; private Button? _sortNameButton; private Button? _sortCountButton; private Button? _sortUnitButton; private Button? _sortLineButton; private CargoSortColumn _sortColumn = CargoSortColumn.LineWeight; private bool _sortDescending = true; private string _lastAppliedFilter = string.Empty; private CargoManifest? _lastAppliedManifest; private bool _viewDirty = true; private double _nextViewTick; public bool IsVisible { get { if ((Object)(object)_panel != (Object)null) { return _panel.activeSelf; } return false; } } public CargoManifestPanel(ManualLogSource log, Func uiScale) { _log = log; _uiScale = uiScale; } public void Toggle() { if (_failed) { return; } try { if (!((Object)(object)_panel == (Object)null) || Build()) { bool flag = !_panel.activeSelf; _panel.SetActive(flag); if (flag) { _viewDirty = true; _nextViewTick = 0.0; } } } catch (Exception exception) { Fail(exception); } } public void Hide() { if ((Object)(object)_panel != (Object)null && _panel.activeSelf) { _panel.SetActive(false); } } public void Reset() { _tracker.Reset(); _lastAppliedManifest = null; _viewDirty = true; Hide(); } public void HandleFrame(double nowSeconds, string? selectedCartId) { if (_failed || !IsVisible) { return; } try { if (Input.GetKeyDown((KeyCode)27)) { Hide(); } else { if (!_viewDirty && nowSeconds < _nextViewTick) { return; } _nextViewTick = nowSeconds + 1.0; CargoManifest orRefresh = _tracker.GetOrRefresh(nowSeconds, (double captureTime) => CartAdapter.TryReadManifest(CartAdapter.TryFindCartById(selectedCartId), captureTime)); string text = (((Object)(object)_filter != (Object)null) ? _filter.text : string.Empty); if (!_viewDirty && orRefresh == _lastAppliedManifest && string.Equals(text, _lastAppliedFilter, StringComparison.Ordinal)) { if (orRefresh != null && (Object)(object)_freshness != (Object)null) { CargoManifestViewModel cargoManifestViewModel = CargoManifestPresenter.Present(orRefresh, _sortColumn, _sortDescending, text, nowSeconds, GameLocalization.LocalizeOrRaw); _freshness.text = cargoManifestViewModel.FreshnessLine; } } else { _lastAppliedManifest = orRefresh; _lastAppliedFilter = text; _viewDirty = false; Render(CargoManifestPresenter.Present(orRefresh, _sortColumn, _sortDescending, text, nowSeconds, GameLocalization.LocalizeOrRaw)); } } } catch (Exception exception) { Fail(exception); } } private void Render(CargoManifestViewModel viewModel) { if ((Object)(object)_message != (Object)null) { _message.text = viewModel.Message; } int num = Math.Min(viewModel.Rows.Count, 12); for (int i = 0; i < _rows.Length; i++) { Text val = _rows[i]; if (!((Object)(object)val == (Object)null)) { if (i < num) { CargoRowViewModel cargoRowViewModel = viewModel.Rows[i]; val.text = TeamsterStrings.Format("manifest.row", cargoRowViewModel.Name, cargoRowViewModel.CountText, cargoRowViewModel.UnitWeightText, cargoRowViewModel.LineWeightText); } else { val.text = string.Empty; } } } if ((Object)(object)_overflow != (Object)null) { int num2 = viewModel.Rows.Count - num; _overflow.text = ((num2 > 0) ? TeamsterStrings.Format("manifest.overflow", num2.ToString(CultureInfo.InvariantCulture)) : string.Empty); } if ((Object)(object)_total != (Object)null) { _total.text = viewModel.TotalLine; } if ((Object)(object)_freshness != (Object)null) { _freshness.text = viewModel.FreshnessLine; } UpdateSortButtonLabels(); } private void SetSort(CargoSortColumn column) { if (_sortColumn == column) { _sortDescending = !_sortDescending; } else { _sortColumn = column; _sortDescending = column != CargoSortColumn.Name; } _viewDirty = true; UpdateSortButtonLabels(); } private void UpdateSortButtonLabels() { string text = (_sortDescending ? " ▼" : " ▲"); SetButtonLabel(_sortNameButton, TeamsterStrings.Get("manifest.colItem") + ((_sortColumn == CargoSortColumn.Name) ? text : string.Empty)); SetButtonLabel(_sortCountButton, TeamsterStrings.Get("manifest.colCount") + ((_sortColumn == CargoSortColumn.Count) ? text : string.Empty)); SetButtonLabel(_sortUnitButton, TeamsterStrings.Get("manifest.colUnit") + ((_sortColumn == CargoSortColumn.UnitWeight) ? text : string.Empty)); SetButtonLabel(_sortLineButton, TeamsterStrings.Get("manifest.colLine") + ((_sortColumn == CargoSortColumn.LineWeight) ? text : string.Empty)); } private static void SetButtonLabel(Button? button, string label) { if (!((Object)(object)button == (Object)null)) { Text componentInChildren = ((Component)button).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = label; } } } private bool Build() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0063: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Expected O, but got Unknown if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null) { return false; } GUIManager instance = GUIManager.Instance; Font averiaSerifBold = instance.AveriaSerifBold; Color header = PanelStyle.Header; Color body = PanelStyle.Body; _panel = PanelStyle.CreateScaledWoodpanel(instance, GUIManager.CustomGUIFront.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-590f, 0f), 420f, 470f, _uiScale()); instance.CreateText(TeamsterStrings.Get("manifest.title"), _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -28f), averiaSerifBold, 19, header, true, Color.black, 380f, 30f, false); GameObject val = instance.CreateInputField(_panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -62f), (ContentType)0, TeamsterStrings.Get("manifest.filterPlaceholder"), 15, 360f, 28f); _filter = val.GetComponent(); if ((Object)(object)_filter != (Object)null) { ((UnityEvent)(object)_filter.onValueChanged).AddListener((UnityAction)delegate { _viewDirty = true; }); } float num = 90f; float num2 = -180f + num / 2f; _sortNameButton = CreateSortButton(instance, num2 + 0f * num, num, delegate { SetSort(CargoSortColumn.Name); }); _sortCountButton = CreateSortButton(instance, num2 + 1f * num, num, delegate { SetSort(CargoSortColumn.Count); }); _sortUnitButton = CreateSortButton(instance, num2 + 2f * num, num, delegate { SetSort(CargoSortColumn.UnitWeight); }); _sortLineButton = CreateSortButton(instance, num2 + 3f * num, num, delegate { SetSort(CargoSortColumn.LineWeight); }); _message = CreateBodyText(instance, averiaSerifBold, body, -128f, 24f); _rows = (Text?[])(object)new Text[12]; float num3 = -152f; for (int num4 = 0; num4 < 12; num4++) { _rows[num4] = CreateBodyText(instance, averiaSerifBold, body, num3, 24f); num3 -= 24f; } _overflow = CreateBodyText(instance, averiaSerifBold, body, num3, 24f); _total = CreateBodyText(instance, averiaSerifBold, header, num3 - 24f, 24f); _freshness = CreateBodyText(instance, averiaSerifBold, body, num3 - 48f, 24f); ((UnityEvent)instance.CreateButton(TeamsterStrings.Get("ui.close"), _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 26f), 110f, 28f).GetComponent