using System;
using System.CodeDom.Compiler;
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.Cryptography;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ChainedPuzzles;
using CustomCheckpoints.Data;
using CustomCheckpoints.Extensions;
using CustomCheckpoints.Manager;
using CustomCheckpoints.Utility;
using GTFO.API;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using LevelGeneration;
using Microsoft.CodeAnalysis;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature;
using TheArchive.Core.Attributes.Feature.Members;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
using TheArchive.Core.FeaturesAPI.Components;
using TheArchive.Core.FeaturesAPI.Settings;
using TheArchive.Core.Localization;
using TheArchive.Interfaces;
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("CustomCheckpoints")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: AssemblyInformationalVersion("0.1.0+40b602f6c0481751f0013ffe2d085d8eba8bb77a")]
[assembly: AssemblyProduct("CustomCheckpoints")]
[assembly: AssemblyTitle("CustomCheckpoints")]
[assembly: AssemblyVersion("0.1.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace CustomCheckpoints
{
[BepInPlugin("dev.mbooster.CustomCheckpoints", "CustomCheckpoints", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CustomCheckpoints : BasePlugin
{
public const string ModName = "CustomCheckpoints";
public const string Author = "mbooster";
public const string Guid = "dev.mbooster.CustomCheckpoints";
public const string Version = "0.1.0";
public override void Load()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
GameDataAPI.OnGameDataInitialized += CheckpointConfigManager.ValidateConfig;
new Harmony("dev.mbooster.CustomCheckpoints").PatchAll();
LevelAPI.OnBuildStart += Execute;
}
private void Execute()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
bool flag = default(bool);
try
{
CheckpointConfigManager.ValidateConfig();
int num = CustomCheckpointManager.ReplaceDoorsForLevel(RundownDataManager.GetDoorData(CheckpointConfigManager.GetConfig()));
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Added ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" checkpoints.");
}
Log.Logger.LogInfo(val);
}
catch (Exception ex)
{
ManualLogSource log = ((BasePlugin)this).Log;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Error occurred during door replacement: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
log.LogError(val2);
}
}
}
[ArchiveModule("dev.mbooster.CustomCheckpoints", "CustomCheckpoints", "0.1.0")]
public class CustomCheckpointsArchiveModule : IArchiveModule
{
public ILocalizationService LocalizationService { get; set; }
public IArchiveLogger Logger { get; set; }
public void Init()
{
}
}
[GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")]
[CompilerGenerated]
internal static class VersionInfo
{
public const string RootNamespace = "CustomCheckpoints";
public const string Version = "0.1.0";
public const string VersionPrerelease = null;
public const string VersionMetadata = "git40b602f-dirty-master";
public const string SemVer = "0.1.0";
public const string GitRevShort = "40b602f-dirty";
public const string GitRevLong = "40b602f6c0481751f0013ffe2d085d8eba8bb77a-dirty";
public const string GitBranch = "master";
public const string GitTag = null;
public const bool GitIsDirty = true;
}
}
namespace CustomCheckpoints.Utility
{
public class JsonSerializer
{
private readonly JsonSerializerOptions _options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
IncludeFields = true,
PropertyNameCaseInsensitive = true,
ReadCommentHandling = JsonCommentHandling.Skip,
WriteIndented = true
};
public JsonSerializer()
{
_options.Converters.Add(new JsonStringEnumConverter());
}
public T Read<T>(string path) where T : new()
{
string json = File.ReadAllText(path);
T val = Deserialize<T>(json);
if (val == null)
{
throw new JsonException("Deserialization returned null.");
}
return val;
}
public void Write(string path, string json)
{
File.WriteAllText(path, json);
}
public string Serialize(object value)
{
return System.Text.Json.JsonSerializer.Serialize(value, _options);
}
public T? Deserialize<T>(string json)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(json, _options);
}
}
public static class Log
{
public static readonly ManualLogSource Logger = Logger.CreateLogSource("CustomCheckpoints");
public static void LogObject(object? obj, string prefix = "", int depth = 0)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
if (depth > 3 || obj == null)
{
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(prefix);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is NULL");
}
Logger.LogInfo(val);
return;
}
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo propertyInfo in properties)
{
try
{
object value = propertyInfo.GetValue(obj);
LogValue(propertyInfo.Name, value, propertyInfo.PropertyType, prefix, depth);
}
catch
{
}
}
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public);
foreach (FieldInfo fieldInfo in fields)
{
try
{
object value2 = fieldInfo.GetValue(obj);
LogValue(fieldInfo.Name, value2, fieldInfo.FieldType, prefix, depth);
}
catch
{
}
}
}
private static void LogValue(string name, object? value, Type type, string prefix, int depth)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Expected O, but got Unknown
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Expected O, but got Unknown
if (type == typeof(IntPtr) || type == typeof(UIntPtr))
{
return;
}
string? text = type.Namespace;
if ((text != null && text.StartsWith("Il2CppInterop")) || type.Name.Contains("Il2CppMethodInfo"))
{
return;
}
string text2 = prefix + name;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val;
if (value == null)
{
val = new BepInExInfoLogInterpolatedStringHandler(7, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = NULL");
}
Logger.LogInfo(val);
return;
}
if (type.IsPrimitive || type == typeof(string) || type.IsEnum)
{
val = new BepInExInfoLogInterpolatedStringHandler(3, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(value);
}
Logger.LogInfo(val);
return;
}
string? text3 = type.Namespace;
if (text3 != null && text3.StartsWith("UnityEngine"))
{
val = new BepInExInfoLogInterpolatedStringHandler(3, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(value);
}
Logger.LogInfo(val);
return;
}
val = new BepInExInfoLogInterpolatedStringHandler(4, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("):");
}
Logger.LogInfo(val);
LogObject(value, text2 + ".", depth + 1);
}
}
}
namespace CustomCheckpoints.Patches
{
[HarmonyPatch(typeof(ChainedPuzzleManager), "CreatePuzzleInstance", new Type[]
{
typeof(ChainedPuzzleDataBlock),
typeof(LG_Area),
typeof(Vector3),
typeof(Transform)
})]
public static class CreatePuzzleInstancePatch
{
public static void Prefix(ref ChainedPuzzleDataBlock data, LG_Area sourceArea)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
if (data == null)
{
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CreatePuzzleInstance: null datablock for ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>((sourceArea != null) ? ((Object)sourceArea).name : null);
}
Log.Logger.LogWarning(val);
data = GetCheckpointScanReplacement();
}
}
private static ChainedPuzzleDataBlock GetCheckpointScanReplacement()
{
return ((IEnumerable<ChainedPuzzleDataBlock>)GameDataBlockBase<ChainedPuzzleDataBlock>.GetAllBlocks()).FirstOrDefault((Func<ChainedPuzzleDataBlock, bool>)((ChainedPuzzleDataBlock b) => ((GameDataBlockBase<ChainedPuzzleDataBlock>)(object)b).name.ToLower().Contains("checkpoint"))) ?? CreateCheckpointBlock();
}
private static ChainedPuzzleDataBlock CreateCheckpointBlock()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Expected O, but got Unknown
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Expected O, but got Unknown
//IL_00ec: Expected O, but got Unknown
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Expected O, but got Unknown
Il2CppArrayBase<ChainedPuzzleDataBlock> allBlocks = GameDataBlockBase<ChainedPuzzleDataBlock>.GetAllBlocks();
int count = allBlocks.Count;
uint num = 0u;
for (int i = 0; i < count; i++)
{
if (((GameDataBlockBase<ChainedPuzzleDataBlock>)(object)allBlocks[i]).persistentID > num)
{
num = ((GameDataBlockBase<ChainedPuzzleDataBlock>)(object)allBlocks[i]).persistentID;
}
}
ChainedPuzzleComponent val = new ChainedPuzzleComponent
{
PuzzleType = 19u
};
List<ChainedPuzzleComponent> val2 = new List<ChainedPuzzleComponent>();
val2.Add(val);
ChainedPuzzleDataBlock val3 = new ChainedPuzzleDataBlock
{
PublicAlarmName = "Alarm",
TriggerAlarmOnActivate = false,
SurvivalWaveSettings = 1u,
SurvivalWavePopulation = 1u,
SurvivalWaveAreaDistance = 2,
DisableSurvivalWaveOnComplete = true,
UseRandomPositions = false,
WantedDistanceFromStartPos = 0f,
WantedDistanceBetweenPuzzleComponents = 1f,
ChainedPuzzle = val2,
OnlyShowHUDWhenPlayerIsClose = false,
AlarmSoundStart = 3339129407u,
AlarmSoundStop = 42633153u
};
((GameDataBlockBase<ChainedPuzzleDataBlock>)val3).name = "Checkpoint";
((GameDataBlockBase<ChainedPuzzleDataBlock>)val3).internalEnabled = true;
((GameDataBlockBase<ChainedPuzzleDataBlock>)val3).persistentID = num + 1;
ChainedPuzzleDataBlock val4 = val3;
GameDataBlockBase<ChainedPuzzleDataBlock>.AddBlock(val4, -1);
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Injected checkpoint scan block with ID ");
((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<uint>(((GameDataBlockBase<ChainedPuzzleDataBlock>)(object)val4).persistentID);
}
Log.Logger.LogInfo(val5);
return val4;
}
}
}
namespace CustomCheckpoints.Manager
{
public static class CheckpointConfigManager
{
private static readonly global::CustomCheckpoints.Utility.JsonSerializer Serializer = new global::CustomCheckpoints.Utility.JsonSerializer();
private const string CheckpointsConfigFileName = "CustomCheckpoints.doors.json";
private static byte[]? _configHash;
private static List<RundownData>? _config;
public static List<RundownData>? GetConfig()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
bool flag = default(bool);
try
{
if (_config != null && _configHash == GetConfigHash())
{
return _config.GetSorted();
}
string configFilepath = GetConfigFilepath();
List<RundownData> list = Serializer.Read<List<RundownData>>(configFilepath);
CacheConfig(list);
return list.GetSorted();
}
catch (Exception ex) when (((ex is DirectoryNotFoundException || ex is FileNotFoundException) ? 1 : 0) != 0)
{
return null;
}
catch (JsonException ex2)
{
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(54, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("CustomCheckpoints.doors.json");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" configuration is invalid. See exception for details: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
}
Log.Logger.LogWarning(val);
return new List<RundownData>();
}
catch (Exception ex3)
{
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Unexpected error occured: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex3.Message);
}
Log.Logger.LogError(val2);
throw;
}
}
public static void ValidateConfig()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
List<RundownData> config = GetConfig();
if (config == null)
{
Log.Logger.LogInfo((object)"No existing configuration detected, creating new checkpoint configuration...");
SaveConfig(RundownDataManager.RetrieveData());
return;
}
bool flag = default(bool);
if (config.Count == 0)
{
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(80, 0, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Config exists, but no door data was found, resetting checkpoint configuration...");
}
Log.Logger.LogWarning(val);
ResetConfig();
}
if (HasReadonlyDataChanged(config))
{
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(69, 0, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Readonly data has been changed, resetting checkpoint configuration...");
}
Log.Logger.LogWarning(val);
ResetConfig();
}
}
public static void SaveConfig(List<RundownData> rundowns)
{
string json = Serializer.Serialize(rundowns);
string configFilepath = GetConfigFilepath();
Serializer.Write(configFilepath, json);
CacheConfig(rundowns);
}
private static bool HasReadonlyDataChanged(List<RundownData> config)
{
List<RundownData> sorted = RundownDataManager.OriginalData.GetSorted();
return !config.SequenceEqual(sorted);
}
private static string GetConfigFilepath()
{
return Path.Combine(Paths.ConfigPath, "CustomCheckpoints.doors.json");
}
private static void ResetConfig()
{
SaveConfig(TryRestoreConfig(_config, RundownDataManager.OriginalData, out List<RundownData> rundowns) ? rundowns : RundownDataManager.OriginalData);
}
private static bool TryRestoreConfig(List<RundownData>? configToRestore, List<RundownData> newConfig, out List<RundownData> rundowns)
{
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Expected O, but got Unknown
rundowns = newConfig;
if (configToRestore == null || configToRestore.Count == 0)
{
return false;
}
int num = 0;
int num2 = 0;
foreach (RundownData rundown in newConfig)
{
RundownData rundownData = configToRestore.FirstOrDefault((RundownData r) => r.Id == rundown.Id);
if (rundownData == null)
{
continue;
}
foreach (ExpeditionData expedition in rundown.Expeditions)
{
ExpeditionData expeditionData = rundownData.Expeditions.FirstOrDefault((ExpeditionData e) => e.Id == expedition.Id);
if (expeditionData == null)
{
continue;
}
foreach (SecurityDoorData door in expedition.Doors)
{
num2++;
SecurityDoorData securityDoorData = expeditionData.Doors.FirstOrDefault((SecurityDoorData d) => d.Id == door.Id);
if (securityDoorData != null)
{
door.IsCheckpoint = securityDoorData.IsCheckpoint;
num++;
}
}
}
}
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Restored ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" door checkpoint states.");
}
Log.Logger.LogInfo(val);
return num > 0;
}
private static void CacheConfig(List<RundownData> config)
{
_configHash = GetConfigHash();
_config = config;
}
private static byte[] GetConfigHash()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
try
{
string configFilepath = GetConfigFilepath();
using MD5 mD = MD5.Create();
using FileStream inputStream = File.OpenRead(configFilepath);
return mD.ComputeHash(inputStream);
}
catch (Exception ex)
{
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Unexpected error occured: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
Log.Logger.LogError(val);
throw;
}
}
}
public static class CustomCheckpointManager
{
public static int ReplaceDoorsForLevel(Dictionary<string, List<SecurityDoorData>> doorData)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
int num = 0;
ExpeditionInTierData activeExpedition = RundownManager.ActiveExpedition;
string key = activeExpedition.LevelLayoutData.GetHashCode().ToString();
doorData.TryGetValue(key, out List<SecurityDoorData> value);
if (value == null || value.Count == 0)
{
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(50, 0, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No door data could be found for the current level.");
}
Log.Logger.LogWarning(val);
return 0;
}
num += ReplaceDoors(activeExpedition.LevelLayoutData, value, Layer.Main);
if (activeExpedition.SecondaryLayerEnabled)
{
num += ReplaceDoors(activeExpedition.SecondaryLayout, value, Layer.Secondary);
}
if (activeExpedition.ThirdLayerEnabled)
{
num += ReplaceDoors(activeExpedition.ThirdLayout, value, Layer.Third);
}
return num;
}
private static int ReplaceDoors(uint layoutId, List<SecurityDoorData> doors, Layer layer)
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
int num = 0;
LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(layoutId);
if (block == null)
{
return 0;
}
List<ExpeditionZoneData> zones = block.Zones;
Il2CppArrayBase<ExpeditionZoneData> items = zones._items;
int size = zones._size;
bool flag = default(bool);
for (int i = 0; i < size; i++)
{
ExpeditionZoneData val = items[i];
string doorId = val.GetDoorId(layer);
if (val.ChainedPuzzleToEnter == 0)
{
continue;
}
SecurityDoorData securityDoorData = doors.FirstOrDefault((SecurityDoorData d) => d.Id == doorId);
if (securityDoorData == null)
{
continue;
}
if (securityDoorData.IsCheckpoint)
{
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(23, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Adding a checkpoint to ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(securityDoorData.Name);
}
Log.Logger.LogInfo(val2);
num++;
}
val.IsCheckpointDoor = securityDoorData.IsCheckpoint;
items[i] = val;
}
return num;
}
}
public static class RundownDataManager
{
public static readonly List<RundownData> OriginalData = RetrieveData();
public static List<RundownData> RetrieveData()
{
List<RundownData> list = new List<RundownData>();
Il2CppArrayBase<RundownDataBlock> allBlocks = GameDataBlockBase<RundownDataBlock>.GetAllBlocks();
int count = allBlocks.Count;
for (int i = 0; i < count; i++)
{
RundownDataBlock obj = allBlocks[i];
List<ExpeditionData> list2 = new List<ExpeditionData>();
uint persistentID = ((GameDataBlockBase<RundownDataBlock>)(object)obj).persistentID;
string name = ((GameDataBlockBase<RundownDataBlock>)(object)obj).name;
List<ExpeditionInTierData>[] tiers = obj.GetTiers();
foreach (List<ExpeditionInTierData> val in tiers)
{
if (val == null)
{
continue;
}
Il2CppArrayBase<ExpeditionInTierData> items = val._items;
int size = val._size;
for (int k = 0; k < size; k++)
{
ExpeditionInTierData val2 = items[k];
if (val2 != null && val2.Enabled)
{
List<SecurityDoorData> list3 = new List<SecurityDoorData>();
string expeditionId = val2.GetExpeditionId(k);
AddAllDoorsFromLayoutId(val2.LevelLayoutData, Layer.Main, list3);
if (val2.SecondaryLayerEnabled)
{
AddAllDoorsFromLayoutId(val2.SecondaryLayout, Layer.Secondary, list3);
}
if (val2.ThirdLayerEnabled)
{
AddAllDoorsFromLayoutId(val2.ThirdLayout, Layer.Third, list3);
}
if (list3.Count != 0)
{
ExpeditionData item = new ExpeditionData(expeditionId, val2.LevelLayoutData, list3);
list2.Add(item);
}
}
}
}
if (list2.Count != 0)
{
RundownData item2 = new RundownData(persistentID, name, list2);
list.Add(item2);
}
}
return list;
}
public static Dictionary<string, List<SecurityDoorData>> GetDoorData(List<RundownData> config)
{
return (from d in config.SelectMany((RundownData r) => r.Expeditions)
where d.Doors.Count > 0
select d).ToDictionary((ExpeditionData e) => e.LayoutId.GetHashCode().ToString(), (ExpeditionData e) => e.Doors);
}
private static void AddAllDoorsFromLayoutId(uint layoutId, Layer layer, List<SecurityDoorData> doors)
{
LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(layoutId);
if (block != null)
{
int zoneAliasStart = block.ZoneAliasStart;
AddDoorsFromLayout(block, layer, doors, zoneAliasStart);
}
}
private static void AddDoorsFromLayout(LevelLayoutDataBlock layout, Layer layer, List<SecurityDoorData> doors, int startAlias)
{
//IL_0028: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected I4, but got Unknown
Il2CppArrayBase<ExpeditionZoneData> items = layout.Zones._items;
int size = layout.Zones._size;
for (int i = 0; i < size; i++)
{
ExpeditionZoneData val = items[i];
if ((int)val.LocalIndex != 0)
{
string doorId = val.GetDoorId(layer);
string text = $"Door to zone {startAlias + val.LocalIndex}";
string value = ((val.ChainedPuzzleToEnter == 0) ? "no alarm" : (((GameDataBlockBase<ChainedPuzzleDataBlock>)(object)GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val.ChainedPuzzleToEnter))?.name ?? "unknown alarm"));
string description = $"{text} ({layer}) — {value}";
SecurityDoorData item = new SecurityDoorData(doorId, text, description, val.IsCheckpointDoor);
doors.Add(item);
}
}
}
}
}
namespace CustomCheckpoints.Features
{
[EnableFeatureByDefault]
[DoNotSaveToConfig]
public class CustomCheckpointMenu : Feature
{
public override string Name => "Custom Checkpoints";
public override string Description => "Configure which security doors are converted into checkpoints.";
public override FeatureGroup Group => FeatureGroups.GetOrCreateTopLevelGroup("Custom Checkpoints", (GroupLocalization)null);
[FeatureConfig]
public static MenuSettings Settings { get; set; } = new MenuSettings();
public override void OnGameDataInitialized()
{
RebuildMenuData();
}
private static void RebuildMenuData()
{
CheckpointConfigManager.ValidateConfig();
List<RundownData> config = CheckpointConfigManager.GetConfig();
if (config != null)
{
Settings.Rebuild(config);
}
}
public override void OnFeatureSettingChanged(FeatureSetting setting)
{
foreach (FeatureSettingsHelper settingsHelper in ((Feature)this).SettingsHelpers)
{
((object)settingsHelper).GetType().GetProperty("IsDirty")?.SetValue(settingsHelper, false);
}
}
}
public class DoorMenuItem
{
private SecurityDoorData? _door;
private List<RundownData>? _config;
private bool _isCheckpoint;
public FLabel Door { get; set; } = new FLabel();
public FLabel Description { get; set; } = new FLabel();
[FSDescription("Set this to 'On' if it should be a checkpoint.")]
public bool Checkpoint
{
get
{
return _door?.IsCheckpoint ?? _isCheckpoint;
}
set
{
_isCheckpoint = value;
if (_door != null && _door.IsCheckpoint != value)
{
_door.IsCheckpoint = value;
if (_config != null)
{
CheckpointConfigManager.SaveConfig(_config);
}
}
}
}
public DoorMenuItem()
{
}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
public DoorMenuItem(SecurityDoorData door, List<RundownData> config)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Expected O, but got Unknown
_door = door;
_config = config;
_isCheckpoint = door.IsCheckpoint;
Door = new FLabel("<color=red>" + door.Name + "</color>", (string)null);
Description = new FLabel("<color=yellow>" + door.Description + "</color>", (string)null);
}
}
public class ExpeditionMenuItem
{
public FLabel Expedition { get; set; } = new FLabel();
[FSDisplayName("Security Doors")]
public List<DoorMenuItem> Doors { get; set; } = new List<DoorMenuItem>();
public ExpeditionMenuItem()
{
}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
public ExpeditionMenuItem(ExpeditionData expedition, List<RundownData> config)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
Expedition = new FLabel("<color=red>" + expedition.Id + "</color>", (string)null);
Doors = expedition.Doors.Select((SecurityDoorData door) => new DoorMenuItem(door, config)).ToList();
}
}
public class MenuSettings
{
[FSDisplayName("Rundowns")]
[FSDescription("Choose checkpoint doors by rundown, expedition, and security door.")]
public List<RundownMenuItem> Rundowns { get; set; } = new List<RundownMenuItem>();
public void Rebuild(List<RundownData> config)
{
Rundowns = config.Select((RundownData rundown) => new RundownMenuItem(rundown, config)).ToList();
}
}
public class RundownMenuItem
{
public FLabel Rundown { get; set; } = new FLabel();
[FSDisplayName("Expeditions")]
public List<ExpeditionMenuItem> Expeditions { get; set; } = new List<ExpeditionMenuItem>();
public RundownMenuItem()
{
}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
public RundownMenuItem(RundownData rundown, List<RundownData> config)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
Rundown = new FLabel("<color=red>" + rundown.Name + "</color>", (string)null);
Expeditions = rundown.Expeditions.Select((ExpeditionData expedition) => new ExpeditionMenuItem(expedition, config)).ToList();
}
}
}
namespace CustomCheckpoints.Extensions
{
public static class DataBlockExtensions
{
public static List<ExpeditionInTierData>?[] GetTiers(this RundownDataBlock? dataBlock)
{
return new List<ExpeditionInTierData>[5]
{
(dataBlock != null) ? dataBlock.TierA : null,
(dataBlock != null) ? dataBlock.TierB : null,
(dataBlock != null) ? dataBlock.TierC : null,
(dataBlock != null) ? dataBlock.TierD : null,
(dataBlock != null) ? dataBlock.TierE : null
};
}
public static string GetDoorId(this ExpeditionZoneData zone, Layer layerName)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
return $"{Enum.GetName(typeof(Layer), layerName)}_{zone.LocalIndex}";
}
public static string GetExpeditionId(this ExpeditionInTierData exp, int index)
{
return exp.GetShortName(index) + " " + StripRichText(exp.Descriptive.PublicName);
}
private static string StripRichText(string input)
{
if (string.IsNullOrEmpty(input))
{
return input;
}
return Regex.Replace(input, "<.*?>", string.Empty);
}
}
public static class RundownDataExtensions
{
public static List<RundownData> GetSorted(this List<RundownData> rundowns)
{
return (from r in rundowns
orderby GetRundownSortKey(r.Name), r.Name
select r).ToList();
}
private static int GetRundownSortKey(string name)
{
Match match = Regex.Match(name, "Rundown (\\d+)\\.0");
if (match.Success)
{
return int.Parse(match.Groups[1].Value);
}
return int.MaxValue;
}
}
}
namespace CustomCheckpoints.Data
{
public class ExpeditionData : IEquatable<ExpeditionData>
{
public string Id { get; init; }
public uint LayoutId { get; init; }
public List<SecurityDoorData> Doors { get; init; }
public ExpeditionData(string id, uint layoutId, List<SecurityDoorData> doors)
{
Id = id;
LayoutId = layoutId;
Doors = doors;
}
public bool Equals(ExpeditionData? other)
{
if (other == null)
{
return false;
}
if (Id == other.Id && LayoutId == other.LayoutId)
{
return Doors.SequenceEqual(other.Doors);
}
return false;
}
public override bool Equals(object? obj)
{
return Equals(obj as ExpeditionData);
}
public override int GetHashCode()
{
return HashCode.Combine(Id, LayoutId);
}
}
public enum Layer
{
Main,
Secondary,
Third
}
public class RundownData : IEquatable<RundownData>
{
public uint Id { get; init; }
public string Name { get; init; }
public List<ExpeditionData> Expeditions { get; init; }
public RundownData(uint id, string name, List<ExpeditionData> expeditions)
{
Id = id;
Name = name;
Expeditions = expeditions;
}
public bool Equals(RundownData? other)
{
if (other == null)
{
return false;
}
if (Id == other.Id && Name == other.Name)
{
return Expeditions.SequenceEqual(other.Expeditions);
}
return false;
}
public override bool Equals(object? obj)
{
return Equals(obj as RundownData);
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Name);
}
}
public class SecurityDoorData : IEquatable<SecurityDoorData>
{
public string Id { get; init; }
public string Name { get; init; }
public string Description { get; init; }
public bool IsCheckpoint { get; set; }
public SecurityDoorData(string id, string name, string description, bool isCheckpoint)
{
Id = id;
Name = name;
Description = description;
IsCheckpoint = isCheckpoint;
}
public bool Equals(SecurityDoorData? other)
{
if (other == null)
{
return false;
}
if (Id == other.Id && Name == other.Name)
{
return Description == other.Description;
}
return false;
}
public override bool Equals(object? obj)
{
return Equals(obj as SecurityDoorData);
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Name, Description);
}
}
}