using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Localization;
using MTFO.Managers;
using MeltdownReactor.Json;
using MeltdownReactor.Json.PartialData;
using MeltdownReactor.ReactorData;
using Microsoft.CodeAnalysis;
using SNetwork;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Flowaria.MeltdownReactor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Flowaria.MeltdownReactor")]
[assembly: AssemblyTitle("Flowaria.MeltdownReactor")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 MeltdownReactor
{
[BepInPlugin("Flowaria.MeltdownReactor", "MeltdownReactor", "2.1.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class EntryPoint : BasePlugin
{
[CompilerGenerated]
private static class <>O
{
public static LiveEditEventHandler <0>__Listener_FileChanged1;
}
public const string PLUGIN_NAME = "MeltdownReactor";
public const string AUTHOR = "Flowaria";
public const string GUID = "Flowaria.MeltdownReactor";
public const string VERSION = "2.1.4";
public static string REACTOR_OVERRIDE_DATA_PATH = Path.Combine(MTFOUtil.CustomPath, "MeltdownReactor");
public static readonly Dictionary<uint, ReactorOverrideData> ReactorOverrideDatas = new Dictionary<uint, ReactorOverrideData>();
private Harmony m_Harmony;
private LiveEditListener listener;
public override void Load()
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Expected O, but got Unknown
MeltdownReactorLogger.Debug("This plugin is dev-ed based on Flowaria.MeltdownReactor, which is only used in rundowns Flowaria.Modulation and Flowaria.Paradigm");
MeltdownReactorLogger.Debug("All credits belong to Flowaria.");
if (!Directory.Exists(REACTOR_OVERRIDE_DATA_PATH))
{
Directory.CreateDirectory(REACTOR_OVERRIDE_DATA_PATH);
StreamWriter streamWriter = File.CreateText(Path.Combine(REACTOR_OVERRIDE_DATA_PATH, "Template.json"));
streamWriter.WriteLine(JSON.Serialize(new ReactorOverrideData()));
streamWriter.Flush();
streamWriter.Close();
return;
}
ClassInjector.RegisterTypeInIl2Cpp<MeltdownReactor>();
m_Harmony = new Harmony("Flowaria.MeltdownReactor");
m_Harmony.PatchAll();
foreach (string item in Directory.EnumerateFiles(REACTOR_OVERRIDE_DATA_PATH, "*.json", SearchOption.AllDirectories))
{
JSON.Load<ReactorOverrideData>(item, out var config);
if (ReactorOverrideDatas.ContainsKey(config.ObjectiveDataID))
{
MeltdownReactorLogger.Error($"Duplicate ObjectiveDataID {config.ObjectiveDataID}");
}
else
{
ReactorOverrideDatas.Add(config.ObjectiveDataID, config);
}
}
listener = LiveEdit.CreateListener(REACTOR_OVERRIDE_DATA_PATH, "*.json", true);
LiveEditListener obj = listener;
object obj2 = <>O.<0>__Listener_FileChanged1;
if (obj2 == null)
{
LiveEditEventHandler val = Listener_FileChanged1;
<>O.<0>__Listener_FileChanged1 = val;
obj2 = (object)val;
}
obj.FileChanged += (LiveEditEventHandler)obj2;
}
private static void Listener_FileChanged1(LiveEditEventArgs e)
{
MeltdownReactorLogger.Warning("LiveEdit File Changed: " + e.FullPath + ".");
LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
{
ReactorOverrideData reactorOverrideData = JSON.Deserialize<ReactorOverrideData>(content);
if (!ReactorOverrideDatas.ContainsKey(reactorOverrideData.ObjectiveDataID))
{
MeltdownReactorLogger.Error("Changing ObjectiveDataID is not allowed, will not update.");
}
else
{
ReactorOverrideDatas[reactorOverrideData.ObjectiveDataID] = reactorOverrideData;
MeltdownReactorLogger.Warning($"Updated override data with ObjectiveDataID {reactorOverrideData.ObjectiveDataID}");
}
});
}
}
public class MeltdownReactor : MonoBehaviour
{
private const string MAINTERMINAL_NAME = "Main Terminal";
private const float HIDE_TIMER_THRESHOLD = 43200f;
private static Color LowTemperature;
private static Color HighTemperature;
private static uint VerifyTextID;
private static uint MainTerminalTextID;
private static uint CooldownCommandDescTextID;
private static uint InfiniteWaveVerifyTextID;
internal static uint NotReadyForVerificationOutputTextID;
internal static uint IncorrectTerminalOutputTextID;
internal static uint CorrectTerminalOutputTextID;
private LG_Light[] _lights;
private float _updateTimer;
private Dictionary<int, LG_ComputerTerminal> verifyZoneOverrideTerminals = new Dictionary<int, LG_ComputerTerminal>();
internal ReactorOverrideData overrideData;
private Dictionary<int, string> meltdownWaveTerminalKeys;
private HashSet<int> infiniteWaveIndices;
private WardenObjectiveDataBlock objectiveDataBlock;
private Dictionary<TERM_Command, List<WardenObjectiveEventData>> commandEventMap = new Dictionary<TERM_Command, List<WardenObjectiveEventData>>();
private Dictionary<TERM_Command, List<TerminalOutput>> commandPostOutputMap = new Dictionary<TERM_Command, List<TerminalOutput>>();
internal LG_WardenObjective_Reactor ChainedReactor { get; set; }
public bool UsingLightEffect { get; set; } = true;
public bool IsCorrectTerminal(LG_ComputerTerminal terminal)
{
int num = ChainedReactor.m_currentWaveCount - 1;
if (num >= 0)
{
MeltdownReactorLogger.Error($"Index: {num}");
MeltdownReactorLogger.Error("Comp Terminal Key1: " + terminal.ItemKey);
MeltdownReactorLogger.Error("Comp Terminal Key2: " + (meltdownWaveTerminalKeys.ContainsKey(num) ? meltdownWaveTerminalKeys[num] : "empty"));
if (meltdownWaveTerminalKeys.ContainsKey(num) && meltdownWaveTerminalKeys[num].Equals(terminal.ItemKey, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
return false;
}
public void Init()
{
if (overrideData == null)
{
MeltdownReactorLogger.Error("ReactorOverrideData is null!");
return;
}
meltdownWaveTerminalKeys = new Dictionary<int, string>();
overrideData.MeltdownWaveIndices.ForEach(delegate(int index)
{
meltdownWaveTerminalKeys.TryAdd(index, string.Empty);
});
infiniteWaveIndices = overrideData.InfiniteWaveIndices.ToHashSet();
LevelAPI.OnEnterLevel += OnDrop;
if (VerifyTextID == 0)
{
VerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownVerification");
MainTerminalTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownMainTerminalName");
CooldownCommandDescTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CommandDesc");
InfiniteWaveVerifyTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.Verification.InfiniteWave");
NotReadyForVerificationOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.Not_ReadyForVerification_Output");
IncorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.IncorrectTerminal_Output");
CorrectTerminalOutputTextID = GameDataBlockBase<TextDataBlock>.GetBlockID("InGame.WardenObjective_Reactor.MeltdownCoolDown.CorrectTerminal_Output");
}
}
private void OnDrop()
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Invalid comparison between Unknown and I4
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
LG_WardenObjective_Reactor chainedReactor = ChainedReactor;
LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
objectiveDataBlock = GameDataBlockBase<WardenObjectiveDataBlock>.GetBlock(overrideData.ObjectiveDataID);
if (objectiveDataBlock == null)
{
MeltdownReactorLogger.Error($"Failed to get the Reactor Startup objective for layer {chainedReactor.SpawnNode.LayerType}");
return;
}
if ((int)objectiveDataBlock.Type != 1)
{
MeltdownReactorLogger.Error("Only Reactor Startup is supported");
((Behaviour)this).enabled = false;
return;
}
if (UsingLightEffect)
{
_lights = ((IEnumerable<LG_Light>)chainedReactor.SpawnNode.m_lightsInNode).Where((LG_Light x) => (int)x.m_category == 3).ToArray();
chainedReactor.m_lightCollection.RemoveLights(Il2CppReferenceArray<LG_Light>.op_Implicit(_lights));
}
if (overrideData.StartupOnDrop && SNet.IsMaster)
{
chainedReactor.AttemptInteract((eReactorInteraction)0, 0f);
terminal.TrySyncSetCommandHidden((TERM_Command)21);
}
SetupVerifyZoneOverride();
SetupMeltdownAndInfiniteWave();
if (overrideData.ReactorTerminal != null && overrideData.ReactorTerminal.TerminalPassword.PasswordProtected)
{
BuildReactorTerminalPassword();
}
}
private void SetupVerifyZoneOverride()
{
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
//IL_022a: Unknown result type (might be due to invalid IL or missing references)
//IL_0231: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_027d: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Unknown result type (might be due to invalid IL or missing references)
//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
//IL_030a: Unknown result type (might be due to invalid IL or missing references)
//IL_0324: Unknown result type (might be due to invalid IL or missing references)
LG_Zone val3 = default(LG_Zone);
foreach (VerifyZoneOverride verifyZoneOverride in overrideData.VerifyZoneOverrides)
{
if (verifyZoneOverrideTerminals.ContainsKey(verifyZoneOverride.WaveIndex))
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: Duplicate Wave Index {verifyZoneOverride.WaveIndex}");
continue;
}
if (infiniteWaveIndices.Contains(verifyZoneOverride.WaveIndex))
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: Wave Index {verifyZoneOverride.WaveIndex} is specified as Infinite Wave but VerifyZoneOverride is specified! Will not process");
continue;
}
if (verifyZoneOverride.WaveIndex < 0 || verifyZoneOverride.WaveIndex >= objectiveDataBlock.ReactorWaves.Count)
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: Invalid Wave Index {verifyZoneOverride.WaveIndex}. Valid value for this reactor is: [0, {objectiveDataBlock.ReactorWaves.Count - 1}]");
continue;
}
ReactorWaveData val = objectiveDataBlock.ReactorWaves[verifyZoneOverride.WaveIndex];
if (!val.VerifyInOtherZone)
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: `VerifyInOtherZone` is false for wave {verifyZoneOverride.WaveIndex}. You need to set it to true to generate the log, and thereby enabling moving the log.");
continue;
}
LG_ComputerTerminal val2 = Utils.FindTerminalWithTerminalSerial(val.VerificationTerminalSerial, ChainedReactor.SpawnNode.m_dimension.DimensionIndex, ChainedReactor.SpawnNode.LayerType, val.ZoneForVerification);
if ((Object)(object)val2 == (Object)null)
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: Cannot find wave log terminal. Wave index: {verifyZoneOverride.WaveIndex}");
continue;
}
TargetZone targetZone = verifyZoneOverride.TargetZone;
if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(targetZone.DimensionIndex, targetZone.LayerType, targetZone.LocalIndex, ref val3) || (Object)(object)val3 == (Object)null)
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: Cannot find target zone {targetZone.LocalIndex}, {targetZone.LayerType}, {targetZone.DimensionIndex}.");
continue;
}
if (val3.TerminalsSpawnedInZone == null || val3.TerminalsSpawnedInZone.Count < 0)
{
MeltdownReactorLogger.Error($"VerifyZoneOverrides: No spawned terminal found in target zone {targetZone.LocalIndex}, {targetZone.LayerType}, {targetZone.DimensionIndex}..");
continue;
}
int num = Builder.SessionSeedRandom.Seed;
if (num < 0)
{
num = ((num != int.MinValue) ? (-num) : int.MaxValue);
}
int num2 = num % val3.TerminalsSpawnedInZone.Count;
LG_ComputerTerminal val4 = val3.TerminalsSpawnedInZone[num2];
string text = val.VerificationTerminalFileName.ToUpperInvariant();
TerminalLogFileData localLog = val2.GetLocalLog(text);
if (localLog == null)
{
MeltdownReactorLogger.Error("VerifyZoneOverrides: Cannot find reactor verify log on terminal.");
continue;
}
val2.RemoveLocalLog(text);
val4.AddLocalLog(localLog, true);
val.VerificationTerminalSerial = val4.ItemKey;
val2.ResetInitialOutput();
val4.ResetInitialOutput();
MeltdownReactorLogger.Debug($"VerifyZoneOverrides: moved wave {verifyZoneOverride.WaveIndex} verify log from {val2.ItemKey} to {val4.ItemKey}");
verifyZoneOverrideTerminals.Add(verifyZoneOverride.WaveIndex, val4);
}
}
private void SetupMeltdownAndInfiniteWave()
{
//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_002a: 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_0134: 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_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
LG_WardenObjective_Reactor chainedReactor = ChainedReactor;
LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
eDimensionIndex dimensionIndex = chainedReactor.SpawnNode.m_dimension.DimensionIndex;
LG_LayerType layerType = chainedReactor.SpawnNode.LayerType;
LG_Zone val3 = default(LG_Zone);
for (int i = 0; i < objectiveDataBlock.ReactorWaves.Count; i++)
{
if (!meltdownWaveTerminalKeys.ContainsKey(i) && !infiniteWaveIndices.Contains(i))
{
continue;
}
ReactorWaveData val = objectiveDataBlock.ReactorWaves[i];
if (!val.HasVerificationTerminal)
{
_ = terminal.m_command;
if (meltdownWaveTerminalKeys.ContainsKey(i))
{
meltdownWaveTerminalKeys[i] = terminal.ItemKey;
AddVerifyCommand(terminal);
MeltdownReactorLogger.Debug($"MeltdownWave: Setup as Meltdown Wave for wave index {i}");
}
else
{
MeltdownReactorLogger.Debug($"InfiniteWave: Setup as Infinite Wavefor wave index {i}");
}
continue;
}
LG_ComputerTerminal val2 = null;
if (verifyZoneOverrideTerminals.ContainsKey(i))
{
val2 = verifyZoneOverrideTerminals[i];
}
else
{
if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, val.ZoneForVerification, ref val3))
{
MeltdownReactorLogger.Error($"Cannot find LG_Zone {dimensionIndex}, {layerType}, {val.ZoneForVerification}");
continue;
}
for (int j = 0; j < val3.TerminalsSpawnedInZone.Count; j++)
{
LG_ComputerTerminal val4 = val3.TerminalsSpawnedInZone[j];
if (val4.ItemKey.Equals(val.VerificationTerminalSerial, StringComparison.InvariantCultureIgnoreCase))
{
val2 = val4;
break;
}
}
}
if ((Object)(object)val2 == (Object)null)
{
MeltdownReactorLogger.Error($"MeltdownWave: cannot find verify terminal for wave index {i}");
continue;
}
val2.ConnectedReactor = chainedReactor;
val2.RemoveLocalLog(val.VerificationTerminalFileName.ToUpperInvariant());
if (meltdownWaveTerminalKeys.ContainsKey(i))
{
meltdownWaveTerminalKeys[i] = val2.ItemKey;
AddVerifyCommand(val2);
MeltdownReactorLogger.Debug($"MeltdownWave: Setup as Meltdown Wave for wave index {i}");
}
else
{
MeltdownReactorLogger.Debug($"InfiniteWave: Setup as Infinite Wavefor wave index {i}");
}
val2.ResetInitialOutput();
}
if (meltdownWaveTerminalKeys.Count == objectiveDataBlock.ReactorWaves.Count)
{
terminal.TrySyncSetCommandHidden((TERM_Command)22);
}
}
private void AddVerifyCommand(LG_ComputerTerminal terminal)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
LG_ComputerTerminalCommandInterpreter command = terminal.m_command;
if (command.HasRegisteredCommand((TERM_Command)42))
{
MeltdownReactorLogger.Debug("TERM_Command.UniqueCommand5 already registered. If this terminal is specified as objective terminal for 2 waves and the number of commands in 'UniqueCommands' on this terminal isn't more than 4, simply ignore this message.");
return;
}
command.AddCommand((TERM_Command)42, "REACTOR_COOLDOWN", new LocalizedText
{
UntranslatedText = ((CooldownCommandDescTextID == 0) ? "Confirm Reactor Startup Cooling Protocol" : Text.Get(CooldownCommandDescTextID)),
Id = 0u
}, (TERM_CommandRule)0);
terminal.TrySyncSetCommandRule((TERM_Command)42, (TERM_CommandRule)0);
}
private void SetIdle()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: 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_0048: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)ChainedReactor == (Object)null))
{
pReactorState val = default(pReactorState);
val.status = (eReactorStatus)0;
val.stateCount = 0;
val.stateProgress = 0f;
val.verifyFailed = false;
pReactorState state = val;
ChainedReactor.m_stateReplicator.State = state;
}
}
private void OnDestroy()
{
LevelAPI.OnEnterLevel -= OnDrop;
ChainedReactor = null;
infiniteWaveIndices?.Clear();
meltdownWaveTerminalKeys?.Clear();
verifyZoneOverrideTerminals?.Clear();
commandEventMap?.Clear();
commandPostOutputMap?.Clear();
infiniteWaveIndices = null;
meltdownWaveTerminalKeys = null;
overrideData = null;
objectiveDataBlock = null;
verifyZoneOverrideTerminals = null;
commandEventMap = null;
commandPostOutputMap = null;
}
private void LateUpdate()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0010: 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_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if ((int)GameStateManager.CurrentStateName == 10)
{
eReactorStatus status = ChainedReactor.m_currentState.status;
if (UsingLightEffect)
{
UpdateLight(status, ChainedReactor.m_currentWaveProgress);
}
UpdateGUIText(status);
}
}
private void UpdateGUIText(eReactorStatus status)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Invalid comparison between Unknown and I4
int num = ChainedReactor.m_currentWaveCount - 1;
if (num < 0)
{
return;
}
bool flag = ChainedReactor.m_currentWaveData.Verify < 43200f;
if ((int)status != 4)
{
return;
}
if (meltdownWaveTerminalKeys.ContainsKey(num))
{
string text = ((MainTerminalTextID == 0) ? "Main Terminal" : Text.Get(MainTerminalTextID));
if (ChainedReactor.m_currentWaveData.HasVerificationTerminal)
{
text = ChainedReactor.m_currentWaveData.VerificationTerminalSerial;
}
ChainedReactor.SetGUIMessage(true, FormatText(VerifyTextID, ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax, "<color=orange>" + text + "</color>"), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
}
else if (infiniteWaveIndices.Contains(num))
{
ChainedReactor.SetGUIMessage(true, string.Format(Text.Get(InfiniteWaveVerifyTextID), ChainedReactor.m_currentWaveCount, ChainedReactor.m_waveCountMax), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
}
else if (ChainedReactor.m_currentWaveData.HasVerificationTerminal)
{
ChainedReactor.SetGUIMessage(true, Text.Format(1103u, (Object[])(object)new Object[3]
{
Object.op_Implicit(ChainedReactor.m_currentWaveCount),
Object.op_Implicit(ChainedReactor.m_waveCountMax),
Object.op_Implicit("<color=orange>" + ChainedReactor.m_currentWaveData.VerificationTerminalSerial + "</color>")
}), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
}
else
{
ChainedReactor.SetGUIMessage(true, Text.Format(1105u, (Object[])(object)new Object[3]
{
Object.op_Implicit(ChainedReactor.m_currentWaveCount),
Object.op_Implicit(ChainedReactor.m_waveCountMax),
Object.op_Implicit("<color=orange>" + ChainedReactor.CurrentStateOverrideCode + "</color>")
}), (ePUIMessageStyle)3, flag, "<size=125%>" + Text.Get(1104u), "</size>");
}
}
private void UpdateLight(eReactorStatus status, float progress)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected I4, but got Unknown
//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)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
if (!(_updateTimer > Clock.Time))
{
_updateTimer = Clock.Time + 0.15f;
switch (status - 1)
{
case 0:
SetLightColor(Color.black);
break;
case 1:
SetLightColor(Color.Lerp(LowTemperature, HighTemperature, progress));
break;
case 2:
SetLightColor(Color.Lerp(HighTemperature, LowTemperature, progress));
break;
case 3:
SetLightColor(LowTemperature);
break;
case 4:
SetLightColor(LowTemperature);
break;
}
}
}
private void SetLightColor(Color color)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if (UsingLightEffect && _lights != null)
{
for (int i = 0; i < _lights.Length; i++)
{
_lights[i].ChangeColor(color);
}
}
}
private void BuildReactorTerminalPassword()
{
//IL_027e: Unknown result type (might be due to invalid IL or missing references)
//IL_0285: Expected O, but got Unknown
//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0308: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Expected O, but got Unknown
LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
TerminalPassword terminalPassword = overrideData.ReactorTerminal.TerminalPassword;
if (!terminalPassword.GeneratePassword)
{
terminal.LockWithPassword(terminalPassword.Password, new string[1] { "" });
return;
}
if (terminalPassword.TerminalZoneSelectionDatas.Count <= 0)
{
MeltdownReactorLogger.Error("Tried to generate a password for terminal " + terminal.PublicName + " with no " + typeof(TerminalZoneSelectionData).Name + "!! This is not allowed.");
return;
}
string codeWord = SerialGenerator.GetCodeWord();
string passwordHintText = terminalPassword.PasswordHintText;
string text = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on ";
int num = terminalPassword.PasswordPartCount;
if (codeWord.Length % num != 0)
{
MeltdownReactorLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({terminalPassword.PasswordPartCount}). Defaulting to 1.");
num = 1;
}
string[] array = ((num > 1) ? Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)StringUtils.SplitIntoChunksArray(codeWord, codeWord.Length / num)) : new string[1] { codeWord });
string text2 = "";
if (terminalPassword.ShowPasswordPartPositions)
{
for (int i = 0; i < array[0].Length; i++)
{
text2 += "-";
}
}
HashSet<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>();
for (int j = 0; j < num; j++)
{
int index = j % terminalPassword.TerminalZoneSelectionDatas.Count;
LG_ComputerTerminal val = Utils.SelectTerminalFromSelectionData(terminalPassword.TerminalZoneSelectionDatas[index][Builder.SessionSeedRandom.Range(0, terminalPassword.TerminalZoneSelectionDatas[index].Count, "NO_TAG")]);
if ((Object)(object)val != (Object)null)
{
string text3 = "";
string text4;
if (terminalPassword.ShowPasswordPartPositions)
{
for (int k = 0; k < j; k++)
{
text3 += text2;
}
text4 = text3 + array[j];
for (int l = j; l < num - 1; l++)
{
text4 += text2;
}
}
else
{
text4 = array[j];
}
string text5 = (terminalPassword.ShowPasswordPartPositions ? ("0" + (j + 1)) : ("0" + Builder.SessionSeedRandom.Range(0, 9, "NO_TAG")));
TerminalLogFileData val2 = new TerminalLogFileData();
val2.FileName = "key" + text5 + "_" + terminal.m_serialNumber + (val.HasPasswordPart ? "_1" : "") + ".LOG";
val2.FileContent = new LocalizedText
{
UntranslatedText = string.Format(Text.Get((num == 1) ? 1431221909u : 2260297836u), text4),
Id = 0u
};
TerminalLogFileData val3 = val2;
val.AddLocalLog(val3, true);
if (!hashSet.Contains(val))
{
if (j > 0)
{
text += ", ";
}
text = text + val.PublicName + " in " + val.SpawnNode.m_zone.AliasName;
}
hashSet.Add(val);
val.HasPasswordPart = true;
}
else
{
MeltdownReactorLogger.Error($"Build() CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log.");
}
}
string text6 = text + ".";
if (terminalPassword.ShowPasswordLength)
{
terminal.LockWithPassword(codeWord, new string[3]
{
passwordHintText,
text6,
"Char[" + codeWord.Length + "]"
});
}
else
{
terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text6 });
}
foreach (LG_ComputerTerminal item in hashSet)
{
item.ResetInitialOutput();
}
}
private void BuildReactorTerminalCustomCommands()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
LG_ComputerTerminal terminal = ChainedReactor.m_terminal;
List<ReactorCustomTerminalCommand> uniqueCommands = overrideData.ReactorTerminal.UniqueCommands;
TERM_Command val = default(TERM_Command);
for (int i = 0; i < uniqueCommands.Count; i++)
{
ReactorCustomTerminalCommand reactorCustomTerminalCommand = uniqueCommands[i];
if (terminal.m_command.TryGetUniqueCommandSlot(ref val))
{
terminal.m_command.AddCommand(val, reactorCustomTerminalCommand.Command, reactorCustomTerminalCommand.CommandDesc, reactorCustomTerminalCommand.SpecialCommandRule);
commandEventMap.Add(val, reactorCustomTerminalCommand.CommandEvents);
commandPostOutputMap.Add(val, reactorCustomTerminalCommand.PostCommandOutputs);
for (int j = 0; j < reactorCustomTerminalCommand.CommandEvents.Count; j++)
{
WardenObjectiveEventData val2 = reactorCustomTerminalCommand.CommandEvents[j];
if (val2.ChainPuzzle != 0)
{
ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle);
if (block != null)
{
ChainedPuzzleInstance val3 = ChainedPuzzleManager.CreatePuzzleInstance(block, terminal.ConnectedReactor.SpawnNode.m_area, terminal.ConnectedReactor.m_chainedPuzzleAlign.position, terminal.ConnectedReactor.m_chainedPuzzleAlign, val2.UseStaticBioscanPoints);
terminal.SetChainPuzzleForCommand(val, j, val3);
}
}
}
}
else
{
MeltdownReactorLogger.Error($"LG_ComputerTerminal: Could not get any more unique command slots for this terminal!! Have you added too many unique commands to this terminal? (Yours: {uniqueCommands.Count}, Max: 5)");
}
}
ChainedPuzzleInstance val6 = default(ChainedPuzzleInstance);
for (int k = 38; k <= 42; k++)
{
TERM_Command val4 = (TERM_Command)(byte)k;
if (!commandEventMap.TryGetValue(val4, out var value) || value == null)
{
continue;
}
ChainedPuzzleInstance val5 = null;
for (int l = 0; l < value.Count; l++)
{
WardenObjectiveEventData eventData = value[l];
if (eventData == null)
{
continue;
}
if (ChainedReactor.m_terminal.TryGetChainPuzzleForCommand(val4, l, ref val6) && (Object)(object)val6 != (Object)null)
{
ChainedPuzzleInstance obj = val6;
obj.OnPuzzleSolved += Action.op_Implicit((Action)delegate
{
WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f);
});
val5 = val6;
}
else if ((Object)(object)val5 != (Object)null)
{
ChainedPuzzleInstance obj2 = val5;
obj2.OnPuzzleSolved += Action.op_Implicit((Action)delegate
{
WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f);
});
}
}
}
MeltdownReactorLogger.Warning("CustomCommand built!");
}
private static string FormatText(uint id, params object[] objs)
{
return string.Format(Text.Get(id), objs);
}
static MeltdownReactor()
{
//IL_0005: 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_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
LowTemperature = ColorExt.Hex("#23E4F2") * 2.5f;
HighTemperature = ColorExt.Hex("#F63838") * 12f;
VerifyTextID = 0u;
MainTerminalTextID = 0u;
CooldownCommandDescTextID = 0u;
InfiniteWaveVerifyTextID = 0u;
NotReadyForVerificationOutputTextID = 0u;
IncorrectTerminalOutputTextID = 0u;
CorrectTerminalOutputTextID = 0u;
}
}
internal static class MeltdownReactorLogger
{
private static readonly ManualLogSource _logger = Logger.CreateLogSource("MeltdownReactor");
private static string Format(object msg)
{
return msg.ToString();
}
public static void Info(object data)
{
_logger.LogMessage((object)Format(data));
}
public static void Verbose(object data)
{
}
public static void Debug(object data)
{
_logger.LogDebug((object)Format(data));
}
public static void Error(object data)
{
_logger.LogError((object)Format(data));
}
public static void Warning(object data)
{
_logger.LogWarning((object)Format(data));
}
}
internal static class Utils
{
public static LG_ComputerTerminal FindTerminalWithTerminalSerial(string itemKey, eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
LG_Zone val = null;
if (Builder.CurrentFloor.TryGetZoneByLocalIndex(dim, layer, localIndex, ref val) && (Object)(object)val != (Object)null)
{
Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator();
while (enumerator.MoveNext())
{
LG_ComputerTerminal current = enumerator.Current;
if (current.ItemKey.Equals(itemKey, StringComparison.InvariantCultureIgnoreCase))
{
return current;
}
}
}
return null;
}
public static TerminalLogFileData GetLocalLog(this LG_ComputerTerminal terminal, string logName)
{
Dictionary<string, TerminalLogFileData> localLogs = terminal.GetLocalLogs();
logName = logName.ToUpperInvariant();
if (!localLogs.ContainsKey(logName))
{
return null;
}
return localLogs[logName];
}
public static void ResetInitialOutput(this LG_ComputerTerminal terminal)
{
terminal.m_command.ClearOutputQueueAndScreenBuffer();
terminal.m_command.AddInitialTerminalOutput();
if (terminal.IsPasswordProtected)
{
terminal.m_command.AddPasswordProtectedOutput((Il2CppStringArray)null);
}
}
public static LG_ComputerTerminal SelectTerminalFromSelectionData(PasswordTerminalZoneSelectionData selectionData)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected I4, but got Unknown
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
TargetZone targetZone = selectionData.TargetZone;
LG_Zone val = default(LG_Zone);
if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(targetZone.DimensionIndex, targetZone.LayerType, targetZone.LocalIndex, ref val) || (Object)(object)val == (Object)null)
{
MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could NOT find zone with " + targetZone);
return null;
}
if (val.TerminalsSpawnedInZone.Count <= 0)
{
MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could not find any terminals in zone with " + targetZone?.ToString() + ". At least one terminal required!!");
return null;
}
List<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>();
if ((int)selectionData.SeedType != 0)
{
Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator();
while (enumerator.MoveNext())
{
LG_ComputerTerminal current = enumerator.Current;
if (!current.HasPasswordPart)
{
list.Add(current);
}
}
if (list.Count <= 0)
{
eLocalZoneIndex localIndex = targetZone.LocalIndex;
MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() Could not find any terminals without a password part in zone with " + ((object)(eLocalZoneIndex)(ref localIndex)).ToString() + ". Putting the password on random (session) already used terminal.");
return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")];
}
}
eSeedType seedType = selectionData.SeedType;
switch ((int)seedType)
{
case 0:
return val.TerminalsSpawnedInZone[Mathf.Clamp(0, val.TerminalsSpawnedInZone.Count - 1, selectionData.TerminalIndex)];
case 1:
return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")];
case 2:
return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")];
case 3:
Random.InitState(selectionData.StaticSeed);
return list[Random.Range(0, list.Count)];
default:
MeltdownReactorLogger.Error("SelectTerminalFromSelectionData() did not have a valid SeedType!!");
return null;
}
}
}
}
namespace MeltdownReactor.ReactorData
{
public class PasswordTerminalZoneSelectionData
{
public TargetZone TargetZone { get; set; } = new TargetZone();
public eSeedType SeedType { get; set; }
public int TerminalIndex { get; set; }
public int StaticSeed { get; set; }
public PasswordTerminalZoneSelectionData()
{
SeedType = (eSeedType)1;
}
public override string ToString()
{
//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)
string[] obj = new string[7]
{
TargetZone?.ToString(),
" ",
null,
null,
null,
null,
null
};
eSeedType seedType = SeedType;
obj[2] = ((object)(eSeedType)(ref seedType)).ToString();
obj[3] = " ";
obj[4] = TerminalIndex.ToString();
obj[5] = " ";
obj[6] = StaticSeed.ToString();
return string.Concat(obj);
}
}
public class ReactorCustomTerminalCommand
{
public string Command { get; set; }
public LocalizedText CommandDesc { get; set; }
public List<TerminalOutput> PostCommandOutputs { get; set; }
public List<WardenObjectiveEventData> CommandEvents { get; set; }
public TERM_CommandRule SpecialCommandRule { get; set; }
public ReactorCustomTerminalCommand()
{
PostCommandOutputs = new List<TerminalOutput>();
CommandEvents = new List<WardenObjectiveEventData>();
}
}
public class ReactorOverrideData
{
public uint ObjectiveDataID { get; set; }
public bool StartupOnDrop { get; set; }
public List<int> MeltdownWaveIndices { get; set; } = new List<int>();
public List<int> InfiniteWaveIndices { get; set; } = new List<int>();
public ReactorTerminalSetting ReactorTerminal { get; set; } = new ReactorTerminalSetting();
public List<VerifyZoneOverride> VerifyZoneOverrides { get; set; } = new List<VerifyZoneOverride>
{
new VerifyZoneOverride()
};
}
public class ReactorTerminalSetting
{
public List<ReactorCustomTerminalCommand> UniqueCommands { get; set; } = new List<ReactorCustomTerminalCommand>();
public TerminalPassword TerminalPassword { get; set; } = new TerminalPassword();
}
public class TargetZone
{
public eDimensionIndex DimensionIndex { get; set; }
public LG_LayerType LayerType { get; set; }
public eLocalZoneIndex LocalIndex { get; set; }
public override string ToString()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
return $"{LocalIndex}, {LayerType}, {DimensionIndex}";
}
}
public class TerminalPassword
{
public bool PasswordProtected { get; set; }
public string Password { get; set; } = string.Empty;
public string PasswordHintText { get; set; } = "Password Required.";
public bool GeneratePassword { get; set; } = true;
public int PasswordPartCount { get; set; } = 1;
public bool ShowPasswordLength { get; set; }
public bool ShowPasswordPartPositions { get; set; }
public List<List<PasswordTerminalZoneSelectionData>> TerminalZoneSelectionDatas { get; set; } = new List<List<PasswordTerminalZoneSelectionData>>
{
new List<PasswordTerminalZoneSelectionData>()
};
}
public class VerifyZoneOverride
{
public int WaveIndex { get; set; } = -1;
public TargetZone TargetZone { get; set; } = new TargetZone();
}
}
namespace MeltdownReactor.Patches
{
[HarmonyPatch]
internal static class Patch_LG_ComputerTerminal
{
[HarmonyPrefix]
[HarmonyPatch(typeof(LG_ComputerTerminal), "OnStateChange")]
private static bool Pre_OnStateChange(LG_ComputerTerminal __instance, bool isRecall)
{
if (__instance.SpawnNode != null || !isRecall)
{
return true;
}
return false;
}
}
[HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")]
internal static class Patch_Meltdown_Reactor_Terminal
{
private static bool Prefix(LG_ComputerTerminalCommandInterpreter __instance, TERM_Command cmd)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
LG_WardenObjective_Reactor connectedReactor = __instance.m_terminal.ConnectedReactor;
if ((Object)(object)connectedReactor == (Object)null || (int)cmd != 42)
{
return true;
}
if (__instance.m_terminal.CommandIsHidden(cmd))
{
return true;
}
_ = __instance.m_terminal.ItemKey;
MeltdownReactor component = ((Component)connectedReactor).gameObject.GetComponent<MeltdownReactor>();
if ((Object)(object)component == (Object)null)
{
return true;
}
if (!connectedReactor.ReadyForVerification)
{
__instance.AddOutput("", true);
__instance.AddOutput((TerminalLineType)3, Text.Get(MeltdownReactor.NotReadyForVerificationOutputTextID), 4f, (TerminalSoundType)0, (TerminalSoundType)0);
__instance.AddOutput("", true);
return false;
}
if (component.IsCorrectTerminal(__instance.m_terminal))
{
MeltdownReactorLogger.Info("Reactor Verify Correct!");
if (SNet.IsMaster)
{
if (connectedReactor.m_currentWaveCount == connectedReactor.m_waveCountMax)
{
connectedReactor.AttemptInteract((eReactorInteraction)5, 0f);
}
else
{
connectedReactor.AttemptInteract((eReactorInteraction)3, 0f);
}
}
__instance.AddOutput(Text.Get(MeltdownReactor.CorrectTerminalOutputTextID), true);
}
else
{
MeltdownReactorLogger.Info("Reactor Verify Incorrect!");
__instance.AddOutput("", true);
__instance.AddOutput((TerminalLineType)3, Text.Get(MeltdownReactor.IncorrectTerminalOutputTextID), 4f, (TerminalSoundType)0, (TerminalSoundType)0);
__instance.AddOutput("", true);
}
return false;
}
}
[HarmonyPatch]
internal static class Patch_Meltdown_Reactor
{
[HarmonyPostfix]
[HarmonyPatch(typeof(LG_WardenObjective_Reactor), "OnBuildDone")]
private static void Post_BuildDone(LG_WardenObjective_Reactor __instance)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Invalid comparison between Unknown and I4
WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock);
if (!WardenObjectiveManager.Current.TryGetActiveWardenObjectiveData(__instance.SpawnNode.LayerType, ref val))
{
MeltdownReactorLogger.Error("Failed to get WardenObjectiveData for this reactor");
}
else if (EntryPoint.ReactorOverrideDatas.ContainsKey(((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID))
{
ReactorOverrideData overrideData = EntryPoint.ReactorOverrideDatas[((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID];
if ((int)val.Type != 1)
{
MeltdownReactorLogger.Error($"ObjectiveDataID {((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID} is not reactor startup, which is unsupported.");
return;
}
MeltdownReactor meltdownReactor = ((Component)__instance).gameObject.AddComponent<MeltdownReactor>();
meltdownReactor.ChainedReactor = __instance;
meltdownReactor.UsingLightEffect = false;
meltdownReactor.overrideData = overrideData;
meltdownReactor.Init();
MeltdownReactorLogger.Warning($"Override Reactor Data for ObjectiveID {((GameDataBlockBase<WardenObjectiveDataBlock>)(object)val).persistentID}");
}
}
}
}
namespace MeltdownReactor.Json
{
internal static class JSON
{
private static readonly JsonSerializerOptions s_SerializerOptions;
public static T Deserialize<T>(string json)
{
return JsonSerializer.Deserialize<T>(json, s_SerializerOptions);
}
public static string Serialize<T>(T obj)
{
return JsonSerializer.Serialize(obj, s_SerializerOptions);
}
static JSON()
{
s_SerializerOptions = new JsonSerializerOptions
{
AllowTrailingCommas = true,
ReadCommentHandling = JsonCommentHandling.Skip,
PropertyNameCaseInsensitive = true,
WriteIndented = true
};
s_SerializerOptions.Converters.Add(new JsonStringEnumConverter());
if (MTFOPartialDataUtil.IsLoaded && MTFOPartialDataUtil.Initialized)
{
s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
s_SerializerOptions.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
MeltdownReactorLogger.Info("PartialData Support Found!");
}
else
{
s_SerializerOptions.Converters.Add(new LocalizedTextConverter());
}
}
public static void Load<T>(string file, out T config) where T : new()
{
if (file.Length < ".json".Length)
{
config = default(T);
return;
}
if (file.Substring(file.Length - ".json".Length) != ".json")
{
file += ".json";
}
file = File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "MeltdownReactor", file));
config = Deserialize<T>(file);
}
}
internal class LocalizedTextConverter : JsonConverter<LocalizedText>
{
public override bool HandleNull => false;
public override LocalizedText Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//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_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Expected O, but got Unknown
switch (reader.TokenType)
{
case JsonTokenType.String:
{
string @string = reader.GetString();
return new LocalizedText
{
Id = 0u,
UntranslatedText = @string
};
}
case JsonTokenType.Number:
return new LocalizedText
{
Id = reader.GetUInt32(),
UntranslatedText = null
};
default:
throw new JsonException($"LocalizedTextJson type: {reader.TokenType} is not implemented!");
}
}
public override void Write(Utf8JsonWriter writer, LocalizedText value, JsonSerializerOptions options)
{
JsonSerializer.Serialize<LocalizedText>(writer, value, options);
}
}
}
namespace MeltdownReactor.Json.PartialData
{
public static class MTFOPartialDataUtil
{
public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";
public static JsonConverter PersistentIDConverter { get; private set; }
public static JsonConverter LocalizedTextConverter { get; private set; }
public static bool IsLoaded { get; private set; }
public static bool Initialized { get; private set; }
public static string PartialDataPath { get; private set; }
public static string ConfigPath { get; private set; }
static MTFOPartialDataUtil()
{
PersistentIDConverter = null;
LocalizedTextConverter = null;
IsLoaded = false;
Initialized = false;
PartialDataPath = string.Empty;
ConfigPath = string.Empty;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
{
return;
}
try
{
Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type[] types = obj.GetTypes();
Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
if ((object)type == null)
{
throw new Exception("Unable to Find PersistentIDConverter Class");
}
Type type2 = types.First((Type t) => t.Name == "LocalizedTextConverter");
if ((object)type2 == null)
{
throw new Exception("Unable to Find LocalizedTextConverter Class");
}
Type obj2 = types.First((Type t) => t.Name == "PartialDataManager") ?? throw new Exception("Unable to Find PartialDataManager Class");
PropertyInfo property = obj2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
PropertyInfo property2 = obj2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
PropertyInfo? property3 = obj2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
if ((object)property == null)
{
throw new Exception("Unable to Find Property: Initialized");
}
if ((object)property2 == null)
{
throw new Exception("Unable to Find Property: PartialDataPath");
}
if ((object)property3 == null)
{
throw new Exception("Unable to Find Field: ConfigPath");
}
Initialized = (bool)property.GetValue(null);
PartialDataPath = (string)property2.GetValue(null);
ConfigPath = (string)property3.GetValue(null);
PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
LocalizedTextConverter = (JsonConverter)Activator.CreateInstance(type2);
IsLoaded = true;
}
catch (Exception value2)
{
MeltdownReactorLogger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
}
}
}
public static class MTFOUtil
{
public const string PLUGIN_GUID = "com.dak.MTFO";
public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;
public static string GameDataPath { get; private set; }
public static string CustomPath { get; private set; }
public static bool HasCustomContent { get; private set; }
public static bool IsLoaded { get; private set; }
static MTFOUtil()
{
GameDataPath = string.Empty;
CustomPath = string.Empty;
HasCustomContent = false;
IsLoaded = false;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
{
return;
}
try
{
Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
if ((object)field == null)
{
throw new Exception("Unable to Find Field: GameDataPath");
}
if ((object)field2 == null)
{
throw new Exception("Unable to Find Field: CustomPath");
}
if ((object)field3 == null)
{
throw new Exception("Unable to Find Field: HasCustomContent");
}
GameDataPath = (string)field.GetValue(null);
CustomPath = (string)field2.GetValue(null);
HasCustomContent = (bool)field3.GetValue(null);
IsLoaded = true;
}
catch (Exception value2)
{
MeltdownReactorLogger.Error($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
}
}
}
}