Decompiled source of PING v0.9.10

plugins/PingMod.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CommonAPI;
using CommonAPI.Systems;
using CommonAPI.Systems.ModLocalization;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PingMod.Patches;
using PingMod.UI;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;
using crecheng.DSPModSave;
using xiaoye97;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PING - Portal Icarus Neural Gateway")]
[assembly: AssemblyDescription("PING - Interstellar paired teleportation portal for Dyson Sphere Program")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PING Mod")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f0f0f0f0-1234-5678-9abc-def012345678")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.1.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 PingMod
{
	[BepInPlugin("org.dspmod.plugin.ping", "PING - Portal Icarus Neural Gateway", "0.9.10")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[CommonAPISubmoduleDependency(new string[] { "ProtoRegistry", "CustomDescSystem", "UtilSystem", "LocalizationModule" })]
	public class PingPlugin : BaseUnityPlugin, IModCanSave
	{
		public const string MODID = "ping";

		public const string GUID = "org.dspmod.plugin.ping";

		public const string NAME = "PING - Portal Icarus Neural Gateway";

		public const string VERSION = "0.9.10";

		public const int PING_ITEM_ID = 3500;

		public const int PING_MODEL_ID = 699;

		public const int PING_RECIPE_ID = 3500;

		public const int UNLOCK_TECH_ID = 1512;

		private const int REFERENCE_ITEM_ID = 2206;

		private const string REFERENCE_PREFAB_HINT = "accumulator";

		private const string REFERENCE_PREFAB_EXCLUDE = "full";

		public static ManualLogSource Log;

		public static ItemProto PingItem;

		public static ModelProto PingModel;

		public static RecipeProto PingRecipe;

		public static ConfigEntry<float> EnergyPerLightYearMJ;

		public static ConfigEntry<float> MaxTravelDistanceLY;

		public static ConfigEntry<float> MaxEnergyStoredGJ;

		public static ConfigEntry<float> ChargingPowerMW;

		public static ConfigEntry<int> CooldownSeconds;

		public static ConfigEntry<float> WindowOpacity;

		public static ConfigEntry<bool> RemoveAllPortals;

		private const string DEFAULT_INGREDIENTS = "1305x20,1209x25,1210x50,1402x25,2206x100";

		private const int RECIPE_SECONDS = 40;

		private const float PODIUM_RADIUS = 3f;

		private const float GATE_MARGIN = 2f;

		private const string CUSTOM_KEYWORD = "pingmod";

		private const string CUSTOM_BUNDLE = "pingmod";

		private const string CUSTOM_PREFAB_PATH = "assets/pingmod/pingportal";

		private const string CUSTOM_ICON_PATH = "assets/pingmod/icon";

		private const byte SAVE_VERSION = 3;

		private const BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static float GateRange => 5f;

		public static bool RequirePaired => true;

		public static float WindowAlpha => WindowOpacity?.Value ?? 0.78f;

		public static long CooldownTicks => (long)(CooldownSeconds?.Value ?? 10) * 60L;

		public static double MaxTravelDistanceLightYears => MaxTravelDistanceLY?.Value ?? 50f;

		public static long MaxEnergyJoules => (long)((double)(MaxEnergyStoredGJ?.Value ?? 10f) * 1000000000.0);

		public static double EnergyPerLightYearJoules => (double)(EnergyPerLightYearMJ?.Value ?? 192f) * 1000000.0;

		public static long ChargeJoulesPerTick => (long)Math.Round((double)(ChargingPowerMW?.Value ?? 150f) * 1000000.0 / 60.0);

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"PING v0.9.10 starting...");
			Guard("config", BindConfig);
			Guard("proto registration", RegisterProtos);
			Guard("loading-finished hook", delegate
			{
				ProtoRegistry.onLoadingFinished += OnLoadingFinished;
			});
			Guard("harmony patches", InstallPatches);
			Log.LogInfo((object)"PING v0.9.10 initialized.");
		}

		private void BindConfig()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			EnergyPerLightYearMJ = ((BaseUnityPlugin)this).Config.Bind<float>("Balancing", "EnergyPerLightYearMJ", 192f, new ConfigDescription("Energy cost per light year of travel distance (MJ). Every jump costs at least 192 MJ.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10000f), Array.Empty<object>()));
			MaxTravelDistanceLY = ((BaseUnityPlugin)this).Config.Bind<float>("Balancing", "MaxTravelDistanceLY", 50f, new ConfigDescription("Maximum distance of a single jump (light years). Longer jumps are refused.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 500f), Array.Empty<object>()));
			MaxEnergyStoredGJ = ((BaseUnityPlugin)this).Config.Bind<float>("Balancing", "MaxEnergyStoredGJ", 10f, new ConfigDescription("Energy capacity of a PING portal (GJ). At 192 MJ/LY a full 50 LY jump costs 9.6 GJ.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1000f), Array.Empty<object>()));
			ChargingPowerMW = ((BaseUnityPlugin)this).Config.Bind<float>("Balancing", "ChargingPowerMW", 150f, new ConfigDescription("Maximum charging power of a PING portal (MW). It charges from surplus power of the grid.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10000f), Array.Empty<object>()));
			CooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Balancing", "CooldownSeconds", 10, new ConfigDescription("Cooldown after a teleport before the same portal can be used again (seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3600), Array.Empty<object>()));
			RemoveAllPortals = ((BaseUnityPlugin)this).Config.Bind<bool>("Uninstall", "RemoveAllPortals", false, "Set to true, load your save once and save again: every PING Portal on each planet is dismantled and returned to your inventory (once per planet per session). Do this before removing the mod, then set it back to false.");
			WindowOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowOpacity", 0.78f, new ConfigDescription("Opacity of the destination window (0.2 = very transparent, 1 = solid).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
		}

		private static void RegisterProtos()
		{
			using (ProtoRegistry.StartModLoad("org.dspmod.plugin.ping"))
			{
				Guard("localization", RegisterLocalization);
				Guard("item", RegisterItem);
				Guard("model", RegisterModel);
				Guard("recipe", RegisterRecipe);
				Guard("build bar", delegate
				{
					LDBTool.SetBuildBar(6, 1, ((Proto)PingItem).ID);
				});
			}
		}

		private static void RegisterLocalization()
		{
			LocalizationModule.RegisterTranslation("ping_gate", "PING Portal", "PING神经网关", "Portail PING");
			LocalizationModule.RegisterTranslation("ping_gateDesc", "PING - Portal Icarus Neural Gateway. Charges from surplus power like an accumulator. While standing on the platform or within 2 m of it, open the Galactic Map, select a planet and use the fast travel button to jump. The destination planet must also have a PING portal, you arrive next to it. Cost: 192 MJ / Light-Year.", "PING - Icarus神经传输网关。像蓄电器一样充电。站在平台上或距离平台2米内时打开星图,选择星球并点击快速旅行即可传送。目标星球也必须有网关,你会出现在它旁边。能耗:每光年192兆焦。", "PING - Portail Icarus Neural Gateway. Se charge avec le surplus d'énergie comme un accumulateur. Sur la plateforme ou à moins de 2 m, ouvrez la carte galactique, sélectionnez une planète et utilisez le voyage rapide. La planète de destination doit aussi posséder un portail PING, vous arrivez à côté. Coût : 192 MJ / année-lumière.");
			LocalizationModule.RegisterTranslation("ping_gateRecipe", "PING Portal", "PING神经网关", "Portail PING");
		}

		private static void RegisterItem()
		{
			PingItem = ProtoRegistry.RegisterItem(3500, "ping_gate", "ping_gateDesc", ResolveReferenceItem()?.IconPath, ProtoRegistry.GetGridIndex(2, 9, 10));
			if (PingItem != null)
			{
				PingItem.StackSize = 5;
				Log.LogInfo((object)$"PING item registered (id={3500}).");
			}
		}

		private static void RegisterModel()
		{
			ItemProto val = ResolveReferenceItem();
			if (val == null)
			{
				Log.LogError((object)string.Format("PING: no vanilla accumulator found (item {0} / prefab hint '{1}'). Model registration skipped.", 2206, "accumulator"));
				return;
			}
			ModelProto val2 = ((ProtoSet<ModelProto>)(object)LDB.models).Select(val.ModelIndex);
			if (val2 == null || string.IsNullOrEmpty(val2.PrefabPath))
			{
				Log.LogError((object)$"PING: reference model of item {((Proto)val).ID} is missing or has no prefab path.");
				return;
			}
			int[] array = ((val.DescFields != null && val.DescFields.Length != 0) ? ((int[])val.DescFields.Clone()) : new int[4] { 22, 11, 12, 1 });
			int[] array2 = ((val.Upgrades != null && val.Upgrades.Length != 0) ? ((int[])val.Upgrades.Clone()) : new int[2]
			{
				((Proto)val).ID,
				0
			});
			string text = TryLoadCustomModel();
			string text2 = text ?? val2.PrefabPath;
			if (text != null && PingItem != null)
			{
				PingItem.IconPath = "assets/pingmod/icon";
				Log.LogInfo((object)"PING: item icon path set to 'assets/pingmod/icon'.");
			}
			PingModel = ProtoRegistry.RegisterModel(699, PingItem, text2, (Material[])null, array, val.BuildIndex, val.BuildMode, array2);
			Log.LogInfo((object)$"PING model registered (id={699}, prefab='{text2}', isNull={PingModel == null}).");
		}

		private static string TryLoadCustomModel()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			try
			{
				string directoryName = Path.GetDirectoryName(typeof(PingPlugin).Assembly.Location);
				string text = Path.Combine(directoryName, "pingmod");
				if (!File.Exists(text))
				{
					Log.LogWarning((object)("PING: model bundle not found at '" + text + "'. Using the vanilla accumulator model."));
					return null;
				}
				ResourceData val = new ResourceData("org.dspmod.plugin.ping", "pingmod", directoryName);
				val.LoadAssetBundle("pingmod");
				if (!val.HasAssetBundle())
				{
					Log.LogWarning((object)"PING: the model bundle could not be loaded. Using the vanilla accumulator model.");
					return null;
				}
				ProtoRegistry.AddResource(val);
				Log.LogInfo((object)("PING: custom model bundle loaded ('" + text + "'), prefab 'assets/pingmod/pingportal'."));
				return "assets/pingmod/pingportal";
			}
			catch (Exception ex)
			{
				SafeError("custom model bundle failed, using the vanilla accumulator model", ex);
				return null;
			}
		}

		private static ItemProto ResolveReferenceItem()
		{
			ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(2206);
			if (IsAccumulatorReference(val))
			{
				return val;
			}
			ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
			if (dataArray == null)
			{
				return null;
			}
			ItemProto[] array = dataArray;
			foreach (ItemProto val2 in array)
			{
				if (IsAccumulatorReference(val2))
				{
					return val2;
				}
			}
			return null;
		}

		private static bool IsAccumulatorReference(ItemProto item)
		{
			if (item == null || ((Proto)item).ID <= 0)
			{
				return false;
			}
			string text = ((ProtoSet<ModelProto>)(object)LDB.models).Select(item.ModelIndex)?.PrefabPath;
			if (!string.IsNullOrEmpty(text) && text.IndexOf("accumulator", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return text.IndexOf("full", StringComparison.OrdinalIgnoreCase) < 0;
			}
			return false;
		}

		private static void RegisterRecipe()
		{
			if (PingItem == null)
			{
				return;
			}
			List<int> list = new List<int>();
			List<int> list2 = new List<int>();
			ParseIngredients("1305x20,1209x25,1210x50,1402x25,2206x100", list, list2);
			if (list.Count == 0)
			{
				Log.LogWarning((object)"PING: the configured ingredients are empty or invalid, using the defaults.");
				ParseIngredients("1305x20,1209x25,1210x50,1402x25,2206x100", list, list2);
			}
			if (list.Count > 6)
			{
				Log.LogWarning((object)"PING: more than 6 ingredients configured, only the first 6 are used.");
				list.RemoveRange(6, list.Count - 6);
				list2.RemoveRange(6, list2.Count - 6);
			}
			int[] array = list.ToArray();
			int[] array2 = list2.ToArray();
			List<int> list3 = new List<int>();
			List<int> list4 = new List<int>();
			for (int i = 0; i < array.Length; i++)
			{
				if (((ProtoSet<ItemProto>)(object)LDB.items).Select(array[i]) == null)
				{
					Log.LogWarning((object)$"PING: recipe ingredient {array[i]} does not exist in this game version and was left out.");
					continue;
				}
				list3.Add(array[i]);
				list4.Add(array2[i]);
			}
			PingRecipe = ProtoRegistry.RegisterRecipe(3500, (ERecipeType)4, 2400, list3.ToArray(), list4.ToArray(), new int[1] { ((Proto)PingItem).ID }, new int[1] { 1 }, "ping_gateDesc", 0);
			if (PingRecipe != null)
			{
				TrySetField(PingRecipe, "ping_gateRecipe", "name");
				TrySetField(PingRecipe, "ping_gateDesc", "desc");
				TrySetField(PingRecipe, 1, "proliferateEffect", "ProliferateEffect");
				if (PingItem != null)
				{
					PingRecipe.IconPath = PingItem.IconPath;
				}
				Log.LogInfo((object)$"PING recipe registered (id={3500}, {list3.Count} ingredients).");
			}
		}

		private static void ParseIngredients(string text, List<int> ids, List<int> counts)
		{
			string[] array = (text ?? "").Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array)
			{
				string[] array2 = text2.Trim().Split(new char[4] { 'x', 'X', ':', '*' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length != 2 || !int.TryParse(array2[0].Trim(), out var result) || !int.TryParse(array2[1].Trim(), out var result2) || result <= 0 || result2 <= 0)
				{
					Log.LogWarning((object)("PING: could not read ingredient '" + text2.Trim() + "' (expected itemIdxcount, e.g. 1305x20)."));
					continue;
				}
				ids.Add(result);
				counts.Add(result2);
			}
		}

		private static void AssignGridIndex()
		{
			if (PingItem == null)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			ItemProto[] dataArray = ((ProtoSet<ItemProto>)(object)LDB.items).dataArray;
			foreach (ItemProto val in dataArray)
			{
				if (val != null && val != PingItem && val.GridIndex > 0)
				{
					hashSet.Add(val.GridIndex);
				}
			}
			RecipeProto[] dataArray2 = ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray;
			foreach (RecipeProto val2 in dataArray2)
			{
				if (val2 != null && val2 != PingRecipe && val2.GridIndex > 0)
				{
					hashSet.Add(val2.GridIndex);
				}
			}
			ItemProto val3 = ResolveReferenceItem();
			int num = ((val3 != null && val3.GridIndex >= 1101) ? val3.GridIndex : 2101);
			int num2 = num / 1000;
			int num3 = (num - num2 * 1000) / 100;
			int num4 = num % 100;
			int num5 = 0;
			for (int j = 0; j < 2; j++)
			{
				if (num5 != 0)
				{
					break;
				}
				for (int k = ((j != 0) ? 1 : num3); k <= 8; k++)
				{
					if (num5 != 0)
					{
						break;
					}
					for (int l = ((j != 0 || k != num3) ? 1 : (num4 + 1)); l <= 14; l++)
					{
						int num6 = num2 * 1000 + k * 100 + l;
						if (!hashSet.Contains(num6))
						{
							num5 = num6;
							break;
						}
					}
				}
			}
			if (num5 == 0)
			{
				Log.LogWarning((object)$"PING: no free grid cell found on page {num2}. The recipe may not be visible in the assembler.");
				return;
			}
			PingItem.GridIndex = num5;
			if (PingRecipe != null)
			{
				PingRecipe.GridIndex = num5;
			}
			Log.LogInfo((object)$"PING grid cell: {num5} (page {num2}, row {num5 % 1000 / 100}, column {num5 % 100}).");
		}

		private void InstallPatches()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Harmony harmony = new Harmony("org.dspmod.plugin.ping");
			Guard("fast-travel button patches", delegate
			{
				FastTravelPatch.Install(harmony);
			});
			Guard("starmap teleport patch", delegate
			{
				PingStarmapPatch.Install(harmony);
			});
			Guard("target window patches", delegate
			{
				PingUiPatch.Install(harmony);
			});
			Guard("factory tick patch", delegate
			{
				PingTicker.Install(harmony);
			});
		}

		private static void OnLoadingFinished()
		{
			Guard("grid cell", AssignGridIndex);
			Guard("attach recipe to tech", AttachRecipeToTech);
			Guard("build bar", delegate
			{
				if (PingItem != null)
				{
					LDBTool.SetBuildBar(6, 1, ((Proto)PingItem).ID);
				}
			});
			Guard("diagnostics", LogDiagnostics);
			Guard("reference size", LogReferenceSize);
			Guard("game materials and power", ApplyGameMaterialsAndPower);
		}

		private static void ApplyGameMaterialsAndPower()
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			if (PingItem == null)
			{
				return;
			}
			PrefabDesc val = ResolveReferenceItem()?.prefabDesc;
			PrefabDesc prefabDesc = PingItem.prefabDesc;
			if (val == null || prefabDesc == null)
			{
				Log.LogWarning((object)"PING: prefab descriptions missing, cannot apply materials and wiring.");
				return;
			}
			LogPower("vanilla accumulator", val);
			LogPower("PING portal (before)", prefabDesc);
			prefabDesc.isPowerNode = val.isPowerNode;
			prefabDesc.powerConnectDistance = val.powerConnectDistance;
			prefabDesc.powerCoverRadius = val.powerCoverRadius;
			LogPower("PING portal (after)", prefabDesc);
			if (PingModel == null || PingModel.PrefabPath == null || PingModel.PrefabPath.IndexOf("pingmod", StringComparison.Ordinal) < 0)
			{
				return;
			}
			Material[][] lodMaterials = val.lodMaterials;
			Material[][] lodMaterials2 = prefabDesc.lodMaterials;
			if (lodMaterials == null || lodMaterials.Length == 0 || lodMaterials[0] == null || lodMaterials[0].Length == 0 || lodMaterials2 == null || lodMaterials2.Length == 0 || lodMaterials2[0] == null)
			{
				Log.LogWarning((object)"PING: no materials available to copy.");
				return;
			}
			LogMaterial("vanilla accumulator material", lodMaterials[0][0]);
			Material[] array = lodMaterials2[0];
			Material[] array2 = (Material[])(object)new Material[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				Material val2 = new Material(lodMaterials[0][Math.Min(i, lodMaterials[0].Length - 1)]);
				((Object)val2).name = "PING_" + i;
				CopyTextures(array[i], val2, i);
				if (val2.HasProperty("_CullMode"))
				{
					val2.SetFloat("_CullMode", 0f);
				}
				array2[i] = val2;
			}
			lodMaterials2[0] = array2;
			Log.LogInfo((object)$"PING: {array2.Length} game materials applied to the portal model.");
		}

		private static void CopyTextures(Material from, Material to, int index)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			if ((Object)(object)from == (Object)null || (Object)(object)to == (Object)null || (Object)(object)to.shader == (Object)null)
			{
				return;
			}
			Shader shader = to.shader;
			int propertyCount = shader.GetPropertyCount();
			for (int i = 0; i < propertyCount; i++)
			{
				if ((int)shader.GetPropertyType(i) != 4)
				{
					continue;
				}
				string propertyName = shader.GetPropertyName(i);
				string text = propertyName.ToLowerInvariant();
				if (text.Contains("jitter"))
				{
					continue;
				}
				string text2 = null;
				if (propertyName == "_MainTex")
				{
					text2 = "_MainTex";
				}
				else if (text.Contains("normal") || text.Contains("bump"))
				{
					text2 = "_BumpMap";
				}
				else if (text.Contains("emi"))
				{
					text2 = "_EmissionMap";
				}
				else if (text.Contains("ms") || text.Contains("metal"))
				{
					text2 = "_MetallicGlossMap";
				}
				if (text2 == null || !from.HasProperty(text2))
				{
					continue;
				}
				Texture texture = from.GetTexture(text2);
				if ((Object)(object)texture == (Object)null)
				{
					if (text2 == "_EmissionMap")
					{
						to.SetTexture(propertyName, (Texture)(object)Texture2D.blackTexture);
					}
					else if (text2 == "_BumpMap")
					{
						to.SetTexture(propertyName, (Texture)(object)Texture2D.normalTexture);
					}
					Log.LogInfo((object)string.Format("PING: material {0}: no '{1}' in the bundle, '{2}' set to {3}.", index, text2, propertyName, (text2 == "_MetallicGlossMap") ? "the vanilla texture" : "a neutral texture"));
				}
				else
				{
					to.SetTexture(propertyName, texture);
					Log.LogInfo((object)$"PING: material {index}: '{propertyName}' <- bundle texture '{((Object)texture).name}' ({text2}).");
				}
			}
		}

		private static void LogPower(string label, PrefabDesc d)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Log.LogInfo((object)($"PING power [{label}]: isAccumulator={d.isAccumulator} isPowerNode={d.isPowerNode} isPowerConsumer={d.isPowerConsumer} " + $"powerPoint={d.powerPoint} connectDistance={d.powerConnectDistance} coverRadius={d.powerCoverRadius} " + $"input={d.inputEnergyPerTick} output={d.outputEnergyPerTick} max={d.maxAcuEnergy} hasBuildCollider={d.hasBuildCollider}"));
		}

		private static void LogMaterial(string label, Material m)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			if ((Object)(object)m == (Object)null || (Object)(object)m.shader == (Object)null)
			{
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			Shader shader = m.shader;
			int propertyCount = shader.GetPropertyCount();
			for (int i = 0; i < propertyCount; i++)
			{
				string propertyName = shader.GetPropertyName(i);
				ShaderPropertyType propertyType = shader.GetPropertyType(i);
				stringBuilder.Append(propertyName).Append(':').Append(propertyType);
				if ((int)propertyType == 0)
				{
					stringBuilder.Append('=').Append(ColorUtility.ToHtmlStringRGBA(m.GetColor(propertyName)));
				}
				else if ((int)propertyType == 2 || (int)propertyType == 3)
				{
					stringBuilder.Append('=').Append(m.GetFloat(propertyName));
				}
				stringBuilder.Append("  ");
			}
			Log.LogInfo((object)$"PING material [{label}] shader='{((Object)shader).name}' properties: {stringBuilder}");
		}

		private static void LogReferenceSize()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			PrefabDesc val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(2206)?.prefabDesc;
			if (val == null)
			{
				Log.LogWarning((object)"PING: reference accumulator has no prefabDesc.");
				return;
			}
			string arg = ((val.lodDistances == null) ? "-" : string.Join(", ", val.lodDistances));
			Log.LogInfo((object)($"PING ref accumulator: buildCollider.ext={val.buildCollider.ext} buildCollider.pos={val.buildCollider.pos} " + $"selectCenter={val.selectCenter} selectSize={val.selectSize} cullingHeight={val.cullingHeight} " + $"roughHeight={val.roughHeight} lodCount={val.lodCount} lodDistances=[{arg}]"));
		}

		private static void AttachRecipeToTech()
		{
			if (PingRecipe == null)
			{
				return;
			}
			TechProto val = ((ProtoSet<TechProto>)(object)LDB.techs).Select(1512);
			if (val == null || ((Proto)val).ID == 0)
			{
				Log.LogWarning((object)$"PING: tech {1512} not found. Unlocking the recipe directly instead.");
				TrySetField(PingRecipe, false, "Locked", "locked");
				return;
			}
			FieldInfo fieldInfo = FindField(typeof(TechProto), "UnlockRecipes", "unlockRecipeIds", "UnlockRecipeIds");
			if (fieldInfo == null)
			{
				Log.LogError((object)"PING: TechProto has no recipe-unlock field (tried UnlockRecipes/unlockRecipeIds/UnlockRecipeIds). Recipe NOT attached!");
				return;
			}
			List<int> list = new List<int>((fieldInfo.GetValue(val) as int[]) ?? new int[0]);
			if (!list.Contains(((Proto)PingRecipe).ID))
			{
				list.Add(((Proto)PingRecipe).ID);
				fieldInfo.SetValue(val, list.ToArray());
			}
			Log.LogInfo((object)$"PING recipe attached to tech: {((Proto)val).name} (id={((Proto)val).ID})");
		}

		private static void LogDiagnostics()
		{
			if (PingItem == null || PingModel == null)
			{
				Log.LogWarning((object)"PING: item or model was not registered.");
				return;
			}
			PrefabDesc prefabDesc = PingItem.prefabDesc;
			Log.LogInfo((object)$"PING model prefab: '{PingModel.PrefabPath}', isAccumulator={prefabDesc?.isAccumulator ?? false}.");
			if (prefabDesc == null || !prefabDesc.isAccumulator)
			{
				Log.LogWarning((object)"PING: the portal prefab is not an accumulator. It will not charge from the grid!");
			}
		}

		public void Export(BinaryWriter w)
		{
			w.Write((byte)3);
			w.Write(PingTicker.AllPortals.Count);
			foreach (PortalData value in PingTicker.AllPortals.Values)
			{
				w.Write(value.planetId);
				w.Write(value.entityId);
				w.Write(value.localPos.x);
				w.Write(value.localPos.y);
				w.Write(value.localPos.z);
				w.Write(value.cooldownUntilTick);
			}
		}

		public void Import(BinaryReader r)
		{
			//IL_0074: 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)
			PingTicker.Reset();
			byte b = r.ReadByte();
			if (b > 3)
			{
				Log.LogWarning((object)$"PING: save data version {b} is newer than supported ({(byte)3}), ignoring it.");
				return;
			}
			int num = r.ReadInt32();
			for (int i = 0; i < num; i++)
			{
				PortalData portalData = new PortalData();
				if (b >= 3)
				{
					portalData.planetId = r.ReadInt32();
					portalData.entityId = r.ReadInt32();
					portalData.localPos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
					portalData.posKnown = true;
					portalData.cooldownUntilTick = r.ReadInt64();
				}
				else if (b == 2)
				{
					portalData.planetId = r.ReadInt32();
					portalData.entityId = r.ReadInt32();
					r.ReadDouble();
					r.ReadInt32();
					portalData.cooldownUntilTick = r.ReadInt64();
				}
				else
				{
					portalData.entityId = r.ReadInt32();
					r.ReadDouble();
					r.ReadInt32();
					portalData.cooldownUntilTick = r.ReadInt64();
					portalData.planetId = r.ReadInt32();
				}
				PingTicker.AllPortals[PingTicker.Key(portalData.planetId, portalData.entityId)] = portalData;
			}
		}

		public void IntoOtherSave()
		{
			PingTicker.Reset();
		}

		internal static void Guard(string phase, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				SafeError("PING - " + phase + " failed", ex);
			}
		}

		internal static void SafeError(string msg, Exception ex)
		{
			try
			{
				if (Log != null)
				{
					Log.LogError((object)(msg + ": " + ex.Message));
					Log.LogWarning((object)ex.StackTrace);
				}
				else
				{
					Debug.LogError((object)("[PING] " + msg + ": " + ex));
				}
			}
			catch
			{
			}
		}

		private static FieldInfo FindField(Type type, params string[] names)
		{
			foreach (string name in names)
			{
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field;
				}
			}
			return null;
		}

		internal static void LogIcon(string label, object proto, string path)
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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)
			if (proto == null)
			{
				return;
			}
			PropertyInfo property = proto.GetType().GetProperty("iconSprite", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo fieldInfo = ((property == null) ? FindField(proto.GetType(), "iconSprite") : null);
			Sprite val = null;
			try
			{
				if (property != null)
				{
					object? value = property.GetValue(proto, null);
					val = (Sprite)((value is Sprite) ? value : null);
				}
				else if (fieldInfo != null)
				{
					object? value2 = fieldInfo.GetValue(proto);
					val = (Sprite)((value2 is Sprite) ? value2 : null);
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("PING icon: reading the sprite failed: " + ex.Message));
			}
			string text = "-";
			if ((Object)(object)val != (Object)null && (Object)(object)val.texture != (Object)null)
			{
				text = ((Texture)val.texture).width + "x" + ((Texture)val.texture).height + ", format " + ((object)val.texture.format/*cast due to .constrained prefix*/).ToString() + ", mips " + ((Texture)val.texture).mipmapCount + ", rect " + ((object)val.rect/*cast due to .constrained prefix*/).ToString();
			}
			Log.LogInfo((object)string.Format("PING icon [{0}]: path='{1}', member found={2}, sprite={3}, texture={4}.", label, path, property != null || fieldInfo != null, ((Object)(object)val != (Object)null) ? ((Object)val).name : "null", text));
		}

		private static void TrySetField(object target, object value, params string[] names)
		{
			FieldInfo fieldInfo = FindField(target.GetType(), names);
			if (fieldInfo != null)
			{
				fieldInfo.SetValue(target, value);
			}
		}
	}
	public class PortalData
	{
		public int planetId;

		public int entityId;

		public Vector3 localPos;

		public bool posKnown;

		public long cooldownUntilTick;
	}
	internal static class PatchHelper
	{
		public static HarmonyMethod Method(Type type, string name)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			return new HarmonyMethod(AccessTools.Method(type, name, (Type[])null, (Type[])null));
		}

		public static bool TryPatch(Harmony harmony, Type type, string method, Type[] args = null, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
		{
			string text = type.Name + "." + method;
			try
			{
				MethodInfo methodInfo = AccessTools.Method(type, method, args, (Type[])null);
				if (methodInfo == null)
				{
					PingPlugin.Log.LogWarning((object)("PING: patch skipped, method not found: " + text));
					return false;
				}
				harmony.Patch((MethodBase)methodInfo, prefix, postfix, transpiler, (HarmonyMethod)null, (HarmonyMethod)null);
				return true;
			}
			catch (Exception ex)
			{
				PingPlugin.SafeError("PING: patch FAILED for " + text, ex);
				return false;
			}
		}
	}
	public static class PingTicker
	{
		private const double UnitsPerLightYear = 2400000.0;

		private const double MinimumCostJoules = 192000000.0;

		private const long SyncIntervalTicks = 60L;

		public static readonly Dictionary<long, PortalData> AllPortals = new Dictionary<long, PortalData>();

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

		private static int pendingPlanetId;

		private static bool pendingHasPos;

		private static Vector3 pendingPos;

		private static bool recipeChecked;

		private static readonly HashSet<int> decommissioned = new HashSet<int>();

		private static bool batchLogged;

		public static long Key(int planetId, int entityId)
		{
			return ((long)planetId << 32) | (uint)entityId;
		}

		public static void Reset()
		{
			AllPortals.Clear();
			LastSyncTick.Clear();
			decommissioned.Clear();
			batchLogged = false;
			pendingPlanetId = 0;
			recipeChecked = false;
		}

		public static void Install(Harmony harmony)
		{
			PatchHelper.TryPatch(harmony, typeof(FactorySystem), "GameTick", new Type[2]
			{
				typeof(long),
				typeof(bool)
			}, null, PatchHelper.Method(typeof(PingTicker), "FactoryTickPostfix"));
		}

		public static double DistanceLy(PlanetData a, PlanetData b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			VectorLF3 val = a.uPosition - b.uPosition;
			return ((VectorLF3)(ref val)).magnitude / 2400000.0;
		}

		public static long CostJoules(double distLy)
		{
			return (long)Math.Ceiling(Math.Max(192000000.0, distLy * PingPlugin.EnergyPerLightYearJoules));
		}

		public static PortalData GetPortal(int planetId, int entityId)
		{
			if (!AllPortals.TryGetValue(Key(planetId, entityId), out var value))
			{
				return null;
			}
			return value;
		}

		public static HashSet<int> PlanetsWithPortals()
		{
			HashSet<int> hashSet = new HashSet<int>();
			foreach (PortalData value in AllPortals.Values)
			{
				hashSet.Add(value.planetId);
			}
			return hashSet;
		}

		public static PortalData FindPortalForEntity(int entityId)
		{
			Player mainPlayer = GameMain.mainPlayer;
			PlanetFactory val = ((mainPlayer != null) ? mainPlayer.factory : null);
			if (val == null || val.entityPool == null)
			{
				return null;
			}
			if (entityId <= 0 || entityId >= val.entityPool.Length)
			{
				return null;
			}
			if (val.entityPool[entityId].id != entityId || val.entityPool[entityId].protoId != 3500)
			{
				return null;
			}
			PortalData portal = GetPortal(val.planetId, entityId);
			if (portal == null)
			{
				SyncPortals(val);
				portal = GetPortal(val.planetId, entityId);
			}
			return portal;
		}

		public static bool TryGetStored(PortalData portal, out long stored)
		{
			stored = 0L;
			if (!TryGetAccumulator(portal, out var power, out var accId))
			{
				return false;
			}
			stored = power.accPool[accId].curEnergy;
			return true;
		}

		public static double CooldownSecondsLeft(PortalData portal)
		{
			long num = portal.cooldownUntilTick - GameMain.gameTick;
			if (num <= 0)
			{
				return 0.0;
			}
			return (double)num / 60.0;
		}

		private static PortalData FindPartner(int planetId)
		{
			PortalData portalData = null;
			foreach (PortalData value in AllPortals.Values)
			{
				if (value.planetId == planetId && (portalData == null || (value.posKnown && !portalData.posKnown) || (value.posKnown == portalData.posKnown && value.entityId < portalData.entityId)))
				{
					portalData = value;
				}
			}
			return portalData;
		}

		public static PortalData FindNearestPortalInRange()
		{
			//IL_0088: 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)
			Player mainPlayer = GameMain.mainPlayer;
			PlanetData localPlanet = GameMain.localPlanet;
			if (mainPlayer == null || localPlanet == null || localPlanet.factory == null)
			{
				return null;
			}
			EntityData[] entityPool = localPlanet.factory.entityPool;
			if (entityPool == null)
			{
				return null;
			}
			PortalData result = null;
			float num = PingPlugin.GateRange;
			foreach (PortalData value in AllPortals.Values)
			{
				if (value.planetId != localPlanet.id)
				{
					continue;
				}
				int entityId = value.entityId;
				if (entityId > 0 && entityId < entityPool.Length && entityPool[entityId].id == entityId)
				{
					float num2 = Vector3.Distance(mainPlayer.position, entityPool[entityId].pos);
					if (num2 <= num)
					{
						num = num2;
						result = value;
					}
				}
			}
			return result;
		}

		internal static void SyncPortals(PlanetFactory factory)
		{
			//IL_00eb: 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)
			EntityData[] entityPool = factory.entityPool;
			PowerSystem powerSystem = factory.powerSystem;
			int planetId = factory.planetId;
			HashSet<long> hashSet = new HashSet<long>();
			if (PingPlugin.RemoveAllPortals != null && PingPlugin.RemoveAllPortals.Value && decommissioned.Add(planetId))
			{
				DecommissionPortals(factory);
			}
			for (int i = 1; i < factory.entityCursor; i++)
			{
				if (entityPool[i].id == i && entityPool[i].protoId == 3500)
				{
					long num = Key(planetId, i);
					hashSet.Add(num);
					if (!AllPortals.TryGetValue(num, out var value))
					{
						value = new PortalData
						{
							planetId = planetId,
							entityId = i
						};
						AllPortals[num] = value;
						PingPlugin.Log.LogInfo((object)$"PING portal registered: planet {planetId}, entityId {i}.");
						LogRenderBatch();
					}
					value.localPos = entityPool[i].pos;
					value.posKnown = true;
					ConfigureAccumulator(powerSystem, entityPool[i].powerAccId);
				}
			}
			List<long> list = new List<long>();
			foreach (KeyValuePair<long, PortalData> allPortal in AllPortals)
			{
				if (allPortal.Value.planetId == planetId && !hashSet.Contains(allPortal.Key))
				{
					list.Add(allPortal.Key);
				}
			}
			foreach (long item in list)
			{
				AllPortals.Remove(item);
			}
		}

		private static void LogRenderBatch()
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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)
			if (batchLogged)
			{
				return;
			}
			batchLogged = true;
			try
			{
				PrefabDesc val = PingPlugin.PingItem?.prefabDesc;
				ObjectRenderer val2 = ((val == null || GameMain.gpuiManager == null) ? null : GameMain.gpuiManager.GetObjectRenderer(val.modelIndex));
				if (val2 == null || val2.lodBatches == null || val2.lodBatches.Length == 0 || val2.lodBatches[0] == null)
				{
					PingPlugin.Log.LogInfo((object)"PING render batch: not available yet.");
					return;
				}
				PingPlugin.LogIcon("item", PingPlugin.PingItem, PingPlugin.PingItem.IconPath);
				if (PingPlugin.PingRecipe != null)
				{
					PingPlugin.LogIcon("recipe", PingPlugin.PingRecipe, PingPlugin.PingRecipe.IconPath);
				}
				if (val.lodMeshes != null && val.lodMeshes.Length != 0 && (Object)(object)val.lodMeshes[0] != (Object)null)
				{
					Mesh val3 = val.lodMeshes[0];
					ManualLogSource log = PingPlugin.Log;
					object[] obj = new object[4] { val3.vertexCount, null, null, null };
					Bounds bounds = val3.bounds;
					obj[1] = ((Bounds)(ref bounds)).center;
					bounds = val3.bounds;
					obj[2] = ((Bounds)(ref bounds)).size;
					obj[3] = val.cullingHeight;
					log.LogInfo((object)string.Format("PING lod mesh: vertices={0}, bounds center={1}, size={2}, cullingHeight={3}.", obj));
				}
				BatchRenderer val4 = val2.lodBatches[0];
				int num = (((Object)(object)val4.mesh != (Object)null) ? val4.mesh.subMeshCount : (-1));
				int num2 = ((val4.materials != null) ? val4.materials.Length : (-1));
				PingPlugin.Log.LogInfo((object)($"PING render batch: lodBatches={val2.lodBatches.Length}, subMeshes={num}, materials={num2}, " + $"castShadow={val.castShadow}, recvShadow={val.recvShadow}, lodMeshSubMeshes={((val.lodMeshes != null && val.lodMeshes.Length != 0 && (Object)(object)val.lodMeshes[0] != (Object)null) ? val.lodMeshes[0].subMeshCount : (-1))}."));
			}
			catch (Exception ex)
			{
				PingPlugin.SafeError("LogRenderBatch failed", ex);
			}
		}

		private static void DecommissionPortals(PlanetFactory factory)
		{
			Player mainPlayer = GameMain.mainPlayer;
			if (mainPlayer == null)
			{
				return;
			}
			List<int> list = new List<int>();
			EntityData[] entityPool = factory.entityPool;
			for (int i = 1; i < factory.entityCursor; i++)
			{
				if (entityPool[i].id == i && entityPool[i].protoId == 3500)
				{
					list.Add(i);
				}
			}
			foreach (int item in list)
			{
				try
				{
					int num = 3500;
					factory.DismantleFinally(mainPlayer, item, ref num);
					mainPlayer.TryAddItemToPackage(3500, 1, 0, true, 0, false);
					PingPlugin.Log.LogInfo((object)$"PING: portal dismantled (planet {factory.planetId}, entity {item}) and returned to the inventory.");
				}
				catch (Exception ex)
				{
					PingPlugin.SafeError("decommissioning a portal failed", ex);
				}
			}
		}

		private static void ConfigureAccumulator(PowerSystem power, int accId)
		{
			if (power != null && power.accPool != null && accId > 0 && accId < power.accPool.Length && power.accPool[accId].id == accId)
			{
				long maxEnergyJoules = PingPlugin.MaxEnergyJoules;
				power.accPool[accId].maxEnergy = maxEnergyJoules;
				power.accPool[accId].inputEnergyPerTick = PingPlugin.ChargeJoulesPerTick;
				power.accPool[accId].outputEnergyPerTick = 0L;
				if (power.accPool[accId].curEnergy > maxEnergyJoules)
				{
					power.accPool[accId].curEnergy = maxEnergyJoules;
				}
			}
		}

		private static bool TryGetAccumulator(PortalData portal, out PowerSystem power, out int accId)
		{
			power = null;
			accId = 0;
			GameData data = GameMain.data;
			object obj;
			if (data == null)
			{
				obj = null;
			}
			else
			{
				GalaxyData galaxy = data.galaxy;
				obj = ((galaxy != null) ? galaxy.PlanetById(portal.planetId) : null);
			}
			PlanetFactory val = ((PlanetData)(obj?)).factory;
			if (val == null || val.entityPool == null)
			{
				return false;
			}
			if (portal.entityId <= 0 || portal.entityId >= val.entityPool.Length)
			{
				return false;
			}
			if (val.entityPool[portal.entityId].id != portal.entityId)
			{
				return false;
			}
			power = val.powerSystem;
			accId = val.entityPool[portal.entityId].powerAccId;
			if (power != null && power.accPool != null && accId > 0 && accId < power.accPool.Length)
			{
				return power.accPool[accId].id == accId;
			}
			return false;
		}

		public static string TryStartTeleport(PortalData origin, PlanetData target)
		{
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			Player mainPlayer = GameMain.mainPlayer;
			if (mainPlayer == null)
			{
				return "PING: no player.";
			}
			if (mainPlayer.warping || mainPlayer.fastTravelling)
			{
				return "PING: not available while travelling.";
			}
			GameData data = GameMain.data;
			object obj;
			if (data == null)
			{
				obj = null;
			}
			else
			{
				GalaxyData galaxy = data.galaxy;
				obj = ((galaxy != null) ? galaxy.PlanetById(origin.planetId) : null);
			}
			PlanetData val = (PlanetData)obj;
			if (val == null)
			{
				return "PING: portal is not ready.";
			}
			if (target.id == val.id)
			{
				return "PING: this is the planet you are on.";
			}
			double num = DistanceLy(val, target);
			double maxTravelDistanceLightYears = PingPlugin.MaxTravelDistanceLightYears;
			if (num > maxTravelDistanceLightYears)
			{
				return $"PING: destination is {num:F1} LY away (maximum {maxTravelDistanceLightYears:F0} LY).";
			}
			PortalData portalData = FindPartner(target.id);
			if (PingPlugin.RequirePaired && portalData == null)
			{
				return "PING: the destination planet has no PING portal.";
			}
			if (GameMain.gameTick < origin.cooldownUntilTick)
			{
				return "PING: portal is cooling down.";
			}
			if (!TryGetAccumulator(origin, out var power, out var accId))
			{
				return "PING: portal is not ready.";
			}
			long num2 = CostJoules(num);
			long curEnergy = power.accPool[accId].curEnergy;
			if (curEnergy < num2)
			{
				return $"PING: not enough energy ({curEnergy / 1000000} / {num2 / 1000000} MJ).";
			}
			power.accPool[accId].curEnergy -= num2;
			origin.cooldownUntilTick = GameMain.gameTick + PingPlugin.CooldownTicks;
			pendingPlanetId = target.id;
			pendingHasPos = portalData?.posKnown ?? false;
			pendingPos = portalData?.localPos ?? Vector3.zero;
			try
			{
				mainPlayer.controller.actionSail.StartFastTravelToPlanet(target);
			}
			catch (Exception ex)
			{
				power.accPool[accId].curEnergy += num2;
				origin.cooldownUntilTick = 0L;
				pendingPlanetId = 0;
				PingPlugin.SafeError("PING teleport failed", ex);
				return "PING: teleport failed, see log.";
			}
			PingPlugin.Log.LogInfo((object)$"PING teleport to {target.name}: distance={num:F2} LY, cost={(double)num2 / 1000000.0:F0} MJ, left={(double)power.accPool[accId].curEnergy / 1000000.0:F0} MJ");
			return null;
		}

		public static void OnArrived(PlanetData planet)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (planet == null || pendingPlanetId != planet.id)
			{
				return;
			}
			pendingPlanetId = 0;
			if (!pendingHasPos)
			{
				return;
			}
			Player mainPlayer = GameMain.mainPlayer;
			if (mainPlayer != null)
			{
				Vector3 normalized = ((Vector3)(ref pendingPos)).normalized;
				Vector3 val = Vector3.Cross(normalized, Vector3.up);
				if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
				{
					val = Vector3.Cross(normalized, Vector3.right);
				}
				Vector3 val2 = pendingPos + normalized * 1.5f + ((Vector3)(ref val)).normalized * 3f;
				Quaternion val3 = Maths.SphericalRotation(val2, 0f);
				mainPlayer.transform.localPosition = val2;
				mainPlayer.transform.localRotation = val3;
				mainPlayer.uPosition = planet.uPosition + VectorLF3.op_Implicit(planet.runtimeRotation * val2);
				mainPlayer.uRotation = planet.runtimeRotation * val3;
				mainPlayer.uVelocity = VectorLF3.zero;
			}
		}

		private static void EnsureRecipeUnlocked()
		{
			if (!recipeChecked && PingPlugin.PingRecipe != null && GameMain.history != null)
			{
				recipeChecked = true;
				GameHistoryData history = GameMain.history;
				int iD = ((Proto)PingPlugin.PingRecipe).ID;
				if (history.TechUnlocked(1512) && !history.RecipeUnlocked(iD))
				{
					history.UnlockRecipe(iD);
					PingPlugin.Log.LogInfo((object)"PING: recipe unlocked retroactively (tech already researched in this save).");
				}
			}
		}

		public static void FactoryTickPostfix(FactorySystem __instance, long time, bool isActive)
		{
			try
			{
				PlanetFactory val = __instance?.factory;
				if (val != null && val.entityPool != null && val.planetId > 0 && GameMain.data != null)
				{
					EnsureRecipeUnlocked();
					int planetId = val.planetId;
					if (!LastSyncTick.TryGetValue(planetId, out var value) || time < value || time - value >= 60)
					{
						SyncPortals(val);
						LastSyncTick[planetId] = time;
					}
				}
			}
			catch (Exception ex)
			{
				PingPlugin.SafeError("FactoryTickPostfix failed", ex);
			}
		}
	}
}
namespace PingMod.UI
{
	public class PingTargetWindow : MonoBehaviour
	{
		private class Entry
		{
			public PlanetData planet;

