using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.0.4.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace DSPCompleteReplicatorQueue
{
public static class InstantCraft
{
public static void CompleteAllTasks(MechaForge forge)
{
if ((Object)(object)Main.Instance != (Object)null)
{
Main.Instance.Request(forge);
}
}
}
[BepInPlugin("Appun.DSP.plugin.DSPCompleteReplicatorQueue", "DSPCompleteReplicatorQueue", "1.0.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Main : BaseUnityPlugin
{
public const string Guid = "Appun.DSP.plugin.DSPCompleteReplicatorQueue";
internal static Main Instance;
private Harmony harmony;
private QueueCompletion completion;
internal bool Busy
{
get
{
if (completion != null)
{
return completion.Active;
}
return false;
}
}
private void Awake()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
Instance = this;
harmony = new Harmony("Appun.DSP.plugin.DSPCompleteReplicatorQueue");
harmony.PatchAll(typeof(WindowUI));
}
internal void Request(MechaForge forge)
{
if (!Busy)
{
completion = new QueueCompletion(forge);
if (!completion.Active && completion.StopReason != null)
{
ReportStop(completion.StopReason);
}
}
}
private void Update()
{
if (!Busy)
{
return;
}
if (!GameMain.isRunning || GameMain.isLoading || GameMain.mainPlayer == null || completion.Forge.player != GameMain.mainPlayer)
{
Cancel();
}
else
{
if (GameMain.isPaused)
{
return;
}
QueueCompletion queueCompletion = completion;
try
{
queueCompletion.ProcessBatch(GameMain.gameTick);
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
if (queueCompletion == completion && !queueCompletion.Active)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Complete Queue: " + queueCompletion.CompletedCycles + " native production cycles completed."));
if (queueCompletion.StopReason != null)
{
ReportStop(queueCompletion.StopReason);
}
}
}
}
private void ReportStop(string reason)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)reason);
UIRealtimeTip.Popup("Complete Queue: " + reason, true, 0);
}
internal void Cancel()
{
if (completion != null)
{
completion.Stop("Completion cancelled; remaining queue preserved.");
}
completion = null;
}
private void OnDestroy()
{
Cancel();
WindowUI.Remove();
if (harmony != null)
{
harmony.UnpatchSelf();
}
if (Instance == this)
{
Instance = null;
}
}
internal void Log(Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
}
public sealed class QueueCompletion
{
private readonly Dictionary<ForgeTask, int> observed = new Dictionary<ForgeTask, int>();
private bool processing;
public MechaForge Forge { get; private set; }
public bool Active { get; private set; }
public int CompletedCycles { get; private set; }
public string StopReason { get; private set; }
public QueueCompletion(MechaForge forge)
{
Forge = forge;
if (forge == null || forge.tasks == null || forge.tasks.Count == 0)
{
return;
}
for (int i = 0; i < forge.tasks.Count; i++)
{
ForgeTask val = forge.tasks[i];
if (!Valid(val) || observed.ContainsKey(val) || (val.parentTaskIndex >= 0 && (val.parentTaskIndex <= i || val.parentTaskIndex >= forge.tasks.Count)))
{
Stop("Invalid task state; queue left unchanged.");
return;
}
observed.Add(val, val.count);
}
Active = true;
}
private static bool Valid(ForgeTask task)
{
if (task == null || task.count <= 0 || task.tickSpend <= 0 || task.itemIds == null || task.itemCounts == null || task.served == null || task.productIds == null || task.productCounts == null || task.produced == null || task.itemIds.Length != task.itemCounts.Length || task.served.Length != task.itemCounts.Length || task.productIds.Length != task.productCounts.Length || task.produced.Length != task.productCounts.Length)
{
return false;
}
for (int i = 0; i < task.itemCounts.Length; i++)
{
if (task.itemIds[i] <= 0 || task.itemCounts[i] <= 0 || task.served[i] < 0)
{
return false;
}
}
for (int j = 0; j < task.productCounts.Length; j++)
{
if (task.productIds[j] <= 0 || task.productCounts[j] <= 0 || task.produced[j] != 0)
{
return false;
}
}
return true;
}
public void Stop(string reason)
{
Active = false;
StopReason = reason;
}
public int ProcessBatch(long gameTick, int maxCycles = 128, double maxMilliseconds = 4.0)
{
if (!Active || processing || maxCycles <= 0 || maxMilliseconds <= 0.0)
{
return 0;
}
int num = 0;
Stopwatch stopwatch = Stopwatch.StartNew();
processing = true;
try
{
while (Active && num < maxCycles && stopwatch.Elapsed.TotalMilliseconds < maxMilliseconds)
{
if (Forge.tasks == null || Forge.player == null || Forge.mecha == null || !Forge.player.isAlive)
{
Stop("Forge or player is no longer available.");
break;
}
if (Forge.tasks.Count == 0)
{
Stop(null);
break;
}
ForgeTask val = Forge.tasks[0];
if (val == null || !observed.TryGetValue(val, out var value) || val.count > value)
{
Stop("Queue changed; press Complete Queue again to include new tasks.");
break;
}
if (!Valid(val) || !val.itemEnough || (val.parentTaskIndex >= 0 && (val.parentTaskIndex == 0 || val.parentTaskIndex >= Forge.tasks.Count || !observed.ContainsKey(Forge.tasks[val.parentTaskIndex]))))
{
Stop("Missing inputs or invalid task state; remaining queue preserved.");
break;
}
int count = val.count;
int tick = val.tick;
val.tick = Math.Max(val.tick, val.tickSpend);
try
{
Forge.GameTick(gameTick, 0f);
}
catch
{
if (val.count == count)
{
val.tick = tick;
}
Stop("Native forge raised an error; accelerated completion stopped.");
throw;
}
if (val.count != count - 1)
{
if (val.count == count)
{
val.tick = tick;
}
Stop("Native forge made no expected progress; remaining queue preserved.");
break;
}
observed[val] = val.count;
num++;
CompletedCycles++;
if (Forge.tasks == null || Forge.tasks.Count == 0)
{
Stop(null);
}
}
}
finally
{
processing = false;
}
return num;
}
}
[HarmonyPatch]
internal static class WindowUI
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__7_0;
internal void <Ensure>b__7_0()
{
InstantCraft.CompleteAllTasks(GetForge(owner));
}
}
private static UIReplicatorWindow owner;
private static Button button;
private static Text label;
private static bool createFailed;
private static readonly FieldInfo ForgeField = typeof(UIReplicatorWindow).GetField("mechaForge", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
private static MechaForge GetForge(UIReplicatorWindow window)
{
if (!((Object)(object)window != (Object)null) || !(ForgeField != null))
{
return null;
}
object? value = ForgeField.GetValue(window);
return (MechaForge)((value is MechaForge) ? value : null);
}
internal static void Remove()
{
if ((Object)(object)button != (Object)null)
{
((UnityEventBase)button.onClick).RemoveAllListeners();
((Component)button).gameObject.SetActive(false);
Object.Destroy((Object)(object)((Component)button).gameObject);
}
button = null;
label = null;
owner = null;
createFailed = false;
}
private static void Ensure(UIReplicatorWindow window)
{
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Expected O, but got Unknown
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: 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_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_0200: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Unknown result type (might be due to invalid IL or missing references)
//IL_024f: 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_0280: Unknown result type (might be due to invalid IL or missing references)
//IL_0292: Unknown result type (might be due to invalid IL or missing references)
//IL_0299: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
//IL_0312: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0354: Unknown result type (might be due to invalid IL or missing references)
//IL_0359: Unknown result type (might be due to invalid IL or missing references)
//IL_035f: Expected O, but got Unknown
if (((Object)(object)button != (Object)null && (Object)(object)owner == (Object)(object)window) || (createFailed && (Object)(object)owner == (Object)(object)window))
{
return;
}
Remove();
owner = window;
GameObject val = null;
try
{
Transform val2 = ((Component)window).transform.Find("panel-bg");
if ((Object)(object)val2 == (Object)null || (Object)(object)window.minusButton == (Object)null)
{
return;
}
Image component = ((Component)window.minusButton).GetComponent<Image>();
val = new GameObject("DSPCompleteReplicatorQueueButton", new Type[3]
{
typeof(RectTransform),
typeof(Image),
typeof(Button)
});
val.SetActive(false);
val.transform.SetParent(val2, false);
RectTransform component2 = val.GetComponent<RectTransform>();
Transform obj = val2.Find("btn-box");
RectTransform val3 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
component2.anchorMin = (Vector2)(((Object)(object)val3 != (Object)null) ? val3.anchorMin : new Vector2(1f, 1f));
component2.anchorMax = (Vector2)(((Object)(object)val3 != (Object)null) ? val3.anchorMax : new Vector2(1f, 1f));
component2.pivot = new Vector2(1f, 0.5f);
component2.sizeDelta = new Vector2(235f, 30f);
component2.anchoredPosition = new Vector2(-28f, -65f);
Image component3 = val.GetComponent<Image>();
if ((Object)(object)component != (Object)null)
{
component3.sprite = component.sprite;
component3.type = component.type;
((Graphic)component3).material = ((Graphic)component).material;
}
((Graphic)component3).color = Color.white;
button = val.GetComponent<Button>();
((Selectable)button).targetGraphic = (Graphic)(object)component3;
ColorBlock colors = ((Selectable)button).colors;
((ColorBlock)(ref colors)).normalColor = new Color(0.05f, 0.09f, 0.09f, 0.25f);
((ColorBlock)(ref colors)).highlightedColor = new Color(0.16f, 0.18f, 0.18f, 0.7f);
((ColorBlock)(ref colors)).pressedColor = new Color(0.18f, 0.27f, 0.27f, 0.7f);
((ColorBlock)(ref colors)).disabledColor = new Color(0.05f, 0.09f, 0.09f, 0.05f);
((Selectable)button).colors = colors;
GameObject val4 = new GameObject("text", new Type[2]
{
typeof(RectTransform),
typeof(Text)
});
val4.transform.SetParent(val.transform, false);
RectTransform component4 = val4.GetComponent<RectTransform>();
component4.anchorMin = Vector2.zero;
component4.anchorMax = Vector2.one;
component4.offsetMin = Vector2.zero;
component4.offsetMax = Vector2.zero;
label = val4.GetComponent<Text>();
label.font = window.multiValueText.font;
label.fontSize = 16;
label.alignment = (TextAnchor)4;
((Graphic)label).color = new Color(0.95f, 0.95f, 0.95f, 1f);
((Graphic)label).raycastTarget = false;
label.text = "Complete Replication Queue";
ButtonClickedEvent onClick = button.onClick;
object obj2 = <>c.<>9__7_0;
if (obj2 == null)
{
UnityAction val5 = delegate
{
InstantCraft.CompleteAllTasks(GetForge(owner));
};
<>c.<>9__7_0 = val5;
obj2 = (object)val5;
}
((UnityEvent)onClick).AddListener((UnityAction)obj2);
val.SetActive(true);
}
catch (Exception ex)
{
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
button = null;
label = null;
createFailed = true;
if ((Object)(object)Main.Instance != (Object)null)
{
Main.Instance.Log(ex);
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIReplicatorWindow), "_OnCreate")]
private static void Created(UIReplicatorWindow __instance)
{
Ensure(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIReplicatorWindow), "_OnOpen")]
private static void Opened(UIReplicatorWindow __instance)
{
createFailed = false;
Ensure(__instance);
}
[HarmonyPostfix]
[HarmonyPriority(0)]
[HarmonyPatch(typeof(UIReplicatorWindow), "_OnUpdate")]
private static void Updated(UIReplicatorWindow __instance)
{
Ensure(__instance);
if (!((Object)(object)button == (Object)null))
{
bool flag = (Object)(object)Main.Instance != (Object)null && Main.Instance.Busy;
MechaForge forge = GetForge(__instance);
((Selectable)button).interactable = !flag && forge != null && forge.tasks != null && forge.tasks.Count > 0;
label.text = (flag ? "Completing Queue..." : "Complete Replication Queue");
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIReplicatorWindow), "_OnFree")]
private static void Freed(UIReplicatorWindow __instance)
{
if ((Object)(object)owner == (Object)(object)__instance && (Object)(object)Main.Instance != (Object)null)
{
Main.Instance.Cancel();
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UIReplicatorWindow), "_OnDestroy")]
private static void Destroyed(UIReplicatorWindow __instance)
{
if (!((Object)(object)owner != (Object)(object)__instance))
{
if ((Object)(object)Main.Instance != (Object)null)
{
Main.Instance.Cancel();
}
Remove();
}
}
}
}