Decompiled source of PING v0.9.10
plugins/PingMod.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.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