Decompiled source of StatsUITweaks v1.5.0

StatsUITweaks.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("StatsUITweaks")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.0")]
[module: UnverifiableCode]
namespace StatsUITweaks;

public class PerformancePanelPatch
{
	private static bool initialized;

	private static UIButton foldBtn;

	private static bool folded;

	private static float scrollHeight = 398f;

	private static float scrollY = 23.5f;

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIPerformancePanel), "_OnOpen")]
	public static void Init(UIPerformancePanel __instance)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		if (initialized)
		{
			return;
		}
		try
		{
			GameObject obj = Object.Instantiate<GameObject>(((Component)UIRoot.instance.uiGame.researchQueue.pauseButton).gameObject, ((Component)__instance).transform);
			((Object)obj).name = "CustomStats_Fold";
			obj.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
			obj.transform.localPosition = new Vector3(-550f, 390f, 0f);
			Transform obj2 = obj.transform.Find("icon");
			Image val = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
			if ((Object)(object)val != (Object)null)
			{
				UIStarmap starmap = UIRoot.instance.uiGame.starmap;
				Transform obj3 = ((Component)starmap.cursorFunctionButton2).transform.Find("icon");
				object sprite;
				if (obj3 == null)
				{
					sprite = null;
				}
				else
				{
					Image component = ((Component)obj3).GetComponent<Image>();
					sprite = ((component != null) ? component.sprite : null);
				}
				val.sprite = (Sprite)sprite;
			}
			foldBtn = obj.GetComponent<UIButton>();
			foldBtn.tips.tipTitle = "Fold 折叠饼图";
			foldBtn.tips.tipText = "Click to fold/unfold pie chart";
			foldBtn.onClick += OnFoldButtonClick;
			if (foldBtn.transitions != null)
			{
				foldBtn.transitions[0].highlightColorOverride = new Color(0.5f, 0.6f, 0.7f, 0.1f);
			}
			obj.SetActive(true);
			scrollHeight = __instance.cpuScrollRect.rectTransform.sizeDelta.y;
			scrollY = ((Component)__instance.cpuScrollRect).transform.localPosition.y;
			initialized = true;
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)"PerformancePanelPatch initial fail!");
			Plugin.Log.LogError((object)ex);
		}
		Toggle(folded);
	}

	public static void OnDestory()
	{
		Toggle(extendScroll: false);
		UIButton obj = foldBtn;
		Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
		initialized = false;
	}

	private static void OnFoldButtonClick(int obj)
	{
		folded = !folded;
		foldBtn.highlighted = folded;
		Toggle(folded);
	}

	private static void Toggle(bool extendScroll)
	{
		if (initialized)
		{
			UIPerformancePanel performancePanelUI = UIRoot.instance.uiGame.statWindow.performancePanelUI;
			Adjust(performancePanelUI.cpuScrollRect.rectTransform, extendScroll);
			Adjust(performancePanelUI.gpuScrollRect.rectTransform, extendScroll);
			Adjust(performancePanelUI.dataScrollRect.rectTransform, extendScroll);
		}
	}

	private static void Adjust(RectTransform scrollRect, bool extendScroll)
	{
		//IL_0014: 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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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)
		foreach (Transform item in ((Transform)scrollRect).parent)
		{
			((Component)item).gameObject.SetActive(!extendScroll);
		}
		((Component)scrollRect).gameObject.SetActive(true);
		((Transform)scrollRect).localPosition = new Vector3(((Transform)scrollRect).localPosition.x, extendScroll ? (scrollY + 362f) : scrollY, 0f);
		scrollRect.sizeDelta = new Vector2(scrollRect.sizeDelta.x, extendScroll ? (scrollHeight + 372f) : scrollHeight);
	}
}
public class PlanetNamePatch
{
	[HarmonyPrefix]
	[HarmonyPatch(typeof(PlanetData), "RegenerateName")]
	private static void RegenerateName(PlanetData __instance, bool notifychange, ref bool __runOriginal)
	{
		if (__runOriginal)
		{
			string text = (__instance.index + 1).ToString();
			__instance.name = __instance.star.displayName + " " + text + Localization.Translate("号星");
			if (notifychange && string.IsNullOrEmpty(__instance.overrideName))
			{
				__instance.NotifyOnDisplayNameChange();
			}
			__runOriginal = false;
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(GalaxyData), "RegeneratePlanetNames")]
	private static void RegenerateName(GalaxyData __instance, ref bool __runOriginal)
	{
		if (__runOriginal)
		{
			StarData[] stars = __instance.stars;
			for (int i = 0; i < stars.Length; i++)
			{
				stars[i].RegeneratePlanetNames(false);
			}
			__runOriginal = false;
		}
	}
}
[BepInPlugin("starfi5h.plugin.StatsUITweaks", "StatsUITweaks", "1.5.0")]
public class Plugin : BaseUnityPlugin
{
	public const string GUID = "starfi5h.plugin.StatsUITweaks";

