Decompiled source of VesselTrails v1.3.2

VesselTrails.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using CommonAPI.Systems;
using DysonSphereMods.Shared;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("Valoneu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyDescription("Visualizes logistics vessel routes in the Star Map.")]
[assembly: AssemblyFileVersion("1.3.2.0")]
[assembly: AssemblyInformationalVersion("1.3.2+28cd33c1b9dcbc30f7c776c691eeca2686efbc35")]
[assembly: AssemblyProduct("DysonSphereMods")]
[assembly: AssemblyTitle("VesselTrails")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DysonSphereMods.Shared
{
	public static class Log
	{
		private static ManualLogSource _logger;

		public static void Init(ManualLogSource logger)
		{
			_logger = logger;
		}

		public static void Debug(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogDebug(data);
			}
		}

		public static void Info(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogInfo(data);
			}
		}

		public static void Warning(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogWarning(data);
			}
		}

		public static void Error(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError(data);
			}
		}

		public static void Fatal(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogFatal(data);
			}
		}

		public static void Message(object data)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogMessage(data);
			}
		}

		public static void LogOnce(string msg, ref bool flag, params object[] args)
		{
			if (flag)
			{
				return;
			}
			flag = true;
			try
			{
				string[] array = ((args == null) ? Array.Empty<string>() : args.Select((object arg) => (arg != null) ? ((!(arg is int) && !(arg is string) && !arg.GetType().IsPrimitive) ? JsonUtility.ToJson(arg) : arg.ToString()) : "null").ToArray());
				object[] args2 = array;
				Info(string.Format(msg, args2));
			}
			catch (Exception arg2)
			{
				Warning($"LogOnce failed to format message: {msg}. Exception: {arg2}");
			}
		}
	}
	public static class MultiplierService
	{
		private static readonly Dictionary<string, float> _multipliers = new Dictionary<string, float>();

		private static bool _isDirty;

		public static event Action OnMultipliersChanged;

		public static void SetMultiplier(string key, float value)
		{
			if (!_multipliers.TryGetValue(key, out var value2) || Math.Abs(value2 - value) > 0.0001f)
			{
				_multipliers[key] = value;
				_isDirty = true;
			}
		}

		public static float GetMultiplier(string key, float defaultValue = 1f)
		{
			if (!_multipliers.TryGetValue(key, out var value))
			{
				return defaultValue;
			}
			return value;
		}

		public static void CommitChanges()
		{
			if (_isDirty)
			{
				_isDirty = false;
				MultiplierService.OnMultipliersChanged?.Invoke();
			}
		}
	}
	public static class TickManager
	{
		private static long _lastSlowTick = -1L;

		private static long _lastLazyTick = -1L;

		private static bool _patched = false;

		public static event Action OnSlowTick;

		public static event Action OnLazyTick;

		public static void Patch(Harmony harmony)
		{
			if (!_patched)
			{
				_patched = true;
				harmony.PatchAll(typeof(TickManager));
			}
		}

		[HarmonyPatch(typeof(GameMain), "Begin")]
		[HarmonyPostfix]
		public static void Init()
		{
			_lastSlowTick = -1L;
			_lastLazyTick = -1L;
		}

		[HarmonyPatch(typeof(GameLogic), "LogicFrame")]
		[HarmonyPostfix]
		public static void GameTick()
		{
			long gameTick = GameMain.gameTick;
			if (gameTick / 60 > _lastSlowTick)
			{
				_lastSlowTick = gameTick / 60;
				TickManager.OnSlowTick?.Invoke();
			}
			if (gameTick / 600 > _lastLazyTick)
			{
				_lastLazyTick = gameTick / 600;
				TickManager.OnLazyTick?.Invoke();
			}
		}
	}
	public abstract class WindowBase
	{
		public Rect WindowRect;

		protected Vector2 ScrollPos;

		private bool _isResizing;

		private Rect _resizeRect = new Rect(0f, 0f, 15f, 15f);

		public Vector2 MinSize = new Vector2(300f, 200f);

		public int WindowId { get; protected set; }

		public string Title { get; set; }

		public bool IsVisible { get; set; }

		protected WindowBase(int windowId, string title, Rect defaultRect)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			WindowId = windowId;
			Title = title;
			WindowRect = defaultRect;
		}

		public virtual void OnGUI()
		{
			//IL_001d: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (IsVisible)
			{
				GUI.backgroundColor = new Color(0.08f, 0.12f, 0.22f, 0.95f);
				WindowRect = GUILayout.Window(WindowId, WindowRect, new WindowFunction(DrawWindowInternal), Title, Array.Empty<GUILayoutOption>());
				GUI.backgroundColor = Color.white;
				((Rect)(ref WindowRect)).x = Mathf.Clamp(((Rect)(ref WindowRect)).x, 0f - ((Rect)(ref WindowRect)).width + 50f, (float)(Screen.width - 50));
				((Rect)(ref WindowRect)).y = Mathf.Clamp(((Rect)(ref WindowRect)).y, -20f, (float)(Screen.height - 50));
			}
		}

		private void DrawWindowInternal(int id)
		{
			//IL_0008: 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_0086: 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)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_00dd: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Invalid comparison between Unknown and I4
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Invalid comparison between Unknown and I4
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			DrawWindowHeader();
			ScrollPos = GUILayout.BeginScrollView(ScrollPos, Array.Empty<GUILayoutOption>());
			DrawWindowContent();
			GUILayout.EndScrollView();
			DrawWindowFooter();
			((Rect)(ref _resizeRect)).x = ((Rect)(ref WindowRect)).width - 20f;
			((Rect)(ref _resizeRect)).y = ((Rect)(ref WindowRect)).height - 20f;
			((Rect)(ref _resizeRect)).width = 20f;
			((Rect)(ref _resizeRect)).height = 20f;
			GUI.Label(_resizeRect, "↘", new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 20,
				normal = new GUIStyleState
				{
					textColor = new Color(0.6f, 0.6f, 0.6f, 0.8f)
				}
			});
			Event current = Event.current;
			bool flag = false;
			if ((int)current.type == 0 && ((Rect)(ref _resizeRect)).Contains(current.mousePosition))
			{
				_isResizing = true;
				flag = true;
				current.Use();
			}
			else if ((int)current.type == 1)
			{
				_isResizing = false;
			}
			else if ((int)current.type == 3 && _isResizing)
			{
				ref Rect windowRect = ref WindowRect;
				((Rect)(ref windowRect)).width = ((Rect)(ref windowRect)).width + current.delta.x;
				ref Rect windowRect2 = ref WindowRect;
				((Rect)(ref windowRect2)).height = ((Rect)(ref windowRect2)).height + current.delta.y;
				((Rect)(ref WindowRect)).width = Mathf.Max(MinSize.x, ((Rect)(ref WindowRect)).width);
				((Rect)(ref WindowRect)).height = Mathf.Max(MinSize.y, ((Rect)(ref WindowRect)).height);
				current.Use();
			}
			if ((int)current.type == 0 && !flag)
			{
				GUIUtility.keyboardControl = 0;
			}
			GUI.DragWindow();
		}

		protected virtual void DrawWindowHeader()
		{
		}

		protected abstract void DrawWindowContent();

		protected virtual void DrawWindowFooter()
		{
		}

		public virtual void Toggle()
		{
			IsVisible = !IsVisible;
		}
	}
}
namespace VesselTrails
{
	[BepInPlugin("com.Valoneu.VesselTrails", "VesselTrails", "1.3.2")]
	[BepInProcess("DSPGAME.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[CommonAPISubmoduleDependency(new string[] { "ProtoRegistry", "CustomKeyBindSystem" })]
	public class VesselTrailsPlugin : BaseUnityPlugin
	{
		public enum ColorMode
		{
			Material,
			Heatmap
		}

		public const string MOD_GUID = "com.Valoneu.VesselTrails";

		public const string MOD_NAME = "VesselTrails";

		public const string MOD_VERSION = "1.3.2";

		public static ConfigEntry<bool> ShowTrails;

		public static ConfigEntry<bool> ShowHoverTooltips;

		public static ConfigEntry<float> TrailOpacity;

		public static ConfigEntry<float> TrailThicknessNormal;

		public static ConfigEntry<float> TrailThicknessStarmap;

		public static ConfigEntry<ColorMode> TrailColorMode;

		public static ConfigEntry<float> HistoryMinutes;

		public static ConfigEntry<float> WindowX;

		public static ConfigEntry<float> WindowY;

		public static ConfigEntry<float> WindowW;

		public static ConfigEntry<float> WindowH;

		private static VesselTrailsWindow _window;

		private static VesselTrailRenderer _renderer;

		private static VesselRouteManager _routeManager;

		public static float CurrentGameTime
		{
			get
			{
				if (GameMain.data == null)
				{
					return 0f;
				}
				return (float)GameMain.gameTick / 60f;
			}
		}

		private void Awake()
		{
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			ShowTrails = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "ShowTrails", true, "Whether to show vessel trails.");
			ShowHoverTooltips = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "ShowHoverTooltips", true, "Whether to show tooltips when hovering over trails.");
			TrailOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "TrailOpacity", 0.8f, "Overall trail opacity (0.0 to 1.0).");
			TrailThicknessNormal = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "TrailThicknessNormal", 1f, "Thickness multiplier for normal view.");
			TrailThicknessStarmap = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "TrailThicknessStarmap", 1f, "Thickness multiplier for star map.");
			TrailColorMode = ((BaseUnityPlugin)this).Config.Bind<ColorMode>("Visuals", "ColorMode", ColorMode.Heatmap, "Coloring mode: Material or Heatmap.");
			HistoryMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HistoryMinutes", 2f, "How many minutes of history to display (data always records 60 min).");
			WindowX = ((BaseUnityPlugin)this).Config.Bind<float>("Internal", "WindowX", 50f, "Window X position.");
			WindowY = ((BaseUnityPlugin)this).Config.Bind<float>("Internal", "WindowY", 50f, "Window Y position.");
			WindowW = ((BaseUnityPlugin)this).Config.Bind<float>("Internal", "WindowW", 500f, "Window width.");
			WindowH = ((BaseUnityPlugin)this).Config.Bind<float>("Internal", "WindowH", 600f, "Window height.");
			RegisterKeyBinds();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Harmony val = new Harmony("com.Valoneu.VesselTrails");
			TickManager.Patch(val);
			val.PatchAll(typeof(VesselTrailsPlugin));
			Log.Info("VesselTrails v1.3.2 loaded!");
		}

		private void RegisterKeyBinds()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!CustomKeyBindSystem.HasKeyBind("ToggleVesselTrailsUI"))
			{
				BuiltinKey val = default(BuiltinKey);
				val.id = 1220;
				val.key = new CombineKey(257, (byte)2, (ECombineKeyAction)0, false);
				val.conflictGroup = 2052;
				val.name = "ToggleVesselTrailsUI";
				val.canOverride = true;
				CustomKeyBindSystem.RegisterKeyBind<PressKeyBind>(val);
			}
			if (!CustomKeyBindSystem.HasKeyBind("ToggleVesselTrailsLines"))
			{
				BuiltinKey val = default(BuiltinKey);
				val.id = 1221;
				val.key = new CombineKey(259, (byte)2, (ECombineKeyAction)0, false);
				val.conflictGroup = 2052;
				val.name = "ToggleVesselTrailsLines";
				val.canOverride = true;
				CustomKeyBindSystem.RegisterKeyBind<PressKeyBind>(val);
			}
			ProtoRegistry.RegisterString("ToggleVesselTrailsUI", "Toggle Vessel Trails UI");
			ProtoRegistry.RegisterString("ToggleVesselTrailsLines", "Toggle Vessel Trails Lines");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameMain), "Begin")]
		public static void GameMain_Begin_Postfix()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			if (_routeManager == null)
			{
				_routeManager = new VesselRouteManager();
			}
			else
			{
				_routeManager.RoutePaths.Clear();
			}
			if (_window == null)
			{
				_window = new VesselTrailsWindow(_routeManager);
			}
			if ((Object)(object)_renderer == (Object)null)
			{
				GameObject val = new GameObject("VesselTrailRenderer");
				_renderer = val.AddComponent<VesselTrailRenderer>();
				_renderer.Init(_routeManager, _window);
				Object.DontDestroyOnLoad((Object)val);
			}
			VesselTrailPersistence.LoadTrailData(_routeManager);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameSave), "SaveCurrentGame")]
		public static void OnSave_Postfix()
		{
			if (_routeManager != null)
			{
				VesselTrailPersistence.SaveTrailData(_routeManager);
			}
		}
	}
	public class VesselRouteManager
	{
		public class RoutePath
		{
			public int StarA;

			public int StarB;

			public Dictionary<int, ItemHistory> ItemHistories = new Dictionary<int, ItemHistory>();

			public float TotalVessels => ItemHistories.Values.Sum((ItemHistory h) => h.AverageVesselCount);

			public int GetTotalTrips(float hMin)
			{
				return ItemHistories.Values.Sum((ItemHistory h) => h.GetTotalTrips(hMin));
			}

			public void UpdateItem(int itemId, List<int> shipKeys, float historyMinutes, float interval)
			{
				if (!ItemHistories.TryGetValue(itemId, out var value))
				{
					value = new ItemHistory
					{
						ItemId = itemId,
						FirstSeenTime = VesselTrailsPlugin.CurrentGameTime
					};
					ItemHistories[itemId] = value;
				}
				value.RecordSample(shipKeys, interval, historyMinutes);
			}

			public void CleanUp(float historyMinutes)
			{
				float lifetime = Mathf.Max(3600f, historyMinutes * 60f);
				foreach (int item in (from kvp in ItemHistories
					where VesselTrailsPlugin.CurrentGameTime - kvp.Value.LastSeenTime > lifetime
					select kvp.Key).ToList())
				{
					ItemHistories.Remove(item);
				}
			}
		}

		public class ItemHistory
		{
			public int ItemId;

			public float FirstSeenTime;

			public float LastSeenTime;

			public float AverageVesselCount;

			private Queue<int> _history = new Queue<int>();

			private long _historySum;

			public List<float> TripStartTimes = new List<float>();

			public HashSet<int> ActiveShipKeys = new HashSet<int>();

			public void RecordSample(List<int> shipKeys, float interval, float historyMinutes)
			{
				int count = shipKeys.Count;
				_history.Enqueue(count);
				_historySum += count;
				int num = Mathf.Max(1, (int)(3600f / interval));
				while (_history.Count > num)
				{
					_historySum -= _history.Dequeue();
				}
				AverageVesselCount = (float)_historySum / (float)_history.Count;
				LastSeenTime = VesselTrailsPlugin.CurrentGameTime;
				foreach (int shipKey in shipKeys)
				{
					if (!ActiveShipKeys.Contains(shipKey))
					{
						TripStartTimes.Add(VesselTrailsPlugin.CurrentGameTime);
						ActiveShipKeys.Add(shipKey);
					}
				}
				ActiveShipKeys.IntersectWith(shipKeys);
			}

			public int GetTotalTrips(float windowMin)
			{
				float num = windowMin * 60f;
				if (num <= 0f)
				{
					num = 60f;
				}
				float cutoff = VesselTrailsPlugin.CurrentGameTime - num;
				TripStartTimes.RemoveAll((float t) => t < cutoff - 120f);
				return TripStartTimes.Count((float t) => t >= cutoff);
			}

			public float GetEffectiveMinutes(float windowMin)
			{
				float num = windowMin * 60f;
				if (num <= 0f)
				{
					num = 60f;
				}
				float num2 = VesselTrailsPlugin.CurrentGameTime - num;
				float num3 = VesselTrailsPlugin.CurrentGameTime;
				foreach (float tripStartTime in TripStartTimes)
				{
					if (tripStartTime >= num2 && tripStartTime < num3)
					{
						num3 = tripStartTime;
					}
				}
				return Mathf.Clamp((VesselTrailsPlugin.CurrentGameTime - num3) / 60f, 0.1f, windowMin);
			}

			public float GetAlpha(float lifetimeSecs)
			{
				float num = VesselTrailsPlugin.CurrentGameTime - FirstSeenTime;
				float num2 = VesselTrailsPlugin.CurrentGameTime - LastSeenTime;
				float num3 = Mathf.Clamp01(num / 10f);
				float num4 = Mathf.Clamp01(1f - num2 / lifetimeSecs);
				return num3 * num4;
			}

			public Color GetColor(float min, float max)
			{
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: 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_0071: Unknown result type (might be due to invalid IL or missing references)
				if (VesselTrailsPlugin.TrailColorMode.Value == VesselTrailsPlugin.ColorMode.Heatmap)
				{
					float num = Mathf.Log(max + 1f);
					float num2 = Mathf.Log(min + 1f);
					float num3 = Mathf.Log(AverageVesselCount + 1f);
					float num4 = num - num2;
					float num5 = ((num4 < 0.01f) ? 0f : Mathf.Clamp01((num3 - num2) / num4));
					if (num5 < 0.5f)
					{
						return Color.Lerp(Color.green, Color.yellow, num5 * 2f);
					}
					return Color.Lerp(Color.yellow, Color.red, (num5 - 0.5f) * 2f);
				}
				return GetItemColor(ItemId);
			}

			public static Color GetItemColor(int itemId)
			{
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				return (Color)(itemId switch
				{
					1001 => new Color(0.4f, 0.6f, 0.9f), 
					1002 => new Color(0.9f, 0.5f, 0.2f), 
					1003 => new Color(0.2f, 0.8f, 1f), 
					1120 => new Color(0.1f, 0.9f, 1f), 
					1121 => new Color(0.2f, 0.2f, 1f), 
					1122 => new Color(1f, 0.1f, 0.1f), 
					1210 => new Color(0.1f, 1f, 0.3f), 
					6006 => Color.white, 
					_ => new Color(0.4f, 0.7f, 1f), 
				});
			}
		}

		public class UICache
		{
			public class ItemData
			{
				public int ItemId;

				public string ItemName;

				public int TotalTrips;

				public float PerMin;

				public float Load;
			}

			public class RouteData
			{
				public int StarA;

				public int StarB;

				public string StarAName;

				public string StarBName;

				public List<ItemData> Items = new List<ItemData>();

				public int TotalTrips;
			}

			public List<RouteData> SortedRoutes = new List<RouteData>();

			public int ClusterTotalTrips;

			public float ClusterTotalLoad;

			public float ClusterTripsPerMin;

			public float LastRefreshTime;
		}

		public Dictionary<(int, int), RoutePath> RoutePaths { get; } = new Dictionary<(int, int), RoutePath>();


		public float GlobalMaxTraffic { get; private set; } = 1f;


		public float GlobalMinTraffic { get; private set; }

		public UICache Cache { get; private set; } = new UICache();


		public VesselRouteManager()
		{
			TickManager.OnSlowTick += UpdateData;
		}

		private void UpdateData()
		{
			//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_0070: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (GameMain.data == null || GameMain.data.galacticTransport == null)
			{
				return;
			}
			GalacticTransport galacticTransport = GameMain.data.galacticTransport;
			Dictionary<(int, int, int), List<int>> dictionary = new Dictionary<(int, int, int), List<int>>();
			for (int i = 1; i < galacticTransport.stationCursor; i++)
			{
				StationComponent val = galacticTransport.stationPool[i];
				if (val == null || val.id <= 0 || val.workShipDatas == null)
				{
					continue;
				}
				for (int j = 0; j < val.workShipDatas.Length; j++)
				{
					ShipData val2 = val.workShipDatas[j];
					if (val2.otherGId <= 0)
					{
						continue;
					}
					int num = val2.planetA / 100;
					int num2 = val2.planetB / 100;
					if (num != num2 && num > 0 && num2 > 0)
					{
						(int, int, int) key = ((num < num2) ? (num, num2, val2.itemId) : (num2, num, val2.itemId));
						if (!dictionary.TryGetValue(key, out var value))
						{
							value = (dictionary[key] = new List<int>());
						}
						int item = (val.gid << 16) | (j & 0xFFFF);
						value.Add(item);
					}
				}
			}
			float value2 = VesselTrailsPlugin.HistoryMinutes.Value;
			HashSet<(int, int, int)> hashSet = new HashSet<(int, int, int)>();
			foreach (KeyValuePair<(int, int, int), List<int>> item2 in dictionary)
			{
				(int, int) key2 = (item2.Key.Item1, item2.Key.Item2);
				if (!RoutePaths.TryGetValue(key2, out var value3))
				{
					value3 = new RoutePath
					{
						StarA = item2.Key.Item1,
						StarB = item2.Key.Item2
					};
					RoutePaths[key2] = value3;
				}
				value3.UpdateItem(item2.Key.Item3, item2.Value, value2, 1f);
				hashSet.Add(item2.Key);
			}
			foreach (RoutePath value4 in RoutePaths.Values)
			{
				foreach (int key3 in value4.ItemHistories.Keys)
				{
					if (!hashSet.Contains((value4.StarA, value4.StarB, key3)))
					{
						value4.ItemHistories[key3].RecordSample(new List<int>(), 1f, value2);
					}
				}
			}
			GlobalMaxTraffic = 0f;
			GlobalMinTraffic = float.MaxValue;
			List<(int, int)> list2 = new List<(int, int)>();
			foreach (KeyValuePair<(int, int), RoutePath> routePath in RoutePaths)
			{
				routePath.Value.CleanUp(value2);
				if (routePath.Value.ItemHistories.Count == 0)
				{
					list2.Add(routePath.Key);
					continue;
				}
				foreach (ItemHistory value5 in routePath.Value.ItemHistories.Values)
				{
					GlobalMaxTraffic = Mathf.Max(GlobalMaxTraffic, value5.AverageVesselCount);
					GlobalMinTraffic = Mathf.Min(GlobalMinTraffic, value5.AverageVesselCount);
				}
			}
			foreach (var item3 in list2)
			{
				RoutePaths.Remove(item3);
			}
			if (GlobalMinTraffic == float.MaxValue)
			{
				GlobalMinTraffic = 0f;
			}
			if (VesselTrailsPlugin.CurrentGameTime - Cache.LastRefreshTime > 1f / 60f)
			{
				RefreshUICache();
			}
		}

		private void RefreshUICache()
		{
			float value = VesselTrailsPlugin.HistoryMinutes.Value;
			List<UICache.RouteData> list = new List<UICache.RouteData>();
			int num = 0;
			float num2 = 0f;
			float num3 = 0.1f;
			foreach (RoutePath value2 in RoutePaths.Values)
			{
				UICache.RouteData obj = new UICache.RouteData
				{
					StarA = value2.StarA,
					StarB = value2.StarB
				};
				StarData obj2 = GameMain.galaxy.StarById(value2.StarA);
				obj.StarAName = ((obj2 != null) ? obj2.displayName : null) ?? "Unknown";
				StarData obj3 = GameMain.galaxy.StarById(value2.StarB);
				obj.StarBName = ((obj3 != null) ? obj3.displayName : null) ?? "Unknown";
				UICache.RouteData routeData = obj;
				foreach (ItemHistory value3 in value2.ItemHistories.Values)
				{
					int totalTrips = value3.GetTotalTrips(value);
					float effectiveMinutes = value3.GetEffectiveMinutes(value);
					float perMin = (float)totalTrips / Mathf.Max(0.1f, effectiveMinutes);
					List<UICache.ItemData> items = routeData.Items;
					UICache.ItemData obj4 = new UICache.ItemData
					{
						ItemId = value3.ItemId
					};
					ItemProto obj5 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(value3.ItemId);
					obj4.ItemName = ((obj5 != null) ? ((Proto)obj5).name : null) ?? "Unknown";
					obj4.TotalTrips = totalTrips;
					obj4.PerMin = perMin;
					obj4.Load = value3.AverageVesselCount;
					items.Add(obj4);
					num += totalTrips;
					num2 += value3.AverageVesselCount;
					if (effectiveMinutes > num3)
					{
						num3 = effectiveMinutes;
					}
				}
				routeData.Items = routeData.Items.OrderByDescending((UICache.ItemData i) => i.TotalTrips).ToList();
				routeData.TotalTrips = routeData.Items.Sum((UICache.ItemData i) => i.TotalTrips);
				if (routeData.TotalTrips > 0 || routeData.Items.Any((UICache.ItemData i) => i.Load > 0.01f))
				{
					list.Add(routeData);
				}
			}
			Cache.SortedRoutes = list.OrderByDescending((UICache.RouteData r) => r.TotalTrips).Take(100).ToList();
			Cache.ClusterTotalTrips = num;
			Cache.ClusterTotalLoad = num2;
			Cache.ClusterTripsPerMin = (float)num / num3;
			Cache.LastRefreshTime = VesselTrailsPlugin.CurrentGameTime;
		}
	}
	public class VesselTrailRenderer : MonoBehaviour
	{
		private static Material _trailMaterial;

		private VesselRouteManager _manager;

		private VesselTrailsWindow _window;

		private VesselRouteManager.RoutePath _hoveredRoute;

		private Vector2 _mousePos;

		private Vector2 _hoverScrollPos;

		public void Init(VesselRouteManager manager, VesselTrailsWindow window)
		{
			_manager = manager;
			_window = window;
		}

		private void Update()
		{
			if (CustomKeyBindSystem.GetKeyBind("ToggleVesselTrailsUI").keyValue)
			{
				_window.Toggle();
			}
			if (CustomKeyBindSystem.GetKeyBind("ToggleVesselTrailsLines").keyValue)
			{
				VesselTrailsPlugin.ShowTrails.Value = !VesselTrailsPlugin.ShowTrails.Value;
			}
		}

		private void LateUpdate()
		{
			//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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: 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_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			if (_manager == null)
			{
				return;
			}
			UIStarmap val = UIRoot.instance?.uiGame?.starmap;
			bool flag = (Object)(object)val != (Object)null && ((ManualBehaviour)val).active;
			Camera val2 = (flag ? val.screenCamera : Camera.main);
			_hoveredRoute = null;
			float num = 0.05f;
			_mousePos = Vector2.op_Implicit(Input.mousePosition);
			Ray ray = (Ray)(((Object)(object)val2 != (Object)null) ? val2.ScreenPointToRay(Vector2.op_Implicit(_mousePos)) : default(Ray));
			int num2 = -2097102335;
			RaycastHit val6 = default(RaycastHit);
			foreach (KeyValuePair<(int, int), VesselRouteManager.RoutePath> routePath in _manager.RoutePaths)
			{
				if (!((Object)(object)val2 != (Object)null))
				{
					continue;
				}
				Vector3 starVPos = GetStarVPos(routePath.Value.StarA, flag);
				Vector3 starVPos2 = GetStarVPos(routePath.Value.StarB, flag);
				float num3 = DistanceRayToSegment(ray, starVPos, starVPos2);
				float num4 = Vector3.Distance(((Component)val2).transform.position, (starVPos + starVPos2) * 0.5f);
				float num5 = num3 / num4;
				if (!(num5 < num))
				{
					continue;
				}
				Vector3 val3 = starVPos2 - starVPos;
				float num6 = Mathf.Clamp01(Vector3.Dot(((Ray)(ref ray)).origin + ((Ray)(ref ray)).direction * num4 - starVPos, val3) / Vector3.Dot(val3, val3));
				Vector3 val4 = starVPos + num6 * val3;
				float num7 = Vector3.Distance(((Component)val2).transform.position, val4);
				bool flag2 = false;
				Vector3 position = ((Component)val2).transform.position;
				Vector3 val5 = val4 - ((Component)val2).transform.position;
				if (Physics.Raycast(position, ((Vector3)(ref val5)).normalized, ref val6, num7, num2) && ((RaycastHit)(ref val6)).distance < num7 * 0.99f)
				{
					flag2 = true;
				}
				if (!flag2)
				{
					if (flag)
					{
						if ((Object)(object)val != (Object)null && val.planetUIs != null)
						{
							UIStarmapPlanet[] planetUIs = val.planetUIs;
							foreach (UIStarmapPlanet val7 in planetUIs)
							{
								if ((Object)(object)val7 == (Object)null || !((ManualBehaviour)val7).active || (Object)(object)val7.planetRenderer == (Object)null)
								{
									continue;
								}
								Vector3 position2 = ((Component)val7.planetRenderer).transform.position;
								if (Vector3.Distance(((Component)val2).transform.position, position2) < num7 * 0.99f)
								{
									val5 = Vector3.Cross(((Ray)(ref ray)).direction, position2 - ((Ray)(ref ray)).origin);
									float magnitude = ((Vector3)(ref val5)).magnitude;
									float num8 = val7.planet.realRadius * 0.00025f * 2f;
									if (magnitude < num8)
									{
										flag2 = true;
										break;
									}
								}
							}
						}
					}
					else
					{
						UniverseSimulator universeSimulator = GameMain.universeSimulator;
						if ((Object)(object)universeSimulator != (Object)null && universeSimulator.planetSimulators != null)
						{
							PlanetSimulator[] planetSimulators = universeSimulator.planetSimulators;
							foreach (PlanetSimulator val8 in planetSimulators)
							{
								if ((Object)(object)val8 == (Object)null || val8.planetData == null)
								{
									continue;
								}
								Vector3 position3 = ((Component)val8).transform.position;
								if (Vector3.Distance(((Component)val2).transform.position, position3) < num7 * 0.99f)
								{
									val5 = Vector3.Cross(((Ray)(ref ray)).direction, position3 - ((Ray)(ref ray)).origin);
									float magnitude2 = ((Vector3)(ref val5)).magnitude;
									float num9 = val8.planetData.realRadius * 0.00025f;
									if (magnitude2 < num9 * 2f)
									{
										flag2 = true;
										break;
									}
								}
							}
						}
					}
				}
				if (!flag2)
				{
					num = num5;
					_hoveredRoute = routePath.Value;
				}
			}
		}

		private float DistanceRayToSegment(Ray ray, Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_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_001d: 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_002d: 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_0040: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = b - a;
			Vector3 val2 = a - ((Ray)(ref ray)).origin;
			float num = Vector3.Dot(val, val);
			float num2 = Vector3.Dot(val, ((Ray)(ref ray)).direction);
			float num3 = Vector3.Dot(((Ray)(ref ray)).direction, ((Ray)(ref ray)).direction);
			float num4 = Vector3.Dot(val, val2);
			float num5 = Vector3.Dot(((Ray)(ref ray)).direction, val2);
			float num6 = num * num3 - num2 * num2;
			float num7 = ((num6 < 0.0001f) ? 0f : Mathf.Clamp01((num2 * num5 - num3 * num4) / num6));
			float num8 = (num2 * num7 + num5) / num3;
			if (num8 < 0f)
			{
				num8 = 0f;
			}
			return Vector3.Distance(a + num7 * val, ((Ray)(ref ray)).origin + num8 * ((Ray)(ref ray)).direction);
		}

		private void OnGUI()
		{
			if (_window != null)
			{
				_window.OnGUI();
			}
			if (_hoveredRoute != null && VesselTrailsPlugin.ShowHoverTooltips.Value)
			{
				DrawHoverTooltip();
			}
		}

		private void DrawHoverTooltip()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00d6: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0125: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			StarData obj = GameMain.galaxy.StarById(_hoveredRoute.StarA);
			string text = ((obj != null) ? obj.displayName : null) ?? $"Star {_hoveredRoute.StarA}";
			StarData obj2 = GameMain.galaxy.StarById(_hoveredRoute.StarB);
			string text2 = ((obj2 != null) ? obj2.displayName : null) ?? $"Star {_hoveredRoute.StarB}";
			float value = VesselTrailsPlugin.HistoryMinutes.Value;
			string text3 = ((value <= 0f) ? "Real-time" : $"Last {value:F1}m");
			GUIStyle val = new GUIStyle(GUI.skin.box)
			{
				richText = true,
				padding = new RectOffset(10, 10, 10, 10)
			};
			val.normal.background = Texture2D.whiteTexture;
			GUI.backgroundColor = new Color(0.05f, 0.07f, 0.1f, 0.95f);
			GUIStyle val2 = new GUIStyle(GUI.skin.label)
			{
				richText = true,
				fontSize = 13
			};
			float num = 95f;
			float num2 = 24f;
			float num3 = 350f;
			float num4 = num + (float)_hoveredRoute.ItemHistories.Count * num2 + 10f;
			float num5 = (float)Screen.height * 0.7f;
			float num6 = Mathf.Min(num4, num5);
			float num7 = _mousePos.x + 20f;
			float num8 = (float)Screen.height - _mousePos.y - num6 - 10f;
			if (num8 < 10f)
			{
				num8 = (float)Screen.height - _mousePos.y + 20f;
			}
			if (num7 + num3 > (float)Screen.width)
			{
				num7 = (float)Screen.width - num3 - 10f;
			}
			if (num8 + num6 > (float)Screen.height)
			{
				num8 = (float)Screen.height - num6 - 10f;
			}
			GUILayout.BeginArea(new Rect(num7, num8, num3, num6), val);
			GUILayout.Label("<b>" + text + " <-> " + text2 + "</b>", val2, Array.Empty<GUILayoutOption>());
			GUILayout.Label("<size=11><color=#aaaaaa>" + text3 + "</color></size>", val2, Array.Empty<GUILayoutOption>());
			GUILayout.Space(5f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("<size=11><i>Item</i></size>", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
			GUILayout.Label("<size=11><i>Total</i></size>", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.Label("<size=11><i>/min</i></size>", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.Label("<size=11><i>Load</i></size>", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.EndHorizontal();
			if (num4 > num5)
			{
				_hoverScrollPos = GUILayout.BeginScrollView(_hoverScrollPos, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num5 - num) });
			}
			foreach (VesselRouteManager.ItemHistory item in _hoveredRoute.ItemHistories.Values.OrderByDescending((VesselRouteManager.ItemHistory h) => h.AverageVesselCount))
			{
				ItemProto obj3 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(item.ItemId);
				string obj4 = ((obj3 != null) ? ((Proto)obj3).name : null) ?? $"Item {item.ItemId}";
				int totalTrips = item.GetTotalTrips(value);
				float effectiveMinutes = item.GetEffectiveMinutes(value);
				float num9 = (float)totalTrips / Mathf.Max(0.1f, effectiveMinutes);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(obj4, val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
				GUILayout.Label($"{totalTrips}", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
				GUILayout.Label($"{num9:F1}", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
				GUILayout.Label($"{item.AverageVesselCount:F1}", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
				GUILayout.EndHorizontal();
			}
			if (num4 > num5)
			{
				GUILayout.EndScrollView();
			}
			GUILayout.EndArea();
			GUI.backgroundColor = Color.white;
		}

		private Vector3 GetStarVPos(int starId, bool isStarmap)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (isStarmap)
			{
				UIStarmap val = UIRoot.instance?.uiGame?.starmap;
				if ((Object)(object)val != (Object)null && val.starUIs != null && starId > 0 && starId <= val.starUIs.Length)
				{
					UIStarmapStar val2 = val.starUIs[starId - 1];
					if ((Object)(object)val2 != (Object)null && (Object)(object)val2.starObject != (Object)null)
					{
						return val2.starObject.vpos;
					}
				}
			}
			else
			{
				UniverseSimulator universeSimulator = GameMain.universeSimulator;
				if ((Object)(object)universeSimulator != (Object)null && universeSimulator.starSimulators != null && starId > 0 && starId <= universeSimulator.starSimulators.Length)
				{
					StarSimulator val3 = universeSimulator.starSimulators[starId - 1];
					if ((Object)(object)val3 != (Object)null)
					{
						return ((Component)val3).transform.position;
					}
				}
			}
			return Vector3.zero;
		}

		private void OnRenderObject()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: 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_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: 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_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_0515: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_054b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0560: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			if (!VesselTrailsPlugin.ShowTrails.Value || _manager == null || _manager.RoutePaths.Count == 0 || GameMain.data == null)
			{
				return;
			}
			Camera current = Camera.current;
			if ((Object)(object)current == (Object)null || (int)current.cameraType != 1)
			{
				return;
			}
			UIStarmap val = UIRoot.instance?.uiGame?.starmap;
			bool flag = (Object)(object)val != (Object)null && ((ManualBehaviour)val).active;
			if (flag)
			{
				if ((Object)(object)current != (Object)(object)val.screenCamera)
				{
					return;
				}
			}
			else if ((Object)(object)current != (Object)(object)Camera.main)
			{
				return;
			}
			if ((Object)(object)_trailMaterial == (Object)null)
			{
				_trailMaterial = new Material(Shader.Find("Hidden/Internal-Colored"));
				_trailMaterial.SetInt("_SrcBlend", 5);
				_trailMaterial.SetInt("_DstBlend", 10);
				_trailMaterial.SetInt("_ZWrite", 0);
				_trailMaterial.SetInt("_ZTest", 4);
				_trailMaterial.SetInt("_Cull", 0);
				_trailMaterial.renderQueue = 3100;
			}
			Vector3 position = ((Component)current).transform.position;
			GL.PushMatrix();
			GL.LoadProjectionMatrix(current.projectionMatrix);
			GL.modelview = current.worldToCameraMatrix * Matrix4x4.Translate(position);
			_trailMaterial.SetPass(0);
			float value = VesselTrailsPlugin.TrailOpacity.Value;
			float lifetimeSecs = Mathf.Max(1f, VesselTrailsPlugin.HistoryMinutes.Value * 60f);
			float num = (flag ? VesselTrailsPlugin.TrailThicknessStarmap.Value : VesselTrailsPlugin.TrailThicknessNormal.Value);
			GL.Begin(7);
			foreach (VesselRouteManager.RoutePath value2 in _manager.RoutePaths.Values)
			{
				Vector3 starVPos = GetStarVPos(value2.StarA, flag);
				Vector3 starVPos2 = GetStarVPos(value2.StarB, flag);
				if (starVPos == Vector3.zero || starVPos2 == Vector3.zero)
				{
					continue;
				}
				Vector3 val2 = starVPos - position;
				Vector3 val3 = starVPos2 - position;
				Vector3 val4 = starVPos2 - starVPos;
				Vector3 normalized = ((Vector3)(ref val4)).normalized;
				Vector3 val5 = (starVPos + starVPos2) * 0.5f - position;
				float magnitude = ((Vector3)(ref val5)).magnitude;
				float num2 = Mathf.Clamp01(Vector3.Dot(-val2, val3 - val2) / Vector3.Dot(val3 - val2, val3 - val2));
				float num3 = Vector3.Distance(Vector3.zero, val2 + num2 * (val3 - val2));
				float num4 = Mathf.Min(magnitude, num3);
				float num5 = (flag ? 4E-05f : 5E-05f);
				float num6 = num4 * num5 * num;
				num6 = Mathf.Max(num6, flag ? 0.005f : 0.05f);
				val4 = Vector3.Cross(normalized, Vector3.up);
				Vector3 normalized2 = ((Vector3)(ref val4)).normalized;
				if (((Vector3)(ref normalized2)).sqrMagnitude < 0.0001f)
				{
					val4 = Vector3.Cross(normalized, Vector3.right);
					normalized2 = ((Vector3)(ref val4)).normalized;
				}
				val4 = Vector3.Cross(normalized, normalized2);
				Vector3 normalized3 = ((Vector3)(ref val4)).normalized;
				List<VesselRouteManager.ItemHistory> list = value2.ItemHistories.Values.ToList();
				if (VesselTrailsPlugin.TrailColorMode.Value == VesselTrailsPlugin.ColorMode.Material)
				{
					int count = list.Count;
					for (int i = 0; i < count; i++)
					{
						VesselRouteManager.ItemHistory itemHistory = list[i];
						float num7 = value * itemHistory.GetAlpha(lifetimeSecs);
						if (!(num7 <= 0.001f))
						{
							Color color = itemHistory.GetColor(_manager.GlobalMinTraffic, _manager.GlobalMaxTraffic);
							color.a = num7;
							float num8 = (float)i / (float)count * MathF.PI * 2f;
							Vector3 val6 = (normalized3 * Mathf.Cos(num8) + normalized2 * Mathf.Sin(num8)) * num6 * 1.2f;
							if (count == 1)
							{
								val6 = Vector3.zero;
							}
							GL.Color(color);
							DrawPrism(val2 + val6, val3 + val6, normalized3 * num6, normalized2 * num6);
						}
					}
					continue;
				}
				float num9 = 0f;
				foreach (VesselRouteManager.ItemHistory item in list)
				{
					num9 = Mathf.Max(num9, item.GetAlpha(lifetimeSecs));
				}
				float num10 = value * num9;
				if (!(num10 <= 0.001f))
				{
					float num11 = Mathf.Log(_manager.GlobalMaxTraffic + 1f);
					float num12 = Mathf.Log(_manager.GlobalMinTraffic + 1f);
					float num13 = Mathf.Log(value2.TotalVessels + 1f);
					float num14 = num11 - num12;
					float num15 = ((num14 < 0.01f) ? 0f : Mathf.Clamp01((num13 - num12) / num14));
					Color val7 = ((num15 < 0.5f) ? Color.Lerp(Color.green, Color.yellow, num15 * 2f) : Color.Lerp(Color.yellow, Color.red, (num15 - 0.5f) * 2f));
					val7.a = num10;
					GL.Color(val7);
					DrawPrism(val2, val3, normalized3 * num6, normalized2 * num6);
				}
			}
			GL.End();
			GL.PopMatrix();
		}

		private void DrawPrism(Vector3 posA, Vector3 posB, Vector3 w, Vector3 h)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0009: 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_0014: 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_001c: 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_0027: 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_002f: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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)
			GL.Vertex(posA + h - w);
			GL.Vertex(posA + h + w);
			GL.Vertex(posB + h + w);
			GL.Vertex(posB + h - w);
			GL.Vertex(posA - h - w);
			GL.Vertex(posA - h + w);
			GL.Vertex(posB - h + w);
			GL.Vertex(posB - h - w);
			GL.Vertex(posA - h - w);
			GL.Vertex(posA + h - w);
			GL.Vertex(posB + h - w);
			GL.Vertex(posB - h - w);
			GL.Vertex(posA - h + w);
			GL.Vertex(posA + h + w);
			GL.Vertex(posB + h + w);
			GL.Vertex(posB - h + w);
		}
	}
	public class VesselTrailsWindow : WindowBase
	{
		private readonly VesselRouteManager _manager;

		public VesselTrailsWindow(VesselRouteManager manager)
			: base(9922, "Vessel Trails Logistics", new Rect(VesselTrailsPlugin.WindowX.Value, VesselTrailsPlugin.WindowY.Value, VesselTrailsPlugin.WindowW.Value, VesselTrailsPlugin.WindowH.Value))
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			_manager = manager;
		}

		protected override void DrawWindowHeader()
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				richText = true,
				fontStyle = (FontStyle)1
			};
			val.normal.textColor = new Color(0.4f, 0.7f, 1f);
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label("SETTINGS", val, Array.Empty<GUILayoutOption>());
			VesselTrailsPlugin.ShowTrails.Value = GUILayout.Toggle(VesselTrailsPlugin.ShowTrails.Value, "Show Trails", Array.Empty<GUILayoutOption>());
			VesselTrailsPlugin.ShowHoverTooltips.Value = GUILayout.Toggle(VesselTrailsPlugin.ShowHoverTooltips.Value, "Show Hover Tooltips", Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			float num = GUILayout.HorizontalSlider(VesselTrailsPlugin.TrailOpacity.Value, 0f, 1f, Array.Empty<GUILayoutOption>());
			VesselTrailsPlugin.TrailOpacity.Value = Mathf.Round(num * 10f) / 10f;
			GUILayout.Label($"Opacity: {VesselTrailsPlugin.TrailOpacity.Value:F1}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			float num2 = GUILayout.HorizontalSlider(VesselTrailsPlugin.TrailThicknessNormal.Value, 0.1f, 25f, Array.Empty<GUILayoutOption>());
			VesselTrailsPlugin.TrailThicknessNormal.Value = Mathf.Round(num2 * 10f) / 10f;
			GUILayout.Label($"Thick (Cam): {VesselTrailsPlugin.TrailThicknessNormal.Value:F1}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			float num3 = GUILayout.HorizontalSlider(VesselTrailsPlugin.TrailThicknessStarmap.Value, 0.1f, 25f, Array.Empty<GUILayoutOption>());
			VesselTrailsPlugin.TrailThicknessStarmap.Value = Mathf.Round(num3 * 10f) / 10f;
			GUILayout.Label($"Thick (Map): {VesselTrailsPlugin.TrailThicknessStarmap.Value:F1}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			float num4 = GUILayout.HorizontalSlider(VesselTrailsPlugin.HistoryMinutes.Value, 1f, 60f, Array.Empty<GUILayoutOption>());
			VesselTrailsPlugin.HistoryMinutes.Value = Mathf.Round(num4);
			GUILayout.Label($"Display: {VesselTrailsPlugin.HistoryMinutes.Value:F0}m", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
			GUILayout.EndHorizontal();
			if (GUILayout.Button($"Color Mode: {VesselTrailsPlugin.TrailColorMode.Value}", Array.Empty<GUILayoutOption>()))
			{
				VesselTrailsPlugin.TrailColorMode.Value = ((VesselTrailsPlugin.TrailColorMode.Value != VesselTrailsPlugin.ColorMode.Heatmap) ? VesselTrailsPlugin.ColorMode.Heatmap : VesselTrailsPlugin.ColorMode.Material);
			}
			GUILayout.Space(15f);
			GUILayout.Label("CLUSTER TOTALS", val, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("All Logistics Vessels", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(((Rect)(ref WindowRect)).width - 240f) });
			GUILayout.Label($"<b>{_manager.Cache.ClusterTotalTrips}</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.Label($"<b>{_manager.Cache.ClusterTripsPerMin:F1}</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.Label($"<b>{_manager.Cache.ClusterTotalLoad:F1}</b>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			float value = VesselTrailsPlugin.HistoryMinutes.Value;
			string text = ((value <= 0f) ? "REAL-TIME" : $"LAST {value:F1}m");
			GUILayout.Label("ACTIVE ROUTES (" + text + ")", val, Array.Empty<GUILayoutOption>());
			if (_manager.Cache.SortedRoutes.Count >= 100)
			{
				GUILayout.Label("<size=10><color=#ffaa00><i>(Showing top 100 routes only)</i></color></size>", val, Array.Empty<GUILayoutOption>());
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Route / Item", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(((Rect)(ref WindowRect)).width - 240f) });
			GUILayout.Label("Total", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.Label("/min", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.Label("Load", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
			GUILayout.EndHorizontal();
			GUILayout.EndVertical();
		}

		protected override void DrawWindowContent()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle(GUI.skin.box);
			val.normal.background = Texture2D.whiteTexture;
			val.padding = new RectOffset(5, 5, 5, 5);
			foreach (VesselRouteManager.UICache.RouteData sortedRoute in _manager.Cache.SortedRoutes)
			{
				GUI.backgroundColor = new Color(0.2f, 0.3f, 0.4f, 0.2f);
				GUILayout.BeginVertical(val, Array.Empty<GUILayoutOption>());
				GUILayout.Label("<b>" + sortedRoute.StarAName + " -> " + sortedRoute.StarBName + "</b>", Array.Empty<GUILayoutOption>());
				foreach (VesselRouteManager.UICache.ItemData item in sortedRoute.Items)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(" <color=#aaaaaa>• " + item.ItemName + "</color>", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(((Rect)(ref WindowRect)).width - 240f) });
					GUILayout.Label($"{item.TotalTrips}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
					GUILayout.Label($"{item.PerMin:F1}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
					GUILayout.Label($"{item.Load:F1}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
					GUILayout.EndHorizontal();
				}
				GUILayout.EndVertical();
			}
		}

		protected override void DrawWindowFooter()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			GUI.backgroundColor = new Color(0.8f, 0.4f, 0.1f, 0.8f);
			if (GUILayout.Button("CLOSE", Array.Empty<GUILayoutOption>()))
			{
				base.IsVisible = false;
			}
			GUI.backgroundColor = Color.white;
		}

		public override void OnGUI()
		{
			if (base.IsVisible)
			{
				float x = ((Rect)(ref WindowRect)).x;
				float y = ((Rect)(ref WindowRect)).y;
				float width = ((Rect)(ref WindowRect)).width;
				float height = ((Rect)(ref WindowRect)).height;
				base.OnGUI();
				if (Mathf.Abs(((Rect)(ref WindowRect)).x - x) > 0.1f || Mathf.Abs(((Rect)(ref WindowRect)).y - y) > 0.1f || Mathf.Abs(((Rect)(ref WindowRect)).width - width) > 0.1f || Mathf.Abs(((Rect)(ref WindowRect)).height - height) > 0.1f)
				{
					VesselTrailsPlugin.WindowX.Value = ((Rect)(ref WindowRect)).x;
					VesselTrailsPlugin.WindowY.Value = ((Rect)(ref WindowRect)).y;
					VesselTrailsPlugin.WindowW.Value = ((Rect)(ref WindowRect)).width;
					VesselTrailsPlugin.WindowH.Value = ((Rect)(ref WindowRect)).height;
				}
			}
		}
	}
	public static class VesselTrailPersistence
	{
		private static string GetSaveFilePath()
		{
			string gameSaveFolder = GameConfig.gameSaveFolder;
			string text = GameMain.data?.gameName ?? "unknown";
			return Path.Combine(gameSaveFolder, text + ".vesseltrails");
		}

		public static void SaveTrailData(VesselRouteManager manager)
		{
			try
			{
				string saveFilePath = GetSaveFilePath();
				using (BinaryWriter binaryWriter = new BinaryWriter(File.Create(saveFilePath)))
				{
					binaryWriter.Write(1);
					binaryWriter.Write(manager.RoutePaths.Count);
					foreach (KeyValuePair<(int, int), VesselRouteManager.RoutePath> routePath in manager.RoutePaths)
					{
						binaryWriter.Write(routePath.Key.Item1);
						binaryWriter.Write(routePath.Key.Item2);
						binaryWriter.Write(routePath.Value.ItemHistories.Count);
						foreach (KeyValuePair<int, VesselRouteManager.ItemHistory> itemHistory in routePath.Value.ItemHistories)
						{
							binaryWriter.Write(itemHistory.Key);
							binaryWriter.Write(itemHistory.Value.AverageVesselCount);
							binaryWriter.Write(itemHistory.Value.TripStartTimes.Count);
							foreach (float tripStartTime in itemHistory.Value.TripStartTimes)
							{
								binaryWriter.Write(tripStartTime);
							}
						}
					}
				}
				Log.Info("Saved vessel trail data to " + saveFilePath);
			}
			catch (Exception ex)
			{
				Log.Warning("Failed to save vessel trail data: " + ex.Message);
			}
		}

		public static void LoadTrailData(VesselRouteManager manager)
		{
			try
			{
				string saveFilePath = GetSaveFilePath();
				if (!File.Exists(saveFilePath))
				{
					return;
				}
				using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(saveFilePath)))
				{
					if (binaryReader.ReadInt32() != 1)
					{
						return;
					}
					int num = binaryReader.ReadInt32();
					for (int i = 0; i < num; i++)
					{
						int num2 = binaryReader.ReadInt32();
						int num3 = binaryReader.ReadInt32();
						(int, int) key = (num2, num3);
						if (!manager.RoutePaths.TryGetValue(key, out var value))
						{
							value = new VesselRouteManager.RoutePath
							{
								StarA = num2,
								StarB = num3
							};
							manager.RoutePaths[key] = value;
						}
						int num4 = binaryReader.ReadInt32();
						for (int j = 0; j < num4; j++)
						{
							int num5 = binaryReader.ReadInt32();
							float averageVesselCount = binaryReader.ReadSingle();
							int num6 = binaryReader.ReadInt32();
							List<float> list = new List<float>();
							for (int k = 0; k < num6; k++)
							{
								list.Add(binaryReader.ReadSingle());
							}
							if (!value.ItemHistories.ContainsKey(num5))
							{
								value.ItemHistories[num5] = new VesselRouteManager.ItemHistory
								{
									ItemId = num5,
									FirstSeenTime = VesselTrailsPlugin.CurrentGameTime,
									LastSeenTime = VesselTrailsPlugin.CurrentGameTime,
									AverageVesselCount = averageVesselCount,
									TripStartTimes = list
								};
							}
						}
					}
				}
				Log.Info("Loaded vessel trail data from " + saveFilePath);
			}
			catch (Exception ex)
			{
				Log.Warning("Failed to load vessel trail data: " + ex.Message);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.Valoneu.VesselTrails";

		public const string PLUGIN_NAME = "VesselTrails";

		public const string PLUGIN_VERSION = "1.3.2";
	}
}