Decompiled source of ControlPanelPlus v1.0.0
ControlPanelPlus.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using UnityEngine.UI.Youthcat; [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("ControlPanelPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("DSP MOD - ControlPanelPlus (logistics control panel QoL)")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+40b5260f88af877ae006ed729e0bc1572ae3ac76")] [assembly: AssemblyProduct("ControlPanelPlus")] [assembly: AssemblyTitle("ControlPanelPlus")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ControlPanelPlus { public static class AstroListTweaks { private sealed class StarGroup { public int starIndex; public readonly List<EntryData> entries = new List<EntryData>(); public string SortName() { if (entries.Count <= 0) { return ""; } return entries[0].text; } } public static void Rebuild(UIControlPanelFilterPanel panel) { //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown if ((Object)(object)panel == (Object)null) { return; } UIComboBox astroFilterBox = panel.astroFilterBox; if ((Object)(object)astroFilterBox == (Object)null) { return; } NativeUi.EnableRichText(astroFilterBox); bool value = Cfg.SortByName.Value; int entryCount = astroFilterBox.entryCount; if (entryCount <= 2) { return; } List<EntryData> list = new List<EntryData>(entryCount); for (int i = 0; i < entryCount; i++) { list.Add(astroFilterBox.GetEntry(i)); } if (list.Count <= 2) { return; } List<StarGroup> list2 = new List<StarGroup>(); Dictionary<int, StarGroup> dictionary = new Dictionary<int, StarGroup>(); for (int j = 2; j < list.Count; j++) { EntryData val = list[j]; if (val != null) { int num = val.value / 100; if (!dictionary.TryGetValue(num, out var value2)) { value2 = new StarGroup(); value2.starIndex = num; dictionary[num] = value2; list2.Add(value2); } value2.entries.Add(val); } } if (value) { list2.Sort((StarGroup a, StarGroup b) => string.Compare(a.SortName(), b.SortName(), StringComparison.CurrentCultureIgnoreCase)); } int num2 = int.MinValue; if (astroFilterBox.selectedIndex >= 0) { EntryData entry = astroFilterBox.GetEntry(astroFilterBox.selectedIndex); if (entry != null) { num2 = entry.value; } } bool onChangeEventEnabled = astroFilterBox.onChangeEventEnabled; astroFilterBox.onChangeEventEnabled = false; try { astroFilterBox.ClearEntries(); astroFilterBox.AddEntry(list[0]); astroFilterBox.AddEntry(list[1]); int num3 = 0; try { if (GameMain.localStar != null) { num3 = GameMain.localStar.astroId; } } catch (Exception) { } if (num3 != 0) { astroFilterBox.AddEntry(new EntryData(Lang.T("当前星系", "Current star system"), num3)); } for (int num4 = 0; num4 < list2.Count; num4++) { StarGroup starGroup = list2[num4]; for (int num5 = 0; num5 < starGroup.entries.Count; num5++) { EntryData val2 = starGroup.entries[num5]; bool flag = val2.value > 0 && val2.value % 100 == 0; val2.text = (flag ? ("<color=yellow>" + val2.text + "</color>") : (" " + val2.text)); astroFilterBox.AddEntry(val2); } } if (num2 != int.MinValue) { for (int num6 = 0; num6 < astroFilterBox.entryCount; num6++) { EntryData entry2 = astroFilterBox.GetEntry(num6); if (entry2 != null && entry2.value == num2) { astroFilterBox.selectedIndex = num6; break; } } } } finally { astroFilterBox.onChangeEventEnabled = onChangeEventEnabled; } CppLog.Debug($"astro list rebuilt: groups={list2.Count} entries={astroFilterBox.entryCount} sorted={value}"); } public static void HandleHotkeys(UIControlPanelWindow w) { //IL_0024: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0038: 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_0053: 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_003c: 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_003f: Unknown result type (might be due to invalid IL or missing references) UIControlPanelFilterPanel filterPanel = w.filterPanel; if ((Object)(object)filterPanel == (Object)null || (Object)(object)filterPanel.astroFilterBox == (Object)null) { return; } KeyCode value = Cfg.ListUp.Value; KeyCode value2 = Cfg.ListDown.Value; if ((int)value != 0 && (int)value2 != 0 && value == value2) { if (Input.GetKeyDown(value2)) { StepList(filterPanel, 1); } } else { if ((int)value != 0 && Input.GetKeyDown(value)) { StepList(filterPanel, -1); } if ((int)value2 != 0 && Input.GetKeyDown(value2)) { StepList(filterPanel, 1); } } if (!NativeUi.MouseOverStorageSlot()) { if (Input.GetKeyDown((KeyCode)276)) { StepPlanet(w, -1); } if (Input.GetKeyDown((KeyCode)275)) { StepPlanet(w, 1); } if (Input.GetKeyDown((KeyCode)273)) { StepSelection(w, -1); } if (Input.GetKeyDown((KeyCode)274)) { StepSelection(w, 1); } } } public static void StepList(UIControlPanelFilterPanel panel, int direction) { UIComboBox astroFilterBox = panel.astroFilterBox; int entryCount = astroFilterBox.entryCount; if (entryCount <= 0) { return; } int num = astroFilterBox.selectedIndex; if (num < 0) { num = ((direction > 0) ? (-1) : 0); } bool control = VFInput.control; for (int i = 0; i <= entryCount; i++) { num += direction; if (num < 0) { num = entryCount - 1; } if (num >= entryCount) { num = 0; } if (!control) { break; } EntryData entry = astroFilterBox.GetEntry(num); if (entry != null && (entry.value == -1 || (entry.value > 0 && entry.value % 100 == 0))) { break; } } if (num >= 0 && num < entryCount) { astroFilterBox.selectedIndex = num; CppLog.Debug($"astro list hotkey direction={direction} -> index={num}"); } } public static void StepPlanet(UIControlPanelWindow w, int direction) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_00d3: Unknown result type (might be due to invalid IL or missing references) List<ControlPanelTarget> list = WindowAccess.Results(w); if (list == null || list.Count == 0) { return; } int allowed = (int)w.filter.typeFilter; List<int> list2 = new List<int>(); for (int i = 0; i < list.Count; i++) { if ((int)list[i].entryType == 0 && FirstEntryOfPlanet(list, list[i].astroId, allowed, out var _)) { list2.Add(list[i].astroId); } } if (list2.Count != 0) { int num = AnchorAstroId(w, list); int num2 = list2.IndexOf(num); if (num2 < 0) { num2 = ((direction > 0) ? (-1) : 0); } int num3 = num2 + direction; if (num3 < 0) { num3 = list2.Count - 1; } if (num3 >= list2.Count) { num3 = 0; } if (FirstEntryOfPlanet(list, list2[num3], allowed, out var target2)) { SelectTarget(w, target2); CppLog.Debug($"planet hotkey direction={direction} anchor={num} -> planet={list2[num3]}"); } } } private static bool FirstEntryOfPlanet(List<ControlPanelTarget> results, int astroId, int allowed, out ControlPanelTarget target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) for (int i = 0; i < results.Count; i++) { ControlPanelTarget val = results[i]; if ((int)val.entryType != 0 && val.astroId == astroId && (allowed & TypeBit(val.entryType)) != 0) { target = val; return true; } } target = ControlPanelTarget.none; return false; } public static void StepSelection(UIControlPanelWindow w, int direction) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) List<ControlPanelTarget> list = WindowAccess.Results(w); if (list == null || list.Count == 0) { return; } int num = -1; for (int i = 0; i < list.Count; i++) { if (list[i] == w.selection) { num = i; break; } } int num2 = num; for (int j = 0; j < list.Count; j++) { num2 = ((num >= 0) ? (num2 + direction) : ((direction <= 0) ? (list.Count - 1) : 0)); if (num2 < 0) { num2 = list.Count - 1; } if (num2 >= list.Count) { num2 = 0; } if ((int)list[num2].entryType != 0) { SelectTarget(w, list[num2]); break; } } } private static void SelectTarget(UIControlPanelWindow w, ControlPanelTarget target) { //IL_0001: 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_000e: 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_0015: Unknown result type (might be due to invalid IL or missing references) w.selection = target; try { w.FocusToEntryByObjId(target.astroId, target.objId, target.objType, true); } catch (Exception ex) { CppLog.Warn("focus entry failed: " + ex.Message); } } private static int AnchorAstroId(UIControlPanelWindow w, List<ControlPanelTarget> results) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) ControlPanelTarget selection = w.selection; if (!((ControlPanelTarget)(ref selection)).isNull && selection.astroId != 0) { return selection.astroId; } PlanetData val = ((GameMain.data != null) ? GameMain.data.localPlanet : null); if (val != null) { return val.astroId; } for (int i = 0; i < results.Count; i++) { if ((int)results[i].entryType == 0) { return results[i].astroId; } } return 0; } private static int TypeBit(EControlPanelEntryType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown return (type - 1) switch { 0 => 2, 1 => 4, 2 => 8, 3 => 16, 4 => 32, 5 => 64, _ => 0, }; } } [HarmonyPatch(typeof(UIControlPanelFilterPanel))] internal static class AstroFilterBoxPatch { [HarmonyPostfix] [HarmonyPatch("ReconstructAstroFilterBox")] public static void AfterReconstruct(UIControlPanelFilterPanel __instance) { if (!Cfg.Enabled.Value) { return; } try { AstroListTweaks.Rebuild(__instance); } catch (Exception ex) { CppLog.Error("astro list rebuild failed: " + ex); } } } public static class Cfg { public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> CollapseAllDefaultMulti; public static ConfigEntry<bool> ExpandDefaultSingle; public static ConfigEntry<bool> EnableStarmapButton; public static ConfigEntry<bool> AllowRemoteItemTransfer; public static ConfigEntry<bool> EnableSlots; public static ConfigEntry<bool>[] SlotSwitches = new ConfigEntry<bool>[5]; public static ConfigEntry<bool> ForcePaste; public static ConfigEntry<bool> DestroyReplacedItems; public static ConfigEntry<bool> AllowMinerOverflow; public static ConfigEntry<bool> EnableSettings; public static ConfigEntry<bool> SetChargePower; public static ConfigEntry<bool> SetTripDrones; public static ConfigEntry<bool> SetTripShips; public static ConfigEntry<bool> SetWarpDistance; public static ConfigEntry<bool> SetWarperNecessary; public static ConfigEntry<bool> SetOrbitCollector; public static ConfigEntry<bool> SetDeliveryDrones; public static ConfigEntry<bool> SetDeliveryShips; public static ConfigEntry<bool> SetPilerCount; public static ConfigEntry<bool> EnablePriority; public static ConfigEntry<KeyCode> CopyKey; public static ConfigEntry<KeyCode> PasteKey; public static ConfigEntry<bool> ItemFilterIntersect; public static ConfigEntry<bool> SortByName; public static ConfigEntry<KeyCode> ListUp; public static ConfigEntry<KeyCode> ListDown; public static bool SlotOn(int slotIndex) { if (slotIndex >= 0 && slotIndex < SlotSwitches.Length && SlotSwitches[slotIndex] != null) { return SlotSwitches[slotIndex].Value; } return false; } private static ConfigDescription Ordered(string description, int order) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = order } }); } public static void Bind(ConfigFile config) { Enabled = config.Bind<bool>("General", "Enabled", true, "本 MOD 总开关。关闭后所有功能停止工作(补丁保持加载但不做任何事)。 / Master switch; when off every feature stops (patches stay loaded but do nothing)."); CollapseAllDefaultMulti = config.Bind<bool>("Expand", "CollapseAllDefaultMulti", true, "多星球结果(全星区 / 某星系含多个有物流设施的星球)时,星球条目默认全部折叠。 / Collapse all planet rows by default when the result spans multiple planets."); ExpandDefaultSingle = config.Bind<bool>("Expand", "ExpandDefaultSingle", true, "单星球结果(筛选为某星球,或某星系只有 1 个星球有物流设施)时,该星球条目默认展开。 / Expand the planet row by default when the result is a single planet."); EnableStarmapButton = config.Bind<bool>("Locate", "EnableStarmapButton", true, Ordered("在每个星球条目的导航按钮左侧显示“星图定位”按钮(左键:保留面板;右键:关闭面板;Shift+右键:关闭面板并点亮导航线)。 / Show the locate button left of the navigation button (left click keeps the panel, right click closes it, Shift+right click also points the navigation line).", 30)); AllowRemoteItemTransfer = config.Bind<bool>("Station", "AllowRemoteItemTransfer", false, "允许在总控面板上从非本地星球取放物品(右键拿取 / 手持物品左键放入 / 清空按钮取回)。若安装了 CheatEnabler,则由其 Architect 模式决定,本项不生效。 / Allow taking/placing items on stations of non-local planets (right click takes, left click places, the clear button retrieves). Inactive when CheatEnabler is installed (its Architect mode wins)."); CopyKey = config.Bind<KeyCode>("StationCopy", "CopyKey", (KeyCode)44, Ordered("复制物流塔设置的按键(默认 < ,即逗号键)。仅当总控面板选中物流塔时生效。 / Key that copies the selected station settings (default <, comma). Only works while a station is selected in the control panel.", 240)); PasteKey = config.Bind<KeyCode>("StationCopy", "PasteKey", (KeyCode)46, Ordered("粘贴物流塔设置的按键(默认 > ,即句号键)。按住 Shift 时批量粘贴到当前星球槽位设置相同的塔。 / Key that pastes onto the selected station(s) (default >, period). Hold Shift to batch paste onto every station on the current planet with the same slot layout.", 230)); EnableSlots = config.Bind<bool>("StationCopy", "EnableSlots", true, Ordered("复制/粘贴第一块:槽位设置(物品种类、数量上限、本地/远程供需、运输机/运输船自动填充)。 / Block 1: slot settings (item type, max count, local/remote supply-demand, auto-replenish flags).", 220)); for (int i = 0; i < SlotSwitches.Length; i++) { int num = i + 1; SlotSwitches[i] = config.Bind<bool>("StationCopy", "Slot" + num, true, Ordered("粘贴时是否写入第 " + num + " 槽位(关闭后该槽位保持不变)。 / Paste gate for slot " + num + " (when off the slot is left untouched).", 210 - i * 10)); } ForcePaste = config.Bind<bool>("StationCopy", "ForcePaste", false, Ordered("强制粘贴:目标槽位已有其他物品时直接覆盖(关闭时跳过该槽位,默认关闭)。 / Force paste: overwrite a slot that already holds a different item (off = skip it, default off).", 270)); DestroyReplacedItems = config.Bind<bool>("StationCopy", "DestroyReplacedItems", false, Ordered("强制粘贴或远程清空时直接销毁被替换的物品(关闭时取回到背包,默认关闭)。 / Destroy the replaced items instead of returning them (also applies to clearing remote slots, default off).", 260)); AllowMinerOverflow = config.Bind<bool>("StationCopy", "AllowMinerOverflow", false, Ordered("大型采矿机 / 轨道采集器保留原始槽位上限并允许溢出(关闭时自动缩减到目标塔容量,默认关闭)。 / Keep the original slot max for vein collectors / orbital collectors and allow overflow (off = clamp to the target capacity, default off).", 250)); EnableSettings = config.Bind<bool>("StationCopy", "EnableSettings", true, Ordered("复制/粘贴第二块:塔设置(充电功率、运输机/运输船路程、曲速路程、起送量、集装数量、轨道采集器开关、翘曲器必备)。 / Block 2: station settings (charging power, trip ranges, warp distance, delivery counts, piler count, orbital collector flag, warper requirement).", 130)); SetChargePower = config.Bind<bool>("StationCopy", "SetChargePower", true, Ordered("粘贴时是否写入充电功率。 / Paste the charging power.", 120)); SetTripDrones = config.Bind<bool>("StationCopy", "SetTripDrones", true, Ordered("粘贴时是否写入物流运输机航程。 / Paste the logistics drone trip range.", 110)); SetTripShips = config.Bind<bool>("StationCopy", "SetTripShips", true, Ordered("粘贴时是否写入物流运输船航程(仅星际物流站)。 / Paste the logistics ship trip range (interstellar stations).", 100)); SetWarpDistance = config.Bind<bool>("StationCopy", "SetWarpDistance", true, Ordered("粘贴时是否写入曲速启用距离(仅星际物流站)。 / Paste the warp enable distance (interstellar stations).", 90)); SetWarperNecessary = config.Bind<bool>("StationCopy", "SetWarperNecessary", true, Ordered("粘贴时是否写入“翘曲器必备”开关(仅星际物流站)。 / Paste the warper-required flag (interstellar stations).", 80)); SetOrbitCollector = config.Bind<bool>("StationCopy", "SetOrbitCollector", true, Ordered("粘贴时是否写入“包含轨道采集器”开关(仅星际物流站)。 / Paste the include-orbital-collectors flag (interstellar stations).", 70)); SetDeliveryDrones = config.Bind<bool>("StationCopy", "SetDeliveryDrones", true, Ordered("粘贴时是否写入配送运输机数量。 / Paste the delivery drone count.", 60)); SetDeliveryShips = config.Bind<bool>("StationCopy", "SetDeliveryShips", true, Ordered("粘贴时是否写入配送运输船数量(仅星际物流站)。 / Paste the delivery ship count (interstellar stations).", 50)); SetPilerCount = config.Bind<bool>("StationCopy", "SetPilerCount", true, Ordered("粘贴时是否写入集装数量。 / Paste the piler count.", 40)); EnablePriority = config.Bind<bool>("StationCopy", "EnablePriority", true, Ordered("复制/粘贴第三块:优先级设置(塔名/点对点、星际航路优先级、分组、槽位优先级锁)。 / Block 3: priority settings (station name/P2P, route priority, group, slot priority locks).", 30)); ItemFilterIntersect = config.Bind<bool>("Filter", "ItemFilterIntersect", false, "物品筛选由“并集”改为“交集”:选 A+B 时只显示同时含有 A 和 B 的条目(默认关闭,保持原版并集)。 / Item filter works as intersection instead of the vanilla union (A and B instead of A or B)."); SortByName = config.Bind<bool>("AstroList", "SortByName", true, "位置下拉框按星系名称排序(前两项“查看全星系 / 查看当前星球”保持不动)。内置星系/星球区分:星系名黄色、星球名缩进两格。 / Sort the location dropdown by star name (first two entries stay pinned). Built-in star/planet distinction: stars yellow, planets indented."); ListUp = config.Bind<KeyCode>("Hotkeys", "ListUp", (KeyCode)280, "位置下拉框向上切换一项(按住 Ctrl 只切换星系)。 / Step the location dropdown up (hold Ctrl to switch stars only)."); ListDown = config.Bind<KeyCode>("Hotkeys", "ListDown", (KeyCode)281, "位置下拉框向下切换一项(按住 Ctrl 只切换星系)。 / Step the location dropdown down (hold Ctrl to switch stars only)."); } } internal sealed class ConfigurationManagerAttributes { public int Order; } public static class ConfigWatcher { private static bool _initialized; private static bool _intersect; private static bool _sort; public static void Reset() { _initialized = false; } public static void Poll(UIControlPanelWindow window) { if ((Object)(object)window == (Object)null || !((ManualBehaviour)window).active) { return; } bool value = Cfg.ItemFilterIntersect.Value; bool value2 = Cfg.SortByName.Value; if (!_initialized) { _initialized = true; _intersect = value; _sort = value2; return; } bool flag = value != _intersect; bool flag2 = value2 != _sort; _intersect = value; _sort = value2; try { if (flag) { window.DetermineFilterResults(); window.DetermineEntryVisible(); CppLog.Info("item filter mode switched at runtime, result list refreshed"); } if (flag2) { UIControlPanelFilterPanel filterPanel = window.filterPanel; if ((Object)(object)filterPanel != (Object)null) { filterPanel.ReconstructAstroFilterBox(); filterPanel.RefreshAstroFilterBox(); CppLog.Info("astro list sorting switched at runtime, dropdown rebuilt"); } } } catch (Exception ex) { CppLog.Error("config change refresh failed: " + ex); } } } [HarmonyPatch(typeof(UIControlPanelWindow))] internal static class ControlPanelWindowPatch { [HarmonyPrefix] [HarmonyPatch("_OnOpen")] public static void OnOpenPrefix(UIControlPanelWindow __instance) { if (!Cfg.Enabled.Value) { return; } try { ExpandCollapse.OnWindowOpening(); } catch (Exception ex) { CppLog.Error("window open prefix hook failed: " + ex); } } [HarmonyPostfix] [HarmonyPatch("_OnOpen")] public static void OnOpen(UIControlPanelWindow __instance) { if (!Cfg.Enabled.Value) { return; } try { ExpandCollapse.OnWindowOpened(__instance); StationCopyPaste.OnWindowOpened(); ItemFilterIntersect.EnsureToggleButton(__instance); ItemFilterShortcuts.Reset(); ConfigWatcher.Reset(); StationCopyPaste.ClearMultiSelect(); } catch (Exception ex) { CppLog.Error("window open hook failed: " + ex); } } [HarmonyPostfix] [HarmonyPatch("_OnClose")] public static void OnClose(UIControlPanelWindow __instance) { try { ExpandCollapse.OnWindowClosed(); StationCopyPaste.OnWindowClosed(); ItemFilterShortcuts.Reset(); ConfigWatcher.Reset(); } catch (Exception ex) { CppLog.Error("window close hook failed: " + ex); } } [HarmonyPostfix] [HarmonyPatch("DetermineFilterResults")] public static void AfterDetermineFilterResults(UIControlPanelWindow __instance) { if (!Cfg.Enabled.Value) { return; } try { ItemFilterIntersect.Apply(__instance); ExpandCollapse.AfterResults(__instance); StationCopyPaste.OnFilterResultsDetermined(__instance); } catch (Exception ex) { CppLog.Error("result hook failed: " + ex); } } } [HarmonyPatch(typeof(UIControlPanelWindow))] internal static class ControlPanelWindowInitPatch { [HarmonyPostfix] [HarmonyPatch("_OnInit")] public static void OnInit(UIControlPanelWindow __instance) { try { ExpandCollapse.OnGameInit(); StationCopyPaste.OnWindowClosed(); ItemFilterShortcuts.Reset(); ConfigWatcher.Reset(); } catch (Exception ex) { CppLog.Error("window init hook failed: " + ex); } } } [HarmonyPatch(typeof(UIControlPanelFilterPanel))] internal static class ControlPanelFilterPanelPatch { [HarmonyPostfix] [HarmonyPatch("_OnOpen")] public static void OnOpen(UIControlPanelFilterPanel __instance) { if (!Cfg.Enabled.Value) { return; } try { NativeUi.EnableRichText(__instance.astroFilterBox); } catch (Exception ex) { CppLog.Error("filter panel open hook failed: " + ex); } } } internal static class CppLog { public const string Prefix = "[CPP] "; public static bool Verbose = true; public static void Debug(string message) { if (Verbose) { ManualLogSource log = ControlPanelPlusPlugin.Log; if (log != null) { log.LogInfo((object)("[CPP] " + message)); } } } public static void Info(string message) { ManualLogSource log = ControlPanelPlusPlugin.Log; if (log != null) { log.LogInfo((object)("[CPP] " + message)); } } public static void Warn(string message) { ManualLogSource log = ControlPanelPlusPlugin.Log; if (log != null) { log.LogWarning((object)("[CPP] " + message)); } } public static void Error(string message) { ManualLogSource log = ControlPanelPlusPlugin.Log; if (log != null) { log.LogError((object)("[CPP] " + message)); } } } [HarmonyPatch(typeof(UIControlPanelObjectEntry), "_OnUpdate")] internal static class EntryFocusSpeedPatch { private const float SpeedUp = 5f; [HarmonyTranspiler] public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { CodeInstruction val = list[i]; if (!(val.opcode != OpCodes.Call) && val.operand is MethodInfo methodInfo && !(methodInfo.DeclaringType != typeof(Time)) && !(methodInfo.Name != "get_deltaTime")) { list.Insert(i + 1, new CodeInstruction(OpCodes.Ldc_R4, (object)5f)); list.Insert(i + 2, new CodeInstruction(OpCodes.Mul, (object)null)); return list; } } CppLog.Warn("focus animation speed patch: Time.deltaTime call not found, using vanilla duration"); return instructions; } } public static class ExpandCollapse { public sealed class PlanetRow { public int astroId; public int index; } private const int LocalKey = 0; private static readonly FieldInfo ResultsField = AccessTools.Field(typeof(UIControlPanelWindow), "results"); private static string _appliedSignature; private static bool _sessionOpened; private static bool _skipDefaultsForThisOpen; private const string ToggleButtonName = "cpt-expand-toggle"; private static UIButton _toggleButton; public static List<ControlPanelTarget> Results(UIControlPanelWindow w) { if ((Object)(object)w == (Object)null || ResultsField == null) { return null; } return ResultsField.GetValue(w) as List<ControlPanelTarget>; } public static List<PlanetRow> PlanetRows(UIControlPanelWindow w) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) List<PlanetRow> list = new List<PlanetRow>(); List<ControlPanelTarget> list2 = Results(w); if (list2 == null) { return list; } for (int i = 0; i < list2.Count; i++) { if ((int)list2[i].entryType == 0) { PlanetRow planetRow = new PlanetRow(); planetRow.astroId = list2[i].astroId; planetRow.index = i; list.Add(planetRow); } } return list; } public static void OnWindowOpening() { _appliedSignature = null; _skipDefaultsForThisOpen = _sessionOpened; _sessionOpened = true; } public static void OnGameInit() { _sessionOpened = false; _skipDefaultsForThisOpen = false; _appliedSignature = null; _toggleButton = null; } public static void OnWindowOpened(UIControlPanelWindow w) { EnsureTopButtons(w); } public static void OnWindowClosed() { _appliedSignature = null; } public static void AfterResults(UIControlPanelWindow w) { if ((Object)(object)w == (Object)null) { return; } List<PlanetRow> list = PlanetRows(w); string text = Signature(w, list); if (text == _appliedSignature) { return; } _appliedSignature = text; if (_skipDefaultsForThisOpen) { _skipDefaultsForThisOpen = false; UpdateToggleLabel(w); CppLog.Debug("panel reopened: keeping the previous planet expand state"); return; } if (list.Count == 0) { UpdateToggleLabel(w); return; } bool flag = list.Count == 1; if (flag ? Cfg.ExpandDefaultSingle.Value : Cfg.CollapseAllDefaultMulti.Value) { bool expand = flag; Apply(w, list, expand, flag ? "单星球默认展开" : "多星球默认折叠"); UpdateToggleLabel(w); } } private static string Signature(UIControlPanelWindow w, List<PlanetRow> planets) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //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_001e: Expected I4, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected I4, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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) StringBuilder stringBuilder = new StringBuilder(128); ControlPanelFilter filter = w.filter; stringBuilder.Append((int)filter.typeFilter).Append('|').Append(filter.astroFilter) .Append('|') .Append((int)filter.sortMethod) .Append('|') .Append(filter.stateFilter) .Append('|') .Append(filter.tagFilter ?? "") .Append('|') .Append(filter.searchFilter ?? ""); if (filter.itemsFilter != null) { stringBuilder.Append('|'); for (int i = 0; i < filter.itemsFilter.Length; i++) { stringBuilder.Append(filter.itemsFilter[i]).Append(','); } } stringBuilder.Append("|p:"); for (int j = 0; j < planets.Count; j++) { stringBuilder.Append(planets[j].astroId).Append(','); } return stringBuilder.ToString(); } public static void Apply(UIControlPanelWindow w, List<PlanetRow> planets, bool expand, string reason) { int num = LocalAstroId(); int num2 = 0; for (int i = 0; i < planets.Count; i++) { PlanetRow planetRow = planets[i]; bool isLocal = planetRow.astroId == num && num != 0; if (IsExpanded(w, planetRow.astroId, isLocal) != expand) { SetExpandState(w, planetRow.astroId, isLocal, expand); w.SetPlanetEntryExpand(planetRow.index, expand); num2++; } } CppLog.Debug($"{reason}: planets={planets.Count} changed={num2}"); } private static int LocalAstroId() { PlanetData val = ((GameMain.data != null) ? GameMain.data.localPlanet : null); if (val == null) { return 0; } return val.astroId; } public static bool IsExpanded(UIControlPanelWindow w, int astroId, bool isLocal) { if (isLocal) { return !w.astroExpands.Contains(0); } return w.astroExpands.Contains(astroId); } private static void SetExpandState(UIControlPanelWindow w, int astroId, bool isLocal, bool expand) { if (isLocal) { if (expand) { w.astroExpands.Remove(0); } else { w.astroExpands.Add(0); } } else if (expand) { w.astroExpands.Add(astroId); } else { w.astroExpands.Remove(astroId); } } private static void EnsureTopButtons(UIControlPanelWindow w) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown if ((Object)(object)w == (Object)null) { return; } Transform val = ((Component)w).transform.Find("cpt-expand-toggle"); if ((Object)(object)val != (Object)null) { _toggleButton = ((Component)val).GetComponent<UIButton>(); UpdateToggleLabel(w); return; } UIButton val2 = NativeUi.MakeSmallTextButton(Lang.T("全部展开", "Expand All"), new Vector2(72f, 22f), 13, "cpt-expand-toggle"); if (!((Object)(object)val2 == (Object)null)) { ((Component)val2).transform.SetParent(((Component)w).transform, false); NativeUi.AnchorTopRight((RectTransform)((Component)val2).transform, -43f, -25f, new Vector2(72f, 22f)); val2.onClick += OnToggleClick; _toggleButton = val2; UpdateToggleLabel(w); CppLog.Debug("expand/collapse toggle button injected"); } } private static bool AllRowsExpanded(UIControlPanelWindow w, List<PlanetRow> planets) { bool flag = planets.Count > 0; for (int i = 0; i < planets.Count; i++) { flag &= IsRowExpanded(w, planets[i]); } return flag; } private static bool IsRowExpanded(UIControlPanelWindow w, PlanetRow row) { int num = LocalAstroId(); bool isLocal = row.astroId == num && num != 0; return IsExpanded(w, row.astroId, isLocal); } public static void UpdateToggleLabel(UIControlPanelWindow w) { if (!((Object)(object)_toggleButton == (Object)null) && !((Object)(object)w == (Object)null)) { Text val = NativeUi.TextOf(_toggleButton); if (!((Object)(object)val == (Object)null)) { bool flag = AllRowsExpanded(w, PlanetRows(w)); val.text = (flag ? Lang.T("全部折叠", "Collapse All") : Lang.T("全部展开", "Expand All")); } } } private static void OnToggleClick(int obj) { if (!Cfg.Enabled.Value) { return; } try { UIControlPanelWindow val = NativeUi.CurrentWindow(); if (!((Object)(object)val == (Object)null) && ((ManualBehaviour)val).active) { List<PlanetRow> planets = PlanetRows(val); bool flag = AllRowsExpanded(val, planets); _appliedSignature = Signature(val, planets); Apply(val, planets, !flag, flag ? "全部折叠按钮" : "全部展开按钮"); UpdateToggleLabel(val); } } catch (Exception ex) { CppLog.Error("expand/collapse toggle failed: " + ex); } } public static void SetAll(bool expand) { if (!Cfg.Enabled.Value) { return; } try { UIControlPanelWindow val = NativeUi.CurrentWindow(); if (!((Object)(object)val == (Object)null) && ((ManualBehaviour)val).active) { List<PlanetRow> planets = PlanetRows(val); _appliedSignature = Signature(val, planets); Apply(val, planets, expand, expand ? "全部展开按钮" : "全部折叠按钮"); UpdateToggleLabel(val); } } catch (Exception ex) { CppLog.Error("expand/collapse all failed: " + ex); } } } internal static class HotkeyDiagnostics { private static float _nextLogAt; public static void Tick(UIControlPanelWindow window) { if ((Object)(object)window == (Object)null || !AnyHotkeyPressed() || Time.unscaledTime < _nextLogAt) { return; } _nextLogAt = Time.unscaledTime + 0.4f; try { if (!VFInput.inFullscreenGUI && !NativeUi.IsInputFocused(window)) { CppLog.Debug("[HOTKEY] " + Describe(window)); } else { CppLog.Info("[HOTKEY BLOCKED] " + Describe(window)); } } catch (Exception ex) { CppLog.Error("hotkey diagnostics failed: " + ex.Message); } } public static bool AnyHotkeyPressed() { //IL_0005: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (!Pressed(Cfg.CopyKey.Value) && !Pressed(Cfg.PasteKey.Value) && !Pressed(Cfg.ListUp.Value) && !Pressed(Cfg.ListDown.Value) && !Pressed((KeyCode)276) && !Pressed((KeyCode)275) && !Pressed((KeyCode)273)) { return Pressed((KeyCode)274); } return true; } private static bool Pressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { return Input.GetKeyDown(key); } return false; } private static string Describe(UIControlPanelWindow w) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_015b: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: 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_036c: Unknown result type (might be due to invalid IL or missing references) UIGame val = (((Object)(object)UIRoot.instance != (Object)null) ? UIRoot.instance.uiGame : null); UIControlPanelFilterPanel filterPanel = w.filterPanel; UIControlPanelInspector currentInspector = w.currentInspector; UIControlPanelStationInspector val2 = (UIControlPanelStationInspector)(object)((currentInspector is UIControlPanelStationInspector) ? currentInspector : null); bool flag = (Object)(object)val2 != (Object)null && (Object)(object)val2.nameInput != (Object)null && val2.nameInput.isFocused; bool flag2 = (Object)(object)filterPanel != (Object)null && (Object)(object)filterPanel.tagFilterInput != (Object)null && filterPanel.tagFilterInput.isFocused; bool flag3 = (Object)(object)filterPanel != (Object)null && (Object)(object)filterPanel.searchFilterInput != (Object)null && filterPanel.searchFilterInput.isFocused; bool flag4 = (Object)(object)filterPanel != (Object)null && (Object)(object)filterPanel.astroFilterBox != (Object)null && (Object)(object)filterPanel.astroFilterBox.searchInput != (Object)null && filterPanel.astroFilterBox.searchInput.isFocused; GameObject val3 = null; EventSystem current = EventSystem.current; if ((Object)(object)current != (Object)null) { val3 = current.currentSelectedGameObject; } string text = "copy=" + ((object)Cfg.CopyKey.Value/*cast due to .constrained prefix*/).ToString() + " paste=" + ((object)Cfg.PasteKey.Value/*cast due to .constrained prefix*/).ToString() + " pageUp=" + ((object)Cfg.ListUp.Value/*cast due to .constrained prefix*/).ToString() + " pageDown=" + ((object)Cfg.ListDown.Value/*cast due to .constrained prefix*/).ToString(); return "panel=" + ((ManualBehaviour)w).active + " fullscreen=" + VFInput.inFullscreenGUI + " paused=" + GameMain.isPaused + " dash=" + ((Object)(object)val != (Object)null && ((ManualBehaviour)val.dashboard).active) + " tree=" + ((Object)(object)val != (Object)null && ((ManualBehaviour)val.techTree).active) + " star=" + ((Object)(object)val != (Object)null && ((ManualBehaviour)val.starmap).active) + " dyson=" + ((Object)(object)val != (Object)null && ((ManualBehaviour)val.dysonEditor).active) + " focused=" + NativeUi.IsInputFocused(w) + " nameFocused=" + flag + " tagFocused=" + flag2 + " searchFocused=" + flag3 + " comboFocused=" + flag4 + " inspector=" + (((Object)(object)w.currentInspector != (Object)null) ? ((object)w.currentInspector).GetType().Name : "null") + " selection=" + w.selection.astroId + "/" + w.selection.objId + " esSel=" + (((Object)(object)val3 != (Object)null) ? ((Object)val3).name : "null") + " | " + text; } } internal class HotkeyDriver : MonoBehaviour { private void Update() { if (!Cfg.Enabled.Value || (Object)(object)UIRoot.instance == (Object)null || (Object)(object)UIRoot.instance.uiGame == (Object)null || GameMain.data == null) { return; } UIControlPanelWindow controlPanelWindow = UIRoot.instance.uiGame.controlPanelWindow; if ((Object)(object)controlPanelWindow == (Object)null || !((ManualBehaviour)controlPanelWindow).active) { return; } HotkeyDiagnostics.Tick(controlPanelWindow); if (VFInput.inFullscreenGUI) { return; } ConfigWatcher.Poll(controlPanelWindow); if (NativeUi.IsInputFocused(controlPanelWindow)) { return; } try { HandleStationCopyPaste(controlPanelWindow); AstroListTweaks.HandleHotkeys(controlPanelWindow); } catch (Exception ex) { CppLog.Error("hotkey handling failed: " + ex); } } private void LateUpdate() { if (Cfg.Enabled.Value) { ItemFilterShortcuts.Tick(); } } private void HandleStationCopyPaste(UIControlPanelWindow window) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_006c: 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) KeyCode value = Cfg.CopyKey.Value; KeyCode value2 = Cfg.PasteKey.Value; UIControlPanelInspector currentInspector = window.currentInspector; UIControlPanelStationInspector val = (UIControlPanelStationInspector)(object)((currentInspector is UIControlPanelStationInspector) ? currentInspector : null); bool flag = (Object)(object)val != (Object)null && val.station != null && val.station.id > 0; if ((int)value != 0 && value != value2 && Input.GetKeyDown(value)) { if (flag) { StationCopyPaste.CopyFromSelection(window); } else { CppLog.Debug("copy key pressed without a station inspector selection"); } } if ((int)value2 != 0 && Input.GetKeyDown(value2)) { if (flag || StationCopyPaste.MultiCount > 0) { StationCopyPaste.Paste(window, VFInput.shift); } else { CppLog.Debug("paste key pressed without a station selection"); } } } } public static class ItemFilterIntersect { private const string ToggleButtonName = "cpt-filter-mode"; private static UIButton _toggleButton; public static void Apply(UIControlPanelWindow w) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected I4, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!Cfg.Enabled.Value || !Cfg.ItemFilterIntersect.Value) { return; } ControlPanelFilter filter = w.filter; if (((ControlPanelFilter)(ref filter)).itemsFilterCount < 2) { return; } List<ControlPanelTarget> list = WindowAccess.Results(w); if (list == null || list.Count == 0) { return; } HashSet<int> hashSet = new HashSet<int>(); int num = 0; for (int i = 0; i < list.Count; i++) { ControlPanelTarget val = list[i]; if ((int)val.entryType != 0) { bool flag = true; EControlPanelEntryType entryType = val.entryType; switch (entryType - 1) { case 0: case 1: case 2: case 3: num++; flag = StationContainsAll(val, filter.itemsFilter); break; case 4: num++; flag = DispenserContainsAll(val, filter.itemsFilter); break; case 5: flag = true; break; } if (!flag) { hashSet.Add(i); } } } for (int j = 0; j < list.Count; j++) { if ((int)list[j].entryType != 0) { continue; } bool flag2 = false; for (int k = j + 1; k < list.Count && (int)list[k].entryType != 0; k++) { if (!hashSet.Contains(k)) { flag2 = true; break; } } if (!flag2) { hashSet.Add(j); } } if (hashSet.Count != 0) { List<int> list2 = new List<int>(hashSet); list2.Sort(); for (int num2 = list2.Count - 1; num2 >= 0; num2--) { WindowAccess.RemoveResultAt(w, list2[num2]); } WindowAccess.MarkEntryVisibleDirty(w); w.ReconnSelectionOnDetermineResults(); CppLog.Debug($"item filter intersect: inspected={num} removed={hashSet.Count} remaining={list.Count}"); } } private static bool StationContainsAll(ControlPanelTarget target, int[] items) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) StationComponent val = ResolveStation(target); if (val == null || val.storage == null) { return false; } foreach (int num in items) { bool flag = false; for (int j = 0; j < val.storage.Length; j++) { if (val.storage[j].itemId == num) { flag = true; break; } } if (!flag) { return false; } } return true; } private static bool DispenserContainsAll(ControlPanelTarget target, int[] items) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) PlanetFactory val = ResolveFactory(target.astroId); if (val == null) { return false; } int objId = target.objId; if (objId <= 0 || objId >= val.entityPool.Length) { return false; } int dispenserId = val.entityPool[objId].dispenserId; if (dispenserId <= 0 || dispenserId >= val.transport.dispenserPool.Length) { return false; } DispenserComponent val2 = val.transport.dispenserPool[dispenserId]; if (val2 == null || val2.id != dispenserId) { return false; } if (items.Length == 1) { return val2.filter == items[0]; } return false; } private static StationComponent ResolveStation(ControlPanelTarget target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) PlanetFactory val = ResolveFactory(target.astroId); if (val == null) { return null; } int objId = target.objId; if (objId <= 0 || objId >= val.entityPool.Length) { return null; } int stationId = val.entityPool[objId].stationId; if (stationId <= 0 || stationId >= val.transport.stationPool.Length) { return null; } StationComponent val2 = val.transport.stationPool[stationId]; if (val2 == null || val2.id != stationId) { return null; } return val2; } private static PlanetFactory ResolveFactory(int astroId) { GameData data = GameMain.data; if (data == null || data.galaxy == null) { return null; } return data.galaxy.PlanetById(astroId)?.factory; } public static void EnsureToggleButton(UIControlPanelWindow window) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown if ((Object)(object)window == (Object)null) { return; } Transform val = ((Component)window).transform.Find("cpt-filter-mode"); if ((Object)(object)val != (Object)null) { _toggleButton = ((Component)val).GetComponent<UIButton>(); UpdateToggleLabel(); return; } UIButton val2 = NativeUi.MakeSmallTextButton(Label(), new Vector2(86f, 22f), 13, "cpt-filter-mode"); if (!((Object)(object)val2 == (Object)null)) { ((Component)val2).transform.SetParent(((Component)window).transform, false); NativeUi.AnchorTopRight((RectTransform)((Component)val2).transform, -121f, -25f, new Vector2(86f, 22f)); val2.onClick += OnToggleClick; _toggleButton = val2; UpdateToggleLabel(); } } private static string Label() { if (!Cfg.ItemFilterIntersect.Value) { return Lang.T("筛选:并集", "Filter: Union"); } return Lang.T("筛选:交集", "Filter: Intersect"); } private static void UpdateToggleLabel() { if (!((Object)(object)_toggleButton == (Object)null)) { Text val = NativeUi.TextOf(_toggleButton); if ((Object)(object)val != (Object)null) { val.text = Label(); } } } private static void OnToggleClick(int obj) { if (!Cfg.Enabled.Value) { return; } try { Cfg.ItemFilterIntersect.Value = !Cfg.ItemFilterIntersect.Value; UIControlPanelWindow val = NativeUi.CurrentWindow(); if ((Object)(object)val != (Object)null && ((ManualBehaviour)val).active) { val.DetermineFilterResults(); val.DetermineEntryVisible(); } UpdateToggleLabel(); ConfigWatcher.Reset(); if ((Object)(object)val != (Object)null) { ConfigWatcher.Poll(val); } CppLog.Info("item filter mode switched: " + Label()); } catch (Exception ex) { CppLog.Error("filter mode toggle failed: " + ex); } } } public static class ItemFilterShortcuts { private static readonly Dictionary<UIControlPanelObjectEntry, Action<int>[]> Handlers = new Dictionary<UIControlPanelObjectEntry, Action<int>[]>(); private static readonly FieldInfo GridStorageField = AccessTools.Field(typeof(UIStorageGrid), "storage"); private static readonly FieldInfo GridMouseXField = AccessTools.Field(typeof(UIStorageGrid), "mouseOnX"); private static readonly FieldInfo GridMouseYField = AccessTools.Field(typeof(UIStorageGrid), "mouseOnY"); private static readonly FieldInfo ReplicatorRecipeArrayField = AccessTools.Field(typeof(UIReplicatorWindow), "recipeProtoArray"); private static readonly FieldInfo ReplicatorMouseIndexField = AccessTools.Field(typeof(UIReplicatorWindow), "mouseRecipeIndex"); private static int[] _lastSeenItems; private static bool _pendingAppend; private static int _pendingItem; private static int[] _pendingBase; public static void AttachStationEntry(UIControlPanelStationEntry entry) { if (!((Object)(object)entry == (Object)null) && !Handlers.ContainsKey((UIControlPanelObjectEntry)(object)entry)) { UIButton[] buttons = (UIButton[])(object)new UIButton[5] { ButtonOf(entry.storageItem0), ButtonOf(entry.storageItem1), ButtonOf(entry.storageItem2), ButtonOf(entry.storageItem3), ButtonOf(entry.storageItem4) }; Register((UIControlPanelObjectEntry)(object)entry, buttons, 5); } } public static void AttachMinerEntry(UIControlPanelAdvancedMinerEntry entry) { if (!((Object)(object)entry == (Object)null) && !Handlers.ContainsKey((UIControlPanelObjectEntry)(object)entry)) { Register((UIControlPanelObjectEntry)(object)entry, (UIButton[])(object)new UIButton[1] { ButtonOf(entry.storageItem) }, 1); } } private static UIButton ButtonOf(UIControlPanelStorageItem item) { if (!((Object)(object)item != (Object)null)) { return null; } return item.itemButton; } private static void Register(UIControlPanelObjectEntry entry, UIButton[] buttons, int slots) { Action<int>[] array = new Action<int>[slots]; for (int i = 0; i < slots; i++) { int slot = i; array[i] = delegate { OnIconRightClick(entry, slot); }; if ((Object)(object)buttons[i] != (Object)null) { buttons[i].onRightClick += array[i]; } } Handlers[entry] = array; } public static void Detach(UIControlPanelObjectEntry entry) { if ((Object)(object)entry == (Object)null || !Handlers.TryGetValue(entry, out var value)) { return; } UIButton[] array = null; UIControlPanelStationEntry val = (UIControlPanelStationEntry)(object)((entry is UIControlPanelStationEntry) ? entry : null); if (val != null) { array = (UIButton[])(object)new UIButton[5] { ButtonOf(val.storageItem0), ButtonOf(val.storageItem1), ButtonOf(val.storageItem2), ButtonOf(val.storageItem3), ButtonOf(val.storageItem4) }; } else { UIControlPanelAdvancedMinerEntry val2 = (UIControlPanelAdvancedMinerEntry)(object)((entry is UIControlPanelAdvancedMinerEntry) ? entry : null); if (val2 != null) { array = (UIButton[])(object)new UIButton[1] { ButtonOf(val2.storageItem) }; } } if (array != null) { for (int i = 0; i < array.Length && i < value.Length; i++) { if ((Object)(object)array[i] != (Object)null) { array[i].onRightClick -= value[i]; } } } Handlers.Remove(entry); } private static void OnIconRightClick(UIControlPanelObjectEntry entry, int slot) { if (!Cfg.Enabled.Value) { return; } try { int num = ItemIdOf(entry, slot); if (num <= 0) { return; } UIControlPanelWindow val = NativeUi.CurrentWindow(); if (!((Object)(object)val == (Object)null) && ((ManualBehaviour)val).active) { if (VFInput.shift) { ScheduleAppend(num); } else { SetSingleItem(val, num, refresh: true); } } } catch (Exception ex) { CppLog.Error("right-click item filter failed: " + ex); } } private static int ItemIdOf(UIControlPanelObjectEntry entry, int slot) { StationComponent val = null; UIControlPanelStationEntry val2 = (UIControlPanelStationEntry)(object)((entry is UIControlPanelStationEntry) ? entry : null); if (val2 != null) { val = val2.station; } else { UIControlPanelAdvancedMinerEntry val3 = (UIControlPanelAdvancedMinerEntry)(object)((entry is UIControlPanelAdvancedMinerEntry) ? entry : null); if (val3 != null) { val = val3.station; } } if (val == null || val.storage == null) { return 0; } if (slot < 0 || slot >= val.storage.Length) { return 0; } return val.storage[slot].itemId; } private static void ScheduleAppend(int itemId) { _pendingBase = CopyItems(_lastSeenItems); _pendingItem = itemId; _pendingAppend = true; } public static void Tick() { UIControlPanelWindow val = NativeUi.CurrentWindow(); if (_pendingAppend) { _pendingAppend = false; if ((Object)(object)val != (Object)null && ((ManualBehaviour)val).active) { ApplyUnion(val, _pendingBase, _pendingItem); } _pendingBase = null; } _lastSeenItems = (((Object)(object)val != (Object)null && ((ManualBehaviour)val).active) ? CopyItems(val.filter.itemsFilter) : null); } public static void Reset() { _pendingAppend = false; _pendingBase = null; _lastSeenItems = null; } private static int[] CopyItems(int[] items) { if (items == null || items.Length == 0) { return null; } int[] array = new int[items.Length]; Array.Copy(items, array, items.Length); return array; } private static void ApplyUnion(UIControlPanelWindow window, int[] baseItems, int itemId) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_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) List<int> list = ((baseItems != null) ? new List<int>(baseItems) : new List<int>()); if (!list.Contains(itemId)) { list.Add(itemId); } while (list.Count > 5) { list.RemoveAt(0); } ControlPanelFilter filter = window.filter; filter.itemsFilter = ((list.Count > 0) ? list.ToArray() : null); window.filter = filter; Refresh(window); _lastSeenItems = CopyItems(window.filter.itemsFilter); CppLog.Info("item filter appended: " + string.Join(",", list.ConvertAll((int i) => i.ToString()).ToArray())); } public static void SetSingleItem(UIControlPanelWindow window, int itemId, bool refresh) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)window == (Object)null || itemId <= 0) { return; } int[] itemsFilter = window.filter.itemsFilter; if (itemsFilter == null || itemsFilter.Length != 1 || itemsFilter[0] != itemId) { ControlPanelFilter filter = window.filter; filter.itemsFilter = new int[1] { itemId }; window.filter = filter; if (refresh && ((ManualBehaviour)window).active) { Refresh(window); CppLog.Info("item filter set by right click: " + itemId); } _lastSeenItems = CopyItems(window.filter.itemsFilter); } } public static void SetSingleItemForOpen(UIControlPanelWindow window, int itemId) { SetSingleItem(window, itemId, refresh: false); } private static void Refresh(UIControlPanelWindow window) { try { UIControlPanelFilterPanel filterPanel = window.filterPanel; if ((Object)(object)filterPanel != (Object)null) { filterPanel.RefreshFilterUI(); } window.DetermineFilterResults(); window.DetermineEntryVisible(); } catch (Exception ex) { CppLog.Error("filter refresh failed: " + ex); } } public static int ItemIdHintUnderMouse() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_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) try { Player val = ((GameMain.data != null) ? GameMain.data.mainPlayer : null); if (val != null && val.inhandItemId > 0) { return val.inhandItemId; } EventSystem current = EventSystem.current; if ((Object)(object)current == (Object)null) { return 0; } PointerEventData val2 = new PointerEventData(current); val2.position = Vector2.op_Implicit(Input.mousePosition); List<RaycastResult> list = new List<RaycastResult>(); current.RaycastAll(val2, list); for (int i = 0; i < list.Count; i++) { RaycastResult val3 = list[i]; GameObject gameObject = ((RaycastResult)(ref val3)).gameObject; if (!((Object)(object)gameObject == (Object)null)) { UIButton componentInParent = gameObject.GetComponentInParent<UIButton>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.tips.itemId > 0) { return componentInParent.tips.itemId; } UIReplicatorWindow componentInParent2 = gameObject.GetComponentInParent<UIReplicatorWindow>(); if ((Object)(object)componentInParent2 != (Object)null) { return ReplicatorItem(componentInParent2); } UIStorageGrid componentInParent3 = gameObject.GetComponentInParent<UIStorageGrid>(); if ((Object)(object)componentInParent3 != (Object)null) { return StorageGridItem(componentInParent3); } UIProductEntry componentInParent4 = gameObject.GetComponentInParent<UIProductEntry>(); if ((Object)(object)componentInParent4 != (Object)null) { return ProductItem(componentInParent4); } } } } catch (Exception ex) { CppLog.Debug("hover item lookup failed: " + ex.Message); } return 0; } private static int ReplicatorItem(UIReplicatorWindow replicator) { if (ReplicatorMouseIndexField == null || ReplicatorRecipeArrayField == null) { return 0; } int num = (int)ReplicatorMouseIndexField.GetValue(replicator); if (num < 0) { return 0; } if (!(ReplicatorRecipeArrayField.GetValue(replicator) is RecipeProto[] array) || num >= array.Length) { return 0; } RecipeProto val = array[num]; if (val == null || val.Results == null || val.Results.Length == 0) { return 0; } return val.Results[0]; } private static int StorageGridItem(UIStorageGrid grid) { if (GridStorageField == null || GridMouseXField == null || GridMouseYField == null) { return 0; } object? value = GridStorageField.GetValue(grid); StorageComponent val = (StorageComponent)((value is StorageComponent) ? value : null); if (val == null || val.grids == null) { return 0; } int num = (int)GridMouseXField.GetValue(grid); int num2 = (int)GridMouseYField.GetValue(grid); if (num < 0 || num2 < 0) { return 0; } int num3 = num + num2 * grid.colCount; if (num3 < 0 || num3 >= val.grids.Length) { return 0; } return val.grids[num3].itemId; } private static int ProductItem(UIProductEntry product) { if ((Object)(object)product.productionStatWindow == (Object)null || !product.productionStatWindow.isProductionTab) { return 0; } if (product.entryData == null) { return 0; } return product.entryData.itemId; } } [HarmonyPatch(typeof(UIGame), "OpenControlPanelWindow")] internal static class AutoFilterOnOpenPatch { [HarmonyPrefix] public static void Prefix(UIGame __instance) { if (!Cfg.Enabled.Value) { return; } try { UIControlPanelWindow controlPanelWindow = __instance.controlPanelWindow; if (!((Object)(object)controlPanelWindow == (Object)null) && !((ManualBehaviour)controlPanelWindow).active) { int num = ItemFilterShortcuts.ItemIdHintUnderMouse(); if (num > 0) { ItemFilterShortcuts.SetSingleItemForOpen(controlPanelWindow, num); } } } catch (Exception ex) { CppLog.Error("auto item filter on open failed: " + ex); } } } [HarmonyPatch(typeof(UIControlPanelStationEntry))] internal static class StationEntryFilterPatch { [HarmonyPostfix] [HarmonyPatch("_OnRegEvent")] public static void OnRegEvent(UIControlPanelStationEntry __instance) { try { ItemFilterShortcuts.AttachStationEntry(__instance); } catch (Exception ex) { CppLog.Error("attach station right-click filter failed: " + ex); } } [HarmonyPostfix] [HarmonyPatch("_OnUnregEvent")] public static void OnUnregEvent(UIControlPanelStationEntry __instance) { ItemFilterShortcuts.Detach((UIControlPanelObjectEntry)(object)__instance); } } [HarmonyPatch(typeof(UIControlPanelAdvancedMinerEntry))] internal static class MinerEntryFilterPatch { [HarmonyPostfix] [HarmonyPatch("_OnRegEvent")] public static void OnRegEvent(UIControlPanelAdvancedMinerEntry __instance) { try { ItemFilterShortcuts.AttachMinerEntry(__instance); } catch (Exception ex) { CppLog.Error("attach miner right-click filter failed: " + ex); } } [HarmonyPostfix] [HarmonyPatch("_OnUnregEvent")] public static void OnUnregEvent(UIControlPanelAdvancedMinerEntry __instance) { ItemFilterShortcuts.Detach((UIControlPanelObjectEntry)(object)__instance); } } public static class Lang { public static bool? LanguageOverride; public static bool Chinese { get { if (LanguageOverride.HasValue) { return LanguageOverride.Value; } try { return Localization.isZHCN; } catch (Exception) { return true; } } } public static string T(string zh, string en) { if (!Chinese) { return en; } return zh; } } internal static class NativeUi { public static Font DinFont() { UIControlPanelWindow val = CurrentWindow(); if (!((Object)(object)val != (Object)null)) { return null; } return val.FONT_DIN; } public static UIControlPanelWindow CurrentWindow() { UIGame val = (((Object)(object)UIRoot.instance != (Object)null) ? UIRoot.instance.uiGame : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.controlPanelWindow; } public static UIButton MakeSmallTextButton(string label, Vector2 size, int fontSize, string name) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) UIGame val = (((Object)(object)UIRoot.instance != (Object)null) ? UIRoot.instance.uiGame : null); UIButton val2 = (((Object)(object)val != (Object)null && (Object)(object)val.assemblerWindow != (Object)null) ? val.assemblerWindow.copyButton : null); if ((Object)(object)val2 == (Object)null) { CppLog.Warn("native button template (assemblerWindow.copyButton) is not available"); return null; } GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject); ((Object)obj).name = name; UIButton component = obj.GetComponent<UIButton>(); Transform val3 = obj.transform.Find("Text"); if ((Object)(object)val3 != (Object)null) { Localizer component2 = ((Component)val3).GetComponent<Localizer>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } Text component3 = ((Component)val3).GetComponent<Text>(); if ((Object)(object)component3 != (Object)null) { component3.text = label; component3.fontSize = fontSize; component3.supportRichText = true; component3.horizontalOverflow = (HorizontalWrapMode)1; component3.verticalOverflow = (VerticalWrapMode)1; } } if ((Object)(object)component != (Object)null) { component.tips.tipTitle = ""; component.tips.tipText = ""; } obj.SetActive(true); RectTransform val4 = (RectTransform)obj.transform; ((Transform)val4).localScale = Vector3.one; val4.sizeDelta = size; return component; } public static int MeasureTipWidth(string text, int fontSize) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00c0: 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) if (string.IsNullOrEmpty(text)) { return 0; } Font val = null; try { UIControlPanelWindow val2 = CurrentWindow(); if ((Object)(object)val2 != (Object)null) { val = val2.FONT_SAIRASB; } } catch (Exception) { } string[] array = text.Split('\n'); float num = 0f; TextGenerator val3 = new TextGenerator(); for (int i = 0; i < array.Length; i++) { float num2 = 0f; if ((Object)(object)val != (Object)null) { TextGenerationSettings val4 = new TextGenerationSettings { font = val, fontSize = fontSize, scaleFactor = 1f, lineSpacing = 1f, richText = false, horizontalOverflow = (HorizontalWrapMode)1, verticalOverflow = (VerticalWrapMode)1, textAnchor = (TextAnchor)0, generationExtents = new Vector2(0f, 0f) }; num2 = val3.GetPreferredWidth(array[i], val4); } if (num2 <= 0f) { num2 = array[i].Length * fontSize; } if (num2 > num) { num = num2; } } return Mathf.CeilToInt(num * 1.15f) + 30; } public static void AnchorTopRight(RectTransform rt, float rightOffset, float topOffset, Vector2 size) { //IL_000b: 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_0035: 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_004d: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = new Vector2(1f, 1f); rt.anchorMax = new Vector2(1f, 1f); rt.pivot = new Vector2(1f, 0.5f); rt.anchoredPosition = new Vector2(rightOffset, topOffset); rt.sizeDelta = size; } public static Text TextOf(UIButton btn) { if ((Object)(object)btn == (Object)null) { return null; } Transform val = ((Component)btn).transform.Find("Text"); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<Text>(); } public static bool IsInputFocused(UIControlPanelWindow w) { EventSystem current = EventSystem.current; if ((Object)(object)current != (Object)null) { GameObject currentSelectedGameObject = current.currentSelectedGameObject; if ((Object)(object)currentSelectedGameObject != (Object)null) { InputField component = currentSelectedGameObject.GetComponent<InputField>(); if ((Object)(object)component != (Object)null && component.isFocused) { return true; } UIInputField component2 = currentSelectedGameObject.GetComponent<UIInputField>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.inputField != (Object)null && component2.inputField.isFocused) { return true; } } } UIControlPanelFilterPanel val = (((Object)(object)w != (Object)null) ? w.filterPanel : null); if ((Object)(object)val != (Object)null) { if ((Object)(object)val.astroFilterBox != (Object)null && (Object)(object)val.astroFilterBox.searchInput != (Object)null && val.astroFilterBox.searchInput.isFocused) { return true; } if ((Object)(object)val.tagFilterInput != (Object)null && val.tagFilterInput.isFocused) { return true; } if ((Object)(object)val.searchFilterInput != (Object)null && val.searchFilterInput.isFocused) { return true; } } UIControlPanelStationInspector val2 = (UIControlPanelStationInspector)(((Object)(object)w != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.nameInput != (Object)null && val2.nameInput.isFocused) { return true; } return false; } public static bool MouseOverStorageSlot() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_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) EventSystem current = EventSystem.current; if ((Object)(object)current == (Object)null) { return false; } PointerEventData val = new PointerEventData(current); val.position = Vector2.op_Implicit(Input.mousePosition); List<RaycastResult> list = new List<RaycastResult>(); current.RaycastAll(val, list); for (int i = 0; i < list.Count; i++) { RaycastResult val2 = list[i]; GameObject gameObject = ((RaycastResult)(ref val2)).gameObject; if (!((Object)(object)gameObject == (Object)null)) { if ((Object)(object)gameObject.GetComponentInParent<UIControlPanelStationStorage>() != (Object)null) { return true; } if ((Object)(object)gameObject.GetComponentInParent<UIStationStorage>() != (Object)null) { return true; } } } return false; } public static void EnableRichText(UIComboBox box) { if (!((Object)(object)box == (Object)null)) { if ((Object)(object)box.mainLabel != (Object)null) { box.mainLabel.supportRichText = true; } if ((Object)(object)box.emptyText != (Object)null) { box.emptyText.supportRichText = true; } if ((Object)(object)((UIListable)box).entryPrefab != (Object)null && (Object)(object)((UIListable)box).entryPrefab.text != (Object)null) { ((UIListable)box).entryPrefab.text.supportRichText = true; } } } } [BepInPlugin("com.dsp.controlpanelplus", "ControlPanelPlus", "1.0.0")] public class ControlPanelPlusPlugin : BaseUnityPlugin { private HotkeyDriver _driver; public static ControlPanelPlusPlugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } internal static Harmony Harmony { get; private set; } private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CppLog.Verbose = false; Cfg.Bind(((BaseUnityPlugin)this).Config); Harmony = new Harmony("com.dsp.controlpanelplus"); Harmony.PatchAll(typeof(ControlPanelPlusPlugin).Assembly); _driver = ((Component)this).gameObject.AddComponent<HotkeyDriver>(); CppLog.Info("ControlPanelPlus 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Harmony = null; } } public static class PluginPresence { public const string CheatEnablerGuid = "org.soardev.cheatenabler"; public const string UiTweaksGuid = "starfi5h.plugin.UITweaks"; private static bool? _cheatEnabler; private static bool? _uiTweaks; public static bool? CheatEnablerPresenceOverride; public static bool? UiTweaksPresenceOverride; public static bool CheatEnablerInstalled { get { if (CheatEnablerPresenceOverride.HasValue) { return CheatEnablerPresenceOverride.Value; } if (!_cheatEnabler.HasValue) { _cheatEnabler = Has("org.soardev.cheatenabler"); } return _cheatEnabler.Value; } } public static bool UiTweaksInstalled { get { if (UiTweaksPresenceOverride.HasValue) { return UiTweaksPresenceOverride.Value; } if (!_uiTweaks.HasValue) { _uiTweaks = Has("starfi5h.plugin.UITweaks"); } return _uiTweaks.Value; } } private static bool Has(string guid) { try { return Chainloader.PluginInfos != null && Chainloader.PluginInfos.ContainsKey(guid); } catch (Exception) { return false; } } } public static class RemoteItemAccess { private static int _scope; public static bool FeatureEnabled { get { if (Cfg.Enabled.Value && Cfg.AllowRemoteItemTransfer.Value) { return !PluginPresence.CheatEnablerInstalled; } return false; } } public static bool ForceLocal => _scope > 0; public static void BeginScope() { if (FeatureEnabled) { _scope++; } } public static void EndScope() { if (_scope > 0) { _scope--; } } public static void ResetScope() { _scope = 0; } } [HarmonyPatch(typeof(UIControlPanelStationStorage), "OnItemIconMouseDown")] internal static class StationStorageMouseDownScopePatch { [HarmonyPrefix] public static void Prefix() { RemoteItemAccess.BeginScope(); } [HarmonyFinalizer] public static void Finalizer() { RemoteItemAccess.EndScope(); } } [HarmonyPatch(typeof(UIControlPanelStationStorage), "OnTakeBackButtonClick")] internal static class StationStorageTakeBackScopePatch { [HarmonyPrefix] public static void Prefix() { RemoteItemAccess.BeginScope(); } [HarmonyFinalizer] public static void Finalizer() { RemoteItemAccess.EndScope(); } } [HarmonyPatch(typeof(UIControlPanelVeinCollectorPanel), "OnProductIconClick")] internal static class VeinCollectorProductScopePatch { [HarmonyPrefix] public static void Prefix() { RemoteItemAccess.BeginScope(); } [HarmonyFinalizer] public static void Finalizer() { RemoteItemAccess.EndScope(); } } [HarmonyPatch(typeof(UIControlPanelStationStorage), "OnTakeBackButtonClick")] internal static class StationStorageRemoteClearDestroyPatch { [HarmonyPrefix] public static bool Prefix(UIControlPanelStationStorage __instance) { if (!Cfg.DestroyReplacedItems.Value) { return true; } if (!Cfg.Enabled.Value || !Cfg.AllowRemoteItemTransfer.Value) { return true; } if (PluginPresence.CheatEnablerInstalled) { return true; } if ((Object)(object)__instance == (Object)null || !__instance.isStationDataValid) { return true; } if (__instance.index < 0 || __instance.index >= __instance.station.storage.Length) { return true; } PlanetData localPlanet = GameMain.localPlanet; if (localPlanet != null && __instance.factory != null && __instance.factory.planet.id == localPlanet.id) { return true; } if (__instance.station.storage[__instance.index].count <= 0) { return true; } try { __instance.factory.transport.SetStationStorage(__instance.station.id, __instance.index, 0, 0, (ELogisticStorage)0, (ELogisticStorage)0, (Player)null); CppLog.Debug("remote clear destroyed the items on purpose"); } catch (Exception ex) { CppLog.Error("remote clear destroy failed: " + ex); } return false; } } [HarmonyPatch(typeof(UIControlPanelStationStorage), "get_isLocal")] internal static class StationStorageIsLocalPatch { [HarmonyPostfix] public static void Postfix(ref bool __result) { if (RemoteItemAccess.ForceLocal) { __result = true; } } } [HarmonyPatch(typeof(UIControlPanelVeinCollectorPanel), "get_isLocal")] internal static class VeinCollectorIsLocalPatch { [HarmonyPostfix] public static void Postfix(ref bool __result) { if (RemoteItemAccess.ForceLocal) { __result = true; } } } public static class StarmapLocate { public const string ButtonName = "cpt-locate-btn"; public static void GetTooltip(out string title, out string text) { title = Lang.T("定位", "Locate"); text = (Lang.Chinese ? "左键:打开星图并保留总控面板\n右键:打开星图并关闭总控面板\nShift+右键:关闭总控面板并点亮导航线" : "Left click: open the star map and keep the panel\nRight click: open the star map and close the panel\nShift+right click: close the panel and point the navigation line"); } public static void EnsureButton(UIControlPanelPlanetEntry entry) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_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_0105: 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_0116: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entry == (Object)null || (Object)(object)entry.navigationButton == (Object)null) { return; } Transform parent = ((Component)entry.navigationButton).transform.parent; if (!((Object)(object)parent == (Object)null) && !((Object)(object)parent.Find("cpt-locate-btn") != (Object)null)) { float num = (Lang.Chinese ? 36f : 52f); UIButton val = NativeUi.MakeSmallTextButton(Lang.T("定位", "Locate"), new Vector2(num, 22f), 12, "cpt-locate-btn"); if (!((Object)(object)val == (Object)null)) { RectTransform val2 = (RectTransform)((Component)entry.navigationButton).transform; RectTransform val3 = (RectTransform)((Component)val).transform; ((Transform)val3).SetParent(parent, false); val3.anchorMin = new Vector2(0f, 0.5f); val3.anchorMax = new Vector2(0f, 0.5f); val3.pivot = new Vector2(1f, 0.5f); val3.anchoredPosition = new Vector2(val2.anchoredPosition.x - 6f, 0f); val3.sizeDelta = new Vector2(num, 22f); ((Transform)val3).localScale = Vector3.one; GetTooltip(out var title, out var text); val.tips.tipTitle = title; val.tips.tipText = text; val.tips.corner = 3; val.tips.offset = new Vector2(18f, -20f); val.tips.delay = 0.7f; val.tips.width = NativeUi.MeasureTipWidth(text, 16); LocateButtonHandler locateButtonHandler = ((Component)val).gameObject.AddComponent<LocateButtonHandler>(); locateButtonHandler.entry = entry; val.onClick += locateButtonHandler.OnButtonClick; val.onRightClick += locateButtonHandler.OnButtonRightClick; CppLog.Debug("locate button injected into planet entry banner"); } } } public static void RefreshVisibility(UIControlPanelPlanetEntry entry) { if ((Object)(object)entry == (Object)null) { return; } Transform val = (((Object)(object)entry.navigationButton != (Object)null) ? ((Component)entry.navigationButton).transform.parent : null); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.Find("cpt-locate-btn"); if (!((Object)(object)val2 == (Object)null)) { bool flag = Cfg.EnableStarmapButton.Value && ((UIControlPanelObjectEntry)entry).isTargetDataValid; if (((Component)val2).gameObject.activeSelf != flag) { ((Component)val2).gameObject.SetActive(flag); } } } public static void Locate(UIControlPanelPlanetEntry entry, bool closePanel, bool linkNavigation) { //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entry == (Object)null || !((UIControlPanelObjectEntry)entry).isTargetDataValid || !Cfg.Enabled.Value || !Cfg.EnableStarmapButton.Value) { return; } PlanetData planet = entry.planet; try { UIGame uiGame = UIRoot.instance.uiGame; UIStarmap starmap = uiGame.starmap; if ((Object)(object)starmap == (Object)null) { return; } Player mainPlayer = GameMain.mainPlayer; mainPlayer.combatState = false; uiGame.ShutPlayerInventory(); if (closePanel) { uiGame.ShutAllFunctionWindow(); } uiGame.ShutTechTree(); uiGame.ShutDashboard(); uiGame.ShutDysonEditorImmediately(); uiGame.CloseEnemyBriefInfo(); if ((Object)(object)uiGame.dashboard != (Object)null && ((ManualBehaviour)uiGame.dashboard).active) { CppLog.Warn("dashboard is still active after ShutDashboard; forcing it closed"); try { ((ManualBehaviour)uiGame.dashboard)._Close(); } catch (Exception ex) { CppLog.Error("forced dashboard close failed: " + ex); } } if (!((ManualBehaviour)starmap).active) { uiGame.BeforeEnterFullScreenUI(); starmap.FadeIn(); } starmap.SetViewStar(planet.star, false); starmap.focusPlanet = null; starmap.focusStar = null; starmap.focusHive = null; starmap.focusEnemyId = 0; double num = (double)planet.realRadius * 0.00025 * 6.0; starmap.screenCameraController.SetViewTarget(planet, (StarData)null, (EnemyDFHiveSystem)null, (Player)null, VectorLF3.zero, num, num, true, false); if (linkNavigation && mainPlayer.navigation != null) { mainPlayer.navigation.indicatorAstroId = planet.astroId; } UIStarmapPlanet val = FindPlanetUi(starmap, planet); if ((Object)(object)val != (Object)null) { starmap.focusPlanet = val; starmap.focusStar = null; starmap.focusHive = null; starmap.focusEnemyId = 0; starmap.OnFocusTargetChange(); } CppLog.Debug($"locate planet {planet.displayName} (astroId={planet.astroId}) selected={(Object)(object)val != (Object)null}"); } catch (Exception ex2) { CppLog.Error("starmap locate failed: " + ex2); } } private static UIStarmapPlanet FindPlanetUi(UIStarmap starmap, PlanetData planet) { if (starmap.planetUIs == null) { return null; } for (int i = 0; i < starmap.planetUIs.Length; i++) { UIStarmapPlanet val = starmap.planetUIs[i]; if ((Object)(object)val != (Object)null && val.planet == planet) { return val; } } return null; } } internal class LocateButtonHandler : MonoBehaviour { public UIControlPanelPlanetEntry entry; public void OnButtonClick(int obj) { StarmapLocate.Locate(entry, closePanel: false, linkNavigation: false); } public void OnButtonRightClick(int obj) { bool linkNavigation = VFInput.shift || Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); StarmapLocate.Locate(entry, closePanel: true, linkNavigation); } } [HarmonyPatch(typeof(UIControlPanelPlanetEntry))] internal static class PlanetEntryPatch { [HarmonyPostfix] [HarmonyPatch("_OnRegEvent")] public static void OnRegEvent(UIControlPanelPlanetEntry __instance) { if (!Cfg.Enabled.Value || !Cfg.EnableStarmapButton.Value) { return; } try { StarmapLocate.EnsureButton(__instance); } catch (Exception ex) { CppLog.Error("planet entry button injection failed: " + ex); } } [HarmonyPostfix] [HarmonyPatch("_OnUpdate")] public static void OnUpdate(UIControlPanelPlanetEntry __instance) { if (!Cfg.Enabled.Value) { return; } try { StarmapLocate.RefreshVisibility(__instance); } catch (Exception ex) { CppLog.Error("planet entry button refresh failed: " + ex); } } } public sealed class SlotSnapshot { public int itemId; public int max; public ELogisticStorage localLogic; public ELogisticStorage remoteLogic; } public sealed class StationSnapshot { public bool isStellar; public bool isCollector; public bool isVeinCollector; public int planetId; public string name = ""; public SlotSnapshot[] slots; public bool droneAutoReplenish; public bool shipAutoReplenish; public long workEnergyPerTick; public double tripRangeDrones; public double tripRangeShips; public double warpEnableDist; public int deliveryDrones; public int deliveryShips; public int pilerCount; public bool includeOrbitCollector; public bool warperNecessary; public byte[] priorityIndex; public byte[] priorityLockTick; public ERemoteRoutePriority routePriority; public long remoteGroupMask; public int[] p2pPartners; public bool IsMiner { get { if (!isCollector) { return isVeinCollector; } return true; } } public string Summary() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (slots != null) { for (int i = 0; i < slots.Length; i++) { if (slots[i].itemId > 0) { num++; } } } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(isCollector ? Lang.T("轨道采集器", "Orbital Collector") : (isVeinCollector ? Lang.T("大型采矿机", "Vein Collector") : (isStellar ? Lang.T("星际物流站", "Interstellar Station") : Lang.T("行星内物流站", "Planetary Station")))); stringBuilder.Append(Lang.T(" 槽位=", " slots=")).Append(num).Append(Lang.T(" 名称=\"", " name=\"")) .Append(name) .Append('"') .Append(Lang.T(" 航路优先级=", " routePriority=")) .Append(routePriority) .Append(Lang.T(" 分组=", " group=")) .Append(remoteGroupMask); if (p2pPartners != null && p2pPartners.Length != 0) { stringBuilder.Append(Lang.T(" P2P伙伴=", " p2pPartners=")).Append(p2pPartners.Length); } return stringBuilder.ToString(); } } internal sealed class PasteResult { public int slotsApplied; public int slotsSkipped; public int slotsConflict; public int slotsLost; public bool settings; public bool priority; public int routesAdded; public string skippedReason = ""; } public static class StationCopyPaste { private static StationSnapshot _clipboard; private static readonly HashSet<long> Multi = new HashSet<long>(); private static string _filterSignature; public static bool HasClipboard => _clipboard != null; public static StationSnapshot Clipboard => _clipboard; public static int MultiCount => Multi.Count; public static void ClearClipboard() { _clipboard = null; } public static bool ToggleMultiSelect(ControlPanelTarget target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (target.astroId == 0 || target.objId == 0) { return false; } StationComponent val = ResolveStation(target.astroId, target.objId); if (val == null || val.id <= 0) { return false; } long item = Key(target.astroId, target.objId); if (!Multi.Remove(item)) { Multi.Add(item); return true; } return true; } private static long Key(int astroId, int objId) { return ((long)astroId << 32) | (uint)objId; } private static int KeyAstro(long key) { return (int)(key >> 32); } private static int KeyObj(long key) { return (int)(key & 0xFFFFFFFFu); } public static bool IsMultiSelected(ControlPanelTarget target) { //IL_000c: 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_0023: 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) if (Multi.Count == 0 || target.astroId == 0 || target.objId == 0) { return false; } return Multi.Contains(Key(target.astroId, target.objId)); } private static void Tip(string message) { UIRealtimeTip.Popup(message, false, 0); } public static void OnWindowOpened() { Multi.Clear(); _filterSignature = null; } public static void OnWindowClosed() { Multi.Clear(); _filterSignature = null; } public static void OnFilterResultsDetermined(UIControlPanelWindow w) { string text = FilterSignature(w); if (text != _filterSignature) { if (_filterSignature != null && Multi.Count > 0) { CppLog.Debug("filter changed, multi-select cleared"); } _filterSignature = text; Multi.Clear(); } } private static string FilterSignature(UIControlPanelWindow w) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected I4, but got Unknown //IL_0022: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0088: 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_0095: Unknown result type (might be due to invalid IL or missing references) ControlPanelFilter filter = w.filter; StringBuilder stringBuilder = new StringBuilder(64); stringBuilder.Append((int)filter.typeFilter).Append('|').Append(filter.astroFilter) .Append('|') .Append((int)filter.sortMethod) .Append('|') .Append(filter.stateFilter) .Append('|') .Append(filter.tagFilter ?? "") .Append('|') .Append(filter.searchFilter ?? ""); if (filter.itemsFilter != null) { for (int i = 0; i < filter.itemsFilter.Length; i++) { stringBuilder.Append(filter.itemsFilter[i]).Append(','); } } return stringBuilder.ToString(); } public static bool ToggleMultiSelect(UIControlPanelObjectEntry entry) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might