Decompiled source of VirtualDimension v1.2.1

BepInEx\plugins\VirtualDimension\VirtualDimension.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using CommonAPI.Systems;
using CommonAPI.Systems.ModLocalization;
using HarmonyLib;
using UnityEngine;
using crecheng.DSPModSave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace VirtualDimension;

public static class Content
{
	public static ManualLogSource Log;

	public static void Register(ManualLogSource log)
	{
		Log = log;
		LocalizationModule.RegisterTranslation("KEYOpenVirtualDimensionUI", "Open Virtual Dimension inventory", "打开虚拟维度空间界面", "Ouvrir l'inventaire de la dimension virtuelle");
		log.LogInfo((object)$"Dimension behavior bound to vanilla PLS item {2104}.");
	}

	public static bool IsTowerEntity(PlanetFactory factory, StationComponent station)
	{
		if (factory == null || station == null || station.entityId <= 0)
		{
			return false;
		}
		EntityData[] entityPool = factory.entityPool;
		if (entityPool == null || station.entityId >= entityPool.Length)
		{
			return false;
		}
		return entityPool[station.entityId].protoId == 2104;
	}
}
public class DimensionStorage
{
	public static readonly DimensionStorage Instance = new DimensionStorage();

	private readonly object _lock = new object();

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

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

	private const byte SAVE_VERSION = 1;

	public void Reset()
	{
		lock (_lock)
		{
			_counts.Clear();
			_limits.Clear();
		}
	}

	public int GetCount(int itemId)
	{
		lock (_lock)
		{
			int value;
			return _counts.TryGetValue(itemId, out value) ? value : 0;
		}
	}

	public int DefaultLimit(int itemId)
	{
		ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId);
		if (val != null && val.IsEntity)
		{
			return 50;
		}
		return 2000000;
	}

	public int GetLimit(int itemId)
	{
		lock (_lock)
		{
			if (_limits.TryGetValue(itemId, out var value))
			{
				return value;
			}
		}
		return DefaultLimit(itemId);
	}

	public void SetLimit(int itemId, int value)
	{
		value = Mathf.Clamp(value, 0, 10000000);
		lock (_lock)
		{
			_limits[itemId] = value;
			if (_counts.TryGetValue(itemId, out var value2) && value2 > value)
			{
				_counts[itemId] = value;
			}
			Prune();
		}
	}

	public void ResetLimit(int itemId)
	{
		lock (_lock)
		{
			_limits.Remove(itemId);
			int num = DefaultLimit(itemId);
			if (_counts.TryGetValue(itemId, out var value) && value > num)
			{
				_counts[itemId] = num;
			}
			Prune();
		}
	}

	public int Insert(int itemId, int want)
	{
		if (want <= 0 || itemId <= 0)
		{
			return 0;
		}
		lock (_lock)
		{
			int value;
			int num = (_limits.TryGetValue(itemId, out value) ? value : DefaultLimit(itemId));
			int value2;
			int num2 = (_counts.TryGetValue(itemId, out value2) ? value2 : 0);
			int num3 = num - num2;
			int num4 = ((want < num3) ? want : num3);
			if (num4 <= 0)
			{
				return 0;
			}
			_counts[itemId] = num2 + num4;
			return num4;
		}
	}

	public int TakeOut(int itemId, int want)
	{
		if (want <= 0 || itemId <= 0)
		{
			return 0;
		}
		lock (_lock)
		{
			int value;
			int num = (_counts.TryGetValue(itemId, out value) ? value : 0);
			int num2 = ((want < num) ? want : num);
			if (num2 <= 0)
			{
				return 0;
			}
			int num3 = num - num2;
			if (num3 <= 0)
			{
				_counts.Remove(itemId);
			}
			else
			{
				_counts[itemId] = num3;
			}
			return num2;
		}
	}

	public List<KeyValuePair<int, int>> GetCountsSnapshot()
	{
		lock (_lock)
		{
			List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>(_counts.Count);
			foreach (KeyValuePair<int, int> count in _counts)
			{
				list.Add(new KeyValuePair<int, int>(count.Key, count.Value));
			}
			return list;
		}
	}

	public bool IsCustomLimit(int itemId)
	{
		lock (_lock)
		{
			return _limits.ContainsKey(itemId);
		}
	}

	public List<KeyValuePair<int, int>> GetLimitsSnapshot()
	{
		lock (_lock)
		{
			List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>(_limits.Count);
			foreach (KeyValuePair<int, int> limit in _limits)
			{
				list.Add(new KeyValuePair<int, int>(limit.Key, limit.Value));
			}
			return list;
		}
	}

	private void Prune()
	{
		if (_counts.ContainsKey(0))
		{
			_counts.Remove(0);
		}
	}

	public void Save(BinaryWriter w)
	{
		lock (_lock)
		{
			w.Write((byte)1);
			int num = 0;
			foreach (KeyValuePair<int, int> count in _counts)
			{
				if (count.Value > 0)
				{
					num++;
				}
			}
			w.Write(num);
			foreach (KeyValuePair<int, int> count2 in _counts)
			{
				if (count2.Value > 0)
				{
					w.Write(count2.Key);
					w.Write(count2.Value);
				}
			}
			w.Write(_limits.Count);
			foreach (KeyValuePair<int, int> limit in _limits)
			{
				w.Write(limit.Key);
				w.Write(limit.Value);
			}
		}
	}

	public void Load(BinaryReader r)
	{
		lock (_lock)
		{
			_counts.Clear();
			_limits.Clear();
			r.ReadByte();
			int num = r.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				int num2 = r.ReadInt32();
				int num3 = r.ReadInt32();
				if (num2 > 0 && num3 > 0)
				{
					_counts[num2] = num3;
				}
			}
			int num4 = r.ReadInt32();
			for (int j = 0; j < num4; j++)
			{
				int num5 = r.ReadInt32();
				int num6 = r.ReadInt32();
				if (num5 > 0)
				{
					_limits[num5] = Mathf.Clamp(num6, 0, 10000000);
				}
			}
		}
	}
}
public static class DimensionUI
{
	public static bool Visible;