	public const string NAME = "StatsUITweaks";

	public const string VERSION = "1.5.0";

	public static ManualLogSource Log;

	public static ConfigEntry<bool> DisplayPerSecond;

	private static Harmony harmony;

	public void Awake()
	{
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Expected O, but got Unknown
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("AstroBox", "OrderByName", true, "Order list by system name.\n以星系名称排序列表");
		ConfigEntry<int> val2 = ((BaseUnityPlugin)this).Config.Bind<int>("AstroBox", "DropDownCount", 15, "Number of items shown in drop-down list.\n下拉列表显示的个数");
		ConfigEntry<string> val3 = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "SystemPrefix", "<color=yellow>", "Prefix string of star system in the list\n星系名称前缀");
		ConfigEntry<string> val4 = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "SystemPostfix", "</color>", "Postfix string of star system in the list\n星系名称后缀");
		ConfigEntry<string> val5 = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "PlanetPrefix", "ㅤ", "Prefix string of planet in the list\n星球名称前缀");
		ConfigEntry<string> obj = ((BaseUnityPlugin)this).Config.Bind<string>("AstroBox", "PlanetPostfix", "", "Postfix string of planet in the list\n星球名称后缀");
		ConfigEntry<KeyCode> val6 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("AstroBox", "HotkeyListUp", (KeyCode)280, "Move to previous item in list.\n切换至列表中上一个项目");
		ConfigEntry<KeyCode> obj2 = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("AstroBox", "HotkeyListDown", (KeyCode)281, "Move to next item in list.\n切换至列表中下一个项目");
		ConfigEntry<int> val7 = ((BaseUnityPlugin)this).Config.Bind<int>("StatsUITweaks", "SignificantDigits", 0, new ConfigDescription("Significant figures of production/consumption (Default=0)\n产量有效位数(默认=0)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
		ConfigEntry<int> val8 = ((BaseUnityPlugin)this).Config.Bind<int>("StatsUITweaks", "TimeSliderSlice", 20, "The number of divisions of the time range slider.\n时间范围滑杆的分割数");
		ConfigEntry<int> val9 = ((BaseUnityPlugin)this).Config.Bind<int>("StatsUITweaks", "ListWidthOffeset", 70, "Increase width of the list.\n增加列表栏位宽度");
		ConfigEntry<bool> val10 = ((BaseUnityPlugin)this).Config.Bind<bool>("StatsUITweaks", "NumericPlanetNo", false, "Convert planet no. from Roman numerals to numbers.\n将星球序号从罗马数字转为十进位数字");
		ConfigEntry<bool> val11 = ((BaseUnityPlugin)this).Config.Bind<bool>("PerformancePanel", "FoldButton", true, "Add a button to fold pie chart.\n在性能面板加入一个折叠饼图的按钮");
		BottleneckCompat();
		Utils.OrderByName = val.Value;
		Utils.DropDownCount = val2.Value;
		Utils.HotkeyListUp = val6.Value;
		Utils.HotkeyListDown = obj2.Value;
		Utils.SystemPrefix = val3.Value;
		Utils.SystemPostfix = val4.Value;
		Utils.PlanetPrefix = val5.Value;
		Utils.PlanetPostfix = obj.Value;
		StatsWindowPatch.SignificantDigits = ((val7.Value > 0) ? val7.Value : 0);
		StatsWindowPatch.TimeSliderSlice = val8.Value;
		StatsWindowPatch.ListWidthOffeset = val9.Value;
		harmony = new Harmony("starfi5h.plugin.StatsUITweaks");
		harmony.PatchAll(typeof(StatsWindowPatch));
		if (val10.Value)
		{
			harmony.PatchAll(typeof(PlanetNamePatch));
		}
		if (val11.Value)
		{
			harmony.PatchAll(typeof(PerformancePanelPatch));
		}
		harmony.PatchAll(typeof(UIControlPanelPatch));
	}

	private static void BottleneckCompat()
	{
		if (!Chainloader.PluginInfos.TryGetValue("Bottleneck", out var value))
		{
			return;
		}
		try
		{
			DisplayPerSecond = (ConfigEntry<bool>)(AccessTools.Field(((object)value.Instance).GetType().Assembly.GetType("Bottleneck.PluginConfig"), "displayPerSecond")?.GetValue(null) ?? null);
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)"Can't find Bottleneck.PluginConfig.displayPerSecond");
			Log.LogWarning((object)ex);
		}
	}
}
public class StatsWindowPatch
{
	private struct Data
	{
		public long production;

