using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using ItemSpawnFix.CustomSettings;
using ItemSpawnFix.Dependencies;
using ItemSpawnFix.JSON;
using ItemSpawnFix.JSON.Converters;
using ItemSpawnFix.Patches;
using ItemSpawnFix.Redistribute;
using ItemSpawnFix.Utils;
using LevelGeneration;
using MTFO.API;
using Microsoft.CodeAnalysis;
using SNetwork;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ItemSpawnFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+939a38ea5571eb3e4e6c7cfbabbb6052d61225a4")]
[assembly: AssemblyProduct("ItemSpawnFix")]
[assembly: AssemblyTitle("ItemSpawnFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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]
[Microsoft.CodeAnalysis.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 ItemSpawnFix
{
internal static class Configuration
{
private static readonly ConfigEntry<bool> _showDebugMessages;
private static readonly ConfigFile configFile;
public static bool ShowDebugMessages => _showDebugMessages.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, "ItemSpawnFix.cfg"), true);
string text = "Debug Settings";
_showDebugMessages = configFile.Bind<bool>(text, "Enable Logs", false, "Prints information to the logs when redistributing resources.");
}
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, "ItemSpawnFix.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged);
}
private static void OnFileChanged(LiveEditEventArgs _)
{
configFile.Reload();
}
}
internal static class DinoLogger
{
private static ManualLogSource logger = Logger.CreateLogSource("ItemSpawnFix");
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.ItemSpawnFix", "ItemSpawnFix", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal sealed class EntryPoint : BasePlugin
{
public const string MODNAME = "ItemSpawnFix";
public override void Load()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
SettingsManager.Init();
Configuration.Init();
RedistributeUtils.Init();
LG_DistributionPatches.Init();
LG_PopulatePatches.Init();
new Harmony("ItemSpawnFix").PatchAll();
((BasePlugin)this).Log.LogMessage((object)"Loaded ItemSpawnFix");
}
}
}
namespace ItemSpawnFix.Utils
{
internal class DictListEnumerator<T> : IEnumerator<T>, IEnumerator, IDisposable
{
private readonly IEnumerator<List<T>> _valueEnumerator;
private List<T>? _curList;
private int _index;
private T? _current;
public T Current => _current;
object IEnumerator.Current => Current;
internal DictListEnumerator(Dictionary<string, List<T>> 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 StringExtensions
{
public static T ToEnum<T>(this string? value, T defaultValue) where T : struct
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
if (!Enum.TryParse<T>(value.Replace(" ", null), ignoreCase: true, out var result))
{
return defaultValue;
}
return result;
}
}
}
namespace ItemSpawnFix.Redistribute
{
[HarmonyPatch(typeof(LG_ResourceContainer_Storage))]
public static class RedistributeUtils
{
private static readonly List<(LG_ResourceContainer_Storage storage, StorageTracker slots)> _storages = new List<(LG_ResourceContainer_Storage, StorageTracker)>();
private static readonly List<(LG_ResourceContainer_Storage storage, StorageTracker slots)> _storagesEmpty = new List<(LG_ResourceContainer_Storage, StorageTracker)>();
private static readonly Dictionary<IntPtr, List<(LG_ResourceContainer_Storage storage, StorageTracker slots)>> _nodeStorages = new Dictionary<IntPtr, List<(LG_ResourceContainer_Storage, StorageTracker)>>();
private static readonly Dictionary<IntPtr, List<(LG_ResourceContainer_Storage storage, StorageTracker slots)>> _nodeStoragesEmpty = new Dictionary<IntPtr, List<(LG_ResourceContainer_Storage, StorageTracker)>>();
private static StorageTracker? _currentTracker;
public static Random Random { get; private set; } = new Random();
public static ExpeditionFunction DistributeFunction { get; set; } = (ExpeditionFunction)0;
public static void Init()
{
LevelAPI.OnBuildStart += OnBuildStart;
}
private static void OnBuildStart()
{
SetSeed(Builder.BuildSeedRandom.Seed);
_storages.Clear();
_storagesEmpty.Clear();
_nodeStorages.Clear();
_nodeStoragesEmpty.Clear();
}
internal static void OnZoneFinished()
{
foreach (var item in _storagesEmpty)
{
SNet.DestroySelfManagedReplicatedObject(((Component)((Component)item.storage).transform.parent).gameObject);
}
_storages.Clear();
_storagesEmpty.Clear();
_nodeStorages.Clear();
_nodeStoragesEmpty.Clear();
}
internal static void OnContainerStorageSpawned(LG_ResourceContainer_Storage storage)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)DistributeFunction != 10)
{
return;
}
(LG_ResourceContainer_Storage, StorageTracker) item = (storage, _currentTracker = new StorageTracker(storage));
_storages.Add(item);
_storagesEmpty.Add(item);
AIG_CourseNode spawnNode = storage.m_core.SpawnNode;
if (spawnNode != null)
{
List<(LG_ResourceContainer_Storage, StorageTracker)> list;
if (!_nodeStorages.TryGetValue(((Il2CppObjectBase)spawnNode).Pointer, out List<(LG_ResourceContainer_Storage, StorageTracker)> value))
{
_nodeStorages.Add(((Il2CppObjectBase)spawnNode).Pointer, value = new List<(LG_ResourceContainer_Storage, StorageTracker)>());
_nodeStoragesEmpty.Add(((Il2CppObjectBase)spawnNode).Pointer, list = new List<(LG_ResourceContainer_Storage, StorageTracker)>());
}
else
{
list = _nodeStoragesEmpty[((Il2CppObjectBase)spawnNode).Pointer];
}
value.Add(item);
list.Add(item);
}
}
internal static void OnContainerItemSpawned(LG_ResourceContainer_Storage storage, Transform align)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)DistributeFunction != 10 || _currentTracker == null)
{
return;
}
if (_currentTracker.Unused)
{
_storagesEmpty.RemoveAt(_storagesEmpty.Count - 1);
AIG_CourseNode spawnNode = storage.m_core.SpawnNode;
if (spawnNode != null && _nodeStoragesEmpty.TryGetValue(((Il2CppObjectBase)spawnNode).Pointer, out List<(LG_ResourceContainer_Storage, StorageTracker)> value))
{
value.RemoveAt(value.Count - 1);
}
}
if (!_currentTracker.RemoveAndCheckSpace(align))
{
_storages.RemoveAt(_storages.Count - 1);
AIG_CourseNode spawnNode2 = storage.m_core.SpawnNode;
if (spawnNode2 != null && _nodeStorages.TryGetValue(((Il2CppObjectBase)spawnNode2).Pointer, out List<(LG_ResourceContainer_Storage, StorageTracker)> value2))
{
value2.RemoveAt(value2.Count - 1);
}
}
}
public static void SetSeed(int seed)
{
Random = new Random(seed);
}
public static bool TryRedistributeItems(AIG_CourseNode node, List<ResourceContainerSpawnData> items, out List<ResourceContainerSpawnData> remainingItems, bool empty)
{
remainingItems = new List<ResourceContainerSpawnData>();
if (items.Count == 0)
{
return true;
}
remainingItems.EnsureCapacity(items.Count);
Enumerator<ResourceContainerSpawnData> enumerator = items.GetEnumerator();
while (enumerator.MoveNext())
{
ResourceContainerSpawnData current = enumerator.Current;
remainingItems.Add(current);
}
if (_storages.Count == 0)
{
return false;
}
if (empty)
{
if (_nodeStoragesEmpty.TryGetValue(((Il2CppObjectBase)node).Pointer, out List<(LG_ResourceContainer_Storage, StorageTracker)> value))
{
TryRedistributeToList(remainingItems, value, _nodeStorages[((Il2CppObjectBase)node).Pointer]);
}
TryRedistributeToList(remainingItems, _storagesEmpty, _storages);
}
else
{
if (_nodeStorages.TryGetValue(((Il2CppObjectBase)node).Pointer, out List<(LG_ResourceContainer_Storage, StorageTracker)> value2))
{
TryRedistributeToList(remainingItems, value2);
}
TryRedistributeToList(remainingItems, _storages);
}
return remainingItems.Count == 0;
}
private static bool TryRedistributeToList(List<ResourceContainerSpawnData> items, List<(LG_ResourceContainer_Storage, StorageTracker)> storages, List<(LG_ResourceContainer_Storage, StorageTracker)>? parent = null)
{
if (storages.Count == 0)
{
return false;
}
StorageTracker currentTracker = _currentTracker;
_currentTracker = null;
int[] array = Enumerable.Range(0, storages.Count).ToArray();
Shuffle(array);
List<int> list = new List<int>();
for (int i = 0; i < array.Length; i++)
{
if (items.Count <= 0)
{
break;
}
var (storage, storageTracker) = storages[array[i]];
while (storageTracker.Count > 0 && items.Count > 0)
{
if (!storageTracker.RemoveRandomAndCheckSpace(out StorageSlot slot))
{
if (parent != null)
{
int index = parent.FindIndex(((LG_ResourceContainer_Storage, StorageTracker) pair) => ((Il2CppObjectBase)pair.Item1).Pointer == ((Il2CppObjectBase)storage).Pointer);
parent.RemoveAt(index);
}
list.Add(array[i]);
}
else if (parent != null)
{
list.Add(array[i]);
}
SpawnItem(storage, slot, items[items.Count - 1]);
items.RemoveAt(items.Count - 1);
}
}
list.Sort((int a, int b) => b.CompareTo(a));
foreach (int item in list)
{
storages.RemoveAt(item);
}
_currentTracker = currentTracker;
return items.Count > 0;
}
private static void Shuffle<T>(T[] array)
{
int num = array.Length;
while (num > 1)
{
int num2 = Random.Next(0, num--);
int num3 = num2;
int num4 = num;
T val = array[num];
T val2 = array[num2];
array[num3] = val;
array[num4] = val2;
}
}
private static void SpawnItem(LG_ResourceContainer_Storage storage, StorageSlot storageSlot, ResourceContainerSpawnData data)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected I4, but got Unknown
int num = Random.Next();
eResourceContainerSpawnType type = data.m_type;
switch ((int)type)
{
case 0:
case 1:
case 2:
case 9:
if ((Object)(object)storageSlot.ResourcePack != (Object)null)
{
storage.SpawnResourcePack(data, storageSlot.ResourcePack, num);
}
break;
case 3:
if ((Object)(object)storageSlot.CommoditySmall != (Object)null)
{
storage.SpawnCommodity(data, storageSlot.CommoditySmall, num);
}
break;
case 4:
if ((Object)(object)storageSlot.CommodityMedium != (Object)null)
{
storage.SpawnCommodity(data, storageSlot.CommodityMedium, num);
}
break;
case 5:
if ((Object)(object)storageSlot.CommodityLarge != (Object)null)
{
storage.SpawnCommodity(data, storageSlot.CommodityLarge, num);
}
break;
case 6:
if ((Object)(object)storageSlot.Consumable != (Object)null)
{
storage.SpawnConsumable(data, storageSlot.Consumable, num);
}
break;
case 7:
if ((Object)(object)storageSlot.Keycard != (Object)null)
{
storage.PlaceKeyCard(data, storageSlot.Keycard, num);
}
break;
case 8:
if ((Object)(object)storageSlot.Keycard != (Object)null)
{
storage.PlaceSmallGenericPickup(data, storageSlot.Keycard, num);
}
break;
case 10:
if ((Object)(object)storageSlot.Keycard != (Object)null)
{
storage.SpawnArtifact(data, storageSlot.Keycard, num);
}
break;
}
}
public static string GetPackListString(List<ResourceContainerSpawnData> packs)
{
//IL_0031: 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)
StringBuilder stringBuilder = new StringBuilder("[");
for (int i = 0; i < packs.Count - 1; i++)
{
StringBuilder stringBuilder2 = stringBuilder;
StringBuilder stringBuilder3 = stringBuilder2;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 2, stringBuilder2);
handler.AppendLiteral("(");
handler.AppendFormatted<eResourceContainerSpawnType>(packs[i].m_type);
handler.AppendLiteral(":");
handler.AppendFormatted(packs[i].m_ammo);
handler.AppendLiteral("),");
stringBuilder3.Append(ref handler);
}
if (packs.Count > 0)
{
StringBuilder stringBuilder2 = stringBuilder;
StringBuilder stringBuilder4 = stringBuilder2;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2);
handler.AppendLiteral("(");
handler.AppendFormatted<eResourceContainerSpawnType>(packs[packs.Count - 1].m_type);
handler.AppendLiteral(":");
handler.AppendFormatted(packs[packs.Count - 1].m_ammo);
handler.AppendLiteral(")");
stringBuilder4.Append(ref handler);
}
stringBuilder.Append(']');
return stringBuilder.ToString();
}
public static string GetPackListString(List<ResourceContainerSpawnData> packs)
{
//IL_0031: 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)
StringBuilder stringBuilder = new StringBuilder("[");
for (int i = 0; i < packs.Count - 1; i++)
{
StringBuilder stringBuilder2 = stringBuilder;
StringBuilder stringBuilder3 = stringBuilder2;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 2, stringBuilder2);
handler.AppendLiteral("(");
handler.AppendFormatted<eResourceContainerSpawnType>(packs[i].m_type);
handler.AppendLiteral(":");
handler.AppendFormatted(packs[i].m_ammo);
handler.AppendLiteral("),");
stringBuilder3.Append(ref handler);
}
if (packs.Count > 0)
{
StringBuilder stringBuilder2 = stringBuilder;
StringBuilder stringBuilder4 = stringBuilder2;
StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2);
handler.AppendLiteral("(");
handler.AppendFormatted<eResourceContainerSpawnType>(packs[packs.Count - 1].m_type);
handler.AppendLiteral(":");
handler.AppendFormatted(packs[packs.Count - 1].m_ammo);
handler.AppendLiteral(")");
stringBuilder4.Append(ref handler);
}
stringBuilder.Append(']');
return stringBuilder.ToString();
}
}
public class StorageTracker
{
private readonly List<(StorageSlot slot, HashSet<IntPtr> alignSet)> _slotAligns;
private readonly int _maxCount;
public bool Unused => _slotAligns.Count == _maxCount;
public int Count => _slotAligns.Count;
public StorageTracker(LG_ResourceContainer_Storage storage)
{
_slotAligns = new List<(StorageSlot, HashSet<IntPtr>)>();
foreach (StorageSlot item in (Il2CppArrayBase<StorageSlot>)(object)storage.m_storageSlots)
{
HashSet<IntPtr> hashSet = new HashSet<IntPtr>();
_slotAligns.Add((item, hashSet));
TryAddAlign(item.ResourcePack, hashSet);
TryAddAlign(item.CommoditySmall, hashSet);
TryAddAlign(item.CommodityMedium, hashSet);
TryAddAlign(item.CommodityLarge, hashSet);
TryAddAlign(item.Consumable, hashSet);
TryAddAlign(item.Keycard, hashSet);
}
_maxCount = _slotAligns.Count;
}
private void TryAddAlign(Transform align, HashSet<IntPtr> alignSet)
{
if ((Object)(object)align != (Object)null)
{
alignSet.Add(((Il2CppObjectBase)align).Pointer);
}
}
public bool RemoveRandomAndCheckSpace(out StorageSlot slot)
{
int index = RedistributeUtils.Random.Next(0, Count);
slot = _slotAligns[index].slot;
_slotAligns.RemoveAt(index);
return Count > 0;
}
public bool RemoveAndCheckSpace(Transform align)
{
Transform align2 = align;
(StorageSlot, HashSet<IntPtr>) item = _slotAligns.First<(StorageSlot, HashSet<IntPtr>)>(((StorageSlot slot, HashSet<IntPtr> alignSet) pair) => pair.alignSet.Contains(((Il2CppObjectBase)align2).Pointer));
_slotAligns.Remove(item);
return Count > 0;
}
}
}
namespace ItemSpawnFix.Patches
{
[HarmonyPatch]
internal static class LG_DistributionPatches
{
private unsafe delegate void d_Enqueue(IntPtr _this, IntPtr item, Il2CppMethodInfo* methodInfo);
private static bool _inDistribute;
private static INativeDetour? GetDistributionDetour;
private static d_Enqueue? orig_Enqueue;
[HarmonyPatch(typeof(LG_DistributeResourceContainer), "ShouldBeRemoved")]
[HarmonyPostfix]
private static void Post_ShouldBeRemoved(ref bool __result)
{
__result = false;
}
[HarmonyPatch(typeof(LG_Distribute_ResourcePacksPerZone), "Build")]
[HarmonyPrefix]
private static void Pre_Build()
{
_inDistribute = true;
}
[HarmonyPatch(typeof(LG_Distribute_ResourcePacksPerZone), "Build")]
[HarmonyPostfix]
private static void Post_Build()
{
_inDistribute = false;
}
public unsafe static void Init()
{
INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)Il2CppClassPointerStore<DistributeItemQueueWrapper<LG_DistributeResourceContainer>>.NativeClassPtr);
for (int i = 0; i < val.MethodCount; i++)
{
INativeMethodInfoStruct val2 = UnityVersionHandler.Wrap(val.Methods[i]);
if (Marshal.PtrToStringAnsi(val2.Name) == "Enqueue")
{
GetDistributionDetour = INativeDetour.CreateAndApply<d_Enqueue>(val2.MethodPointer, (d_Enqueue)EnqueuePatch, ref orig_Enqueue);
break;
}
}
}
private unsafe static void EnqueuePatch(IntPtr _this, IntPtr item, Il2CppMethodInfo* methodInfo)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
orig_Enqueue(_this, item, methodInfo);
if (_inDistribute)
{
LG_DistributeItem val = new LG_DistributeItem(item);
val.m_assignedNode.FunctionDistributionPerAreaLookup[val.m_function].Add(val);
if (Configuration.ShowDebugMessages)
{
DinoLogger.Log($"New distribution created for {((Object)val.m_assignedNode.m_zone.NavInfo).ToString()} {((Object)val.m_assignedNode.m_area.m_navInfo).ToString()} of type {val.m_function} added to lookup");
}
}
}
}
[HarmonyPatch(typeof(LG_PopulateFunctionMarkersInZoneJob))]
internal static class LG_PopulatePatches
{
private unsafe delegate void d_BuildFunc(IntPtr _this, IntPtr builder, IntPtr distItem, out IntPtr deepestSpawner, bool debug, Il2CppMethodInfo* methodInfo);
private static readonly List<AIG_CourseNode> _validNodes = new List<AIG_CourseNode>();
private static int _currZoneID = -1;
private static INativeDetour? TriggerFunctionBuilderDetour;
private static d_BuildFunc? orig_TriggerFunctionBuilder;
[HarmonyPatch("Build")]
[HarmonyPostfix]
private static void PostBuild(bool __result)
{
if (__result)
{
RedistributeUtils.OnZoneFinished();
}
}
[HarmonyPatch("BuildBothFunctionAndPropMarkerAndRemoveSurplus")]
[HarmonyWrapSafe]
[HarmonyPriority(200)]
[HarmonyPrefix]
private static bool OverrideFallbackLogic(LG_PopulateFunctionMarkersInZoneJob __instance, LG_FunctionMarkerBuilder builder, LG_DistributeItem distItem)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected I4, but got Unknown
if (!__instance.m_fallbackMode)
{
return true;
}
ExpeditionFunction function = distItem.m_function;
switch (function - 8)
{
default:
return true;
case 0:
case 2:
case 4:
{
LG_MarkerSpawner val = default(LG_MarkerSpawner);
__instance.TriggerFunctionBuilder(builder, distItem, ref val, false);
return false;
}
}
}
[HarmonyPatch("Build")]
[HarmonyWrapSafe]
[HarmonyPriority(200)]
[HarmonyPrefix]
private static bool OverrideBuildOrder(LG_PopulateFunctionMarkersInZoneJob __instance, ref bool __result)
{
if (!SettingsManager.ActiveSettings.RaiseObjectSpawnPriority)
{
return true;
}
__result = false;
if (!__instance.BuildGenericFunctionItems((eDistributionQueue)1))
{
return false;
}
if (!__instance.BuildGateKeyItems())
{
return false;
}
if (!__instance.BuildGenericFunctionItems((eDistributionQueue)0))
{
return false;
}
if (!__instance.BuildPickupItems())
{
return false;
}
if (!__instance.BuildResourceContainers())
{
return false;
}
__result = true;
return false;
}
[HarmonyPatch("BuildGenericFunctionItems")]
[HarmonyWrapSafe]
[HarmonyPriority(200)]
[HarmonyPrefix]
private static bool AllowRedistributeGeneric(LG_PopulateFunctionMarkersInZoneJob __instance, eDistributionQueue queue, ref bool __result)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
if (!SettingsManager.ActiveSettings.AllowRedistributeObjects)
{
return true;
}
DistributeItemQueueWrapper<LG_DistributeItem> val = (((int)queue != 0) ? __instance.m_distributionData.PrioritizedClusterItems : __instance.m_distributionData.GenericFunctionItems);
if (val.Count != 0)
{
LG_DistributeItem val2 = val.m_itemQueue.Dequeue();
__result = false;
LG_FunctionMarkerBuilder val3 = new LG_FunctionMarkerBuilder(val2.m_assignedNode, val2.m_function, val2.m_isWardenObjective, val2.m_wardenObjectiveChainIndex, val2.m_assignedGate, val2.m_localTerminalLogFiles, val2.m_terminalStartStateData, val2.m_terminalPlacementData);
LG_MarkerSpawner val4 = default(LG_MarkerSpawner);
__instance.TriggerFunctionBuilder(val3, val2, ref val4, false);
return false;
}
__result = true;
return false;
}
public unsafe static void Init()
{
TriggerFunctionBuilderDetour = INativeDetour.CreateAndApply<d_BuildFunc>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<LG_PopulateFunctionMarkersInZoneJob>("TriggerFunctionBuilder", typeof(void).Name, false, new string[4]
{
"LG_FunctionMarkerBuilder",
"LG_DistributeItem",
typeof(LG_MarkerSpawner).MakeByRefType().FullName,
typeof(bool).Name
}), (d_BuildFunc)TriggerFunctionBuilderPatch, ref orig_TriggerFunctionBuilder);
LevelAPI.OnBuildStart += delegate
{
_currZoneID = -1;
};
}
private unsafe static void TriggerFunctionBuilderPatch(IntPtr _this, IntPtr builder, IntPtr distItem, out IntPtr deepestSpawner, bool debug, Il2CppMethodInfo* methodInfo)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Invalid comparison between Unknown and I4
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Invalid comparison between Unknown and I4
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Invalid comparison between Unknown and I4
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
LG_PopulateFunctionMarkersInZoneJob val = new LG_PopulateFunctionMarkersInZoneJob(_this);
LG_FunctionMarkerBuilder val2 = new LG_FunctionMarkerBuilder(builder);
LG_DistributeItem val3 = new LG_DistributeItem(distItem);
ExpeditionFunction val4 = (RedistributeUtils.DistributeFunction = val3.m_function);
bool flag = (int)val4 == 10;
LG_DistributeResourceContainer val5 = ((!flag) ? ((LG_DistributeResourceContainer)null) : new LG_DistributeResourceContainer(distItem));
bool flag2 = (flag ? (val5.m_packs.Count == 0) : val3.ShouldBeRemoved());
if (val.m_fallbackMode)
{
if ((int)val4 == 20)
{
if (!flag2)
{
orig_TriggerFunctionBuilder(_this, builder, distItem, out deepestSpawner, debug, methodInfo);
}
else
{
deepestSpawner = IntPtr.Zero;
}
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
return;
}
RedistributeUtils.SetSeed(Builder.BuildSeedRandom.Range(0, int.MaxValue, "NO_TAG"));
AIG_CourseNode assignedNode = val3.m_assignedNode;
string value = ((Object)assignedNode.m_area.m_navInfo).ToString();
string value2 = ((Object)assignedNode.m_zone.NavInfo).ToString();
if (!flag2 && Configuration.ShowDebugMessages)
{
DinoLogger.Log($"Creating {val4} with floor fallback in {value2} {value}");
}
if (flag2)
{
deepestSpawner = IntPtr.Zero;
}
else if (flag && TryRedistributeItems(val3.m_assignedNode, val5, empty: false))
{
deepestSpawner = IntPtr.Zero;
}
else
{
orig_TriggerFunctionBuilder(_this, builder, distItem, out deepestSpawner, debug, methodInfo);
}
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
return;
}
if ((int)val4 != 20)
{
val3.m_allowFunctionFallback = false;
}
orig_TriggerFunctionBuilder(_this, builder, distItem, out deepestSpawner, debug, methodInfo);
if (flag2 || (int)val4 == 20)
{
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
return;
}
if (deepestSpawner == IntPtr.Zero)
{
RedistributeUtils.SetSeed(Builder.BuildSeedRandom.Range(0, int.MaxValue, "NO_TAG"));
AIG_CourseNode node = val3.m_assignedNode;
string value3 = ((Object)node.m_area.m_navInfo).ToString();
LG_Zone zone = node.m_zone;
string text = ((Object)zone.NavInfo).ToString();
if (Configuration.ShowDebugMessages)
{
DinoLogger.Log($"No markers remaining for distribute {val4} in {text} {value3} trying to redistribute");
}
if (flag && TryRedistributeItems(node, val5, empty: true))
{
deepestSpawner = IntPtr.Zero;
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
return;
}
if (_currZoneID != zone.ID)
{
_currZoneID = zone.ID;
_validNodes.Clear();
Enumerator<LG_Area> enumerator = zone.m_areas.GetEnumerator();
while (enumerator.MoveNext())
{
LG_Area current = enumerator.Current;
_validNodes.Add(current.m_courseNode);
}
}
int num = _validNodes.FindLastIndex((AIG_CourseNode n) => n.NodeID == node.NodeID);
if (num >= 0)
{
_validNodes.RemoveAt(num);
}
while (_validNodes.Count > 0)
{
int index = RedistributeUtils.Random.Next(0, _validNodes.Count);
val2.m_node = _validNodes[index];
val3.m_assignedNode = _validNodes[index];
orig_TriggerFunctionBuilder(_this, builder, distItem, out deepestSpawner, debug, methodInfo);
if (deepestSpawner == IntPtr.Zero)
{
_validNodes.RemoveAt(index);
continue;
}
if (Configuration.ShowDebugMessages)
{
DinoLogger.Log($"Redistributed {val4} to {text} {((Object)_validNodes[index].m_area.m_navInfo).ToString()} (orig: {value3})");
}
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
return;
}
if (Configuration.ShowDebugMessages)
{
DinoLogger.Log("No markers available in " + text);
}
if (flag && TryRedistributeItems(node, val5, empty: false))
{
deepestSpawner = IntPtr.Zero;
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
return;
}
val2.m_node = node;
val3.m_assignedNode = node;
if (Configuration.ShowDebugMessages)
{
DinoLogger.Log($"Unable to redistribute {val4} in {text}, moving to floor fallback in {value3}");
}
AddToFallbackQueue(val, val3);
}
RedistributeUtils.DistributeFunction = (ExpeditionFunction)0;
}
private static bool TryRedistributeItems(AIG_CourseNode node, LG_DistributeResourceContainer distRes, bool empty)
{
string text = ((Object)node.m_zone.NavInfo).ToString();
if (RedistributeUtils.TryRedistributeItems(node, distRes.m_packs, out List<ResourceContainerSpawnData> remainingItems, empty))
{
if (empty)
{
DinoLogger.Log("Redistributed " + RedistributeUtils.GetPackListString(distRes.m_packs) + " to empty containers in " + text);
}
else
{
DinoLogger.Log("Redistributed " + RedistributeUtils.GetPackListString(distRes.m_packs) + " to containers in " + text);
}
return true;
}
if (Configuration.ShowDebugMessages)
{
if (empty)
{
DinoLogger.Log("Not enough empty containers in " + text + ", sending remaining items to new container spawns: " + RedistributeUtils.GetPackListString(remainingItems));
}
else
{
DinoLogger.Log("Not enough containers in " + text + ", sending remaining items to floor container spawns: " + RedistributeUtils.GetPackListString(remainingItems));
}
}
distRes.m_packs.Clear();
foreach (ResourceContainerSpawnData item in remainingItems)
{
distRes.m_packs.Add(item);
}
return false;
}
private static void AddToFallbackQueue(LG_PopulateFunctionMarkersInZoneJob job, LG_DistributeItem distItem)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Invalid comparison between Unknown and I4
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Invalid comparison between Unknown and I4
LG_ZoneDistribution distributionDataFallback = job.m_zone.DistributionDataFallback;
if ((int)distItem.m_function == 10)
{
distributionDataFallback.ResourceContainerItems.Enqueue(((Il2CppObjectBase)distItem).Cast<LG_DistributeResourceContainer>());
}
else if ((int)distItem.m_function == 8 || (int)distItem.m_function == 12)
{
distributionDataFallback.PickupItems.Enqueue(((Il2CppObjectBase)distItem).Cast<LG_DistributePickUpItem>());
}
else
{
distributionDataFallback.GenericFunctionItems.Enqueue(distItem);
}
}
}
[HarmonyPatch(typeof(LG_ResourceContainer_Storage))]
internal static class LG_ResourceContainerPatches
{
[HarmonyPatch("Setup")]
[HarmonyPostfix]
private static void Post_Setup(LG_ResourceContainer_Storage __instance)
{
RedistributeUtils.OnContainerStorageSpawned(__instance);
}
[HarmonyPatch("SpawnResourcePack")]
[HarmonyPatch("SpawnCommodity")]
[HarmonyPatch("SpawnConsumable")]
[HarmonyPatch("PlaceKeyCard")]
[HarmonyPatch("PlaceSmallGenericPickup")]
[HarmonyPatch("SpawnArtifact")]
[HarmonyPostfix]
private static void Post_SpawnItem(LG_ResourceContainer_Storage __instance, Transform align)
{
RedistributeUtils.OnContainerItemSpawned(__instance, align);
}
}
}
namespace ItemSpawnFix.JSON
{
public static class ISFJson
{
private static readonly JsonSerializerOptions _setting = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip,
IncludeFields = true,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
IgnoreReadOnlyProperties = true
};
public static T? Deserialize<T>(string json)
{
return JsonSerializer.Deserialize<T>(json, _setting);
}
public static T? Deserialize<T>(ref Utf8JsonReader reader)
{
return JsonSerializer.Deserialize<T>(ref reader, _setting);
}
public static object? Deserialize(Type type, string json)
{
return JsonSerializer.Deserialize(json, type, _setting);
}
public static string Serialize<T>(T value)
{
return JsonSerializer.Serialize(value, _setting);
}
public static void Serialize<T>(Utf8JsonWriter writer, T value)
{
JsonSerializer.Serialize(writer, value, _setting);
}
public static void Serialize<T>(Utf8JsonWriter writer, string name, T value)
{
writer.WritePropertyName(name);
JsonSerializer.Serialize(writer, value, _setting);
}
}
}
namespace ItemSpawnFix.JSON.Converters
{
public sealed class LevelTargetConverter : JsonConverter<LevelTarget>
{
public override LevelTarget? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
LevelTarget levelTarget = new LevelTarget();
if (ParseTarget(ref reader, levelTarget, options))
{
return levelTarget;
}
throw new JsonException("Expected level target to be a tier, tierindex, or level layout ID");
}
private static bool ParseTarget(ref Utf8JsonReader reader, LevelTarget target, 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Invalid comparison between Unknown and I4
if (reader.TokenType == JsonTokenType.Null)
{
return true;
}
if (reader.TokenType == JsonTokenType.String)
{
string @string = reader.GetString();
if (@string.Length >= 5)
{
target.Tier = @string.Substring(0, 5).ToEnum<eRundownTier>((eRundownTier)99);
}
else
{
target.Tier = ("Tier" + @string[0]).ToEnum<eRundownTier>((eRundownTier)99);
}
int num = ((@string.Length < 5) ? 1 : 5);
if ((int)target.Tier != 99 && @string.Length > num)
{
string text = @string;
int num2 = num;
if (int.TryParse(text.Substring(num2, text.Length - num2), out var result))
{
target.TierIndex = result - 1;
}
else
{
target.Tier = (eRundownTier)99;
}
}
if ((int)target.Tier == 99)
{
target.LevelLayoutID = JsonSerializer.Deserialize<uint>(ref reader, options);
}
return true;
}
if (reader.TokenType == JsonTokenType.Number)
{
target.LevelLayoutID = reader.GetUInt32();
return true;
}
return false;
}
public override void Write(Utf8JsonWriter writer, LevelTarget? 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_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (value != null)
{
if (value.LevelLayoutID == 0 && (int)value.Tier == 99)
{
writer.WriteNullValue();
return;
}
if (value.LevelLayoutID != 0)
{
writer.WriteNumberValue(value.LevelLayoutID);
return;
}
eRundownTier tier = value.Tier;
string? text = ((object)(eRundownTier)(ref tier)).ToString();
writer.WriteStringValue(text[text.Length - 1] + ((value.TierIndex >= 0) ? (value.TierIndex + 1).ToString() : ""));
}
}
}
public sealed class SettingsDataConverter : JsonConverter<SettingsData>
{
public override SettingsData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
SettingsData settingsData = new SettingsData();
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Expected Trigger Coordinator to be either a string or object");
}
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return settingsData;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string? @string = reader.GetString();
reader.Read();
switch (@string.ToLowerInvariant())
{
case "levels":
case "level":
if (reader.TokenType == JsonTokenType.StartArray)
{
settingsData.Levels = JsonSerializer.Deserialize<LevelTarget[]>(ref reader, options);
}
else if (reader.TokenType != JsonTokenType.Null)
{
settingsData.Levels = new LevelTarget[1] { JsonSerializer.Deserialize<LevelTarget>(ref reader, options) };
}
break;
case "raiseobjectspawnpriority":
settingsData.RaiseObjectSpawnPriority = reader.GetBoolean();
break;
case "allowredistributeobjects":
settingsData.AllowRedistributeObjects = reader.GetBoolean();
break;
}
}
throw new JsonException("Expected EndObject token");
}
public override void Write(Utf8JsonWriter writer, SettingsData? value, JsonSerializerOptions options)
{
if (value == null)
{
writer.WriteNullValue();
return;
}
writer.WriteStartObject();
writer.WritePropertyName("Levels");
if (value.Levels.Length == 0)
{
writer.WriteNullValue();
}
else if (value.Levels.Length == 1)
{
JsonSerializer.Serialize(writer, value.Levels[0], options);
}
else
{
JsonSerializer.Serialize(writer, value.Levels, options);
}
writer.WriteNumber("RundownID", value.RundownID);
writer.WriteBoolean("RaiseObjectSpawnPriority", value.RaiseObjectSpawnPriority);
writer.WriteBoolean("AllowRedistributeObjects", value.AllowRedistributeObjects);
writer.WriteEndObject();
}
}
}
namespace ItemSpawnFix.Dependencies
{
internal static class MTFOWrapper
{
public const string PLUGIN_GUID = "com.dak.MTFO";
public static readonly bool HasMTFO;
public static string GameDataPath
{
get
{
if (!HasMTFO)
{
return "";
}
return GameDataPath_Unsafe();
}
}
public static string CustomPath
{
get
{
if (!HasMTFO)
{
return "";
}
return CustomPath_Unsafe();
}
}
public static bool HasCustomContent
{
get
{
if (!HasMTFO)
{
return false;
}
return HasCustomContent_Unsafe();
}
}
static MTFOWrapper()
{
HasMTFO = ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.dak.MTFO");
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static string GameDataPath_Unsafe()
{
return MTFOPathAPI.RundownPath;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static string CustomPath_Unsafe()
{
return MTFOPathAPI.CustomPath;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool HasCustomContent_Unsafe()
{
return MTFOPathAPI.HasRundownPath;
}
}
}
namespace ItemSpawnFix.CustomSettings
{
[JsonConverter(typeof(LevelTargetConverter))]
public sealed class LevelTarget
{
public uint LevelLayoutID { get; set; }
public eRundownTier Tier { get; set; } = (eRundownTier)99;
public int TierIndex { get; set; } = -1;
public bool IsMatch(uint layoutID, uint rundownID, eRundownTier tier, int tierIndex)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
if (layoutID == LevelLayoutID)
{
return true;
}
if (Tier == tier && (TierIndex == -1 || TierIndex == tierIndex))
{
return true;
}
return false;
}
}
[JsonConverter(typeof(SettingsDataConverter))]
public sealed class SettingsData
{
public static readonly SettingsData Default = new SettingsData();
public static readonly SettingsData[] Template = new SettingsData[3]
{
new SettingsData
{
Levels = new LevelTarget[1]
{
new LevelTarget
{
LevelLayoutID = 420u
}
}
},
new SettingsData
{
Levels = new LevelTarget[1]
{
new LevelTarget
{
Tier = (eRundownTier)1
}
}
},
new SettingsData
{
Levels = new LevelTarget[2]
{
new LevelTarget
{
LevelLayoutID = 4115u
},
new LevelTarget
{
Tier = (eRundownTier)2,
TierIndex = 0
}
}
}
};
public uint RundownID;
public LevelTarget[] Levels { get; set; } = Array.Empty<LevelTarget>();
public bool RaiseObjectSpawnPriority { get; set; }
public bool AllowRedistributeObjects { get; set; }
}
public sealed class SettingsManager
{
public static readonly SettingsManager Current;
private static (eRundownTier tier, int tierIndex) _currentLevel;
private readonly Dictionary<string, List<SettingsData>> _fileToData = new Dictionary<string, List<SettingsData>>();
private readonly LiveEditListener _liveEditListener;
public static SettingsData ActiveSettings { get; set; }
private void FileChanged(LiveEditEventArgs e)
{
LiveEditEventArgs e2 = e;
DinoLogger.Warning("LiveEdit File Changed: " + e2.FileName);
LiveEdit.TryReadFileContent(e2.FullPath, (Action<string>)delegate(string content)
{
ReadFileContent(e2.FullPath, content);
});
}
private void FileDeleted(LiveEditEventArgs e)
{
DinoLogger.Warning("LiveEdit File Removed: " + e.FileName);
_fileToData.Remove(e.FullPath);
RefreshSettings();
}
private void FileCreated(LiveEditEventArgs e)
{
LiveEditEventArgs e2 = e;
DinoLogger.Warning("LiveEdit File Created: " + e2.FileName);
LiveEdit.TryReadFileContent(e2.FullPath, (Action<string>)delegate(string content)
{
ReadFileContent(e2.FullPath, content);
});
}
private void ReadFileContent(string file, string content)
{
_fileToData.Remove(file);
List<SettingsData> list = null;
try
{
list = ISFJson.Deserialize<List<SettingsData>>(content);
}
catch (JsonException ex)
{
DinoLogger.Error("Error parsing settings json " + file);
DinoLogger.Error(ex.Message);
}
if (list != null)
{
_fileToData[file] = list;
RefreshSettings();
}
}
private static uint ActiveRundownID()
{
string activeRundownKey = RundownManager.ActiveRundownKey;
uint result = default(uint);
if (!RundownManager.RundownProgressionReady || !RundownManager.TryGetIdFromLocalRundownKey(activeRundownKey, ref result))
{
return 0u;
}
return result;
}
private static void RefreshSettings()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Invalid comparison between Unknown and I4
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
SettingsData activeSettings = ActiveSettings;
ActiveSettings = SettingsData.Default;
uint num = ActiveRundownID();
if (num == 0)
{
return;
}
pActiveExpedition activeExpeditionData = RundownManager.GetActiveExpeditionData();
if ((int)activeExpeditionData.tier == 99)
{
return;
}
if (_currentLevel.tier == activeExpeditionData.tier && _currentLevel.tierIndex == activeExpeditionData.expeditionIndex)
{
ActiveSettings = activeSettings;
return;
}
uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData;
IEnumerator<SettingsData> enumerator = Current.GetEnumerator();
while (enumerator.MoveNext())
{
SettingsData current = enumerator.Current;
if (current.RundownID != 0 && current.RundownID != num)
{
continue;
}
LevelTarget[] levels = current.Levels;
for (int i = 0; i < levels.Length; i++)
{
if (levels[i].IsMatch(levelLayoutData, num, activeExpeditionData.tier, activeExpeditionData.expeditionIndex))
{
ActiveSettings = current;
return;
}
}
}
}
private SettingsManager()
{
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Expected O, but got Unknown
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Expected O, but got Unknown
if (!MTFOWrapper.HasCustomContent)
{
DinoLogger.Log($"No custom path detected! Has MTFO? {MTFOWrapper.HasMTFO}");
return;
}
string text = Path.Combine(MTFOWrapper.CustomPath, "ItemSpawnFix");
if (!Directory.Exists(text))
{
DinoLogger.Log("No settings directory detected. Creating template.");
Directory.CreateDirectory(text);
StreamWriter streamWriter = File.CreateText(Path.Combine(text, "Template.json"));
streamWriter.WriteLine(ISFJson.Serialize(SettingsData.Template));
streamWriter.Flush();
streamWriter.Close();
}
else
{
DinoLogger.Log("SettingsData 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);
}
static SettingsManager()
{
ActiveSettings = SettingsData.Default;
_currentLevel = ((eRundownTier)99, 0);
Current = new SettingsManager();
}
internal static void Init()
{
LevelAPI.OnBuildStart += RefreshSettings;
}
public List<SettingsData> GetSettingsData()
{
List<SettingsData> list2 = new List<SettingsData>(_fileToData.Values.Sum((List<SettingsData> list) => list.Count));
IEnumerator<SettingsData> enumerator = GetEnumerator();
while (enumerator.MoveNext())
{
list2.Add(enumerator.Current);
}
return list2;
}
public IEnumerator<SettingsData> GetEnumerator()
{
return new DictListEnumerator<SettingsData>(_fileToData);
}
}
}