	public static bool TextFieldFocused;

	private const int WindowId = 901005;

	private const float GripSize = 20f;

	private const float TitleBarHeight = 24f;

	private static Rect _windowRect;

	private static bool _rectInited;

	private static bool _resizing;

	private static Vector2 _resizeStart;

	private static Rect _resizeStartRect;

	private static Vector2 _scroll;

	private static string _search = string.Empty;

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

	private static string _focusedControl = string.Empty;

	private static GUIStyle _winStyle;

	private static GUIStyle _headerStyle;

	private static GUIStyle _normalStyle;

	private static GUIStyle _mutedStyle;

	private static GUIStyle _countStyle;

	private static GUIStyle _gripStyle;

	private static Texture2D _bg;

	public static void Toggle()
	{
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		Visible = !Visible;
		if (Visible && !_rectInited)
		{
			float num = ((VDMod.WindowWidthEntry != null) ? VDMod.WindowWidthEntry.Value : 1000f);
			float num2 = ((VDMod.WindowHeightEntry != null) ? VDMod.WindowHeightEntry.Value : 620f);
			num = Mathf.Clamp(num, 620f, (float)Screen.width - 40f);
			num2 = Mathf.Clamp(num2, 380f, (float)Screen.height - 40f);
			_windowRect = new Rect(Mathf.Max(20f, ((float)Screen.width - num) * 0.5f), Mathf.Max(20f, ((float)Screen.height - num2) * 0.5f), num, num2);
			_rectInited = true;
		}
	}

