Decompiled source of HelloDSP v0.0.47

BepInEx\plugins\HelloDSP\HelloDSP.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HelloDSP")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Home")]
[assembly: AssemblyProduct("HelloDSP")]
[assembly: AssemblyCopyright("Copyright © Home 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4ca5d0ba-296c-4954-8a97-205484480612")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HelloDSP;

[BepInPlugin("com.ycx.hellodsp", "HelloDSP", "0.0.47")]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.ycx.hellodsp";

	public const string PluginName = "HelloDSP";

	public const string PluginVersion = "0.0.47";

	internal static ManualLogSource Log;

	private VeinGuide _veinGuide;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Log.LogInfo((object)"模组已加载:HelloDSP");
		Log.LogInfo((object)"快捷键:F8 打开矿物指引");
		_veinGuide = new VeinGuide(Log);
		try
		{
			_harmony = new Harmony("com.ycx.hellodsp");
			_harmony.PatchAll();
			Log.LogInfo((object)"已加载 Harmony 补丁");
		}
		catch (Exception arg)
		{
			Log.LogWarning((object)$"Harmony patch failed: {arg}");
		}
	}

	private void Update()
	{
		try
		{
			if (GameMain.isRunning && Input.GetKeyDown((KeyCode)289))
			{
				_veinGuide?.OpenOrRefresh();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)ex);
			}
		}
		finally
		{
			MainThreadDispatcher.RunPending();
			_veinGuide?.Tick();
		}
	}
}
[Serializable]
public class GalaxyOverviewExport
{
	public int seed;

	public int starCount;

	public List<StarExport> stars = new List<StarExport>();
}
[Serializable]
public class StarExport
{
	public int id;

	public string name;

	public string type;

	public string spectr;

	public Vec3Export position;

	public int planetCount;

	public List<PlanetExport> planets = new List<PlanetExport>();
}
[Serializable]
public class PlanetExport
{
	public int id;

	public string name;

	public string type;

	public int starId;

	public int index;

	public double radius;

	public double orbitRadius;

	public double orbitInclination;

	public double orbitLongitude;

	public double orbitalPeriod;

	public double rotationPeriod;

	public int themeId;
}
[Serializable]
public class CurrentPlanetExport
{
	public int galaxySeed;

	public int id;

	public string name;

	public string type;

	public int starId;

	public int index;

	public double radius;

	public double orbitRadius;

	public int themeId;

	public bool factoryLoaded;

	public string veinSource;

	public int veinCursor;

	public List<VeinTypeSummaryExport> veinTypeSummaries = new List<VeinTypeSummaryExport>();

	public List<VeinTypePlannedSummaryExport> veinTypePlannedSummaries = new List<VeinTypePlannedSummaryExport>();

	public List<VeinGroupExport> veinGroups = new List<VeinGroupExport>();

	public List<VeinEntryExport> veins = new List<VeinEntryExport>();
}
[Serializable]
public class VeinTypeSummaryExport
{
	public string veinType;

	public string veinTypeZh;

	public int count;

	public double totalAmount;
}
[Serializable]
public class VeinTypePlannedSummaryExport
{
	public string veinType;

	public string veinTypeZh;

	public bool plannedKnown;

	public int plannedCount;

	public double plannedTotalAmount;

	public int unplannedCount;

	public double unplannedTotalAmount;
}
[Serializable]
public class VeinGroupExport
{
	public int groupIndex;

	public string veinType;

	public string veinTypeZh;

	public int count;

	public double totalAmount;

	public int minerCount;

	public bool planned;

	public bool plannedKnown;

	public Vec3Export position;

	public string positionInt;

	public int minedCount;

	public double minedTotalAmount;

	public int unminedCount;

	public double unminedTotalAmount;
}
[Serializable]
public class VeinEntryExport
{
	public int poolIndex;

	public string veinType;

	public string veinTypeZh;

	public double amount;

	public int productId;

	public Vec3Export position;

	public string positionInt;

	public int groupIndex;

	public int modelIndex;

	public bool planned;

	public bool plannedKnown;

	public bool mined;

	public bool minedKnown;

	public int minerCount;

	public List<int> minerIds = new List<int>();
}
[Serializable]
public struct Vec3Export
{
	public double x;

	public double y;

	public double z;

	public static Vec3Export From(double x, double y, double z)
	{
		Vec3Export result = default(Vec3Export);
		result.x = x;
		result.y = y;
		result.z = z;
		return result;
	}
}
internal static class Exporter
{
	private static string GetExportDir()
	{
		return Path.Combine(Paths.ConfigPath, "HelloDSP", "exports");
	}

	public static void ExportGalaxyOverview(ManualLogSource log)
	{
		GalaxyData galaxy = GameMain.galaxy;
		if (galaxy == null)
		{
			log.LogWarning((object)"ExportGalaxyOverview: GameMain.galaxy is null");
			return;
		}
		GalaxyOverviewExport galaxyOverviewExport = new GalaxyOverviewExport
		{
			seed = galaxy.seed,
			starCount = galaxy.starCount
		};
		for (int i = 0; i < galaxy.starCount; i++)
		{
			StarData val = galaxy.stars[i];
			if (val == null)
			{
				continue;
			}
			StarExport starExport = new StarExport
			{
				id = val.id,
				name = val.name,
				type = ((object)(EStarType)(ref val.type)).ToString(),
				spectr = ((object)(ESpectrType)(ref val.spectr)).ToString(),
				position = Vec3Export.From(val.position.x, val.position.y, val.position.z),
				planetCount = val.planetCount
			};
			if (val.planets != null)
			{
				for (int j = 0; j < val.planets.Length; j++)
				{
					PlanetData val2 = val.planets[j];
					if (val2 != null)
					{
						starExport.planets.Add(new PlanetExport
						{
							id = val2.id,
							name = val2.displayName,
							type = ((object)(EPlanetType)(ref val2.type)).ToString(),
							starId = ((val2.star != null) ? val2.star.id : 0),
							index = val2.index,
							radius = val2.realRadius,
							orbitRadius = val2.orbitRadius,
							orbitInclination = val2.orbitInclination,
							orbitLongitude = val2.orbitLongitude,
							orbitalPeriod = val2.orbitalPeriod,
							rotationPeriod = val2.rotationPeriod,
							themeId = val2.theme
						});
					}
				}
			}
			galaxyOverviewExport.stars.Add(starExport);
		}
		WriteJson(log, $"galaxy_{galaxyOverviewExport.seed}_{Timestamp()}.json", galaxyOverviewExport);
	}

