Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DawnLibExperimental v1.0.0
BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.core.dll
Decompiled 7 hours agousing 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
The result has been truncated due to the large size, download it to view full contents!
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
The result has been truncated due to the large size, download it to view full contents!
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 agousing 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"; } }