	public static void OnGUI()
	{
		//IL_0012: 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_005c: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		if (Visible)
		{
			InitStyles();
			GUILayout.Window(901005, _windowRect, new WindowFunction(WindowFunc), string.Empty, _winStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(((Rect)(ref _windowRect)).width),
				GUILayout.Height(((Rect)(ref _windowRect)).height)
			});
		}
	}

	private static void InitStyles()
	{
		//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: Expected O, but got Unknown
		//IL_007f: 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_00a5: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Expected O, but got Unknown
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: 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_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Expected O, but got Unknown
		//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_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Expected O, but got Unknown
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Expected O, but got Unknown
		if (_winStyle == null)
		{
			Font font = Font.CreateDynamicFontFromOSFont(new string[6] { "Microsoft YaHei", "微软雅黑", "SimHei", "黑体", "Arial Unicode MS", "Arial" }, 14);
			_winStyle = new GUIStyle(GUI.skin.window)
			{
				font = font
			};
			_winStyle.normal.background = MakeTex(new Color(0.09f, 0.06f, 0.13f, 0.98f));
			_winStyle.padding = new RectOffset(12, 12, 10, 12);
			_winStyle.fontSize = 14;
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				font = font,
				fontSize = 18,
				fontStyle = (FontStyle)1
			};
			val.normal.textColor = new Color(0.85f, 0.72f, 1f);
			_headerStyle = val;
			GUIStyle val2 = new GUIStyle(GUI.skin.label)
			{
				font = font,
				fontSize = 13
			};
			val2.normal.textColor = Color.white;
			_normalStyle = val2;
			GUIStyle val3 = new GUIStyle(GUI.skin.label)
			{
				font = font,
				fontSize = 12
			};
			val3.normal.textColor = new Color(0.7f, 0.66f, 0.78f);
			_mutedStyle = val3;
			GUIStyle val4 = new GUIStyle(GUI.skin.label)
			{
				font = font,
				fontSize = 13,
				alignment = (TextAnchor)5
			};
			val4.normal.textColor = new Color(0.82f, 0.95f, 1f);
			_countStyle = val4;
		}
	}

	private static Texture2D MakeTex(Color color)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_bg == (Object)null)
		{
			_bg = new Texture2D(1, 1);
			_bg.SetPixel(0, 0, color);
			_bg.Apply();
		}
		return _bg;
	}

	private static void WindowFunc(int id)
	{
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Invalid comparison between Unknown and I4
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Invalid comparison between Unknown and I4
		DimensionStorage instance = DimensionStorage.Instance;
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("虚拟维度空间(全星系共享存储)", _headerStyle, Array.Empty<GUILayoutOption>());
		GUILayout.FlexibleSpace();
		if (GUILayout.Button("关闭 [Esc]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }))
		{
			Visible = false;
		}
		GUILayout.EndHorizontal();
		int num = 0;
		long num2 = 0L;
		foreach (KeyValuePair<int, int> item in instance.GetCountsSnapshot())
		{
			if (item.Value > 0)
			{
				num++;
				num2 += item.Value;
			}
		}
		GUILayout.Label($"存储物品种类:{num}    物品总量:{num2:N0}    每种上限范围:0 ~ {10000000:N0}(建筑默认 {50},物品默认 {2000000:N0})", _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(4f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label("搜索:", _normalStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) });
		GUI.SetNextControlName("vd_search");
		_search = GUILayout.TextField(_search, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) });
		GUILayout.Label("输入物品名或ID;留空显示已存储/已设置的物品", _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.EndHorizontal();
		GUILayout.Space(6f);
		_focusedControl = GUI.GetNameOfFocusedControl();
		TextFieldFocused = _focusedControl.StartsWith("vd_", StringComparison.Ordinal);
		float num3 = Mathf.Max(120f, ((Rect)(ref _windowRect)).height - 24f - 176f);
		_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num3) });
		List<int> list = BuildRows(_search);
		foreach (int item2 in list)
		{
			DrawRow(instance, item2);
		}
		if (list.Count == 0)
		{
			GUILayout.Label("(没有匹配的物品)", _mutedStyle, Array.Empty<GUILayoutOption>());
		}
		GUILayout.EndScrollView();
		GUILayout.Label("提示:星际供应槽把超出上限一半的部分存入维度(只出不进);只有设置为星际需求的站点才从维度收货(补至上限一半)。本地小飞机照常工作,可与星际模式组合。跨星球无需飞船。", _mutedStyle, Array.Empty<GUILayoutOption>());
		GUILayout.EndVertical();
		DrawResizeGrip();
		if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 27)
		{
			Visible = false;
			Event.current.Use();
		}
		GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
	}

	private static void DrawResizeGrip()
	{
		//IL_008c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Invalid comparison between Unknown and I4
		//IL_00ad: 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_016f: Invalid comparison between Unknown and I4
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).width - 20f - 6f, ((Rect)(ref _windowRect)).height - 24f - 20f - 4f, 20f, 20f);
		if (_gripStyle == null)
		{
			GUIStyle val2 = new GUIStyle(GUI.skin.label)
			{
				fontSize = 13,
				alignment = (TextAnchor)4
			};
			val2.normal.textColor = new Color(0.62f, 0.52f, 0.8f);
			_gripStyle = val2;
		}
		GUI.Label(val, "◢", _gripStyle);
		Event current = Event.current;
		if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
		{
			_resizing = true;
			_resizeStart = current.mousePosition;
			_resizeStartRect = _windowRect;
			current.Use();
		}
		else if ((int)current.type == 3 && _resizing)
		{
			Vector2 val3 = current.mousePosition - _resizeStart;
			((Rect)(ref _windowRect)).width = Mathf.Clamp(((Rect)(ref _resizeStartRect)).width + val3.x, 620f, (float)Screen.width - 40f);
			((Rect)(ref _windowRect)).height = Mathf.Clamp(((Rect)(ref _resizeStartRect)).height + val3.y, 380f, (float)Screen.height - 40f);
			current.Use();
		}
		else if ((int)current.type == 1 && _resizing)
		{
			_resizing = false;
			if (VDMod.WindowWidthEntry != null)
			{
				VDMod.WindowWidthEntry.Value = ((Rect)(ref _windowRect)).width;
			}
			if (VDMod.WindowHeightEntry != null)
			{
				VDMod.WindowHeightEntry.Value = ((Rect)(ref _windowRect)).height;
			}
			current.Use();
		}
	}

	private static List<int> BuildRows(string search)
	{
		List<int> list = new List<int>();
		DimensionStorage dim = DimensionStorage.Instance;
		if (string.IsNullOrWhiteSpace(search))
		{
			HashSet<int> hashSet = new HashSet<int>();
			foreach (KeyValuePair<int, int> item in dim.GetCountsSnapshot())
			{
				if (item.Value > 0)
				{
					hashSet.Add(item.Key);
				}
			}
			foreach (KeyValuePair<int, int> item2 in dim.GetLimitsSnapshot())
			{
				hashSet.Add(item2.Key);
			}
			list.AddRange(hashSet);
			list.Sort(delegate(int a, int b)
			{
				int num2 = dim.GetCount(b).CompareTo(dim.GetCount(a));
				return (num2 == 0) ? a.CompareTo(b) : num2;
			});
			return list;
		}
		search = search.Trim();
		if (int.TryParse(search, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
		{
			if (((ProtoSet<ItemProto>)(object)LDB.items).Select(result) != null)
			{
				list.Add(result);
			}
			return list;
		}
		ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
		foreach (ItemProto val in dataArray)
		{
			if (val != null && !string.IsNullOrEmpty(((Proto)val).Name))
			{
				if (((Proto)val).Name.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0 || ((Proto)val).ID.ToString(CultureInfo.InvariantCulture).IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					list.Add(((Proto)val).ID);
				}
				if (list.Count >= 200)
				{
					break;
				}
			}
		}
		list.Sort();
		return list;
	}

	private static void DrawRow(DimensionStorage dim, int itemId)
	{
		ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(itemId);
		if (val == null)
		{
			return;
		}
		int count = dim.GetCount(itemId);
		int limit = dim.GetLimit(itemId);
		bool flag = dim.IsCustomLimit(itemId);
		bool isEntity = val.IsEntity;
		if (!_buffers.TryGetValue(itemId, out var value) || string.IsNullOrEmpty(value))
		{
			string text = (_buffers[itemId] = limit.ToString(CultureInfo.InvariantCulture));
			value = text;
		}
		bool flag2 = _focusedControl == "vd_limit_" + itemId;
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
		StringBuilder stringBuilder = new StringBuilder(64);
		stringBuilder.Append(((Proto)val).Name);
		if (isEntity)
		{
			stringBuilder.Append(" [建筑]");
		}
		if (flag)
		{
			stringBuilder.Append(" [自定义]");
		}
		GUILayout.Label(stringBuilder.ToString(), _normalStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(340f) });
		GUILayout.Label(count.ToString("N0", CultureInfo.InvariantCulture), _countStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(130f) });
		GUILayout.Label("/", _mutedStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(10f) });
		GUILayout.Label(limit.ToString("N0", CultureInfo.InvariantCulture), _normalStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
		GUI.SetNextControlName("vd_limit_" + itemId);
		value = GUILayout.TextField(value, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
		_buffers[itemId] = value;
		if (GUILayout.Button("应用", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(46f) }))
		{
			ApplyLimit(dim, itemId, value);
		}
		float num = GUILayout.HorizontalSlider((float)limit, 0f, 10000000f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) });
		if (Math.Abs(num - (float)limit) > 0.5f)
		{
			int value2 = Mathf.RoundToInt(num);
			dim.SetLimit(itemId, value2);
			if (!flag2)
			{
				_buffers[itemId] = value2.ToString(CultureInfo.InvariantCulture);
			}
		}
		if (GUILayout.Button("0", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
		{
			SetAndSync(dim, itemId, 0);
		}
		if (GUILayout.Button("50", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(34f) }))
		{
			SetAndSync(dim, itemId, 50);
		}
		if (GUILayout.Button("200万", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }))
		{
			SetAndSync(dim, itemId, 2000000);
		}
		if (GUILayout.Button("1000万", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(52f) }))
		{
			SetAndSync(dim, itemId, 10000000);
		}
		if (GUILayout.Button("默认", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(44f) }))
		{
			dim.ResetLimit(itemId);
			_buffers[itemId] = dim.GetLimit(itemId).ToString(CultureInfo.InvariantCulture);
		}
		GUILayout.EndHorizontal();
	}

	private static void SetAndSync(DimensionStorage dim, int itemId, int value)
	{
		dim.SetLimit(itemId, value);
		_buffers[itemId] = value.ToString(CultureInfo.InvariantCulture);
	}

	private static void ApplyLimit(DimensionStorage dim, int itemId, string text)
	{
		if (TryParseLimit(text, out var value))
		{
			SetAndSync(dim, itemId, value);
		}
	}

	private static bool TryParseLimit(string text, out int value)
	{
		value = 0;
		if (string.IsNullOrWhiteSpace(text))
		{
			return false;
		}
		text = text.Trim().Replace(",", string.Empty).Replace(" ", string.Empty);
		int num = 1;
		char c = text[text.Length - 1];
		if (c == 'w' || c == 'W' || c == '万')
		{
			num = 10000;
			text = text.Substring(0, text.Length - 1);
		}
		if (!double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
		{
			return false;
		}
		value = Mathf.Clamp((int)Math.Round(result * (double)num), 0, 10000000);
		return true;
	}
}
[HarmonyPatch(typeof(StationComponent), "InternalTickLocal")]
public static class StationInternalTickLocalPatch
{
	public static void Postfix(StationComponent __instance, PlanetFactory factory, float power)
	{
		if (power > 0.01f && Content.IsTowerEntity(factory, __instance))
		{
			StationLogic.Service(__instance, factory);
		}
	}
}
[HarmonyPatch(typeof(UIStationWindow), "_OnUpdate")]
public static class UIStationWindowUpdatePatch
{
	private const string Title = "虚拟维度塔";