	public static void ExportCurrentPlanet(ManualLogSource log)
	{
		PlanetData localPlanet = GameMain.localPlanet;
		if (localPlanet == null)
		{
			log.LogWarning((object)"ExportCurrentPlanet: GameMain.localPlanet is null");
			return;
		}
		CurrentPlanetExport currentPlanetExport = new CurrentPlanetExport
		{
			galaxySeed = ((GameMain.galaxy != null) ? GameMain.galaxy.seed : 0),
			id = localPlanet.id,
			name = localPlanet.displayName,
			type = ((object)(EPlanetType)(ref localPlanet.type)).ToString(),
			starId = ((localPlanet.star != null) ? localPlanet.star.id : 0),
			index = localPlanet.index,
			radius = localPlanet.realRadius,
			orbitRadius = localPlanet.orbitRadius,
			themeId = localPlanet.theme,
			factoryLoaded = localPlanet.factoryLoaded
		};
		PlanetFactory factory = localPlanet.factory;
		if (factory != null)
		{
			currentPlanetExport.veinSource = "factory";
			currentPlanetExport.veinCursor = factory.veinCursor;
			SummarizeVeins(factory.veinPool, factory.veinCursor, currentPlanetExport);
			Dictionary<int, int> minerCountByGroupIndex = ExportVeinDetails(factory, factory.veinPool, factory.veinCursor, currentPlanetExport, planningAvailable: true);
			ExportVeinGroups(factory, currentPlanetExport, minerCountByGroupIndex);
			AnnotateGroupMiningCoverage(currentPlanetExport);
		}
		else
		{
			currentPlanetExport.veinSource = "runtime";
			currentPlanetExport.veinCursor = localPlanet.runtimeVeinCursor;
			SummarizeVeins(localPlanet.runtimeVeinPool, localPlanet.runtimeVeinCursor, currentPlanetExport);
			ExportVeinDetails(null, localPlanet.runtimeVeinPool, localPlanet.runtimeVeinCursor, currentPlanetExport, planningAvailable: false);
			if (currentPlanetExport.veinTypeSummaries.Count == 0)
			{
				log.LogWarning((object)$"ExportCurrentPlanet: no veins found via runtime pool (planetId={localPlanet.id}). If this is unexpected, try landing to load factory then press F8 again.");
			}
		}
		currentPlanetExport.veinTypeSummaries.Sort((VeinTypeSummaryExport a, VeinTypeSummaryExport b) => string.CompareOrdinal(a.veinType, b.veinType));
		currentPlanetExport.veinGroups.Sort((VeinGroupExport a, VeinGroupExport b) => a.groupIndex.CompareTo(b.groupIndex));
		currentPlanetExport.veinTypePlannedSummaries.Sort((VeinTypePlannedSummaryExport a, VeinTypePlannedSummaryExport b) => string.CompareOrdinal(a.veinType, b.veinType));
		if (currentPlanetExport.veinTypeSummaries.Count > 0)
		{
			log.LogInfo((object)$"Veins on planet {currentPlanetExport.id} ({currentPlanetExport.name}) via {currentPlanetExport.veinSource}:");
			for (int i = 0; i < currentPlanetExport.veinTypeSummaries.Count; i++)
			{
				VeinTypeSummaryExport veinTypeSummaryExport = currentPlanetExport.veinTypeSummaries[i];
				log.LogInfo((object)$"- {veinTypeSummaryExport.veinType}: count={veinTypeSummaryExport.count}, totalAmount={veinTypeSummaryExport.totalAmount}");
			}
		}
		else
		{
			log.LogWarning((object)$"No vein summaries produced (planetId={currentPlanetExport.id}, source={currentPlanetExport.veinSource}, cursor={currentPlanetExport.veinCursor}).");
		}
		if (currentPlanetExport.veinTypePlannedSummaries.Count > 0)
		{
			log.LogInfo((object)"Veins planned vs unplanned (planned = group has at least one miner):");
			for (int j = 0; j < currentPlanetExport.veinTypePlannedSummaries.Count; j++)
			{
				VeinTypePlannedSummaryExport veinTypePlannedSummaryExport = currentPlanetExport.veinTypePlannedSummaries[j];
				if (!veinTypePlannedSummaryExport.plannedKnown)
				{
					log.LogInfo((object)("- " + veinTypePlannedSummaryExport.veinType + ": plannedUnknown (factory not loaded?)"));
					continue;
				}
				log.LogInfo((object)$"- {veinTypePlannedSummaryExport.veinType}: planned={veinTypePlannedSummaryExport.plannedCount} ({veinTypePlannedSummaryExport.plannedTotalAmount}), unplanned={veinTypePlannedSummaryExport.unplannedCount} ({veinTypePlannedSummaryExport.unplannedTotalAmount})");
			}
		}
		int plannedGroupsWithMissedVeins = 0;
		for (int k = 0; k < currentPlanetExport.veinGroups.Count; k++)
		{
			VeinGroupExport veinGroupExport = currentPlanetExport.veinGroups[k];
			if (veinGroupExport.plannedKnown && veinGroupExport.planned && veinGroupExport.unminedCount > 0)
			{
				plannedGroupsWithMissedVeins++;
			}
		}
		if (plannedGroupsWithMissedVeins > 0)
		{
			log.LogWarning((object)$"Found {plannedGroupsWithMissedVeins} planned vein groups with unmined veins (miner coverage/capacity). See JSON veinGroups[].unminedCount for details.");
		}
		log.LogInfo((object)$"Vein detail entries: {currentPlanetExport.veins.Count}");
		if (plannedGroupsWithMissedVeins > 0)
		{
			MainThreadDispatcher.Enqueue(delegate
			{
				InGameNotifier.Warning("发现 " + plannedGroupsWithMissedVeins + " 个矿簇存在漏挖(已放矿机但有矿点未覆盖)");
			});
		}
		WriteJson(log, $"planet_{currentPlanetExport.id}_{Timestamp()}.json", currentPlanetExport);
	}

