using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.Json; using System.Text.Json.Serialization; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CellMenu; using ExtraObjectiveSetup.Expedition; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LocalProgression; using LocalProgression.Data; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using ProgressionGear.Dependencies; using ProgressionGear.GearToggle; using ProgressionGear.JSON; using ProgressionGear.Patches; using ProgressionGear.ProgressionLock; using ProgressionGear.Utils; using TMPro; 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("ProgressionGear")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+804c32d592b9d5ac8154625bb6c2e69c2e452c63")] [assembly: AssemblyProduct("ProgressionGear")] [assembly: AssemblyTitle("ProgressionGear")] [assembly: AssemblyVersion("1.0.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 ProgressionGear { internal static class Configuration { private static readonly ConfigEntry _disableProgression; private static readonly ConfigEntry _toggleBlink; private static readonly ConfigFile _configFile; public static bool DisableProgression => _disableProgression.Value; public static bool ToggleBlink => _toggleBlink.Value; static Configuration() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown _configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ProgressionGear.cfg"), true); string text = "Override"; _disableProgression = _configFile.Bind(text, "Disable Progression Locks", false, "Disables progression-locking for weapons."); text = "General Settings"; _toggleBlink = _configFile.Bind(text, "Toggle Blink", true, "Enables the blinking effect on gear toggle buttons."); } public static void Init() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown LiveEdit.CreateListener(Paths.ConfigPath, "ProgressionGear.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged); } private static void OnFileChanged(LiveEditEventArgs _) { bool disableProgression = DisableProgression; _configFile.Reload(); if (disableProgression != DisableProgression) { GearLockManager.Current.SetupAllowedGearsForActiveRundown(); } } } internal static class DinoLogger { private static ManualLogSource logger = Logger.CreateLogSource("ProgressionGear"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } [BepInPlugin("Dinorush.ProgressionGear", "ProgressionGear", "1.6.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class EntryPoint : BasePlugin { public const string GUID = "Dinorush.ProgressionGear"; public const string MODNAME = "ProgressionGear"; public override void Load() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (!MTFOWrapper.HasCustomContent) { DinoLogger.Error("No MTFO datablocks detected. Not loading ProgressionGear..."); return; } MTFOHotReloadAPI.OnHotReload += FixGearInstanceDict; Harmony val = new Harmony("ProgressionGear"); val.PatchAll(); if (!LocalProgressionWrapper.HasLocalProgression) { val.PatchAll(typeof(PageRundownPatches_NoLP)); } Configuration.Init(); GearLockManager.Current.Init(); GearToggleManager.Current.Init(); ProgressionLockManager.Current.Init(); DinoLogger.Log("Loaded ProgressionGear"); } private static void FixGearInstanceDict() { GearManager.Current.m_allGearPerInstanceKey.Clear(); GearManager.Current.OnGearLoadingDone(); } } } namespace ProgressionGear.Utils { internal class DictListEnumerator : IEnumerator, IEnumerator, IDisposable { private readonly IEnumerator> _valueEnumerator; private List? _curList; private int _index; private T? _current; public T Current => _current; object IEnumerator.Current => Current; internal DictListEnumerator(Dictionary> data) { _valueEnumerator = data.Values.GetEnumerator(); if (_valueEnumerator.MoveNext()) { _curList = _valueEnumerator.Current; } _index = -1; } public void Dispose() { } public bool MoveNext() { if (_curList == null || ++_index >= _curList.Count) { if (!_valueEnumerator.MoveNext()) { return false; } _curList = _valueEnumerator.Current; _index = 0; } _current = _curList[_index]; return true; } public void Reset() { _valueEnumerator.Reset(); if (_valueEnumerator.MoveNext()) { _curList = _valueEnumerator.Current; } _index = -1; } } internal static class GearIDRangeExtensions { public static uint GetOfflineID(this GearIDRange gearIDRange) { string playfabItemInstanceId = gearIDRange.PlayfabItemInstanceId; if (!playfabItemInstanceId.Contains("OfflineGear_ID_")) { DinoLogger.Error("Find PlayfabItemInstanceId without substring 'OfflineGear_ID_'! " + playfabItemInstanceId); return 0u; } try { return uint.Parse(playfabItemInstanceId.Substring("OfflineGear_ID_".Length)); } catch { DinoLogger.Error("Caught exception while trying to parse persistentID of PlayerOfflineGearDB from GearIDRange, which means itemInstanceId could be ill-formated"); return 0u; } } } internal static class StringExtensions { public static T ToEnum(this string? value, T defaultValue) where T : struct { if (string.IsNullOrEmpty(value)) { return defaultValue; } if (!Enum.TryParse(value.Replace(" ", null), ignoreCase: true, out var result)) { return defaultValue; } return result; } } } namespace ProgressionGear.ProgressionLock { public sealed class GearLockManager { private struct PriorityLockData { public int priority; public bool locked; public bool explicitLock; } private readonly HashSet _lockedGearIds = new HashSet(); internal readonly List<(InventorySlot inventorySlot, Dictionary loadedGears)> GearSlots = new List<(InventorySlot, Dictionary)> { ((InventorySlot)1, new Dictionary()), ((InventorySlot)2, new Dictionary()), ((InventorySlot)10, new Dictionary()), ((InventorySlot)3, new Dictionary()) }; public static GearLockManager Current { get; private set; } = new GearLockManager(); public GearManager? VanillaGearManager { get; internal set; } public void Init() { MTFOHotReloadAPI.OnHotReload += SetupAllowedGearsForActiveRundown; } private void ConfigRundownGears() { _lockedGearIds.Clear(); GearToggleManager.Current.ResetToggleInfos(); if (Configuration.DisableProgression) { return; } IEnumerator enumerator = ProgressionLockManager.Current.GetEnumerator(); Dictionary dictionary = new Dictionary(); while (enumerator.MoveNext()) { ProgressionLockData current = enumerator.Current; foreach (uint offlineID in current.OfflineIDs) { PriorityLockData value = new PriorityLockData { priority = current.Priority, locked = IsGearLocked(current), explicitLock = IsLockExplicit(current) }; if (!dictionary.TryGetValue(offlineID, out var value2) || ((!value2.explicitLock || value.explicitLock) && value2.priority <= value.priority)) { dictionary[offlineID] = value; } } } foreach (KeyValuePair item in dictionary.Where((KeyValuePair kv) => kv.Value.locked)) { _lockedGearIds.Add(item.Key); GearToggleManager.Current.RemoveFromToggleInfos(item.Key); } } private void ClearLoadedGears() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown foreach (var gearSlot in GearSlots) { ((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[(int)gearSlot.inventorySlot].Clear(); } } public bool IsGearAllowed(uint id) { return !_lockedGearIds.Contains(id); } private void AddGearForCurrentRundown() { //IL_0019: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected I4, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) foreach (var gearSlot in GearSlots) { InventorySlot item = gearSlot.inventorySlot; Dictionary item2 = gearSlot.loadedGears; List val = ((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[(int)item]; if (item2.Count == 0) { DinoLogger.Debug($"No gear has been loaded for {item}."); continue; } foreach (uint key in item2.Keys) { if (!EOSWrapper.IsGearAllowed(key)) { GearToggleManager.Current.RemoveFromToggleInfos(key); } else if (IsGearAllowed(key)) { val.Add(item2[key]); } } if (val.Count == 0) { DinoLogger.Warning($"No gear is allowed for {item}!"); } } } private unsafe void ResetPlayerSelectedGears() { //IL_00c5: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected I4, but got Unknown VanillaGearManager.RescanFavorites(); foreach (var gearSlot in GearSlots) { InventorySlot item = gearSlot.inventorySlot; int num = (int)item; try { if (((Il2CppArrayBase)(object)VanillaGearManager.m_lastEquippedGearPerSlot)[num] != null) { PlayerBackpackManager.EquipLocalGear(((Il2CppArrayBase)(object)VanillaGearManager.m_lastEquippedGearPerSlot)[num]); } else if (((Il2CppArrayBase>)(object)VanillaGearManager.m_favoriteGearPerSlot)[num].Count > 0) { PlayerBackpackManager.EquipLocalGear(((Il2CppArrayBase>)(object)VanillaGearManager.m_favoriteGearPerSlot)[num][0]); } else if (((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[num].Count > 0) { PlayerBackpackManager.EquipLocalGear(((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[num][0]); } } catch (Il2CppException ex) { Il2CppException ex2 = ex; DinoLogger.Error("Error attempting to equip gear for slot " + ((object)(*(InventorySlot*)(&item))/*cast due to .constrained prefix*/).ToString() + ":\n" + ((Exception)(object)ex2).StackTrace); } } } private void RemoveToggleGears() { //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown foreach (var gearSlot in GearSlots) { InventorySlot item = gearSlot.inventorySlot; List val = ((Il2CppArrayBase>)(object)VanillaGearManager.m_gearPerSlot)[(int)item]; for (int num = val.Count - 1; num >= 0; num--) { if (!GearToggleManager.Current.IsVisibleID(val[num].GetOfflineID())) { val.RemoveAt(num); } } } } internal void SetupAllowedGearsForActiveRundown() { if (ProgressionWrapper.UpdateReferences()) { EOSWrapper.CacheLocks(); ConfigRundownGears(); ClearLoadedGears(); AddGearForCurrentRundown(); ResetPlayerSelectedGears(); RemoveToggleGears(); } } private static bool IsGearLocked(ProgressionLockData data) { if (!data.Unlock.Any() || IsComplete(data.Unlock, data.UnlockRequired, data.MissingLevelDefault)) { if (data.Lock.Any()) { return IsComplete(data.Lock, data.LockRequired, data.MissingLevelDefault); } return false; } return true; } private static bool IsLockExplicit(ProgressionLockData data) { if (!IsComplete(data.Unlock, data.UnlockRequired, data.MissingLevelDefault)) { if (data.Lock.Any()) { return IsComplete(data.Lock, data.LockRequired, data.MissingLevelDefault); } return false; } return true; } private static bool IsComplete(List list, int require, bool valueIfNone) { if (require == 0) { foreach (ProgressionRequirement item in list) { if (!IsComplete(item, valueIfNone)) { return false; } } } else { foreach (ProgressionRequirement item2 in list) { if (IsComplete(item2, valueIfNone)) { require--; } if (require == 0) { break; } } } return require == 0; } private static bool IsComplete(ProgressionRequirement req, bool valueIfNone) { return ProgressionWrapper.IsComplete(req, valueIfNone); } } public sealed class ProgressionData { public string ExpeditionKey { get; set; } = string.Empty; public int MainCompletionCount { get; set; } public int SecondaryCompletionCount { get; set; } public int ThirdCompletionCount { get; set; } public int AllCompletionCount { get; set; } public int NoBoosterAllClearCount { get; set; } public ProgressionData() { } public ProgressionData(string key, int main, int secondary, int third, int all, int noBooster) { ExpeditionKey = key; MainCompletionCount = main; SecondaryCompletionCount = secondary; ThirdCompletionCount = third; AllCompletionCount = all; NoBoosterAllClearCount = noBooster; } } public sealed class ProgressionLockData { public static readonly ProgressionLockData[] Template = new ProgressionLockData[2] { new ProgressionLockData { Unlock = new List { new ProgressionRequirement { LevelLayoutID = 420u }, new ProgressionRequirement { Tier = (eRundownTier)2 }, new ProgressionRequirement { LevelLayoutID = 10u, Main = true, Secondary = true }, new ProgressionRequirement { Tier = (eRundownTier)1, TierIndex = 1, Main = false, All = true } }, UnlockRequired = 2, Lock = new List { new ProgressionRequirement { Tier = (eRundownTier)3 } }, LockRequired = 0, OfflineIDs = new List { 0u }, Priority = 0, Name = "Example" }, new ProgressionLockData { Name = "Empty Example" } }; public int UnlockRequired; public int LockRequired; public List Unlock { get; set; } = new List(); public List Lock { get; set; } = new List(); public bool MissingLevelDefault { get; set; } = true; public List OfflineIDs { get; set; } = new List(); public int Priority { get; set; } public string Name { get; set; } = string.Empty; } public sealed class ProgressionLockManager { public static readonly ProgressionLockManager Current = new ProgressionLockManager(); private readonly Dictionary> _fileToData = new Dictionary>(); private readonly LiveEditListener _liveEditListener; private void FileChanged(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { ReadFileContent(e.FullPath, content); }); } private void FileDeleted(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Removed: " + e.FullPath); _fileToData.Remove(e.FullPath); RefreshLocks(); } private void FileCreated(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Created: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { ReadFileContent(e.FullPath, content); }); } private void ReadFileContent(string file, string content) { _fileToData.Remove(file); List list = null; try { list = PWJson.Deserialize>(content); } catch (JsonException ex) { DinoLogger.Error("Error parsing progression lock json " + file); DinoLogger.Error(ex.Message); } if (list != null) { _fileToData[file] = list; RefreshLocks(); } } private static void RefreshLocks() { GearLockManager.Current.SetupAllowedGearsForActiveRundown(); } private ProgressionLockManager() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown string text = Path.Combine(MTFOWrapper.CustomPath, "ProgressionGear", "ProgressionLocks"); if (!Directory.Exists(text)) { DinoLogger.Log("No ProgressionLocks directory detected. Creating template."); Directory.CreateDirectory(text); StreamWriter streamWriter = File.CreateText(Path.Combine(text, "Template.json")); streamWriter.WriteLine(PWJson.Serialize(ProgressionLockData.Template)); streamWriter.Flush(); streamWriter.Close(); } else { DinoLogger.Log("ProgressionLocks directory detected."); } foreach (string item in Directory.EnumerateFiles(text, "*.json", SearchOption.AllDirectories)) { string content = File.ReadAllText(item); ReadFileContent(item, content); } _liveEditListener = LiveEdit.CreateListener(text, "*.json", true); _liveEditListener.FileCreated += new LiveEditEventHandler(FileCreated); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); _liveEditListener.FileDeleted += new LiveEditEventHandler(FileDeleted); } internal void Init() { } public List GetLockData() { List list = new List(_fileToData.Values.Sum((List list2) => list2.Count)); IEnumerator enumerator = GetEnumerator(); while (enumerator.MoveNext()) { list.Add(enumerator.Current); } return list; } public IEnumerator GetEnumerator() { return new DictListEnumerator(_fileToData); } } public sealed class ProgressionRequirement { public eRundownTier Tier { get; set; } = (eRundownTier)99; public int TierIndex { get; set; } = -1; public uint LevelLayoutID { get; set; } public bool Main { get; set; } = true; public bool Secondary { get; set; } public bool Overload { get; set; } public bool All { get; set; } public bool AllNoBooster { get; set; } public bool Complete(ProgressionData data) { if ((!AllNoBooster || data.NoBoosterAllClearCount > 0) && (!All || data.AllCompletionCount > 0) && (!Main || data.MainCompletionCount > 0) && (!Secondary || data.SecondaryCompletionCount > 0)) { if (Overload) { return data.ThirdCompletionCount > 0; } return true; } return false; } } public static class ProgressionWrapper { private struct ExpeditionKey { public eRundownTier tier; public int expIndex; } private static readonly Dictionary _layoutToExpedition; private static readonly Dictionary> _tierExpeditionKeys; private static readonly Dictionary> _nativeProgression; public static uint CurrentRundownID { get; private set; } static ProgressionWrapper() { _layoutToExpedition = new Dictionary(); _tierExpeditionKeys = new Dictionary> { { (eRundownTier)1, new List() }, { (eRundownTier)2, new List() }, { (eRundownTier)3, new List() }, { (eRundownTier)4, new List() }, { (eRundownTier)5, new List() } }; _nativeProgression = new Dictionary>(); CurrentRundownID = 0u; } private static uint ActiveRundownID() { string activeRundownKey = RundownManager.ActiveRundownKey; uint result = default(uint); if (!RundownManager.RundownProgressionReady || !RundownManager.TryGetIdFromLocalRundownKey(activeRundownKey, ref result)) { return 0u; } return result; } public static bool UpdateReferences() { uint num = ActiveRundownID(); if (num == 0) { return false; } if (CurrentRundownID == num) { return true; } CurrentRundownID = num; _layoutToExpedition.Clear(); RundownDataBlock block = GameDataBlockBase.GetBlock(CurrentRundownID); AddTierLayouts((eRundownTier)1, block.TierA); AddTierLayouts((eRundownTier)2, block.TierB); AddTierLayouts((eRundownTier)3, block.TierC); AddTierLayouts((eRundownTier)4, block.TierD); AddTierLayouts((eRundownTier)5, block.TierE); return true; } internal static void UpdateNativeProgression(eRundownTier tier, int expIndex, ProgressionData data) { //IL_000b: 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_0018: Unknown result type (might be due to invalid IL or missing references) UpdateReferences(); if (!_nativeProgression.ContainsKey(tier)) { _nativeProgression[tier] = new List(5); } List list = _nativeProgression[tier]; if (list.Count <= expIndex) { list.EnsureCapacity(expIndex + 1); for (int i = list.Count; i <= expIndex; i++) { list.Add(new ProgressionData()); } } list[expIndex] = data; } private static void AddTierLayouts(eRundownTier tier, List dataList) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0055: Unknown result type (might be due to invalid IL or missing references) _tierExpeditionKeys[tier].Clear(); for (int i = 0; i < dataList.Count; i++) { ExpeditionInTierData val = dataList[i]; if (val.Enabled) { ExpeditionKey expeditionKey = new ExpeditionKey { tier = tier, expIndex = i }; _layoutToExpedition.TryAdd(val.LevelLayoutData, expeditionKey); _tierExpeditionKeys[tier].Add(expeditionKey); } } } private static ProgressionData GetProgressionData(uint id, eRundownTier tier, int index) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (LocalProgressionWrapper.HasLocalProgression) { return LocalProgressionWrapper.GetProgressionDataLP(id, tier, index); } if (_nativeProgression.Count == 0) { return new ProgressionData(); } return _nativeProgression[tier][index]; } public static bool IsComplete(ProgressionRequirement req, bool valueIfNone = true) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) UpdateReferences(); if (req.LevelLayoutID != 0) { if (!_layoutToExpedition.ContainsKey(req.LevelLayoutID)) { return valueIfNone; } ExpeditionKey expeditionKey = _layoutToExpedition[req.LevelLayoutID]; return req.Complete(GetProgressionData(CurrentRundownID, expeditionKey.tier, expeditionKey.expIndex)); } if ((int)req.Tier != 99) { if (!_tierExpeditionKeys.ContainsKey(req.Tier)) { return valueIfNone; } if (req.TierIndex >= 0) { if (req.TierIndex < _tierExpeditionKeys[req.Tier].Count) { return req.Complete(GetProgressionData(CurrentRundownID, req.Tier, req.TierIndex)); } return valueIfNone; } foreach (ExpeditionKey item in _tierExpeditionKeys[req.Tier]) { if (!req.Complete(GetProgressionData(CurrentRundownID, item.tier, item.expIndex))) { return false; } } } return true; } } } namespace ProgressionGear.Patches { [HarmonyPatch] internal static class GearManagerPatches { private static readonly Dictionary _checksumToRanges = new Dictionary(); [HarmonyPatch(typeof(GearManager), "SetupGearInOfflineMode")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_SetupGearInOfflineMode() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected I4, but got Unknown GearLockManager.Current.VanillaGearManager = GearManager.Current; foreach (var gearSlot in GearLockManager.Current.GearSlots) { InventorySlot item = gearSlot.inventorySlot; Dictionary item2 = gearSlot.loadedGears; Enumerator enumerator2 = ((Il2CppArrayBase>)(object)GearManager.Current.m_gearPerSlot)[(int)item].GetEnumerator(); while (enumerator2.MoveNext()) { GearIDRange current2 = enumerator2.Current; uint offlineID = current2.GetOfflineID(); item2.TryAdd(offlineID, current2); } } GearToggleManager.Current.ResetToggleInfos(); } [HarmonyPatch(typeof(CM_PlayerInventory), "UpdateInventory")] [HarmonyWrapSafe] [HarmonyPrefix] private static void Pre_UpdateInventoryIcons() { _checksumToRanges.Clear(); CacheSlot((InventorySlot)1); CacheSlot((InventorySlot)2); CacheSlot((InventorySlot)10); CacheSlot((InventorySlot)3); static void CacheSlot(InventorySlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) foreach (GearIDRange item in (Il2CppArrayBase)(object)GearManager.GetAllGearForSlot(slot)) { _checksumToRanges.TryAdd(item.GetChecksum(), item); } } } [HarmonyPatch(typeof(GearManager), "CheckGearIconTargetCallbacks")] [HarmonyWrapSafe] [HarmonyPrefix] private static bool Pre_IconsLoadedCallbacks(uint gearKey) { if (_checksumToRanges.TryGetValue(gearKey, out GearIDRange value)) { return value != null; } return true; } } internal static class PageRundownPatches_NoLP { [HarmonyPatch(typeof(CM_PageRundown_New), "SetIconStatus")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_IconUpdate(CM_ExpeditionIcon_New icon, string mainFinishCount, string secondFinishCount, string thirdFinishCount, string allFinishedCount) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) ProgressionData progressionData = new ProgressionData(); if (mainFinishCount != "-") { progressionData.MainCompletionCount = int.Parse(mainFinishCount); } if (secondFinishCount != "-") { progressionData.SecondaryCompletionCount = int.Parse(secondFinishCount); } if (thirdFinishCount != "-") { progressionData.ThirdCompletionCount = int.Parse(thirdFinishCount); } if (allFinishedCount != "-") { progressionData.AllCompletionCount = int.Parse(allFinishedCount); } ProgressionWrapper.UpdateNativeProgression(icon.Tier, icon.ExpIndex, progressionData); } } [HarmonyPatch] internal static class PlayerLobbyBarPatches { private struct ButtonInfo { public GameObject go; public CM_ScrollWindowHeader item; public BoxCollider2D collider; public TextMeshPro text; public readonly void SetMode(bool isDouble) { //IL_0039: 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_000e: 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_0023: Unknown result type (might be due to invalid IL or missing references) if (isDouble) { go.transform.localPosition = DoubleButtonPos; ((Collider2D)collider).offset = Vector2.op_Implicit(DoubleColliderOffset); } else { go.transform.localPosition = SingleButtonPos; ((Collider2D)collider).offset = Vector2.op_Implicit(SingleColliderOffset); } } } private static readonly Vector3 SingleButtonPos = new Vector3(360f, -800f, -2f); private static readonly Vector3 DoubleButtonPos = new Vector3(500f, -800f, -2f); private static readonly Vector3 SingleColliderOffset = new Vector3(90f, -6.5f); private static readonly Vector3 DoubleColliderOffset = new Vector3(100f, -6.5f); private static CM_InventorySlotItem? _cachedItem; private static ButtonInfo _leftButton; private static ButtonInfo _rightButton; private static CM_PlayerLobbyBar? _activeBar; [HarmonyPatch(typeof(CM_PlayerLobbyBar), "ShowWeaponSelectionPopup")] [HarmonyAfter(new string[] { "Inas.ExtraObjectiveSetup" })] [HarmonyWrapSafe] [HarmonyPrefix] private static void Pre_ShowLoadoutForSlot() { uint currentRundownID = ProgressionWrapper.CurrentRundownID; if (ProgressionWrapper.UpdateReferences() && currentRundownID != ProgressionWrapper.CurrentRundownID) { GearLockManager.Current.SetupAllowedGearsForActiveRundown(); } } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "UpdateWeaponWindowInfo")] [HarmonyPrefix] private static void Pre_LoadoutHeaderSelected(CM_PlayerLobbyBar __instance) { _cachedItem = __instance.selectedWeaponSlotItem; } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "UpdateWeaponWindowInfo")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_LoadoutHeaderSelected(CM_PlayerLobbyBar __instance, InventorySlot slot) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) BackpackItem val = default(BackpackItem); if ((Object)(object)_cachedItem != (Object)(object)__instance.selectedWeaponSlotItem || !PlayerBackpackManager.TryGetItem(__instance.m_player, slot, ref val) || val.GearIDRange == null) { return; } uint offlineID = val.GearIDRange.GetOfflineID(); if (!GearToggleManager.Current.TryGetToggleInfo(offlineID, out var toggleInfo)) { return; } foreach (iScrollWindowContent item in (Il2CppArrayBase)(object)__instance.m_popupScrollWindow.ContentItems) { CM_InventorySlotItem val2 = ((Il2CppObjectBase)item).TryCast(); if (toggleInfo.ids.Contains(val2.m_gearID.GetOfflineID())) { val2.IsPicked = true; val2.LoadData(val.GearIDRange, true, true); __instance.OnWeaponSlotItemSelected(val2); _cachedItem = __instance.selectedWeaponSlotItem; break; } } } [HarmonyPatch(typeof(CM_ScrollWindow), "Setup", new Type[] { })] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_LobbyBarSetup(CM_ScrollWindow __instance) { if (!((Object)(object)_rightButton.go != (Object)null)) { CreateButton(__instance, ref _rightButton, right: true); CreateButton(__instance, ref _leftButton, right: false); } } [HarmonyPatch(typeof(CM_ScrollWindow), "ResetHeaders")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_ResetHeaders() { if (!((Object)(object)_rightButton.go == (Object)null)) { _rightButton.go.SetActive(false); _leftButton.go.SetActive(false); } } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "ShowWeaponSelectionPopup")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_LoadoutMenuOpened(CM_PlayerLobbyBar __instance) { //IL_004c: 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) CM_ScrollWindow popupScrollWindow = __instance.m_popupScrollWindow; _rightButton.go.transform.SetParent(((Component)popupScrollWindow).transform, false); _leftButton.go.transform.SetParent(((Component)popupScrollWindow).transform, false); _rightButton.go.transform.localPosition = DoubleButtonPos; _leftButton.go.transform.localPosition = DoubleButtonPos; popupScrollWindow.AddNonContentItem((CM_Item)(object)_rightButton.item); popupScrollWindow.AddNonContentItem((CM_Item)(object)_leftButton.item); _activeBar = __instance; if ((Object)(object)__instance.selectedWeaponSlotItem != (Object)null) { Post_LoadoutItemSelected(__instance.selectedWeaponSlotItem); } } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "OnWeaponSlotItemSelected")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_LoadoutItemSelected(CM_InventorySlotItem slotItem) { if ((Object)(object)_rightButton.go == (Object)null) { return; } uint offlineID = slotItem.m_gearID.GetOfflineID(); if (GearToggleManager.Current.TryGetToggleInfo(offlineID, out var toggleInfo)) { if (toggleInfo.text.Length > 1) { _rightButton.go.SetActive(true); _rightButton.SetMode(isDouble: true); ((TMP_Text)_rightButton.text).SetText(LocalizedText.op_Implicit(toggleInfo.text[0]), true); _leftButton.go.SetActive(true); ((TMP_Text)_leftButton.text).SetText(LocalizedText.op_Implicit(toggleInfo.text[1]), true); } else { _rightButton.go.SetActive(true); _rightButton.SetMode(isDouble: false); ((TMP_Text)_rightButton.text).SetText(LocalizedText.op_Implicit(toggleInfo.text[0]), true); _leftButton.go.SetActive(false); } } else { _rightButton.go.SetActive(false); _leftButton.go.SetActive(false); } } private static void CreateButton(CM_ScrollWindow window, ref ButtonInfo button, bool right) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) button.go = Object.Instantiate(((Component)((Il2CppArrayBase)(object)window.m_headers)[0]).gameObject); ((Object)button.go).name = "PG_" + (right ? "Right" : "Left"); CM_ScrollWindowHeader val = (button.item = button.go.GetComponent()); val.SetSelected(false); Transform transform = button.go.transform; transform.localScale = Vector3.one * 1.5f; transform.Rotate(0f, (float)(right ? 180 : 0), 180f); Transform child = transform.GetChild(0); child.localPosition = new Vector3(5f, -25f, 0f); ((Component)child).GetComponent().size = new Vector2(2600f, 29f); Transform child2 = transform.GetChild(1); child2.Rotate(0f, (float)(right ? 180 : 0), 180f); child2.localPosition = (right ? new Vector3(-10f, -5f, 0f) : new Vector3(185f, -5f, 0f)); button.text = ((Il2CppArrayBase)(object)((CM_Item)val).m_texts)[0]; ((TMP_Text)button.text).alignment = (TextAlignmentOptions)4098; transform.GetChild(2).localScale = new Vector3(0.8f, 1f, 1f); button.collider = ((CM_Item)val).m_collider; button.collider.size = new Vector2(200f, 40f); ((Collider2D)button.collider).offset = Vector2.op_Implicit(DoubleColliderOffset); button.go.SetActive(false); ((CM_Item)val).OnBtnPressCallback = null; ((CM_Item)val).OnBtnPressCallback += Action.op_Implicit(ButtonPressedCallback(right)); } private static Action ButtonPressedCallback(bool toNext) { return delegate { CM_InventorySlotItem val = _activeBar.selectedWeaponSlotItem ?? _cachedItem; if (!((Object)(object)val == (Object)null)) { uint offlineID = val.m_gearID.GetOfflineID(); ToggleInfo toggleInfo = GearToggleManager.Current.GetToggleInfo(offlineID); List ids = toggleInfo.ids; int num = ((toNext ^ toggleInfo.reverse) ? 1 : (ids.Count - 1)); uint value = ids[(ids.IndexOf(offlineID) + num) % ids.Count]; GearIDRange val2 = default(GearIDRange); if (GearManager.TryGetGear("OfflineGear_ID_" + value, ref val2)) { val.LoadData(val2, true, true); _activeBar.OnWeaponSlotItemSelected(val); } else { DinoLogger.Error($"Couldn't swap to next weapon ({value}) in toggle list!"); } } }; } } [HarmonyPatch] internal static class RundownManagerPatches { [HarmonyPatch(typeof(RundownManager), "SetActiveExpedition")] [HarmonyAfter(new string[] { "Inas.ExtraObjectiveSetup" })] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_RundownManager_SetActiveExpedition(pActiveExpedition expPackage) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)expPackage.tier != 99) { GearLockManager.Current.SetupAllowedGearsForActiveRundown(); } } } } namespace ProgressionGear.JSON { public sealed class GearToggleDataConverter : JsonConverter { public override GearToggleData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { GearToggleData gearToggleData = new GearToggleData(); if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException("Expected progression lock to be an object"); } while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return gearToggleData; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string? text = reader.GetString(); reader.Read(); switch (text.ToLowerInvariant().Replace(" ", "")) { case "offlineids": { if (PWJson.TryDeserialize>(ref reader, out var value, options)) { gearToggleData.OfflineIDs = value; break; } throw new JsonException("GearToggle: Failed to read OfflineIDs!"); } case "buttontext": { if (TryReadButtonText(ref reader, out LocalizedText[] buttonText, options)) { gearToggleData.ButtonText = buttonText; break; } throw new JsonException("GearToggle: Failed to read ButtonText!"); } case "reverseorder": if (reader.TokenType != JsonTokenType.True && reader.TokenType != JsonTokenType.False) { throw new JsonException("GearToggle: Expected boolean for ReverseOrder"); } gearToggleData.ReverseOrder = reader.GetBoolean(); break; case "name": if (reader.TokenType != JsonTokenType.String) { throw new JsonException("GearToggle: Expected string for Name"); } gearToggleData.Name = reader.GetString(); break; } } throw new JsonException("Expected EndObject token"); } private static bool TryReadButtonText(ref Utf8JsonReader reader, out LocalizedText[] buttonText, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.StartArray) { buttonText = (LocalizedText[])(object)new LocalizedText[2]; reader.Read(); if (!PWJson.TryDeserialize(ref reader, out buttonText[1], options)) { throw new JsonException("GearToggle: Failed to read right ButtonText!"); } reader.Read(); if (reader.TokenType == JsonTokenType.EndArray) { buttonText = (LocalizedText[])(object)new LocalizedText[1] { buttonText[1] }; return true; } if (reader.TokenType == JsonTokenType.Null) { buttonText = (LocalizedText[])(object)new LocalizedText[1] { buttonText[1] }; reader.Read(); } else if (!PWJson.TryDeserialize(ref reader, out buttonText[0], options)) { throw new JsonException("GearToggle: Failed to read left ButtonText!"); } reader.Read(); if (reader.TokenType != JsonTokenType.EndArray) { throw new JsonException($"GearToggle: Expected EndArray token when reading ButtonText, found {reader.TokenType}"); } return true; } buttonText = (LocalizedText[])(object)new LocalizedText[1]; if (!PWJson.TryDeserialize(ref reader, out buttonText[0], options)) { throw new JsonException("GearToggle: Failed to read ButtonText!"); } return true; } public override void Write(Utf8JsonWriter writer, GearToggleData? value, JsonSerializerOptions options) { if (value != null) { writer.WriteStartObject(); PWJson.Serialize(writer, "OfflineIDs", value.OfflineIDs, options); if (value.ButtonText.Length > 1) { writer.WriteStartArray("ButtonText"); PWJson.Serialize(writer, value.ButtonText[0], options); PWJson.Serialize(writer, value.ButtonText[1], options); writer.WriteEndArray(); } else { PWJson.Serialize(writer, "ButtonText", value.ButtonText[0], options); } writer.WriteBoolean("ReverseOrder", value.ReverseOrder); writer.WriteString("Name", value.Name); writer.WriteEndObject(); } } } public sealed class ProgressionLockDataConverter : JsonConverter { public override ProgressionLockData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ProgressionLockData progressionLockData = new ProgressionLockData(); if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException("Expected progression lock to be an object"); } while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return progressionLockData; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string? text = reader.GetString(); reader.Read(); switch (text.ToLowerInvariant().Replace(" ", "")) { case "unlocklayoutids": case "unlocktiers": case "unlock": { if (PWJson.TryDeserialize>(ref reader, out var value2, options)) { progressionLockData.Unlock = value2; } break; } case "unlockrequired": if (reader.TokenType != JsonTokenType.Number) { throw new JsonException("Expected number for UnlockRequired"); } progressionLockData.UnlockRequired = reader.GetInt32(); break; case "locklayoutids": case "locktiers": case "lock": { if (PWJson.TryDeserialize>(ref reader, out var value, options)) { progressionLockData.Lock = value; } break; } case "lockrequired": if (reader.TokenType != JsonTokenType.Number) { throw new JsonException("Expected number for LockRequired"); } progressionLockData.LockRequired = reader.GetInt32(); break; case "missingleveldefault": if (reader.TokenType != JsonTokenType.True && reader.TokenType != JsonTokenType.False) { throw new JsonException("Expected boolean for MissingLevelDefault"); } progressionLockData.MissingLevelDefault = reader.GetBoolean(); break; case "offlineids": { if (PWJson.TryDeserialize>(ref reader, out var value3, options)) { progressionLockData.OfflineIDs = value3; } break; } case "priority": if (reader.TokenType != JsonTokenType.Number) { throw new JsonException("Expected number for Priority"); } progressionLockData.Priority = reader.GetInt32(); break; case "overload": if (reader.TokenType != JsonTokenType.String) { throw new JsonException("Expected string for Name"); } progressionLockData.Name = reader.GetString(); break; } } throw new JsonException("Expected EndObject token"); } public override void Write(Utf8JsonWriter writer, ProgressionLockData? value, JsonSerializerOptions options) { if (value != null) { writer.WriteStartObject(); writer.WritePropertyName("Unlock"); PWJson.Serialize(writer, value.Unlock); writer.WriteNumber("UnlockRequired", value.UnlockRequired); writer.WritePropertyName("Lock"); PWJson.Serialize(writer, value.Lock); writer.WriteNumber("LockRequired", value.LockRequired); writer.WritePropertyName("OfflineIDs"); PWJson.Serialize(writer, value.OfflineIDs); writer.WriteNumber("Priority", value.Priority); writer.WriteString("Name", value.Name); writer.WriteEndObject(); } } } public sealed class ProgressionRequirementConverter : JsonConverter { public override ProgressionRequirement? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { ProgressionRequirement progressionRequirement = new ProgressionRequirement(); if (ParseRequirement(ref reader, progressionRequirement, options)) { return progressionRequirement; } if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException("Expected progression requirement to be a tier, level layout ID, or object"); } while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return progressionRequirement; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string? text = reader.GetString(); reader.Read(); switch (text.ToLowerInvariant().Replace(" ", "")) { case "levellayout": case "requirement": case "levelid": case "tier": case "level": case "levellayoutid": ParseRequirement(ref reader, progressionRequirement, options); break; case "high": case "main": progressionRequirement.Main = reader.GetBoolean(); break; case "extreme": case "secondary": progressionRequirement.Secondary = reader.GetBoolean(); break; case "overload": progressionRequirement.Overload = reader.GetBoolean(); break; case "all": case "pe": case "prisonerefficiency": progressionRequirement.All = reader.GetBoolean(); break; case "penobooster": case "allnobooster": case "prisonerefficiencynobooster": progressionRequirement.AllNoBooster = reader.GetBoolean(); break; } } throw new JsonException("Expected EndObject token"); } private static bool ParseRequirement(ref Utf8JsonReader reader, ProgressionRequirement req, JsonSerializerOptions options) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 if (reader.TokenType == JsonTokenType.Null) { return true; } if (reader.TokenType == JsonTokenType.String) { string text = reader.GetString(); if (text.Length >= 5) { req.Tier = text.Substring(0, 5).ToEnum((eRundownTier)99); } else { req.Tier = ("Tier" + text[0]).ToEnum((eRundownTier)99); } int num = ((text.Length < 5) ? 1 : 5); if ((int)req.Tier != 99 && text.Length > num) { if (int.TryParse(text.Substring(num), out var result)) { req.TierIndex = result - 1; } else { req.Tier = (eRundownTier)99; } } if ((int)req.Tier == 99) { req.LevelLayoutID = JsonSerializer.Deserialize(ref reader, options); } return true; } if (reader.TokenType == JsonTokenType.Number) { req.LevelLayoutID = reader.GetUInt32(); return true; } return false; } public override void Write(Utf8JsonWriter writer, ProgressionRequirement? value, JsonSerializerOptions options) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (value == null) { return; } if (value.LevelLayoutID == 0 && (int)value.Tier == 99) { writer.WriteNullValue(); return; } if (value.Main && !value.Secondary && !value.Overload && !value.All) { if (value.LevelLayoutID != 0) { writer.WriteNumberValue(value.LevelLayoutID); } else { writer.WriteStringValue(((object)value.Tier/*cast due to .constrained prefix*/).ToString()); } return; } writer.WriteStartObject(); writer.WritePropertyName("Level"); if (value.LevelLayoutID != 0) { writer.WriteNumberValue(value.LevelLayoutID); } else { writer.WriteStringValue(((object)value.Tier/*cast due to .constrained prefix*/).ToString() + ((value.TierIndex >= 0) ? ((object)(value.TierIndex + 1)) : "")); } writer.WriteBoolean("Main", value.Main); writer.WriteBoolean("Secondary", value.Secondary); writer.WriteBoolean("Overload", value.Overload); writer.WriteBoolean("All", value.All); writer.WriteBoolean("AllNoBooster", value.AllNoBooster); writer.WriteEndObject(); } } public static class PWJson { private static readonly JsonSerializerOptions _settings; static PWJson() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown _settings = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = true, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _settings.Converters.Add(new JsonStringEnumConverter()); _settings.Converters.Add((JsonConverter)new LocalizedTextConverter()); _settings.Converters.Add(new ProgressionRequirementConverter()); _settings.Converters.Add(new ProgressionLockDataConverter()); _settings.Converters.Add(new GearToggleDataConverter()); if (PartialDataWrapper.HasPartialData) { _settings.Converters.Add(PartialDataWrapper.PersistentIDConverter); } } public static T? Deserialize(string json) { return JsonSerializer.Deserialize(json, _settings); } public static object? Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _settings); } public static T? Deserialize(ref Utf8JsonReader reader) { return JsonSerializer.Deserialize(ref reader, _settings); } public static bool TryDeserialize(ref Utf8JsonReader reader, [MaybeNullWhen(false)] out T value) { value = Deserialize(ref reader); return value != null; } public static bool TryDeserialize(ref Utf8JsonReader reader, [MaybeNullWhen(false)] out T value, JsonSerializerOptions options) { value = JsonSerializer.Deserialize(ref reader, options); return value != null; } public static string Serialize(T value) { return JsonSerializer.Serialize(value, _settings); } public static void Serialize(Utf8JsonWriter writer, T value) { JsonSerializer.Serialize(writer, value, _settings); } public static void Serialize(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } public static void Serialize(Utf8JsonWriter writer, string name, T value, JsonSerializerOptions options) { writer.WritePropertyName(name); JsonSerializer.Serialize(writer, value, options); } } } namespace ProgressionGear.GearToggle { public sealed class GearToggleData { private static readonly List DefaultIDs = new List(); private static readonly LocalizedText DefaultText = new LocalizedText { Id = 0u, UntranslatedText = "Switch Gear" }; private static readonly LocalizedText[] DefaultTextArr = (LocalizedText[])(object)new LocalizedText[1] { DefaultText }; public static readonly GearToggleData[] Template = new GearToggleData[2] { new GearToggleData(), new GearToggleData { ButtonText = (LocalizedText[])(object)new LocalizedText[2] { new LocalizedText { Id = 0u, UntranslatedText = "Previous" }, new LocalizedText { Id = 0u, UntranslatedText = "Next" } } } }; public List OfflineIDs { get; set; } = DefaultIDs; public LocalizedText[] ButtonText { get; set; } = DefaultTextArr; public bool ReverseOrder { get; set; } public string Name { get; set; } = string.Empty; } public sealed class GearToggleManager { public static readonly GearToggleManager Current = new GearToggleManager(); private readonly Dictionary> _fileToData = new Dictionary>(); private readonly Dictionary _idToInfo = new Dictionary(); private readonly LiveEditListener _liveEditListener; private void FileChanged(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { ReadFileContent(e.FullPath, content); }); } private void FileDeleted(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Removed: " + e.FullPath); _fileToData.Remove(e.FullPath); ResetToggleInfos(); RefreshLocks(); } private void FileCreated(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Created: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { ReadFileContent(e.FullPath, content); }); } private void ReadFileContent(string file, string content) { _fileToData.Remove(file); List list = null; try { list = PWJson.Deserialize>(content); } catch (JsonException ex) { DinoLogger.Error("Error parsing progression lock json " + file); DinoLogger.Error(ex.Message); } if (list != null) { _fileToData[file] = list; ResetToggleInfos(); RefreshLocks(); } } private static void RefreshLocks() { GearLockManager.Current.SetupAllowedGearsForActiveRundown(); } private GearToggleManager() { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown string text = Path.Combine(MTFOWrapper.CustomPath, "ProgressionGear", "GearToggle"); if (!Directory.Exists(text)) { DinoLogger.Log("No GearToggle directory detected. Creating template."); Directory.CreateDirectory(text); StreamWriter streamWriter = File.CreateText(Path.Combine(text, "Template.json")); streamWriter.WriteLine(PWJson.Serialize(GearToggleData.Template)); streamWriter.Flush(); streamWriter.Close(); } else { DinoLogger.Log("GearToggle directory detected."); } foreach (string item in Directory.EnumerateFiles(text, "*.json", SearchOption.AllDirectories)) { string content = File.ReadAllText(item); ReadFileContent(item, content); } _liveEditListener = LiveEdit.CreateListener(text, "*.json", true); _liveEditListener.FileCreated += new LiveEditEventHandler(FileCreated); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); _liveEditListener.FileDeleted += new LiveEditEventHandler(FileDeleted); } internal void Init() { MTFOHotReloadAPI.OnHotReload += ResetToggleInfos; } public bool IsVisibleID(uint id) { if (_idToInfo.TryGetValue(id, out var value)) { return value.ids[0] == id; } return true; } public bool HasRelatedIDs(uint id) { return _idToInfo.ContainsKey(id); } public ToggleInfo GetToggleInfo(uint id) { return _idToInfo.GetValueOrDefault(id); } public bool TryGetToggleInfo(uint id, [MaybeNullWhen(false)] out ToggleInfo toggleInfo) { return _idToInfo.TryGetValue(id, out toggleInfo); } public List GetData() { List list = new List(_fileToData.Values.Sum((List list2) => list2.Count)); IEnumerator enumerator = GetEnumerator(); while (enumerator.MoveNext()) { list.Add(enumerator.Current); } return list; } public IEnumerator GetEnumerator() { return new DictListEnumerator(_fileToData); } public void RemoveFromToggleInfos(uint id) { if (_idToInfo.TryGetValue(id, out var value)) { value.ids.Remove(id); if (value.ids.Count == 1) { _idToInfo.Remove(value.ids[0]); } _idToInfo.Remove(id); } } public void ResetToggleInfos() { _idToInfo.Clear(); HashSet hashSet = new HashSet(); IEnumerator enumerator = GetEnumerator(); while (enumerator.MoveNext()) { GearToggleData current = enumerator.Current; if (current.OfflineIDs.Count <= 1) { continue; } List list = new List(current.OfflineIDs.Count); foreach (uint offlineID in current.OfflineIDs) { if (hashSet.Add(offlineID)) { list.Add(offlineID); continue; } DinoLogger.Warning($"Duplicate ID {offlineID} detected in toggle data. Removed from {current.Name}"); } if (list.Count <= 1) { continue; } RemoveInvalidGear(list, current.Name); if (list.Count <= 1) { continue; } ToggleInfo value = new ToggleInfo { ids = list, text = current.ButtonText, reverse = current.ReverseOrder }; foreach (uint item in list) { _idToInfo[item] = value; } } } private void RemoveInvalidGear(List relatedIDs, string name) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GearLockManager.Current.VanillaGearManager == (Object)null) { return; } while (relatedIDs.Count > 1) { foreach (var (value, dictionary) in GearLockManager.Current.GearSlots) { if (!dictionary.ContainsKey(relatedIDs[0])) { continue; } for (int num = relatedIDs.Count - 1; num >= 1; num--) { uint num2 = relatedIDs[num]; if (!dictionary.ContainsKey(num2)) { DinoLogger.Warning($"ID {num2} removed from toggle data {name} since it is not of type {value}"); relatedIDs.RemoveAt(num); } } return; } DinoLogger.Warning($"ID {relatedIDs[0]} removed from toggle data {name} since it does not exist."); relatedIDs.RemoveAt(0); } } } public struct ToggleInfo { public List ids; public LocalizedText[] text; public bool reverse; } } namespace ProgressionGear.Dependencies { internal static class EOSWrapper { public const string GUID = "Inas.ExtraObjectiveSetup"; private static readonly HashSet _targetIDs; private static bool _allow; public static bool HasEOS { get; private set; } static EOSWrapper() { _targetIDs = new HashSet(); _allow = false; HasEOS = ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("Inas.ExtraObjectiveSetup"); } public static void CacheLocks() { if (HasEOS) { CacheLocksEOS(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void CacheLocksEOS() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 _targetIDs.Clear(); ExpeditionDefinition definition = ExpeditionDefinitionManager.Current.GetDefinition(ExpeditionDefinitionManager.Current.CurrentMainLevelLayout); if (definition == null || definition.ExpeditionGears == null) { _allow = false; return; } _allow = (int)definition.ExpeditionGears.Mode == 0; definition.ExpeditionGears.GearIds.ForEach(delegate(uint id) { _targetIDs.Add(id); }); } public static bool IsGearAllowed(uint id) { if (!HasEOS) { return true; } return IsGearAllowedEOS(id); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool IsGearAllowedEOS(uint id) { if (!_allow) { return !_targetIDs.Contains(id); } return _targetIDs.Contains(id); } } internal static class LocalProgressionWrapper { public const string GUID = "Inas.LocalProgression"; public static bool HasLocalProgression { get; private set; } static LocalProgressionWrapper() { HasLocalProgression = ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("Inas.LocalProgression"); } public static ProgressionData GetProgressionDataLP(uint id, eRundownTier tier, int index) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!HasLocalProgression) { return new ProgressionData(); } ExpeditionProgressionData expeditionLP = LocalProgressionManager.Current.GetExpeditionLP(id, tier, index); return new ProgressionData(expeditionLP.ExpeditionKey, expeditionLP.MainCompletionCount, expeditionLP.SecondaryCompletionCount, expeditionLP.ThirdCompletionCount, expeditionLP.AllClearCount, expeditionLP.NoBoosterAllClearCount); } } internal static class MTFOWrapper { public const string PLUGIN_GUID = "com.dak.MTFO"; public static string GameDataPath => MTFOPathAPI.RundownPath; public static string CustomPath => MTFOPathAPI.CustomPath; public static bool HasCustomContent => MTFOPathAPI.HasRundownPath; } internal static class PartialDataWrapper { public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks"; public static readonly bool HasPartialData; public static JsonConverter? PersistentIDConverter { get; private set; } static PartialDataWrapper() { if (!((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value)) { return; } try { PersistentIDConverter = (JsonConverter)Activator.CreateInstance((((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? throw new Exception("Assembly is Missing!")).GetTypes().First((Type t) => t.Name == "PersistentIDConverter") ?? throw new Exception("Unable to Find PersistentIDConverter Class")); HasPartialData = true; } catch (Exception value2) { DinoLogger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}"); } } } }