		public long consumption;
	}

	public static int SignificantDigits = 0;

	public static int TimeSliderSlice = 20;

	public static int ListWidthOffeset = 70;

	private static bool initialized;

	private static bool enable;

	private static Slider timerSlider;

	private static InputField filterInput;

	private static UIButton locateBtn;

	private static GameObject filterGo;

	private static string searchStr = "";

	private static float ratio = 1f;

	private static readonly Dictionary<long[], Data> dict = new Dictionary<long[], Data>();

	private static readonly string[] formatF = new string[11]
	{
		"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9",
		"F10"
	};

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "_OnOpen")]
	public static void Init(UIStatisticsWindow __instance)
	{
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0353: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_0367: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: 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_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		if (initialized)
		{
			return;
		}
		initialized = true;
		try
		{
			if (ListWidthOffeset > 0)
			{
				Reposition(((Component)__instance.productAstroBox).transform, ((Component)__instance.productTimeBox).transform);
				if (ListWidthOffeset > 40)
				{
					((RectTransform)((Component)__instance.productSortBox).transform).sizeDelta = new Vector2(200f - (float)(ListWidthOffeset - 40), 30f);
					((Component)__instance.productSortBox).transform.localPosition = new Vector3(135f - (float)(ListWidthOffeset - 40), ((Component)__instance.productSortBox).transform.localPosition.y);
				}
				Reposition(((Component)__instance.powerAstroBox).transform, ((Component)__instance.powerTimeBox).transform);
				Reposition(((Component)__instance.researchAstroBox).transform, ((Component)__instance.researchTimeBox).transform);
				Reposition(((Component)__instance.dysonAstroBox).transform, ((Component)__instance.dysonTimeBox).transform);
				Reposition(((Component)__instance.killAstroBox).transform, ((Component)__instance.killTimeBox).transform);
				if (ListWidthOffeset > 40)
				{
					((RectTransform)((Component)__instance.killSortBox).transform).sizeDelta = new Vector2(200f - (float)(ListWidthOffeset - 40), 30f);
					((Component)__instance.killSortBox).transform.localPosition = new Vector3(135f - (float)(ListWidthOffeset - 40), ((Component)__instance.killSortBox).transform.localPosition.y);
				}
			}
			Utils.EnableRichText(__instance.productAstroBox);
			Utils.EnableRichText(__instance.powerAstroBox);
			Utils.EnableRichText(__instance.researchAstroBox);
			Utils.EnableRichText(__instance.dysonAstroBox);
			Utils.EnableRichText(__instance.killAstroBox);
			Slider slider = UIRoot.instance.uiGame.dysonEditor.controlPanel.inspector.layerInfo.slider0;
			GameObject val = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Control Panel Window/filter-group/sub-group/search-filter");
			UIButton pauseButton = UIRoot.instance.uiGame.researchQueue.pauseButton;
			GameObject obj = Object.Instantiate<GameObject>(((Component)slider).gameObject, ((Component)__instance.productTimeBox).transform);
			((Object)obj).name = "CustomStats_Ratio";
			obj.transform.localPosition = new Vector3(-153f, 8f, 0f);
			obj.GetComponent<RectTransform>().sizeDelta = new Vector2(155.5f, 13f);
			timerSlider = obj.GetComponent<Slider>();
			timerSlider.minValue = 0f;
			timerSlider.maxValue = TimeSliderSlice;
			timerSlider.wholeNumbers = true;
			timerSlider.value = timerSlider.maxValue;
			((UnityEvent<float>)(object)timerSlider.onValueChanged).AddListener((UnityAction<float>)OnSliderChange);
			obj.SetActive(true);
			filterGo = Object.Instantiate<GameObject>(val, ((Component)__instance.productAstroBox).transform);
			((Object)filterGo).name = "CustomStats_Fliter";
			filterGo.transform.localPosition = new Vector3(0f, 20f, 0f);
			filterInput = filterGo.GetComponentInChildren<InputField>();
			filterInput.text = "";
			((UnityEvent<string>)(object)filterInput.onValueChanged).AddListener((UnityAction<string>)OnInputValueChanged);
			filterGo.GetComponent<RectTransform>().sizeDelta = new Vector2(((RectTransform)((Component)__instance.productAstroBox).transform).sizeDelta.x, 28f);
			filterGo.SetActive(true);
			GameObject obj2 = Object.Instantiate<GameObject>(((Component)pauseButton).gameObject, ((Component)__instance.productAstroBox).transform);
			((Object)obj2).name = "CustomStats_Navi";
			obj2.transform.localScale = new Vector3(0.33f, 0.33f, 0.33f);
			obj2.transform.localPosition = new Vector3(2f, -6f, 0f);
			Transform obj3 = obj2.transform.Find("icon");
			Image val2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				UIStarmap starmap = UIRoot.instance.uiGame.starmap;
				Transform obj4 = ((Component)starmap.cursorFunctionButton3).transform.Find("icon");
				object sprite;
				if (obj4 == null)
				{
					sprite = null;
				}
				else
				{
					Image component = ((Component)obj4).GetComponent<Image>();
					sprite = ((component != null) ? component.sprite : null);
				}
				val2.sprite = (Sprite)sprite;
			}
			locateBtn = obj2.GetComponent<UIButton>();
			locateBtn.tips.tipTitle = "Locate";
			locateBtn.tips.tipText = "Left click: Navigate to planet\nRight click: Show planet in starmap";
			locateBtn.onClick += OnLocateButtonClick;
			locateBtn.onRightClick += OnLocateButtonRightClick;
			obj2.SetActive(true);
			enable = true;
			if ((Object)(object)__instance.astroBox != (Object)(object)__instance.productAstroBox)
			{
				OnTabButtonClick(__instance);
			}
		}
		catch (Exception ex)
		{
			Plugin.Log.LogError((object)"UI component initial fail!");
			Plugin.Log.LogError((object)ex);
		}
		static void Reposition(Transform astroBoxtTansform, Transform timeBoxTransform)
		{
			//IL_0001: 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_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)
			((RectTransform)astroBoxtTansform).sizeDelta = new Vector2(200f + (float)ListWidthOffeset, 30f);
			timeBoxTransform.localPosition = new Vector3((float)(330 - ListWidthOffeset), timeBoxTransform.localPosition.y);
		}
	}

	public static void OnDestory()
	{
		Slider obj = timerSlider;
		Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
		InputField obj2 = filterInput;
		Object.Destroy((Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null));
		UIButton obj3 = locateBtn;
		Object.Destroy((Object)(object)((obj3 != null) ? ((Component)obj3).gameObject : null));
		Object.Destroy((Object)(object)filterGo);
		initialized = false;
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "OnTabButtonClick")]
	private static void OnTabButtonClick(UIStatisticsWindow __instance)
	{
		if (enable)
		{
			if ((Object)(object)__instance.timeBox != (Object)null)
			{
				((Component)timerSlider).gameObject.transform.SetParent(((Component)__instance.timeBox).transform);
			}
			if ((Object)(object)__instance.astroBox != (Object)null)
			{
				filterGo.transform.SetParent(((Component)__instance.astroBox).transform);
				((Component)locateBtn).gameObject.transform.SetParent(((Component)__instance.astroBox).transform);
			}
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "_OnUpdate")]
	private static void OnUpdate(UIStatisticsWindow __instance)
	{
		if (__instance.isStatisticsTab)
		{
			Utils.DetermineAstroBoxIndex(__instance.astroBox);
		}
	}

	private static void OnLocateButtonClick(int obj)
	{
		int astroFilter = UIRoot.instance.uiGame.statWindow.astroFilter;
		if (astroFilter > 0)
		{
			GameMain.mainPlayer.navigation.indicatorAstroId = astroFilter;
		}
	}

	private static void OnLocateButtonRightClick(int obj)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		int astroFilter = UIRoot.instance.uiGame.statWindow.astroFilter;
		if (astroFilter <= 0)
		{
			return;
		}
		UIRoot.instance.uiGame.OpenStarmap();
		int num = astroFilter / 100 - 1;
		int num2 = astroFilter % 100 - 1;
		UIStarmap starmap = UIRoot.instance.uiGame.starmap;
		if (num < 0 || num >= starmap.starUIs.Length)
		{
			return;
		}
		if (num2 >= 0)
		{
			PlanetData val = GameMain.galaxy.PlanetById(astroFilter);
			if (val != null)
			{
				starmap.focusPlanet = null;
				starmap.focusStar = starmap.starUIs[num];
				starmap.OnCursorFunction2Click(0);
				starmap.screenCameraController.SetViewTarget(val, (StarData)null, (EnemyDFHiveSystem)null, (Player)null, VectorLF3.zero, (double)val.realRadius * 0.00025 * 6.0, (double)val.realRadius * 0.00025 * 16.0, true, false);
			}
		}
		else
		{
			starmap.focusPlanet = null;
			starmap.focusStar = starmap.starUIs[num];
			starmap.OnCursorFunction2Click(0);
		}
	}

	private static void OnInputValueChanged(string value)
	{
		searchStr = value;
		UIRoot.instance.uiGame.statWindow.RefreshAstroBox();
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ValueToAstroBox")]
	[HarmonyAfter(new string[] { "Bottleneck" })]
	private static void FilterList(UIStatisticsWindow __instance, ref int __state)
	{
		if (!__instance.isStatisticsTab)
		{
			return;
		}
		int startIndex = 1;
		if (!__instance.isDysonTab && __instance.gameData.localPlanet != null)
		{
			startIndex = 2;
			if (__instance.astroBox.Items.Count > 2 && (__instance.astroBox.Items[2] == "Local System" || __instance.astroBox.Items[2] == "本地系统" || __instance.astroBox.Items[2] == Localization.Translate("localSystemLabel")))
			{
				startIndex = 3;
			}
		}
		Utils.UpdateAstroBox(__instance.astroBox, startIndex, searchStr);
		__state = __instance.astroBox.itemIndex;
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ValueToAstroBox")]
	private static void RestoreItemIndex(UIStatisticsWindow __instance, int __state)
	{
		if (!__instance.isStatisticsTab || (Object)(object)__instance.astroBox == (Object)null)
		{
			return;
		}
		try
		{
			int count = __instance.astroBox.ItemsData.Count;
			if (__state != __instance.astroBox.itemIndex && __state >= 0 && __state < count && __instance.astroBox.itemIndex < count && __instance.astroBox.ItemsData[__state] == __instance.astroBox.ItemsData[__instance.astroBox.itemIndex])
			{
				__instance.astroBox.itemIndex = __state;
			}
		}
		catch (Exception)
		{
		}
		if ((Object)(object)locateBtn == (Object)null)
		{
			return;
		}
		int astroFilter = __instance.astroFilter;
		if (astroFilter <= 0)
		{
			locateBtn.tips.tipTitle = "Locate";
			return;
		}
		string text = "Locate " + astroFilter;
		PlanetData val = GameMain.galaxy.PlanetById(astroFilter);
		if (val?.factory != null)
		{
			text = text + " idx=" + val.factory.index;
		}
		locateBtn.tips.tipTitle = text;
	}

	private static void OnSliderChange(float value)
	{
		if (value < 1f)
		{
			timerSlider.value = 1f;
			return;
		}
		ratio = value / timerSlider.maxValue;
		UIRoot.instance.uiGame.statWindow.ComputeDisplayEntriesDetail();
		if (ratio == 1f)
		{
			UIRoot.instance.uiGame.statWindow.ValueToTimeBox();
		}
		else
		{
			ChangeTimeBoxText(UIRoot.instance.uiGame.statWindow);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ValueToTimeBox")]
	private static void ChangeTimeBoxText(UIStatisticsWindow __instance)
	{
		if (ratio != 1f && __instance.isStatisticsTab)
		{
			string text = $" ({100f * ratio:N0}%)";
			InputField input = UIRoot.instance.uiGame.statWindow.timeBox.m_Input;
			switch (__instance.timeLevel)
			{
			case 0:
				input.text = (int)(60f * ratio + 0.5f) + Localization.Translate("空格秒") + text;
				break;
			case 1:
				input.text = (10f * ratio).ToString("F1") + Localization.Translate("空格分钟") + text;
				break;
			case 2:
				input.text = (60f * ratio).ToString("F1") + Localization.Translate("空格分钟") + text;
				break;
			case 3:
				input.text = (10f * ratio).ToString("F1") + Localization.Translate("统计10小时").Replace("10", " ") + text;
				break;
			case 4:
				input.text = (100f * ratio).ToString("F1") + Localization.Translate("统计100小时").Replace("100", " ") + text;
				break;
			case 5:
				input.text = Localization.Translate("统计总计") + text;
				break;
			}
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeDisplayEntriesDetail")]
	private static void ClearData()
	{
		dict.Clear();
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeFirstHalfDetail", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(int),
		typeof(int[]),
		typeof(long[])
	})]
	private static bool ComputeFirstHalfDetail(int lastCursor, int lvlen, int cur, int[] detail, long[] targetDetail)
	{
		if (ratio == 1f)
		{
			return true;
		}
		dict.TryGetValue(targetDetail, out var value);
		int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
		int num2 = cur + num - 1;
		for (int i = 0; i < lvlen - num; i++)
		{
			if (++num2 > lastCursor)
			{
				num2 -= lvlen;
			}
			long num3 = detail[num2];
			value.production += num3;
			int num4 = (int)((float)(i + 1) / ratio);
			for (int j = (int)((float)i / ratio); j < num4; j++)
			{
				targetDetail[j] += num3;
			}
		}
		dict[targetDetail] = value;
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeFirstHalfDetail", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(int),
		typeof(long[]),
		typeof(long[])
	})]
	private static bool ComputeFirstHalfDetail(int lastCursor, int lvlen, int cur, long[] detail, long[] targetDetail)
	{
		if (ratio == 1f)
		{
			return true;
		}
		dict.TryGetValue(targetDetail, out var value);
		int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
		int num2 = cur + num - 1;
		for (int i = 0; i < lvlen - num; i++)
		{
			if (++num2 > lastCursor)
			{
				num2 -= lvlen;
			}
			long num3 = detail[num2];
			value.production += num3;
			int num4 = (int)((float)(i + 1) / ratio);
			for (int j = (int)((float)i / ratio); j < num4; j++)
			{
				targetDetail[j] += num3;
			}
		}
		dict[targetDetail] = value;
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeSecondHalfDetail", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(int),
		typeof(int[]),
		typeof(long[])
	})]
	private static bool ComputeSecondHalfDetail(int lastCursor, int lvlen, int cur, int[] detail, long[] targetDetail)
	{
		if (ratio == 1f)
		{
			return true;
		}
		dict.TryGetValue(targetDetail, out var value);
		int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
		int num2 = cur + num - 1;
		for (int i = 0; i < lvlen - num; i++)
		{
			if (++num2 > lastCursor)
			{
				num2 -= lvlen;
			}
			long num3 = detail[num2];
			value.consumption += num3;
			int num4 = (int)((float)(i + 1) / ratio);
			for (int j = (int)((float)i / ratio); j < num4; j++)
			{
				targetDetail[lvlen + j] += num3;
			}
		}
		dict[targetDetail] = value;
		return false;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIStatisticsWindow), "ComputeSecondHalfDetail", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(int),
		typeof(long[]),
		typeof(long[])
	})]
	private static bool ComputeSecondHalfDetail(int lastCursor, int lvlen, int cur, long[] detail, long[] targetDetail)
	{
		if (ratio == 1f)
		{
			return true;
		}
		dict.TryGetValue(targetDetail, out var value);
		int num = (int)((float)lvlen * (1f - ratio) + 0.5f);
		int num2 = cur + num - 1;
		for (int i = 0; i < lvlen - num; i++)
		{
			if (++num2 > lastCursor)
			{
				num2 -= lvlen;
			}
			long num3 = detail[num2];
			value.consumption += num3;
			int num4 = (int)((float)(i + 1) / ratio);
			for (int j = (int)((float)i / ratio); j < num4; j++)
			{
				targetDetail[lvlen + j] += num3;
			}
		}
		dict[targetDetail] = value;
		return false;
	}

	[HarmonyPostfix]
	[HarmonyAfter(new string[] { "Bottleneck" })]
	[HarmonyPriority(100)]
	[HarmonyPatch(typeof(UIProductEntry), "_OnUpdate")]
	private static void UIProductEntry_ShowInText(UIProductEntry __instance)
	{
		if (__instance.productionStatWindow.isPowerTab)
		{
			return;
		}
		int timeLevel = __instance.productionStatWindow.timeLevel;
		if (ratio == 1f || !dict.TryGetValue(__instance.entryData.detail, out var value))
		{
			if (SignificantDigits > 0)
			{
				double num = __instance.entryData.production;
				double num2 = __instance.entryData.consumption;
				if (num < 0.0)
				{
					num = 0.0 - num;
				}
				if (num2 < 0.0)
				{
					num2 = 0.0 - num2;
				}
				if (timeLevel < 5)
				{
					num /= __instance.lvDivisors[timeLevel];
					num2 /= __instance.lvDivisors[timeLevel];
				}
				if (Plugin.DisplayPerSecond != null && Plugin.DisplayPerSecond.Value)
				{
					num /= 60.0;
					num2 /= 60.0;
				}
				__instance.productText.text = ToLevelString(num);
				__instance.consumeText.text = ToLevelString(num2);
			}
		}
		else
		{
			double num = value.production;
			double num2 = value.consumption;
			if (timeLevel != 5)
			{
				num /= __instance.lvDivisors[timeLevel] * (double)ratio;
				num2 /= __instance.lvDivisors[timeLevel] * (double)ratio;
			}
			if (Plugin.DisplayPerSecond != null && Plugin.DisplayPerSecond.Value)
			{
				num /= 60.0;
				num2 /= 60.0;
			}
			if (SignificantDigits <= 0)
			{
				__instance.productText.text = __instance.ToLevelString(num, timeLevel);
				__instance.consumeText.text = __instance.ToLevelString(num2, timeLevel);
			}
			else
			{
				__instance.productText.text = ToLevelString(num);
				__instance.consumeText.text = ToLevelString(num2);
			}
		}
	}

	private static string ToLevelString(double value)
	{
		if (value == 0.0)
		{
			return "0";
		}
		string text = "";
		if (value >= 1000000.0)
		{
			value /= 1000000.0;
			text = " M";
		}
		else if (value >= 10000.0)
		{
			value /= 1000.0;
			text = " k";
		}
		int num = 0;
		if (value >= 1000.0)
		{
			num = 3;
		}
		else if (value >= 100.0)
		{
			num = 2;
		}
		else if (value >= 10.0)
		{
			num = 1;
		}
		num = SignificantDigits - num - 1;
		if (num < 0)
		{
			num = 0;
		}
		if (num >= formatF.Length)
		{
			num = formatF.Length - 1;
		}
		if (num > 0)
		{
			double num2 = 0.1;
			for (int i = 0; i < num; i++)
			{
				num2 *= 0.1;
			}
			if (value - (double)(int)value < num2)
			{
				return value.ToString("F1") + text;
			}
		}
		return value.ToString(formatF[num]) + text;
	}

	[HarmonyPostfix]
	[HarmonyAfter(new string[] { "Bottleneck" })]
	[HarmonyPriority(100)]
	[HarmonyPatch(typeof(UIKillEntry), "_OnUpdate")]
	private static void UIKillEntry_ShowInText(UIKillEntry __instance)
	{
		if (ratio != 1f && dict.TryGetValue(__instance.entryData.detail, out var value))
		{
			int timeLevel = __instance.productionStatWindow.timeLevel;
			double num = value.production;
			if (timeLevel != 5)
			{
				num /= __instance.lvDivisors[timeLevel] * (double)ratio;
			}
			if (Plugin.DisplayPerSecond != null && Plugin.DisplayPerSecond.Value)
			{
				num /= 60.0;
			}
			__instance.killText.text = __instance.ToLevelString(num, timeLevel);
		}
	}
}
public class UIControlPanelPatch
{
	private static bool initialized;

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIControlPanelFilterPanel), "_OnOpen")]
	public static void Init(UIControlPanelFilterPanel __instance)
	{
		if (!initialized)
		{
			initialized = true;
			Utils.EnableRichText(__instance.astroFilterBox);
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(UIControlPanelFilterPanel), "_OnUpdate")]
	public static void OnUpdate(UIControlPanelFilterPanel __instance)
	{
		Utils.DetermineAstroBoxIndex(__instance.astroFilterBox);
	}

	[HarmonyPostfix]
	[HarmonyPriority(200)]
	[HarmonyPatch(typeof(UIControlPanelFilterPanel), "ReconstructAstroFilterBox")]
	private static void FilterList(UIControlPanelFilterPanel __instance)
	{
		Utils.UpdateAstroBox(__instance.astroFilterBox, 2);
	}
}
public static class Utils
{
	public static bool OrderByName = true;

