using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using DysonSphereMods.Shared; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Valoneu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyDescription("Copy and paste station item slot configurations between ILS/PLS.")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyInformationalVersion("1.0.5+169d032e74b53ca717fdf65cef1b7a9d8a6aab73")] [assembly: AssemblyProduct("DysonSphereMods")] [assembly: AssemblyTitle("CopyPasteStations")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DysonSphereMods.Shared { public static class Log { private static ManualLogSource _logger; public static void Init(ManualLogSource logger) { _logger = logger; } public static void Debug(object data) { ManualLogSource logger = _logger; if (logger != null) { logger.LogDebug(data); } } public static void Info(object data) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo(data); } } public static void Warning(object data) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning(data); } } public static void Error(object data) { ManualLogSource logger = _logger; if (logger != null) { logger.LogError(data); } } public static void Fatal(object data) { ManualLogSource logger = _logger; if (logger != null) { logger.LogFatal(data); } } public static void Message(object data) { ManualLogSource logger = _logger; if (logger != null) { logger.LogMessage(data); } } public static void LogOnce(string msg, ref bool flag, params object[] args) { if (flag) { return; } flag = true; try { string[] array = ((args == null) ? Array.Empty() : args.Select((object arg) => (arg != null) ? ((!(arg is int) && !(arg is string) && !arg.GetType().IsPrimitive) ? JsonUtility.ToJson(arg) : arg.ToString()) : "null").ToArray()); object[] args2 = array; Info(string.Format(msg, args2)); } catch (Exception arg2) { Warning($"LogOnce failed to format message: {msg}. Exception: {arg2}"); } } } public static class MultiplierService { private static readonly Dictionary _multipliers = new Dictionary(); private static bool _isDirty; public static event Action OnMultipliersChanged; public static void SetMultiplier(string key, float value) { if (!_multipliers.TryGetValue(key, out var value2) || Math.Abs(value2 - value) > 0.0001f) { _multipliers[key] = value; _isDirty = true; } } public static float GetMultiplier(string key, float defaultValue = 1f) { if (!_multipliers.TryGetValue(key, out var value)) { return defaultValue; } return value; } public static void CommitChanges() { if (_isDirty) { _isDirty = false; MultiplierService.OnMultipliersChanged?.Invoke(); } } } public static class TickManager { private static long _lastSlowTick = -1L; private static long _lastLazyTick = -1L; private static bool _patched = false; public static event Action OnSlowTick; public static event Action OnLazyTick; public static void Patch(Harmony harmony) { if (!_patched) { _patched = true; harmony.PatchAll(typeof(TickManager)); } } [HarmonyPatch(typeof(GameMain), "Begin")] [HarmonyPostfix] public static void Init() { _lastSlowTick = -1L; _lastLazyTick = -1L; } [HarmonyPatch(typeof(GameLogic), "LogicFrame")] [HarmonyPostfix] public static void GameTick() { long gameTick = GameMain.gameTick; if (gameTick / 60 > _lastSlowTick) { _lastSlowTick = gameTick / 60; TickManager.OnSlowTick?.Invoke(); } if (gameTick / 600 > _lastLazyTick) { _lastLazyTick = gameTick / 600; TickManager.OnLazyTick?.Invoke(); } } } public abstract class WindowBase { public Rect WindowRect; protected Vector2 ScrollPos; private bool _isResizing; private Rect _resizeRect = new Rect(0f, 0f, 15f, 15f); public Vector2 MinSize = new Vector2(300f, 200f); public int WindowId { get; protected set; } public string Title { get; set; } public bool IsVisible { get; set; } protected WindowBase(int windowId, string title, Rect defaultRect) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) WindowId = windowId; Title = title; WindowRect = defaultRect; } public virtual void OnGUI() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (IsVisible) { GUI.backgroundColor = new Color(0.08f, 0.12f, 0.22f, 0.95f); WindowRect = GUILayout.Window(WindowId, WindowRect, new WindowFunction(DrawWindowInternal), Title, Array.Empty()); GUI.backgroundColor = Color.white; ((Rect)(ref WindowRect)).x = Mathf.Clamp(((Rect)(ref WindowRect)).x, 0f - ((Rect)(ref WindowRect)).width + 50f, (float)(Screen.width - 50)); ((Rect)(ref WindowRect)).y = Mathf.Clamp(((Rect)(ref WindowRect)).y, -20f, (float)(Screen.height - 50)); } } private void DrawWindowInternal(int id) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00dd: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Invalid comparison between Unknown and I4 //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Invalid comparison between Unknown and I4 //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) DrawWindowHeader(); ScrollPos = GUILayout.BeginScrollView(ScrollPos, Array.Empty()); DrawWindowContent(); GUILayout.EndScrollView(); DrawWindowFooter(); ((Rect)(ref _resizeRect)).x = ((Rect)(ref WindowRect)).width - 20f; ((Rect)(ref _resizeRect)).y = ((Rect)(ref WindowRect)).height - 20f; ((Rect)(ref _resizeRect)).width = 20f; ((Rect)(ref _resizeRect)).height = 20f; GUI.Label(_resizeRect, "↘", new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 20, normal = new GUIStyleState { textColor = new Color(0.6f, 0.6f, 0.6f, 0.8f) } }); Event current = Event.current; bool flag = false; if ((int)current.type == 0 && ((Rect)(ref _resizeRect)).Contains(current.mousePosition)) { _isResizing = true; flag = true; current.Use(); } else if ((int)current.type == 1) { _isResizing = false; } else if ((int)current.type == 3 && _isResizing) { ref Rect windowRect = ref WindowRect; ((Rect)(ref windowRect)).width = ((Rect)(ref windowRect)).width + current.delta.x; ref Rect windowRect2 = ref WindowRect; ((Rect)(ref windowRect2)).height = ((Rect)(ref windowRect2)).height + current.delta.y; ((Rect)(ref WindowRect)).width = Mathf.Max(MinSize.x, ((Rect)(ref WindowRect)).width); ((Rect)(ref WindowRect)).height = Mathf.Max(MinSize.y, ((Rect)(ref WindowRect)).height); current.Use(); } if ((int)current.type == 0 && !flag) { GUIUtility.keyboardControl = 0; } GUI.DragWindow(); } protected virtual void DrawWindowHeader() { } protected abstract void DrawWindowContent(); protected virtual void DrawWindowFooter() { } public virtual void Toggle() { IsVisible = !IsVisible; } } } namespace CopyPasteStations { [BepInPlugin("com.Valoneu.CopyPasteStations", "CopyPasteStations", "1.0.5")] [BepInProcess("DSPGAME.exe")] public class CopyPasteStationsPlugin : BaseUnityPlugin { public const string GUID = "com.Valoneu.CopyPasteStations"; public const string NAME = "CopyPasteStations"; public const string VERSION = "1.0.5"; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Log.Init(((BaseUnityPlugin)this).Logger); new Harmony("com.Valoneu.CopyPasteStations").PatchAll(typeof(CopyPastePatches)); Log.Info("CopyPasteStations v1.0.5 loaded!"); } } [HarmonyPatch] public static class CopyPastePatches { private static List _clipboard; private static bool _clipboardIsStellar; private static int _clipboardDroneCount; private static int _clipboardShipCount; [HarmonyPostfix] [HarmonyPatch(typeof(PlanetFactory), "CopyBuildingSetting")] public static void CopyBuildingSetting_Postfix(PlanetFactory __instance, int objectId) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) StationComponent station = GetStation(__instance, objectId); if (station != null) { _clipboardIsStellar = station.isStellar; _clipboardDroneCount = station.idleDroneCount + station.workDroneCount; _clipboardShipCount = station.idleShipCount + station.workShipCount; _clipboard = new List(); for (int i = 0; i < station.storage.Length; i++) { StationStore val = station.storage[i]; _clipboard.Add(new SlotConfig { ItemId = val.itemId, LocalLogic = val.localLogic, RemoteLogic = val.remoteLogic, Max = val.max, KeepMode = val.keepMode }); } } } [HarmonyPostfix] [HarmonyPatch(typeof(PlanetFactory), "PasteBuildingSetting")] public static void PasteBuildingSetting_Postfix(PlanetFactory __instance, int objectId) { //IL_0184: 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_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) if (_clipboard == null) { return; } StationComponent station = GetStation(__instance, objectId); if (station == null || (_clipboardIsStellar && (station.isCollector || station.isVeinCollector))) { return; } Player mainPlayer = GameMain.mainPlayer; int num = Math.Min(_clipboard.Count, station.storage.Length); int num3 = default(int); for (int i = 0; i < num; i++) { SlotConfig slotConfig = _clipboard[i]; if (station.storage[i].itemId != slotConfig.ItemId) { if (station.storage[i].count > 0) { int itemId = station.storage[i].itemId; int num2 = station.storage[i].count; int inc = station.storage[i].inc; if (mainPlayer != null) { int num4 = mainPlayer.package.AddItem(itemId, num2, inc, ref num3, false); num2 -= num4; } if (num2 > 0) { GameMain.data.trashSystem.AddTrash(itemId, num2, inc, station.entityId, 0); } } station.storage[i].count = 0; station.storage[i].inc = 0; station.storage[i].localOrder = 0; station.storage[i].remoteOrder = 0; } station.storage[i].itemId = slotConfig.ItemId; station.storage[i].localLogic = slotConfig.LocalLogic; station.storage[i].remoteLogic = slotConfig.RemoteLogic; station.storage[i].max = slotConfig.Max; station.storage[i].keepMode = slotConfig.KeepMode; } station.UpdateNeeds(); if (mainPlayer == null) { return; } int num5 = 5001; int num6 = 5002; int num7 = station.idleDroneCount + station.workDroneCount; int clipboardDroneCount = _clipboardDroneCount; if (num7 < clipboardDroneCount) { int val = clipboardDroneCount - num7; int itemCount = mainPlayer.package.GetItemCount(num5); int num8 = Math.Min(val, itemCount); if (num8 > 0) { int num9 = default(int); mainPlayer.package.TakeTailItems(ref num5, ref num8, ref num9, false); station.idleDroneCount += num8; } } if (station.isStellar && _clipboardIsStellar) { int num10 = station.idleShipCount + station.workShipCount; int clipboardShipCount = _clipboardShipCount; if (num10 < clipboardShipCount) { int val2 = clipboardShipCount - num10; int itemCount2 = mainPlayer.package.GetItemCount(num6); int num11 = Math.Min(val2, itemCount2); if (num11 > 0) { int num12 = default(int); mainPlayer.package.TakeTailItems(ref num6, ref num11, ref num12, false); station.idleShipCount += num11; } } } UIStationWindow val3 = UIRoot.instance?.uiGame?.stationWindow; if ((Object)(object)val3 != (Object)null && ((ManualBehaviour)val3).active) { val3.OnStationIdChange(); } __instance.transport.RefreshStationTraffic(station.id); if (station.isStellar) { GalacticTransport galacticTransport = GameMain.data.galacticTransport; if (galacticTransport != null) { galacticTransport.RefreshTraffic(station.gid); } } } private static StationComponent GetStation(PlanetFactory factory, int objectId) { if (factory?.transport == null || objectId <= 0) { return null; } if (objectId >= factory.entityPool.Length) { return null; } int stationId = factory.entityPool[objectId].stationId; if (stationId <= 0 || stationId >= factory.transport.stationCursor) { return null; } StationComponent val = factory.transport.stationPool[stationId]; if (val == null || val.id != stationId) { return null; } return val; } } public class SlotConfig { public int ItemId; public ELogisticStorage LocalLogic; public ELogisticStorage RemoteLogic; public int Max; public int KeepMode; } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.Valoneu.CopyPasteStations"; public const string PLUGIN_NAME = "CopyPasteStations"; public const string PLUGIN_VERSION = "1.0.5"; } }