			public double distLy;

			public bool hasPortal;

			public bool sameStar;

			public long cost;

			public string label;

			public string searchKey;
		}

		private class RowView
		{
			public GameObject root;

			public Image background;

			public PingHoverTint tint;

			public Text nameText;

			public Text distText;

			public Text costText;

			public Image portalIcon;

			public Entry entry;
		}

		private const float WindowWidth = 560f;

		private const float WindowHeight = 504f;

		private const float ListTop = 114f;

		private const float ListWidth = 528f;

		private const float RowHeight = 26f;

		private const int VisibleRows = 12;

		private const int ScrollStep = 3;

		private static readonly Color PanelColor = new Color(0f, 0.086f, 0.108f, 0.8f);

		private static readonly Color GlassColor = new Color(0.38f, 0.847f, 1f, 0.05f);

		private static readonly Color AccentLineColor = new Color(0.655f, 0.914f, 1f, 0.9f);

		private const float FrameCut = 14f;

		private static readonly Color StorageColor = new Color(0.055f, 0.102f, 0.141f, 0.54f);

		private static readonly Color TitleColor = new Color(0.588f, 0.588f, 0.588f, 1f);

		private static readonly Color CountColor = new Color(0.38f, 0.847f, 1f, 0.78f);

		private static readonly Color FrameColor = new Color(0.655f, 0.914f, 1f, 0.55f);

