using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace VoidFleetCap;
[BepInPlugin("aimod.VoidFleetCap", "VoidFleetCap", "1.3.5")]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "aimod.VoidFleetCap";
public const string NAME = "VoidFleetCap";
public const string VERSION = "1.3.5";
internal static ManualLogSource Log;
internal const int Slots = 48;
private int tick;
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
try
{
Install();
}
catch (Exception ex)
{
Log.LogError((object)("install failed: " + ex));
}
}
private void Install()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Expected O, but got Unknown
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Expected O, but got Unknown
Harmony h = new Harmony("aimod.VoidFleetCap");
Type t = typeof(CombatModuleComponent);
HarmonyMethod prep = new HarmonyMethod(typeof(Patches).GetMethod("Prep"));
HarmonyMethod finish = new HarmonyMethod(typeof(Patches).GetMethod("Finish"));
HarmonyMethod clamp = new HarmonyMethod(typeof(Patches).GetMethod("Clamp"));
P("GameTick/clamp", delegate
{
h.Patch((MethodBase)t.GetMethod("GameTick", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), clamp, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
});
P("Import", delegate
{
h.Patch((MethodBase)t.GetMethod("Import", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), (HarmonyMethod)null, finish, (HarmonyMethod)null, (HarmonyMethod)null);
});
try
{
MethodInfo method = t.GetMethod("AutoReplenishAllFleets", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method != null)
{
h.Patch((MethodBase)method, new HarmonyMethod(typeof(Patches).GetMethod("ReplenishPrep")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
MethodInfo method2 = t.GetMethod("ReplenishFleet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method2 != null)
{
h.Patch((MethodBase)method2, new HarmonyMethod(typeof(Patches).GetMethod("ReplenishIndex")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
catch (Exception ex)
{
Log.LogWarning((object)("replenish patch: " + ex.Message));
}
MethodInfo[] methods = t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!(methodInfo.Name != "Setup"))
{
MethodInfo mm = methodInfo;
ParameterInfo[] parameters = methodInfo.GetParameters();
string text = ((parameters.Length != 0) ? parameters[0].ParameterType.Name : "?");
P("Setup(" + text + ")", delegate
{
h.Patch((MethodBase)mm, prep, finish, (HarmonyMethod)null, (HarmonyMethod)null);
});
}
}
P("UIMechaWindow._OnCreate/pageButtons", delegate
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
h.Patch((MethodBase)AccessTools.Method(typeof(UIMechaWindow), "_OnCreate", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches).GetMethod("PageButtons")), (HarmonyMethod)null, (HarmonyMethod)null);
});
P("TechProto.GetHashNeeded", delegate
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
h.Patch((MethodBase)AccessTools.Method(typeof(TechProto), "GetHashNeeded", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches).GetMethod("HashNeeded")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
});
P("UIZS_FleetPanel.RefreshCompletely/entries", delegate
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
h.Patch((MethodBase)AccessTools.Method(typeof(UIZS_FleetPanel), "RefreshCompletely", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches).GetMethod("ZSFleetEntries")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
});
Log.LogInfo((object)("1.3.5 installed, slots=" + 48 + " fleetTechMax=23 droneRateMax=20 droneDurabilityMax=30"));
AppDomain.CurrentDomain.AssemblyLoad += delegate(object s, AssemblyLoadEventArgs e)
{
try
{
TcfvDroplets.Attach(e.LoadedAssembly, h);
}
catch (Exception)
{
}
};
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly asm in assemblies)
{
try
{
TcfvDroplets.Attach(asm, h);
}
catch (Exception)
{
}
}
}
private static void P(string label, Action a)
{
try
{
a();
Log.LogInfo((object)(" patched " + label));
}
catch (Exception ex)
{
Log.LogError((object)(" patch " + label + " failed: " + ex.Message));
}
}
private void Update()
{
if (++tick % 60 != 0)
{
return;
}
try
{
TechCap.Apply();
}
catch (Exception ex)
{
Log.LogWarning((object)("tech: " + ex.Message));
}
try
{
FleetSync.Apply();
}
catch (Exception ex2)
{
Log.LogWarning((object)("sync: " + ex2.Message));
}
}
}
internal static class Patches
{
public static void Prep(CombatModuleComponent __instance)
{
Cap.Shrink(__instance, 8);
}
public static void Finish(CombatModuleComponent __instance)
{
Cap.Expand(__instance);
}
public static void Clamp(CombatModuleComponent __instance)
{
Cap.Clamp(__instance);
}
public static void DropletGuard()
{
TcfvDroplets.Ensure();
}
public static void PageButtons(object __instance)
{
PageExpand.Run(__instance);
}
public static void ZSFleetEntries(UIZS_FleetPanel __instance)
{
ZSPanel.Fill(__instance);
}
public static void ReplenishPrep(CombatModuleComponent __instance)
{
try
{
Cap.Expand(__instance);
Cap.Clamp(__instance);
}
catch (Exception)
{
}
}
public static bool ReplenishIndex(CombatModuleComponent __instance, int fleetIndex)
{
try
{
object value = AccessTools.Field(typeof(CombatModuleComponent), "moduleFleets").GetValue(__instance);
if (!(value is Array array))
{
return true;
}
return fleetIndex >= 0 && fleetIndex < array.Length;
}
catch (Exception)
{
return true;
}
}
public static bool HashNeeded(TechProto __instance, int levelRequest, ref long __result)
{
try
{
if (__instance == null)
{
return true;
}
if (!TechCap.BaseHash.TryGetValue(((Proto)__instance).ID, out var value))
{
return true;
}
if (!TechCap.BaseLevel.TryGetValue(((Proto)__instance).ID, out var value2))
{
return true;
}
int maxLevel = __instance.MaxLevel;
int num = levelRequest;
if (num > maxLevel)
{
num = maxLevel;
}
if (num < value2)
{
num = value2;
}
if (num <= value2)
{
__result = value;
return false;
}
if (TechCap.Points.TryGetValue(((Proto)__instance).ID, out var value3) && value3 > 0)
{
double num2 = 1000000.0 * Math.Pow((double)num / 20.0, 3.0);
long num3 = (long)Math.Round(num2 * 3600.0 / (double)value3);
if (num3 < value)
{
num3 = value;
}
__result = num3;
return false;
}
double num4 = (double)num / (double)value2;
__result = (long)Math.Round((double)value * num4 * num4);
return false;
}
catch (Exception)
{
return true;
}
}
}
internal static class Cap
{
private static FieldInfo ff;
private static FieldInfo fp;
private static FieldInfo fCount;
private static FieldInfo fProto;
private static FieldInfo fIsSpace;
private static MethodInfo mCreate;
private static MethodInfo mSet2;
private static MethodInfo mSet3;
private static Type mSet3Type;
private static FieldInfo fGround;
private static FieldInfo fSmall;
private static FieldInfo fLarge;
private static bool logged;
internal static int Slots => 48;
private static void Fields()
{
if (ff != null)
{
return;
}
ff = typeof(CombatModuleComponent).GetField("moduleFleets", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
fp = typeof(CombatModuleComponent).GetField("moduleFleetPoses", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
fCount = typeof(CombatModuleComponent).GetField("fleetCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
fIsSpace = typeof(CombatModuleComponent).GetField("isSpace", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (ff == null)
{
return;
}
Type elementType = ff.FieldType.GetElementType();
fProto = elementType.GetField("protoId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
mCreate = elementType.GetMethod("Create", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(int) }, null);
MethodInfo[] methods = elementType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!(methodInfo.Name != "SetItemId"))
{
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length == 2)
{
mSet2 = methodInfo;
}
else if (parameters.Length == 3)
{
mSet3 = methodInfo;
mSet3Type = parameters[2].ParameterType;
}
}
}
fGround = typeof(ItemProto).GetField("kFighterGroundIds", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
fSmall = typeof(ItemProto).GetField("kFighterSpaceSmallIds", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
fLarge = typeof(ItemProto).GetField("kFighterSpaceLargeIds", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
internal static bool IsMecha(CombatModuleComponent c)
{
try
{
if (c == null || GameMain.mainPlayer == null)
{
return false;
}
Mecha mecha = GameMain.mainPlayer.mecha;
if (mecha == null)
{
return false;
}
return c == mecha.groundCombatModule || c == mecha.spaceCombatModule;
}
catch (Exception)
{
return false;
}
}
internal static void Shrink(CombatModuleComponent c, int len)
{
try
{
Fields();
if (c != null && !(ff == null))
{
ResizeTo(ff, c, len);
ResizeTo(fp, c, len);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("shrink: " + ex.Message));
}
}
internal static void Expand(CombatModuleComponent c)
{
try
{
Fields();
if (c != null && !(ff == null) && !(fp == null) && IsMecha(c))
{
ResizeTo(ff, c, Slots);
ResizeTo(fp, c, Slots);
FillFleets(c);
FillPoses(c);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("expand: " + ex.Message));
}
}
private static void FillFleets(CombatModuleComponent c)
{
if (!(ff.GetValue(c) is Array array) || fProto == null)
{
return;
}
object value = array.GetValue(0);
if (value == null)
{
return;
}
int num = (int)fProto.GetValue(value);
if (num == 0)
{
return;
}
bool space = fIsSpace != null && (bool)fIsSpace.GetValue(c);
int ground = IdOf(fGround);
int small = IdOf(fSmall);
int large = IdOf(fLarge);
int num2 = 0;
for (int i = 1; i < array.Length; i++)
{
object value2 = array.GetValue(i);
if (value2 != null && (int)fProto.GetValue(value2) == 0)
{
object obj = Make(num, space, ground, small, large);
if (obj != null)
{
array.SetValue(obj, i);
num2++;
}
}
}
if (!logged)
{
logged = true;
Plugin.Log.LogInfo((object)("slots ready: len=" + array.Length + " made=" + num2));
}
}
private static object Make(int protoId, bool space, int ground, int small, int large)
{
if (mCreate == null)
{
return null;
}
object obj = mCreate.Invoke(null, new object[1] { protoId });
try
{
if (space)
{
if (mSet3 != null && small > 0)
{
mSet3.Invoke(obj, new object[3]
{
-1,
small,
Size(0)
});
}
else if (mSet2 != null && small > 0)
{
mSet2.Invoke(obj, new object[2] { -1, small });
}
if (mSet3 != null && large > 0)
{
mSet3.Invoke(obj, new object[3]
{
-1,
large,
Size(1)
});
}
}
else if (ground > 0)
{
if (mSet2 != null)
{
mSet2.Invoke(obj, new object[2] { -1, ground });
}
else if (mSet3 != null)
{
mSet3.Invoke(obj, new object[3]
{
-1,
ground,
Size(0)
});
}
}
}
catch (Exception)
{
}
return obj;
}
private static object Size(int v)
{
if (mSet3Type == null)
{
return v;
}
try
{
return Enum.ToObject(mSet3Type, v);
}
catch (Exception)
{
return v;
}
}
private static int IdOf(FieldInfo f)
{
try
{
if (f == null)
{
return 0;
}
if (!(f.GetValue(null) is int[] array) || array.Length == 0)
{
return 0;
}
return array[0];
}
catch (Exception)
{
return 0;
}
}
private static void FillPoses(CombatModuleComponent c)
{
if (!(fp.GetValue(c) is Array { Length: >8 } array))
{
return;
}
for (int i = 8; i < array.Length; i++)
{
object value = array.GetValue(i % 8);
if (value != null)
{
array.SetValue(value, i);
}
}
}
internal static void Clamp(CombatModuleComponent c)
{
try
{
Fields();
if (c != null && !(ff == null) && !(fCount == null) && ff.GetValue(c) is Array array)
{
int num = (int)fCount.GetValue(c);
if (num > array.Length)
{
fCount.SetValue(c, array.Length);
}
}
}
catch (Exception)
{
}
}
private static void ResizeTo(FieldInfo f, object o, int len)
{
if (f.GetValue(o) is Array array && array.Length != len)
{
Type elementType = array.GetType().GetElementType();
int length = Math.Min(array.Length, len);
Array array2 = Array.CreateInstance(elementType, len);
Array.Copy(array, array2, length);
f.SetValue(o, array2);
}
}
}
internal static class TcfvDroplets
{
private static bool patched;
private static Type type;
private static FieldInfo fPool;
private static FieldInfo fLen;
private static FieldInfo fList;
internal static void Attach(Assembly asm, Harmony h)
{
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Expected O, but got Unknown
if (patched || asm == null)
{
return;
}
string name;
try
{
name = asm.GetName().Name;
}
catch (Exception)
{
return;
}
if (name != "DSP_Battle")
{
return;
}
Type type = asm.GetType("DSP_Battle.Droplets");
if (type == null)
{
return;
}
TcfvDroplets.type = type;
fPool = type.GetField("dropletPool", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
fLen = type.GetField("dropletArrayLength", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
fList = type.GetField("warpRushCharge", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
Ensure();
MethodInfo methodInfo = null;
MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo2 in methods)
{
if (methodInfo2.Name == "GameData_GameTick")
{
methodInfo = methodInfo2;
break;
}
}
if (methodInfo == null)
{
Plugin.Log.LogWarning((object)"DSP_Battle.Droplets: GameData_GameTick not found");
return;
}
h.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Patches).GetMethod("DropletGuard")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
patched = true;
Plugin.Log.LogInfo((object)" patched DSP_Battle.Droplets.GameData_GameTick + dropletPool");
}
internal static void Ensure()
{
try
{
if (type == null || fPool == null || !(fPool.GetValue(null) is Array array))
{
return;
}
int num = 144;
if (array.Length >= num)
{
return;
}
Type elementType = array.GetType().GetElementType();
ConstructorInfo constructor = elementType.GetConstructor(new Type[1] { typeof(int) });
Array array2 = Array.CreateInstance(elementType, num);
Array.Copy(array, array2, array.Length);
for (int i = array.Length; i < num; i++)
{
object value = ((constructor != null) ? constructor.Invoke(new object[1] { i }) : Activator.CreateInstance(elementType));
array2.SetValue(value, i);
}
fPool.SetValue(null, array2);
if (fLen != null)
{
fLen.SetValue(null, num);
}
if (fList != null && fList.GetValue(null) is IList list)
{
while (list.Count < num)
{
list.Add(0);
}
}
Plugin.Log.LogInfo((object)("dropletPool expanded: " + array.Length + " -> " + num));
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("dropletPool: " + ex.Message));
}
}
}
internal static class FleetSync
{
internal const int VanillaLevel = 7;
internal const int VanillaFleets = 8;
private static int lastG = -1;
private static int lastS = -1;
private static FieldInfo ff;
private static FieldInfo fFleetId;
internal static void Apply()
{
if (GameMain.mainPlayer != null)
{
Mecha mecha = GameMain.mainPlayer.mecha;
if (mecha != null)
{
Sync(mecha.groundCombatModule, TechCap.LevelOf("地面编队扩容"), "ground", ref lastG);
Sync(mecha.spaceCombatModule, TechCap.LevelOf("太空编队扩容"), "space", ref lastS);
}
}
}
internal static int Pages(int squads)
{
return (squads - 1) / 4 + 1;
}
private static void Sync(CombatModuleComponent c, int level, string tag, ref int last)
{
if (c == null)
{
return;
}
Cap.Expand(c);
if (level <= 7)
{
if (level != last)
{
Plugin.Log.LogInfo((object)(tag + " vanilla range, fleetCount=" + c.fleetCount + " (tech Lv" + level + ", " + Pages(c.fleetCount) + " pages)"));
}
last = level;
return;
}
int num = 8 + 2 * (level - 7);
if (num > 48)
{
num = 48;
}
if (num < 1)
{
num = 1;
}
int fleetCount = c.fleetCount;
if (fleetCount != num)
{
if (fleetCount > num)
{
int num2 = ActiveFleets(c, num);
if (num2 > 0)
{
if (level != last)
{
Plugin.Log.LogInfo((object)(tag + " fleetCount=" + fleetCount + " (tech Lv" + level + ", want " + num + ", " + num2 + " launched, keep)"));
}
last = level;
return;
}
}
c.fleetCount = num;
Plugin.Log.LogInfo((object)(tag + " fleetCount: " + fleetCount + " -> " + num + " (tech Lv" + level + ", " + Pages(num) + " pages)"));
}
else if (level != last)
{
Plugin.Log.LogInfo((object)(tag + " fleetCount=" + fleetCount + " (tech Lv" + level + ", " + Pages(num) + " pages)"));
}
last = level;
}
private static int ActiveFleets(CombatModuleComponent c, int from)
{
try
{
if (ff == null)
{
ff = typeof(CombatModuleComponent).GetField("moduleFleets", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
if (ff == null)
{
return 0;
}
if (!(ff.GetValue(c) is Array array))
{
return 0;
}
int num = 0;
for (int i = from; i < array.Length; i++)
{
object value = array.GetValue(i);
if (value != null)
{
if (fFleetId == null)
{
fFleetId = value.GetType().GetField("fleetId", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
if (!(fFleetId == null) && (int)fFleetId.GetValue(value) != 0)
{
num++;
}
}
}
return num;
}
catch (Exception)
{
return 0;
}
}
}
internal static class PageExpand
{
internal const int Need = 12;
internal static void Run(object window)
{
try
{
if (window == null)
{
return;
}
Type type = window.GetType();
FieldInfo field = type.GetField("fleetPageButtons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo field2 = type.GetField("fleetPageButton", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field == null || field2 == null)
{
return;
}
Array array = field.GetValue(window) as Array;
object? value = field2.GetValue(window);
Component val = (Component)((value is Component) ? value : null);
if (array == null || (Object)(object)val == (Object)null || array.Length >= 12)
{
return;
}
Type elementType = array.GetType().GetElementType();
Array array2 = Array.CreateInstance(elementType, 12);
Array.Copy(array, array2, array.Length);
Transform parent = val.transform.parent;
for (int i = array.Length; i < 12; i++)
{
Component val2 = Object.Instantiate<Component>(val, parent);
if ((Object)(object)val2 != (Object)null)
{
array2.SetValue(val2, i);
}
}
field.SetValue(window, array2);
Plugin.Log.LogInfo((object)("fleet page buttons: " + array.Length + " -> " + 12));
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("pageButtons: " + ex.Message));
}
}
}
internal static class ZSPanel
{
internal static void Fill(UIZS_FleetPanel p)
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
try
{
if ((Object)(object)p == (Object)null)
{
return;
}
Type typeFromHandle = typeof(UIZS_FleetPanel);
FieldInfo fieldInfo = AccessTools.Field(typeFromHandle, "mecha");
object obj = ((fieldInfo != null) ? fieldInfo.GetValue(p) : null);
if (obj != null)
{
Type type = obj.GetType();
CombatModuleComponent val = (CombatModuleComponent)AccessTools.Field(type, "groundCombatModule").GetValue(obj);
CombatModuleComponent val2 = (CombatModuleComponent)AccessTools.Field(type, "spaceCombatModule").GetValue(obj);
int num = 4;
if (val != null && val.fleetCount > num)
{
num = val.fleetCount;
}
if (val2 != null && val2.fleetCount > num)
{
num = val2.fleetCount;
}
if (num > 48)
{
num = 48;
}
FillOne(typeFromHandle, p, "gFleetEntries", "groundFleetEntry", val, num);
FillOne(typeFromHandle, p, "sFleetEntries", "SpaceFleetEntry", val2, num);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("zsPanel: " + ex.Message));
}
}
private static void FillOne(Type t, UIZS_FleetPanel p, string listName, string tplName, CombatModuleComponent mod, int want)
{
FieldInfo fieldInfo = AccessTools.Field(t, listName);
FieldInfo fieldInfo2 = AccessTools.Field(t, tplName);
if (fieldInfo == null || fieldInfo2 == null || mod == null)
{
return;
}
IList list = fieldInfo.GetValue(p) as IList;
object? value = fieldInfo2.GetValue(p);
UIZS_FleetEntry val = (UIZS_FleetEntry)((value is UIZS_FleetEntry) ? value : null);
if (list == null || (Object)(object)val == (Object)null)
{
return;
}
int num = 0;
while (list.Count > want)
{
int index = list.Count - 1;
object? obj = list[index];
UIZS_FleetEntry val2 = (UIZS_FleetEntry)((obj is UIZS_FleetEntry) ? obj : null);
list.RemoveAt(index);
if ((Object)(object)val2 != (Object)null)
{
try
{
Object.Destroy((Object)(object)((Component)val2).gameObject);
}
catch (Exception)
{
}
}
}
while (list.Count < want)
{
int count = list.Count;
UIZS_FleetEntry val3 = Object.Instantiate<UIZS_FleetEntry>(val, ((Component)val).transform.parent);
if ((Object)(object)val3 == (Object)null)
{
break;
}
((ManualBehaviour)val3)._Create();
val3.fleetIndex = count;
val3.fleetProtoId = ((count < mod.moduleFleets.Length) ? mod.moduleFleets[count].protoId : 0);
val3.fleetPanel = p;
try
{
((ManualBehaviour)val3)._Init((object)GameMain.data);
}
catch (Exception)
{
}
list.Add(val3);
num++;
}
if (num > 0)
{
Plugin.Log.LogInfo((object)(listName + " entries: +" + num + " -> " + list.Count));
}
}
}
internal static class TechCap
{
private struct Target
{
public string Name;
public int Tier;
public int Max;
}
private static readonly Target[] Targets = new Target[4]
{
new Target
{
Name = "地面编队扩容",
Tier = 7,
Max = 23
},
new Target
{
Name = "太空编队扩容",
Tier = 7,
Max = 23
},
new Target
{
Name = "战斗无人机射速",
Tier = 5,
Max = 20
},
new Target
{
Name = "战斗无人机耐久",
Tier = 5,
Max = 30
}
};
internal static readonly Dictionary<int, long> BaseHash = new Dictionary<int, long>();
internal static readonly Dictionary<int, int> BaseLevel = new Dictionary<int, int>();
internal static readonly Dictionary<int, int> Points = new Dictionary<int, int>();
private static readonly Dictionary<string, TechProto> cache = new Dictionary<string, TechProto>();
private static bool logged;
internal static TechProto Find(string name, int tier)
{
TechProto[] array = (((Object)(object)LDB.techs != (Object)null) ? ((ProtoSet<TechProto>)(object)LDB.techs).dataArray : null);
if (array == null)
{
return null;
}
TechProto val = null;
TechProto[] array2 = array;
foreach (TechProto val2 in array2)
{
if (val2 != null && !(((Proto)val2).name != name))
{
if (val2.Level == tier)
{
return val2;
}
if (val == null || val2.Level > val.Level)
{
val = val2;
}
}
}
return val;
}
private static Target TargetOf(string name)
{
Target[] targets = Targets;
for (int i = 0; i < targets.Length; i++)
{
Target result = targets[i];
if (result.Name == name)
{
return result;
}
}
return new Target
{
Name = name,
Tier = 7,
Max = 23
};
}
internal static TechProto Of(string name)
{
if (cache.TryGetValue(name, out var value) && value != null)
{
return value;
}
value = Find(name, TargetOf(name).Tier);
if (value != null)
{
cache[name] = value;
}
return value;
}
internal static int IdOf(string name)
{
return ((Proto)(Of(name)?)).ID ?? 0;
}
internal static int LevelOf(string name)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
if (GameMain.history == null)
{
return -1;
}
TechProto val = Of(name);
if (val == null)
{
return -1;
}
if (!GameMain.history.techStates.TryGetValue(((Proto)val).ID, out var value))
{
return 0;
}
return value.curLevel;
}
internal static void Apply()
{
//IL_0211: 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_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
//IL_0508: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)LDB.techs == (Object)null || ((ProtoSet<TechProto>)(object)LDB.techs).dataArray == null)
{
return;
}
GameHistoryData history = GameMain.history;
if (history == null)
{
return;
}
List<string> list = new List<string>();
Target[] targets = Targets;
for (int i = 0; i < targets.Length; i++)
{
Target target = targets[i];
TechProto val = Find(target.Name, target.Tier);
if (val == null)
{
list.Add(target.Name + ":NOTFOUND");
continue;
}
if (val.Level != target.Tier)
{
string[] obj = new string[6] { target.Name, ":TIERMISS(want", null, null, null, null };
int tier = target.Tier;
obj[2] = tier.ToString();
obj[3] = ",got";
obj[4] = val.Level.ToString();
obj[5] = ")";
list.Add(string.Concat(obj));
}
if (!BaseHash.ContainsKey(((Proto)val).ID))
{
int num = Math.Max(1, val.Level);
BaseLevel[((Proto)val).ID] = num;
BaseHash[((Proto)val).ID] = val.GetHashNeeded(num);
int num2 = 0;
if (val.ItemPoints != null)
{
int[] itemPoints = val.ItemPoints;
foreach (int num3 in itemPoints)
{
if (num3 > num2)
{
num2 = num3;
}
}
}
Points[((Proto)val).ID] = num2;
}
if (val.MaxLevel != target.Max)
{
val.MaxLevel = target.Max;
}
if (history.techStates != null && history.techStates.TryGetValue(((Proto)val).ID, out var value))
{
bool flag = false;
if (value.maxLevel != target.Max)
{
value.maxLevel = target.Max;
flag = true;
}
if (value.curLevel > target.Max)
{
value.curLevel = target.Max;
flag = true;
}
if (flag)
{
history.techStates[((Proto)val).ID] = value;
}
}
list.Add(target.Name + ":id" + ((Proto)val).ID + "/Lv" + val.Level + "/max" + val.MaxLevel + "/base" + BaseHash[((Proto)val).ID] + "@L" + BaseLevel[((Proto)val).ID] + "/pts" + (Points.ContainsKey(((Proto)val).ID) ? Points[((Proto)val).ID] : (-1)) + "/h" + val.GetHashNeeded(val.Level) + "->" + val.GetHashNeeded(target.Max) + "/cur" + CurLevel(((Proto)val).ID));
}
try
{
int num4 = 0;
TechProto[] dataArray = ((ProtoSet<TechProto>)(object)LDB.techs).dataArray;
foreach (TechProto val2 in dataArray)
{
if (val2 == null)
{
continue;
}
bool flag2 = false;
Target[] targets2 = Targets;
for (int l = 0; l < targets2.Length; l++)
{
Target target2 = targets2[l];
if (target2.Name == ((Proto)val2).name && target2.Tier == val2.Level)
{
flag2 = true;
break;
}
}
if (!flag2 && history.techStates != null && history.techStates.TryGetValue(((Proto)val2).ID, out var value2) && value2.maxLevel > val2.MaxLevel)
{
value2.maxLevel = val2.MaxLevel;
if (value2.curLevel > val2.MaxLevel)
{
value2.curLevel = val2.MaxLevel;
}
history.techStates[((Proto)val2).ID] = value2;
if (num4 < 12)
{
Plugin.Log.LogInfo((object)("repair tech state: " + ((Proto)val2).name + " id" + ((Proto)val2).ID + " max " + value2.maxLevel + " cur " + value2.curLevel));
}
num4++;
}
}
if (num4 > 0)
{
Plugin.Log.LogInfo((object)("repair tech state: " + num4 + " techs clamped back to vanilla max"));
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("repair: " + ex.Message));
}
if (!logged)
{
logged = true;
Plugin.Log.LogInfo((object)("tech: " + string.Join(" | ", list.ToArray())));
DumpLevels("地面编队扩容");
DumpLevels("太空编队扩容");
DumpLevels("战斗无人机射速");
DumpLevels("战斗无人机耐久");
}
}
private static string CurLevel(int id)
{
if (GameMain.history != null && GameMain.history.techStates.TryGetValue(id, out var value))
{
return value.curLevel + "/" + value.maxLevel;
}
return "?";
}
private static void DumpLevels(string name)
{
TechProto val = Of(name);
if (val == null)
{
Plugin.Log.LogInfo((object)("levels " + name + ": NOTFOUND"));
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("levels ").Append(name).Append(" id")
.Append(((Proto)val).ID)
.Append(" max")
.Append(val.MaxLevel)
.Append(": ");
int num = Math.Max(1, val.Level);
int num2 = Math.Min(val.MaxLevel, num + 30);
for (int i = num; i <= num2; i++)
{
stringBuilder.Append(i).Append("=").Append(val.GetHashNeeded(i));
if (i != num2)
{
stringBuilder.Append(", ");
}
}
Plugin.Log.LogInfo((object)stringBuilder.ToString());
}
}