	public static int DropDownCount = 15;

	public static string PlanetPrefix = "ㅤ";

	public static string PlanetPostfix = "";

	public static string SystemPrefix = "<color=yellow>";

	public static string SystemPostfix = "</color>";

	public static KeyCode HotkeyListUp = (KeyCode)280;

	public static KeyCode HotkeyListDown = (KeyCode)281;

	private static readonly Dictionary<int, int> astroIndex = new Dictionary<int, int>();

	private static readonly List<(string, int)> systemList = new List<(string, int)>();

	private static readonly List<string> newItems = new List<string>();

	private static readonly List<int> newItemData = new List<int>();

	public static void DetermineAstroBoxIndex(UIComboBox astroBox)
	{
		//IL_0007: 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)
		int num = astroBox.itemIndex;
		if (Input.GetKeyDown(HotkeyListUp))
		{
			if (VFInput.control)
			{
				int num2;
				do
				{
					num = ((num > 0) ? (num - 1) : (astroBox.ItemsData.Count - 1));
					num2 = astroBox.ItemsData[num];
				}
				while ((num2 % 100 != 0 || num2 <= 0) && num2 != -1 && num != astroBox.itemIndex);
				astroBox.itemIndex = num;
			}
			else
			{
				astroBox.itemIndex = ((num > 0) ? (num - 1) : (astroBox.ItemsData.Count - 1));
			}
		}
		else
		{
			if (!Input.GetKeyDown(HotkeyListDown))
			{
				return;
			}
			if (VFInput.control)
			{
				int num3;
				do
				{
					num = (num + 1) % astroBox.ItemsData.Count;
					num3 = astroBox.ItemsData[num];
				}
				while ((num3 % 100 != 0 || num3 <= 0) && num3 != -1 && num != astroBox.itemIndex);
				astroBox.itemIndex = num;
			}
			else
			{
				astroBox.itemIndex = (num + 1) % astroBox.ItemsData.Count;
			}
		}
	}