		private static readonly Color AccentColor = new Color(0.99f, 0.59f, 0.37f, 1f);

		private static readonly Color ButtonOff = new Color(0.38f, 0.847f, 1f, 0.13f);

		private static readonly Color ButtonOn = new Color(0.99f, 0.59f, 0.37f, 0.85f);

		private static readonly Color TextNormal = new Color(1f, 1f, 1f, 0.9f);

		private static readonly Color TextDim = new Color(1f, 1f, 1f, 0.3f);

		private static readonly Color TextBad = new Color(1f, 0.35f, 0.3f, 0.95f);

		private static readonly Color RowEven = new Color(0.655f, 0.914f, 1f, 0.07f);

		private static readonly Color RowOdd = new Color(0.655f, 0.914f, 1f, 0.025f);

		private static PingTargetWindow instance;

		private static Vector2 savedPosition;

		private static bool hasSavedPosition;

		private Font font;

		private RectTransform panelRect;

		private Image panelImage;

		private PingFrameGraphic panelFill;

		private Text energyText;

		private RectTransform energyFill;

		private Text statusText;

		private Text countText;

		private Button teleportButton;

		private PlanetData selected;

		private InputField searchField;

		private Image portalFilterImage;

		private Image rangeFilterImage;

		private Image starFilterImage;