	private static void SummarizeVeins(VeinData[] veinPool, int veinCursor, CurrentPlanetExport export)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		if (veinPool == null || veinCursor <= 1)
		{
			return;
		}
		Dictionary<string, VeinTypeSummaryExport> dictionary = new Dictionary<string, VeinTypeSummaryExport>(StringComparer.Ordinal);
		int num = Math.Min(veinCursor, veinPool.Length);
		for (int i = 1; i < num; i++)
		{
			VeinData val = veinPool[i];
			if ((int)val.type != 0 && val.amount > 0)
			{
				string text = ((object)(EVeinType)(ref val.type)).ToString();
				if (!dictionary.TryGetValue(text, out var value))
				{
					value = new VeinTypeSummaryExport
					{
						veinType = text,
						veinTypeZh = VeinTypeToZh(text),
						count = 0,
						totalAmount = 0.0
					};
				}
				value.count++;
				value.totalAmount += val.amount;
				dictionary[text] = value;
			}
		}
		foreach (KeyValuePair<string, VeinTypeSummaryExport> item in dictionary)
		{
			export.veinTypeSummaries.Add(item.Value);
		}
	}

	private static Dictionary<int, int> ExportVeinDetails(PlanetFactory factory, VeinData[] veinPool, int veinCursor, CurrentPlanetExport export, bool planningAvailable)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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_0060: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_00a5: 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_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		if (veinPool == null)
		{
			return null;
		}
		if (veinCursor <= 1)
		{
			return null;
		}
		int num = Math.Min(veinCursor, veinPool.Length);
		export.veins.Capacity = Math.Max(export.veins.Capacity, num);
		bool flag = HasVeinField("minerCount");
		Dictionary<int, HashSet<int>> dictionary = new Dictionary<int, HashSet<int>>();
		for (int i = 1; i < num; i++)
		{
			VeinData val = veinPool[i];
			if ((int)val.type == 0 || val.amount <= 0)
			{
				continue;
			}
			int intField = GetIntField(val, "groupIndex");
			int intField2 = GetIntField(val, "minerCount");
			int intField3 = GetIntField(val, "minerId0");
			int intField4 = GetIntField(val, "minerId1");
			int intField5 = GetIntField(val, "minerId2");
			int intField6 = GetIntField(val, "minerId3");
			int num2 = intField2;
			bool minedKnown = flag;
			bool mined = intField2 > 0;
			if (planningAvailable && factory != null)
			{
				num2 = VeinMiningUtil.CountRealMiners(factory, intField3, intField4, intField5, intField6);
				minedKnown = true;
				mined = num2 > 0;
			}
			if (planningAvailable && factory != null && intField > 0)
			{
				if (!dictionary.TryGetValue(intField, out var value))
				{
					value = (dictionary[intField] = new HashSet<int>());
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField3))
				{
					value.Add(intField3);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField4))
				{
					value.Add(intField4);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField5))
				{
					value.Add(intField5);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField6))
				{
					value.Add(intField6);
				}
			}
			Vec3Export position = GetPosition(val);
			VeinEntryExport veinEntryExport = new VeinEntryExport
			{
				poolIndex = i,
				veinType = ((object)(EVeinType)(ref val.type)).ToString(),
				veinTypeZh = VeinTypeToZh(((object)(EVeinType)(ref val.type)).ToString()),
				amount = val.amount,
				productId = GetIntField(val, "productId"),
				groupIndex = intField,
				modelIndex = GetIntField(val, "modelIndex"),
				position = position,
				positionInt = FormatPositionInt(position),
				planned = false,
				plannedKnown = false,
				mined = mined,
				minedKnown = minedKnown,
				minerCount = ((planningAvailable && factory != null) ? num2 : intField2)
			};
			if (planningAvailable && factory != null)
			{
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField3))
				{
					veinEntryExport.minerIds.Add(intField3);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField4))
				{
					veinEntryExport.minerIds.Add(intField4);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField5))
				{
					veinEntryExport.minerIds.Add(intField5);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, intField6))
				{
					veinEntryExport.minerIds.Add(intField6);
				}
			}
			else
			{
				if (intField3 > 0)
				{
					veinEntryExport.minerIds.Add(intField3);
				}
				if (intField4 > 0)
				{
					veinEntryExport.minerIds.Add(intField4);
				}
				if (intField5 > 0)
				{
					veinEntryExport.minerIds.Add(intField5);
				}
				if (intField6 > 0)
				{
					veinEntryExport.minerIds.Add(intField6);
				}
			}
			export.veins.Add(veinEntryExport);
		}
		Dictionary<int, int> dictionary2 = null;
		if (planningAvailable && factory != null)
		{
			dictionary2 = new Dictionary<int, int>();
			foreach (KeyValuePair<int, HashSet<int>> item in dictionary)
			{
				dictionary2[item.Key] = ((item.Value != null) ? item.Value.Count : 0);
			}
			for (int j = 0; j < export.veins.Count; j++)
			{
				VeinEntryExport veinEntryExport2 = export.veins[j];
				if (veinEntryExport2.groupIndex > 0)
				{
					veinEntryExport2.plannedKnown = true;
					if (dictionary2.TryGetValue(veinEntryExport2.groupIndex, out var value2))
					{
						veinEntryExport2.planned = value2 > 0;
					}
					else
					{
						veinEntryExport2.planned = false;
					}
				}
				else
				{
					veinEntryExport2.plannedKnown = false;
					veinEntryExport2.planned = false;
				}
			}
			Dictionary<string, VeinTypePlannedSummaryExport> dictionary3 = new Dictionary<string, VeinTypePlannedSummaryExport>(StringComparer.Ordinal);
			for (int k = 0; k < export.veins.Count; k++)
			{
				VeinEntryExport veinEntryExport3 = export.veins[k];
				string text = veinEntryExport3.veinType ?? "";
				if (!dictionary3.TryGetValue(text, out var value3))
				{
					value3 = new VeinTypePlannedSummaryExport
					{
						veinType = text,
						veinTypeZh = VeinTypeToZh(text),
						plannedKnown = true,
						plannedCount = 0,
						plannedTotalAmount = 0.0,
						unplannedCount = 0,
						unplannedTotalAmount = 0.0
					};
				}
				if (!veinEntryExport3.plannedKnown)
				{
					value3.plannedKnown = false;
				}
				else if (veinEntryExport3.planned)
				{
					value3.plannedCount++;
					value3.plannedTotalAmount += veinEntryExport3.amount;
				}
				else
				{
					value3.unplannedCount++;
					value3.unplannedTotalAmount += veinEntryExport3.amount;
				}
				dictionary3[text] = value3;
			}
			export.veinTypePlannedSummaries.Clear();
			foreach (KeyValuePair<string, VeinTypePlannedSummaryExport> item2 in dictionary3)
			{
				export.veinTypePlannedSummaries.Add(item2.Value);
			}
		}
		return dictionary2;
	}

	private static bool HasVeinField(string fieldName)
	{
		try
		{
			return typeof(VeinData).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null;
		}
		catch
		{
			return false;
		}
	}

	private static void AnnotateGroupMiningCoverage(CurrentPlanetExport export)
	{
		if (export.veinGroups == null || export.veinGroups.Count == 0 || export.veins == null || export.veins.Count == 0)
		{
			return;
		}
		Dictionary<int, VeinGroupExport> dictionary = new Dictionary<int, VeinGroupExport>();
		for (int i = 0; i < export.veinGroups.Count; i++)
		{
			VeinGroupExport veinGroupExport = export.veinGroups[i];
			dictionary[veinGroupExport.groupIndex] = veinGroupExport;
		}
		for (int j = 0; j < export.veins.Count; j++)
		{
			VeinEntryExport veinEntryExport = export.veins[j];
			if (veinEntryExport.groupIndex > 0 && dictionary.TryGetValue(veinEntryExport.groupIndex, out var value))
			{
				if (veinEntryExport.minedKnown && veinEntryExport.mined)
				{
					value.minedCount++;
					value.minedTotalAmount += veinEntryExport.amount;
				}
				else
				{
					value.unminedCount++;
					value.unminedTotalAmount += veinEntryExport.amount;
				}
			}
		}
	}

	private static void ExportVeinGroups(PlanetFactory factory, CurrentPlanetExport export, Dictionary<int, int> minerCountByGroupIndex)
	{
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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)
		Array arrayMember = GetArrayMember(factory, "veinGroups");
		if (arrayMember == null)
		{
			return;
		}
		int num = GetIntMember(factory, "veinGroupCursor");
		if (num <= 0 || num > arrayMember.Length)
		{
			num = arrayMember.Length;
		}
		export.veinGroups.Clear();
		HashSet<int> hashSet = new HashSet<int>();
		for (int i = 1; i < num; i++)
		{
			object value = arrayMember.GetValue(i);
			if (value == null)
			{
				continue;
			}
			int num2 = GetIntMember(value, "id");
			if (num2 <= 0)
			{
				num2 = i;
			}
			string enumStringMember = GetEnumStringMember(value, "type");
			if (!string.IsNullOrEmpty(enumStringMember) && !string.Equals(enumStringMember, "None", StringComparison.OrdinalIgnoreCase))
			{
				int intMember = GetIntMember(value, "count");
				double doubleMember = GetDoubleMember(value, "amount");
				int value2 = 0;
				bool flag = false;
				if (minerCountByGroupIndex != null)
				{
					flag = true;
					minerCountByGroupIndex.TryGetValue(num2, out value2);
				}
				else
				{
					value2 = GetIntMember(value, "minerCount");
					flag = value2 != 0 || HasMember(value, "minerCount");
				}
				Vector3 result;
				Vec3Export vec3Export = (TryGetVector3Member(value, "pos", out result) ? Vec3Export.From(result.x, result.y, result.z) : Vec3Export.From(0.0, 0.0, 0.0));
				bool planned = value2 > 0;
				export.veinGroups.Add(new VeinGroupExport
				{
					groupIndex = num2,
					veinType = enumStringMember,
					veinTypeZh = VeinTypeToZh(enumStringMember),
					count = intMember,
					totalAmount = doubleMember,
					minerCount = value2,
					planned = planned,
					plannedKnown = flag,
					position = vec3Export,
					positionInt = FormatPositionInt(vec3Export)
				});
				hashSet.Add(num2);
			}
		}
		if (minerCountByGroupIndex == null || export.veins == null)
		{
			return;
		}
		foreach (KeyValuePair<int, int> item in minerCountByGroupIndex)
		{
			int key = item.Key;
			if (key <= 0 || hashSet.Contains(key))
			{
				continue;
			}
			string text = "";
			int num3 = 0;
			double num4 = 0.0;
			Vec3Export vec3Export2 = Vec3Export.From(0.0, 0.0, 0.0);
			for (int j = 0; j < export.veins.Count; j++)
			{
				VeinEntryExport veinEntryExport = export.veins[j];
				if (veinEntryExport.groupIndex == key)
				{
					if (string.IsNullOrEmpty(text))
					{
						text = veinEntryExport.veinType;
					}
					if (num3 == 0)
					{
						vec3Export2 = veinEntryExport.position;
					}
					num3++;
					num4 += veinEntryExport.amount;
				}
			}
			int value3 = item.Value;
			export.veinGroups.Add(new VeinGroupExport
			{
				groupIndex = key,
				veinType = text,
				veinTypeZh = VeinTypeToZh(text),
				count = num3,
				totalAmount = num4,
				minerCount = value3,
				planned = (value3 > 0),
				plannedKnown = true,
				position = vec3Export2,
				positionInt = FormatPositionInt(vec3Export2)
			});
		}
	}

	private static Array GetArrayMember(object obj, string name)
	{
		return GetMemberValue(obj, name) as Array;
	}

	private static bool HasMember(object obj, string name)
	{
		if (obj == null)
		{
			return false;
		}
		Type type = obj.GetType();
		if (!(type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null))
		{
			return type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null;
		}
		return true;
	}

	private static object GetMemberValue(object obj, string name)
	{
		try
		{
			if (obj == null)
			{
				return null;
			}
			Type type = obj.GetType();
			FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				return field.GetValue(obj);
			}
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanRead)
			{
				return property.GetValue(obj, null);
			}
			return null;
		}
		catch
		{
			return null;
		}
	}

	private static string GetEnumStringMember(object obj, string name)
	{
		return GetMemberValue(obj, name)?.ToString();
	}

	private static int GetIntMember(object obj, string name)
	{
		try
		{
			object memberValue = GetMemberValue(obj, name);
			if (memberValue == null)
			{
				return 0;
			}
			if (memberValue is int result)
			{
				return result;
			}
			return Convert.ToInt32(memberValue);
		}
		catch
		{
			return 0;
		}
	}

	private static double GetDoubleMember(object obj, string name)
	{
		try
		{
			object memberValue = GetMemberValue(obj, name);
			if (memberValue == null)
			{
				return 0.0;
			}
			if (memberValue is double result)
			{
				return result;
			}
			if (memberValue is float num)
			{
				return num;
			}
			if (memberValue is int num2)
			{
				return num2;
			}
			if (memberValue is long num3)
			{
				return num3;
			}
			return Convert.ToDouble(memberValue);
		}
		catch
		{
			return 0.0;
		}
	}

	private static bool TryGetVector3Member(object obj, string name, out Vector3 result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		result = default(Vector3);
		try
		{
			if (GetMemberValue(obj, name) is Vector3 val)
			{
				result = val;
				return true;
			}
			return false;
		}
		catch
		{
			return false;
		}
	}

	private static int GetIntField(VeinData vein, string fieldName)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			object obj = vein;
			FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return 0;
			}
			object value = field.GetValue(obj);
			if (value == null)
			{
				return 0;
			}
			if (value is int result)
			{
				return result;
			}
			return Convert.ToInt32(value);
		}
		catch
		{
			return 0;
		}
	}

	private static Vec3Export GetPosition(VeinData vein)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0039: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		if (TryGetVector3Field(vein, "pos", out var result))
		{
			return Vec3Export.From(result.x, result.y, result.z);
		}
		if (TryGetVector3Field(vein, "position", out result))
		{
			return Vec3Export.From(result.x, result.y, result.z);
		}
		if (TryGetVector3Field(vein, "pos0", out result))
		{
			return Vec3Export.From(result.x, result.y, result.z);
		}
		return Vec3Export.From(0.0, 0.0, 0.0);
	}

	private static bool TryGetVector3Field(VeinData vein, string fieldName, out Vector3 result)
	{
		//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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		result = default(Vector3);
		try
		{
			object obj = vein;
			FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return false;
			}
			object value = field.GetValue(obj);
			if (value == null)
			{
				return false;
			}
			if (value is Vector3 val)
			{
				result = val;
				return true;
			}
			return false;
		}
		catch
		{
			return false;
		}
	}

	private static string FormatPositionInt(Vec3Export pos)
	{
		int num = (int)Math.Round(pos.x);
		int num2 = (int)Math.Round(pos.y);
		int num3 = (int)Math.Round(pos.z);
		return "(" + num + "," + num2 + "," + num3 + ")";
	}

	private static string VeinTypeToZh(string veinType)
	{
		if (string.IsNullOrEmpty(veinType))
		{
			return veinType;
		}
		return veinType switch
		{
			"Iron" => "铁", 
			"Copper" => "铜", 
			"Stone" => "石矿", 
			"Coal" => "煤", 
			"Silicium" => "硅石", 
			"Silicon" => "硅石", 
			"Titanium" => "钛", 
			"Oil" => "原油", 
			"Fireice" => "可燃冰", 
			"Fractal" => "分形硅石", 
			"Kimberlite" => "金伯利矿石", 
			"Diamond" => "金伯利矿石", 
			"Bamboo" => "刺笋结晶", 
			"Crysrub" => "刺笋结晶", 
			"Grat" => "光栅石", 
			"Mag" => "磁铁矿", 
			_ => veinType, 
		};
	}

	private static void WriteJson(ManualLogSource log, string fileName, object data)
	{
		string exportDir = GetExportDir();
		Directory.CreateDirectory(exportDir);
		string text = Path.Combine(exportDir, fileName);
		string contents = SimpleJson.ToJson(data, pretty: true);
		File.WriteAllText(text, contents, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
		log.LogInfo((object)("Exported: " + text));
		MainThreadDispatcher.Enqueue(delegate
		{
			InGameNotifier.Info("已导出:" + fileName);
		});
	}

	private static string Timestamp()
	{
		return DateTime.Now.ToString("yyyyMMdd_HHmmss");
	}
}
internal static class InGameNotifier
{
	public static void Info(string message)
	{
		if (string.IsNullOrWhiteSpace(message))
		{
			return;
		}
		try
		{
			UIRealtimeTip.Popup(message, true, 0);
		}
		catch
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)message);
			}
		}
	}

	public static void Warning(string message)
	{
		if (string.IsNullOrWhiteSpace(message))
		{
			return;
		}
		try
		{
			UIRealtimeTip.Popup(message, true, 2);
		}
		catch
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)message);
			}
		}
	}
}
internal static class MainThreadDispatcher
{
	private static readonly ConcurrentQueue<Action> Queue = new ConcurrentQueue<Action>();

