Decompiled source of DawnLibExperimental v1.0.0

BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.core.dll

Decompiled 7 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("XuXiaolan,loaforc")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+75bd30d5352a35f1657d9c13965f4155c465bcd3")]
[assembly: AssemblyProduct("DawnLibCore")]
[assembly: AssemblyTitle("DawnLibCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Dawn
{
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.teamxiaolan.dawnlib.core";

		public const string PLUGIN_NAME = "DawnLibCore";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.dll

Decompiled 7 hours ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using Dawn.Interfaces;
using Dawn.Internal;
using Dawn.Utils;
using DunGen;
using DunGen.Graph;
using DunGenPlus;
using EasyTextEffects;
using EasyTextEffects.Effects;
using GameNetcodeStuff;
using GoodItemScan;
using HarmonyLib;
using IL;
using IL.GameNetcodeStuff;
using InjectionLibrary.Attributes;
using LethalConfig.AutoConfig;
using LethalConfig.ConfigItems;
using LethalLevelLoader;
using LethalLib.Modules;
using LethalQuantities.Objects;
using LethalQuantities.Patches;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MrovLib.Events;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using On;
using On.BepInEx.Configuration;
using On.DunGen;
using On.GameNetcodeStuff;
using On.TMPro;
using On.Unity.Netcode;
using PathfindingLib.API.SmartPathfinding;
using Steamworks;
using Steamworks.Data;
using TMPro;
using TerminalFormatter.Nodes;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Pool;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
using UnityEngine.UI;
using UnityEngine.Video;
using WeatherRegistry;
using com.github.teamxiaolan.dawnlib.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RequiresInjections]
[assembly: InternalsVisibleTo("com.github.teamxiaolan.dawnlib.dusk")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("DunGenPlus")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("GoodItemScan")]
[assembly: IgnoresAccessChecksTo("LethalConfig")]
[assembly: IgnoresAccessChecksTo("LethalLevelLoader")]
[assembly: IgnoresAccessChecksTo("LethalLib")]
[assembly: IgnoresAccessChecksTo("LethalQuantities")]
[assembly: IgnoresAccessChecksTo("MMHOOK_Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("MMHOOK_BepInEx")]
[assembly: IgnoresAccessChecksTo("MMHOOK_BepInEx.Preloader")]
[assembly: IgnoresAccessChecksTo("MMHOOK_DunGen")]
[assembly: IgnoresAccessChecksTo("MMHOOK_Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("MMHOOK_Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("MMHOOK_UnityEngine.CoreModule")]
[assembly: IgnoresAccessChecksTo("MrovLib")]
[assembly: IgnoresAccessChecksTo("StarlancerAI")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: IgnoresAccessChecksTo("WeatherRegistry")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("XuXiaolan,loaforc")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A modern API for Lethal Company content and all sizes of mods.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+75bd30d5352a35f1657d9c13965f4155c465bcd3")]
[assembly: AssemblyProduct("DawnLib")]
[assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		private readonly string <Name>k__BackingField;

		public string Name => <Name>k__BackingField;

		public ExtensionMarkerAttribute(string name)
		{
			<Name>k__BackingField = name;
		}
	}
}
public sealed class Vector3Converter : JsonConverter<Vector3>
{
	public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer)
	{
		//IL_0012: 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_0040: Unknown result type (might be due to invalid IL or missing references)
		writer.WriteStartObject();
		writer.WritePropertyName("x");
		writer.WriteValue(value.x);
		writer.WritePropertyName("y");
		writer.WriteValue(value.y);
		writer.WritePropertyName("z");
		writer.WriteValue(value.z);
		writer.WriteEndObject();
	}

	public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Invalid comparison between Unknown and I4
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Invalid comparison between Unknown and I4
		float num = 0f;
		float num2 = 0f;
		float num3 = 0f;
		if ((int)reader.TokenType != 1)
		{
			throw new JsonSerializationException("Expected StartObject for Vector3");
		}
		while (reader.Read() && (int)reader.TokenType != 13)
		{
			if ((int)reader.TokenType == 4)
			{
				string text = (string)reader.Value;
				reader.Read();
				switch (text)
				{
				case "x":
					num = Convert.ToSingle(reader.Value);
					break;
				case "y":
					num2 = Convert.ToSingle(reader.Value);
					break;
				case "z":
					num3 = Convert.ToSingle(reader.Value);
					break;
				}
			}
		}
		return new Vector3(num, num2, num3);
	}
}
public class DawnDeadBodyNamespacedKeyContainer : MonoBehaviour
{
	[field: SerializeField]
	public NamespacedKey Value { get; internal set; }

	public DawnDeadBodyInfo GetDawnDeadBodynfo()
	{
		return LethalContent.DeadBodies[Value.AsTyped<DawnDeadBodyInfo>()];
	}
}
public class DawnMapObjectNamespacedKeyContainer : MonoBehaviour
{
	[field: SerializeField]
	public NamespacedKey Value { get; internal set; }

	public DawnMapObjectInfo GetDawnMapObjectInfo()
	{
		return LethalContent.MapObjects[Value.AsTyped<DawnMapObjectInfo>()];
	}
}
public class DawnStoryLogNamespacedKeyContainer : MonoBehaviour
{
	[field: SerializeField]
	public NamespacedKey Value { get; internal set; }
}
namespace Dawn
{
	public abstract class BaseInfoBuilder
	{
		internal abstract void SoloAddTags(IEnumerable<NamespacedKey> newTags);
	}
	public abstract class BaseInfoBuilder<TInfo, T, TBuilder> : BaseInfoBuilder where TInfo : INamespaced<TInfo> where TBuilder : BaseInfoBuilder<TInfo, T, TBuilder>
	{
		protected HashSet<NamespacedKey> tags = new HashSet<NamespacedKey>();

		protected IDataContainer? customData;

		protected NamespacedKey<TInfo> key { get; private set; }

		protected T value { get; private set; }

		internal BaseInfoBuilder(NamespacedKey<TInfo> key, T value)
		{
			this.key = key;
			this.value = value;
		}

		public TBuilder AddTag(NamespacedKey tag)
		{
			tags.Add(tag);
			return (TBuilder)this;
		}

		public TBuilder AddTags(IEnumerable<NamespacedKey> newTags)
		{
			foreach (NamespacedKey newTag in newTags)
			{
				AddTag(newTag);
			}
			return (TBuilder)this;
		}

		internal override void SoloAddTags(IEnumerable<NamespacedKey> newTags)
		{
			AddTags(newTags);
		}

		public TBuilder SetCustomData(IDataContainer container)
		{
			customData = container ?? throw new ArgumentNullException("container");
			return (TBuilder)this;
		}

		public TBuilder EditCustomData(Action<IDataContainer> callback)
		{
			if (customData == null)
			{
				customData = new DataContainer();
			}
			callback(customData);
			return (TBuilder)this;
		}

		internal abstract TInfo Build();
	}
	[JsonObject(/*Could not decode attribute arguments.*/)]
	public class DataContainer : IDataContainer
	{
		private class NoOpDisposable : IDisposable
		{
			public void Dispose()
			{
			}
		}

		[JsonProperty]
		protected Dictionary<NamespacedKey, object> dictionary = new Dictionary<NamespacedKey, object>();

		public IEnumerable<NamespacedKey> Keys => dictionary.Keys;

		public int Count => dictionary.Count;

		public bool Has(NamespacedKey key)
		{
			return dictionary.ContainsKey(key);
		}

		public bool TryGet<T>(NamespacedKey key, [NotNullWhen(true)] out T? value)
		{
			if (dictionary.TryGetValue(key, out object value2))
			{
				JToken val = (JToken)((value2 is JToken) ? value2 : null);
				if (val != null)
				{
					value = val.ToObject<T>();
					return true;
				}
				if (value2 is T val2)
				{
					value = val2;
					return true;
				}
				if (typeof(T) == typeof(int) && value2 is long num)
				{
					value = (T)(object)(int)num;
					return true;
				}
				if (typeof(T) == typeof(long) && value2 is int num2)
				{
					value = (T)(object)(long)num2;
					return true;
				}
				throw new InvalidCastException($"type of '{key}' is {value2.GetType().Name} which can not be {typeof(T).Name}");
			}
			value = default(T);
			return false;
		}

		public T GetOrSetDefault<T>(NamespacedKey key, T defaultValue)
		{
			if (TryGet<T>(key, out T value))
			{
				return value;
			}
			Set(key, defaultValue);
			return defaultValue;
		}

		public T GetOrCreateDefault<T>(NamespacedKey key) where T : new()
		{
			if (TryGet<T>(key, out T value))
			{
				return value;
			}
			value = new T();
			Set(key, value);
			return value;
		}

		public virtual void Set<T>(NamespacedKey key, T value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			dictionary[key] = value;
		}

		public virtual void Remove(NamespacedKey key)
		{
			dictionary.Remove(key);
		}

		public virtual void Clear()
		{
			dictionary.Clear();
		}

		public virtual void MarkDirty()
		{
		}

		public virtual IDisposable CreateEditContext()
		{
			return new NoOpDisposable();
		}

		public bool Has<T>(NamespacedKey key)
		{
			if (dictionary.ContainsKey(key))
			{
				return dictionary[key] is T;
			}
			return false;
		}
	}
	public class FrozenEmptyDataContainer : IDataContainer
	{
		public static FrozenEmptyDataContainer Instance { get; private set; } = new FrozenEmptyDataContainer();

		public IEnumerable<NamespacedKey> Keys { get; } = Array.Empty<NamespacedKey>();

		public int Count => 0;

		private FrozenEmptyDataContainer()
		{
		}

		public bool TryGet<T>(NamespacedKey key, [NotNullWhen(true)] out T? value)
		{
			value = default(T);
			return false;
		}

		public T GetOrSetDefault<T>(NamespacedKey key, T defaultValue)
		{
			throw new RegistryFrozenException();
		}

		public T GetOrCreateDefault<T>(NamespacedKey key) where T : new()
		{
			throw new RegistryFrozenException();
		}

		public void Set<T>(NamespacedKey key, T value)
		{
			throw new RegistryFrozenException();
		}

		public void Remove(NamespacedKey key)
		{
			throw new RegistryFrozenException();
		}

		public void Clear()
		{
			throw new RegistryFrozenException();
		}

		public void MarkDirty()
		{
			throw new RegistryFrozenException();
		}

		public IDisposable CreateEditContext()
		{
			throw new RegistryFrozenException();
		}

		public bool Has<T>(NamespacedKey key)
		{
			throw new NotImplementedException();
		}
	}
	public interface IDataContainer
	{
		IEnumerable<NamespacedKey> Keys { get; }

		int Count { get; }

		bool Has<T>(NamespacedKey key);

		bool TryGet<T>(NamespacedKey key, [NotNullWhen(true)] out T? value);

		T GetOrSetDefault<T>(NamespacedKey key, T defaultValue);

		T GetOrCreateDefault<T>(NamespacedKey key) where T : new();

		void Set<T>(NamespacedKey key, T value);

		void Remove(NamespacedKey key);

		void Clear();

		void MarkDirty();

		IDisposable CreateEditContext();
	}
	public interface INamespaced
	{
		NamespacedKey Key { get; }
	}
	public interface INamespaced<T> : INamespaced where T : INamespaced<T>
	{
		NamespacedKey<T> TypedKey { get; }
	}
	public class JSONTagDefinition
	{
		public string Tag;

		public string[] Values;
	}
	public class NamespacedKeyConverter : JsonConverter
	{
		public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (value is NamespacedKey namespacedKey)
			{
				writer.WriteValue(namespacedKey.ToString());
			}
			else
			{
				writer.WriteNull();
			}
		}

		public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)reader.TokenType == 11)
			{
				return null;
			}
			string text = reader.Value?.ToString();
			if (text == null)
			{
				return null;
			}
			NamespacedKey namespacedKey = NamespacedKey.ForceParse(text);
			if (objectType == typeof(NamespacedKey))
			{
				return namespacedKey;
			}
			if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(NamespacedKey<>))
			{
				MethodInfo method = typeof(NamespacedKey).GetMethod("AsTyped");
				MethodInfo methodInfo = method.MakeGenericMethod(objectType.GetGenericArguments()[0]);
				return methodInfo.Invoke(namespacedKey, null);
			}
			throw new JsonSerializationException($"Cannot deserialize {objectType}");
		}

		public override bool CanConvert(Type objectType)
		{
			if (objectType == typeof(NamespacedKey))
			{
				return true;
			}
			if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(NamespacedKey<>))
			{
				return true;
			}
			return false;
		}
	}
	public class NamespacedKeyDictionaryConverter : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				return objectType.GetGenericArguments()[0] == typeof(NamespacedKey);
			}
			return false;
		}

		public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			writer.WriteStartObject();
			IDictionary dictionary = (IDictionary)value;
			List<object> list = new List<object>();
			foreach (object key in dictionary.Keys)
			{
				list.Add(key);
			}
			foreach (object item in list)
			{
				NamespacedKey namespacedKey = (NamespacedKey)item;
				object obj = dictionary[item];
				writer.WritePropertyName(namespacedKey.ToString());
				serializer.Serialize(writer, obj);
			}
			writer.WriteEndObject();
		}

		public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			Type type = objectType.GetGenericArguments()[1];
			Type type2 = typeof(Dictionary<, >).MakeGenericType(typeof(NamespacedKey), type);
			IDictionary dictionary = (IDictionary)Activator.CreateInstance(type2);
			JObject val = JObject.Load(reader);
			foreach (JProperty item in val.Properties())
			{
				NamespacedKey key = NamespacedKey.ForceParse(item.Name);
				object value = item.Value.ToObject(type, serializer);
				dictionary[key] = value;
			}
			return dictionary;
		}
	}
	public interface IAdditionalResolvableKeys
	{
		IEnumerable<NamespacedKey> AdditionalResolvableKeys();
	}
	[Serializable]
	public class NamespacedKey : INetworkSerializable
	{
		private static readonly Regex NamespacedKeyRegex = new Regex("[?!.\\n\\t\"`\\[\\]'-]");

		private static readonly Dictionary<char, string> NumberWords = new Dictionary<char, string>
		{
			{ '0', "Zero" },
			{ '1', "One" },
			{ '2', "Two" },
			{ '3', "Three" },
			{ '4', "Four" },
			{ '5', "Five" },
			{ '6', "Six" },
			{ '7', "Seven" },
			{ '8', "Eight" },
			{ '9', "Nine" }
		};

		public const char Separator = ':';

		public const string VanillaNamespace = "lethal_company";

		[SerializeField]
		private string _namespace;

		[SerializeField]
		private string _key;

		public string Namespace => _namespace;

		public string Key => _key;

		public ulong NetworkID => ComputeStableHash64(ToString());

		internal static string NormalizeStringForNamespacedKey(string input, bool CSharpName)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				return string.Empty;
			}
			string text = NamespacedKeyRegex.Replace(input, string.Empty);
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			bool flag = false;
			string text2 = text;
			foreach (char c in text2)
			{
				if (flag || (!char.IsDigit(c) && c != ' '))
				{
					flag = true;
					stringBuilder.Append(c);
				}
			}
			StringBuilder stringBuilder2 = new StringBuilder(stringBuilder.Length);
			string text3 = stringBuilder.ToString();
			foreach (char c2 in text3)
			{
				if (NumberWords.TryGetValue(c2, out string value))
				{
					stringBuilder2.Append(value);
				}
				else
				{
					stringBuilder2.Append(c2);
				}
			}
			string text4 = stringBuilder2.ToString();
			if (CSharpName)
			{
				text4 = text4.Replace(" ", string.Empty);
				text4 = text4.Replace("_", string.Empty);
				return text4.ToCapitalized();
			}
			return text4.ToLowerInvariant().Replace(" ", "_");
		}

		protected NamespacedKey(string @namespace, string key)
		{
			_namespace = NormalizeStringForNamespacedKey(@namespace, CSharpName: false);
			_key = NormalizeStringForNamespacedKey(key, CSharpName: false);
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public NamespacedKey()
		{
		}

		public static NamespacedKey From(string @namespace, string key)
		{
			return new NamespacedKey(@namespace, key);
		}

		public static NamespacedKey Vanilla(string key)
		{
			return From("lethal_company", key);
		}

		public static NamespacedKey Parse(string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				throw new ArgumentException("Input cannot be null or empty.", "input");
			}
			string[] array = input.Split(':');
			if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || string.IsNullOrWhiteSpace(array[1]))
			{
				throw new FormatException($"Invalid namespaced key '{input}'. Expected 'namespace{':'}key'.");
			}
			return From(array[0], array[1]);
		}

		public static bool TryParse(string input, [NotNullWhen(true)] out NamespacedKey? result)
		{
			result = null;
			if (string.IsNullOrWhiteSpace(input))
			{
				return false;
			}
			string[] array = input.Split(':');
			if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || string.IsNullOrWhiteSpace(array[1]))
			{
				return false;
			}
			result = From(array[0], array[1]);
			return true;
		}

		public static NamespacedKey ForceParse(string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				throw new ArgumentException("Input cannot be null or empty.", "input");
			}
			string[] array = input.Split(':');
			if (array.Length == 2)
			{
				return From(array[0], array[1]);
			}
			string input2 = array[0];
			string key = NormalizeStringForNamespacedKey(input2, CSharpName: false);
			return From("lethal_company", key);
		}

		public override string ToString()
		{
			return $"{Namespace}{':'}{Key}";
		}

		public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			serializer.SerializeValue(ref _namespace, false);
			serializer.SerializeValue(ref _key, false);
		}

		public static bool operator ==(NamespacedKey? left, NamespacedKey? right)
		{
			if ((object)left == right)
			{
				return true;
			}
			if ((object)left == null || (object)right == null)
			{
				return false;
			}
			return left.Equals(right);
		}

		public static bool operator !=(NamespacedKey? left, NamespacedKey? right)
		{
			return !(left == right);
		}

		public override bool Equals(object? obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (!(obj is NamespacedKey namespacedKey))
			{
				return false;
			}
			if (Namespace == namespacedKey.Namespace)
			{
				return Key == namespacedKey.Key;
			}
			return false;
		}

		private static ulong ComputeStableHash64(string value)
		{
			ulong num = 14695981039346656037uL;
			byte[] bytes = Encoding.UTF8.GetBytes(value);
			byte[] array = bytes;
			foreach (byte b in array)
			{
				num ^= b;
				num *= 1099511628211L;
			}
			return num;
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(Namespace, Key);
		}

		public NamespacedKey<T> AsTyped<T>() where T : INamespaced
		{
			return NamespacedKey<T>.From(Namespace, Key);
		}

		public bool IsVanilla()
		{
			return Namespace == "lethal_company";
		}

		public bool IsModded()
		{
			return !IsVanilla();
		}
	}
	[Serializable]
	public class NamespacedKey<T> : NamespacedKey where T : INamespaced
	{
		protected NamespacedKey(string @namespace, string key)
			: base(@namespace, key)
		{
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public NamespacedKey()
		{
		}

		public new static NamespacedKey<T> From(string @namespace, string key)
		{
			return new NamespacedKey<T>(@namespace, key);
		}

		public new static NamespacedKey<T> Vanilla(string key)
		{
			return From("lethal_company", key);
		}

		public new static NamespacedKey<T> Parse(string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				throw new ArgumentException("Input cannot be null or empty.", "input");
			}
			string[] array = input.Split(':');
			if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || string.IsNullOrWhiteSpace(array[1]))
			{
				throw new FormatException($"Invalid namespaced key '{input}'. Expected 'namespace{':'}key'.");
			}
			return From(array[0], array[1]);
		}
	}
	public class NamespacedKeyResolver : IDisposable
	{
		public enum MatchType
		{
			ExactKey,
			CompactKey,
			Fuzzy
		}

		private readonly List<NamespacedKey> _keys = new List<NamespacedKey>();

		private readonly Dictionary<string, NamespacedKey> _fullLookup = new Dictionary<string, NamespacedKey>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, List<NamespacedKey>> _keyLookup = new Dictionary<string, List<NamespacedKey>>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, List<NamespacedKey>> _compactKeyLookup = new Dictionary<string, List<NamespacedKey>>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, NamespacedKey?> _cache = new Dictionary<string, NamespacedKey>(StringComparer.OrdinalIgnoreCase);

		private readonly bool _allowFuzzyMatching;

		public NamespacedKeyResolver(IEnumerable<NamespacedKey> keys, bool allowFuzzyMatching = true)
		{
			_allowFuzzyMatching = allowFuzzyMatching;
			foreach (NamespacedKey key in keys)
			{
				AddKey(key);
			}
		}

		public List<NamespacedKey> Resolve(IEnumerable<string> inputs)
		{
			List<NamespacedKey> list = new List<NamespacedKey>();
			foreach (string input in inputs)
			{
				if (TryResolve(input, out NamespacedKey key))
				{
					list.Add(key);
				}
			}
			return list;
		}

		public bool TryResolve(string input, [NotNullWhen(true)] out NamespacedKey? key)
		{
			key = null;
			if (string.IsNullOrWhiteSpace(input))
			{
				return false;
			}
			string text = input.Trim();
			if (_cache.TryGetValue(text, out key))
			{
				return key != null;
			}
			key = ResolveInternal(text);
			_cache[text] = key;
			if (key == null)
			{
				Debuggers.NamespacedKeys?.Log("Could not resolve NamespacedKey input '" + input + "'.");
				return false;
			}
			return true;
		}

		private NamespacedKey? ResolveInternal(string input)
		{
			if (TryResolveFullKey(input, out NamespacedKey key))
			{
				return key;
			}
			string text = NamespacedKey.NormalizeStringForNamespacedKey(input, CSharpName: false);
			string text2 = Compact(text);
			if (_keyLookup.TryGetValue(text, out List<NamespacedKey> value))
			{
				return PickBestMatch(input, value, MatchType.ExactKey);
			}
			if (_compactKeyLookup.TryGetValue(text2, out List<NamespacedKey> value2))
			{
				return PickBestMatch(input, value2, MatchType.CompactKey);
			}
			if (_allowFuzzyMatching)
			{
				return TryResolveFuzzy(input, text, text2);
			}
			return null;
		}

		private bool TryResolveFullKey(string input, out NamespacedKey? key)
		{
			key = null;
			if (!input.Contains(':'))
			{
				return false;
			}
			if (!NamespacedKey.TryParse(input, out NamespacedKey parsed))
			{
				return false;
			}
			if (_fullLookup.TryGetValue(parsed.ToString(), out NamespacedKey value))
			{
				key = value;
				return true;
			}
			if (!_allowFuzzyMatching)
			{
				return false;
			}
			List<NamespacedKey> keys = _keys.Where((NamespacedKey x) => x.Namespace == parsed.Namespace).ToList();
			NamespacedKey bestFuzzyMatch = GetBestFuzzyMatch(parsed.Key, keys);
			if (bestFuzzyMatch == null)
			{
				return false;
			}
			DawnPlugin.Logger.LogError((object)($"Fuzzy NamespacedKey match used. Input '{input}' resolved to '{bestFuzzyMatch}'. \n" + $"This should be changed to the exact key '{bestFuzzyMatch}'."));
			key = bestFuzzyMatch;
			return true;
		}

		private NamespacedKey? TryResolveFuzzy(string rawInput, string normalizedInput, string compactInput)
		{
			NamespacedKey bestFuzzyMatch = GetBestFuzzyMatch(normalizedInput, compactInput, _keys);
			if (bestFuzzyMatch == null)
			{
				return null;
			}
			DawnPlugin.Logger.LogError((object)($"Fuzzy NamespacedKey match used. Input '{rawInput}' resolved to '{bestFuzzyMatch}'.\n" + $"This should be changed to the exact name '{bestFuzzyMatch.Key}' or full key '{bestFuzzyMatch}'."));
			return bestFuzzyMatch;
		}

		private NamespacedKey? GetBestFuzzyMatch(string normalizedInput, List<NamespacedKey> keys)
		{
			return GetBestFuzzyMatch(normalizedInput, Compact(normalizedInput), keys);
		}

		private NamespacedKey? GetBestFuzzyMatch(string normalizedInput, string compactInput, List<NamespacedKey> keys)
		{
			int num = int.MaxValue;
			List<NamespacedKey> list = new List<NamespacedKey>();
			foreach (NamespacedKey key2 in keys)
			{
				string key = key2.Key;
				string b = Compact(key);
				int num2 = Math.Min(LevenshteinDistance(normalizedInput, key), LevenshteinDistance(compactInput, b));
				int maxDistance = GetMaxDistance(normalizedInput, key);
				if (num2 <= maxDistance)
				{
					if (num2 < num)
					{
						num = num2;
						list.Clear();
						list.Add(key2);
					}
					else if (num2 == num)
					{
						list.Add(key2);
					}
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			return PickBestMatch(normalizedInput, list, MatchType.Fuzzy);
		}

		private NamespacedKey PickBestMatch(string input, List<NamespacedKey> matches, MatchType matchType)
		{
			if (matches.Count == 1)
			{
				return matches[0];
			}
			NamespacedKey namespacedKey = matches[0];
			Debuggers.NamespacedKeys?.Log(BuildMultipleMatchWarning(input, namespacedKey, matches, matchType));
			return namespacedKey;
		}

		private void AddKey(NamespacedKey key)
		{
			_keys.Add(key);
			_fullLookup[key.ToString()] = key;
			AddToLookup(_keyLookup, key.Key, key);
			AddToLookup(_compactKeyLookup, Compact(key.Key), key);
		}

		private static void AddToLookup(Dictionary<string, List<NamespacedKey>> lookup, string lookupKey, NamespacedKey key)
		{
			if (!lookup.TryGetValue(lookupKey, out List<NamespacedKey> value))
			{
				value = (lookup[lookupKey] = new List<NamespacedKey>());
			}
			value.Add(key);
		}

		private static string BuildMultipleMatchWarning(string input, NamespacedKey selected, List<NamespacedKey> matches, MatchType matchType)
		{
			return $"NamespacedKey input '{input}' matched multiple keys using {matchType} matching.\n" + string.Format("Using '{0}'. Other matches: {1}", selected, string.Join(", ", matches.Where((NamespacedKey x) => !x.Equals(selected))));
		}

		private static string Compact(string value)
		{
			return value.Replace("_", string.Empty).Replace(" ", string.Empty).Replace("-", string.Empty)
				.ToLowerInvariant();
		}

		private static int GetMaxDistance(string a, string b)
		{
			int num = Math.Max(a.Length, b.Length);
			if (num <= 5)
			{
				return 1;
			}
			if (num <= 12)
			{
				return 2;
			}
			return 3;
		}

		private static int LevenshteinDistance(string a, string b)
		{
			int[,] array = new int[a.Length + 1, b.Length + 1];
			for (int i = 0; i <= a.Length; i++)
			{
				array[i, 0] = i;
			}
			for (int j = 0; j <= b.Length; j++)
			{
				array[0, j] = j;
			}
			for (int k = 1; k <= a.Length; k++)
			{
				for (int l = 1; l <= b.Length; l++)
				{
					int num = ((a[k - 1] != b[l - 1]) ? 1 : 0);
					array[k, l] = Math.Min(Math.Min(array[k - 1, l] + 1, array[k, l - 1] + 1), array[k - 1, l - 1] + num);
				}
			}
			return array[a.Length, b.Length];
		}

		public void Dispose()
		{
			_keys.Clear();
			_fullLookup.Clear();
			_keyLookup.Clear();
			_compactKeyLookup.Clear();
			_cache.Clear();
		}
	}
	public class NamespacedKeyResolver<T> : IDisposable where T : INamespaced
	{
		private readonly NamespacedKeyResolver _resolver;

		public NamespacedKeyResolver(IEnumerable<T> values, bool allowFuzzyMatching = true)
		{
			_resolver = new NamespacedKeyResolver(CollectResolvableKeys(values), allowFuzzyMatching);
		}

		private static IEnumerable<NamespacedKey> CollectResolvableKeys(IEnumerable<T> values)
		{
			HashSet<NamespacedKey> seen = new HashSet<NamespacedKey>();
			foreach (T value in values)
			{
				if (seen.Add(value.Key))
				{
					yield return value.Key;
				}
				if (value is ITaggable taggable)
				{
					foreach (NamespacedKey item in taggable.AllTags())
					{
						if (!(item == null) && seen.Add(item))
						{
							yield return item;
						}
					}
				}
				if (!(value is IAdditionalResolvableKeys additionalResolvableKeys))
				{
					continue;
				}
				foreach (NamespacedKey item2 in additionalResolvableKeys.AdditionalResolvableKeys())
				{
					if (!(item2 == null) && seen.Add(item2))
					{
						yield return item2;
					}
				}
			}
		}

		public List<NamespacedKey<T>> Resolve(IEnumerable<string> inputs)
		{
			List<NamespacedKey<T>> list = new List<NamespacedKey<T>>();
			foreach (string input in inputs)
			{
				if (TryResolve(input, out NamespacedKey<T> key))
				{
					list.Add(key);
				}
			}
			return list;
		}

		public bool TryResolve(string input, [NotNullWhen(true)] out NamespacedKey<T>? key)
		{
			key = null;
			if (!_resolver.TryResolve(input, out NamespacedKey key2))
			{
				return false;
			}
			key = key2.AsTyped<T>();
			return true;
		}

		public void Dispose()
		{
			_resolver.Dispose();
		}
	}
	public static class NamespacedKeyResolverWeightExtensions
	{
		public static List<ResolvedNamespacedWeight<T>> ResolveWeights<T>(this NamespacedKeyResolver<T> resolver, IEnumerable<UnresolvedNamespacedWeight> weights) where T : INamespaced
		{
			List<ResolvedNamespacedWeight<T>> list = new List<ResolvedNamespacedWeight<T>>();
			foreach (UnresolvedNamespacedWeight weight in weights)
			{
				ResolvedNamespacedWeight<T>? resolvedNamespacedWeight = resolver.ResolveWeight(weight);
				if (!resolvedNamespacedWeight.HasValue)
				{
					Debuggers.Weights?.Log("Could not resolve weight key input '" + weight.KeyInput + "'.");
				}
				else
				{
					list.Add(resolvedNamespacedWeight.Value);
				}
			}
			return list;
		}

		public static ResolvedNamespacedWeight<T>? ResolveWeight<T>(this NamespacedKeyResolver<T> resolver, UnresolvedNamespacedWeight weight) where T : INamespaced
		{
			if (!resolver.TryResolve(weight.KeyInput, out NamespacedKey<T> key))
			{
				return null;
			}
			return new ResolvedNamespacedWeight<T>(key, weight.Operation, weight.Value);
		}
	}
	public readonly struct ResolvedNamespacedWeight<T> : IOperationWithValue where T : INamespaced
	{
		public NamespacedKey<T> Key { get; }

		public MathOperation Operation { get; }

		public float Value { get; }

		public ResolvedNamespacedWeight(NamespacedKey<T> key, MathOperation operation, float value)
		{
			Key = key;
			Operation = operation;
			Value = value;
		}
	}
	[Serializable]
	public readonly struct UnresolvedNamespacedWeight : IOperationWithValue
	{
		public string KeyInput { get; }

		public MathOperation Operation { get; }

		public float Value { get; }

		public UnresolvedNamespacedWeight(string keyInput, MathOperation operation, float value)
		{
			KeyInput = keyInput;
			Operation = operation;
			Value = value;
		}

		public override string ToString()
		{
			string arg = Operation switch
			{
				MathOperation.Additive => "+", 
				MathOperation.Subtractive => "-", 
				MathOperation.Multiplicative => "*", 
				MathOperation.Divisive => "/", 
				_ => "+", 
			};
			return $"{KeyInput}={arg}{Value}";
		}

		public static List<UnresolvedNamespacedWeight> ConvertManyFromString(string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				return new List<UnresolvedNamespacedWeight>();
			}
			string[] array = input.Split(',', StringSplitOptions.RemoveEmptyEntries);
			List<UnresolvedNamespacedWeight> list = new List<UnresolvedNamespacedWeight>(array.Length);
			string[] array2 = array;
			foreach (string text in array2)
			{
				list.Add(ConvertFromString(text.Trim()));
			}
			return list;
		}

		public static UnresolvedNamespacedWeight ConvertFromString(string input)
		{
			string[] array = input.Split('=', StringSplitOptions.RemoveEmptyEntries);
			string keyInput = array[0].Trim();
			MathOperation operation = MathOperation.Additive;
			float result = 0f;
			if (array.Length > 1 && !string.IsNullOrWhiteSpace(array[1]))
			{
				string text = array[1].Trim();
				operation = text[0] switch
				{
					'+' => MathOperation.Additive, 
					'-' => MathOperation.Subtractive, 
					'*' => MathOperation.Multiplicative, 
					'/' => MathOperation.Divisive, 
					_ => MathOperation.Additive, 
				};
				if (!float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out result) && (text.Length <= 1 || !float.TryParse(text.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out result)))
				{
					DawnPlugin.Logger.LogWarning((object)("Invalid weight value in config input: " + input));
					result = 0f;
				}
			}
			return new UnresolvedNamespacedWeight(keyInput, operation, Mathf.Abs(result));
		}
	}
	public class PersistentDataContainer : DataContainer
	{
		public class EditContext : IDisposable
		{
			private PersistentDataContainer _container;

			private bool _prevAutoSave;

			public EditContext(PersistentDataContainer container)
			{
				_container = container;
				_prevAutoSave = _container.AutoSave;
				_container.AutoSave = false;
			}

			public void Dispose()
			{
				_container.AutoSave = _prevAutoSave;
				_container.MarkDirty();
			}
		}

		private string _filePath;

		private readonly SemaphoreSlim _saveLock = new SemaphoreSlim(1, 1);

		public bool AutoSave { get; private set; } = true;

		internal static List<PersistentDataContainer> HasCorruptedData { get; private set; } = new List<PersistentDataContainer>();

		public string FileName => Path.GetFileName(_filePath);

		public PersistentDataContainer(string filePath)
		{
			Debuggers.PersistentDataContainer?.Log("new PersistentDataContainer: " + Path.GetFileName(filePath));
			_filePath = filePath;
			if (!File.Exists(filePath))
			{
				return;
			}
			Debuggers.PersistentDataContainer?.Log("loading existing file");
			try
			{
				dictionary = JsonConvert.DeserializeObject<Dictionary<NamespacedKey, object>>(File.ReadAllText(_filePath), DawnLib.JSONSettings);
			}
			catch (Exception arg)
			{
				DawnPlugin.Logger.LogFatal((object)$"Exception when loading from persistent data container ({Path.GetFileName(_filePath)}):\n{arg}");
				HasCorruptedData.Add(this);
				return;
			}
			if (dictionary == null)
			{
				DawnPlugin.Logger.LogFatal((object)("Failure when loading from persistent data container (" + Path.GetFileName(_filePath) + "), file likely corrupted, please delete."));
				HasCorruptedData.Add(this);
				return;
			}
			foreach (object value in dictionary.Values)
			{
				if (value is ChildPersistentDataContainer childPersistentDataContainer)
				{
					Debuggers.PersistentDataContainer?.Log(string.Format("updated parent for a loaded persistent data container. count = {0}: {1}", childPersistentDataContainer.Count, string.Join(", ", childPersistentDataContainer.Keys.Select((NamespacedKey it) => it.ToString()))));
					childPersistentDataContainer.Internal_SetParent(this);
				}
			}
			Debuggers.PersistentDataContainer?.Log($"loaded {dictionary.Count} entries.");
		}

		public override void Set<T>(NamespacedKey key, T value)
		{
			if (value is IDataContainer && !(value is ChildPersistentDataContainer))
			{
				throw new NotSupportedException($"{key} is a {value.GetType().Name}, which is not supported by persistent data container. Only ChildPersistentDataContainer is supported.");
			}
			if (value is ChildPersistentDataContainer childPersistentDataContainer && childPersistentDataContainer.Parent != this)
			{
				throw new NotSupportedException($"{key} is a child persistent data container being added to '{FileName}' when it belongs to '{childPersistentDataContainer.Parent.FileName}'.");
			}
			base.Set(key, value);
			if (AutoSave)
			{
				Task.Run((Func<Task?>)SaveAsync);
			}
		}

		public override void Clear()
		{
			base.Clear();
			if (AutoSave)
			{
				MarkDirty();
			}
		}

		public override void Remove(NamespacedKey key)
		{
			base.Remove(key);
			if (AutoSave)
			{
				MarkDirty();
			}
		}

		[Obsolete("Use CreateEditContext()")]
		public IDisposable LargeEdit()
		{
			return CreateEditContext();
		}

		public override IDisposable CreateEditContext()
		{
			return new EditContext(this);
		}

		public override void MarkDirty()
		{
			Task.Run((Func<Task?>)SaveAsync);
		}

		private async Task SaveAsync()
		{
			Debuggers.PersistentDataContainer?.Log("saving (" + Path.GetFileName(_filePath) + ")");
			await _saveLock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false);
			try
			{
				await using FileStream stream = new FileStream(_filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true);
				await using StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
				string value = JsonConvert.SerializeObject((object)dictionary, DawnLib.JSONSettings);
				await writer.WriteAsync(value).ConfigureAwait(continueOnCapturedContext: false);
				await writer.FlushAsync().ConfigureAwait(continueOnCapturedContext: false);
				await stream.FlushAsync().ConfigureAwait(continueOnCapturedContext: false);
				Debuggers.PersistentDataContainer?.Log("saved (" + Path.GetFileName(_filePath) + ")");
			}
			catch (Exception arg)
			{
				DawnPlugin.Logger.LogError((object)$"Error happened while trying to save PersistentDataContainer ({Path.GetFileName(_filePath)}):\n{arg}");
			}
			finally
			{
				_saveLock.Release();
			}
		}

		internal void DeleteFile()
		{
			File.Delete(_filePath);
		}
	}
	public class ChildPersistentDataContainer : DataContainer
	{
		public PersistentDataContainer Parent { get; private set; }

		internal ChildPersistentDataContainer()
		{
		}

		public ChildPersistentDataContainer(PersistentDataContainer parent)
		{
			Parent = parent;
		}

		public override void MarkDirty()
		{
			if (Parent.AutoSave)
			{
				Parent.MarkDirty();
			}
		}

		public override IDisposable CreateEditContext()
		{
			return Parent.CreateEditContext();
		}

		internal void Internal_SetParent(PersistentDataContainer parent)
		{
			Parent = parent;
		}
	}
	public abstract class DawnBaseInfo<T> : INamespaced<T>, INamespaced, ITaggable, IRegistryEvents where T : DawnBaseInfo<T>
	{
		private HashSet<NamespacedKey> _tags;

		private IDataContainer? _customData;

		public IDataContainer CustomData
		{
			get
			{
				if (_customData == null)
				{
					_customData = new DataContainer();
				}
				return _customData;
			}
		}

		public NamespacedKey Key => TypedKey;

		public NamespacedKey<T> TypedKey { get; }

		protected DawnBaseInfo(NamespacedKey<T> key, HashSet<NamespacedKey> tags, IDataContainer? customData)
		{
			TypedKey = key;
			_tags = tags;
			_customData = customData;
		}

		public bool HasTag(NamespacedKey tag)
		{
			return _tags.Contains(tag);
		}

		public IEnumerable<NamespacedKey> AllTags()
		{
			return _tags;
		}

		internal void Internal_AddTag(NamespacedKey tag)
		{
			Debuggers.Tags?.Log($"Internal_AddTag: {tag} !!!");
			_tags.Add(tag);
		}

		public void OnFrozen()
		{
			if (_customData == null)
			{
				_customData = FrozenEmptyDataContainer.Instance;
			}
		}

		public bool ShouldSkipIgnoreOverride()
		{
			if (!Key.IsVanilla() && !HasTag(DawnLibTags.IsExternal))
			{
				return HasTag(Tags.Unimplemented);
			}
			return true;
		}

		public bool ShouldSkipRespectOverride()
		{
			if (ShouldSkipIgnoreOverride())
			{
				return !HasTag(DawnLibTags.LunarConfig);
			}
			return false;
		}
	}
	public class DawnInfoContainer<T> : MonoBehaviour where T : DawnBaseInfo<T>
	{
		public T Value { get; internal set; }
	}
	public static class DawnLib
	{
		public const string PLUGIN_GUID = "com.github.teamxiaolan.dawnlib";

		internal static readonly JsonSerializerSettings JSONSettings = new JsonSerializerSettings
		{
			ReferenceLoopHandling = (ReferenceLoopHandling)1,
			PreserveReferencesHandling = (PreserveReferencesHandling)0,
			TypeNameHandling = (TypeNameHandling)3,
			Formatting = (Formatting)1,
			Converters = new List<JsonConverter>(3)
			{
				(JsonConverter)(object)new NamespacedKeyConverter(),
				(JsonConverter)(object)new NamespacedKeyDictionaryConverter(),
				(JsonConverter)(object)new Vector3Converter()
			}
		};

		private static PersistentDataContainer? _profileContainer;

		public static DawnWeightSystem Weights { get; } = new DawnWeightSystem();

		public static PersistentDataContainer? GetCurrentSave()
		{
			return NetworkSingleton<DawnNetworker>.Instance?.SaveContainer;
		}

		public static PersistentDataContainer? GetCurrentContract()
		{
			return NetworkSingleton<DawnNetworker>.Instance?.ContractContainer;
		}

		public static PersistentDataContainer GetCurrentInstallSave()
		{
			if (_profileContainer == null)
			{
				_profileContainer = new PersistentDataContainer(Path.Combine(Paths.BepInExRootPath, "DawnLib.dawndata"));
			}
			return _profileContainer;
		}

		public static void RegisterNetworkPrefab(GameObject prefab)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new ArgumentNullException("prefab");
			}
			MiscFixesPatch.networkPrefabsToAdd.Add(prefab);
		}

		public static void RegisterNetworkScene(string scenePath)
		{
			DawnNetworkSceneManager.AddScenePath(scenePath);
		}

		public static void FixMixerGroups(GameObject prefab)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new ArgumentNullException("prefab");
			}
			MiscFixesPatch.soundPrefabsToFix.Add(prefab);
		}

		public static void FixDoorwaySockets(GameObject tilePrefab)
		{
			if (!Object.op_Implicit((Object)(object)tilePrefab))
			{
				throw new ArgumentNullException("tilePrefab");
			}
			MiscFixesPatch.tilesToFixSockets.Add(tilePrefab);
		}

		public static DawnTerminalCommandInfo DefineTerminalCommand(NamespacedKey<DawnTerminalCommandInfo> key, TerminalCommandBasicInformation commandBasicInformation, Action<TerminalCommandInfoBuilder> callback)
		{
			TerminalCommandInfoBuilder terminalCommandInfoBuilder = new TerminalCommandInfoBuilder(key, commandBasicInformation);
			callback(terminalCommandInfoBuilder);
			DawnTerminalCommandInfo dawnTerminalCommandInfo = terminalCommandInfoBuilder.Build();
			LethalContent.TerminalCommands.Register(dawnTerminalCommandInfo);
			return dawnTerminalCommandInfo;
		}

		public static DawnDeadBodyInfo DefineDeadBodyInfo(NamespacedKey<DawnDeadBodyInfo> key, GameObject deadBodyPrefab, Action<DeadBodyInfoBuilder> callback)
		{
			DeadBodyInfoBuilder deadBodyInfoBuilder = new DeadBodyInfoBuilder(key, deadBodyPrefab);
			callback(deadBodyInfoBuilder);
			DawnDeadBodyInfo dawnDeadBodyInfo = deadBodyInfoBuilder.Build();
			DawnStoryLogNamespacedKeyContainer dawnStoryLogNamespacedKeyContainer = deadBodyPrefab.AddComponent<DawnStoryLogNamespacedKeyContainer>();
			dawnStoryLogNamespacedKeyContainer.Value = dawnDeadBodyInfo.Key;
			DeadBodyInfo deadBody = default(DeadBodyInfo);
			if (dawnDeadBodyInfo.DeadBodyPrefab.TryGetComponent<DeadBodyInfo>(ref deadBody))
			{
				DeadBodyInfoExtensions.set_DawnInfo(deadBody, dawnDeadBodyInfo);
			}
			LethalContent.DeadBodies.Register(dawnDeadBodyInfo);
			return dawnDeadBodyInfo;
		}

		public static DawnRoundLoadingStepInfo DefineRoundLoadingStep(NamespacedKey<DawnRoundLoadingStepInfo> key, Func<ILoadingContext, Task> loadingContextCallback, Action<RoundLoadingStepInfoBuilder> callback)
		{
			RoundLoadingStepInfoBuilder roundLoadingStepInfoBuilder = new RoundLoadingStepInfoBuilder(key, loadingContextCallback);
			callback(roundLoadingStepInfoBuilder);
			DawnRoundLoadingStepInfo dawnRoundLoadingStepInfo = roundLoadingStepInfoBuilder.Build();
			LethalContent.RoundLoadingSteps.Register(dawnRoundLoadingStepInfo);
			return dawnRoundLoadingStepInfo;
		}

		public static DawnSurfaceInfo DefineSurface(NamespacedKey<DawnSurfaceInfo> key, FootstepSurface surface, Action<SurfaceInfoBuilder> callback)
		{
			SurfaceInfoBuilder surfaceInfoBuilder = new SurfaceInfoBuilder(key, surface);
			callback(surfaceInfoBuilder);
			DawnSurfaceInfo dawnSurfaceInfo = surfaceInfoBuilder.Build();
			FootstepSurfaceExtensions.set_DawnInfo(surface, dawnSurfaceInfo);
			LethalContent.Surfaces.Register(dawnSurfaceInfo);
			return dawnSurfaceInfo;
		}

		public static DawnStoryLogInfo DefineStoryLog(NamespacedKey<DawnStoryLogInfo> key, GameObject storyLogGameObject, Action<StoryLogInfoBuilder> callback)
		{
			StoryLogInfoBuilder storyLogInfoBuilder = new StoryLogInfoBuilder(key, storyLogGameObject);
			callback(storyLogInfoBuilder);
			DawnStoryLogInfo dawnStoryLogInfo = storyLogInfoBuilder.Build();
			DawnStoryLogNamespacedKeyContainer dawnStoryLogNamespacedKeyContainer = storyLogGameObject.AddComponent<DawnStoryLogNamespacedKeyContainer>();
			dawnStoryLogNamespacedKeyContainer.Value = dawnStoryLogInfo.Key;
			LethalContent.StoryLogs.Register(dawnStoryLogInfo);
			return dawnStoryLogInfo;
		}

		public static DawnDungeonInfo DefineDungeon(NamespacedKey<DawnDungeonInfo> key, string flowName, Action<DungeonFlowInfoBuilder> callback)
		{
			DungeonFlow val = ScriptableObject.CreateInstance<DungeonFlow>();
			((Object)val).name = flowName;
			DungeonFlowInfoBuilder dungeonFlowInfoBuilder = new DungeonFlowInfoBuilder(key, val);
			callback(dungeonFlowInfoBuilder);
			DawnDungeonInfo dawnDungeonInfo = dungeonFlowInfoBuilder.Build();
			DungeonFlowExtensions.set_DawnInfo(val, dawnDungeonInfo);
			LethalContent.Dungeons.Register(dawnDungeonInfo);
			return dawnDungeonInfo;
		}

		public static DawnTileSetInfo DefineTileSet(NamespacedKey<DawnTileSetInfo> key, TileSet tileSet, Action<TilesetInfoBuilder> callback)
		{
			TilesetInfoBuilder tilesetInfoBuilder = new TilesetInfoBuilder(key, tileSet);
			callback(tilesetInfoBuilder);
			DawnTileSetInfo dawnTileSetInfo = tilesetInfoBuilder.Build();
			TileSetExtensions.set_DawnInfo(tileSet, dawnTileSetInfo);
			LethalContent.TileSets.Register(dawnTileSetInfo);
			return dawnTileSetInfo;
		}

		public static DawnMapObjectInfo DefineMapObject(NamespacedKey<DawnMapObjectInfo> key, GameObject mapObject, Action<MapObjectInfoBuilder> callback)
		{
			MapObjectInfoBuilder mapObjectInfoBuilder = new MapObjectInfoBuilder(key, mapObject);
			callback(mapObjectInfoBuilder);
			DawnMapObjectInfo dawnMapObjectInfo = mapObjectInfoBuilder.Build();
			IIndoorMapHazard val = default(IIndoorMapHazard);
			if (!mapObject.TryGetComponent<IIndoorMapHazard>(ref val))
			{
				DawnMapObjectNamespacedKeyContainer dawnMapObjectNamespacedKeyContainer = mapObject.AddComponent<DawnMapObjectNamespacedKeyContainer>();
				dawnMapObjectNamespacedKeyContainer.Value = dawnMapObjectInfo.Key;
			}
			if (dawnMapObjectInfo.InsideInfo != null)
			{
				IndoorMapHazardTypeExtensions.set_DawnInfo(dawnMapObjectInfo.InsideInfo.IndoorMapHazardType, dawnMapObjectInfo);
			}
			if (dawnMapObjectInfo.OutsideInfo != null)
			{
				SpawnableOutsideObjectExtensions.set_DawnInfo(dawnMapObjectInfo.OutsideInfo.SpawnableOutsideObject, dawnMapObjectInfo);
			}
			LethalContent.MapObjects.Register(dawnMapObjectInfo);
			return dawnMapObjectInfo;
		}

		public static DawnUnlockableItemInfo DefineUnlockable(NamespacedKey<DawnUnlockableItemInfo> key, UnlockableItem unlockableItem, Action<UnlockableInfoBuilder> callback)
		{
			UnlockableInfoBuilder unlockableInfoBuilder = new UnlockableInfoBuilder(key, unlockableItem);
			callback(unlockableInfoBuilder);
			DawnUnlockableItemInfo dawnUnlockableItemInfo = unlockableInfoBuilder.Build();
			UnlockableItemExtensions.set_DawnInfo(unlockableItem, dawnUnlockableItemInfo);
			LethalContent.Unlockables.Register(dawnUnlockableItemInfo);
			return dawnUnlockableItemInfo;
		}

		public static DawnItemInfo DefineItem(NamespacedKey<DawnItemInfo> key, Item item, Action<ItemInfoBuilder> callback)
		{
			ItemInfoBuilder itemInfoBuilder = new ItemInfoBuilder(key, item);
			callback(itemInfoBuilder);
			DawnItemInfo dawnItemInfo = itemInfoBuilder.Build();
			ItemExtensions.set_DawnInfo(item, dawnItemInfo);
			LethalContent.Items.Register(dawnItemInfo);
			return dawnItemInfo;
		}

		public static DawnEnemyInfo DefineEnemy(NamespacedKey<DawnEnemyInfo> key, EnemyType enemy, Action<EnemyInfoBuilder> callback)
		{
			EnemyInfoBuilder enemyInfoBuilder = new EnemyInfoBuilder(key, enemy);
			callback(enemyInfoBuilder);
			DawnEnemyInfo dawnEnemyInfo = enemyInfoBuilder.Build();
			EnemyTypeExtensions.set_DawnInfo(enemy, dawnEnemyInfo);
			LethalContent.Enemies.Register(dawnEnemyInfo);
			return dawnEnemyInfo;
		}

		public static DawnMoonInfo DefineMoon(NamespacedKey<DawnMoonInfo> key, SelectableLevel level, Action<MoonInfoBuilder> callback)
		{
			MoonInfoBuilder moonInfoBuilder = new MoonInfoBuilder(key, level);
			callback(moonInfoBuilder);
			DawnMoonInfo dawnMoonInfo = moonInfoBuilder.Build();
			SelectableLevelExtensions.set_DawnInfo(level, dawnMoonInfo);
			LethalContent.Moons.Register(dawnMoonInfo);
			return dawnMoonInfo;
		}

		public static DawnWeatherEffectInfo DefineWeatherEffect(NamespacedKey<DawnWeatherEffectInfo> key, WeatherEffect weather, Action<WeatherEffectInfoBuilder> callback)
		{
			WeatherEffectInfoBuilder weatherEffectInfoBuilder = new WeatherEffectInfoBuilder(key, weather);
			callback(weatherEffectInfoBuilder);
			DawnWeatherEffectInfo dawnWeatherEffectInfo = weatherEffectInfoBuilder.Build();
			WeatherEffectExtensions.set_DawnInfo(weather, dawnWeatherEffectInfo);
			LethalContent.Weathers.Register(dawnWeatherEffectInfo);
			return dawnWeatherEffectInfo;
		}

		public static void ApplyTag(JSONTagDefinition definition)
		{
			NamespacedKey namespacedKey = NamespacedKey.Parse(definition.Tag);
			ListenToRegistry<DawnMoonInfo>(LethalContent.Moons, namespacedKey);
			ListenToRegistry<DawnMapObjectInfo>(LethalContent.MapObjects, namespacedKey);
			ListenToRegistry<DawnEnemyInfo>(LethalContent.Enemies, namespacedKey);
			ListenToRegistry<DawnItemInfo>(LethalContent.Items, namespacedKey);
			ListenToRegistry<DawnWeatherEffectInfo>(LethalContent.Weathers, namespacedKey);
			ListenToRegistry<DawnDungeonInfo>(LethalContent.Dungeons, namespacedKey);
			ListenToRegistry<DawnUnlockableItemInfo>(LethalContent.Unlockables, namespacedKey);
			Debuggers.Tags?.Log($"Scheduled applying tag: {namespacedKey}");
			void ListenToRegistry<T>(TaggedRegistry<T> registry, NamespacedKey tag) where T : notnull, DawnBaseInfo<T>
			{
				registry.OnFreezeWithContext += delegate
				{
					string[] values = definition.Values;
					foreach (string input in values)
					{
						if (registry.TryGetValue(NamespacedKey.Parse(input), out T value))
						{
							value.Internal_AddTag(tag);
						}
					}
				};
			}
		}

		public static void ApplyAllTagsInFolder(string path)
		{
			string[] files = Directory.GetFiles(path, "*.tag.json", SearchOption.AllDirectories);
			foreach (string path2 in files)
			{
				JSONTagDefinition definition = JsonConvert.DeserializeObject<JSONTagDefinition>(File.ReadAllText(path2));
				ApplyTag(definition);
			}
		}
	}
	public class DawnNamespacedKeyContainer<T> : MonoBehaviour where T : NamespacedKey
	{
		public T Value { get; internal set; }
	}
	internal static class DeadBodyRegistrationHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__CollectVanillaDeadBodies;
		}

		internal static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CollectVanillaDeadBodies;
			if (obj == null)
			{
				hook_Awake val = CollectVanillaDeadBodies;
				<>O.<0>__CollectVanillaDeadBodies = val;
				obj = (object)val;
			}
			StartOfRound.Awake += (hook_Awake)obj;
		}

		private static void CollectVanillaDeadBodies(orig_Awake orig, StartOfRound self)
		{
			if (LethalContent.DeadBodies.IsFrozen)
			{
				orig.Invoke(self);
				return;
			}
			DeadBodyInfo deadBody = default(DeadBodyInfo);
			foreach (var item3 in self.playerRagdolls.WithIndex())
			{
				int item = item3.index;
				GameObject item2 = item3.value;
				string text = NamespacedKey.NormalizeStringForNamespacedKey(((Object)item2).name, CSharpName: true);
				NamespacedKey<DawnDeadBodyInfo> namespacedKey = DeadBodyKeys.GetByReflection(text);
				if (namespacedKey == null)
				{
					namespacedKey = NamespacedKey<DawnDeadBodyInfo>.From("unknown_modded", text);
				}
				DawnDeadBodyInfo dawnDeadBodyInfo = new DawnDeadBodyInfo(namespacedKey, new HashSet<NamespacedKey>(), item2, null)
				{
					Index = item
				};
				DawnDeadBodyNamespacedKeyContainer dawnDeadBodyNamespacedKeyContainer = item2.AddComponent<DawnDeadBodyNamespacedKeyContainer>();
				dawnDeadBodyNamespacedKeyContainer.Value = dawnDeadBodyInfo.Key;
				if (item2.TryGetComponent<DeadBodyInfo>(ref deadBody))
				{
					DeadBodyInfoExtensions.set_DawnInfo(deadBody, dawnDeadBodyInfo);
				}
				LethalContent.DeadBodies.Register(dawnDeadBodyInfo);
			}
			foreach (DawnDeadBodyInfo value in LethalContent.DeadBodies.Values)
			{
				if (!value.ShouldSkipIgnoreOverride())
				{
					int count = self.playerRagdolls.Count;
					self.playerRagdolls.Add(value.DeadBodyPrefab);
					value.Index = count;
				}
			}
			LethalContent.DeadBodies.Freeze();
			orig.Invoke(self);
		}
	}
	public sealed class DawnDeadBodyInfo : DawnBaseInfo<DawnDeadBodyInfo>
	{
		public GameObject DeadBodyPrefab { get; }

		public int Index { get; internal set; }

		internal DawnDeadBodyInfo(NamespacedKey<DawnDeadBodyInfo> key, HashSet<NamespacedKey> tags, GameObject deadBodyPrefab, IDataContainer? customData)
			: base(key, tags, customData)
		{
			DeadBodyPrefab = deadBodyPrefab;
		}
	}
	public class DeadBodyInfoBuilder : BaseInfoBuilder<DawnDeadBodyInfo, GameObject, DeadBodyInfoBuilder>
	{
		public DeadBodyInfoBuilder(NamespacedKey<DawnDeadBodyInfo> key, GameObject value)
			: base(key, value)
		{
		}

		internal override DawnDeadBodyInfo Build()
		{
			return new DawnDeadBodyInfo(base.key, tags, base.value, customData);
		}
	}
	public static class DeadBodyInfoExtensions
	{
		[SpecialName]
		public sealed class <G>$A470D541580C35A9FF28AD8B9B478A06
		{
			[SpecialName]
			public static class <M>$CFBEF7FC135F73CAEF4B193506E3AC03
			{
			}

			[ExtensionMarker("<M>$CFBEF7FC135F73CAEF4B193506E3AC03")]
			public DawnDeadBodyInfo DawnInfo
			{
				[ExtensionMarker("<M>$CFBEF7FC135F73CAEF4B193506E3AC03")]
				get
				{
					throw new NotSupportedException();
				}
				[ExtensionMarker("<M>$CFBEF7FC135F73CAEF4B193506E3AC03")]
				set
				{
					throw new NotSupportedException();
				}
			}

			[ExtensionMarker("<M>$CFBEF7FC135F73CAEF4B193506E3AC03")]
			private DawnDeadBodyInfo GetDawnInfoCore()
			{
				throw new NotSupportedException();
			}

			[ExtensionMarker("<M>$CFBEF7FC135F73CAEF4B193506E3AC03")]
			private void SetDawnInfoCore(DawnDeadBodyInfo dawnBodyInfo)
			{
				throw new NotSupportedException();
			}
		}

		public static DawnDeadBodyInfo get_DawnInfo(DeadBodyInfo deadBody)
		{
			return deadBody.GetDawnInfoCore();
		}

		public static void set_DawnInfo(DeadBodyInfo deadBody, DawnDeadBodyInfo value)
		{
			deadBody.SetDawnInfoCore(value);
		}

		private static DawnDeadBodyInfo GetDawnInfoCore(this DeadBodyInfo deadBody)
		{
			return ((IDeadBodyInfoDawnObject)deadBody).DawnInfo;
		}

		private static void SetDawnInfoCore(this DeadBodyInfo deadBody, DawnDeadBodyInfo dawnBodyInfo)
		{
			((IDeadBodyInfoDawnObject)deadBody).DawnInfo = dawnBodyInfo;
		}
	}
	public static class PlayerControllerBExtensions
	{
		[SpecialName]
		public sealed class <G>$45B62F97DAFB2E69FE261FE1356619DD
		{
			[SpecialName]
			public static class <M>$C7EFA495105B6AEA9D4C0BF5D9482B99
			{
			}

			[ExtensionMarker("<M>$C7EFA495105B6AEA9D4C0BF5D9482B99")]
			public void KillPlayer(Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, NamespacedKey deathAnimationKey, Vector3 positionOffset, bool setOverrideDropItems)
			{
				throw new NotSupportedException();
			}
		}

		public static void KillPlayer(this PlayerControllerB playerControllerB, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, NamespacedKey deathAnimationKey, Vector3 positionOffset, bool setOverrideDropItems)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (LethalContent.DeadBodies.TryGetValue(deathAnimationKey, out DawnDeadBodyInfo value))
			{
				playerControllerB.KillPlayer(bodyVelocity, spawnBody, causeOfDeath, value.Index, positionOffset, setOverrideDropItems);
			}
		}

		public static bool TryGetCurrentDawnSurface(this PlayerControllerB player, [NotNullWhen(true)] out DawnSurface? dawnSurface)
		{
			dawnSurface = (DawnSurface)((ICurrentDawnSurface)player).CurrentDawnSurface;
			return (Object)(object)dawnSurface != (Object)null;
		}

		public static void SetCurrentDawnSurface(this PlayerControllerB player, DawnSurface? dawnSurface)
		{
			((ICurrentDawnSurface)player).CurrentDawnSurface = dawnSurface;
		}
	}
	internal static class DungeonRegistrationHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__RegisterDawnDungeons;

			public static Action<Action<RandomMapObject>, RandomMapObject> <1>__FixRandomMapObjects;

			public static hook_SetPlanetsWeather <2>__UpdateAllDungeonWeights;

			public static hook_EndOfGame <3>__UnloadDungeonBundleForAllPlayers;

			public static hook_Awake <4>__DeleteLLLTranspilerAndEnsureDelayedDungeon;

			public static hook_Awake <5>__RemoveHotloadingIfDebugDunGenPlus;

			public static Manipulator <6>__MakeExtraScrapGenerationMoreModular;

			public static hook_TeleportPlayer <7>__HandleStingerAudio;

			public static Manipulator <8>__DelayDungeonGeneration;

			public static Func<IEnumerator> <9>__LoadDungeonBundle;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action<NamespacedKeyResolver<DawnMoonInfo>> <>9__0_0;

			public static Action<NamespacedKeyResolver<DawnMoonInfo>> <>9__0_1;

			public static hook_GenerateNewFloor <>9__0_2;

			public static Action<NamespacedKeyResolver<DawnDungeonInfo>> <>9__0_3;

			public static hook_Start <>9__0_4;

			public static hook_Generate <>9__0_5;

			public static Func<Instruction, bool> <>9__2_0;

			public static Func<Instruction, bool> <>9__2_1;

			public static Func<Instruction, bool> <>9__2_2;

			public static Func<Instruction, bool> <>9__2_3;

			public static Func<Instruction, bool> <>9__2_4;

			public static Func<Instruction, bool> <>9__2_5;

			public static Func<Instruction, bool> <>9__2_6;

			public static Func<Instruction, bool> <>9__2_7;

			public static Func<Instruction, bool> <>9__9_0;

			public static Func<Instruction, bool> <>9__9_1;

			public static Func<Instruction, bool> <>9__9_2;

			public static Func<bool> <>9__11_0;

			public static Func<EntranceTeleport, bool> <>9__12_0;

			public static Func<GlobalPropSettings, bool> <>9__12_1;

			public static Func<IndoorMapType, DungeonFlow> <>9__15_0;

			public static Func<bool> <>9__17_0;

			internal void <Init>b__0_0(NamespacedKeyResolver<DawnMoonInfo> _)
			{
				AddDawnDungeonsToMoons();
			}

			internal void <Init>b__0_1(NamespacedKeyResolver<DawnMoonInfo> _)
			{
				CollectNonDawnDungeons();
			}

			internal void <Init>b__0_2(orig_GenerateNewFloor orig, RoundManager self)
			{
				UpdateDungeonWeightOnLevel(self.currentLevel);
				orig.Invoke(self);
			}

			internal void <Init>b__0_3(NamespacedKeyResolver<DawnDungeonInfo> _)
			{
				CleanDawnDungeonReferences();
			}

			internal void <Init>b__0_4(orig_Start orig, RuntimeDungeon self)
			{
				self.GenerateOnStart = false;
				orig.Invoke(self);
			}

			internal void <Init>b__0_5(orig_Generate orig, RuntimeDungeon self)
			{
				AdjustFireExits(self.Generator.DungeonFlow);
				TryInjectTileSets(self.Generator.DungeonFlow);
				orig.Invoke(self);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_0(Instruction instr)
			{
				return ILPatternMatchingExt.MatchLdarg(instr, 0);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_1(Instruction instr)
			{
				return ILPatternMatchingExt.MatchLdfld<RoundManager>(instr, "currentDungeonType");
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_2(Instruction instr)
			{
				return ILPatternMatchingExt.MatchLdcI4(instr, 4);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_3(Instruction instr)
			{
				ILLabel val = default(ILLabel);
				return ILPatternMatchingExt.MatchBneUn(instr, ref val);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_4(Instruction instr)
			{
				return ILPatternMatchingExt.MatchLdloc(instr, 1);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_5(Instruction instr)
			{
				return ILPatternMatchingExt.MatchLdcI4(instr, 6);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_6(Instruction instr)
			{
				return ILPatternMatchingExt.MatchAdd(instr);
			}

			internal bool <MakeExtraScrapGenerationMoreModular>b__2_7(Instruction instr)
			{
				return ILPatternMatchingExt.MatchStloc(instr, 1);
			}

			internal bool <DelayDungeonGeneration>b__9_0(Instruction i)
			{
				return ILPatternMatchingExt.MatchLdarg(i, 0);
			}

			internal bool <DelayDungeonGeneration>b__9_1(Instruction i)
			{
				return ILPatternMatchingExt.MatchLdfld<RoundManager>(i, "dungeonGenerator");
			}

			internal bool <DelayDungeonGeneration>b__9_2(Instruction i)
			{
				return ILPatternMatchingExt.MatchCallvirt<RuntimeDungeon>(i, "Generate");
			}

			internal bool <LoadDungeonBundle>b__11_0()
			{
				return NetworkSingleton<DawnDungeonNetworker>.Instance.allPlayersDone;
			}

			internal bool <AdjustFireExits>b__12_0(EntranceTeleport e)
			{
				return e.entranceId != 0;
			}

			internal bool <AdjustFireExits>b__12_1(GlobalPropSettings p)
			{
				return p.ID == 1231;
			}

			internal DungeonFlow <AddDawnDungeonsToMoons>b__15_0(IndoorMapType t)
			{
				return t.dungeonFlow;
			}

			internal bool <CollectNonDawnDungeons>b__17_0()
			{
				return true;
			}
		}

		private static bool _alreadyPatched = false;

		private static readonly Dictionary<string, string> _internalToHumanDungeonNames = new Dictionary<string, string>
		{
			{ "LevelOne", "Facility" },
			{ "LevelTwo", "Mansion" },
			{ "LevelThree", "Mineshaft" }
		};

		internal static void Init()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//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)
			//IL_019f: Expected O, but got Unknown
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			DetourContext val = new DetourContext(int.MaxValue);
			try
			{
				object obj = <>O.<0>__RegisterDawnDungeons;
				if (obj == null)
				{
					hook_Awake val2 = RegisterDawnDungeons;
					<>O.<0>__RegisterDawnDungeons = val2;
					obj = (object)val2;
				}
				StartOfRound.Awake += (hook_Awake)obj;
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
			DetourContext val3 = new DetourContext(200);
			try
			{
				DawnPlugin.Hooks.Add(new Hook((MethodBase)AccessTools.DeclaredMethod(typeof(RandomMapObject), "Awake", (Type[])null, (Type[])null), (Delegate)new Action<Action<RandomMapObject>, RandomMapObject>(FixRandomMapObjects)));
			}
			finally
			{
				((IDisposable)val3)?.Dispose();
			}
			LethalContent.Moons.OnFreezeWithContext += delegate
			{
				AddDawnDungeonsToMoons();
			};
			LethalContent.Moons.OnFreezeWithContext += delegate
			{
				CollectNonDawnDungeons();
			};
			object obj2 = <>O.<2>__UpdateAllDungeonWeights;
			if (obj2 == null)
			{
				hook_SetPlanetsWeather val4 = UpdateAllDungeonWeights;
				<>O.<2>__UpdateAllDungeonWeights = val4;
				obj2 = (object)val4;
			}
			StartOfRound.SetPlanetsWeather += (hook_SetPlanetsWeather)obj2;
			object obj3 = <>O.<3>__UnloadDungeonBundleForAllPlayers;
			if (obj3 == null)
			{
				hook_EndOfGame val5 = UnloadDungeonBundleForAllPlayers;
				<>O.<3>__UnloadDungeonBundleForAllPlayers = val5;
				obj3 = (object)val5;
			}
			StartOfRound.EndOfGame += (hook_EndOfGame)obj3;
			object obj4 = <>O.<4>__DeleteLLLTranspilerAndEnsureDelayedDungeon;
			if (obj4 == null)
			{
				hook_Awake val6 = DeleteLLLTranspilerAndEnsureDelayedDungeon;
				<>O.<4>__DeleteLLLTranspilerAndEnsureDelayedDungeon = val6;
				obj4 = (object)val6;
			}
			MenuManager.Awake += (hook_Awake)obj4;
			object obj5 = <>O.<5>__RemoveHotloadingIfDebugDunGenPlus;
			if (obj5 == null)
			{
				hook_Awake val7 = RemoveHotloadingIfDebugDunGenPlus;
				<>O.<5>__RemoveHotloadingIfDebugDunGenPlus = val7;
				obj5 = (object)val7;
			}
			MenuManager.Awake += (hook_Awake)obj5;
			object obj6 = <>O.<6>__MakeExtraScrapGenerationMoreModular;
			if (obj6 == null)
			{
				Manipulator val8 = MakeExtraScrapGenerationMoreModular;
				<>O.<6>__MakeExtraScrapGenerationMoreModular = val8;
				obj6 = (object)val8;
			}
			RoundManager.SpawnScrapInLevel += (Manipulator)obj6;
			object obj7 = <>c.<>9__0_2;
			if (obj7 == null)
			{
				hook_GenerateNewFloor val9 = delegate(orig_GenerateNewFloor orig, RoundManager self)
				{
					UpdateDungeonWeightOnLevel(self.currentLevel);
					orig.Invoke(self);
				};
				<>c.<>9__0_2 = val9;
				obj7 = (object)val9;
			}
			RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj7;
			LethalContent.Dungeons.BeforeFreezeWithContext += delegate
			{
				CleanDawnDungeonReferences();
			};
			object obj8 = <>O.<7>__HandleStingerAudio;
			if (obj8 == null)
			{
				hook_TeleportPlayer val10 = HandleStingerAudio;
				<>O.<7>__HandleStingerAudio = val10;
				obj8 = (object)val10;
			}
			EntranceTeleport.TeleportPlayer += (hook_TeleportPlayer)obj8;
			object obj9 = <>c.<>9__0_4;
			if (obj9 == null)
			{
				hook_Start val11 = delegate(orig_Start orig, RuntimeDungeon self)
				{
					self.GenerateOnStart = false;
					orig.Invoke(self);
				};
				<>c.<>9__0_4 = val11;
				obj9 = (object)val11;
			}
			RuntimeDungeon.Start += (hook_Start)obj9;
			object obj10 = <>c.<>9__0_5;
			if (obj10 == null)
			{
				hook_Generate val12 = delegate(orig_Generate orig, RuntimeDungeon self)
				{
					AdjustFireExits(self.Generator.DungeonFlow);
					TryInjectTileSets(self.Generator.DungeonFlow);
					orig.Invoke(self);
				};
				<>c.<>9__0_5 = val12;
				obj10 = (object)val12;
			}
			RuntimeDungeon.Generate += (hook_Generate)obj10;
		}

		private static void RemoveHotloadingIfDebugDunGenPlus(orig_Awake orig, MenuManager self)
		{
			if ((Object)(object)self.versionNumberText == (Object)null)
			{
				orig.Invoke(self);
				return;
			}
			if (DungeonGenerationPlusCompat.Enabled && DungeonGenerationPlusCompat.IsDebugOn() && !DungeonGenerationPlusCompat.RemovedHotloading)
			{
				DungeonGenerationPlusCompat.RemovedHotloading = true;
				foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values)
				{
					if (!value.ShouldSkipIgnoreOverride())
					{
						AssetBundle val = AssetBundle.LoadFromFile(value.AssetBundlePath);
						DungeonFlow val2 = val.LoadAsset<DungeonFlow>(((Object)value.DungeonFlow).name ?? "");
						if ((Object)(object)val2 == (Object)null)
						{
							DawnPlugin.Logger.LogError((object)("Bundle: " + Path.GetFileName(value.AssetBundlePath) + " does not contain DungeonFlow: " + ((Object)value.DungeonFlow).name + "."));
							return;
						}
						DawnDungeonNetworker.TryApplyLoadedDungeonFlow(val2, val);
					}
				}
			}
			orig.Invoke(self);
		}

		private static void MakeExtraScrapGenerationMoreModular(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			ILLabel val2 = default(ILLabel);
			if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[8]
			{
				(Instruction instr) => ILPatternMatchingExt.MatchLdarg(instr, 0),
				(Instruction instr) => ILPatternMatchingExt.MatchLdfld<RoundManager>(instr, "currentDungeonType"),
				(Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 4),
				(Instruction instr) => ILPatternMatchingExt.MatchBneUn(instr, ref val2),
				(Instruction instr) => ILPatternMatchingExt.MatchLdloc(instr, 1),
				(Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 6),
				(Instruction instr) => ILPatternMatchingExt.MatchAdd(instr),
				(Instruction instr) => ILPatternMatchingExt.MatchStloc(instr, 1)
			}))
			{
				DawnPlugin.Logger.LogWarning((object)"Failed to find IL for RoundManager.SpawnScrapInLevel (MakeExtraScrapGenerationMoreModular).");
				return;
			}
			val.RemoveRange(8);
			val.Emit(OpCodes.Ldloc_1);
			val.Emit(OpCodes.Call, (MethodBase)AccessTools.DeclaredMethod(typeof(DungeonRegistrationHandler), "GetExtraScrapForCurrentlyLoadedInterior", (Type[])null, (Type[])null));
			val.Emit(OpCodes.Add);
			val.Emit(OpCodes.Stloc_1);
		}

		private static int GetExtraScrapForCurrentlyLoadedInterior()
		{
			return RoundManagerRefs.GetCurrentDungeonInfo()?.ExtraScrapGeneration ?? 0;
		}

		private static void HandleStingerAudio(orig_TeleportPlayer orig, EntranceTeleport self)
		{
			if (!self.checkedForFirstTime)
			{
				self.checkedForFirstTime = true;
				if (!self.isEntranceToBuilding)
				{
					orig.Invoke(self);
					return;
				}
				DawnDungeonInfo currentDungeonInfo = RoundManagerRefs.GetCurrentDungeonInfo();
				if (currentDungeonInfo == null || (Object)(object)currentDungeonInfo.StingerDetail.FirstTimeAudio == (Object)null)
				{
					orig.Invoke(self);
					return;
				}
				if (!currentDungeonInfo.StingerDetail.AllowStingerToPlay.Provide())
				{
					orig.Invoke(self);
					return;
				}
				if (!currentDungeonInfo.CustomData.TryGet<bool>(DawnKeys.StingerPlayed, out var value))
				{
					DawnPlugin.Logger.LogError((object)$"Failed to get {DawnKeys.StingerPlayed} from dungeon: {currentDungeonInfo.Key}.");
					orig.Invoke(self);
					return;
				}
				if (value && !currentDungeonInfo.StingerDetail.PlaysMoreThanOnce)
				{
					orig.Invoke(self);
					return;
				}
				float num = Random.Range(0f, 100f);
				if (num > currentDungeonInfo.StingerDetail.PlayChance)
				{
					orig.Invoke(self);
					return;
				}
				Debuggers.Dungeons?.Log($"Playing dungeon stinger for dungeon {currentDungeonInfo.Key}, alreadyPlayed: {value} (Chance Roll: {num} <= {currentDungeonInfo.StingerDetail.PlayChance})");
				currentDungeonInfo.CustomData.Set(DawnKeys.StingerPlayed, value: true);
				((MonoBehaviour)self).StartCoroutine(self.playMusicOnDelay());
			}
			orig.Invoke(self);
		}

		private static void FixRandomMapObjects(Action<RandomMapObject> orig, RandomMapObject self)
		{
			foreach (DawnMapObjectInfo value in LethalContent.MapObjects.Values)
			{
				for (int i = 0; i < self.spawnablePrefabs.Count; i++)
				{
					if (!((Object)(object)self.spawnablePrefabs[i] == (Object)null))
					{
						GameObject mapObjectPrefab = value.GetMapObjectPrefab();
						if (!((Object)(object)mapObjectPrefab == (Object)null) && ((Object)self.spawnablePrefabs[i]).name.Equals(((Object)mapObjectPrefab).name, StringComparison.OrdinalIgnoreCase))
						{
							self.spawnablePrefabs[i] = mapObjectPrefab;
							break;
						}
					}
				}
			}
			orig.Invoke(self);
		}

		private static void DeleteLLLTranspilerAndEnsureDelayedDungeon(orig_Awake orig, MenuManager self)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			orig.Invoke(self);
			if (!_alreadyPatched)
			{
				if (LethalLevelLoaderCompat.Enabled)
				{
					DawnPlugin.Logger.LogDebug((object)"Removing LethalLevelLoader dungeon generation transpiler.");
					LethalLevelLoaderCompat.TryRemoveLLLDungeonTranspiler();
					LethalLevelLoaderCompat.ScrewWithLLLDynamicDungeonRarity();
				}
				object obj = <>O.<8>__DelayDungeonGeneration;
				if (obj == null)
				{
					Manipulator val = DelayDungeonGeneration;
					<>O.<8>__DelayDungeonGeneration = val;
					obj = (object)val;
				}
				RoundManager.GenerateNewFloor += (Manipulator)obj;
				_alreadyPatched = true;
			}
		}

		private static void CleanDawnDungeonReferences()
		{
			foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values)
			{
				if (!value.ShouldSkipIgnoreOverride())
				{
					List<DungeonArchetype> list = value.DungeonFlow.GetUsedArchetypes().Distinct().ToList();
					List<TileSet> list2 = value.DungeonFlow.GetUsedTileSets().Distinct().ToList();
					value.DungeonFlow.Nodes.Clear();
					value.DungeonFlow.Lines.Clear();
					for (int num = list.Count - 1; num >= 0; num--)
					{
						Object.Destroy((Object)(object)list[num]);
					}
					for (int num2 = list2.Count - 1; num2 >= 0; num2--)
					{
						Object.Destroy((Object)(object)list2[num2]);
					}
				}
			}
		}

		private static void DelayDungeonGeneration(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0),
				(Instruction i) => ILPatternMatchingExt.MatchLdfld<RoundManager>(i, "dungeonGenerator"),
				(Instruction i) => ILPatternMatchingExt.MatchCallvirt<RuntimeDungeon>(i, "Generate")
			}))
			{
				val.RemoveRange(3);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<IEnumerator>>((Func<IEnumerator>)LoadDungeonBundle);
				MethodInfo method = typeof(MonoBehaviour).GetMethod("StartCoroutine", new Type[1] { typeof(IEnumerator) });
				val.Emit(OpCodes.Callvirt, (MethodBase)method);
				val.Emit(OpCodes.Pop);
			}
			else
			{
				DawnPlugin.Logger.LogError((object)"Failed to apply DawnLib dungeon generation delay patch!");
				DawnPlugin.Logger.LogError((object)"IL code:");
				DawnPlugin.Logger.LogError((object)((object)il).ToString());
			}
		}

		private static IEnumerator UnloadDungeonBundleForAllPlayers(orig_EndOfGame orig, StartOfRound self, int bodiesInsured, int connectedPlayersOnServer, int scrapCollected)
		{
			if (!DungeonGenerationPlusCompat.Enabled || !DungeonGenerationPlusCompat.IsDebugOn())
			{
				if ((Object)(object)NetworkSingleton<DawnDungeonNetworker>.Instance != (Object)null)
				{
					IEnumerator unloadIEnumerator = NetworkSingleton<DawnDungeonNetworker>.Instance.UnloadExisting();
					while (unloadIEnumerator.MoveNext())
					{
						yield return unloadIEnumerator.Current;
					}
					NetworkSingleton<DawnDungeonNetworker>.Instance.PlayerSetBundleStateRpc(GameNetworkManager.Instance.localPlayerController, DawnMoonNetworker.BundleState.Done);
				}
				else if (!DawnConfig.VanillaCompatibility.Value)
				{
					DawnPlugin.Logger.LogError((object)"DawnDungeonNetworker is null, but VanillaCompatibility is false! This is a bug!");
				}
			}
			IEnumerator origIEnumerator = orig.Invoke(self, bodiesInsured, connectedPlayersOnServer, scrapCollected);
			while (origIEnumerator.MoveNext())
			{
				yield return origIEnumerator.Current;
			}
		}

		private static IEnumerator LoadDungeonBundle()
		{
			DawnDungeonInfo dungeonInfo = DungeonFlowExtensions.get_DawnInfo(RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow);
			if (!DungeonGenerationPlusCompat.Enabled || !DungeonGenerationPlusCompat.IsDebugOn())
			{
				if (!dungeonInfo.ShouldSkipIgnoreOverride() && NetworkSingleton<DawnDungeonNetworker>.IsNotNull)
				{
					NetworkSingleton<DawnDungeonNetworker>.Instance.QueueDungeonBundleLoading(dungeonInfo.Key);
					IEnumerator waitForLoad = (IEnumerator)new WaitUntil((Func<bool>)(() => NetworkSingleton<DawnDungeonNetworker>.Instance.allPlayersDone));
					while (waitForLoad.MoveNext())
					{
						yield return waitForLoad.Current;
					}
				}
				yield return (object)new WaitForSeconds(0.1f);
			}
			if (LethalLevelLoaderCompat.Enabled && dungeonInfo.ShouldSkipRespectOverride())
			{
				LethalLevelLoaderCompat.LetLLLHandleGeneration();
				yield break;
			}
			BoundedRange boundedRange = dungeonInfo.DungeonClampRange;
			if (dungeonInfo.DungeonClampRange.Min == 0f && dungeonInfo.DungeonClampRange.Max == 0f)
			{
				boundedRange = new BoundedRange(0f, 999f);
			}
			RoundManager.Instance.dungeonGenerator.Generator.LengthMultiplier = Mathf.Clamp(RoundManager.Instance.dungeonGenerator.Generator.LengthMultiplier, boundedRange.Min, boundedRange.Max);
			RoundManager.Instance.dungeonGenerator.Generate();
		}

		private static void AdjustFireExits(DungeonFlow dungeonFlow)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			GameObject val = GameObject.FindGameObjectWithTag("OutsideLevelNavMesh");
			EntranceTeleport[] array = (from e in Object.FindObjectsByType<EntranceTeleport>((FindObjectsInactive)0, (FindObjectsSortMode)1)
				where e.entranceId != 0
				select e).ToArray();
			for (int num = 0; num < array.Length; num++)
			{
				EntranceTeleport val2 = array[num];
				val2.entranceId = num + 1;
			}
			foreach (GlobalPropSettings item in dungeonFlow.GlobalProps.Where((GlobalPropSettings p) => p.ID == 1231))
			{
				item.Count = new IntRange(array.Length, array.Length);
			}
		}

		private static void UpdateAllDungeonWeights(orig_SetPlanetsWeather orig, StartOfRound self, int connectedPlayersOnServer)
		{
			orig.Invoke(self, connectedPlayersOnServer);
			UpdateDungeonWeightOnLevel(self.currentLevel);
		}

		internal static void UpdateDungeonWeightOnLevel(SelectableLevel level)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!LethalContent.Weathers.IsFrozen || !LethalContent.Dungeons.IsFrozen || (Object)(object)StartOfRound.Instance == (Object)null || (WeatherRegistryCompat.Enabled && !WeatherRegistryCompat.IsWeatherManagerReady()))
			{
				return;
			}
			IntWithRarity[] dungeonFlowTypes = level.dungeonFlowTypes;
			foreach (IntWithRarity val in dungeonFlowTypes)
			{
				DawnDungeonInfo dawnDungeonInfo = DungeonFlowExtensions.get_DawnInfo(RoundManagerRefs.Instance.dungeonFlowTypes[val.id].dungeonFlow);
				if (!dawnDungeonInfo.ShouldSkipRespectOverride())
				{
					int rarity = dawnDungeonInfo.GetRarity(SelectableLevelExtensions.get_DawnInfo(level), LevelWeatherTypeExtensions.get_DawnInfo(level.currentWeather));
					val.rarity = rarity;
				}
			}
		}

		private static void AddDawnDungeonsToMoons()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			foreach (DawnMoonInfo value in LethalContent.Moons.Values)
			{
				List<IntWithRarity> list = value.Level.dungeonFlowTypes.ToList();
				foreach (DawnDungeonInfo value2 in LethalContent.Dungeons.Values)
				{
					if (!value2.ShouldSkipIgnoreOverride())
					{
						int num = Array.IndexOf(RoundManagerRefs.Instance.dungeonFlowTypes.Select((IndoorMapType t) => t.dungeonFlow).ToArray(), value2.DungeonFlow);
						IntWithRarity item = new IntWithRarity(num, 0, (LevelAmbienceLibrary)null);
						list.Add(item);
					}
				}
				value.Level.dungeonFlowTypes = list.ToArray();
			}
		}

		private static void RegisterDawnDungeons(orig_Awake orig, StartOfRound self)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			List<IndoorMapType> list = RoundManagerRefs.Instance.dungeonFlowTypes.ToList();
			foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values)
			{
				if (!value.ShouldSkipIgnoreOverride())
				{
					IndoorMapType item = new IndoorMapType(value.DungeonFlow, value.MapTileSize, value.StingerDetail.FirstTimeAudio);
					list.Add(item);
				}
			}
			RoundManagerRefs.Instance.dungeonFlowTypes = list.ToArray();
			orig.Invoke(self);
		}

		private static void CollectNonDawnDungeons()
		{
			IndoorMapType[] dungeonFlowTypes = RoundManagerRefs.Instance.dungeonFlowTypes;
			foreach (IndoorMapType val in dungeonFlowTypes)
			{
				if (val == null || (Object)(object)val.dungeonFlow == (Object)null || DungeonFlowExtensions.get_DawnInfo(val.dungeonFlow) != null)
				{
					continue;
				}
				string name = FormatFlowName(val.dungeonFlow);
				NamespacedKey<DawnDungeonInfo> namespacedKey = DungeonKeys.GetByReflection(name);
				BoundedRange dungeonClampRange = new BoundedRange(0f, 999f);
				if (namespacedKey == null && LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetExtendedDungeonModName(val.dungeonFlow, out string modName))
				{
					namespacedKey = NamespacedKey<DawnDungeonInfo>.From(modName, ((Object)val.dungeonFlow).name);
					dungeonClampRange = LethalLevelLoaderCompat.GetDungeonClamp(val.dungeonFlow);
				}
				else if (namespacedKey == null)
				{
					namespacedKey = NamespacedKey<DawnDungeonInfo>.From("unknown_modded", ((Object)val.dungeonFlow).name);
				}
				if (LethalContent.Dungeons.ContainsKey(namespacedKey))
				{
					Debuggers.Dungeons?.Log($"LethalContent.Dungeons already contains {namespacedKey}");
					DungeonFlowExtensions.set_DawnInfo(val.dungeonFlow, LethalContent.Dungeons[namespacedKey]);
					continue;
				}
				HashSet<NamespacedKey> tags = new HashSet<NamespacedKey> { DawnLibTags.IsExternal };
				CollectLLLTags(val.dungeonFlow, tags);
				WeightProfile<int> weightProfile = new WeightProfile<int>(DawnWeightChannels.DungeonRarity.Policy);
				weightProfile.AddSource(new DungeonListBaseRaritySource(val.dungeonFlow));
				PersistentDataContainer persistentDataContainer = new PersistentDataContainer(Path.Combine(PersistentDataHandler.RootPath, "dungeon_" + namespacedKey.Namespace + "_" + namespacedKey.Key));
				if (!persistentDataContainer.Has(DawnKeys.StingerPlayed))
				{
					persistentDataContainer.Set(DawnKeys.StingerPlayed, value: false);
				}
				DawnStingerDetail stingerDetail = new DawnStingerDetail(val.firstTimeAudio, playsMoreThanOnce: false, 100f, new FuncProvider<bool>(() => true));
				int extraScrapGeneration = 0;
				if (namespacedKey == DungeonKeys.MineshaftFlow)
				{
					extraScrapGeneration = 6;
				}
				DawnDungeonInfo value = new DawnDungeonInfo(namespacedKey, tags, val.dungeonFlow, new DawnWeightedValue<int>(DawnWeightChannels.DungeonRarity, weightProfile), val.MapTileSize, stingerDetail, string.Empty, dungeonClampRange, extraScrapGeneration, persistentDataContainer);
				DungeonFlowExtensions.set_DawnInfo(val.dungeonFlow, value);
				LethalContent.Dungeons.Register(value);
			}
			CollectArchetypesAndTileSets();
			LethalContent.Dungeons.Freeze();
		}

		private static void CollectArchetypesAndTileSets()
		{
			foreach (DawnDungeonInfo value in LethalContent.Dungeons.Values)
			{
				DungeonArchetype[] usedArchetypes = value.DungeonFlow.GetUsedArchetypes();
				foreach (DungeonArchetype val in usedArchetypes)
				{
					Debuggers.Dungeons?.Log("dungeonArchetype.name: " + ((Object)val).name);
					NamespacedKey<DawnArchetypeInfo> namespacedKey;
					if (value.Key.IsVanilla())
					{
						string text = FormatArchetypeName(val);
						namespacedKey = DungeonArchetypeKeys.GetByReflection(text);
						if (namespacedKey == null)
						{
							DawnPlugin.Logger.LogWarning((object)$"archetype: '{((Object)val).name}' (part of {value.Key}) is vanilla, but DawnLib couldn't get a corresponding NamespacedKey, archetype has formatted name: {text}!");
							continue;
						}
					}
					else
					{
						namespacedKey = NamespacedKey<DawnArchetypeInfo>.From(value.Key.Namespace, ((Object)val).name);
					}
					if (LethalContent.Archetypes.ContainsKey(namespacedKey))
					{
						Debuggers.Dungeons?.Log($"LethalContent.Archetypes already contains {namespacedKey}");
						DungeonArchetypeExtensions.set_DawnInfo(val, LethalContent.Archetypes[namespacedKey]);
						continue;
					}
					HashSet<NamespacedKey> hashSet = new HashSet<NamespacedKey>();
					if (value.HasTag(DawnLibTags.IsExternal))
					{
						hashSet.Add(DawnLibTags.IsExternal);
					}
					DawnArchetypeInfo dawnArchetypeInfo = new DawnArchetypeInfo(namespacedKey, hashSet, val, null);
					DungeonArchetypeExtensions.set_DawnInfo(val, dawnArchetypeInfo);
					dawnArchetypeInfo.ParentInfo = value;
					LethalContent.Archetypes.Register(dawnArchetypeInfo);
					List<TileSet> tileSets = val.TileSets;
					List<TileSet> branchCapTileSets = val.BranchCapTileSets;
					List<TileSet> list = new List<TileSet>(tileSets.Count + branchCapTileSets.Count);
					list.AddRange(tileSets);
					list.AddRange(branchCapTileSets);
					List<TileSet> list2 = list;
					foreach (TileSet item in list2)
					{
						TryRegisterTileSet(value, item, dawnArchetypeInfo);
					}
				}
				TileSet[] usedTileSets = value.DungeonFlow.GetUsedTileSets();
				foreach (TileSet tileSet in usedTileSets)
				{
					TryRegisterTileSet(value, tileSet, null);
				}
			}
			LethalContent.Archetypes.Freeze();
			LethalContent.TileSets.Freeze();
		}

		private static void TryRegisterTileSet(DawnDungeonInfo dungeonInfo, TileSet tileSet, DawnArchetypeInfo? archetypeInfo)
		{
			if (TileSetExtensions.get_DawnInfo(tileSet) != null)
			{
				return;
			}
			Debuggers.Dungeons?.Log("tileSet.name: " + ((Object)tileSet).name);
			NamespacedKey<DawnTileSetInfo> namespacedKey;
			if (dungeonInfo.Key.IsVanilla())
			{
				string text = FormatTileSetName(tileSet);
				namespacedKey = DungeonTileSetKeys.GetByReflection(text);
				if (namespacedKey == null)
				{
					string text2 = archetypeInfo?.TypedKey.ToString() ?? "no archetype";
					DawnPlugin.Logger.LogWarning((object)("tileset: '" + ((Object)tileSet).name + "' (part of " + text2 + ") is vanilla, but DawnLib couldn't get a corresponding NamespacedKey, tileset has formatted name: " + text + "!"));
					return;
				}
			}
			else
			{
				namespacedKey = NamespacedKey<DawnTileSetInfo>.From(dungeonInfo.Key.Namespace, ((Object)tileSet).name);
			}
			if (LethalContent.TileSets.ContainsKey(namespacedKey))
			{
				Debuggers.Dungeons?.Log($"LethalContent.TileSets already contains {namespacedKey}");
				TileSetExtensions.set_DawnInfo(tileSet, LethalContent.TileSets[namespacedKey]);
				return;
			}
			HashSet<NamespacedKey> hashSet = new HashSet<NamespacedKey>();
			if (dungeonInfo.HasTag(DawnLibTags.IsExternal))
			{
				hashSet.Add(DawnLibTags.IsExternal);
			}
			DawnTileSetInfo dawnTileSetInfo = new DawnTileSetInfo(namespacedKey, hashSet, ConstantPredicate.True, tileSet, archetypeInfo?.DungeonArchetype.BranchCapTileSets.Contains(tileSet) ?? false, archetypeInfo?.DungeonArchetype.TileSets.Contains(tileSet) ?? false, null);
			archetypeInfo?.AddTileSet(dawnTileSetInfo);
			TileSetExtensions.set_DawnInfo(tileSet, dawnTileSetInfo);
			LethalContent.TileSets.Register(dawnTileSetInfo);
		}

		private static string FormatTileSetName(TileSet tileSet)
		{
			string input = NamespacedKey.NormalizeStringForNamespacedKey(((Object)tileSet).name, CSharpName: true);
			return ReplaceInternalLevelNames(input).Replace("Tiles", string.Empty);
		}

		private static string FormatArchetypeName(DungeonArchetype dungeonArchetype)
		{
			string input = NamespacedKey.NormalizeStringForNamespacedKey(((Object)dungeonArchetype).name, CSharpName: true);
			return ReplaceInternalLevelNames(input).Replace("Archetype", string.Empty);
		}

		private static string FormatFlowName(DungeonFlow dungeonFlow)
		{
			string input = NamespacedKey.NormalizeStringForNamespacedKey(((Object)dungeonFlow).name, CSharpName: true);
			return ReplaceInternalLevelNames(input);
		}

		private static string ReplaceInternalLevelNames(string input)
		{
			string text = input;
			foreach (KeyValuePair<string, string> internalToHumanDungeonName in _internalToHumanDungeonNames)
			{
				internalToHumanDungeonName.Deconstruct(out var key, out var value);
				string oldValue = key;
				string newValue = value;
				text = text.Replace(oldValue, newValue);
			}
			return text;
		}

		private static void CollectLLLTags(DungeonFlow dungeonFlow, HashSet<NamespacedKey> tags)
		{
			if (LethalLevelLoaderCompat.Enabled && LethalLevelLoaderCompat.TryGetAllTagsWithModNames(dungeonFlow, out List<(string, string)> allTagsWithModNames))
			{
				tags.AddToList(allTagsWithModNames, Debuggers.Dungeons, ((Object)dungeonFlow).name);
			}
		}

		private static void TryInjectTileSets(DungeonFlow dungeonFlow)
		{
			DungeonArchetype[] usedArchetypes = dungeonFlow.GetUsedArc

BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.dusk.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dawn;
using Dawn.Interfaces;
using Dawn.Internal;
using Dawn.Utils;
using DunGen;
using DunGen.Graph;
using Dusk;
using Dusk.Internal;
using Dusk.Utils;
using Dusk.Weights;
using GameNetcodeStuff;
using HarmonyLib;
using IL;
using IL.GameNetcodeStuff;
using LethalConfig;
using LethalConfig.AutoConfig;
using LethalConfig.ConfigItems;
using LethalConfig.Mods;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using On;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
using UnityEngine.UI;
using UnityEngine.VFX;
using UnityEngine.Video;
using com.github.teamxiaolan.dawnlib.dusk.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("LethalConfig")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: IgnoresAccessChecksTo("WeatherRegistry")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("XuXiaolan,loaforc")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Assetloading, content and config management built ontop of DawnLib.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+75bd30d5352a35f1657d9c13965f4155c465bcd3")]
[assembly: AssemblyProduct("DawnLib.DuskMod")]
[assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib.dusk")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Dawn.Internal
{
	internal static class DuskLethalConfigCompat
	{
		internal const string VERSION = "1.4.6";

		public static bool Enabled
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
				{
					return CompatibilityBoolExtensions.ShouldRunCompatibility(DawnConfig.LethalConfigCompatibility.Value, "1.4.6", Chainloader.PluginInfos["ainavt.lc.lethalconfig"].Metadata.Version);
				}
				return false;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void CreateLethalConfigMod(DuskMod duskMod)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			ModInfo val = new ModInfo
			{
				Name = duskMod.ModInformation.ModName,
				Guid = "com.local." + duskMod.ModInformation.ModName + "." + duskMod.ModInformation.AuthorName,
				Version = duskMod.ModInformation.Version,
				Description = duskMod.ModInformation.ModDescription,
				Icon = duskMod.ModInformation.ModIcon
			};
			Mod val2 = new Mod(val);
			LethalConfigManager.Mods.Add(val.Guid, val2);
			foreach (ConfigEntryBase configEntry in duskMod.ConfigEntries)
			{
				DebugLogSource lethalConfig = Debuggers.LethalConfig;
				if (lethalConfig != null)
				{
					lethalConfig.Log((object)$"No-Code DuskMod | Generating config item for {configEntry.Definition.Section}.{configEntry.Definition.Key} with type {configEntry.SettingType} and value {configEntry.BoxedValue}");
				}
				BaseConfigItem val3 = AutoConfigGenerator.GenerateConfigForEntry(configEntry);
				if (val3 != null)
				{
					val3.IsAutoGenerated = true;
					val3.Owner = val2;
					val2.ConfigItems.Add(val3);
				}
			}
		}
	}
}
namespace Dusk
{
	[Serializable]
	public class AssetBundleData
	{
		[AssetBundleReference]
		public string assetBundleName;

		[AssetBundleReference]
		public List<string> DependencyBundleNames = new List<string>();

		public bool enabledByDefault = true;

		[AssertNotEmpty]
		public string configName;
	}
	public abstract class AssetBundleLoader<TLoader> : IAssetBundleLoader where TLoader : AssetBundleLoader<TLoader>
	{
		private readonly bool _hasNonPreloadAudioClips;

		private List<string> _audioClipNames = new List<string>();

		private readonly bool _hasVideoClips;

		private List<string> _videoClipNames = new List<string>();

		private AssetBundle? _bundle;

		public AssetBundleData AssetBundleData { get; set; }

		public DuskContentDefinition[] Content { get; }

		public Dictionary<string, ConfigEntryBase> ConfigEntries => Content.SelectMany((DuskContentDefinition c) => c.generalConfigs).ToDictionary<KeyValuePair<string, ConfigEntryBase>, string, ConfigEntryBase>((KeyValuePair<string, ConfigEntryBase> it) => it.Key, (KeyValuePair<string, ConfigEntryBase> it) => it.Value);

		protected AssetBundleLoader(DuskMod mod, string filePath)
			: this(mod.Assembly, filePath)
		{
		}

		internal AssetBundleLoader(Assembly assembly, string filePath)
			: this(AssetBundleUtils.LoadBundle(assembly, filePath))
		{
		}

		protected AssetBundleLoader(AssetBundle bundle)
		{
			_bundle = bundle;
			DebugLogSource assetLoading = Debuggers.AssetLoading;
			if (assetLoading != null)
			{
				assetLoading.Log((object)(((Object)bundle).name + " contains these objects: " + string.Join(",", bundle.GetAllAssetNames())));
			}
			Type typeFromHandle = typeof(TLoader);
			PropertyInfo[] properties = typeFromHandle.GetProperties();
			foreach (PropertyInfo propertyInfo in properties)
			{
				LoadFromBundleAttribute loadFromBundleAttribute = (LoadFromBundleAttribute)propertyInfo.GetCustomAttribute(typeof(LoadFromBundleAttribute));
				if (loadFromBundleAttribute != null)
				{
					propertyInfo.SetValue(this, LoadAsset(bundle, loadFromBundleAttribute.BundleFile));
				}
			}
			Object[] array = bundle.LoadAllAssets();
			foreach (Object val in array)
			{
				GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null);
				if (val2 == null)
				{
					VideoClip val3 = (VideoClip)(object)((val is VideoClip) ? val : null);
					if (val3 == null)
					{
						AudioClip val4 = (AudioClip)(object)((val is AudioClip) ? val : null);
						if (val4 != null && !val4.preloadAudioData)
						{
							_audioClipNames.Add(((Object)val4).name);
							_hasNonPreloadAudioClips = true;
						}
					}
					else
					{
						_videoClipNames.Add(((Object)val3).name);
						_hasVideoClips = true;
					}
					continue;
				}
				DawnLib.FixMixerGroups(val2);
				DebugLogSource assetLoading2 = Debuggers.AssetLoading;
				if (assetLoading2 != null)
				{
					assetLoading2.Log((object)("Fixed Mixer Groups: " + ((Object)val2).name));
				}
				if (!((Object)(object)val2.GetComponent<NetworkObject>() == (Object)null))
				{
					DawnLib.RegisterNetworkPrefab(val2);
					DebugLogSource assetLoading3 = Debuggers.AssetLoading;
					if (assetLoading3 != null)
					{
						assetLoading3.Log((object)("Registered Network Prefab: " + ((Object)val2).name));
					}
				}
			}
			Content = bundle.LoadAllAssets<DuskContentDefinition>();
			List<Type> definitionOrder = new List<Type>(14)
			{
				typeof(DuskMoonDefinition),
				typeof(DuskDungeonDefinition),
				typeof(DuskWeatherDefinition),
				typeof(DuskVehicleDefinition),
				typeof(DuskMapObjectDefinition),
				typeof(DuskEnemyDefinition),
				typeof(DuskUnlockableDefinition),
				typeof(DuskItemDefinition),
				typeof(DuskTerminalCommandDefinition),
				typeof(DuskEntityReplacementDefinition),
				typeof(DuskStoryLogDefinition),
				typeof(DuskAchievementDefinition),
				typeof(DuskSurfaceDefinition),
				typeof(DuskAdditionalTilesDefinition)
			};
			Content = Content.OrderBy(delegate(DuskContentDefinition it)
			{
				Type type = ((object)it).GetType();
				int num = definitionOrder.IndexOf(type);
				return (num < 0) ? int.MaxValue : num;
			}).ToArray();
		}

		public ConfigEntry<T> GetConfig<T>(string configName)
		{
			return (ConfigEntry<T>)(object)ConfigEntries[configName];
		}

		public bool TryGetConfig<T>(string configName, [NotNullWhen(true)] out ConfigEntry<T>? entry)
		{
			if (ConfigEntries.TryGetValue(configName, out ConfigEntryBase value))
			{
				entry = (ConfigEntry<T>)(object)value;
				return true;
			}
			DuskContentDefinition? duskContentDefinition = Content.FirstOrDefault();
			if (duskContentDefinition != null)
			{
				ManualLogSource? logger = duskContentDefinition.Mod.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)$"TryGetConfig: '{configName}' does not exist on '{Content}', returning false and entry will be null");
				}
			}
			entry = null;
			return false;
		}

		internal void TryUnload()
		{
			if ((Object)(object)_bundle == (Object)null)
			{
				DawnPlugin.Logger.LogError((object)"Tried to unload bundle twice?");
				throw new NullReferenceException();
			}
			if (_hasNonPreloadAudioClips)
			{
				DawnPlugin.Logger.LogWarning((object)("Bundle: '" + ((Object)_bundle).name + "' is being unloaded but contains atleast one AudioClip that has 'preloadAudioData' to false! This will cause errors when trying to play said AudioClips, unloading stopped."));
				foreach (string audioClipName in _audioClipNames)
				{
					DebugLogSource assetLoading = Debuggers.AssetLoading;
					if (assetLoading != null)
					{
						assetLoading.Log((object)("AudioClip Name: " + audioClipName));
					}
				}
			}
			if (_hasVideoClips)
			{
				foreach (string videoClipName in _videoClipNames)
				{
					DebugLogSource assetLoading2 = Debuggers.AssetLoading;
					if (assetLoading2 != null)
					{
						assetLoading2.Log((object)("VideoClip Name: " + videoClipName));
					}
				}
				return;
			}
			_bundle.Unload(false);
			_bundle = null;
		}

		private Object LoadAsset(AssetBundle bundle, string path)
		{
			Object val = bundle.LoadAsset<Object>(path);
			if (val == (Object)null)
			{
				throw new ArgumentException(path + " is not valid in the assetbundle!");
			}
			return val;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class AssetBundleReference : PropertyAttribute
	{
	}
	[CreateAssetMenu(fileName = "New Content Container", menuName = "DawnLib/Content Container", order = -10)]
	public class ContentContainer : ScriptableObject
	{
		public List<AssetBundleData> assetBundles;
	}
	public class DefaultBundle : AssetBundleLoader<DefaultBundle>
	{
		public DefaultBundle(DuskMod mod, string filePath)
			: base(mod, filePath)
		{
		}

		internal DefaultBundle(AssetBundle bundle)
			: base(bundle)
		{
		}
	}
	public interface IAssetBundleLoader
	{
		DuskContentDefinition[] Content { get; }

		AssetBundleData AssetBundleData { get; set; }
	}
	[AttributeUsage(AttributeTargets.Property)]
	public class LoadFromBundleAttribute(string bundleFile) : Attribute()
	{
		public string BundleFile { get; private set; } = bundleFile;
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class AssertAssetInCorrectBundle : PropertyAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class AssertNotNull : PropertyAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class AssertNotEmpty : PropertyAttribute
	{
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	public sealed class ContentOrderAttribute(int order) : Attribute()
	{
		public int Order { get; } = order;
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
	public sealed class DefaultKeySourceAttribute(string memberName, bool normalize = true) : PropertyAttribute()
	{
		public string MemberName { get; } = memberName;

		public bool Normalize { get; } = normalize;
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class DontDrawIfEmpty(string? groupId = null, string? header = null) : PropertyAttribute()
	{
		public string? GroupId { get; } = groupId;

		public string? Header { get; } = header;
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
	public class UnlockedNamespacedKey : PropertyAttribute
	{
	}
	public class AutoDuskModHandler
	{
		public static void AutoRegisterMods()
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "*.duskmod", SearchOption.AllDirectories);
			foreach (string text in files)
			{
				AssetBundle val = AssetBundle.LoadFromFile(text);
				DebugLogSource assetLoading = Debuggers.AssetLoading;
				if (assetLoading != null)
				{
					assetLoading.Log((object)(((Object)val).name + " contains these objects: " + string.Join(",", val.GetAllAssetNames())));
				}
				DuskModInformation[] array = val.LoadAllAssets<DuskModInformation>();
				if (array.Length == 0)
				{
					DawnPlugin.Logger.LogError((object)(".duskmod bundle: '" + Path.GetFileName(text) + "' does not have a 'Mod Information' file!"));
					continue;
				}
				if (array.Length > 1)
				{
					DawnPlugin.Logger.LogError((object)(".duskmod bundle: '" + Path.GetFileName(text) + "' has multiple 'Mod Information' files! Only the first one will be used."));
				}
				DawnPlugin.Logger.LogInfo((object)("AuthorName: " + array[0].AuthorName + ", ModName: " + array[0].ModName + ", Version: " + array[0].Version));
				DuskMod.RegisterNoCodeMod(array[0], val, Path.GetDirectoryName(text));
			}
		}
	}
	public class DefaultContentHandler : ContentHandler
	{
		public DefaultContentHandler(DuskMod mod)
			: base(mod)
		{
			ManualLogSource? logger = mod.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)$"Trying to register bundle: {((Object)mod.Content).name} with {mod.Content.assetBundles.Count} assets.");
			}
			foreach (AssetBundleData assetBundle in mod.Content.assetBundles)
			{
				if (!IsContentEnabled(assetBundle))
				{
					continue;
				}
				if (!mod.TryGetRelativeFile(out string fullPath, "Assets", assetBundle.assetBundleName))
				{
					ManualLogSource? logger2 = mod.Logger;
					if (logger2 != null)
					{
						logger2.LogError((object)("The bundle: " + assetBundle.configName + " is not defined at plugins/" + Path.GetRelativePath(Paths.PluginPath, fullPath) + "."));
					}
					if (mod.TryGetRelativeFile(out string fullPath2, assetBundle.assetBundleName))
					{
						ManualLogSource? logger3 = mod.Logger;
						if (logger3 != null)
						{
							logger3.LogError((object)("The bundle is instead defined at plugins/" + Path.GetRelativePath(Paths.PluginPath, fullPath2) + ". It should be in an Assets/ subfolder."));
						}
					}
					ManualLogSource? logger4 = mod.Logger;
					if (logger4 != null)
					{
						logger4.LogError((object)"Please make sure that you uploaded your mod zip correctly.");
					}
					ManualLogSource? logger5 = mod.Logger;
					if (logger5 != null)
					{
						logger5.LogError((object)"Local mods do not have their folder structure edited, but uploaded mods CAN if you don't follow a specific naming scheme");
					}
					ManualLogSource? logger6 = mod.Logger;
					if (logger6 != null)
					{
						logger6.LogError((object)"Here is a working example:\nFolder Structure:\nYOURMOD.zip\n└─ plugins\n    └─ Assets\n        └─ NormalAssetBundlesGoHere\n    └─ DuskModAssetBundleGoesHere\n└─ CHANGELOG.md\n└─ icon.md\n└─ LICENSE.md\n└─ manifest.json\n└─ README.md\n");
					}
				}
				else
				{
					DefaultBundle bundle = new DefaultBundle(AssetBundle.LoadFromFile(fullPath))
					{
						AssetBundleData = assetBundle
					};
					LoadAllContent(bundle);
				}
			}
		}
	}
	[CreateAssetMenu(fileName = "New Mod Information", menuName = "DawnLib/Mod Information", order = -10)]
	public class DuskModInformation : ScriptableObject
	{
		[field: SerializeField]
		[field: AssertNotEmpty]
		public string AuthorName { get; private set; }

		[field: SerializeField]
		[field: AssertNotEmpty]
		public string ModName { get; private set; }

		[field: SerializeField]
		[field: AssertNotEmpty]
		public string Version { get; private set; }

		[field: SerializeField]
		public TextAsset? READMEFile { get; private set; }

		[field: SerializeField]
		public TextAsset? ChangelogFile { get; private set; }

		[field: SerializeField]
		[field: AssertNotEmpty]
		public string ModDescription { get; private set; }

		[Tooltip("Comma separated list of dependencies that this mod depends on apart from the default DawnLib, BepInEx and potentially WeatherRegistry, grab from the thunderstore page.")]
		[field: SerializeField]
		[field: AssertNotEmpty]
		public List<string> ExtraDependencies { get; private set; } = new List<string>();

		[field: SerializeField]
		public string WebsiteUrl { get; private set; }

		[field: SerializeField]
		public Sprite? ModIcon { get; private set; }

		internal void SetInfoDetails(string authorName, string modName, string version, string modDescription, string websiteUrl, List<string> extraDependencies, Sprite? modIcon, TextAsset? readmeFile, TextAsset? changelogFile)
		{
			AuthorName = authorName;
			ModName = modName;
			Version = version;
			ModDescription = modDescription;
			WebsiteUrl = websiteUrl;
			ExtraDependencies = extraDependencies;
			ModIcon = modIcon;
			READMEFile = readmeFile;
			ChangelogFile = changelogFile;
		}

		public BepInPlugin CreatePluginMetadata()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			return new BepInPlugin(AuthorName + "." + ModName, ModName, Version);
		}
	}
	public class ConfigContext(ConfigFile file, string heading) : IDisposable
	{
		public void Dispose()
		{
		}

		public ConfigEntry<T> Bind<T>(string name, string description, T defaultValue)
		{
			return ConfigFileExtensions.CleanedBind<T>(file, heading, name, defaultValue, description);
		}
	}
	public class ConfigManager(ConfigFile file)
	{
		public ConfigFile File { get; } = file;

		public ConfigContext CreateConfigSection(string header)
		{
			return new ConfigContext(File, header);
		}

		public ConfigContext CreateConfigSectionForBundleData(AssetBundleData data)
		{
			return CreateConfigSection(data.configName + " Options");
		}

		public ConfigEntryBase CreateDynamicConfig(bool userAllowedToEdit, DuskDynamicConfig configDefinition, ConfigContext context)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			return (ConfigEntryBase)(configDefinition.DynamicConfigType switch
			{
				DuskDynamicConfigType.String => Bind<string>(configDefinition.defaultString), 
				DuskDynamicConfigType.Int => Bind<int>(configDefinition.defaultInt), 
				DuskDynamicConfigType.Bool => Bind<bool>(configDefinition.defaultBool), 
				DuskDynamicConfigType.Float => Bind<float>(configDefinition.defaultFloat), 
				DuskDynamicConfigType.BoundedRange => Bind<BoundedRange>(configDefinition.defaultBoundedRange), 
				DuskDynamicConfigType.AnimationCurve => Bind<AnimationCurve>(configDefinition.defaultAnimationCurve), 
				DuskDynamicConfigType.Vector3 => Bind<Vector3>(configDefinition.defaultVector3), 
				DuskDynamicConfigType.Color => Bind<Color>(configDefinition.defaultColor), 
				_ => throw new ArgumentOutOfRangeException($"DynamicConfigType of '{configDefinition.DynamicConfigType}' is not yet internally implemented!!"), 
			});
			ConfigEntryBase Bind<T>(T defaultValue)
			{
				ConfigEntry<T> val = context.Bind(configDefinition.settingName, configDefinition.Description, defaultValue);
				if (!userAllowedToEdit)
				{
					DuskBaseConfig.AssignValueIfNotNull(val, defaultValue);
				}
				return (ConfigEntryBase)(object)val;
			}
		}

		public static Dictionary<string, string> ParseNamespacedKeyWithCurves(string configString)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from s in configString.Split('|', StringSplitOptions.RemoveEmptyEntries)
				select s.Trim())
			{
				string[] array = (from s in item.Split('-')
					select s.Trim()).ToArray();
				if (array.Length == 2)
				{
					string key = array[0].ToLowerInvariant();
					dictionary[key] = array[1];
				}
			}
			return dictionary;
		}

		public static AnimationCurve ParseCurve(string keyValuePairs)
		{
			return TomlTypeConverter.ConvertToValue<AnimationCurve>(keyValuePairs);
		}

		public static string ParseString(AnimationCurve animationCurve)
		{
			return TomlTypeConverter.ConvertToString((object)animationCurve, typeof(AnimationCurve));
		}

		internal static ConfigFile GenerateConfigFile(BepInPlugin plugin)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			return new ConfigFile(Utility.CombinePaths(new string[2]
			{
				Paths.ConfigPath,
				plugin.GUID + ".cfg"
			}), false, plugin);
		}

		public static ConfigEntryBase? FindEntry(ConfigFile file, string section, string key)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			ConfigDefinition definition = new ConfigDefinition(section, key);
			ICollection<ConfigEntryBase> values = ((IDictionary<ConfigDefinition, ConfigEntryBase>)file).Values;
			return ((IEnumerable<ConfigEntryBase>)values).FirstOrDefault((Func<ConfigEntryBase, bool>)((ConfigEntryBase x) => x.Definition == definition));
		}
	}
	public static class ConfigReaderTypeUtility
	{
		private static readonly Dictionary<Type, DuskDynamicConfigType> SettingTypeToDynamicType = new Dictionary<Type, DuskDynamicConfigType>
		{
			{
				typeof(string),
				DuskDynamicConfigType.String
			},
			{
				typeof(int),
				DuskDynamicConfigType.Int
			},
			{
				typeof(float),
				DuskDynamicConfigType.Float
			},
			{
				typeof(bool),
				DuskDynamicConfigType.Bool
			},
			{
				typeof(BoundedRange),
				DuskDynamicConfigType.BoundedRange
			},
			{
				typeof(Vector3),
				DuskDynamicConfigType.Vector3
			},
			{
				typeof(Color),
				DuskDynamicConfigType.Color
			},
			{
				typeof(AnimationCurve),
				DuskDynamicConfigType.AnimationCurve
			}
		};

		private static readonly Dictionary<DuskDynamicConfigType, string> DynamicTypeToEventFieldName = new Dictionary<DuskDynamicConfigType, string>
		{
			{
				DuskDynamicConfigType.String,
				"onString"
			},
			{
				DuskDynamicConfigType.Int,
				"onInt"
			},
			{
				DuskDynamicConfigType.Float,
				"onFloat"
			},
			{
				DuskDynamicConfigType.Bool,
				"onBool"
			},
			{
				DuskDynamicConfigType.BoundedRange,
				"onBoundedRange"
			},
			{
				DuskDynamicConfigType.Vector3,
				"onVector3"
			},
			{
				DuskDynamicConfigType.Color,
				"onColor"
			},
			{
				DuskDynamicConfigType.AnimationCurve,
				"onAnimationCurve"
			}
		};

		public static DuskDynamicConfigType? ConvertSettingTypeToDynamicType(Type settingType)
		{
			if (SettingTypeToDynamicType.TryGetValue(settingType, out var value))
			{
				return value;
			}
			return null;
		}

		public static string GetEventFieldName(DuskDynamicConfigType configType)
		{
			if (DynamicTypeToEventFieldName.TryGetValue(configType, out string value))
			{
				return value;
			}
			throw new ArgumentOutOfRangeException("configType", configType, null);
		}
	}
	[AddComponentMenu("DawnLib/Misc Utilities/Config Reader")]
	public class ConfigReader : MonoBehaviour
	{
		[Header("Config Target")]
		[SerializeField]
		private string pluginGuid = "";

		[SerializeField]
		private string section = "";

		[SerializeField]
		private string key = "";

		[SerializeField]
		private DuskDynamicConfigType expectedType;

		[Header("Invoke")]
		[SerializeField]
		private bool invokeOnStart = true;

		[Header("Events")]
		[SerializeField]
		private UnityEvent onUnsupportedType;

		[SerializeField]
		private UnityEvent onEntryNotFound;

		[SerializeField]
		private UnityEvent onTypeMismatch;

		[SerializeField]
		private StringEvent onString;

		[SerializeField]
		private FloatEvent onFloat;

		[SerializeField]
		private IntEvent onInt;

		[SerializeField]
		private BoolEvent onBool;

		[SerializeField]
		private BoundedRangeEvent onBoundedRange;

		[SerializeField]
		private Vector3Event onVector3;

		[SerializeField]
		private ColorEvent onColor;

		[SerializeField]
		private AnimationCurveEvent onAnimationCurve;

		private ConfigEntryBase? _matchedEntry;

		public DuskDynamicConfigType ExpectedType => expectedType;

		public ConfigEntryBase? MatchedEntry => _matchedEntry;

		private void Start()
		{
			ResolveEntry();
			if (invokeOnStart)
			{
				InvokeMatchedEvent();
			}
		}

		public void ResolveEntry()
		{
			_matchedEntry = TryFindConfigEntry(pluginGuid, section, key);
			if (_matchedEntry == null)
			{
				DuskPlugin.Logger.LogWarning((object)("ConfigReader could not find config entry: plugin='" + pluginGuid + "', section='" + section + "', key='" + key + "'"));
				return;
			}
			DebugLogSource configs = Debuggers.Configs;
			if (configs != null)
			{
				configs.Log((object)$"Matched config entry: plugin='{pluginGuid}', section='{_matchedEntry.Definition.Section}', key='{_matchedEntry.Definition.Key}', type='{_matchedEntry.SettingType}', value='{_matchedEntry.BoxedValue}'");
			}
		}

		public void InvokeMatchedEvent()
		{
			if (_matchedEntry == null)
			{
				ResolveEntry();
			}
			if (_matchedEntry == null)
			{
				UnityEvent obj = onEntryNotFound;
				if (obj != null)
				{
					obj.Invoke();
				}
				return;
			}
			DuskDynamicConfigType? duskDynamicConfigType = ConfigReaderTypeUtility.ConvertSettingTypeToDynamicType(_matchedEntry.SettingType);
			if (!duskDynamicConfigType.HasValue)
			{
				DuskPlugin.Logger.LogWarning((object)("Unsupported config type on ConfigReader: " + _matchedEntry.SettingType.FullName));
				UnityEvent obj2 = onUnsupportedType;
				if (obj2 != null)
				{
					obj2.Invoke();
				}
			}
			else if (duskDynamicConfigType.Value != expectedType)
			{
				DuskPlugin.Logger.LogWarning((object)$"ConfigReader type mismatch for '{pluginGuid}:{section}:{key}'. Expected '{expectedType}', but config entry was '{duskDynamicConfigType.Value}'.");
				UnityEvent obj3 = onTypeMismatch;
				if (obj3 != null)
				{
					obj3.Invoke();
				}
			}
			else
			{
				InvokeExpectedTypeEvent(_matchedEntry.BoxedValue);
			}
		}

		private void InvokeExpectedTypeEvent(object value)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			switch (expectedType)
			{
			case DuskDynamicConfigType.String:
				((UnityEvent<string>)(object)onString)?.Invoke((string)value);
				return;
			case DuskDynamicConfigType.Int:
				((UnityEvent<int>)(object)onInt)?.Invoke((int)value);
				return;
			case DuskDynamicConfigType.Float:
				((UnityEvent<float>)(object)onFloat)?.Invoke(Convert.ToSingle(value, CultureInfo.InvariantCulture));
				return;
			case DuskDynamicConfigType.Bool:
				((UnityEvent<bool>)(object)onBool)?.Invoke((bool)value);
				return;
			case DuskDynamicConfigType.BoundedRange:
				((UnityEvent<BoundedRange>)(object)onBoundedRange)?.Invoke((BoundedRange)value);
				return;
			case DuskDynamicConfigType.Vector3:
				((UnityEvent<Vector3>)(object)onVector3)?.Invoke((Vector3)value);
				return;
			case DuskDynamicConfigType.Color:
				((UnityEvent<Color>)(object)onColor)?.Invoke((Color)value);
				return;
			case DuskDynamicConfigType.AnimationCurve:
				((UnityEvent<AnimationCurve>)(object)onAnimationCurve)?.Invoke((AnimationCurve)value);
				return;
			}
			DuskPlugin.Logger.LogWarning((object)$"Unhandled expected config type: {expectedType}");
			UnityEvent obj = onUnsupportedType;
			if (obj != null)
			{
				obj.Invoke();
			}
		}

		private static ConfigEntryBase? TryFindConfigEntry(string pluginGuid, string section, string key)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			if (string.IsNullOrWhiteSpace(pluginGuid) || string.IsNullOrWhiteSpace(section) || string.IsNullOrWhiteSpace(key))
			{
				return null;
			}
			if (!Chainloader.PluginInfos.TryGetValue(pluginGuid, out var value))
			{
				return null;
			}
			DebugLogSource configs = Debuggers.Configs;
			if (configs != null)
			{
				configs.Log((object)("ConfigReader: pluginGuid=" + pluginGuid + ", section=" + section + ", key=" + key));
			}
			ConfigFile config = value.Instance.Config;
			ConfigDefinition val = new ConfigDefinition(section, key);
			ICollection<ConfigEntryBase> values = ((IDictionary<ConfigDefinition, ConfigEntryBase>)config).Values;
			foreach (ConfigEntryBase item in values)
			{
				ConfigDefinition definition = item.Definition;
				DebugLogSource configs2 = Debuggers.Configs;
				if (configs2 != null)
				{
					configs2.Log((object)("Existing definition: Section: " + definition.Section + " | Key: " + definition.Key));
				}
				if (definition == val)
				{
					return item;
				}
			}
			return null;
		}
	}
	public abstract class DuskBaseConfig
	{
		public ConfigEntry<bool> AllowEditingConfig;

		internal abstract List<ConfigEntryBase?> _configEntries { get; }

		public DuskBaseConfig(ConfigContext section, string EntityNameReference)
		{
			bool defaultValue = true;
			string input = default(string);
			if (!((DataContainer)DawnPlugin.PersistentData).TryGet<string>(DawnKeys.LastVersion, ref input) || Version.Parse(input) >= Version.Parse("0.7.8"))
			{
				defaultValue = false;
			}
			AllowEditingConfig = section.Bind(EntityNameReference + " | Allow Editing Config", "Whether you're allowed to edit the config entries for " + EntityNameReference + ".", defaultValue);
		}

		public bool UserAllowedToEdit()
		{
			return AllowEditingConfig.Value;
		}

		internal static void AssignValueIfNotNull<T>(ConfigEntry<T>? configEntry, T value)
		{
			if (configEntry != null)
			{
				configEntry.Value = value;
			}
		}

		public List<ConfigEntryBase> ConfigEntries()
		{
			List<ConfigEntryBase> list = new List<ConfigEntryBase>(1) { (ConfigEntryBase)(object)AllowEditingConfig };
			foreach (ConfigEntryBase configEntry in _configEntries)
			{
				if (configEntry != null)
				{
					list.Add(configEntry);
				}
			}
			return list;
		}
	}
	[Serializable]
	public class DuskDynamicConfig
	{
		public string settingName;

		public DuskDynamicConfigType DynamicConfigType;

		public string defaultString;

		public int defaultInt;

		public float defaultFloat;

		public bool defaultBool;

		public BoundedRange defaultBoundedRange;

		public AnimationCurve defaultAnimationCurve;

		public Vector3 defaultVector3;

		public Color defaultColor;

		public string Description;
	}
	public enum DuskDynamicConfigType
	{
		String,
		Int,
		Float,
		Bool,
		BoundedRange,
		AnimationCurve,
		Vector3,
		Color
	}
	public abstract class ContentHandler(DuskMod mod)
	{
		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		protected bool IsContentEnabled(string bundleName)
		{
			if (!mod.TryGetBundleDataFromName(bundleName, out AssetBundleData data))
			{
				return false;
			}
			return IsContentEnabled(data);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		protected bool IsContentEnabled(AssetBundleData assetBundleData)
		{
			string configName = assetBundleData.configName;
			using ConfigContext configContext = mod.ConfigManager.CreateConfigSectionForBundleData(assetBundleData);
			ConfigEntry<bool> val = configContext.Bind("Enabled", "Whether " + configName + " is enabled.", assetBundleData.enabledByDefault);
			mod._configEntries.Add((ConfigEntryBase)(object)val);
			return val.Value;
		}

		protected bool TryLoadContentBundle<TAsset>(string assetBundleName, out TAsset? asset, bool forceEnabled = false) where TAsset : AssetBundleLoader<TAsset>
		{
			asset = null;
			if (!mod.TryGetBundleDataFromName(assetBundleName, out AssetBundleData data))
			{
				ManualLogSource? logger = mod.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("Assetbundle name: " + assetBundleName + " is not implemented yet!"));
				}
				return false;
			}
			if (!IsContentEnabled(data) && !forceEnabled)
			{
				return false;
			}
			ConstructorInfo constructor = typeof(TAsset).GetConstructor(new Type[2]
			{
				typeof(DuskMod),
				typeof(string)
			});
			if (constructor == null)
			{
				ManualLogSource? logger2 = mod.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)(typeof(TAsset).Name + " is not properly setup to handle TryLoadContentBundle. It must have a constructor with (DuskMod, string) as arguments!"));
				}
				return false;
			}
			asset = (TAsset)constructor.Invoke(new object[2] { mod, assetBundleName });
			AssetBundleData assetBundleData = data;
			asset.AssetBundleData = assetBundleData;
			asset.TryUnload();
			return true;
		}

		protected void LoadAllContent(IAssetBundleLoader bundle)
		{
			DuskContentDefinition[] content = bundle.Content;
			DuskContentDefinition[] array = content;
			foreach (DuskContentDefinition duskContentDefinition in array)
			{
				duskContentDefinition.AssetBundleData = bundle.AssetBundleData;
				duskContentDefinition.Register(mod);
				duskContentDefinition.RegisterPost(mod);
				duskContentDefinition.RegisterConfigs(mod);
			}
		}

		protected void LoadAllContent(params IAssetBundleLoader[] bundles)
		{
			foreach (IAssetBundleLoader bundle in bundles)
			{
				LoadAllContent(bundle);
			}
		}

		protected bool RegisterContent<TAsset>(string bundleName, out TAsset? asset, bool forceEnabled = false) where TAsset : AssetBundleLoader<TAsset>
		{
			if (TryLoadContentBundle<TAsset>(bundleName, out asset, forceEnabled))
			{
				LoadAllContent(asset);
				return true;
			}
			return false;
		}
	}
	public abstract class ContentHandler<T> : ContentHandler where T : ContentHandler<T>
	{
		public static T Instance { get; private set; }

		public ContentHandler(DuskMod mod)
			: base(mod)
		{
			Instance = (T)this;
		}
	}
	public class AchievementSaveData(bool completed)
	{
		public bool Completed { get; set; } = completed;
	}
	[AddComponentMenu("DawnLib/Achievements/Achievement Triggers")]
	public class AchievementTriggers : MonoBehaviour
	{
		[SerializeReference]
		private DuskAchievementReference _reference;

		[SerializeField]
		private UnityEvent _onAchievementCompleted = new UnityEvent();

		public void TryCompleteAchievement()
		{
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Trying to complete achievement: {_reference.TypedKey}");
			}
			if (_reference.TryResolve(out DuskAchievementDefinition info) && DuskModContent.Achievements.TryTriggerAchievement(info.TypedKey))
			{
				_onAchievementCompleted.Invoke();
			}
		}

		public void TryIncrementAchievement(float amountToIncrement)
		{
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Trying to increment achievement: {_reference.TypedKey} by {amountToIncrement}");
			}
			if (_reference.TryResolve(out DuskAchievementDefinition info) && DuskModContent.Achievements.TryIncrementAchievement(info.TypedKey, amountToIncrement))
			{
				_onAchievementCompleted.Invoke();
			}
		}

		public void TryDiscoverMoreProgressAchievement(string uniqueStringID)
		{
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Trying to discover more progress for achievement: {_reference.TypedKey} with unique string id: {uniqueStringID}");
			}
			if (_reference.TryResolve(out DuskAchievementDefinition info) && DuskModContent.Achievements.TryDiscoverMoreProgressAchievement(info.TypedKey, uniqueStringID))
			{
				_onAchievementCompleted.Invoke();
			}
		}

		public void TryDiscoverMoreProgressAchievement(List<string> uniqueStringIDs)
		{
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)string.Format("Trying to discover more progress for achievement: {0} with unique string ids: {1}", _reference.TypedKey, string.Join(", ", uniqueStringIDs)));
			}
			if (_reference.TryResolve(out DuskAchievementDefinition info) && DuskModContent.Achievements.TryDiscoverMoreProgressAchievement(info.TypedKey, uniqueStringIDs))
			{
				_onAchievementCompleted.Invoke();
			}
		}

		public void ResetAllAchievementProgress()
		{
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Trying to reset all progress for achievement: {_reference.TypedKey}");
			}
			if (_reference.TryResolve(out DuskAchievementDefinition info))
			{
				info.ResetProgress();
			}
		}

		public void SoftResetAllAchievementProgress()
		{
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Trying to soft reset all progress for achievement: {_reference.TypedKey}");
			}
			if (_reference.TryResolve(out DuskAchievementDefinition info))
			{
				info.SoftResetProgress();
			}
		}
	}
	public class AchievementModUIElement : MonoBehaviour
	{
		[SerializeField]
		private TextMeshProUGUI _modNameText;

		[SerializeField]
		private Image _modIcon;

		[SerializeField]
		private Button _achievementAccessButton;

		[SerializeField]
		private GameObject _achievementUIElementPrefab;

		internal GameObject _achievementsContainer;

		internal List<AchievementUIElement> achievementsContainerList = new List<AchievementUIElement>();

		internal static List<AchievementModUIElement> achievementModUIElements = new List<AchievementModUIElement>();

		private void Awake()
		{
			achievementModUIElements.Add(this);
		}

		private void OnDestroy()
		{
			achievementModUIElements.Remove(this);
		}

		internal void SetupModUI(DuskMod mod)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			((TMP_Text)_modNameText).text = mod.ModInformation.ModName;
			if ((Object)(object)mod.ModInformation.ModIcon != (Object)null)
			{
				_modIcon.sprite = mod.ModInformation.ModIcon;
				((Graphic)_modIcon).color = Color.white;
			}
			List<DuskAchievementDefinition> list = (from a in DuskModContent.Achievements.Values.Where((DuskAchievementDefinition a) => a.Mod == mod).ToList()
				orderby a.AchievementName descending
				select a).ToList();
			foreach (DuskAchievementDefinition item in list)
			{
				DebugLogSource achievements = Debuggers.Achievements;
				if (achievements != null)
				{
					achievements.Log((object)("Adding achievement: " + item.AchievementName));
				}
				GameObject val = Object.Instantiate<GameObject>(_achievementUIElementPrefab, _achievementsContainer.transform);
				val.SetActive(false);
				AchievementUIElement component = val.GetComponent<AchievementUIElement>();
				component.SetupAchievementUI(item);
				((Object)val).name = "DawnLib Achievement UI - " + item.AchievementName + " - " + mod.Plugin.GUID;
				achievementsContainerList.Add(component);
			}
			((UnityEvent)_achievementAccessButton.onClick).AddListener(new UnityAction(OnButtonClick));
		}

		public void OnButtonClick()
		{
			foreach (AchievementModUIElement modUIElement in Singleton<AchievementUICanvas>.Instance._modUIElements)
			{
				if ((Object)(object)modUIElement == (Object)(object)this)
				{
					continue;
				}
				foreach (AchievementUIElement achievementsContainer in modUIElement.achievementsContainerList)
				{
					((Component)achievementsContainer).gameObject.SetActive(false);
				}
			}
			foreach (AchievementUIElement achievementsContainer2 in achievementsContainerList)
			{
				((Component)achievementsContainer2).gameObject.SetActive(!((Component)achievementsContainer2).gameObject.activeSelf);
			}
		}
	}
	public class AchievementUICanvas : Singleton<AchievementUICanvas>
	{
		[SerializeField]
		internal GameObject _achievementContents;

		[SerializeField]
		private GameObject _modContents;

		[SerializeField]
		private Button _backButton;

		[SerializeField]
		private GameObject _background;

		[SerializeField]
		private GameObject _achievementModUIElementPrefab;

		internal Button _achievementsButton;

		private GameObject _mainButtons;

		internal MenuManager _menuManager;

		internal List<AchievementModUIElement> _modUIElements = new List<AchievementModUIElement>();

		private void Start()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			_mainButtons = _menuManager.menuButtons;
			((UnityEvent)_backButton.onClick).AddListener(new UnityAction(BackButtonOnClick));
			((UnityEvent)_backButton.onClick).AddListener(new UnityAction(_menuManager.PlayCancelSFX));
			AddAllAchievementsToContents();
		}

		private void AddAllAchievementsToContents()
		{
			foreach (DuskMod duskMod in DuskMod.AllMods)
			{
				if (DuskModContent.Achievements.Values.Count((DuskAchievementDefinition a) => a.Mod == duskMod) > 0)
				{
					GameObject val = Object.Instantiate<GameObject>(_achievementModUIElementPrefab, _modContents.transform);
					AchievementModUIElement component = val.GetComponent<AchievementModUIElement>();
					component._achievementsContainer = _achievementContents;
					_modUIElements.Add(component);
					component.SetupModUI(duskMod);
				}
			}
		}

		public void BackButtonOnClick()
		{
			_menuManager.EnableUIPanel(_mainButtons);
			if ((Object)(object)_achievementsButton != (Object)null)
			{
				((Selectable)_achievementsButton).Select();
			}
			_background.SetActive(false);
		}

		public void AchievementsButtonOnClick()
		{
			_mainButtons.SetActive(false);
			_background.SetActive(true);
			((Selectable)_backButton).Select();
		}
	}
	public class AchievementUIElement : MonoBehaviour
	{
		[SerializeField]
		[FormerlySerializedAs("_achievementNameTMP")]
		internal TextMeshProUGUI achievementNameTMP;

		[SerializeField]
		[FormerlySerializedAs("_achievementDescriptionTMP")]
		internal TextMeshProUGUI achievementDescriptionTMP;

		[SerializeField]
		[FormerlySerializedAs("_achievementProgressGO")]
		internal GameObject achievementProgressGO;

		[SerializeField]
		[FormerlySerializedAs("_achievementHiddenButton")]
		internal Button achievementHiddenButton;

		[SerializeField]
		[FormerlySerializedAs("_achievementIcon")]
		internal Image achievementIcon;

		[SerializeField]
		[FormerlySerializedAs("_unfinishedAchievementColor")]
		internal Color unfinishedAchievementColor = new Color(0.5f, 0.5f, 0.5f);

		[SerializeField]
		[FormerlySerializedAs("_backgroundImage")]
		internal Image backgroundImage;

		[SerializeField]
		[FormerlySerializedAs("_progressBar")]
		internal Image progressBar;

		[SerializeField]
		internal AudioSource audioSource;

		[SerializeField]
		[FormerlySerializedAs("_eventTrigger")]
		internal EventTrigger? eventTrigger;

		internal DuskAchievementDefinition achievementDefinition;

		public void SetupAchievementUI(DuskAchievementDefinition definition)
		{
			achievementDefinition = definition;
			DuskAchievementHandler.UpdateUIElement(this, definition);
		}

		public void ResetAchievementProgress()
		{
			achievementDefinition.ResetProgress();
		}
	}
	public class AchievementUIGetCanvas : Singleton<AchievementUIGetCanvas>
	{
		private static readonly int SlideOut = Animator.StringToHash("SlideOut");

		[SerializeField]
		private GameObject _achievementGetUIElementPrefab;

		[SerializeField]
		private GameObject achievementContent;

		private Queue<DuskAchievementDefinition> achievementQueue = new Queue<DuskAchievementDefinition>();

		private void Start()
		{
			DuskAchievementHandler.OnAchievementUnlocked = (Action<DuskAchievementDefinition>)Delegate.Combine(DuskAchievementHandler.OnAchievementUnlocked, new Action<DuskAchievementDefinition>(QueuePopup));
		}

		protected override void OnDestroy()
		{
			DuskAchievementHandler.OnAchievementUnlocked = (Action<DuskAchievementDefinition>)Delegate.Remove(DuskAchievementHandler.OnAchievementUnlocked, new Action<DuskAchievementDefinition>(QueuePopup));
			base.OnDestroy();
		}

		internal void QueuePopup(DuskAchievementDefinition achievement)
		{
			achievementQueue.Enqueue(achievement);
			if (achievementContent.transform.childCount == 0)
			{
				((MonoBehaviour)this).StartCoroutine(ShowNextAchievement());
			}
		}

		private IEnumerator ShowNextAchievement()
		{
			while (achievementQueue.Count > 0)
			{
				DuskAchievementDefinition duskAchievementDefinition = achievementQueue.Dequeue();
				GameObject achievementElement = Object.Instantiate<GameObject>(_achievementGetUIElementPrefab, achievementContent.transform);
				AchievementUIElement component = achievementElement.GetComponent<AchievementUIElement>();
				component.SetupAchievementUI(duskAchievementDefinition);
				if ((Object)(object)duskAchievementDefinition.FinishAchievementAudioClip != (Object)null)
				{
					component.audioSource.clip = duskAchievementDefinition.FinishAchievementAudioClip;
				}
				component.audioSource.Play();
				yield return (object)new WaitForSeconds(duskAchievementDefinition.PopupTime);
				achievementElement.GetComponent<Animator>().SetTrigger(SlideOut);
				yield return (object)new WaitForSeconds(3f);
				Object.Destroy((Object)(object)achievementElement);
			}
		}
	}
	public abstract class DuskAchievementDefinition : DuskContentDefinition, INamespaced<DuskAchievementDefinition>, INamespaced
	{
		[SerializeField]
		private NamespacedKey<DuskAchievementDefinition> _typedKey;

		[field: SerializeField]
		public Sprite? AchievementIcon { get; private set; }

		[field: Space(10f)]
		[field: SerializeField]
		public string AchievementName { get; private set; }

		[field: SerializeField]
		public string AchievementDescription { get; private set; }

		[field: SerializeField]
		public TMP_ColorGradient? FinishedAchievementNameColorGradientPreset { get; private set; }

		[field: SerializeField]
		public TMP_ColorGradient? FinishedAchievementDescColorGradientPreset { get; private set; }

		[field: SerializeField]
		public Sprite? FinishedAchievementBackgroundIcon { get; private set; }

		[field: SerializeField]
		public AudioClip? FinishAchievementAudioClip { get; private set; }

		[field: Space(10f)]
		[field: SerializeField]
		public string AchievementRequirement { get; private set; }

		[field: SerializeField]
		public bool IsHidden { get; private set; }

		[field: SerializeField]
		public bool CanBeUnhidden { get; private set; }

		[field: SerializeField]
		public float PopupTime { get; private set; } = 5f;

		public bool Completed { get; protected set; }

		public NamespacedKey<DuskAchievementDefinition> TypedKey => _typedKey;

		public override NamespacedKey Key
		{
			get
			{
				return (NamespacedKey)(object)TypedKey;
			}
			protected set
			{
				_typedKey = value.AsTyped<DuskAchievementDefinition>();
			}
		}

		protected override string EntityNameReference => AchievementName;

		protected virtual AchievementSaveData GetSaveData()
		{
			return new AchievementSaveData(Completed);
		}

		protected virtual void LoadSaveData(AchievementSaveData saveData)
		{
			Completed = saveData.Completed;
		}

		public void LoadAchievementState(IDataContainer dataContainer)
		{
			LoadSaveData(dataContainer.GetOrSetDefault<AchievementSaveData>(Key, GetSaveData()));
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Loaded Achievement: {AchievementName} with value: {Completed}");
			}
		}

		public void SaveAchievementState(IDataContainer dataContainer)
		{
			dataContainer.Set<AchievementSaveData>(Key, GetSaveData());
			DebugLogSource achievements = Debuggers.Achievements;
			if (achievements != null)
			{
				achievements.Log((object)$"Saving Achievement: {AchievementName} with value: {Completed}");
			}
		}

		protected bool TryCompleteAchievement()
		{
			if (Completed)
			{
				return false;
			}
			Completed = true;
			DuskAchievementHandler.OnAchievementUnlocked?.Invoke(this);
			return Completed;
		}

		internal bool TryCompleteFromServer()
		{
			return TryCompleteAchievement();
		}

		public virtual void ResetProgress()
		{
			Completed = false;
			DuskAchievementHandler.SaveAll();
			DuskAchievementHandler.LoadAll();
			foreach (AchievementModUIElement achievementModUIElement in AchievementModUIElement.achievementModUIElements)
			{
				foreach (AchievementUIElement achievementsContainer in achievementModUIElement.achievementsContainerList)
				{
					DuskAchievementHandler.UpdateUIElement(achievementsContainer, achievementsContainer.achievementDefinition);
				}
			}
		}

		public void SoftResetProgress()
		{
			if (!Completed)
			{
				ResetProgress();
			}
		}

		public override void Register(DuskMod mod)
		{
			base.Register(mod);
			DuskModContent.Achievements.Register(this);
		}

		public virtual bool IsActive()
		{
			return true;
		}
	}
	public static class DuskAchievementExtensions
	{
		public static bool TryTriggerAchievement(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey)
		{
			DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition);
			if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition) && duskAchievementDefinition is DuskInstantAchievement duskInstantAchievement)
			{
				return duskInstantAchievement.TriggerAchievement();
			}
			return false;
		}

		public static bool TryIncrementAchievement(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey, float amount)
		{
			DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition);
			if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition) && duskAchievementDefinition is DuskStatAchievement duskStatAchievement)
			{
				return duskStatAchievement.IncrementProgress(amount);
			}
			return false;
		}

		public static bool TryDiscoverMoreProgressAchievement(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey, IEnumerable<string> uniqueStringIDs)
		{
			DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition);
			if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition) && duskAchievementDefinition is DuskDiscoveryAchievement duskDiscoveryAchievement)
			{
				return duskDiscoveryAchievement.TryDiscoverMoreProgress(uniqueStringIDs);
			}
			return false;
		}

		public static bool TryDiscoverMoreProgressAchievement(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey, string uniqueStringID)
		{
			DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition);
			if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition) && duskAchievementDefinition is DuskDiscoveryAchievement duskDiscoveryAchievement)
			{
				return duskDiscoveryAchievement.TryDiscoverMoreProgress(uniqueStringID);
			}
			return false;
		}

		public static void ResetAchievement(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey)
		{
			DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition);
			if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition))
			{
				duskAchievementDefinition.ResetProgress();
			}
		}

		public static void SoftResetAchievement(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey)
		{
			DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition);
			if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition))
			{
				duskAchievementDefinition.SoftResetProgress();
			}
		}
	}
	internal static class DuskAchievementHandler
	{
		public static Action<DuskAchievementDefinition>? OnAchievementUnlocked;

		internal static void LoadAll()
		{
			using (((DataContainer)DuskPlugin.PersistentData).CreateEditContext())
			{
				foreach (DuskAchievementDefinition value in DuskModContent.Achievements.Values)
				{
					value.LoadAchievementState((IDataContainer)(object)DuskPlugin.PersistentData);
				}
			}
		}

		internal static void SaveAll()
		{
			using (((DataContainer)DuskPlugin.PersistentData).CreateEditContext())
			{
				foreach (DuskAchievementDefinition value in DuskModContent.Achievements.Values)
				{
					value.SaveAchievementState((IDataContainer)(object)DuskPlugin.PersistentData);
				}
			}
		}

		internal static void UpdateUIElement(AchievementUIElement achievementUIElement, DuskAchievementDefinition achievementDefinition)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)achievementUIElement.achievementNameTMP).text = achievementDefinition.AchievementName;
			((TMP_Text)achievementUIElement.achievementDescriptionTMP).text = achievementDefinition.AchievementDescription;
			achievementUIElement.achievementIcon.sprite = achievementDefinition.AchievementIcon;
			((Selectable)achievementUIElement.achievementHiddenButton).interactable = false;
			if ((Object)(object)achievementUIElement.eventTrigger != (Object)null)
			{
				((Behaviour)achievementUIElement.eventTrigger).enabled = false;
			}
			if (achievementDefinition.CanBeUnhidden)
			{
				((Selectable)achievementUIElement.achievementHiddenButton).interactable = true;
				if ((Object)(object)achievementUIElement.eventTrigger != (Object)null)
				{
					((Behaviour)achievementUIElement.eventTrigger).enabled = true;
				}
			}
			if (!achievementDefinition.IsHidden || achievementDefinition.Completed)
			{
				if ((Object)(object)achievementUIElement.eventTrigger != (Object)null)
				{
					((Behaviour)achievementUIElement.eventTrigger).enabled = true;
				}
				((Selectable)achievementUIElement.achievementHiddenButton).interactable = true;
				((UnityEvent)achievementUIElement.achievementHiddenButton.onClick).Invoke();
			}
			if (!achievementDefinition.Completed)
			{
				((Graphic)achievementUIElement.achievementNameTMP).color = achievementUIElement.unfinishedAchievementColor;
				((Graphic)achievementUIElement.achievementDescriptionTMP).color = achievementUIElement.unfinishedAchievementColor;
				achievementUIElement.backgroundImage.sprite = null;
				((Graphic)achievementUIElement.backgroundImage).color = Color32.op_Implicit(new Color32((byte)0, (byte)0, (byte)0, (byte)107));
				((TMP_Text)achievementUIElement.achievementNameTMP).colorGradientPreset = null;
				((TMP_Text)achievementUIElement.achievementDescriptionTMP).colorGradientPreset = null;
			}
			else
			{
				if ((Object)(object)achievementDefinition.FinishedAchievementBackgroundIcon != (Object)null)
				{
					achievementUIElement.backgroundImage.sprite = achievementDefinition.FinishedAchievementBackgroundIcon;
					((Graphic)achievementUIElement.backgroundImage).color = Color.white;
				}
				((TMP_Text)achievementUIElement.achievementNameTMP).colorGradientPreset = achievementDefinition.FinishedAchievementNameColorGradientPreset;
				((TMP_Text)achievementUIElement.achievementDescriptionTMP).colorGradientPreset = achievementDefinition.FinishedAchievementDescColorGradientPreset;
			}
			IProgress val = (IProgress)(object)((achievementDefinition is IProgress) ? achievementDefinition : null);
			if (val != null)
			{
				DebugLogSource achievements = Debuggers.Achievements;
				if (achievements != null)
				{
					achievements.Log((object)$"Setting up progress achievement: {achievementDefinition.AchievementName} with percentage: {IProgressExtensions.Percentage(val)}");
				}
				achievementUIElement.progressBar.fillAmount = IProgressExtensions.Percentage(val);
				((TMP_Text)((Component)achievementUIElement.progressBar).GetComponentInChildren<TextMeshProUGUI>()).text = $"{val.CurrentProgress}/{val.MaxProgress}";
			}
			else
			{
				achievementUIElement.achievementProgressGO.SetActive(false);
			}
		}
	}
	[Serializable]
	public class DuskAchievementReference : DuskContentReference<DuskAchievementDefinition, DuskAchievementDefinition>
	{
		public DuskAchievementReference()
		{
		}

		public DuskAchievementReference(NamespacedKey<DuskAchievementDefinition> key)
			: base(key)
		{
		}

		public override bool TryResolve(out DuskAchievementDefinition info)
		{
			return DuskModContent.Achievements.TryGetValue(base.TypedKey, ref info);
		}

		public override DuskAchievementDefinition Resolve()
		{
			return DuskModContent.Achievements[base.TypedKey];
		}
	}
	[CreateAssetMenu(fileName = "New Discovery Achievement Definition", menuName = "DawnLib/Definitions/Achievements/Discovery Definition")]
	public class DuskDiscoveryAchievement : DuskAchievementDefinition, IProgress
	{
		public class DiscoverySaveData : AchievementSaveData
		{
			public List<string> CurrentlyCollectedUniqueStringIDs { get; }

			public DiscoverySaveData(bool completed, List<string> currentlyCollectedUniqueStringIDs)
			{
				CurrentlyCollectedUniqueStringIDs = currentlyCollectedUniqueStringIDs;
				base..ctor(completed);
			}
		}

		[Tooltip("Unique string ID for each discovery to account for progress.")]
		[field: SerializeField]
		public List<string> UniqueStringIDs { get; private set; }

		public List<string> CurrentlyCollectedUniqueStringIDs { get; private set; } = new List<string>();

		public float MaxProgress => UniqueStringIDs.Count;

		public float CurrentProgress => CurrentlyCollectedUniqueStringIDs.Count;

		protected override AchievementSaveData GetSaveData()
		{
			return new DiscoverySaveData(base.Completed, CurrentlyCollectedUniqueStringIDs);
		}

		protected override void LoadSaveData(AchievementSaveData saveData)
		{
			base.LoadSaveData(saveData);
			CurrentlyCollectedUniqueStringIDs = ((DiscoverySaveData)saveData).CurrentlyCollectedUniqueStringIDs;
		}

		public override void ResetProgress()
		{
			CurrentlyCollectedUniqueStringIDs.Clear();
			base.ResetProgress();
		}

		public bool TryDiscoverMoreProgress(string UniqueID)
		{
			if (CurrentlyCollectedUniqueStringIDs.Contains(UniqueID))
			{
				return false;
			}
			if (!UniqueStringIDs.Contains(UniqueID))
			{
				return false;
			}
			CurrentlyCollectedUniqueStringIDs.Add(UniqueID);
			if (CurrentProgress >= MaxProgress)
			{
				CurrentlyCollectedUniqueStringIDs = UniqueStringIDs;
				return TryCompleteAchievement();
			}
			return false;
		}

		public bool TryDiscoverMoreProgress(IEnumerable<string> UniqueID)
		{
			foreach (string item in UniqueID)
			{
				if (TryDiscoverMoreProgress(item))
				{
					return true;
				}
			}
			return false;
		}

		public void UndiscoverProgress(string UniqueID)
		{
			if (UniqueStringIDs.Contains(UniqueID))
			{
				CurrentlyCollectedUniqueStringIDs.Remove(UniqueID);
			}
		}

		public void UndiscoverProgress(IEnumerable<string> UniqueID)
		{
			foreach (string item in UniqueID)
			{
				UndiscoverProgress(item);
			}
		}

		public override void TryNetworkRegisterAssets()
		{
		}
	}
	[CreateAssetMenu(fileName = "New Instant Achievement Definition", menuName = "DawnLib/Definitions/Achievements/Instant Definition")]
	public class DuskInstantAchievement : DuskAchievementDefinition
	{
		[field: SerializeField]
		public bool SyncedCompletion { get; private set; }

		public bool TriggerAchievement()
		{
			if (SyncedCompletion)
			{
				NetworkSingleton<DuskNetworker>.Instance?.TriggerAchievementServerRpc(Key);
			}
			return TryCompleteAchievement();
		}

		public override void TryNetworkRegisterAssets()
		{
		}
	}
	[CreateAssetMenu(fileName = "New Parent Achievement Definition", menuName = "DawnLib/Definitions/Achievements/Parent Definition")]
	public class DuskParentAchievement : DuskAchievementDefinition, IProgress
	{
		[field: SerializeReference]
		[field: FormerlySerializedAs("ChildrenAchievementNames")]
		public List<DuskAchievementReference> ChildrenAchievementReferences { get; private set; } = new List<DuskAchievementReference>();

		public float MaxProgress => ChildrenAchievementReferences.Count;

		public float CurrentProgress => CountCompleted();

		public override void Register(DuskMod mod)
		{
			base.Register(mod);
			DuskAchievementHandler.OnAchievementUnlocked = (Action<DuskAchievementDefinition>)Delegate.Combine(DuskAchievementHandler.OnAchievementUnlocked, (Action<DuskAchievementDefinition>)delegate(DuskAchievementDefinition definition)
			{
				if (definition.Mod == mod && CountCompleted() >= ChildrenAchievementReferences.Count)
				{
					TryCompleteAchievement();
				}
			});
		}

		private int CountCompleted()
		{
			int num = 0;
			foreach (DuskAchievementDefinition value in DuskModContent.Achievements.Values)
			{
				if (!value.Completed)
				{
					continue;
				}
				foreach (DuskAchievementReference childrenAchievementReference in ChildrenAchievementReferences)
				{
					if (childrenAchievementReference.TryResolve(out DuskAchievementDefinition info) && info.AchievementName == value.AchievementName)
					{
						num++;
						break;
					}
				}
			}
			return num;
		}

		public override bool IsActive()
		{
			int num = 0;
			foreach (DuskAchievementReference childrenAchievementReference in ChildrenAchievementReferences)
			{
				if (childrenAchievementReference.TryResolve(out DuskAchievementDefinition info) && info.IsActive())
				{
					num++;
				}
			}
			return num == ChildrenAchievementReferences.Count;
		}

		public override void TryNetworkRegisterAssets()
		{
		}
	}
	[CreateAssetMenu(fileName = "New Stat Achievement Definition", menuName = "DawnLib/Definitions/Achievements/Stat Definition")]
	public class DuskStatAchievement : DuskAchievementDefinition, IProgress
	{
		public class StatSaveData : AchievementSaveData
		{
			public float CurrentProgress { get; }

			public StatSaveData(bool completed, float currentProgress)
			{
				CurrentProgress = currentProgress;
				base..ctor(completed);
			}
		}

		[field: SerializeField]
		public float MaxProgress { get; private set; }

		public float CurrentProgress { get; private set; }

		protected override AchievementSaveData GetSaveData()
		{
			return new StatSaveData(base.Completed, CurrentProgress);
		}

		protected override void LoadSaveData(AchievementSaveData saveData)
		{
			base.LoadSaveData(saveData);
			CurrentProgress = ((StatSaveData)saveData).CurrentProgress;
		}

		public override void ResetProgress()
		{
			CurrentProgress = 0f;
			base.ResetProgress();
		}

		public bool IncrementProgress(float amount)
		{
			CurrentProgress = Mathf.Max(0f, CurrentProgress + amount);
			if (CurrentProgress >= MaxProgress)
			{
				CurrentProgress = MaxProgress;
				return TryCompleteAchievement();
			}
			return false;
		}

		public void DecrementProgress(float amount)
		{
			CurrentProgress -= Mathf.Max(0f, amount);
			if (CurrentProgress <= 0f)
			{
				CurrentProgress = 0f;
			}
		}

		public override void TryNetworkRegisterAssets()
		{
		}
	}
	public class DungeonConfig : DuskBaseConfig
	{
		public ConfigEntry<string>? MoonSpawnWeights;

		public ConfigEntry<string>? WeatherSpawnWeights;

		public ConfigEntry<string>? RouteSpawnWeights;

		public ConfigEntry<BoundedRange>? DungeonRangeClamp;

		public ConfigEntry<int>? ExtraScrapGeneration;

		internal override List<ConfigEntryBase?> _configEntries => new List<ConfigEntryBase>(5)
		{
			(ConfigEntryBase)(object)MoonSpawnWeights,
			(ConfigEntryBase)(object)WeatherSpawnWeights,
			(ConfigEntryBase)(object)RouteSpawnWeights,
			(ConfigEntryBase)(object)DungeonRangeClamp,
			(ConfigEntryBase)(object)ExtraScrapGeneration
		};

		public DungeonConfig(ConfigContext section, string EntityNameReference)
			: base(section, EntityNameReference)
		{
		}
	}
	[CreateAssetMenu(fileName = "New Additional Tiles Definition", menuName = "DawnLib/Definitions/Additional Tiles Definition")]
	public class DuskAdditionalTilesDefinition : DuskContentDefinition<DawnTileSetInfo>
	{
		[Flags]
		public enum BranchCapSetting
		{
			Regular = 1,
			BranchCap = 2
		}

		[SerializeField]
		[UnlockedNamespacedKey]
		public List<NamespacedKey<DawnArchetypeInfo>> archetypeKeys = new List<NamespacedKey<DawnArchetypeInfo>>();

		[field: SerializeField]
		public TileSet TilesToAdd { get; private set; }

		[field: SerializeField]
		public BranchCapSetting BranchCap { get; private set; } = BranchCapSetting.Regular | BranchCapSetting.BranchCap;

		[field: SerializeField]
		public DuskPredicate? Predicate { get; private set; }

		protected override string EntityNameReference
		{
			get
			{
				TileSet tilesToAdd = TilesToAdd;
				return ((tilesToAdd != null) ? ((Object)tilesToAdd).name : null) ?? string.Empty;
			}
		}

		public override void Register(DuskMod mod)
		{
			base.Register(mod);
			DawnTileSetInfo tileSetInfo = DawnLib.DefineTileSet(base.TypedKey, TilesToAdd, (Action<TilesetInfoBuilder>)delegate(TilesetInfoBuilder builder)
			{
				ApplyTagsTo((BaseInfoBuilder)(object)builder);
				builder.SetIsRegular(BranchCap.HasFlag(BranchCapSetting.Regular));
				builder.SetIsBranchCap(BranchCap.HasFlag(BranchCapSetting.BranchCap));
				if ((Object)(object)Predicate != (Object)null)
				{
					builder.SetInjectionPredicate((IPredicate)(object)Predicate);
				}
			});
			tileSetInfo.SetupDetails();
			tileSetInfo.RegisterSpawnSyncedObjects();
			LethalContent.Archetypes.BeforeFreezeWithContext += delegate
			{
				DawnArchetypeInfo val = default(DawnArchetypeInfo);
				foreach (NamespacedKey<DawnArchetypeInfo> archetypeKey in archetypeKeys)
				{
					if (LethalContent.Archetypes.TryGetValue(archetypeKey, ref val))
					{
						val.AddTileSet(tileSetInfo);
					}
				}
			};
			((Registry<DawnDungeonInfo>)(object)LethalContent.Dungeons).OnFreezeWithContext += delegate
			{
				List<GameObject> list = new List<GameObject>();
				foreach (NetworkPrefab prefab in NetworkManager.Singleton.NetworkConfig.Prefabs.Prefabs)
				{
					list.Add(prefab.Prefab);
				}
				NetworkObject val = default(NetworkObject);
				foreach (SpawnSyncedObject spawnSyncedObject in tileSetInfo.SpawnSyncedObjects)
				{
					if ((Object)(object)spawnSyncedObject.spawnPrefab == (Object)null)
					{
						DuskPlugin.Logger.LogWarning((object)("SpawnSyncedObject.spawnPrefab is null in tileSet: " + (object)((DawnBaseInfo<DawnTileSetInfo>)(object)tileSetInfo).TypedKey));
					}
					else if (!spawnSyncedObject.spawnPrefab.TryGetComponent<NetworkObject>(ref val))
					{
						GameObject val2 = ((IEnumerable<GameObject>)list).FirstOrDefault((Func<GameObject, bool>)((GameObject potentialPrefab) => ((Object)potentialPrefab).name == ((Object)spawnSyncedObject.spawnPrefab).name));
						if ((Object)(object)val2 == (Object)null)
						{
							DuskPlugin.Logger.LogWarning((object)("SpawnSyncedObject's network prefab is missing in tileSet: " + ((object)((DawnBaseInfo<DawnTileSetInfo>)(object)tileSetInfo).TypedKey)?.ToString() + ", prefab: " + ((Object)spawnSyncedObject.spawnPrefab).name + ", spawner: " + ((Object)((Component)spawnSyncedObject).gameObject).name));
						}
						else
						{
							spawnSyncedObject.spawnPrefab = val2;
						}
					}
				}
			};
		}

		public override void TryNetworkRegisterAssets()
		{
			NetworkObject val = default(NetworkObject);
			foreach (GameObject item in TilesToAdd.TileWeights.Weights.Select((GameObjectChance x) => x.Value))
			{
				if (item.TryGetComponent<NetworkObject>(ref val))
				{
					DawnLib.RegisterNetworkPrefab(item);
				}
			}
		}
	}
	[Serializable]
	public class DuskAdditionalTilesReference : DuskContentReference<DuskAdditionalTilesDefinition, DawnTileSetInfo>
	{
		public DuskAdditionalTilesReference()
		{
		}

		public DuskAdditionalTilesReference(NamespacedKey<DawnTileSetInfo> key)
			: base(key)
		{
		}

		public override bool TryResolve(out DawnTileSetInfo info)
		{
			return LethalContent.TileSets.TryGetValue(base.TypedKey, ref info);
		}

		public override DawnTileSetInfo Resolve()
		{
			return LethalContent.TileSets[base.TypedKey];
		}
	}
	[CreateAssetMenu(fileName = "New Dungeon Definition", menuName = "DawnLib/Definitions/Dungeon Definition")]
	public class DuskDungeonDefinition : DuskContentDefinition<DawnDungeonInfo>
	{
		private IWeightModifierSource<int> _spawnWeightSource;

		[field: SerializeField]
		public DungeonFlowReference DungeonFlowReference { get; private set; }

		[field: SerializeField]
		public AudioClip? StingerAudio { get; private set; }

		[field: Space(5f)]
		[field: Header("Configs | Spawn Weights")]
		[field: SerializeField]
		public List<NamespacedConfigWeight> MoonSpawnWeightsConfig { get; private set; } = new List<NamespacedConfigWeight>();

		[field: SerializeField]
		public List<NamespacedConfigWeight> WeatherSpawnWeightsConfig { get; private set; } = new List<NamespacedConfigWeight>();

		[field: SerializeField]
		public List<IntComparisonConfigWeight> RouteSpawnWeightsConfig { get; private set; } = new List<IntComparisonConfigWeight>();

		[field: SerializeField]
		public bool GenerateSpawnWeightsConfig { get; private set; } = true;

		[field: Space(2f)]
		[field: Header("Configs | Generation")]
		[field: SerializeField]
		public int ExtraScrapGeneration { get; private set; }

		[field: SerializeField]
		public bool GenerateExtraScrapConfig { get; private set; } = true;

		[field: SerializeField]
		public bool GenerateClampConfig { get; private set; } = true;

		[field: Header("Configs | Misc")]
		[field: SerializeField]
		public BoundedRange DungeonRangeClamp { get; private set; } = new BoundedRange(0f, 999f);

		[field: SerializeField]
		public float MapTileSize { get; private set; } = 1f;

		[field: SerializeField]
		public bool StingerPlaysMoreThanOnce { get; private set; }

		[field: SerializeField]
		[field: Range(0f, 100f)]
		public float StingerPlayChance { get; private set; }

		public DungeonConfig Config { get; private set; }

		protected override string EntityNameReference => DungeonFlowReference?.FlowAssetName ?? string.Empty;

		public override void Register(DuskMod mod)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			base.Register(mod);
			if (DungeonRangeClamp.Min == 0f && DungeonRangeClamp.Max == 0f)
			{
				DungeonRangeClamp = new BoundedRange(0f, 999f);
			}
			using ConfigContext section = mod.ConfigManager.CreateConfigSectionForBundleData(AssetBundleData);
			Config = CreateDungeonConfig(section);
			base.BaseConfig = Config;
			_spawnWeightSource = DuskContentDefinition.CreateSpawnWeightSource(() => DuskContentDefinition.GetConfigWeights(Config.MoonSpawnWeights, MoonSpawnWeightsConfig), () => DuskContentDefinition.GetConfigWeights(null, new List<NamespacedConfigWeight>()), () => DuskContentDefinition.GetConfigWeights(Config.WeatherSpawnWeights, WeatherSpawnWeightsConfig), () => DuskContentDefinition.GetConfigWeights(Config.RouteSpawnWeights, RouteSpawnWeightsConfig), () => 0);
			DawnLib.DefineDungeon(base.TypedKey, DungeonFlowReference.FlowAssetName, (Action<DungeonFlowInfoBuilder>)delegate(DungeonFlowInfoBuilder builder)
			{
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Expected O, but got Unknown
				DungeonFlowReference.ArchetypeTileSetMapping[] archetypeTileSets = DungeonFlowReference.ArchetypeTileSets;
				foreach (DungeonFlowReference.ArchetypeTileSetMapping archetypeTileSetMapping in archetypeTileSets)
				{
					builder.SetArchetypeTileSetMapping(archetypeTileSetMapping.ArchetypeName, (IEnumerable<string>)archetypeTileSetMapping.TileSetNames);
				}
				builder.SetAssetBundlePath(mod.GetRelativePath("Assets", DungeonFlowReference.BundleName));
				builder.SetMapTileSize(MapTileSize);
				if ((Object)(object)StingerAudio != (Object)null)
				{
					builder.SetFirstTimeAudio(StingerAudio);
				}
				builder.OverrideStingerPlaysMoreThanOnce(StingerPlaysMoreThanOnce);
				builder.OverrideStingerPlayChance(StingerPlayChance);
				builder.SetDungeonRangeClamp(DungeonRangeClamp);
				builder.SetExtraScrapGeneration(ExtraScrapGeneration);
				builder.SetWeights((Action<WeightProfile<int>>)delegate(WeightProfile<int> weightProfile)
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					weightProfile.AddSource(_spawnWeightSource);
				});
				ApplyTagsTo((BaseInfoBuilder)(object)builder);
				((BaseInfoBuilder<DawnDungeonInfo, DungeonFlow, DungeonFlowInfoBuilder>)(object)builder).SetCustomData((IDataContainer)new PersistentDataContainer(Path.Combine(PersistentDataHandler.RootPath, "dungeon_" + ((NamespacedKey)base.TypedKey).Namespace + "_" + ((NamespacedKey)base.TypedKey).Key)));
				((BaseInfoBuilder<DawnDungeonInfo, DungeonFlow, DungeonFlowInfoBuilder>)(object)builder).EditCustomData((Action<IDataContainer>)delegate(IDataContainer customData)
				{
					if (!customData.Has<bool>(DawnKeys.StingerPlayed))
					{
						customData.Set<bool>(DawnKeys.StingerPlayed, false);
					}
				});
			});
		}

		public DungeonConfig CreateDungeonConfig(ConfigContext section)
		{
			DungeonConfig dungeonConfig = new DungeonConfig(section, EntityNameReference)
			{
				MoonSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Moon Weights", "Preset moon weights for " + EntityNameReference + ".", MoonSpawnWeightsConfig.ConvertManyToString()) : null),
				WeatherSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Weather Weights", "Preset weather weights for " + EntityNameReference + ".", WeatherSpawnWeightsConfig.ConvertManyToString()) : null),
				RouteSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Route Weights", "Preset route weights for " + EntityNameReference + ".", IntComparisonConfigWeight.ConvertManyToString(RouteSpawnWeightsConfig)) : null),
				ExtraScrapGeneration = (GenerateExtraScrapConfig ? section.Bind(EntityNameReference + " | Extra Scrap Generation", "Extra scrap generation for " + EntityNameReference + ".", ExtraScrapGeneration) : null),
				DungeonRangeClamp = (GenerateClampConfig ? section.Bind<BoundedRange>(EntityNameReference + " | Dungeon Range Clamp", "Dungeon range clamp for " + EntityNameReference + ".", DungeonRangeClamp) : null)
			};
			if (!dungeonConfig.UserAllowedToEdit())
			{
				DuskBaseConfig.AssignValueIfNotNull(dungeonConfig.MoonSpawnWeights, MoonSpawnWeightsConfig.ConvertManyToString());
				DuskBaseConfig.AssignValueIfNotNull(dungeonConfig.WeatherSpawnWeights, WeatherSpawnWeightsConfig.ConvertManyToString());
				DuskBaseConfig.AssignValueIfNotNull(dungeonConfig.RouteSpawnWeights, IntComparisonConfigWeight.ConvertManyToString(RouteSpawnWeightsConfig));
				DuskBaseConfig.AssignValueIfNotNull(dungeonConfig.ExtraScrapGeneration, ExtraScrapGeneration);
				DuskBaseConfig.AssignValueIfNotNull<BoundedRange>(dungeonConfig.DungeonRangeClamp, DungeonRangeClamp);
			}
			return dungeonConfig;
		}

		public override void TryNetworkRegisterAssets()
		{
		}
	}
	[Serializable]
	public class DuskDungeonReference : DuskContentReference<DuskDungeonDefinition, DawnDungeonInfo>
	{
		public DuskDungeonReference()
		{
		}

		public DuskDungeonReference(NamespacedKey<DawnDungeonInfo> key)
			: base(key)
		{
		}

		public override bool TryResolve(out DawnDungeonInfo info)
		{
			return ((Registry<DawnDungeonInfo>)(object)LethalContent.Dungeons).TryGetValue(base.TypedKey, ref info);
		}

		public override DawnDungeonInfo Resolve()
		{
			return ((Registry<DawnDungeonInfo>)(object)LethalContent.Dungeons)[base.TypedKey];
		}
	}
	public abstract class DuskContentDefinition : ScriptableObject
	{
		[FormerlySerializedAs("ConfigEntries")]
		[SerializeField]
		private List<DuskDynamicConfig> _configEntries = new List<DuskDynamicConfig>();

		[SerializeField]
		[UnlockedNamespacedKey]
		internal List<NamespacedKey> _tags = new List<NamespacedKey>();

		internal readonly Dictionary<string, ConfigEntryBase> generalConfigs = new Dictionary<string, ConfigEntryBase>();

		internal AssetBundleData AssetBundleData;

		public abstract NamespacedKey Key { get; protected set; }

		public DuskBaseConfig? BaseConfig { get; set; }

		public DuskMod Mod { get; private set; }

		protected abstract string EntityNameReference { get; }

		public virtual void Register(DuskMod mod)
		{
			if (AssetBundleData == null)
			{
				ManualLogSource? logger = mod.Logger;
				if (logger != null)
				{
					logger.LogError((object)("BUG! Tried to register " + ((Object)this).name + " without setting AssetBundleData?"));
				}
			}
			else
			{
				Mod = mod;
				TryNetworkRegisterAssets();
			}
		}

		public virtual void RegisterPost(DuskMod mod)
		{
			using ConfigContext context = mod.ConfigManager.CreateConfigSectionForBundleData(AssetBundleData);
			foreach (DuskDynamicConfig configEntry in _configEntries)
			{
				ConfigEntryBase value = mod.ConfigManager.CreateDynamicConfig(BaseConfig?.UserAllowedToEdit() ?? true, configEntry, context);
				generalConfigs[StringExtensions.CleanStringForConfig(configEntry.settingName)] = value;
			}
		}

		public void RegisterConfigs(DuskMod mod)
		{
			foreach (KeyValuePair<string, ConfigEntryBase> generalConfig in generalConfigs)
			{
				mod._configEntries.Add(generalConfig.Value);
			}
			if (BaseConfig != null)
			{
				mod._configEntries.AddRange(BaseConfig.ConfigEntries());
			}
		}

		public abstract void TryNetworkRegisterAssets();

		public string GetDefaultKey()
		{
			return NamespacedKey.NormalizeStringForNamespacedKey(EntityNameReference, false);
		}

		protected void ApplyTagsTo(BaseInfoBuilder builder)
		{
			builder.SoloAddTags((IEnumerable<NamespacedKey>)_tags);
		}

		public static IWeightModifierSource<int> CreateSpawnWeightSource(Func<IEnumerable<UnresolvedNamespacedWeight>> getMoons, Func<IEnumerable<UnresolvedNamespacedWeight>> getInteriors, Func<IEnumerable<UnresolvedNamespacedWeight>> getWeathers, Func<IEnumerable<IntComparisonConfigWeight>> getRoutes, Func<int> getDefaultWeight)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			return (IWeightModifierSource<int>)(object)new CompositeIntWeightSource().Add((IWeightModifierSource<int>)new MoonIntWeightSource(getMoons)).Add((IWeightModifierSource<int>)new MoonSceneIntWeightSource(getMoons)).Add((IWeightModifierSource<int>)new DungeonIntWeightSource(getInteriors))
				.Add((IWeightModifierSource<int>)new WeatherIntWeightSource(getWeathers))
				.Add((IWeightModifierSource<int>)(object)new RoutePriceIntWeightSource(getRoutes))
				.Add((IWeightModifierSource<int>)new GlobalBaseIntSource(getDefaultWeight));
		}

		public static IEnumerable<UnresolvedNamespacedWeight> GetConfigWeights(ConfigEntry<string>? spawnWeightsConfig, List<NamespacedConfigWeight> spawnWeightDefaults)
		{
			if (spawnWeightsConfig != null)
			{
				return UnresolvedNamespacedWeight.ConvertManyFromString(spawnWeightsConfig.Value);
			}
			return spawnWeightDefaults.ToUnresolvedWeights();
		}

		public static IEnumerable<IntComparisonConfigWeight> GetConfigWeights(ConfigEntry<string>? spawnWeightsConfig, List<IntComparisonConfigWeight> spawnWeightDefaults)
		{
			if (spawnWeightsConfig != null)
			{
				return IntComparisonConfigWeight.ConvertManyFromString(spawnWeightsConfig.Value);
			}
			return spawnWeightDefaults;
		}

		public static string CurvesToConfigString(IEnumerable<NamespacedKeyWithAnimationCurve> curves)
		{
			List<string> list = new List<string>();
			foreach (NamespacedKeyWithAnimationCurve curf in curves)
			{
				list.Add($"{curf.Key} - {ConfigManager.ParseString(curf.Curve)}");
			}
			return string.Join(" | ", list);
		}
	}
	public abstract class DuskContentDefinition<TInfo> : DuskContentDefinition where TInfo : INamespaced<TInfo>
	{
		public NamespacedKey<TInfo> TypedKey => Key.AsTyped<TInfo>();

		public override NamespacedKey Key { get; protected set; }
	}
	[Serializable]
	public abstract class DuskContentReference : INetworkSerializable
	{
		[SerializeField]
		internal string assetGUID;

		public abstract Type Type { get; }

		public abstract Type DefinitionType { get; }

		public abstract NamespacedKey Key { get; protected set; }

		public abstract void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter;
	}
	[Serializable]
	public abstract class DuskContentReference<TDef, TInfo> : DuskContentReference where TDef : DuskContentDefinition where TInfo : INamespaced<TInfo>
	{
		public NamespacedKey<TInfo> TypedKey => Key.AsTyped<TInfo>();

		public override NamespacedKey Key { get; protected set; }

		public override Type Type => typeof(TInfo);

		public override Type DefinitionType => typeof(TDef);

		public DuskContentReference()
		{
			Key = (NamespacedKey)(object)NamespacedKey<?>.From("", "");
		}

		protected DuskContentReference(NamespacedKey<TInfo> key)
		{
			Key = (NamespacedKey)(object)key;
		}

		public unsafe override void NetworkSerialize<T>(BufferSerializer<T> serializer)
		{
			NamespacedKey key = Key;
			((BufferSerializer<NamespacedKey>*)(&serializer))->SerializeNetworkSerializable<NamespacedKey>(ref key);
			Key = key;
		}

		public abstract bool TryResolve(out TInfo info);

		public abstract TInfo Resolve();
	}
	[Flags]
	public enum SpawnTable
	{
		Inside = 1,
		Outside = 2,
		Daytime = 4,
		Weed = 8
	}
	[CreateAssetMenu(fileName = "New Enemy Definition", menuName = "DawnLib/Definitions/Enemy Definition")]
	public class DuskEnemyDefinition : DuskContentDefinition<DawnEnemyInfo>
	{
		private IWeightModifierSource<int> _spawnWeightSource;

		[field: FormerlySerializedAs("enemyType")]
		[field: SerializeField]
		public EnemyType EnemyType { get; private set; }

		[field: SerializeField]
		public SpawnTable SpawnTable { get; private set; }

		[field: Header("Optional | Bestiary")]
		[field: TextArea(2, 20)]
		[field: SerializeField]
		public string BestiaryNodeText { get; private set; } = string.Empty;

		[field: SerializeField]
		public VideoClip BestiaryVideo { get; private set; }

		[field: SerializeField]
		public string BestiaryWordOverride { get; private set; } = string.Empty;

		[field: Space(10f)]
		[field: Header("Configs | Spawn Weights | Format: <Namespace>:<Key>=<Operation><Value>, i.e. magic_wesleys_mod:trite=+20")]
		[field: SerializeField]
		public List<NamespacedConfigWeight> MoonSpawnWeightsConfig { get; private set; } = new List<NamespacedConfigWeight>();

		[field: SerializeField]
		public List<NamespacedConfigWeight> InteriorSpawnWeightsConfig { get; private set; } = new List<NamespacedConfigWeight>();

		[field: SerializeField]
		public List<NamespacedConfigWeight> WeatherSpawnWeightsConfig { get; private set; } = new List<NamespacedConfigWeight>();

		[field: SerializeField]
		public List<IntComparisonConfigWeight> RouteSpawnWeightsConfig { get; private set; } = new List<IntComparisonConfigWeight>();

		[field: SerializeField]
		public bool GenerateSpawnWeightsConfig { get; private set; } = true;

		[field: SerializeField]
		public bool GeneratePowerLevelConfig { get; private set; } = true;

		[field: SerializeField]
		public bool GenerateMaxSpawnCountConfig { get; private set; } = true;

		public EnemyConfig Config { get; private set; }

		protected override string EntityNameReference => EnemyType?.enemyName ?? string.Empty;

		public override void Register(DuskMod mod)
		{
			base.Register(mod);
			using ConfigContext section = mod.ConfigManager.CreateConfigSectionForBundleData(AssetBundleData);
			Config = CreateEnemyConfig(section);
			base.BaseConfig = Config;
			if (GeneratePowerLevelConfig)
			{
				ConfigEntry<float> powerLevel = Config.PowerLevel;
				if (powerLevel != null)
				{
					EnemyType.PowerLevel = powerLevel.Value;
				}
			}
			if (GenerateMaxSpawnCountConfig)
			{
				ConfigEntry<int> maxSpawnCount = Config.MaxSpawnCount;
				if (maxSpawnCount != null)
				{
					EnemyType.MaxCount = maxSpawnCount.Value;
				}
			}
			_spawnWeightSource = DuskContentDefinition.CreateSpawnWeightSource(() => DuskContentDefinition.GetConfigWeights(Config.MoonSpawnWeights, MoonSpawnWeightsConfig), () => DuskContentDefinition.GetConfigWeights(Config.InteriorSpawnWeights, InteriorSpawnWeightsConfig), () => DuskContentDefinition.GetConfigWeights(Config.WeatherSpawnWeights, WeatherSpawnWeightsConfig), () => DuskContentDefinition.GetConfigWeights(Config.RouteSpawnWeights, RouteSpawnWeightsConfig), () => 0);
			DawnLib.DefineEnemy(base.TypedKey, EnemyType, (Action<EnemyInfoBuilder>)delegate(EnemyInfoBuilder builder)
			{
				if (SpawnTable.HasFlag(SpawnTable.Daytime))
				{
					builder.DefineDaytime((Action<EnemyLocationBuilder>)delegate(EnemyLocationBuilder daytimeBuilder)
					{
						daytimeBuilder.SetWeights((Action<WeightProfile<int>>)delegate(WeightProfile<int> weightProfile)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							weightProfile.AddSource(_spawnWeightSource);
						});
					});
				}
				if (SpawnTable.HasFlag(SpawnTable.Outside))
				{
					builder.DefineOutside((Action<EnemyLocationBuilder>)delegate(EnemyLocationBuilder outsideBuilder)
					{
						outsideBuilder.SetWeights((Action<WeightProfile<int>>)delegate(WeightProfile<int> weightProfile)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							weightProfile.AddSource(_spawnWeightSource);
						});
					});
				}
				if (SpawnTable.HasFlag(SpawnTable.Inside))
				{
					builder.DefineInside((Action<EnemyLocationBuilder>)delegate(EnemyLocationBuilder insideBuilder)
					{
						insideBuilder.SetWeights((Action<WeightProfile<int>>)delegate(WeightProfile<int> weightProfile)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							weightProfile.AddSource(_spawnWeightSource);
						});
					});
				}
				if (SpawnTable.HasFlag(SpawnTable.Weed))
				{
					builder.DefineWeed((Action<EnemyLocationBuilder>)delegate(EnemyLocationBuilder weedBuilder)
					{
						weedBuilder.SetWeights((Action<WeightProfile<int>>)delegate(WeightProfile<int> weightProfile)
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							weightProfile.AddSource(_spawnWeightSource);
						});
					});
				}
				if (!string.IsNullOrWhiteSpace(BestiaryNodeText))
				{
					builder.CreateBestiaryNode(BestiaryNodeText);
					builder.CreateNameKeyword(BestiaryWordOverride);
					builder.SetBestiaryVideo(BestiaryVideo);
				}
				ApplyTagsTo((BaseInfoBuilder)(object)builder);
			});
		}

		public EnemyConfig CreateEnemyConfig(ConfigContext section)
		{
			EnemyConfig enemyConfig = new EnemyConfig(section, EntityNameReference)
			{
				MoonSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Moon Weights", "Preset moon weights for " + EntityNameReference + ".", MoonSpawnWeightsConfig.ConvertManyToString()) : null),
				InteriorSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Interior Weights", "Preset interior weights for " + EntityNameReference + ".", InteriorSpawnWeightsConfig.ConvertManyToString()) : null),
				WeatherSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Weather Weights", "Preset weather weights for " + EntityNameReference + ".", WeatherSpawnWeightsConfig.ConvertManyToString()) : null),
				RouteSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Route Weights", "Preset route weights for " + EntityNameReference + ".", IntComparisonConfigWeight.ConvertManyToString(RouteSpawnWeightsConfig)) : null),
				PowerLevel = (GeneratePowerLevelConfig ? section.Bind(EntityNameReference + " | Power Level", "Power level for " + EntityNameReference + ".", EnemyType.PowerLevel) : null),
				MaxSpawnCount = (GenerateMaxSpawnCountConfig ? section.Bind(EntityNameReference + " | Max Spawn Count", "Max spawn count for " + EntityNameReference + ".", EnemyType.MaxCount) : null)
			};
			if (!enemyConfig.UserAllowedToEdit())
			{
				DuskBaseConfig.AssignValueIfNotNull(enemyConfig.MoonSpawnWeights, MoonSpawnWeightsConfig.ConvertManyToString());
				DuskBaseConfig.AssignValueIfNotNull(enemyConfig.InteriorSpawnWeights, InteriorSpawnWeightsConfig.ConvertManyToString());
				DuskBaseConfig.AssignValueIfNotNull(enemyConfig.WeatherSpawnWeights, WeatherSpawnWeightsConfig.ConvertManyToString());
				DuskBaseConfig.AssignValueIfNotNull(enemyConfig.RouteSpawnWeights, IntComparisonConfigWeight.ConvertManyToString(RouteSpawnWeightsConfig));
				DuskBaseConfig.AssignValueIfNotNull(enemyConfig.PowerLevel, EnemyType.PowerLevel);
				DuskBaseConfig.AssignValueIfNotNull(enemyConfig.MaxSpawnCount, EnemyType.MaxCount);
			}
			return enemyConfig;
		}

		public override void TryNetworkRegisterAssets()
		{
			NetworkObject val = default(NetworkObject);
			if (EnemyType.enemyPrefab.TryGetComponent<NetworkObject>(ref val))
			{
				DawnLib.RegisterNetworkPrefab(EnemyType.enemyPrefab);
			}
		}
	}
	[Serializable]
	public class DuskEnemyReference : DuskContentReference<DuskEnemyDefinition, DawnEnemyInfo>
	{
		public DuskEnemyReference()
		{
		}

		public DuskEnemyReference(NamespacedKey<DawnEnemyInfo> key)
			: base(key)
		{
		}

		public override bool TryResolve(out DawnEnemyInfo info)
		{
			return ((Registry<DawnEnemyInfo>)(object)LethalContent.Enemies).TryGetValue(base.TypedKey, ref info);
		}

		public override DawnEnemyInfo Resolve()
		{
			return ((Registry<DawnEnemyInfo>)(object)LethalContent.Enemies)[base.TypedKey];
		}
	}
	public class EnemyConfig : DuskBaseConfig
	{
		public ConfigEntry<string>? MoonSpawnWeights;

		public ConfigEntry<string>? InteriorSpawnWeights;

		public ConfigEntry<string>? WeatherSpawnWeights;

		public ConfigEntry<string>? RouteSpawnWeights;

		public ConfigEntry<float>? PowerLevel;

		public ConfigEntry<int>? MaxSpawnCount;

		internal override List<ConfigEntryBase?> _configEntries => new List<ConfigEntryBase>(6)
		{
			(ConfigEntryBase)(object)MoonSpawnWeights,
			(ConfigEntryBase)(object)InteriorSpawnWeights,
			(ConfigEntryBase)(object)WeatherSpawnWeights,
			(ConfigEntryBase)(object)RouteSpawnWeights,
			(ConfigEn

BepInEx/plugins/DawnLib/Compatibility~/com.github.teamxiaolan.dawnlib.compatibility.dll

Decompiled 7 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using loaforcsSoundAPI;
using loaforcsSoundAPI.SoundPacks.Data.Conditions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("XuXiaolan,loaforc")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+75bd30d5352a35f1657d9c13965f4155c465bcd3")]
[assembly: AssemblyProduct("DawnLib.Compatibility")]
[assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib.compatibility")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Dawn.Compatibility
{
	[BepInPlugin("com.github.teamxiaolan.dawnlib.compatibility", "DawnLib.Compatibility", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DawnCompatibilityPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			if (SoundAPICompat.Enabled)
			{
				SoundAPICompat.Init();
			}
			Logger.LogInfo((object)"com.github.teamxiaolan.dawnlib.compatibility v1.0.0 has loaded!");
		}
	}
	internal class DawnTaggableCondition(Func<ITaggable?> generator) : Condition()
	{
		private NamespacedKey? _key;

		public string Value { get; private set; }

		public override bool Evaluate(IContext context)
		{
			if (_key == null)
			{
				_key = NamespacedKey.ForceParse(Value);
			}
			ITaggable val = generator();
			if (val != null)
			{
				return val.HasTag(_key);
			}
			return false;
		}
	}
	internal static class SoundAPICompat
	{
		public static bool Enabled => Chainloader.PluginInfos.ContainsKey("me.loaforc.soundapi");

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		internal static void Init()
		{
			SoundAPI.RegisterCondition("DawnLib:moon:has_tag", (Func<Condition>)(() => (Condition)(object)new DawnTaggableCondition(() => (ITaggable?)(object)((!Object.op_Implicit((Object)(object)StartOfRound.Instance)) ? null : SelectableLevelExtensions[StartOfRound.Instance.currentLevel]))));
			SoundAPI.RegisterCondition("DawnLib:dungeon:has_tag", (Func<Condition>)(() => (Condition)(object)new DawnTaggableCondition(delegate
			{
				if (!Object.op_Implicit((Object)(object)RoundManager.Instance))
				{
					return (ITaggable?)null;
				}
				return (ITaggable?)(object)((!Object.op_Implicit((Object)(object)RoundManager.Instance.dungeonGenerator)) ? null : DungeonFlowExtensions[RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow]);
			})));
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.teamxiaolan.dawnlib.compatibility";

		public const string PLUGIN_NAME = "DawnLib.Compatibility";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}