		private RectTransform scrollHandle;

		private readonly List<RowView> rows = new List<RowView>();

		private readonly List<Entry> entries = new List<Entry>();

		private readonly List<Entry> view = new List<Entry>();

		private PortalData origin;

		private int originStarId;

		private int scroll;

		private bool filterPortal = true;

		private bool filterRange = true;

		private bool filterStar;

		private bool pointerInside;

		private Sprite portalSprite;

		public static bool IsOpen
		{
			get
			{
				if ((Object)(object)instance != (Object)null)
				{
					return ((Component)instance).gameObject.activeSelf;
				}
				return false;
			}
		}

		public static void Open(PortalData portal)
		{
			try
			{
				if (portal != null)
				{
					if ((Object)(object)instance == (Object)null)
					{
						instance = Create();
					}
					if (!((Object)(object)instance == (Object)null))
					{
						instance.Show(portal);
					}
				}
			}
			catch (Exception ex)
			{
				PingPlugin.SafeError("PING target window: open failed", ex);
			}
		}

		public static void Close(bool clearInspect = false)
		{
			try
			{
				if (!((Object)(object)instance == (Object)null) && ((Component)instance).gameObject.activeSelf)
				{
					instance.Hide(clearInspect);
				}
			}
			catch (Exception ex)
			{
				PingPlugin.SafeError("PING target window: close failed", ex);
			}
		}

