using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using VeinProtector.Core;
using VeinProtector.Patches;
[assembly: AssemblyInformationalVersion("0.5.1")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyProduct("VeinProtector")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyFileVersion("0.5.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyTitle("VeinProtector")]
[assembly: AssemblyVersion("0.5.1.0")]
namespace VeinProtector
{
[BepInPlugin("skye.dsp.veinprotector", "VeinProtector", "0.5.1")]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "skye.dsp.veinprotector";
public const string PluginName = "VeinProtector";
public const string PluginVersion = "0.5.1";
internal static ConfigEntry<bool> ProtectionEnabled;
internal static ManualLogSource Log;
private static ConfigFile _configFile;
internal static Plugin Instance { get; private set; }
internal static bool IsProtectionEnabled
{
get
{
if (ProtectionEnabled != null)
{
return ProtectionEnabled.Value;
}
return true;
}
}
private void Awake()
{
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
_configFile = ((BaseUnityPlugin)this).Config;
ProtectionEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Vein Protection", "Enabled", true, "Keep ordinary solid veins at one remaining unit. Toggle this from DSP Settings.");
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded");
((BaseUnityPlugin)this).Logger.LogInfo((object)"Version = 0.5.1");
((BaseUnityPlugin)this).Logger.LogInfo((object)("ProtectionEnabled = " + ProtectionEnabled.Value));
ApplyPatch("skye.dsp.veinprotector.OptionsToggle", typeof(OptionsProtectionTogglePatch), AccessTools.Method(typeof(UIOptionWindow), "_OnOpen", Type.EmptyTypes, (Type[])null), "UIOptionWindow._OnOpen options toggle");
ApplyPatch("skye.dsp.veinprotector.MinerGuard", typeof(MinerAllProtectedPrefixPatch), GetInternalUpdateMethod(), "MinerComponent.InternalUpdate protection Prefix");
ApplyPatch("skye.dsp.veinprotector.MinerLogic", typeof(MinerProtectionTranspilerPatch), GetInternalUpdateMethod(), "MinerComponent.InternalUpdate protection Transpiler");
ApplyPatch("skye.dsp.veinprotector.MinerUI", typeof(UIMinerWindowPatch), AccessTools.Method(typeof(UIMinerWindow), "_OnUpdate", Type.EmptyTypes, (Type[])null), "UIMinerWindow._OnUpdate");
ApplyPatch("skye.dsp.veinprotector.CollectorUI", typeof(UIVeinCollectorPanelPatch), AccessTools.Method(typeof(UIVeinCollectorPanel), "_OnUpdate", Type.EmptyTypes, (Type[])null), "UIVeinCollectorPanel._OnUpdate");
ApplyPatch("skye.dsp.veinprotector.ReferenceDetails", typeof(ReferenceSpeedDetailExtensionPatch), AccessTools.Method(typeof(UIReferenceSpeedTip), "SetTip", (Type[])null, (Type[])null), "UIReferenceSpeedTip.SetTip read-only detail extension");
if (!MinerProtectionTranspilerPatch.TimeMultiplierPatched || !MinerProtectionTranspilerPatch.ProtectedVeinSkipPatched || !MinerProtectionTranspilerPatch.CostBoundaryPatched || !UIMinerWindowPatch.SpeedMultiplierPatched)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Protection transpiler patch points incomplete: mining-rate=" + MinerProtectionTranspilerPatch.TimeMultiplierPatched + ", vein-skip=" + MinerProtectionTranspilerPatch.ProtectedVeinSkipPatched + ", cost-boundary=" + MinerProtectionTranspilerPatch.CostBoundaryPatched + ", miner-UI=" + UIMinerWindowPatch.SpeedMultiplierPatched));
}
if (!UIVeinCollectorPanelPatch.SpeedMultiplierPatched)
{
((BaseUnityPlugin)this).Logger.LogError((object)"Advanced miner detail speed multiplier patch point was not found; vanilla UI is retained");
}
if (IsUxAssistLoaded())
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"UXAssist also contains a vein-protection feature. Do not enable both vein-protection implementations simultaneously.");
}
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
internal static void SetProtectionEnabled(bool enabled)
{
if (ProtectionEnabled != null && ProtectionEnabled.Value != enabled)
{
ProtectionEnabled.Value = enabled;
if (_configFile != null)
{
_configFile.Save();
}
}
}
internal static void LogError(string message)
{
if (Log != null)
{
Log.LogError((object)message);
}
}
internal static void LogWarning(string message)
{
if (Log != null)
{
Log.LogWarning((object)message);
}
}
private static MethodInfo GetInternalUpdateMethod()
{
return AccessTools.Method(typeof(MinerComponent), "InternalUpdate", new Type[6]
{
typeof(PlanetFactory),
typeof(VeinData[]),
typeof(float),
typeof(float),
typeof(float),
typeof(int[])
}, (Type[])null);
}
private bool ApplyPatch(string owner, Type patchClass, MethodBase target, string description)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
try
{
if (target == null)
{
throw new MissingMethodException("Target method was not found: " + description);
}
Harmony val = new Harmony(owner);
val.CreateClassProcessor(patchClass).Patch();
Patches patchInfo = Harmony.GetPatchInfo(target);
bool flag = patchInfo != null && patchInfo.Owners.Contains(owner);
if (!flag)
{
((BaseUnityPlugin)this).Logger.LogError((object)(description + " patch was not found in Harmony patch info"));
}
return flag;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to install " + description + " patch: " + ex));
return false;
}
}
private static bool IsUxAssistLoaded()
{
foreach (PluginInfo value in Chainloader.PluginInfos.Values)
{
if (value.Metadata.Name.IndexOf("UXAssist", StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
}
}
namespace VeinProtector.Core
{
internal static class VeinProtectionLogic
{
internal const int KeepVeinAmount = 1;
internal static bool IsSupportedProtectedResourceItem(int itemId)
{
if (itemId <= 0 || (Object)(object)LDB.veins == (Object)null)
{
return false;
}
int num = 15;
for (int i = 1; i < num; i++)
{
if (i != 7)
{
VeinProto val = ((ProtoSet<VeinProto>)(object)LDB.veins).Select(i);
if (val != null && IsSupportedProtectedVeinPrototype(itemId, i, val.MiningItem))
{
return true;
}
}
}
return false;
}
internal static bool IsSupportedProtectedVeinPrototype(int itemId, int veinTypeId, int miningItemId)
{
if (itemId > 0 && miningItemId == itemId && veinTypeId > 0 && veinTypeId < 15)
{
return veinTypeId != 7;
}
return false;
}
internal static bool ShouldShowReferenceExtension(bool protectionEnabled, int itemId, bool supportedVeinItem)
{
if (protectionEnabled && itemId > 0)
{
return supportedVeinItem;
}
return false;
}
internal static double CalculateReferenceSpeedLoss(double baseReferenceSpeed, int physicalCount, int effectiveCount)
{
if (baseReferenceSpeed <= 0.0 || physicalCount <= effectiveCount)
{
return 0.0;
}
return baseReferenceSpeed * (double)(physicalCount - effectiveCount);
}
internal static bool AddProtectedVeinId(HashSet<int> protectedVeinIds, int veinId)
{
if (protectedVeinIds != null && veinId > 0)
{
return protectedVeinIds.Add(veinId);
}
return false;
}
internal static float CalculateProtectedReferenceSpeed(bool protectionEnabled, float miningRate, float vanillaTotal, double protectionLoss)
{
if (!protectionEnabled || miningRate <= 0f || protectionLoss <= 0.0)
{
return vanillaTotal;
}
return Math.Max(0f, (float)((double)vanillaTotal - protectionLoss));
}
internal static IEnumerable<PlanetFactory> EnumerateFactoriesForAstroFilter(GameData data, int astroFilter)
{
if (data == null || data.factories == null || data.factoryCount <= 0)
{
yield break;
}
int factoryLimit = Math.Min(data.factoryCount, data.factories.Length);
HashSet<int> yieldedFactoryIds = new HashSet<int>();
switch (astroFilter)
{
case -1:
{
for (int i = 0; i < factoryLimit; i++)
{
PlanetFactory factory = data.factories[i];
if (IsActualFactory(factory, factoryLimit) && yieldedFactoryIds.Add(factory.index))
{
yield return factory;
}
}
break;
}
case 0:
{
PlanetData localPlanet = data.localPlanet;
if (localPlanet != null)
{
PlanetFactory localFactory = localPlanet.factory;
if (IsActualFactory(localFactory, factoryLimit) && yieldedFactoryIds.Add(localFactory.index))
{
yield return localFactory;
}
break;
}
goto default;
}
default:
if (astroFilter % 100 == 0)
{
StarData star = ((astroFilter == 0) ? data.localStar : ((data.galaxy == null) ? null : data.galaxy.StarById(astroFilter / 100)));
if (star == null || star.planets == null)
{
break;
}
int planetLimit = Math.Min(star.planetCount, star.planets.Length);
for (int j = 0; j < planetLimit; j++)
{
PlanetFactory factory2 = star.planets[j]?.factory;
if (IsActualFactory(factory2, factoryLimit) && yieldedFactoryIds.Add(factory2.index))
{
yield return factory2;
}
}
}
else
{
PlanetFactory selectedFactory = ((data.galaxy == null) ? null : data.galaxy.PlanetById(astroFilter))?.factory;
if (IsActualFactory(selectedFactory, factoryLimit) && yieldedFactoryIds.Add(selectedFactory.index))
{
yield return selectedFactory;
}
}
break;
}
}
private static bool IsActualFactory(PlanetFactory factory, int factoryLimit)
{
if (factory != null && factory.index >= 0)
{
return factory.index < factoryLimit;
}
return false;
}
internal static int GetEffectiveVeinCount(MinerComponent miner, VeinData[] veinPool, float miningRate)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
if (!Plugin.IsProtectionEnabled || (int)miner.type != 2 || miningRate <= 0f)
{
return miner.veinCount;
}
if (miner.minimumVeinAmount > 1)
{
return miner.veinCount;
}
if (veinPool == null || miner.veins == null)
{
return 0;
}
int num = 0;
int num2 = Math.Min(miner.veinCount, miner.veins.Length);
for (int i = 0; i < num2; i++)
{
int num3 = miner.veins[i];
if (num3 > 0 && num3 < veinPool.Length && veinPool[num3].id != 0 && veinPool[num3].amount > 1)
{
num++;
}
}
return num;
}
internal static int GetProductionTickCount(MinerComponent miner, VeinData[] veinPool, float miningRate)
{
//IL_0000: 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_0015: Invalid comparison between Unknown and I4
int effectiveVeinCount = GetEffectiveVeinCount(miner, veinPool, miningRate);
if (effectiveVeinCount > 0 || (int)miner.type != 2 || miningRate <= 0f || veinPool == null || miner.veins == null)
{
return effectiveVeinCount;
}
int num = Math.Min(miner.veinCount, miner.veins.Length);
for (int i = 0; i < num; i++)
{
int num2 = miner.veins[i];
if (num2 <= 0 || num2 >= veinPool.Length || veinPool[num2].id == 0 || veinPool[num2].amount <= 0)
{
return miner.veinCount;
}
}
return 0;
}
internal static int GetEffectiveVeinCount(MinerComponent miner, VeinData[] veinPool, PlanetFactory factory)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
float miningRate = 0f;
if (factory != null && factory.gameData != null && factory.gameData.history != null)
{
miningRate = factory.gameData.history.miningCostRate;
}
return GetEffectiveVeinCount(miner, veinPool, miningRate);
}
internal static int GetEffectiveVeinCount(MinerComponent miner, PlanetFactory factory)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return GetEffectiveVeinCount(miner, factory?.veinPool, factory);
}
internal static bool IsProtectedVein(MinerComponent miner, VeinData[] veinPool, float miningRate, int veinId)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
return Plugin.IsProtectionEnabled && (int)miner.type == 2 && miningRate > 0f && veinPool != null && veinId > 0 && veinId < veinPool.Length && veinPool[veinId].id != 0 && veinPool[veinId].amount == 1;
}
internal static int GetMaxAllowedCost(int amount, MinerComponent miner, float miningRate)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
if (!Plugin.IsProtectionEnabled || (int)miner.type != 2 || !(miningRate > 0f) || amount <= 1)
{
return amount;
}
return amount - 1;
}
internal static void AdvanceCurrentVein(ref MinerComponent miner)
{
int veinCount = miner.veinCount;
if (veinCount <= 0)
{
miner.currentVeinIndex = 0;
return;
}
int num = miner.currentVeinIndex + 1;
miner.currentVeinIndex = ((num < veinCount) ? num : 0);
}
internal static bool AreAllBoundVeinsProtected(MinerComponent miner, VeinData[] veinPool, float miningRate)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
if (!Plugin.IsProtectionEnabled || (int)miner.type != 2 || miningRate <= 0f || miner.veinCount <= 0 || veinPool == null || miner.veins == null)
{
return false;
}
int num = Math.Min(miner.veinCount, miner.veins.Length);
if (num == 0)
{
return false;
}
for (int i = 0; i < num; i++)
{
int num2 = miner.veins[i];
if (num2 <= 0 || num2 >= veinPool.Length || veinPool[num2].id == 0 || veinPool[num2].amount != 1)
{
return false;
}
}
return num == miner.veinCount;
}
}
}
namespace VeinProtector.Patches
{
[HarmonyPatch]
internal static class MinerProtectionTranspilerPatch
{
private static readonly MethodInfo ProductionTickCountMethod = AccessTools.Method(typeof(VeinProtectionLogic), "GetProductionTickCount", new Type[3]
{
typeof(MinerComponent),
typeof(VeinData[]),
typeof(float)
}, (Type[])null);
private static readonly MethodInfo ProtectedVeinMethod = AccessTools.Method(typeof(VeinProtectionLogic), "IsProtectedVein", (Type[])null, (Type[])null);
private static readonly MethodInfo AdvanceMethod = AccessTools.Method(typeof(VeinProtectionLogic), "AdvanceCurrentVein", (Type[])null, (Type[])null);
private static readonly MethodInfo MaxAllowedCostMethod = AccessTools.Method(typeof(VeinProtectionLogic), "GetMaxAllowedCost", (Type[])null, (Type[])null);
internal static bool TimeMultiplierPatched;
internal static bool ProtectedVeinSkipPatched;
internal static bool CostBoundaryPatched;
[HarmonyTargetMethod]
private static MethodInfo TargetMethod()
{
return AccessTools.Method(typeof(MinerComponent), "InternalUpdate", new Type[6]
{
typeof(PlanetFactory),
typeof(VeinData[]),
typeof(float),
typeof(float),
typeof(float),
typeof(int[])
}, (Type[])null);
}
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Expected O, but got Unknown
//IL_0356: Unknown result type (might be due to invalid IL or missing references)
//IL_035c: Expected O, but got Unknown
//IL_0365: Unknown result type (might be due to invalid IL or missing references)
//IL_036b: Expected O, but got Unknown
//IL_0379: Unknown result type (might be due to invalid IL or missing references)
//IL_037f: Expected O, but got Unknown
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
//IL_038e: Expected O, but got Unknown
//IL_039b: Unknown result type (might be due to invalid IL or missing references)
//IL_03a1: Expected O, but got Unknown
//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
//IL_03b6: Expected O, but got Unknown
//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
//IL_03c5: Expected O, but got Unknown
//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
//IL_03d8: Expected O, but got Unknown
//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
//IL_03ee: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Expected O, but got Unknown
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Expected O, but got Unknown
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Expected O, but got Unknown
//IL_0258: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Expected O, but got Unknown
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_026d: Expected O, but got Unknown
//IL_027f: Unknown result type (might be due to invalid IL or missing references)
//IL_0285: Expected O, but got Unknown
//IL_0293: Unknown result type (might be due to invalid IL or missing references)
//IL_0299: Expected O, but got Unknown
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_02ac: Expected O, but got Unknown
//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
//IL_02bc: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 1; i + 2 < list.Count; i++)
{
FieldInfo fieldInfo = list[i].operand as FieldInfo;
if (list[i].opcode == OpCodes.Ldfld && fieldInfo != null && fieldInfo.Name == "veinCount" && list[i + 1].opcode == OpCodes.Conv_R4 && list[i + 2].opcode == OpCodes.Mul && list[i - 1].opcode == OpCodes.Ldarg_0)
{
list.RemoveAt(i);
list.RemoveAt(i - 1);
list.InsertRange(i - 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[5]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldobj, (object)typeof(MinerComponent)),
new CodeInstruction(OpCodes.Ldarg_2, (object)null),
new CodeInstruction(OpCodes.Ldarg_S, (object)(byte)4),
new CodeInstruction(OpCodes.Call, (object)ProductionTickCountMethod)
});
TimeMultiplierPatched = true;
break;
}
}
for (int j = 4; j + 1 < list.Count; j++)
{
FieldInfo fieldInfo2 = list[j].operand as FieldInfo;
LocalBuilder localBuilder = list[j + 1].operand as LocalBuilder;
if (list[j].opcode == OpCodes.Ldfld && fieldInfo2 != null && fieldInfo2.Name == "amount" && list[j + 1].opcode == OpCodes.Stloc_S && localBuilder != null && localBuilder.LocalIndex == 8 && list[j - 3].opcode == OpCodes.Ldarg_2 && list[j - 2].opcode == OpCodes.Ldloc_3 && list[j - 1].opcode == OpCodes.Ldelema)
{
list.InsertRange(j + 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[6]
{
new CodeInstruction(OpCodes.Ldloc_S, (object)localBuilder),
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldobj, (object)typeof(MinerComponent)),
new CodeInstruction(OpCodes.Ldarg_S, (object)(byte)4),
new CodeInstruction(OpCodes.Call, (object)MaxAllowedCostMethod),
new CodeInstruction(OpCodes.Stloc_S, (object)localBuilder)
});
CostBoundaryPatched = true;
break;
}
}
int num = FindVeinSelection(list);
if (num >= 0)
{
Label label = generator.DefineLabel();
list[num].labels.Add(label);
Label label2 = generator.DefineLabel();
list[num + 6].labels.Add(label2);
list.InsertRange(num + 6, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[10]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldobj, (object)typeof(MinerComponent)),
new CodeInstruction(OpCodes.Ldarg_2, (object)null),
new CodeInstruction(OpCodes.Ldarg_S, (object)(byte)4),
new CodeInstruction(OpCodes.Ldloc_3, (object)null),
new CodeInstruction(OpCodes.Call, (object)ProtectedVeinMethod),
new CodeInstruction(OpCodes.Brfalse, (object)label2),
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Call, (object)AdvanceMethod),
new CodeInstruction(OpCodes.Br, (object)label)
});
ProtectedVeinSkipPatched = true;
}
return list;
}
private static int FindVeinSelection(List<CodeInstruction> codes)
{
for (int i = 0; i + 5 < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldarg_0 && codes[i + 1].opcode == OpCodes.Ldfld && codes[i + 1].operand is FieldInfo && ((FieldInfo)codes[i + 1].operand).Name == "veins" && codes[i + 2].opcode == OpCodes.Ldarg_0 && codes[i + 3].opcode == OpCodes.Ldfld && codes[i + 3].operand is FieldInfo && ((FieldInfo)codes[i + 3].operand).Name == "currentVeinIndex" && codes[i + 4].opcode == OpCodes.Ldelem_I4 && codes[i + 5].opcode == OpCodes.Stloc_3)
{
return i;
}
}
return -1;
}
}
[HarmonyPatch(typeof(UIMinerWindow), "_OnUpdate")]
internal static class UIMinerWindowPatch
{
internal static bool SpeedMultiplierPatched;
private static readonly MethodInfo EffectiveCountMethod = AccessTools.Method(typeof(VeinProtectionLogic), "GetEffectiveVeinCount", new Type[3]
{
typeof(MinerComponent),
typeof(VeinData[]),
typeof(PlanetFactory)
}, (Type[])null);
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Expected O, but got Unknown
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 1; i + 2 < list.Count; i++)
{
FieldInfo fieldInfo = list[i].operand as FieldInfo;
if (list[i].opcode == OpCodes.Ldfld && fieldInfo != null && fieldInfo.Name == "veinCount" && list[i + 1].opcode == OpCodes.Conv_R4 && list[i + 2].opcode == OpCodes.Mul && list[i - 1].opcode == OpCodes.Ldloc_0)
{
list.RemoveAt(i);
list.RemoveAt(i - 1);
list.InsertRange(i - 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[5]
{
new CodeInstruction(OpCodes.Ldloc_0, (object)null),
new CodeInstruction(OpCodes.Ldloc_2, (object)null),
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(UIMinerWindow), "factory")),
new CodeInstruction(OpCodes.Call, (object)EffectiveCountMethod)
});
SpeedMultiplierPatched = true;
break;
}
}
return list;
}
}
[HarmonyPatch]
[HarmonyPatch]
internal static class MinerAllProtectedPrefixPatch
{
[HarmonyTargetMethod]
private static MethodInfo TargetMethod()
{
return AccessTools.Method(typeof(MinerComponent), "InternalUpdate", new Type[6]
{
typeof(PlanetFactory),
typeof(VeinData[]),
typeof(float),
typeof(float),
typeof(float),
typeof(int[])
}, (Type[])null);
}
[HarmonyPrefix]
private static bool Prefix(ref MinerComponent __instance, VeinData[] __1, float __3, ref uint __result)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if (!VeinProtectionLogic.AreAllBoundVeinsProtected(__instance, __1, __3))
{
return true;
}
__result = 0u;
return false;
}
}
[HarmonyPatch(typeof(UIOptionWindow), "_OnOpen")]
internal static class OptionsProtectionTogglePatch
{
private const string RowName = "VeinProtector-ProtectionRow";
private const string ToggleName = "VeinProtector-ProtectionToggle";
private const int GameTabIndex = 2;
private const float BottomMargin = 22f;
private static int _loggedFailure;
[HarmonyPostfix]
private static void Postfix(UIOptionWindow __instance)
{
try
{
if ((Object)(object)__instance == (Object)null)
{
throw new InvalidOperationException("UIOptionWindow is null");
}
RectTransform gameScrollContentRect = __instance.gameScrollContentRect;
if ((Object)(object)gameScrollContentRect == (Object)null)
{
throw new InvalidOperationException("confirmed Game page gameScrollContentRect is missing");
}
EnsureProtectionRow(__instance, gameScrollContentRect);
}
catch (Exception ex)
{
if (Interlocked.Exchange(ref _loggedFailure, 1) == 0)
{
Plugin.LogError("Settings protection row creation failed: " + ex);
}
}
}
private static void EnsureProtectionRow(UIOptionWindow window, RectTransform content)
{
Transform val = FindNamedChild(((Component)window).transform, "VeinProtector-ProtectionRow");
RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
bool flag = (Object)(object)val2 == (Object)null;
if (flag)
{
val2 = CreateProtectionRow(window, content);
}
bool flag2 = (Object)(object)((Transform)val2).parent != (Object)(object)content;
if (flag2)
{
((Transform)val2).SetParent((Transform)(object)content, false);
}
((Component)val2).gameObject.SetActive(true);
Toggle nativeToggle = GetNativeToggle((Transform)(object)val2);
if ((Object)(object)nativeToggle == (Object)null)
{
throw new InvalidOperationException("the cloned settings row has no Unity Toggle");
}
UIToggle componentInChildren = ((Component)val2).GetComponentInChildren<UIToggle>(true);
if ((Object)(object)componentInChildren == (Object)null)
{
throw new InvalidOperationException("the cloned settings row has no UIToggle wrapper");
}
Text val3 = FindLabel((Transform)(object)val2, ((Component)componentInChildren).transform);
if ((Object)(object)val3 == (Object)null)
{
throw new InvalidOperationException("the cloned settings row has no label Text");
}
RemoveLocalizers((Transform)(object)val2);
val3.text = GetProtectionLabel();
((Behaviour)val3).enabled = true;
((Component)val3).gameObject.SetActive(true);
((Object)((Component)nativeToggle).gameObject).name = "VeinProtector-ProtectionToggle";
ProtectionToggleBinding protectionToggleBinding = ((Component)val2).GetComponent<ProtectionToggleBinding>();
if ((Object)(object)protectionToggleBinding == (Object)null)
{
protectionToggleBinding = ((Component)val2).gameObject.AddComponent<ProtectionToggleBinding>();
}
protectionToggleBinding.Bind(nativeToggle);
protectionToggleBinding.Sync(Plugin.IsProtectionEnabled);
if (flag || flag2)
{
PlaceNewRow(content, val2);
}
}
private static RectTransform CreateProtectionRow(UIOptionWindow window, RectTransform targetContent)
{
if ((Object)(object)window.techQueueComp == (Object)null || (Object)(object)window.gameScrollContentRect == (Object)null)
{
throw new InvalidOperationException("confirmed Game tech-queue Toggle template or content is missing");
}
RectTransform gameScrollContentRect = window.gameScrollContentRect;
Text val = FindLabel((Transform)(object)gameScrollContentRect, ((Component)window.techQueueComp).transform);
if ((Object)(object)val == (Object)null)
{
throw new InvalidOperationException("the confirmed tech-queue row label could not be resolved");
}
Transform val2 = FindCommonRowRoot((Transform)(object)gameScrollContentRect, ((Component)window.techQueueComp).transform, ((Component)val).transform);
if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)gameScrollContentRect)
{
throw new InvalidOperationException("tech-queue label and Toggle do not share a setting-row parent");
}
GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, (Transform)(object)targetContent, false);
((Object)val3).name = "VeinProtector-ProtectionRow";
val3.SetActive(true);
Transform transform = val3.transform;
RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val4 == (Object)null)
{
throw new InvalidOperationException("tech-queue row has no RectTransform");
}
UIToggle[] componentsInChildren = ((Component)val4).GetComponentsInChildren<UIToggle>(true);
if (componentsInChildren.Length != 1)
{
throw new InvalidOperationException("tech-queue row must contain exactly one UIToggle; found " + componentsInChildren.Length);
}
Toggle nativeToggle = GetNativeToggle((Transform)(object)val4);
if ((Object)(object)nativeToggle == (Object)null)
{
throw new InvalidOperationException("tech-queue row clone has no Unity Toggle");
}
ClearAllListeners(nativeToggle);
return val4;
}
private static Transform FindCommonRowRoot(Transform content, Transform toggle, Transform label)
{
Transform val = toggle;
while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)content)
{
if ((Object)(object)label == (Object)(object)val || label.IsChildOf(val))
{
return val;
}
val = val.parent;
}
return null;
}
private static void PlaceNewRow(RectTransform content, RectTransform row)
{
//IL_0030: 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_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
LayoutGroup component = ((Component)content).GetComponent<LayoutGroup>();
ContentSizeFitter component2 = ((Component)content).GetComponent<ContentSizeFitter>();
Rect rect = content.rect;
float previousHeight = Mathf.Max(((Rect)(ref rect)).height, content.sizeDelta.y);
if ((Object)(object)component != (Object)null)
{
((Transform)row).SetAsLastSibling();
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
EnsureContentHeight(content, row, previousHeight);
return;
}
List<RectTransform> directSettingRows = GetDirectSettingRows(content, row);
if (directSettingRows.Count == 0)
{
throw new InvalidOperationException("Game content has no active direct-child setting rows for manual spacing");
}
directSettingRows.Sort(delegate(RectTransform a, RectTransform b)
{
//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_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references)
Bounds localBounds3 = GetLocalBounds(a, (Transform)(object)content);
float y = ((Bounds)(ref localBounds3)).min.y;
Bounds localBounds4 = GetLocalBounds(b, (Transform)(object)content);
return y.CompareTo(((Bounds)(ref localBounds4)).min.y);
});
RectTransform rect2 = directSettingRows[0];
Bounds localBounds = GetLocalBounds(rect2, (Transform)(object)content);
float num = MeasureBottomGap(directSettingRows, content, ((Bounds)(ref localBounds)).size.y);
float num2 = ((Bounds)(ref localBounds)).min.y - num;
Bounds localBounds2 = GetLocalBounds(row, (Transform)(object)content);
row.anchoredPosition = new Vector2(row.anchoredPosition.x, row.anchoredPosition.y + num2 - ((Bounds)(ref localBounds2)).max.y);
((Transform)row).SetAsLastSibling();
if ((Object)(object)component2 != (Object)null)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
}
EnsureContentHeight(content, row, previousHeight);
}
private static float GetRequiredHeight(RectTransform row)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Abs(row.anchoredPosition.y);
Rect rect = row.rect;
return num + ((Rect)(ref rect)).height + 22f;
}
private static void EnsureContentHeight(RectTransform content, RectTransform row, float previousHeight)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
float requiredHeight = GetRequiredHeight(row);
float preferredHeight = LayoutUtility.GetPreferredHeight(content);
float[] array = new float[5];
Rect rect = content.rect;
array[0] = ((Rect)(ref rect)).height;
array[1] = content.sizeDelta.y;
array[2] = previousHeight;
array[3] = requiredHeight;
array[4] = preferredHeight;
float num = Mathf.Max(array);
if (num > content.sizeDelta.y)
{
content.sizeDelta = new Vector2(content.sizeDelta.x, num);
}
}
private static float MeasureBottomGap(List<RectTransform> rows, RectTransform content, float fallbackRowHeight)
{
//IL_0023: 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_0034: 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_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
int num = Math.Min(3, rows.Count - 1);
float num2 = 0f;
int num3 = 0;
for (int i = 0; i < num; i++)
{
Bounds localBounds = GetLocalBounds(rows[i], (Transform)(object)content);
Bounds localBounds2 = GetLocalBounds(rows[i + 1], (Transform)(object)content);
float num4 = ((Bounds)(ref localBounds2)).min.y - ((Bounds)(ref localBounds)).max.y;
if (num4 >= 0f && num4 < 100f)
{
num2 += num4;
num3++;
}
}
if (num3 > 0)
{
return num2 / (float)num3;
}
return Mathf.Max(0f, Mathf.Max(fallbackRowHeight + 8f, 40f) - fallbackRowHeight);
}
private static List<RectTransform> GetDirectSettingRows(RectTransform content, RectTransform excluded)
{
List<RectTransform> list = new List<RectTransform>();
for (int i = 0; i < ((Transform)content).childCount; i++)
{
Transform child = ((Transform)content).GetChild(i);
RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)excluded) && ((Component)val).gameObject.activeSelf && !IsDropdownListItem((Transform)(object)val) && HasSettingControl((Transform)(object)val))
{
list.Add(val);
}
}
return list;
}
private static bool HasSettingControl(Transform row)
{
if (!((Object)(object)((Component)row).GetComponentInChildren<UIToggle>(true) != (Object)null) && !((Object)(object)((Component)row).GetComponentInChildren<Slider>(true) != (Object)null) && !((Object)(object)((Component)row).GetComponentInChildren<UIComboBox>(true) != (Object)null) && !((Object)(object)((Component)row).GetComponentInChildren<Dropdown>(true) != (Object)null) && !((Object)(object)((Component)row).GetComponentInChildren<UIButton>(true) != (Object)null))
{
return (Object)(object)((Component)row).GetComponentInChildren<Button>(true) != (Object)null;
}
return true;
}
private static bool IsDropdownListItem(Transform row)
{
string name = ((Object)row).name;
if (name.IndexOf("Dropdown List", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Dropdown Item", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Scrollbar", StringComparison.OrdinalIgnoreCase) < 0)
{
return (Object)(object)((Component)row).GetComponent<Scrollbar>() != (Object)null;
}
return true;
}
private static Bounds GetLocalBounds(RectTransform rect, Transform localTo)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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)
Vector3[] array = (Vector3[])(object)new Vector3[4];
rect.GetWorldCorners(array);
Vector3 val = localTo.InverseTransformPoint(array[0]);
Bounds result = default(Bounds);
((Bounds)(ref result))..ctor(val, Vector3.zero);
for (int i = 1; i < array.Length; i++)
{
((Bounds)(ref result)).Encapsulate(localTo.InverseTransformPoint(array[i]));
}
return result;
}
private static Toggle GetNativeToggle(Transform root)
{
if ((Object)(object)root == (Object)null)
{
return null;
}
UIToggle componentInChildren = ((Component)root).GetComponentInChildren<UIToggle>(true);
if ((Object)(object)componentInChildren == (Object)null)
{
return null;
}
FieldInfo fieldInfo = AccessTools.Field(typeof(UIToggle), "toggle");
if (!(fieldInfo == null))
{
object? value = fieldInfo.GetValue(componentInChildren);
return (Toggle)((value is Toggle) ? value : null);
}
return null;
}
private static Text FindLabel(Transform root, Transform toggle)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)root == (Object)null || (Object)(object)toggle == (Object)null)
{
return null;
}
Text[] componentsInChildren = ((Component)root).GetComponentsInChildren<Text>(true);
Text result = null;
float num = float.PositiveInfinity;
Vector3 val = root.InverseTransformPoint(toggle.position);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if (!((Object)(object)componentsInChildren[i] == (Object)null) && !((Object)(object)((Component)componentsInChildren[i]).transform == (Object)(object)toggle) && !((Component)componentsInChildren[i]).transform.IsChildOf(toggle) && !string.IsNullOrWhiteSpace(componentsInChildren[i].text))
{
Vector3 val2 = root.InverseTransformPoint(((Component)componentsInChildren[i]).transform.position);
float num2 = Mathf.Abs(val2.y - val.y) + Mathf.Abs(val2.x - val.x) * 0.01f;
if (num2 < num)
{
result = componentsInChildren[i];
num = num2;
}
}
}
return result;
}
private static void RemoveLocalizers(Transform root)
{
Component[] componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if ((Object)(object)componentsInChildren[i] != (Object)null && ((object)componentsInChildren[i]).GetType().Name.IndexOf("Localizer", StringComparison.OrdinalIgnoreCase) >= 0)
{
Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
}
}
}
private static void ClearAllListeners(Toggle toggle)
{
((UnityEventBase)toggle.onValueChanged).RemoveAllListeners();
FieldInfo fieldInfo = AccessTools.Field(typeof(UnityEventBase), "m_PersistentCalls");
object obj = ((fieldInfo == null) ? null : fieldInfo.GetValue(toggle.onValueChanged));
MethodInfo methodInfo = ((obj == null) ? null : AccessTools.Method(obj.GetType(), "Clear", (Type[])null, (Type[])null));
if (methodInfo != null)
{
methodInfo.Invoke(obj, null);
}
MethodInfo methodInfo2 = AccessTools.Method(typeof(UnityEventBase), "DirtyPersistentCalls", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
methodInfo2.Invoke(toggle.onValueChanged, null);
}
}
private static Transform FindNamedChild(Transform root, string name)
{
if ((Object)(object)root == (Object)null)
{
return null;
}
if (((Object)root).name == name)
{
return root;
}
for (int i = 0; i < root.childCount; i++)
{
Transform val = FindNamedChild(root.GetChild(i), name);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static string GetProtectionLabel()
{
try
{
return (CultureInfo.GetCultureInfo(Localization.CurrentLanguageLCID).TwoLetterISOLanguageName == "en") ? "Vein Protection" : "矿脉保护";
}
catch
{
return "矿脉保护";
}
}
}
internal sealed class ProtectionToggleBinding : MonoBehaviour
{
private Toggle _toggle;
private UnityAction<bool> _listener;
internal void Bind(Toggle toggle)
{
if (!((Object)(object)_toggle == (Object)(object)toggle) || _listener == null)
{
if ((Object)(object)_toggle != (Object)null && _listener != null)
{
((UnityEvent<bool>)(object)_toggle.onValueChanged).RemoveListener(_listener);
}
_toggle = toggle;
ClearListeners(_toggle);
_listener = OnValueChanged;
((UnityEvent<bool>)(object)_toggle.onValueChanged).AddListener(_listener);
}
}
internal void Sync(bool value)
{
if ((Object)(object)_toggle != (Object)null && _toggle.isOn != value)
{
_toggle.isOn = value;
}
}
private void OnValueChanged(bool value)
{
Plugin.SetProtectionEnabled(value);
}
private static void ClearListeners(Toggle toggle)
{
((UnityEventBase)toggle.onValueChanged).RemoveAllListeners();
FieldInfo fieldInfo = AccessTools.Field(typeof(UnityEventBase), "m_PersistentCalls");
object obj = ((fieldInfo == null) ? null : fieldInfo.GetValue(toggle.onValueChanged));
MethodInfo methodInfo = ((obj == null) ? null : AccessTools.Method(obj.GetType(), "Clear", (Type[])null, (Type[])null));
if (methodInfo != null)
{
methodInfo.Invoke(obj, null);
}
MethodInfo methodInfo2 = AccessTools.Method(typeof(UnityEventBase), "DirtyPersistentCalls", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
methodInfo2.Invoke(toggle.onValueChanged, null);
}
}
}
[HarmonyPatch(typeof(UIVeinCollectorPanel), "_OnUpdate")]
internal static class UIVeinCollectorPanelPatch
{
internal static bool SpeedMultiplierPatched;
private static readonly MethodInfo EffectiveCountMethod = AccessTools.Method(typeof(VeinProtectionLogic), "GetEffectiveVeinCount", new Type[2]
{
typeof(MinerComponent),
typeof(PlanetFactory)
}, (Type[])null);
private static readonly FieldInfo FactoryField = AccessTools.Field(typeof(UIVeinCollectorPanel), "factory");
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 0; i + 3 < list.Count; i++)
{
FieldInfo fieldInfo = list[i + 1].operand as FieldInfo;
if (list[i].opcode == OpCodes.Ldloc_0 && list[i + 1].opcode == OpCodes.Ldfld && fieldInfo != null && fieldInfo.Name == "veinCount" && list[i + 2].opcode == OpCodes.Conv_R4 && list[i + 3].opcode == OpCodes.Mul)
{
list.RemoveAt(i + 1);
list.InsertRange(i + 1, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldfld, (object)FactoryField),
new CodeInstruction(OpCodes.Call, (object)EffectiveCountMethod)
});
SpeedMultiplierPatched = true;
break;
}
}
return list;
}
}
[HarmonyPatch(typeof(UIReferenceSpeedTip), "SetTip")]
internal static class ReferenceSpeedDetailExtensionPatch
{
private const int ProductCycle = 1;
private static readonly FieldInfo EntriesField = AccessTools.Field(typeof(UIReferenceSpeedTip), "entries");
private static readonly FieldInfo EntryRectField = AccessTools.Field(typeof(UIReferenceSpeedTipEntry), "rectTrans");
private static int _loggedFailure;
[HarmonyPrefix]
private static void Prefix(UIReferenceSpeedTip __instance)
{
try
{
if (!((Object)(object)__instance == (Object)null))
{
ReferenceSpeedTipExtensionState component = ((Component)__instance).GetComponent<ReferenceSpeedTipExtensionState>();
if ((Object)(object)component != (Object)null)
{
component.BeforeSetTip();
}
}
}
catch (Exception ex)
{
if (Interlocked.Exchange(ref _loggedFailure, 1) == 0)
{
Plugin.LogError("Reference detail pre-refresh cleanup failed: " + ex);
}
}
}
[HarmonyPostfix]
private static void Postfix(UIReferenceSpeedTip __instance, int _itemId, int _astroFilter, object _itemCycle, Transform _parent)
{
ReferenceSpeedTipExtensionState referenceSpeedTipExtensionState = null;
try
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.rectTrans == (Object)null)
{
return;
}
int num = Convert.ToInt32(_itemCycle, CultureInfo.InvariantCulture);
referenceSpeedTipExtensionState = ((Component)__instance).GetComponent<ReferenceSpeedTipExtensionState>();
if ((Object)(object)referenceSpeedTipExtensionState == (Object)null)
{
referenceSpeedTipExtensionState = ((Component)__instance).gameObject.AddComponent<ReferenceSpeedTipExtensionState>();
}
referenceSpeedTipExtensionState.CaptureVanillaBaseline(__instance);
if (num != 1)
{
referenceSpeedTipExtensionState.Hide();
return;
}
bool supportedVeinItem = VeinProtectionLogic.IsSupportedProtectedResourceItem(_itemId);
if (!VeinProtectionLogic.ShouldShowReferenceExtension(Plugin.IsProtectionEnabled, _itemId, supportedVeinItem))
{
referenceSpeedTipExtensionState.Hide();
return;
}
int statisticsAstroFilter = GetStatisticsAstroFilter(_parent, _astroFilter);
GameData data = GameMain.data;
float vanillaTotal = ReadVanillaReferenceTotal(_itemId, statisticsAstroFilter);
CalculateForTooltip(_itemId, statisticsAstroFilter, out var protectedVeinCount, out var protectionLoss);
float speed = VeinProtectionLogic.CalculateProtectedReferenceSpeed(Plugin.IsProtectionEnabled, (data == null || data.history == null) ? 0f : data.history.miningCostRate, vanillaTotal, protectionLoss);
referenceSpeedTipExtensionState.Refresh(__instance, GetProtectedVeinLabel(protectedVeinCount), GetProtectedSpeedLabel(speed));
}
catch (Exception ex)
{
if ((Object)(object)referenceSpeedTipExtensionState != (Object)null)
{
try
{
referenceSpeedTipExtensionState.AbortExtension();
}
catch (Exception ex2)
{
ex = new AggregateException(ex, ex2);
}
}
if (Interlocked.Exchange(ref _loggedFailure, 1) == 0)
{
Plugin.LogError("Reference detail extension failed: " + ex);
}
}
}
private static int GetStatisticsAstroFilter(Transform parent, int tooltipAstroFilter)
{
UIProductEntry val = (((Object)(object)parent == (Object)null) ? null : ((Component)parent).GetComponentInParent<UIProductEntry>());
if ((Object)(object)val != (Object)null && (Object)(object)val.productionStatWindow != (Object)null)
{
return val.productionStatWindow.astroFilter;
}
if (tooltipAstroFilter != 0)
{
return tooltipAstroFilter;
}
return -1;
}
private static float ReadVanillaReferenceTotal(int itemId, int astroFilter)
{
GameData data = GameMain.data;
if (data == null || data.statistics == null || data.statistics.production == null || data.statistics.production.factoryStatPool == null)
{
return 0f;
}
FactoryProductionStat[] factoryStatPool = data.statistics.production.factoryStatPool;
float num = 0f;
foreach (PlanetFactory item in VeinProtectionLogic.EnumerateFactoriesForAstroFilter(data, astroFilter))
{
if (item == null || item.index < 0 || item.index >= factoryStatPool.Length)
{
continue;
}
FactoryProductionStat val = factoryStatPool[item.index];
if (val != null && val.productIndices != null && itemId >= 0 && itemId < val.productIndices.Length && val.productPool != null)
{
int num2 = val.productIndices[itemId];
if (num2 > 0 && num2 < val.productPool.Length && val.productPool[num2] != null)
{
num += val.productPool[num2].refProductSpeed;
}
}
}
return num;
}
private static void CalculateForTooltip(int itemId, int astroFilter, out int protectedVeinCount, out double protectionLoss)
{
//IL_00b1: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Invalid comparison between Unknown and I4
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_0250: Unknown result type (might be due to invalid IL or missing references)
protectedVeinCount = 0;
protectionLoss = 0.0;
GameData data = GameMain.data;
if (!Plugin.IsProtectionEnabled || data == null || data.history == null)
{
return;
}
float miningCostRate = data.history.miningCostRate;
if (miningCostRate <= 0f)
{
return;
}
foreach (PlanetFactory item in VeinProtectionLogic.EnumerateFactoriesForAstroFilter(data, astroFilter))
{
if (item == null || item.veinPool == null || item.factorySystem == null)
{
continue;
}
MinerComponent[] minerPool = item.factorySystem.minerPool;
if (minerPool == null)
{
continue;
}
int num = Math.Min(item.factorySystem.minerCursor, minerPool.Length);
HashSet<int> hashSet = new HashSet<int>();
for (int i = 1; i < num; i++)
{
MinerComponent miner = minerPool[i];
if (miner.id != i || (int)miner.type != 2 || miner.veinCount <= 0 || miner.minimumVeinAmount > 1 || miner.veins == null)
{
continue;
}
int num2 = Math.Min(miner.veinCount, miner.veins.Length);
for (int j = 0; j < num2; j++)
{
int num3 = miner.veins[j];
if (num3 > 0 && num3 < item.veinPool.Length)
{
VeinData val = item.veinPool[num3];
if (val.id != 0 && val.productId == itemId && val.amount <= 1)
{
VeinProtectionLogic.AddProtectedVeinId(hashSet, num3);
}
}
}
if (miner.period <= 0 || miner.currentVeinIndex < 0 || miner.currentVeinIndex >= num2 || item.powerSystem == null || item.powerSystem.consumerPool == null || miner.pcId < 0 || miner.pcId >= item.powerSystem.consumerPool.Length)
{
continue;
}
int num4 = miner.veins[miner.currentVeinIndex];
if (num4 > 0 && num4 < item.veinPool.Length)
{
VeinData val2 = item.veinPool[num4];
if (val2.id != 0 && val2.productId == itemId && item.powerSystem.consumerPool[miner.pcId].networkId > 0)
{
int effectiveVeinCount = VeinProtectionLogic.GetEffectiveVeinCount(miner, item.veinPool, miningCostRate);
double baseReferenceSpeed = 3600.0 / (double)miner.period * (double)data.history.miningSpeedScale * (double)miner.speed;
protectionLoss += VeinProtectionLogic.CalculateReferenceSpeedLoss(baseReferenceSpeed, miner.veinCount, effectiveVeinCount);
}
}
}
protectedVeinCount += hashSet.Count;
}
}
private static string GetProtectedVeinLabel(int count)
{
string text = count.ToString("#,##0", CultureInfo.CurrentCulture);
if (!IsEnglishUi())
{
return "已保护矿点:" + text;
}
return "Protected veins: " + text;
}
private static string GetProtectedSpeedLabel(float speed)
{
string text = speed.ToString("#,##0.##", CultureInfo.CurrentCulture) + " / min";
if (!IsEnglishUi())
{
return "保护状态参考速率:" + text;
}
return "Protected-State Reference Rate: " + text;
}
private static bool IsEnglishUi()
{
try
{
return CultureInfo.GetCultureInfo(Localization.CurrentLanguageLCID).TwoLetterISOLanguageName == "en";
}
catch
{
return false;
}
}
}
internal sealed class ReferenceSpeedTipExtensionState : MonoBehaviour
{
private sealed class RectState
{
internal readonly RectTransform Rect;
internal readonly Vector2 BasePosition;
internal readonly Vector2 BaseSize;
internal bool Shift;
internal RectState(RectTransform rect, Vector2 basePosition, Vector2 baseSize, bool shift)
{
//IL_000e: 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_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
Rect = rect;
BasePosition = basePosition;
BaseSize = baseSize;
Shift = shift;
}
}
private const float AddedHeight = 44f;
private const float GapAbove = 2f;
private const float GapBelow = 3f;
private const float RowHeight = 18f;
private static int _loggedFailure;
private static readonly FieldInfo EntriesField = AccessTools.Field(typeof(UIReferenceSpeedTip), "entries");
private static readonly FieldInfo EntryRectField = AccessTools.Field(typeof(UIReferenceSpeedTipEntry), "rectTrans");
private readonly List<RectState> _layout = new List<RectState>();
private RectTransform _panel;
private Vector2 _panelBaseSize;
private Vector2 _panelBasePosition;
private Bounds _baseTableHeaderBounds;
private Vector2 _baseTableHeaderPosition;
private float _layoutOffset;
private RectTransform _extensionRoot;
private Text _protectedVeinText;
private Text _protectedSpeedText;
private string _expectedVeinText;
private string _expectedSpeedText;
private Coroutine _detailLayoutCoroutine;
private int _layoutGeneration;
internal void BeforeSetTip()
{
CancelPendingLayout();
RestoreBaseLayout();
if ((Object)(object)_extensionRoot != (Object)null)
{
((Component)_extensionRoot).gameObject.SetActive(false);
}
}
internal void Hide()
{
CancelPendingLayout();
RestoreBaseLayout();
if ((Object)(object)_extensionRoot != (Object)null)
{
((Component)_extensionRoot).gameObject.SetActive(false);
}
}
internal void AbortExtension()
{
CancelPendingLayout();
RestoreBaseLayout();
if ((Object)(object)_extensionRoot != (Object)null)
{
((Component)_extensionRoot).gameObject.SetActive(false);
}
}
internal void Refresh(UIReferenceSpeedTip tip, string protectedVeins, string protectedSpeed)
{
EnsureExtensionRoot(tip);
_protectedVeinText.text = protectedVeins;
_protectedSpeedText.text = protectedSpeed;
_expectedVeinText = protectedVeins;
_expectedSpeedText = protectedSpeed;
CaptureBaseLayout(tip);
RefreshCanvasLayout(tip);
ValidateVisibleText();
ScheduleNextFrame(tip);
}
internal void CaptureVanillaBaseline(UIReferenceSpeedTip tip)
{
CaptureBaseLayout(tip);
}
private void EnsureExtensionRoot(UIReferenceSpeedTip tip)
{
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Expected O, but got Unknown
if ((Object)(object)_extensionRoot != (Object)null && (Object)(object)_protectedVeinText != (Object)null && (Object)(object)_protectedSpeedText != (Object)null)
{
return;
}
Transform val = ((Transform)tip.rectTrans).Find("VeinProtector-ReferenceExtension");
if ((Object)(object)val != (Object)null)
{
_extensionRoot = (RectTransform)(object)((val is RectTransform) ? val : null);
_protectedVeinText = FindText(val, "VeinProtector-ProtectedVeinText");
_protectedSpeedText = FindText(val, "VeinProtector-ProtectedRefSpeedText");
}
if ((Object)(object)_extensionRoot == (Object)null)
{
GameObject val2 = new GameObject("VeinProtector-ReferenceExtension", new Type[1] { typeof(RectTransform) });
ref RectTransform extensionRoot = ref _extensionRoot;
Transform transform = val2.transform;
extensionRoot = (RectTransform)(object)((transform is RectTransform) ? transform : null);
((Transform)_extensionRoot).SetParent((Transform)(object)tip.rectTrans, false);
}
if ((Object)(object)_protectedVeinText == (Object)null || (Object)(object)_protectedSpeedText == (Object)null)
{
Text totalSpeedText = tip.totalSpeedText;
if ((Object)(object)totalSpeedText == (Object)null || !((Behaviour)totalSpeedText).enabled || !((Component)totalSpeedText).gameObject.activeInHierarchy || string.IsNullOrEmpty(totalSpeedText.text))
{
throw new InvalidOperationException("visible vanilla Reference Rate Text template was not found");
}
if ((Object)(object)_protectedVeinText == (Object)null)
{
_protectedVeinText = CloneText(totalSpeedText, (Transform)(object)_extensionRoot, "VeinProtector-ProtectedVeinText");
PlaceChildText(((Graphic)_protectedVeinText).rectTransform, 0f);
}
if ((Object)(object)_protectedSpeedText == (Object)null)
{
_protectedSpeedText = CloneText(totalSpeedText, (Transform)(object)_extensionRoot, "VeinProtector-ProtectedRefSpeedText");
PlaceChildText(((Graphic)_protectedSpeedText).rectTransform, -21f);
}
}
((Component)_extensionRoot).gameObject.SetActive(false);
}
private static Text FindText(Transform root, string name)
{
Transform val = root.Find(name);
if (!((Object)(object)val == (Object)null))
{
return ((Component)val).GetComponent<Text>();
}
return null;
}
private static Text CloneText(Text source, Transform parent, string name)
{
GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent, false);
((Object)val).name = name;
Text component = val.GetComponent<Text>();
if ((Object)(object)component == (Object)null)
{
throw new InvalidOperationException("cloned reference detail row has no Unity UI Text component");
}
RemoveLocalizerComponents(val.transform);
((Graphic)component).raycastTarget = false;
component.resizeTextForBestFit = false;
component.fontSize = 16;
component.alignment = (TextAnchor)3;
((Behaviour)component).enabled = true;
val.SetActive(true);
return component;
}
private static void PlaceChildText(RectTransform rect, float y)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: 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_005b: Unknown result type (might be due to invalid IL or missing references)
rect.anchorMin = new Vector2(0f, 1f);
rect.anchorMax = new Vector2(1f, 1f);
rect.pivot = new Vector2(0f, 1f);
rect.sizeDelta = new Vector2(0f, 18f);
rect.anchoredPosition = new Vector2(0f, y);
}
private void CaptureBaseLayout(UIReferenceSpeedTip tip)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: 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_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
_layout.Clear();
_panel = tip.rectTrans;
_panelBaseSize = _panel.sizeDelta;
_panelBasePosition = _panel.anchoredPosition;
if ((Object)(object)tip.tableHeaderTrans == (Object)null)
{
throw new InvalidOperationException("reference table header RectTransform is missing");
}
_baseTableHeaderBounds = GetLocalBounds(tip.tableHeaderTrans, (Transform)(object)tip.rectTrans);
_baseTableHeaderPosition = tip.tableHeaderTrans.anchoredPosition;
_layoutOffset = 49f;
CaptureRect(tip.headerTrans, shift: false);
CaptureRect(((Object)(object)tip.totalSpeedText == (Object)null) ? null : ((Graphic)tip.totalSpeedText).rectTransform, shift: false);
CaptureRect(tip.emptyTipTrans, shift: false);
CaptureRect(((Object)(object)tip.zeroCountTipText == (Object)null) ? null : ((Graphic)tip.zeroCountTipText).rectTransform, shift: false);
CaptureRect(tip.tableHeaderTrans, shift: true);
CaptureRect(tip.subTipRectTrans, shift: true);
if ((Object)(object)tip.previousPageBtn != (Object)null)
{
Transform transform = ((Component)tip.previousPageBtn).transform;
CaptureRect((RectTransform)(object)((transform is RectTransform) ? transform : null), shift: true);
}
if ((Object)(object)tip.nextPageBtn != (Object)null)
{
Transform transform2 = ((Component)tip.nextPageBtn).transform;
CaptureRect((RectTransform)(object)((transform2 is RectTransform) ? transform2 : null), shift: true);
}
if (!(EntriesField != null) || !(EntriesField.GetValue(tip) is IEnumerable enumerable))
{
return;
}
foreach (object item in enumerable)
{
if (item != null && EntryRectField != null)
{
object? value = EntryRectField.GetValue(item);
CaptureRect((RectTransform)((value is RectTransform) ? value : null), shift: true);
}
}
}
private void CaptureRect(RectTransform rect, bool shift)
{
//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)
if ((Object)(object)rect == (Object)null || (Object)(object)rect == (Object)(object)_panel || (Object)(object)rect == (Object)(object)_extensionRoot)
{
return;
}
for (int i = 0; i < _layout.Count; i++)
{
if ((Object)(object)_layout[i].Rect == (Object)(object)rect)
{
_layout[i].Shift = _layout[i].Shift || shift;
return;
}
}
_layout.Add(new RectState(rect, rect.anchoredPosition, rect.sizeDelta, shift));
}
private static Bounds GetLocalBounds(RectTransform rect, Transform localTo)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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)
Vector3[] array = (Vector3[])(object)new Vector3[4];
rect.GetWorldCorners(array);
Vector3 val = localTo.InverseTransformPoint(array[0]);
Bounds result = default(Bounds);
((Bounds)(ref result))..ctor(val, Vector3.zero);
for (int i = 1; i < array.Length; i++)
{
((Bounds)(ref result)).Encapsulate(localTo.InverseTransformPoint(array[i]));
}
return result;
}
private void ApplyExtensionLayout(UIReferenceSpeedTip tip)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: 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_0074: 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)
_panel.sizeDelta = new Vector2(_panelBaseSize.x, _panelBaseSize.y + _layoutOffset);
for (int i = 0; i < _layout.Count; i++)
{
RectState rectState = _layout[i];
if ((Object)(object)rectState.Rect != (Object)null && rectState.Shift && !IsChildOfShiftedRect(rectState.Rect))
{
rectState.Rect.anchoredPosition = new Vector2(rectState.BasePosition.x, rectState.BasePosition.y - _layoutOffset);
}
}
_extensionRoot.anchorMin = new Vector2(0f, 1f);
_extensionRoot.anchorMax = new Vector2(0f, 1f);
_extensionRoot.pivot = new Vector2(0f, 1f);
_extensionRoot.sizeDelta = new Vector2(((Bounds)(ref _baseTableHeaderBounds)).size.x, 44f);
RectTransform extensionRoot = _extensionRoot;
float x = ((Bounds)(ref _baseTableHeaderBounds)).min.x;
Rect rect = tip.rectTrans.rect;
extensionRoot.anchoredPosition = new Vector2(x - ((Rect)(ref rect)).xMin, _baseTableHeaderPosition.y - 2f);
if ((Object)(object)((Transform)_extensionRoot).parent != (Object)(object)tip.rectTrans)
{
((Transform)_extensionRoot).SetParent((Transform)(object)tip.rectTrans, false);
}
if ((Object)(object)((Transform)tip.tableHeaderTrans).parent == (Object)(object)((Transform)_extensionRoot).parent)
{
((Transform)_extensionRoot).SetSiblingIndex(((Transform)tip.tableHeaderTrans).GetSiblingIndex());
}
((Component)_extensionRoot).gameObject.SetActive(true);
_protectedVeinText.text = _expectedVeinText;
_protectedSpeedText.text = _expectedSpeedText;
((Behaviour)_protectedVeinText).enabled = true;
((Behaviour)_protectedSpeedText).enabled = true;
((Component)_protectedVeinText).gameObject.SetActive(true);
((Component)_protectedSpeedText).gameObject.SetActive(true);
PlaceChildText(((Graphic)_protectedVeinText).rectTransform, 0f);
PlaceChildText(((Graphic)_protectedSpeedText).rectTransform, -21f);
}
private void RefreshCanvasLayout(UIReferenceSpeedTip tip)
{
((Component)_extensionRoot).gameObject.SetActive(true);
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(tip.rectTrans);
ApplyExtensionLayout(tip);
Canvas.ForceUpdateCanvases();
}
private static void RemoveLocalizerComponents(Transform root)
{
Component[] componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
if ((Object)(object)componentsInChildren[i] != (Object)null && ((object)componentsInChildren[i]).GetType().Name.IndexOf("Localizer", StringComparison.OrdinalIgnoreCase) >= 0)
{
Object.Destroy((Object)(object)componentsInChildren[i]);
}
}
}
private void ScheduleNextFrame(UIReferenceSpeedTip tip)
{
Plugin instance = Plugin.Instance;
if ((Object)(object)instance == (Object)null)
{
throw new InvalidOperationException("Plugin coroutine runner is unavailable");
}
CancelPendingLayout();
_detailLayoutCoroutine = ((MonoBehaviour)instance).StartCoroutine(ApplyReferenceDetailLayoutNextFrame(tip, ++_layoutGeneration));
}
private IEnumerator ApplyReferenceDetailLayoutNextFrame(UIReferenceSpeedTip tip, int generation)
{
yield return null;
if (generation != _layoutGeneration)
{
yield break;
}
_detailLayoutCoroutine = null;
if ((Object)(object)tip == (Object)null)
{
yield break;
}
if ((Object)(object)_extensionRoot == (Object)null || !Object.op_Implicit((Object)(object)_extensionRoot))
{
AbortExtension();
yield break;
}
if (!((Component)tip).gameObject.activeInHierarchy)
{
AbortExtension();
yield break;
}
try
{
_protectedVeinText.text = _expectedVeinText;
_protectedSpeedText.text = _expectedSpeedText;
RefreshCanvasLayout(tip);
ValidateVisibleText();
}
catch (Exception ex)
{
try
{
AbortExtension();
}
catch (Exception ex2)
{
ex = new AggregateException(ex, ex2);
}
if (Interlocked.Exchange(ref _loggedFailure, 1) == 0)
{
Plugin.LogWarning("Reference detail next-frame layout failed; vanilla tooltip layout restored: " + ex.Message);
}
}
}
private void CancelPendingLayout()
{
_layoutGeneration++;
Plugin instance = Plugin.Instance;
if (_detailLayoutCoroutine != null && (Object)(object)instance != (Object)null)
{
((MonoBehaviour)instance).StopCoroutine(_detailLayoutCoroutine);
_detailLayoutCoroutine = null;
}
}
private void ValidateVisibleText()
{
ValidateText(_protectedVeinText);
ValidateText(_protectedSpeedText);
if ((Object)(object)_extensionRoot == (Object)null || !((Component)_extensionRoot).gameObject.activeInHierarchy)
{
throw new InvalidOperationException("reference extension root is not active");
}
}
private static void ValidateText(Text text)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: 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)
if ((Object)(object)text == (Object)null || !((Behaviour)text).enabled || !((Component)text).gameObject.activeInHierarchy || string.IsNullOrEmpty(text.text) || ((Graphic)text).color.a <= 0.01f)
{
throw new InvalidOperationException("VeinProtector detail Text is empty, inactive, or transparent");
}
CanvasRenderer component = ((Component)text).GetComponent<CanvasRenderer>();
if ((Object)(object)component != (Object)null && component.GetAlpha() <= 0.01f)
{
throw new InvalidOperationException("VeinProtector detail CanvasRenderer alpha is zero");
}
Rect rect = ((Graphic)text).rectTransform.rect;
if (((Rect)(ref rect)).width <= 0.5f || ((Rect)(ref rect)).height <= 0.5f)
{
throw new InvalidOperationException("VeinProtector detail Text has an empty RectTransform");
}
}
private void RestoreBaseLayout()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < _layout.Count; i++)
{
RectState rectState = _layout[i];
if ((Object)(object)rectState.Rect != (Object)null)
{
rectState.Rect.anchoredPosition = rectState.BasePosition;
rectState.Rect.sizeDelta = rectState.BaseSize;
}
}
if ((Object)(object)_panel != (Object)null)
{
_panel.sizeDelta = _panelBaseSize;
_panel.anchoredPosition = _panelBasePosition;
}
_layoutOffset = 0f;
_layout.Clear();
_panel = null;
}
private bool IsChildOfShiftedRect(RectTransform rect)
{
for (int i = 0; i < _layout.Count; i++)
{
if (_layout[i].Shift && (Object)(object)_layout[i].Rect != (Object)null && (Object)(object)rect != (Object)(object)_layout[i].Rect && ((Transform)rect).IsChildOf((Transform)(object)_layout[i].Rect))
{
return true;
}
}
return false;
}
}
}