	public static void Enqueue(Action action)
	{
		if (action != null)
		{
			Queue.Enqueue(action);
		}
	}

	public static void RunPending()
	{
		Action result;
		while (Queue.TryDequeue(out result))
		{
			try
			{
				result();
			}
			catch
			{
			}
		}
	}
}
internal static class SimpleJson
{
	private static readonly Dictionary<Type, FieldInfo[]> FieldCache = new Dictionary<Type, FieldInfo[]>();

	public static string ToJson(object value, bool pretty)
	{
		StringBuilder stringBuilder = new StringBuilder(16384);
		WriteValue(stringBuilder, value, pretty, 0);
		return stringBuilder.ToString();
	}

	private static void WriteValue(StringBuilder sb, object value, bool pretty, int indent)
	{
		if (value == null)
		{
			sb.Append("null");
		}
		else if (value is string s)
		{
			WriteString(sb, s);
		}
		else if (value is bool flag)
		{
			sb.Append(flag ? "true" : "false");
		}
		else if (IsNumber(value))
		{
			WriteNumber(sb, value);
		}
		else if (value is IDictionary dict)
		{
			WriteDictionary(sb, dict, pretty, indent);
		}
		else if (value is IEnumerable enumerable)
		{
			WriteArray(sb, enumerable, pretty, indent);
		}
		else
		{
			WriteObject(sb, value, pretty, indent);
		}
	}

	private static void WriteObject(StringBuilder sb, object value, bool pretty, int indent)
	{
		FieldInfo[] serializableFields = GetSerializableFields(value.GetType());
		sb.Append('{');
		if (pretty && serializableFields.Length != 0)
		{
			sb.Append('\n');
		}
		bool flag = true;
		foreach (FieldInfo fieldInfo in serializableFields)
		{
			object value2 = fieldInfo.GetValue(value);
			if (value2 is IList list && list.Count == 0)
			{
				continue;
			}
			if (!flag)
			{
				sb.Append(',');
				if (pretty)
				{
					sb.Append('\n');
				}
			}
			flag = false;
			if (pretty)
			{
				AppendIndent(sb, indent + 1);
			}
			WriteString(sb, fieldInfo.Name);
			sb.Append(pretty ? ": " : ":");
			WriteValue(sb, value2, pretty, indent + 1);
		}
		if (pretty)
		{
			if (serializableFields.Length != 0 && !flag)
			{
				sb.Append('\n');
			}
			AppendIndent(sb, indent);
		}
		sb.Append('}');
	}

	private static void WriteDictionary(StringBuilder sb, IDictionary dict, bool pretty, int indent)
	{
		sb.Append('{');
		if (pretty && dict.Count > 0)
		{
			sb.Append('\n');
		}
		bool flag = true;
		foreach (DictionaryEntry item in dict)
		{
			if (!(item.Key is string s))
			{
				continue;
			}
			if (!flag)
			{
				sb.Append(',');
				if (pretty)
				{
					sb.Append('\n');
				}
			}
			flag = false;
			if (pretty)
			{
				AppendIndent(sb, indent + 1);
			}
			WriteString(sb, s);
			sb.Append(pretty ? ": " : ":");
			WriteValue(sb, item.Value, pretty, indent + 1);
		}
		if (pretty)
		{
			if (dict.Count > 0)
			{
				sb.Append('\n');
			}
			AppendIndent(sb, indent);
		}
		sb.Append('}');
	}

	private static void WriteArray(StringBuilder sb, IEnumerable enumerable, bool pretty, int indent)
	{
		sb.Append('[');
		bool flag = true;
		int num = 0;
		foreach (object item in enumerable)
		{
			if (!flag)
			{
				sb.Append(',');
			}
			flag = false;
			num++;
			if (pretty)
			{
				sb.Append('\n');
				AppendIndent(sb, indent + 1);
			}
			WriteValue(sb, item, pretty, indent + 1);
		}
		if (pretty && num > 0)
		{
			sb.Append('\n');
			AppendIndent(sb, indent);
		}
		sb.Append(']');
	}

	private static void WriteString(StringBuilder sb, string s)
	{
		sb.Append('"');
		foreach (char c in s)
		{
			switch (c)
			{
			case '\\':
				sb.Append("\\\\");
				continue;
			case '"':
				sb.Append("\\\"");
				continue;
			case '\b':
				sb.Append("\\b");
				continue;
			case '\f':
				sb.Append("\\f");
				continue;
			case '\n':
				sb.Append("\\n");
				continue;
			case '\r':
				sb.Append("\\r");
				continue;
			case '\t':
				sb.Append("\\t");
				continue;
			}
			if (c < ' ')
			{
				sb.Append("\\u");
				int num = c;
				sb.Append(num.ToString("x4", CultureInfo.InvariantCulture));
			}
			else
			{
				sb.Append(c);
			}
		}
		sb.Append('"');
	}

	private static void WriteNumber(StringBuilder sb, object value)
	{
		if (!(value is float num))
		{
			if (!(value is double num2))
			{
				if (value is decimal num3)
				{
					sb.Append(num3.ToString(CultureInfo.InvariantCulture));
				}
				else
				{
					sb.Append(Convert.ToString(value, CultureInfo.InvariantCulture));
				}
			}
			else
			{
				sb.Append(num2.ToString("R", CultureInfo.InvariantCulture));
			}
		}
		else
		{
			sb.Append(num.ToString("R", CultureInfo.InvariantCulture));
		}
	}

	private static bool IsNumber(object value)
	{
		if (!(value is sbyte) && !(value is byte) && !(value is short) && !(value is ushort) && !(value is int) && !(value is uint) && !(value is long) && !(value is ulong) && !(value is float) && !(value is double))
		{
			return value is decimal;
		}
		return true;
	}