		public static void Tick()
		{
			try
			{
				if (!((Object)(object)instance == (Object)null) && ((Component)instance).gameObject.activeSelf && !GameMain.isPaused && GameMain.isRunning)
				{
					instance.DoTick();
				}
			}
			catch (Exception ex)
			{
				PingPlugin.SafeError("PING target window: tick failed", ex);
			}
		}

		private static PingTargetWindow Create()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			UIGame val = (((Object)(object)UIRoot.instance != (Object)null) ? UIRoot.instance.uiGame : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform val2 = (((Object)(object)val.inserterWindow != (Object)null) ? ((Component)val.inserterWindow).transform.parent : ((Component)UIRoot.instance.overlayCanvas).transform);
			GameObject val3 = new GameObject("PingTargetWindow", new Type[1] { typeof(RectTransform) });
			RectTransform component = val3.GetComponent<RectTransform>();
			((Transform)component).SetParent(val2, false);
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0.5f, 0.5f);
			component.anchorMax = val4;
			component.anchorMin = val4;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(560f, 504f);
			component.anchoredPosition = Vector2.zero;
			((Transform)component).localScale = Vector3.one;
			PingTargetWindow pingTargetWindow = val3.AddComponent<PingTargetWindow>();
			pingTargetWindow.panelRect = component;
			pingTargetWindow.Build(val);
			val3.SetActive(false);
			return pingTargetWindow;
		}