	public static void Postfix(UIStationWindow __instance)
	{
		try
		{
			if (__instance.transport == null)
			{
				return;
			}
			int value = Traverse.Create((object)__instance).Field("_stationId").GetValue<int>();
			if (value > 0)
			{
				StationComponent stationComponent = __instance.transport.GetStationComponent(value);
				if (Content.IsTowerEntity(__instance.transport.factory, stationComponent) && (Object)(object)__instance.titleText != (Object)null)
				{
					__instance.titleText.text = "虚拟维度塔";
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(GameData), "NewGame")]
public static class GameDataNewGamePatch
{
	public static void Postfix()
	{
		DimensionStorage.Instance.Reset();
	}
}
[HarmonyPatch(typeof(SpaceSector), "InitPrefabDescArray")]
public static class SpaceSectorPrefabArrayFix
{
	private static readonly ManualLogSource Log = Logger.CreateLogSource("VirtualDimension.PrefabFix");

	[HarmonyPrefix]
	public static bool Prefix()
	{
		if (SpaceSector.PrefabDescByModelIndex != null)
		{
			return false;
		}
		SpaceSector.PrefabDescByModelIndex = BuildArray();
		return false;
	}

	public static PrefabDesc[] BuildArray()
	{
		ModelProto[] dataArray = ((ProtoSet<ModelProto>)(object)LDB.models).dataArray;
		int num = 0;
		for (int i = 0; i < dataArray.Length; i++)
		{
			if (dataArray[i] != null && ((Proto)dataArray[i]).ID > num)
			{
				num = ((Proto)dataArray[i]).ID;
			}
		}
		PrefabDesc[] array = (PrefabDesc[])(object)new PrefabDesc[num + 1];
		for (int j = 0; j < dataArray.Length; j++)
		{
			if (dataArray[j] != null)
			{
				array[((Proto)dataArray[j]).ID] = dataArray[j].prefabDesc;
			}
		}
		Log.LogInfo((object)$"PrefabDescByModelIndex rebuilt: {dataArray.Length} models, max id {num}, size {array.Length}");
		return array;
	}
}
[HarmonyPatch(typeof(PlanetFactory), "InitPrefabDescArray")]
public static class PlanetFactoryPrefabArrayFix
{
	[HarmonyPrefix]
	public static bool Prefix()
	{
		if (PlanetFactory.PrefabDescByModelIndex != null)
		{
			return false;
		}
		PlanetFactory.PrefabDescByModelIndex = SpaceSectorPrefabArrayFix.BuildArray();
		return false;
	}
}
public static class StationLogic
{
	public static void Service(StationComponent station, PlanetFactory factory)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Invalid comparison between Unknown and I4
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Invalid comparison between Unknown and I4
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		if (station == null || station.storage == null)
		{
			return;
		}
		DimensionStorage instance = DimensionStorage.Instance;
		int num = Mathf.Max(1, VDMod.TransferPerTick);
		for (int i = 0; i < station.storage.Length; i++)
		{
			StationStore val = station.storage[i];
			if (val.itemId <= 0 || val.max <= 0)
			{
				continue;
			}
			int num2 = val.max / 2;
			if ((int)val.remoteLogic == 1)
			{
				int num3 = val.count - num2;
				if (num3 > 0)
				{
					int num4 = instance.Insert(val.itemId, Mathf.Min(num3, num));
					if (num4 > 0)
					{
						val.count -= num4;
					}
				}
			}
			else if ((int)val.remoteLogic == 2)
			{
				int num5 = num2 - val.count;
				if (num5 > 0)
				{
					int num6 = instance.TakeOut(val.itemId, Mathf.Min(num5, num));
					if (num6 > 0)
					{
						val.count += num6;
					}
				}
			}
			station.storage[i] = val;
		}
	}
}
public static class VDMod
{
	public const string GUID = "org.trae.virtualdimension";

	public const string NAME = "VirtualDimension";

	public const string VERSION = "1.2.1";

	public const int TOWER_ITEM_ID = 2104;

	public const string KEYBIND_NAME = "OpenVirtualDimensionUI";

	public const int HARD_MAX_LIMIT = 10000000;

	public const int DEFAULT_ITEM_LIMIT = 2000000;

	public const int DEFAULT_BUILDING_LIMIT = 50;

	public const int DEFAULT_TRANSFER_PER_TICK = 3600;

	public const float DEFAULT_WINDOW_WIDTH = 1000f;

	public const float DEFAULT_WINDOW_HEIGHT = 620f;

	public static ConfigFile ConfigFile;

	public static ConfigEntry<float> WindowWidthEntry;

	public static ConfigEntry<float> WindowHeightEntry;

	public static int TransferPerTick = 3600;
}
[BepInPlugin("org.trae.virtualdimension", "VirtualDimension", "1.2.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[CommonAPISubmoduleDependency(new string[] { "ProtoRegistry", "CustomKeyBindSystem", "LocalizationModule" })]
public class VirtualDimensionPlugin : BaseUnityPlugin, IModCanSave
{
	private Harmony _harmony;

	private PressKeyBind _openUiKey;

	private ConfigEntry<int> _transferPerTick;

	private void Awake()
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		VDMod.ConfigFile = ((BaseUnityPlugin)this).Config;
		_transferPerTick = ((BaseUnityPlugin)this).Config.Bind<int>("General", "TransferPerTick", 3600, "Items transferred per tick (60 ticks/s) between a tower slot and the dimension.");
		VDMod.WindowWidthEntry = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowWidth", 1000f, "Saved width of the Alt+5 dimension window (resizable via the bottom-right grip).");
		VDMod.WindowHeightEntry = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowHeight", 620f, "Saved height of the Alt+5 dimension window.");
		VDMod.TransferPerTick = Mathf.Clamp(_transferPerTick.Value, 1, 10000000);
		_harmony = new Harmony("org.trae.virtualdimension");
		_harmony.PatchAll(Assembly.GetExecutingAssembly());
		Content.Register(((BaseUnityPlugin)this).Logger);
		CustomKeyBindSystem.RegisterKeyBindWithReturn<PressKeyBind>(new BuiltinKey
		{
			key = new CombineKey(53, (byte)4, (ECombineKeyAction)0, false),
			conflictGroup = 2052,
			name = "OpenVirtualDimensionUI",
			canOverride = true
		});
		((BaseUnityPlugin)this).Logger.LogInfo((object)"VirtualDimension 1.2.1 loaded.");
	}

	private void Update()
	{
		if (_openUiKey == null)
		{
			_openUiKey = CustomKeyBindSystem.GetKeyBind("OpenVirtualDimensionUI");
		}
		if (_openUiKey != null && _openUiKey.keyValue && InGame())
		{
			DimensionUI.Toggle();
		}
		if (DimensionUI.Visible && DimensionUI.TextFieldFocused)
		{
			VFInput.inputing = true;
		}
	}

	private void OnGUI()
	{
		if (DimensionUI.Visible && InGame())
		{
			DimensionUI.OnGUI();
		}
	}

	private static bool InGame()
	{
		if (GameMain.data != null)
		{
			return GameMain.mainPlayer != null;
		}
		return false;
	}

	public void Export(BinaryWriter w)
	{
		try
		{
			DimensionStorage.Instance.Save(w);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Dimension save failed: " + ex));
		}
	}

	public void Import(BinaryReader r)
	{
		try
		{
			DimensionStorage.Instance.Load(r);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Dimension storage loaded.");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Dimension load failed: " + ex));
			DimensionStorage.Instance.Reset();
		}
	}

	public void IntoOtherSave()
	{
		DimensionStorage.Instance.Reset();
		DimensionUI.Visible = false;
	}
}