	private static FieldInfo[] GetSerializableFields(Type t)
	{
		if (FieldCache.TryGetValue(t, out var value))
		{
			return value;
		}
		FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
		FieldCache[t] = fields;
		return fields;
	}

	private static void AppendIndent(StringBuilder sb, int indent)
	{
		for (int i = 0; i < indent; i++)
		{
			sb.Append("    ");
		}
	}
}
internal static class VeinMiningUtil
{
	private static FieldInfo _entityPrebuildIdField;

	public static bool IsRealMinerEntity(PlanetFactory factory, int entityId)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (factory == null)
			{
				return false;
			}
			if (entityId <= 0)
			{
				return false;
			}
			if (factory.entityPool == null)
			{
				return false;
			}
			if (entityId >= factory.entityPool.Length)
			{
				return false;
			}
			EntityData val = factory.entityPool[entityId];
			if (val.id != entityId)
			{
				return false;
			}
			if (val.protoId <= 0)
			{
				return false;
			}
			if (_entityPrebuildIdField == null)
			{
				_entityPrebuildIdField = typeof(EntityData).GetField("prebuildId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (_entityPrebuildIdField != null)
			{
				object obj = val;
				object value = _entityPrebuildIdField.GetValue(obj);
				if (value != null && Convert.ToInt32(value) > 0)
				{
					return false;
				}
			}
			return true;
		}
		catch
		{
			return false;
		}
	}

	public static int CountRealMiners(PlanetFactory factory, int minerId0, int minerId1, int minerId2, int minerId3)
	{
		int num = 0;
		if (IsRealMinerEntity(factory, minerId0))
		{
			num++;
		}
		if (minerId1 > 0 && minerId1 != minerId0 && IsRealMinerEntity(factory, minerId1))
		{
			num++;
		}
		if (minerId2 > 0 && minerId2 != minerId0 && minerId2 != minerId1 && IsRealMinerEntity(factory, minerId2))
		{
			num++;
		}
		if (minerId3 > 0 && minerId3 != minerId0 && minerId3 != minerId1 && minerId3 != minerId2 && IsRealMinerEntity(factory, minerId3))
		{
			num++;
		}
		return num;
	}
}
internal enum VeinScope
{
	All,
	Unworked,
	Missed
}
internal enum VeinLinkMode
{
	Groups,
	Veins
}
internal sealed class VeinGuide
{
	private const int LineSegments = 14;

	private const int MaxLinesVeins = 180;

	private const int MaxLinesGroups = 220;

	private const float RayLiftGroups = 6f;

	private const float RayLiftVeins = 4f;

	private const float RaySurfaceMargin = 3f;

	private const float UiAutoRefreshIntervalSeconds = 0.35f;

	private const float RaysAutoRefreshIntervalSeconds = 3f;

	private readonly ManualLogSource _log;

	private GameObject _uiRoot;

	private Text _statusText;

	private Button _btnClose;

	private Button _btnApply;

	private Button _btnClear;

	private Button _btnScopeAll;

	private Button _btnScopeUnworked;

	private Button _btnScopeMissed;

	private Button _btnModeGroups;

	private Button _btnModeVeins;

	private readonly List<Button> _oreButtons = new List<Button>();

	private readonly Dictionary<Button, string> _oreByButton = new Dictionary<Button, string>();

	private string _selectedOre = "";

	private VeinScope _scope = VeinScope.Missed;

	private VeinLinkMode _mode;

	private GameObject _rayRoot;

	private readonly List<LineRenderer> _lines = new List<LineRenderer>();

	private readonly List<Vector3> _targets = new List<Vector3>();

	private bool _raysActive;

	private float _nextUiRefreshTime;

	private float _nextRaysRefreshTime;

	private Material _rayMaterial;

	private Font _uiFont;

	public VeinGuide(ManualLogSource log)
	{
		_log = log;
	}

	public void OpenOrRefresh()
	{
		try
		{
			if (!GameMain.isRunning)
			{
				return;
			}
			if (GameMain.localPlanet == null)
			{
				MainThreadDispatcher.Enqueue(delegate
				{
					InGameNotifier.Warning("当前不在星球上,无法指引矿物");
				});
				return;
			}
			EnsureUi();
			if (!((Object)(object)_uiRoot == (Object)null))
			{
				BuildOreButtons();
				_uiRoot.SetActive(true);
				UpdateButtonStates();
				ApplyGuide();
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogWarning((object)$"VeinGuide.OpenOrRefresh exception: {arg}");
			}
		}
	}