		private void Build(UIGame uiGame)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Expected O, but got Unknown
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Expected O, but got Unknown
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Expected O, but got Unknown
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0605: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Expected O, but got Unknown
			font = null;
			if ((Object)(object)uiGame.assemblerWindow != (Object)null && (Object)(object)uiGame.assemblerWindow.stateText != (Object)null)
			{
				font = uiGame.assemblerWindow.stateText.font;
			}
			if ((Object)(object)font == (Object)null)
			{
				font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			portalSprite = ((PingPlugin.PingItem != null) ? PingPlugin.PingItem.iconSprite : null);
			panelImage = AddImage((Component)(object)panelRect, Color.clear, raycast: true);
			panelFill = AddFrame(NewRect("fill", (Transform)(object)panelRect, 0f, 0f, 560f, 504f), PingFrameGraphic.Kind.Fill, PanelColor, 0f);
			AddFrame(NewRect("glass", (Transform)(object)panelRect, 0f, 0f, 560f, 504f), PingFrameGraphic.Kind.Fill, GlassColor, 0f);
			AddFrame(NewRect("border", (Transform)(object)panelRect, 0f, 0f, 560f, 504f), PingFrameGraphic.Kind.Outline, FrameColor, 1.5f);
			AddFrame(NewRect("accents", (Transform)(object)panelRect, 0f, 0f, 560f, 504f), PingFrameGraphic.Kind.Accents, AccentLineColor, 3f);
			AddImage((Component)(object)NewRect("title-accent", (Transform)(object)panelRect, 16f, 40f, 56f, 2f), AccentColor, raycast: false);
			PingDragHandle pingDragHandle = ((Component)panelRect).gameObject.AddComponent<PingDragHandle>();
			pingDragHandle.target = panelRect;
			pingDragHandle.onMoved = delegate
			{
				//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)
				savedPosition = panelRect.anchoredPosition;
				hasSavedPosition = true;
			};
			AddText((Component)(object)NewRect("title", (Transform)(object)panelRect, 16f, 10f, 440f, 28f), "PING Portal - Select Destination", 18, TitleColor, (TextAnchor)3).fontStyle = (FontStyle)1;
			((UnityEvent)NewButton("close", (Transform)(object)panelRect, 516f, 8f, 28f, 28f, "X", 16, ButtonOff).onClick).AddListener((UnityAction)delegate
			{
				Hide(clearInspect: true);
			});
			RectTransform val = NewRect("energy-back", (Transform)(object)panelRect, 16f, 46f, 528f, 20f);
			AddImage((Component)(object)val, new Color(0f, 0f, 0f, 0.55f), raycast: false);
			energyFill = NewRect("energy-fill", (Transform)(object)val, 0f, 0f, 0f, 20f);
			AddImage((Component)(object)energyFill, new Color(0.99f, 0.59f, 0.37f, 0.65f), raycast: false);
			energyText = AddText((Component)(object)NewRect("energy-text", (Transform)(object)val, 0f, 0f, 528f, 20f), "", 14, TextNormal, (TextAnchor)4);
			Button val2 = NewButton("filter-portal", (Transform)(object)panelRect, 16f, 74f, 32f, 32f, ((Object)(object)portalSprite == (Object)null) ? "P" : "", 16, ButtonOff);
			portalFilterImage = ((Component)val2).GetComponent<Image>();
			if ((Object)(object)portalSprite != (Object)null)
			{
				AddImage((Component)(object)NewRect("icon", ((Component)val2).transform, 2f, 2f, 28f, 28f), Color.white, raycast: false).sprite = portalSprite;
			}
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				filterPortal = !filterPortal;
				FiltersChanged();
			});
			Button val3 = NewButton("filter-range", (Transform)(object)panelRect, 56f, 74f, 92f, 32f, "", 14, ButtonOff);
			rangeFilterImage = ((Component)val3).GetComponent<Image>();
			SetButtonLabel(val3, "<= " + PingPlugin.MaxTravelDistanceLightYears.ToString("F0") + " ly", 14);
			((UnityEvent)val3.onClick).AddListener((UnityAction)delegate
			{
				filterRange = !filterRange;
				FiltersChanged();
			});
			Button val4 = NewButton("filter-star", (Transform)(object)panelRect, 156f, 74f, 100f, 32f, "This star", 14, ButtonOff);
			starFilterImage = ((Component)val4).GetComponent<Image>();
			((UnityEvent)val4.onClick).AddListener((UnityAction)delegate
			{
				filterStar = !filterStar;
				FiltersChanged();
			});
			BuildSearchField();
			RectTransform val5 = NewRect("list", (Transform)(object)panelRect, 16f, 114f, 528f, 312f);
			AddImage((Component)(object)val5, StorageColor, raycast: true);
			for (int num = 0; num < 12; num++)
			{
				rows.Add(BuildRow(val5, num));
			}
			scrollHandle = NewRect("scroll-handle", (Transform)(object)val5, 523f, 0f, 4f, 40f);
			AddImage((Component)(object)scrollHandle, new Color(1f, 1f, 1f, 0.35f), raycast: false);
			statusText = AddText((Component)(object)NewRect("status", (Transform)(object)panelRect, 16f, 434f, 400f, 24f), "", 14, TextNormal, (TextAnchor)3);
			countText = AddText((Component)(object)NewRect("count", (Transform)(object)panelRect, 404f, 434f, 140f, 24f), "", 14, CountColor, (TextAnchor)5);
			teleportButton = NewButton("teleport", (Transform)(object)panelRect, 404f, 466f, 140f, 34f, "Teleport", 16, ButtonOff);
			((UnityEvent)teleportButton.onClick).AddListener((UnityAction)delegate
			{
				OnTeleportClick();
			});
		}

		private void BuildSearchField()
		{
			//IL_0026: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRect("search", (Transform)(object)panelRect, 264f, 74f, 280f, 32f);
			Image targetGraphic = AddImage((Component)(object)val, StorageColor, raycast: true);
			Text val2 = AddText((Component)(object)NewRect("text", (Transform)(object)val, 8f, 0f, 264f, 32f), "", 16, TextNormal, (TextAnchor)3);
			val2.supportRichText = false;
			((Graphic)val2).raycastTarget = false;
			Text val3 = AddText((Component)(object)NewRect("placeholder", (Transform)(object)val, 8f, 0f, 264f, 32f), "Search planet or star...", 16, TextDim, (TextAnchor)3);
			val3.fontStyle = (FontStyle)2;
			searchField = ((Component)val).gameObject.AddComponent<InputField>();
			((Selectable)searchField).targetGraphic = (Graphic)(object)targetGraphic;
			searchField.textComponent = val2;
			searchField.placeholder = (Graphic)(object)val3;
			searchField.lineType = (LineType)0;
			((UnityEvent<string>)(object)searchField.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				FiltersChanged();
			});
		}

		private RowView BuildRow(RectTransform parent, int index)
		{
			//IL_005c: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			RowView rowView = new RowView();
			RectTransform val = NewRect("row-" + index, (Transform)(object)parent, 0f, (float)index * 26f, 520f, 24f);
			rowView.root = ((Component)val).gameObject;
			rowView.background = AddImage((Component)(object)val, (index % 2 == 0) ? RowEven : RowOdd, raycast: true);
			Button obj = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)rowView.background;
			((Selectable)obj).transition = (Transition)0;
			PingHoverTint pingHoverTint = ((Component)val).gameObject.AddComponent<PingHoverTint>();
			pingHoverTint.image = rowView.background;
			pingHoverTint.normal = ((index % 2 == 0) ? RowEven : RowOdd);
			rowView.tint = pingHoverTint;
			int rowIndex = index;
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				OnRowClick(rowIndex);
			});
			PingRowHover pingRowHover = ((Component)val).gameObject.AddComponent<PingRowHover>();
			pingRowHover.onEnter = delegate
			{
				OnRowHover(rowIndex);
			};
			pingRowHover.onExit = delegate
			{
				ShowStatus("", warning: false);
			};
			rowView.portalIcon = AddImage((Component)(object)NewRect("portal", (Transform)(object)val, 6f, 3f, 20f, 20f), Color.white, raycast: false);
			rowView.portalIcon.sprite = portalSprite;
			rowView.nameText = AddText((Component)(object)NewRect("name", (Transform)(object)val, 34f, 0f, 270f, 24f), "", 16, TextNormal, (TextAnchor)3);
			rowView.distText = AddText((Component)(object)NewRect("dist", (Transform)(object)val, 306f, 0f, 100f, 24f), "", 14, TextNormal, (TextAnchor)5);
			rowView.costText = AddText((Component)(object)NewRect("cost", (Transform)(object)val, 412f, 0f, 104f, 24f), "", 14, TextNormal, (TextAnchor)5);
			return rowView;
		}

		private static RectTransform NewRect(string name, Transform parent, float x, float y, float w, float h)
		{
			//IL_0014: 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_003f: 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_005e: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			component.anchorMax = val;
			component.anchorMin = val;
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(x, 0f - y);
			component.sizeDelta = new Vector2(w, h);
			((Transform)component).localScale = Vector3.one;
			return component;
		}

		private static PingFrameGraphic AddFrame(RectTransform rect, PingFrameGraphic.Kind kind, Color color, float thickness)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			PingFrameGraphic pingFrameGraphic = ((Component)rect).gameObject.AddComponent<PingFrameGraphic>();
			pingFrameGraphic.kind = kind;
			pingFrameGraphic.thickness = thickness;
			pingFrameGraphic.cut = 14f;
			((Graphic)pingFrameGraphic).color = color;
			((Graphic)pingFrameGraphic).raycastTarget = false;
			return pingFrameGraphic;
		}

		private static Image AddImage(Component target, Color color, bool raycast)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Image obj = target.gameObject.AddComponent<Image>();
			((Graphic)obj).color = color;
			((Graphic)obj).raycastTarget = raycast;
			return obj;
		}

		private Text AddText(Component target, string content, int size, Color color, TextAnchor anchor)
		{
			//IL_001f: 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)
			Text obj = target.gameObject.AddComponent<Text>();
			obj.font = font;
			obj.fontSize = size;
			((Graphic)obj).color = color;
			obj.alignment = anchor;
			obj.text = content;
			obj.horizontalOverflow = (HorizontalWrapMode)1;
			obj.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private Button NewButton(string name, Transform parent, float x, float y, float w, float h, string label, int size, Color color)
		{
			//IL_0010: 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_0046: 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)
			RectTransform val = NewRect(name, parent, x, y, w, h);
			Image val2 = AddImage((Component)(object)val, color, raycast: true);
			Button obj = ((Component)val).gameObject.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val2;
			((Selectable)obj).transition = (Transition)0;
			PingHoverTint pingHoverTint = ((Component)val).gameObject.AddComponent<PingHoverTint>();
			pingHoverTint.image = val2;
			pingHoverTint.normal = color;
			RectTransform target = NewRect("label", (Transform)(object)val, 0f, 0f, w, h);
			AddText((Component)(object)target, label, size, TextNormal, (TextAnchor)4);
			return obj;
		}

		private static void SetButtonLabel(Button button, string label, int size)
		{
			Text componentInChildren = ((Component)button).GetComponentInChildren<Text>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = label;
			}
		}

		private void Show(PortalData portal)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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)
			origin = portal;
			selected = null;
			PlanetData val = ((GameMain.galaxy != null) ? GameMain.galaxy.PlanetById(portal.planetId) : null);
			originStarId = ((val != null && val.star != null) ? val.star.id : 0);
			filterPortal = PingPlugin.RequirePaired;
			filterRange = true;
			filterStar = false;
			scroll = 0;
			searchField.text = "";
			BuildEntries();
			ApplyFilters();
			RefreshFilterButtons();
			RefreshHeader();
			ShowStatus("", warning: false);
			Color panelColor = PanelColor;
			panelColor.a = PingPlugin.WindowAlpha;
			((Graphic)panelFill).color = panelColor;
			panelRect.anchoredPosition = (hasSavedPosition ? savedPosition : Vector2.zero);
			((Component)this).gameObject.SetActive(true);
			((Component)this).transform.SetAsLastSibling();
		}

		private void Hide(bool clearInspect)
		{
			((Component)this).gameObject.SetActive(false);
			pointerInside = false;
			if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)searchField != (Object)null && searchField.isFocused)
			{
				EventSystem.current.SetSelectedGameObject((GameObject)null);
			}
			if (clearInspect)
			{
				Player mainPlayer = GameMain.mainPlayer;
				if (mainPlayer != null && (Object)(object)mainPlayer.controller != (Object)null && mainPlayer.controller.actionInspect != null)
				{
					mainPlayer.controller.actionInspect.InspectNothing();
				}
			}
		}

		private void BuildEntries()
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Invalid comparison between Unknown and I4
			entries.Clear();
			GalaxyData galaxy = GameMain.galaxy;
			if (galaxy == null || origin == null)
			{
				return;
			}
			PlanetData val = galaxy.PlanetById(origin.planetId);
			if (val == null)
			{
				return;
			}
			HashSet<int> hashSet = PingTicker.PlanetsWithPortals();
			for (int i = 0; i < galaxy.starCount; i++)
			{
				StarData val2 = galaxy.stars[i];
				if (val2 == null || val2.planets == null)
				{
					continue;
				}
				for (int j = 0; j < val2.planetCount; j++)
				{
					PlanetData val3 = val2.planets[j];
					if (val3 != null && val3.id != origin.planetId)
					{
						Entry entry = new Entry();
						entry.planet = val3;
						entry.distLy = PingTicker.DistanceLy(val, val3);
						entry.hasPortal = hashSet.Contains(val3.id);
						entry.sameStar = val2.id == originStarId;
						entry.cost = PingTicker.CostJoules(entry.distLy);
						entry.label = (((int)val3.type == 5) ? "[GAS] " : "") + val3.displayName;
						entry.searchKey = (val3.displayName + " " + val2.displayName).ToLowerInvariant();
						entries.Add(entry);
					}
				}
			}
			entries.Sort(delegate(Entry a, Entry b)
			{
				int num = a.distLy.CompareTo(b.distLy);
				return (num == 0) ? a.planet.id.CompareTo(b.planet.id) : num;
			});
		}

		private void ApplyFilters()
		{
			string text = (((Object)(object)searchField != (Object)null) ? searchField.text.Trim().ToLowerInvariant() : "");
			double maxTravelDistanceLightYears = PingPlugin.MaxTravelDistanceLightYears;
			view.Clear();
			foreach (Entry entry in entries)
			{
				if ((!filterPortal || entry.hasPortal) && (!filterRange || !(entry.distLy > maxTravelDistanceLightYears)) && (!filterStar || entry.sameStar) && (text.Length <= 0 || entry.searchKey.IndexOf(text, StringComparison.Ordinal) >= 0))
				{
					view.Add(entry);
				}
			}
			ClampScroll();
			RefreshRows();
		}

		private static string Reason(Entry entry)
		{
			double maxTravelDistanceLightYears = PingPlugin.MaxTravelDistanceLightYears;
			if (entry.distLy > maxTravelDistanceLightYears)
			{
				return "Too far: " + entry.distLy.ToString("F1") + " ly (maximum " + maxTravelDistanceLightYears.ToString("F0") + " ly).";
			}
			if (PingPlugin.RequirePaired && !entry.hasPortal)
			{
				return "There is no PING portal on this planet.";
			}
			return null;
		}

		private void FiltersChanged()
		{
			scroll = 0;
			ShowStatus("", warning: false);
			RefreshFilterButtons();
			ApplyFilters();
		}

		private void RefreshFilterButtons()
		{
			SetToggleColor(portalFilterImage, filterPortal);
			SetToggleColor(rangeFilterImage, filterRange);
			SetToggleColor(starFilterImage, filterStar);
		}

		private static void SetToggleColor(Image image, bool on)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Color val = (on ? ButtonOn : ButtonOff);
			PingHoverTint component = ((Component)image).GetComponent<PingHoverTint>();
			if ((Object)(object)component != (Object)null)
			{
				component.normal = val;
			}
			((Graphic)image).color = val;
		}

		private void ClampScroll()
		{
			int num = Mathf.Max(0, view.Count - 12);
			scroll = Mathf.Clamp(scroll, 0, num);
		}

		private void RefreshRows()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_00b6: 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_00bd: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			long stored = 0L;
			if (origin != null)
			{
				PingTicker.TryGetStored(origin, out stored);
			}
			for (int i = 0; i < rows.Count; i++)
			{
				RowView rowView = rows[i];
				int num = scroll + i;
				if (num >= view.Count)
				{
					rowView.entry = null;
					((Graphic)rowView.background).color = ((i % 2 == 0) ? RowEven : RowOdd);
					rowView.root.SetActive(false);
					continue;
				}
				Entry entry = (rowView.entry = view[num]);
				rowView.root.SetActive(true);
				bool flag = Reason(entry) == null;
				Color color = (flag ? TextNormal : TextDim);
				Color val = ((i % 2 == 0) ? RowEven : RowOdd);
				if (entry.planet == selected)
				{
					((Color)(ref val))..ctor(AccentColor.r, AccentColor.g, AccentColor.b, 0.3f);
				}
				rowView.tint.normal = val;
				((Graphic)rowView.background).color = val;
				rowView.nameText.text = entry.label;
				((Graphic)rowView.nameText).color = color;
				rowView.distText.text = (entry.sameStar ? "same star" : (entry.distLy.ToString("F1") + " ly"));
				((Graphic)rowView.distText).color = color;
				rowView.costText.text = entry.cost / 1000000 + " MJ";
				((Graphic)rowView.costText).color = ((!flag) ? TextDim : ((stored < entry.cost) ? TextBad : TextNormal));
				((Behaviour)rowView.portalIcon).enabled = entry.hasPortal;
				((Graphic)rowView.portalIcon).color = (Color)(flag ? Color.white : new Color(1f, 1f, 1f, 0.35f));
			}
			RefreshScrollBar();
			RefreshTeleportButton();
			countText.text = ((view.Count == 0) ? "" : (scroll + 1 + "-" + Mathf.Min(view.Count, scroll + 12) + " of " + view.Count));
			if (view.Count == 0)
			{
				ShowStatus(filterPortal ? "No matching planet with a PING portal. Build a portal on the destination planet first." : "No matching planet.", warning: true);
			}
		}

		private void RefreshScrollBar()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			float num = 312f;
			bool flag = view.Count > 12;
			((Component)scrollHandle).gameObject.SetActive(flag);
			if (flag)
			{
				float num2 = Mathf.Max(24f, num * 12f / (float)view.Count);
				float num3 = num - num2;
				float num4 = (float)scroll / (float)(view.Count - 12);
				scrollHandle.sizeDelta = new Vector2(4f, num2);
				scrollHandle.anchoredPosition = new Vector2(523f, (0f - num3) * num4);
			}
		}

		private void RefreshHeader()
		{
			//IL_003e: 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)
			if (origin == null)
			{
				return;
			}
			long maxEnergyJoules = PingPlugin.MaxEnergyJoules;
			if (!PingTicker.TryGetStored(origin, out var stored))
			{
				energyText.text = "Portal not ready";
				energyFill.sizeDelta = new Vector2(0f, 20f);
				return;
			}
			float num = ((maxEnergyJoules > 0) ? Mathf.Clamp01((float)((double)stored / (double)maxEnergyJoules)) : 0f);
			energyFill.sizeDelta = new Vector2(528f * num, 20f);
			string text = ((double)stored / 1000000000.0).ToString("F2") + " / " + ((double)maxEnergyJoules / 1000000000.0).ToString("F1") + " GJ  (" + (num * 100f).ToString("F0") + "%)";
			double num2 = PingTicker.CooldownSecondsLeft(origin);
			if (num2 > 0.0)
			{
				text = text + "   cooldown " + num2.ToString("F0") + " s";
			}
			energyText.text = text;
		}

		private void RefreshTeleportButton()
		{
			//IL_0046: 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)
			if (!((Object)(object)teleportButton == (Object)null))
			{
				Entry entry = FindSelectedEntry();
				bool flag = entry != null && Reason(entry) == null;
				Text componentInChildren = ((Component)teleportButton).GetComponentInChildren<Text>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((Graphic)componentInChildren).color = (flag ? TextNormal : TextDim);
				}
			}
		}

		private Entry FindSelectedEntry()
		{
			if (selected == null)
			{
				return null;
			}
			for (int i = 0; i < view.Count; i++)
			{
				if (view[i].planet == selected)
				{
					return view[i];
				}
			}
			return null;
		}

		private void ShowStatus(string message, bool warning)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)statusText == (Object)null))
			{
				statusText.text = message;
				((Graphic)statusText).color = (warning ? AccentColor : TextNormal);
			}
		}

		private void OnRowHover(int rowIndex)
		{
			RowView rowView = rows[rowIndex];
			if (rowView.entry != null)
			{
				string text = Reason(rowView.entry);
				if (text != null)
				{
					ShowStatus(text, warning: true);
					return;
				}
				ShowStatus("Click to select (" + rowView.entry.cost / 1000000 + " MJ, " + rowView.entry.distLy.ToString("F1") + " ly).", warning: false);
			}
		}

		private void OnRowClick(int rowIndex)
		{
			RowView rowView = rows[rowIndex];
			if (rowView.entry != null && origin != null)
			{
				selected = rowView.entry.planet;
				string text = Reason(rowView.entry);
				if (text != null)
				{
					ShowStatus(text, warning: true);
				}
				RefreshRows();
			}
		}

		private void OnTeleportClick()
		{
			if (origin == null)
			{
				return;
			}
			Entry entry = FindSelectedEntry();
			if (entry == null)
			{
				ShowStatus("Select a destination first.", warning: true);
				return;
			}
			string text = Reason(entry);
			if (text != null)
			{
				ShowStatus(text, warning: true);
				return;
			}
			string text2 = PingTicker.TryStartTeleport(origin, entry.planet);
			if (text2 != null)
			{
				ShowStatus(text2, warning: true);
			}
			else
			{
				Hide(clearInspect: true);
			}
		}

		private void DoTick()
		{
			//IL_007e: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (origin == null || !PortalStillExists())
			{
				Hide(clearInspect: false);
				return;
			}
			if (VFInput.escape)
			{
				if (searchField.isFocused)
				{
					VFInput.UseEscape();
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
				else if (!VFInput.inputing)
				{
					VFInput.UseEscape();
					Hide(clearInspect: true);
					return;
				}
			}
			Camera val = (((Object)(object)UIRoot.instance.overlayCanvas != (Object)null) ? UIRoot.instance.overlayCanvas.worldCamera : null);
			pointerInside = RectTransformUtility.RectangleContainsScreenPoint(panelRect, Vector2.op_Implicit(Input.mousePosition), val);
			if (pointerInside)
			{
				VFInput.inScrollView = true;
				float y = Input.mouseScrollDelta.y;
				if (Mathf.Abs(y) > 0.01f)
				{
					scroll -= ((y > 0f) ? 1 : (-1)) * 3;
					ClampScroll();
					RefreshRows();
				}
			}
			int frameCount = Time.frameCount;
			if (frameCount % 15 == 0)
			{
				RefreshHeader();
			}
			if (frameCount % 30 == 0)
			{
				RefreshRows();
			}
		}

		private bool PortalStillExists()
		{
			PortalData portal = PingTicker.GetPortal(origin.planetId, origin.entityId);
			if (portal != null)
			{
				return portal == origin;
			}
			return false;
		}

		private void FixedUpdate()
		{
			if (pointerInside)
			{
				VFInput.inScrollView = true;
			}
		}
	}
	public class PingDragHandle : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		public RectTransform target;

		public Action onMoved;

		public void OnBeginDrag(PointerEventData eventData)
		{
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Canvas componentInParent = ((Component)target).GetComponentInParent<Canvas>();
				float num = (((Object)(object)componentInParent != (Object)null && componentInParent.scaleFactor > 0f) ? componentInParent.scaleFactor : 1f);
				Vector2 val = target.anchoredPosition + eventData.delta / num;
				Transform parent = ((Transform)target).parent;
				RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if ((Object)(object)val2 != (Object)null)
				{
					float num2 = target.sizeDelta.x * 0.5f;
					float num3 = target.sizeDelta.y * 0.5f;
					Rect rect = val2.rect;
					float num4 = ((Rect)(ref rect)).width * 0.5f;
					rect = val2.rect;
					float num5 = ((Rect)(ref rect)).height * 0.5f;
					val.x = Mathf.Clamp(val.x, 0f - num4 - num2 + 120f, num4 + num2 - 120f);
					val.y = Mathf.Clamp(val.y, 0f - num5 - num3 + 60f, num5 - num3);
				}
				target.anchoredPosition = val;
			}
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			if (onMoved != null)
			{
				onMoved();
			}
		}
	}
	public class PingHoverTint : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public Image image;

		public Color normal;

		public void OnPointerEnter(PointerEventData eventData)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)image == (Object)null))
			{
				((Graphic)image).color = new Color(Mathf.Min(1f, normal.r + 0.18f), Mathf.Min(1f, normal.g + 0.18f), Mathf.Min(1f, normal.b + 0.18f), Mathf.Min(1f, normal.a + 0.18f));
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)image != (Object)null)
			{
				((Graphic)image).color = normal;
			}
		}
	}
	public class PingRowHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public Action onEnter;

		public Action onExit;

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (onEnter != null)
			{
				onEnter();
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			if (onExit != null)
			{
				onExit();
			}
		}
	}
	public class PingFrameGraphic : MaskableGraphic
	{
		public enum Kind
		{
			Fill,
			Outline,
			Accents
		}

		public Kind kind;

		public float thickness = 1f;

		public float cut = 14f;

		protected override void OnPopulateMesh(VertexHelper vh)
		{
			//IL_0007: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0080: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: 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_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_019f: Unknown result type (might be due to invalid IL or missing references)
			vh.Clear();
			Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect();
			float num = Mathf.Min(cut, Mathf.Min(((Rect)(ref pixelAdjustedRect)).width, ((Rect)(ref pixelAdjustedRect)).height) * 0.4f);
			Vector2[] array = (Vector2[])(object)new Vector2[6]
			{
				new Vector2(((Rect)(ref pixelAdjustedRect)).xMin + num, ((Rect)(ref pixelAdjustedRect)).yMax),
				new Vector2(((Rect)(ref pixelAdjustedRect)).xMax, ((Rect)(ref pixelAdjustedRect)).yMax),
				new Vector2(((Rect)(ref pixelAdjustedRect)).xMax, ((Rect)(ref pixelAdjustedRect)).yMin + num),
				new Vector2(((Rect)(ref pixelAdjustedRect)).xMax - num, ((Rect)(ref pixelAdjustedRect)).yMin),
				new Vector2(((Rect)(ref pixelAdjustedRect)).xMin, ((Rect)(ref pixelAdjustedRect)).yMin),
				new Vector2(((Rect)(ref pixelAdjustedRect)).xMin, ((Rect)(ref pixelAdjustedRect)).yMax - num)
			};
			Vector2 center = ((Rect)(ref pixelAdjustedRect)).center;
			if (kind == Kind.Fill)
			{
				vh.AddVert(Vector2.op_Implicit(center), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
				for (int i = 0; i < array.Length; i++)
				{
					vh.AddVert(Vector2.op_Implicit(array[i]), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
				}
				for (int j = 0; j < array.Length; j++)
				{
					vh.AddTriangle(0, 1 + j, 1 + (j + 1) % array.Length);
				}
			}
			else if (kind == Kind.Outline)
			{
				for (int k = 0; k < array.Length; k++)
				{
					Edge(vh, array[k], array[(k + 1) % array.Length], thickness, center);
				}
			}
			else
			{
				Edge(vh, array[5], array[0], thickness, center);
				Edge(vh, array[2], array[3], thickness, center);
				Edge(vh, array[1] + new Vector2(-22f, 0f), array[1], thickness, center);
				Edge(vh, array[1], array[1] + new Vector2(0f, -22f), thickness, center);
				Edge(vh, array[4], array[4] + new Vector2(22f, 0f), thickness, center);
				Edge(vh, array[4], array[4] + new Vector2(0f, 22f), thickness, center);
			}
		}

		private void Edge(VertexHelper vh, Vector2 a, Vector2 b, float t, Vector2 centre)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0028: 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_0033: 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_0058: 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_005f: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0080: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type