	public static void EnableRichText(UIComboBox uIComboBox)
	{
		uIComboBox.m_Text.supportRichText = true;
		uIComboBox.m_EmptyItemRes.supportRichText = true;
		((Component)uIComboBox.m_ListItemRes).GetComponentInChildren<Text>().supportRichText = true;
		foreach (Button itemButton in uIComboBox.ItemButtons)
		{
			((Component)itemButton).GetComponentInChildren<Text>().supportRichText = true;
		}
		uIComboBox.DropDownCount = DropDownCount;
	}

	public static void UpdateAstroBox(UIComboBox astroBox, int startIndex, string searchStr = "")
	{
		if (astroBox.Items.Count <= startIndex)
		{
			return;
		}
		astroIndex.Clear();
		systemList.Clear();
		newItems.Clear();
		newItemData.Clear();
		for (int i = startIndex; i < astroBox.Items.Count; i++)
		{
			int num = astroBox.ItemsData[i];
			if (num % 100 == 0)
			{
				if (astroIndex.ContainsKey(num))
				{
					Plugin.Log.LogDebug((object)$"[{num}] => {astroBox.Items[i]}");
					systemList[astroIndex[num]] = (astroBox.Items[i], num);
				}
				else
				{
					astroIndex[num] = systemList.Count;
					systemList.Add((astroBox.Items[i], astroBox.ItemsData[i]));
				}
			}
		}
		if (OrderByName)
		{
			systemList.Sort();
		}
		foreach (var system in systemList)
		{
			int num2 = system.Item2 / 100;
			for (int j = startIndex; j < astroBox.Items.Count; j++)
			{
				int num3 = astroBox.ItemsData[j];
				if (num3 / 100 != num2)
				{
					continue;
				}
				string text = astroBox.Items[j];
				if (num3 % 100 != 0)
				{
					if (!text.StartsWith(PlanetPrefix) || !text.EndsWith(PlanetPostfix))
					{
						text = PlanetPrefix + text + PlanetPostfix;
					}
				}
				else if (!text.StartsWith(SystemPrefix) || !text.EndsWith(SystemPostfix))
				{
					text = SystemPrefix + text + SystemPostfix;
				}
				newItems.Add(text);
				newItemData.Add(astroBox.ItemsData[j]);
			}
		}
		astroBox.Items.RemoveRange(startIndex, astroBox.Items.Count - startIndex);
		astroBox.ItemsData.RemoveRange(startIndex, astroBox.ItemsData.Count - startIndex);
		astroBox.Items.AddRange(newItems);
		astroBox.ItemsData.AddRange(newItemData);
		if (string.IsNullOrEmpty(searchStr))
		{
			return;
		}
		for (int num4 = astroBox.Items.Count - 1; num4 >= startIndex; num4--)
		{
			int startIndex2 = ((astroBox.ItemsData[num4] % 100 == 0) ? SystemPrefix.Length : PlanetPrefix.Length);
			int num5 = astroBox.Items[num4].Length - ((astroBox.ItemsData[num4] % 100 == 0) ? SystemPostfix.Length : PlanetPostfix.Length);
			int num6 = astroBox.Items[num4].IndexOf(searchStr, startIndex2, StringComparison.OrdinalIgnoreCase);
			if (num6 == -1 || num6 + searchStr.Length > num5)
			{
				astroBox.Items.RemoveAt(num4);
				astroBox.ItemsData.RemoveAt(num4);
			}
		}
	}
}