	public void Tick()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: 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_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: 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_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: 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)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		bool flag = (Object)(object)_uiRoot != (Object)null && _uiRoot.activeSelf;
		if (!_raysActive && !flag)
		{
			return;
		}
		try
		{
			if (!GameMain.isRunning || GameMain.mainPlayer == null || GameMain.localPlanet == null)
			{
				ClearRays();
				return;
			}
			Vector3 val = GameMain.mainPlayer.position + new Vector3(0f, 1.8f, 0f);
			PlanetData localPlanet = GameMain.localPlanet;
			float time = Time.time;
			if (_raysActive && Time.time >= _nextRaysRefreshTime)
			{
				_nextRaysRefreshTime = Time.time + 3f;
				RefreshGuideSilently(localPlanet);
			}
			if (_raysActive)
			{
				int num = 14;
				Color val5 = default(Color);
				Color startColor = default(Color);
				Color endColor = default(Color);
				for (int i = 0; i < _targets.Count; i++)
				{
					LineRenderer val2 = _lines[i];
					if (Object.op_Implicit((Object)(object)val2) && ((Component)val2).gameObject.activeSelf)
					{
						Vector3 val3 = _targets[i];
						float num2 = Vector3.Distance(val, val3);
						float num3 = Mathf.InverseLerp(35f, 260f, num2);
						Color val4 = new Color(0.3f, 0.95f, 1f, 1f);
						((Color)(ref val5))..ctor(0.05f, 0.25f, 0.75f, 1f);
						Color val6 = Color.Lerp(val4, val5, num3);
						Vector3 b = ComputeArcMid(val, val3);
						for (int j = 0; j < num; j++)
						{
							float t = (float)j / (float)(num - 1);
							Vector3 p = QuadraticBezier(val, b, val3, t);
							p = ClampAboveSurface(localPlanet, p, 3f);
							val2.SetPosition(j, p);
						}
						float num4 = 0.55f + 0.45f * Mathf.Sin(time * 3f + (float)i * 0.37f);
						float num5 = 0.32f + 0.55f * num4;
						float num6 = 0.14f + 0.32f * num4;
						((Color)(ref startColor))..ctor(val6.r, val6.g, val6.b, num5);
						((Color)(ref endColor))..ctor(val6.r * 0.55f, val6.g * 0.45f, val6.b * 0.75f, num6);
						val2.startColor = startColor;
						val2.endColor = endColor;
					}
				}
			}
			if (flag && Time.time >= _nextUiRefreshTime)
			{
				_nextUiRefreshTime = Time.time + 0.35f;
				UpdateStatus();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogWarning((object)("VeinGuide.Tick exception: " + ex.Message));
			}
		}
	}

	private void RefreshGuideSilently(PlanetData planet)
	{
		try
		{
			if (planet != null)
			{
				BuildTargets(planet);
				EnsureRayRoot();
				EnsureLineRenderers();
				_raysActive = _targets.Count > 0;
				UpdateStatus();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogWarning((object)("VeinGuide.RefreshGuideSilently exception: " + ex.Message));
			}
		}
	}

	private static Vector3 ComputeArcMid(Vector3 start, Vector3 end)
	{
		//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_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		Vector3 val = end - start;
		float magnitude = ((Vector3)(ref val)).magnitude;
		Vector3 val2 = start + end;
		Vector3 val3;
		if (!(((Vector3)(ref val2)).sqrMagnitude > 0.001f))
		{
			val3 = Vector3.up;
		}
		else
		{
			val2 = start + end;
			val3 = ((Vector3)(ref val2)).normalized;
		}
		Vector3 val4 = val3;
		float num = Mathf.Clamp(magnitude * 0.15f, 4f, 26f);
		return start + val * 0.5f + val4 * num;
	}

	private static Vector3 QuadraticBezier(Vector3 a, Vector3 b, Vector3 c, float t)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_002e: Unknown result type (might be due to invalid IL or missing references)
		float num = 1f - t;
		return num * num * a + 2f * num * t * b + t * t * c;
	}

	private static Vector3 ClampAboveSurface(PlanetData planet, Vector3 p, float margin)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (planet == null)
			{
				return p;
			}
			float num = planet.realRadius + margin;
			float magnitude = ((Vector3)(ref p)).magnitude;
			if (magnitude > 0.01f && magnitude < num)
			{
				return p / magnitude * num;
			}
			return p;
		}
		catch
		{
			return p;
		}
	}

	private void EnsureUi()
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: 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_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Expected O, but got Unknown
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02de: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0352: Unknown result type (might be due to invalid IL or missing references)
		//IL_036b: Unknown result type (might be due to invalid IL or missing references)
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03df: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0407: Unknown result type (might be due to invalid IL or missing references)
		//IL_0416: Unknown result type (might be due to invalid IL or missing references)
		//IL_0425: Unknown result type (might be due to invalid IL or missing references)
		//IL_0434: Unknown result type (might be due to invalid IL or missing references)
		//IL_0460: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0511: Unknown result type (might be due to invalid IL or missing references)
		//IL_051b: Expected O, but got Unknown
		//IL_052d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0537: Expected O, but got Unknown
		//IL_0549: Unknown result type (might be due to invalid IL or missing references)
		//IL_0553: Expected O, but got Unknown
		//IL_0574: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f6: Expected O, but got Unknown
		//IL_0608: Unknown result type (might be due to invalid IL or missing references)
		//IL_0612: Expected O, but got Unknown
		//IL_0640: Unknown result type (might be due to invalid IL or missing references)
		//IL_0671: Unknown result type (might be due to invalid IL or missing references)
		//IL_0686: Unknown result type (might be due to invalid IL or missing references)
		//IL_069b: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_071f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0744: Unknown result type (might be due to invalid IL or missing references)
		//IL_0759: Unknown result type (might be due to invalid IL or missing references)
		//IL_076e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0783: Unknown result type (might be due to invalid IL or missing references)
		//IL_0797: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_07bd: Expected O, but got Unknown
		//IL_07d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_07fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0812: Unknown result type (might be due to invalid IL or missing references)
		//IL_0826: Unknown result type (might be due to invalid IL or missing references)
		//IL_0842: Unknown result type (might be due to invalid IL or missing references)
		//IL_084c: Expected O, but got Unknown
		if ((Object)(object)_uiRoot != (Object)null || (Object)(object)UIRoot.instance == (Object)null || (Object)(object)UIRoot.instance.uiGame == (Object)null)
		{
			return;
		}
		_uiFont = FindAnyUiFont(((Component)UIRoot.instance.uiGame).gameObject) ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
		RectTransform windowGroup = UIRoot.instance.uiGame.windowGroup;
		_uiRoot = new GameObject("HelloDSP_VeinGuide_UI", new Type[1] { typeof(RectTransform) });
		_uiRoot.transform.SetParent((Transform)(object)windowGroup, false);
		RectTransform component = _uiRoot.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0.5f, 0.5f);
		component.anchorMax = new Vector2(0.5f, 0.5f);
		component.pivot = new Vector2(0.5f, 0.5f);
		component.sizeDelta = new Vector2(820f, 380f);
		component.anchoredPosition = Vector2.zero;
		((Graphic)_uiRoot.AddComponent<Image>()).color = new Color(0.05f, 0.08f, 0.14f, 0.92f);
		Text obj = CreateText(_uiRoot.transform, "Title", "矿物指引", 18, (FontStyle)1, new Color(0.92f, 0.96f, 1f, 1f));
		obj.alignment = (TextAnchor)0;
		RectTransform rectTransform = ((Graphic)obj).rectTransform;
		rectTransform.anchorMin = new Vector2(0f, 1f);
		rectTransform.anchorMax = new Vector2(1f, 1f);
		rectTransform.pivot = new Vector2(0f, 1f);
		rectTransform.anchoredPosition = new Vector2(16f, -14f);
		rectTransform.sizeDelta = new Vector2(-100f, 28f);
		_btnClose = CreateButton(_uiRoot.transform, "BtnClose", "关闭", new Vector2(64f, 28f));
		RectTransform component2 = ((Component)_btnClose).GetComponent<RectTransform>();
		component2.anchorMin = new Vector2(1f, 1f);
		component2.anchorMax = new Vector2(1f, 1f);
		component2.pivot = new Vector2(1f, 1f);
		component2.anchoredPosition = new Vector2(-12f, -10f);
		component2.sizeDelta = new Vector2(64f, 28f);
		((UnityEvent)_btnClose.onClick).AddListener((UnityAction)delegate
		{
			_uiRoot.SetActive(false);
		});
		((Graphic)CreateText(_uiRoot.transform, "OreLabel", "矿种:", 14, (FontStyle)0, new Color(0.75f, 0.82f, 0.92f, 1f))).rectTransform.SetAnchors(new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -52f), new Vector2(60f, 20f));
		((Graphic)CreateText(_uiRoot.transform, "ScopeLabel", "范围:", 14, (FontStyle)0, new Color(0.75f, 0.82f, 0.92f, 1f))).rectTransform.SetAnchors(new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -130f), new Vector2(60f, 20f));
		((Graphic)CreateText(_uiRoot.transform, "ModeLabel", "连线:", 14, (FontStyle)0, new Color(0.75f, 0.82f, 0.92f, 1f))).rectTransform.SetAnchors(new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -170f), new Vector2(60f, 20f));
		_btnScopeAll = CreateButton(_uiRoot.transform, "ScopeAll", "全部", new Vector2(90f, 28f));
		_btnScopeUnworked = CreateButton(_uiRoot.transform, "ScopeUnworked", "未挖", new Vector2(90f, 28f));
		_btnScopeMissed = CreateButton(_uiRoot.transform, "ScopeMissed", "漏挖", new Vector2(90f, 28f));
		PlaceRowButtons((Button[])(object)new Button[3] { _btnScopeAll, _btnScopeUnworked, _btnScopeMissed }, 86f, -134f);
		((UnityEvent)_btnScopeAll.onClick).AddListener((UnityAction)delegate
		{
			_scope = VeinScope.All;
			UpdateButtonStates();
			ApplyGuide();
		});
		((UnityEvent)_btnScopeUnworked.onClick).AddListener((UnityAction)delegate
		{
			_scope = VeinScope.Unworked;
			UpdateButtonStates();
			ApplyGuide();
		});
		((UnityEvent)_btnScopeMissed.onClick).AddListener((UnityAction)delegate
		{
			_scope = VeinScope.Missed;
			UpdateButtonStates();
			ApplyGuide();
		});
		_btnModeGroups = CreateButton(_uiRoot.transform, "ModeGroups", "矿簇", new Vector2(90f, 28f));
		_btnModeVeins = CreateButton(_uiRoot.transform, "ModeVeins", "矿点", new Vector2(90f, 28f));
		PlaceRowButtons((Button[])(object)new Button[2] { _btnModeGroups, _btnModeVeins }, 86f, -174f);
		((UnityEvent)_btnModeGroups.onClick).AddListener((UnityAction)delegate
		{
			_mode = VeinLinkMode.Groups;
			UpdateButtonStates();
			ApplyGuide();
		});
		((UnityEvent)_btnModeVeins.onClick).AddListener((UnityAction)delegate
		{
			_mode = VeinLinkMode.Veins;
			UpdateButtonStates();
			ApplyGuide();
		});
		_statusText = CreateText(_uiRoot.transform, "Status", "", 13, (FontStyle)0, new Color(0.86f, 0.9f, 0.98f, 1f));
		_statusText.alignment = (TextAnchor)0;
		RectTransform component3 = ((Component)_statusText).GetComponent<RectTransform>();
		component3.anchorMin = new Vector2(0f, 0f);
		component3.anchorMax = new Vector2(1f, 0f);
		component3.pivot = new Vector2(0f, 0f);
		component3.anchoredPosition = new Vector2(18f, 54f);
		component3.sizeDelta = new Vector2(-36f, 44f);
		_btnApply = CreateButton(_uiRoot.transform, "Apply", "显示指引", new Vector2(120f, 34f));
		_btnClear = CreateButton(_uiRoot.transform, "Clear", "清除指引", new Vector2(120f, 34f));
		RectTransform component4 = ((Component)_btnApply).GetComponent<RectTransform>();
		component4.anchorMin = new Vector2(0f, 0f);
		component4.anchorMax = new Vector2(0f, 0f);
		component4.pivot = new Vector2(0f, 0f);
		component4.anchoredPosition = new Vector2(18f, 18f);
		component4.sizeDelta = new Vector2(120f, 34f);
		((UnityEvent)_btnApply.onClick).AddListener(new UnityAction(ApplyGuide));
		RectTransform component5 = ((Component)_btnClear).GetComponent<RectTransform>();
		component5.anchorMin = new Vector2(0f, 0f);
		component5.anchorMax = new Vector2(0f, 0f);
		component5.pivot = new Vector2(0f, 0f);
		component5.anchoredPosition = new Vector2(150f, 18f);
		component5.sizeDelta = new Vector2(120f, 34f);
		((UnityEvent)_btnClear.onClick).AddListener((UnityAction)delegate
		{
			ClearRays();
			UpdateStatus();
			MainThreadDispatcher.Enqueue(delegate
			{
				InGameNotifier.Info("已清除指引");
			});
		});
		_uiRoot.SetActive(false);
	}

	private void ApplyGuide()
	{
		try
		{
			if (!GameMain.isRunning || GameMain.localPlanet == null)
			{
				MainThreadDispatcher.Enqueue(delegate
				{
					InGameNotifier.Warning("当前不在星球上,无法指引矿物");
				});
				return;
			}
			BuildTargets(GameMain.localPlanet);
			EnsureRayRoot();
			EnsureLineRenderers();
			_raysActive = _targets.Count > 0;
			_nextRaysRefreshTime = Time.time + 3f;
			UpdateStatus();
			if (_targets.Count == 0)
			{
				MainThreadDispatcher.Enqueue(delegate
				{
					InGameNotifier.Warning("未找到符合条件的矿物");
				});
			}
			else
			{
				MainThreadDispatcher.Enqueue(delegate
				{
					InGameNotifier.Info($"已显示 {_targets.Count} 条指引线");
				});
			}
		}
		catch (Exception arg)
		{
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogWarning((object)$"VeinGuide.ApplyGuide exception: {arg}");
			}
			MainThreadDispatcher.Enqueue(delegate
			{
				InGameNotifier.Warning("指引失败");
			});
		}
	}

	private void BuildTargets(PlanetData planet)
	{
		//IL_0096: 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_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Unknown result type (might be due to invalid IL or missing references)
		//IL_0388: Unknown result type (might be due to invalid IL or missing references)
		//IL_038a: Unknown result type (might be due to invalid IL or missing references)
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0396: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d7: 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_016f: 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)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0336: Unknown result type (might be due to invalid IL or missing references)
		//IL_033e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0342: 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_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0405: Unknown result type (might be due to invalid IL or missing references)
		//IL_040c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0413: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0434: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_0442: Unknown result type (might be due to invalid IL or missing references)
		//IL_044c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: 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_0211: 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_022f: Unknown result type (might be due to invalid IL or missing references)
		_targets.Clear();
		PlanetFactory factory = planet.factory;
		VeinData[] array;
		int num;
		bool planningKnown;
		if (factory != null)
		{
			array = factory.veinPool;
			num = factory.veinCursor;
			planningKnown = true;
		}
		else
		{
			array = planet.runtimeVeinPool;
			num = planet.runtimeVeinCursor;
			planningKnown = false;
		}
		if (array == null || num <= 1)
		{
			return;
		}
		int num2 = Math.Min(num, array.Length);
		Dictionary<int, HashSet<int>> groupMinerIds = new Dictionary<int, HashSet<int>>();
		Dictionary<int, bool> groupHasUncovered = new Dictionary<int, bool>();
		Dictionary<int, Vector3> dictionary = new Dictionary<int, Vector3>();
		Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
		Dictionary<int, string> dictionary3 = new Dictionary<int, string>();
		for (int i = 1; i < num2; i++)
		{
			VeinData val = array[i];
			if ((int)val.type == 0 || val.amount <= 0)
			{
				continue;
			}
			string text = ((object)(EVeinType)(ref val.type)).ToString();
			if (!string.IsNullOrEmpty(_selectedOre) && !string.Equals(_selectedOre, text, StringComparison.Ordinal))
			{
				continue;
			}
			int groupIndex2 = val.groupIndex;
			if (groupIndex2 <= 0)
			{
				continue;
			}
			if (!dictionary3.ContainsKey(groupIndex2))
			{
				dictionary3[groupIndex2] = text;
			}
			dictionary[groupIndex2] = (dictionary.TryGetValue(groupIndex2, out var value) ? (value + val.pos) : val.pos);
			dictionary2[groupIndex2] = ((!dictionary2.TryGetValue(groupIndex2, out var value2)) ? 1 : (value2 + 1));
			if (((factory != null) ? VeinMiningUtil.CountRealMiners(factory, val.minerId0, val.minerId1, val.minerId2, val.minerId3) : val.minerCount) <= 0)
			{
				groupHasUncovered[groupIndex2] = true;
			}
			if (!groupMinerIds.TryGetValue(groupIndex2, out var value3))
			{
				value3 = new HashSet<int>();
				groupMinerIds[groupIndex2] = value3;
			}
			if (factory != null)
			{
				if (VeinMiningUtil.IsRealMinerEntity(factory, val.minerId0))
				{
					value3.Add(val.minerId0);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, val.minerId1))
				{
					value3.Add(val.minerId1);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, val.minerId2))
				{
					value3.Add(val.minerId2);
				}
				if (VeinMiningUtil.IsRealMinerEntity(factory, val.minerId3))
				{
					value3.Add(val.minerId3);
				}
			}
			else
			{
				if (val.minerId0 > 0)
				{
					value3.Add(val.minerId0);
				}
				if (val.minerId1 > 0)
				{
					value3.Add(val.minerId1);
				}
				if (val.minerId2 > 0)
				{
					value3.Add(val.minerId2);
				}
				if (val.minerId3 > 0)
				{
					value3.Add(val.minerId3);
				}
			}
		}
		int num3 = ((_mode == VeinLinkMode.Veins) ? 180 : 220);
		if (_mode == VeinLinkMode.Groups)
		{
			foreach (KeyValuePair<int, Vector3> item in dictionary)
			{
				if (_targets.Count >= num3)
				{
					break;
				}
				int key = item.Key;
				if (FilterGroup(key))
				{
					int value4;
					int val2 = ((!dictionary2.TryGetValue(key, out value4)) ? 1 : value4);
					Vector3 val3 = item.Value / (float)Math.Max(1, val2);
					_targets.Add(val3 + ((Vector3)(ref val3)).normalized * 6f);
				}
			}
			return;
		}
		for (int j = 1; j < num2; j++)
		{
			if (_targets.Count >= num3)
			{
				break;
			}
			VeinData val4 = array[j];
			if ((int)val4.type == 0 || val4.amount <= 0)
			{
				continue;
			}
			string b = ((object)(EVeinType)(ref val4.type)).ToString();
			if (!string.IsNullOrEmpty(_selectedOre) && !string.Equals(_selectedOre, b, StringComparison.Ordinal))
			{
				continue;
			}
			int groupIndex3 = val4.groupIndex;
			if (groupIndex3 > 0 && FilterGroup(groupIndex3))
			{
				int num4 = ((factory != null) ? VeinMiningUtil.CountRealMiners(factory, val4.minerId0, val4.minerId1, val4.minerId2, val4.minerId3) : val4.minerCount);
				if (_scope == VeinScope.All || num4 <= 0)
				{
					_targets.Add(val4.pos + ((Vector3)(ref val4.pos)).normalized * 4f);
				}
			}
		}
		bool FilterGroup(int groupIndex)
		{
			bool value5;
			bool flag = groupHasUncovered.TryGetValue(groupIndex, out value5) && value5;
			HashSet<int> value6;
			bool flag2 = ((groupMinerIds.TryGetValue(groupIndex, out value6) && value6.Count != 0) ? 1 : 0) > (false ? 1 : 0);
			if (_scope == VeinScope.Unworked)
			{
				return planningKnown && !flag2 && flag;
			}
			if (_scope == VeinScope.Missed)
			{
				return planningKnown && flag2 && flag;
			}
			return true;
		}
	}

	private void EnsureRayRoot()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_rayRoot != (Object)null))
		{
			_rayRoot = new GameObject("HelloDSP_VeinGuide_Rays");
			Object.DontDestroyOnLoad((Object)(object)_rayRoot);
			Shader val = Shader.Find("Legacy Shaders/Particles/Additive");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Color");
			}
			_rayMaterial = new Material(val);
			_rayMaterial.color = new Color(0.2f, 0.9f, 1f, 0.6f);
		}
	}

	private void EnsureLineRenderers()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: 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_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_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Expected O, but got Unknown
		int count = _targets.Count;
		while (_lines.Count < count)
		{
			int count2 = _lines.Count;
			GameObject val = new GameObject($"HelloDSP_Ray_{count2}");
			val.transform.SetParent(_rayRoot.transform, false);
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.positionCount = 14;
			((Renderer)val2).material = _rayMaterial;
			val2.useWorldSpace = true;
			val2.numCapVertices = 4;
			val2.numCornerVertices = 4;
			val2.widthMultiplier = 0.9f;
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val2).receiveShadows = false;
			((Renderer)val2).motionVectorGenerationMode = (MotionVectorGenerationMode)2;
			val2.widthCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
			{
				new Keyframe(0f, 0.18f),
				new Keyframe(0.25f, 0.54f),
				new Keyframe(1f, 0.14f)
			});
			_lines.Add(val2);
		}
		for (int i = 0; i < _lines.Count; i++)
		{
			bool active = i < count;
			if ((Object)(object)_lines[i] != (Object)null)
			{
				((Component)_lines[i]).gameObject.SetActive(active);
			}
		}
	}

	private void ClearRays()
	{
		_targets.Clear();
		_raysActive = false;
		for (int i = 0; i < _lines.Count; i++)
		{
			if ((Object)(object)_lines[i] != (Object)null)
			{
				((Component)_lines[i]).gameObject.SetActive(false);
			}
		}
	}

	private void BuildOreButtons()
	{
		for (int i = 0; i < _oreButtons.Count; i++)
		{
			if ((Object)(object)_oreButtons[i] != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_oreButtons[i]).gameObject);
			}
		}
		_oreButtons.Clear();
		_oreByButton.Clear();
		if ((Object)(object)_uiRoot == (Object)null || GameMain.localPlanet == null)
		{
			return;
		}
		List<string> list = CollectOreTypes(GameMain.localPlanet);
		list.Sort(StringComparer.Ordinal);
		Dictionary<string, (string, int)> dictionary = new Dictionary<string, (string, int)>(StringComparer.Ordinal);
		for (int j = 0; j < list.Count; j++)
		{
			string text = list[j];
			string key = VeinTypeToZh(text);
			if (!dictionary.TryGetValue(key, out var value))
			{
				dictionary[key] = (text, j);
			}
			else if ((string.Equals(text, "Crysrub", StringComparison.Ordinal) && string.Equals(value.Item1, "Bamboo", StringComparison.Ordinal)) || (string.Equals(text, "Silicon", StringComparison.Ordinal) && string.Equals(value.Item1, "Silicium", StringComparison.Ordinal)) || (string.Equals(text, "Kimberlite", StringComparison.Ordinal) && string.Equals(value.Item1, "Diamond", StringComparison.Ordinal)))
			{
				dictionary[key] = (text, value.Item2);
			}
		}
		List<(string, string, int)> list2 = new List<(string, string, int)>();
		foreach (KeyValuePair<string, (string, int)> item in dictionary)
		{
			list2.Add((item.Value.Item1, item.Key, item.Value.Item2));
		}
		list2.Sort(((string type, string label, int order) a, (string type, string label, int order) b) => a.order.CompareTo(b.order));
		float num = 86f;
		float y = -56f;
		float x = num;
		float maxX = 800f;
		float rowH = 34f;
		CreateOreButton("", "全部", ref x, ref y, num, maxX, rowH);
		for (int k = 0; k < list2.Count; k++)
		{
			CreateOreButton(list2[k].Item1, list2[k].Item2, ref x, ref y, num, maxX, rowH);
		}
	}

	private void CreateOreButton(string type, string label, ref float x, ref float y, float startX, float maxX, float rowH)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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_0107: Expected O, but got Unknown
		Button val = CreateButton(_uiRoot.transform, "Ore_" + type, label, new Vector2(88f, 28f));
		_oreButtons.Add(val);
		_oreByButton[val] = type;
		RectTransform component = ((Component)val).GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0f, 1f);
		component.anchorMax = new Vector2(0f, 1f);
		component.pivot = new Vector2(0f, 1f);
		component.anchoredPosition = new Vector2(x, y);
		component.sizeDelta = new Vector2(88f, 28f);
		x += 96f;
		if (x + 88f > maxX)
		{
			x = startX;
			y -= rowH;
		}
		((UnityEvent)val.onClick).AddListener((UnityAction)delegate
		{
			_selectedOre = type;
			UpdateButtonStates();
			ApplyGuide();
		});
	}

	private void UpdateButtonStates()
	{
		SetButtonSelected(_btnScopeAll, _scope == VeinScope.All);
		SetButtonSelected(_btnScopeUnworked, _scope == VeinScope.Unworked);
		SetButtonSelected(_btnScopeMissed, _scope == VeinScope.Missed);
		SetButtonSelected(_btnModeGroups, _mode == VeinLinkMode.Groups);
		SetButtonSelected(_btnModeVeins, _mode == VeinLinkMode.Veins);
		foreach (KeyValuePair<Button, string> item in _oreByButton)
		{
			SetButtonSelected(item.Key, string.Equals(item.Value, _selectedOre, StringComparison.Ordinal));
		}
	}

	private void UpdateStatus()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		if ((Object)(object)_statusText == (Object)null)
		{
			return;
		}
		int count = _targets.Count;
		string text = "未知";
		try
		{
			if (GameMain.mainPlayer != null)
			{
				Vector3 position = GameMain.mainPlayer.position;
				text = "(" + (int)Math.Round(position.x) + "," + (int)Math.Round(position.y) + "," + (int)Math.Round(position.z) + ")";
			}
		}
		catch
		{
		}
		_statusText.text = "玩家坐标:" + text + "\n指引线数:" + count + "条";
	}

	private static List<string> CollectOreTypes(PlanetData planet)
	{
		//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_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
		VeinData[] array;
		int num;
		if (planet.factory != null)
		{
			array = planet.factory.veinPool;
			num = planet.factory.veinCursor;
		}
		else
		{
			array = planet.runtimeVeinPool;
			num = planet.runtimeVeinCursor;
		}
		if (array == null || num <= 1)
		{
			return new List<string>();
		}
		int num2 = Math.Min(num, array.Length);
		for (int i = 1; i < num2; i++)
		{
			VeinData val = array[i];
			if ((int)val.type != 0 && val.amount > 0)
			{
				hashSet.Add(((object)(EVeinType)(ref val.type)).ToString());
			}
		}
		return new List<string>(hashSet);
	}

	private static string VeinTypeToZh(string veinType)
	{
		return veinType switch
		{
			"Iron" => "铁", 
			"Copper" => "铜", 
			"Stone" => "石矿", 
			"Coal" => "煤", 
			"Silicium" => "硅石", 
			"Silicon" => "硅石", 
			"Titanium" => "钛", 
			"Oil" => "原油", 
			"Fireice" => "可燃冰", 
			"Fractal" => "分形硅石", 
			"Kimberlite" => "金伯利矿石", 
			"Diamond" => "金伯利矿石", 
			"Bamboo" => "刺笋结晶", 
			"Crysrub" => "刺笋结晶", 
			"Grat" => "光栅石", 
			"Mag" => "磁铁矿", 
			_ => veinType, 
		};
	}

	private static void PlaceRowButtons(Button[] buttons, float startX, float y)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		float num = startX;
		for (int i = 0; i < buttons.Length; i++)
		{
			RectTransform component = ((Component)buttons[i]).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(num, y);
			component.sizeDelta = new Vector2(90f, 28f);
			num += 98f;
		}
	}

	private static void SetButtonSelected(Button btn, bool selected)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)btn))
		{
			Image component = ((Component)btn).GetComponent<Image>();
			if (Object.op_Implicit((Object)(object)component))
			{
				((Graphic)component).color = (selected ? new Color(0.13f, 0.42f, 0.62f, 0.92f) : new Color(0.12f, 0.16f, 0.24f, 0.85f));
			}
		}
	}

	private static Font FindAnyUiFont(GameObject root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return null;
		}
		try
		{
			Text[] componentsInChildren = root.GetComponentsInChildren<Text>(true);
			if (componentsInChildren == null)
			{
				return null;
			}
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)componentsInChildren[i].font != (Object)null)
				{
					return componentsInChildren[i].font;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private Text CreateText(Transform parent, string name, string text, int fontSize, FontStyle style, Color color)
	{
		//IL_0014: 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_0047: 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)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		Text obj = val.AddComponent<Text>();
		obj.text = text;
		obj.font = _uiFont;
		obj.fontSize = fontSize;
		obj.fontStyle = style;
		((Graphic)obj).color = color;
		((Graphic)obj).raycastTarget = false;
		return obj;
	}

	private Button CreateButton(Transform parent, string name, string label, Vector2 size)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		Image val2 = val.AddComponent<Image>();
		((Graphic)val2).color = new Color(0.12f, 0.16f, 0.24f, 0.85f);
		Button obj = val.AddComponent<Button>();
		((Selectable)obj).targetGraphic = (Graphic)(object)val2;
		val.GetComponent<RectTransform>().sizeDelta = size;
		Text obj2 = CreateText(val.transform, "Text", label, 13, (FontStyle)0, new Color(0.9f, 0.94f, 1f, 1f));
		obj2.alignment = (TextAnchor)4;
		RectTransform rectTransform = ((Graphic)obj2).rectTransform;
		rectTransform.anchorMin = Vector2.zero;
		rectTransform.anchorMax = Vector2.one;
		rectTransform.offsetMin = Vector2.zero;
		rectTransform.offsetMax = Vector2.zero;
		return obj;
	}
}
internal static class RectTransformExt
{
	public static RectTransform SetAnchors(this RectTransform rt, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 anchoredPos, Vector2 size)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		rt.anchorMin = anchorMin;
		rt.anchorMax = anchorMax;
		rt.pivot = pivot;
		rt.anchoredPosition = anchoredPos;
		rt.sizeDelta = size;
		return rt;
	}
}