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 DawnLib v0.9.12
BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.dll
Decompiled 4 days 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.Adapters; using DunGen.Graph; using DunGenPlus; using GameNetcodeStuff; using GoodItemScan; using HarmonyLib; using IL; using IL.GameNetcodeStuff; 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.TMPro; using On.Unity.Netcode; using PathfindingLib.API.SmartPathfinding; using Steamworks; 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.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.Serialization; using UnityEngine.UI; using WeatherRegistry; using com.github.teamxiaolan.dawnlib.NetcodePatcher; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [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("0.9.12.0")] [assembly: AssemblyInformationalVersion("0.9.12+f11bddf4b9fdcd9f76adee794e9e867ff12f8841")] [assembly: AssemblyProduct("DawnLib")] [assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.12.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(); } } [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] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } 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 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 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; } [Serializable] public class NamespacedKey : INetworkSerializable { private static readonly Regex NamespacedKeyRegex = new Regex("[?!.\\n\\t\"`\\[\\]'-]"); private static readonly Dictionary<string, NamespacedKey> CanonicalByFull = new Dictionary<string, NamespacedKey>(StringComparer.Ordinal); private static readonly Dictionary<string, NamespacedKey> CanonicalByKey = new Dictionary<string, NamespacedKey>(StringComparer.Ordinal); private static readonly Dictionary<string, List<NamespacedKey>> SmartPlaceholdersByKey = new Dictionary<string, List<NamespacedKey>>(StringComparer.Ordinal); 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"; public const string SmartMatchingNamespace = "smart_matching"; [SerializeField] private string _namespace; [SerializeField] private string _key; public string Namespace => _namespace; public string Key => _key; public ulong NetworkID => ComputeStableHash64(ToString()); private static void PromoteSmartPlaceholders(string key, string newNamespace) { if (!SmartPlaceholdersByKey.TryGetValue(key, out List<NamespacedKey> value) || value.Count == 0) { return; } foreach (NamespacedKey item in value) { if (item._namespace == "smart_matching") { Debuggers.NamespacedKeys?.Log($"Promoting placeholder {item} to {newNamespace}"); item._namespace = newNamespace; } } } 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(" ", "_"); } private static string BuildFullKey(string @namespace, string key) { return $"{@namespace}{':'}{key}"; } private static bool ShouldReplaceCandidate(NamespacedKey existing, NamespacedKey candidate) { if (existing.Namespace == "smart_matching" && candidate.Namespace != "smart_matching") { return true; } if (candidate.Namespace == "lethal_company" && existing.Namespace != "lethal_company") { return true; } return false; } private static void Register(NamespacedKey key) { string key2 = BuildFullKey(key.Namespace, key.Key); CanonicalByFull.TryAdd(key2, key); NamespacedKey value2; if (key.Namespace == "smart_matching") { if (!SmartPlaceholdersByKey.TryGetValue(key.Key, out List<NamespacedKey> value)) { value = new List<NamespacedKey>(); SmartPlaceholdersByKey[key.Key] = value; } value.Add(key); if (!CanonicalByKey.ContainsKey(key.Key)) { CanonicalByKey[key.Key] = key; } } else if (CanonicalByKey.TryGetValue(key.Key, out value2)) { if (ShouldReplaceCandidate(value2, key)) { CanonicalByKey[key.Key] = key; PromoteSmartPlaceholders(key.Key, key.Namespace); } } else { CanonicalByKey[key.Key] = key; PromoteSmartPlaceholders(key.Key, key.Namespace); } } private static bool TrySmartResolveByKey(string normalizedKey, [NotNullWhen(true)] out NamespacedKey? match) { match = null; if (CanonicalByKey.TryGetValue(normalizedKey, out NamespacedKey value)) { match = value; return true; } return false; } protected NamespacedKey(string @namespace, string key) { _namespace = NormalizeStringForNamespacedKey(@namespace, CSharpName: false); _key = NormalizeStringForNamespacedKey(key, CSharpName: false); Register(this); } [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) { return ForceParse(input, useSmartMatching: false); } public static NamespacedKey ForceParse(string input, bool useSmartMatching) { 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 text = NormalizeStringForNamespacedKey(input2, CSharpName: false); if (useSmartMatching) { if (TrySmartResolveByKey(text, out NamespacedKey match)) { return match; } return From("smart_matching", text); } return From("lethal_company", text); } public override string ToString() { return BuildFullKey(Namespace, Key); } public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter { serializer.SerializeValue(ref _namespace, false); serializer.SerializeValue(ref _key, false); } public override bool Equals(object? obj) { if (this == obj) { return true; } if (!(obj is NamespacedKey namespacedKey)) { return false; } if (string.Equals(Namespace, namespacedKey.Namespace, StringComparison.Ordinal)) { return string.Equals(Key, namespacedKey.Key, StringComparison.Ordinal); } 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() { int num = 13; num = num * 17 + (Namespace?.GetHashCode() ?? 0); return num * 17 + (Key?.GetHashCode() ?? 0); } 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 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 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 ((object)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 { FileStream stream = new FileStream(_filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true); try { StreamWriter writer = new StreamWriter(stream, Encoding.UTF8); try { 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) + ")"); } finally { if (writer != null) { await writer.DisposeAsync(); } } } finally { if (stream != null) { await stream.DisposeAsync(); } } } 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 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 prefab) { if (!Object.op_Implicit((Object)(object)prefab)) { throw new ArgumentNullException("prefab"); } MiscFixesPatch.tilesToFixSockets.Add(prefab); } 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 DawnSurfaceInfo DefineSurface(NamespacedKey<DawnSurfaceInfo> key, FootstepSurface surface, Action<SurfaceInfoBuilder> callback) { SurfaceInfoBuilder surfaceInfoBuilder = new SurfaceInfoBuilder(key, surface); callback(surfaceInfoBuilder); DawnSurfaceInfo dawnSurfaceInfo = surfaceInfoBuilder.Build(); surface.SetDawnInfo(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.TypedKey; 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(); val.SetDawnInfo(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(); tileSet.SetDawnInfo(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(); DawnMapObjectNamespacedKeyContainer dawnMapObjectNamespacedKeyContainer = mapObject.AddComponent<DawnMapObjectNamespacedKeyContainer>(); dawnMapObjectNamespacedKeyContainer.Value = dawnMapObjectInfo.Key; if (dawnMapObjectInfo.InsideInfo != null) { dawnMapObjectInfo.InsideInfo.IndoorMapHazardType.SetDawnInfo(dawnMapObjectInfo); } if (dawnMapObjectInfo.OutsideInfo != null) { dawnMapObjectInfo.OutsideInfo.SpawnableOutsideObject.SetDawnInfo(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(); unlockableItem.SetDawnInfo(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(); item.SetDawnInfo(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(); enemy.SetDawnInfo(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(); level.SetDawnInfo(dawnMoonInfo); LethalContent.Moons.Register(dawnMoonInfo); return dawnMoonInfo; } public static void ApplyTag(JSONTagDefinition definition) { JSONTagDefinition definition2 = definition; NamespacedKey namespacedKey2 = NamespacedKey.Parse(definition2.Tag); ListenToRegistry<DawnMoonInfo>(LethalContent.Moons, namespacedKey2); ListenToRegistry<DawnMapObjectInfo>(LethalContent.MapObjects, namespacedKey2); ListenToRegistry<DawnEnemyInfo>(LethalContent.Enemies, namespacedKey2); ListenToRegistry<DawnItemInfo>(LethalContent.Items, namespacedKey2); ListenToRegistry<DawnWeatherEffectInfo>(LethalContent.Weathers, namespacedKey2); ListenToRegistry<DawnDungeonInfo>(LethalContent.Dungeons, namespacedKey2); ListenToRegistry<DawnUnlockableItemInfo>(LethalContent.Unlockables, namespacedKey2); Debuggers.Tags?.Log($"Scheduled applying tag: {namespacedKey2}"); void ListenToRegistry<T>(TaggedRegistry<T> registry, NamespacedKey namespacedKey) where T : notnull, DawnBaseInfo<T> { TaggedRegistry<T> registry2 = registry; NamespacedKey namespacedKey3 = namespacedKey; registry2.OnFreeze += delegate { string[] values = definition2.Values; foreach (string input in values) { if (registry2.TryGetValue(NamespacedKey.Parse(input), out var value)) { value.Internal_AddTag(namespacedKey3); } } }; } } 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; } } [HarmonyPatch] internal static class DungeonRegistrationHandler { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__RegisterDawnDungeons; public static hook_OnClientDisconnect <1>__StartOfRoundOnClientDisconnect; public static Action<Action<RandomMapObject>, RandomMapObject> <2>__FixRandomMapObjects; public static Action <3>__AddDawnDungeonsToMoons; public static Action <4>__CollectNonDawnDungeons; public static hook_SetPlanetsWeather <5>__UpdateAllDungeonWeights; public static hook_EndOfGame <6>__UnloadDungeonBundleForAllPlayers; public static hook_Awake <7>__DeleteLLLTranspilerAndEnsureDelayedDungeon; public static Manipulator <8>__MakeExtraScrapGenerationMoreModular; public static Action <9>__CleanDawnDungeonReferences; public static hook_TeleportPlayer <10>__HandleStingerAudio; public static Manipulator <11>__DelayDungeonGeneration; public static Func<IEnumerator> <12>__LoadDungeonBundle; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_GenerateNewFloor <>9__0_0; public static hook_Start <>9__0_1; public static hook_Generate <>9__0_2; public static Func<Instruction, bool> <>9__3_0; public static Func<Instruction, bool> <>9__3_1; public static Func<Instruction, bool> <>9__3_2; public static Func<Instruction, bool> <>9__3_3; public static Func<Instruction, bool> <>9__3_4; public static Func<Instruction, bool> <>9__3_5; public static Func<Instruction, bool> <>9__3_6; public static Func<Instruction, bool> <>9__3_7; public static Func<Instruction, bool> <>9__11_0; public static Func<Instruction, bool> <>9__11_1; public static Func<Instruction, bool> <>9__11_2; public static Func<bool> <>9__13_0; public static Func<EntranceTeleport, bool> <>9__15_0; public static Func<GlobalPropSettings, bool> <>9__15_1; public static Func<IndoorMapType, DungeonFlow> <>9__18_0; public static Func<bool> <>9__20_0; internal void <Init>b__0_0(orig_GenerateNewFloor orig, RoundManager self) { UpdateDungeonWeightOnLevel(self.currentLevel); orig.Invoke(self); } internal void <Init>b__0_1(orig_Start orig, RuntimeDungeon self) { self.GenerateOnStart = false; orig.Invoke(self); } internal void <Init>b__0_2(orig_Generate orig, RuntimeDungeon self) { AdjustFireExits(self.Generator.DungeonFlow); TryInjectTileSets(self.Generator.DungeonFlow); orig.Invoke(self); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_0(Instruction instr) { return ILPatternMatchingExt.MatchLdarg(instr, 0); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_1(Instruction instr) { return ILPatternMatchingExt.MatchLdfld<RoundManager>(instr, "currentDungeonType"); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_2(Instruction instr) { return ILPatternMatchingExt.MatchLdcI4(instr, 4); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_3(Instruction instr) { ILLabel val = default(ILLabel); return ILPatternMatchingExt.MatchBneUn(instr, ref val); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_4(Instruction instr) { return ILPatternMatchingExt.MatchLdloc(instr, 1); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_5(Instruction instr) { return ILPatternMatchingExt.MatchLdcI4(instr, 6); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_6(Instruction instr) { return ILPatternMatchingExt.MatchAdd(instr); } internal bool <MakeExtraScrapGenerationMoreModular>b__3_7(Instruction instr) { return ILPatternMatchingExt.MatchStloc(instr, 1); } internal bool <DelayDungeonGeneration>b__11_0(Instruction i) { return ILPatternMatchingExt.MatchLdarg(i, 0); } internal bool <DelayDungeonGeneration>b__11_1(Instruction i) { return ILPatternMatchingExt.MatchLdfld<RoundManager>(i, "dungeonGenerator"); } internal bool <DelayDungeonGeneration>b__11_2(Instruction i) { return ILPatternMatchingExt.MatchCallvirt<RuntimeDungeon>(i, "Generate"); } internal bool <LoadDungeonBundle>b__13_0() { return NetworkSingleton<DawnDungeonNetworker>.Instance.allPlayersDone; } internal bool <AdjustFireExits>b__15_0(EntranceTeleport e) { return e.entranceId != 0; } internal bool <AdjustFireExits>b__15_1(GlobalPropSettings p) { return p.ID == DawnDungeonInfo.FireExitGlobalPropID; } internal DungeonFlow <AddDawnDungeonsToMoons>b__18_0(IndoorMapType t) { return t.dungeonFlow; } internal bool <CollectNonDawnDungeons>b__20_0() { return true; } } [CompilerGenerated] private sealed class <LoadDungeonBundle>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private DawnDungeonInfo <dungeonInfo>5__2; private IEnumerator <waitForLoad>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadDungeonBundle>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <dungeonInfo>5__2 = null; <waitForLoad>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <dungeonInfo>5__2 = RoundManager.Instance.dungeonGenerator.Generator.DungeonFlow.GetDawnInfo(); if (!<dungeonInfo>5__2.ShouldSkipIgnoreOverride()) { NetworkSingleton<DawnDungeonNetworker>.Instance.QueueDungeonBundleLoading(<dungeonInfo>5__2.Key); <waitForLoad>5__3 = (IEnumerator)new WaitUntil((Func<bool>)(() => NetworkSingleton<DawnDungeonNetworker>.Instance.allPlayersDone)); goto IL_00b0; } goto IL_00c4; case 1: <>1__state = -1; goto IL_00b0; case 2: { <>1__state = -1; if (LethalLevelLoaderCompat.Enabled && <dungeonInfo>5__2.ShouldSkipRespectOverride()) { LethalLevelLoaderCompat.LetLLLHandleGeneration(); } else { BoundedRange boundedRange = <dungeonInfo>5__2.DungeonClampRange; if (<dungeonInfo>5__2.DungeonClampRange.Min == 0f && <dungeonInfo>5__2.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(); } return false; } IL_00b0: if (<waitForLoad>5__3.MoveNext()) { <>2__current = <waitForLoad>5__3.Current; <>1__state = 1; return true; } <waitForLoad>5__3 = null; goto IL_00c4; IL_00c4: <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <UnloadDungeonBundleForAllPlayers>d__12 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public orig_EndOfGame orig; public StartOfRound self; public int bodiesInsured; public int connectedPlayersOnServer; public int scrapCollected; private IEnumerator <origIEnumerator>5__2; private IEnumerator <unloadIEnumerator>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <UnloadDungeonBundleForAllPlayers>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <origIEnumerator>5__2 = null; <unloadIEnumerator>5__3 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)NetworkSingleton<DawnDungeonNetworker>.Instance != (Object)null) { <unloadIEnumerator>5__3 = NetworkSingleton<DawnDungeonNetworker>.Instance.UnloadExisting(); goto IL_0062; } if (!DawnConfig.VanillaCompatibility.Value) { DawnPlugin.Logger.LogError((object)"DawnDungeonNetworker is null, but VanillaCompatibility is false! This is a bug!"); } goto IL_00ad; case 1: <>1__state = -1; goto IL_0062; case 2: { <>1__state = -1; break; } IL_0062: if (<unloadIEnumerator>5__3.MoveNext()) { <>2__current = <unloadIEnumerator>5__3.Current; <>1__state = 1; return true; } NetworkSingleton<DawnDungeonNetworker>.Instance.PlayerSetBundleStateServerRpc(GameNetworkManager.Instance.localPlayerController, DawnMoonNetworker.BundleState.Done); <unloadIEnumerator>5__3 = null; goto IL_00ad; IL_00ad: <origIEnumerator>5__2 = orig.Invoke(self, bodiesInsured, connectedPlayersOnServer, scrapCollected); break; } if (<origIEnumerator>5__2.MoveNext()) { <>2__current = <origIEnumerator>5__2.Current; <>1__state = 2; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly NamespacedKey StingerPlayedKey = NamespacedKey.From("dawn_lib", "played_stinger_once_before"); 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0168: 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_0173: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0224: 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(); } object obj2 = <>O.<1>__StartOfRoundOnClientDisconnect; if (obj2 == null) { hook_OnClientDisconnect val3 = StartOfRoundOnClientDisconnect; <>O.<1>__StartOfRoundOnClientDisconnect = val3; obj2 = (object)val3; } StartOfRound.OnClientDisconnect += (hook_OnClientDisconnect)obj2; DetourContext val4 = 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)val4)?.Dispose(); } LethalContent.Moons.OnFreeze += AddDawnDungeonsToMoons; LethalContent.Moons.OnFreeze += CollectNonDawnDungeons; object obj3 = <>O.<5>__UpdateAllDungeonWeights; if (obj3 == null) { hook_SetPlanetsWeather val5 = UpdateAllDungeonWeights; <>O.<5>__UpdateAllDungeonWeights = val5; obj3 = (object)val5; } StartOfRound.SetPlanetsWeather += (hook_SetPlanetsWeather)obj3; object obj4 = <>O.<6>__UnloadDungeonBundleForAllPlayers; if (obj4 == null) { hook_EndOfGame val6 = UnloadDungeonBundleForAllPlayers; <>O.<6>__UnloadDungeonBundleForAllPlayers = val6; obj4 = (object)val6; } StartOfRound.EndOfGame += (hook_EndOfGame)obj4; object obj5 = <>O.<7>__DeleteLLLTranspilerAndEnsureDelayedDungeon; if (obj5 == null) { hook_Awake val7 = DeleteLLLTranspilerAndEnsureDelayedDungeon; <>O.<7>__DeleteLLLTranspilerAndEnsureDelayedDungeon = val7; obj5 = (object)val7; } MenuManager.Awake += (hook_Awake)obj5; object obj6 = <>O.<8>__MakeExtraScrapGenerationMoreModular; if (obj6 == null) { Manipulator val8 = MakeExtraScrapGenerationMoreModular; <>O.<8>__MakeExtraScrapGenerationMoreModular = val8; obj6 = (object)val8; } RoundManager.SpawnScrapInLevel += (Manipulator)obj6; object obj7 = <>c.<>9__0_0; if (obj7 == null) { hook_GenerateNewFloor val9 = delegate(orig_GenerateNewFloor orig, RoundManager self) { UpdateDungeonWeightOnLevel(self.currentLevel); orig.Invoke(self); }; <>c.<>9__0_0 = val9; obj7 = (object)val9; } RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj7; LethalContent.Dungeons.BeforeFreeze += CleanDawnDungeonReferences; object obj8 = <>O.<10>__HandleStingerAudio; if (obj8 == null) { hook_TeleportPlayer val10 = HandleStingerAudio; <>O.<10>__HandleStingerAudio = val10; obj8 = (object)val10; } EntranceTeleport.TeleportPlayer += (hook_TeleportPlayer)obj8; object obj9 = <>c.<>9__0_1; if (obj9 == null) { hook_Start val11 = delegate(orig_Start orig, RuntimeDungeon self) { self.GenerateOnStart = false; orig.Invoke(self); }; <>c.<>9__0_1 = val11; obj9 = (object)val11; } RuntimeDungeon.Start += (hook_Start)obj9; object obj10 = <>c.<>9__0_2; 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_2 = val12; obj10 = (object)val12; } RuntimeDungeon.Generate += (hook_Generate)obj10; } [HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")] [HarmonyPrefix] [HarmonyPriority(100)] internal static void GenerateNewLevelClientRpc_Prefix(RoundManager __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if ((int)((NetworkBehaviour)__instance).__rpc_exec_stage == 0) { RestoreRuntimeDungeon(); } } private static void RestoreRuntimeDungeon() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.FindGameObjectWithTag("DungeonGenerator"); RuntimeDungeon val2 = default(RuntimeDungeon); if (!val.TryGetComponent<RuntimeDungeon>(ref val2)) { RuntimeDungeon val3 = val.AddComponent<RuntimeDungeon>(); UnityNavMeshAdapter val4 = ((Component)val3).gameObject.AddComponent<UnityNavMeshAdapter>(); Transform child = ((Component)val3).transform.GetParent().GetChild(1); if (!((Object)(object)child == (Object)null)) { val3.Root = ((Component)child).gameObject; val4.BakeMode = (RuntimeNavMeshBakeMode)3; val4.LayerMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[4] { "Default", "Room", "Colliders", "NavigationSurface" })); DungeonGenerator generator = val3.Generator; generator.AllowTilePooling = true; generator.GenerateAsynchronously = true; } } } 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 (RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow?.GetDawnInfo())?.ExtraScrapGeneration ?? 0; } private static void HandleStingerAudio(orig_TeleportPlayer orig, EntranceTeleport self) { if (!self.checkedForFirstTime) { self.checkedForFirstTime = true; DawnDungeonInfo dawnDungeonInfo = RoundManager.Instance.dungeonGenerator?.Generator?.DungeonFlow.GetDawnInfo(); if (dawnDungeonInfo == null || (Object)(object)dawnDungeonInfo.StingerDetail.FirstTimeAudio == (Object)null) { orig.Invoke(self); return; } if (!dawnDungeonInfo.StingerDetail.AllowStingerToPlay.Provide()) { orig.Invoke(self); return; } if (!dawnDungeonInfo.CustomData.TryGet<bool>(StingerPlayedKey, out var value)) { DawnPlugin.Logger.LogError((object)$"Failed to get {StingerPlayedKey} from dungeon: {dawnDungeonInfo.Key}."); orig.Invoke(self); return; } if (value && !dawnDungeonInfo.StingerDetail.PlaysMoreThanOnce) { orig.Invoke(self); return; } float num = Random.Range(0f, 100f); if (num > dawnDungeonInfo.StingerDetail.PlayChance) { orig.Invoke(self); return; } Debuggers.Dungeons?.Log($"Playing dungeon stinger for dungeon {dawnDungeonInfo.Key}, alreadyPlayed: {value} (Chance Roll: {num} <= {dawnDungeonInfo.StingerDetail.PlayChance})"); dawnDungeonInfo.CustomData.Set(StingerPlayedKey, 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.<11>__DelayDungeonGeneration; if (obj == null) { Manipulator val = DelayDungeonGeneration; <>O.<11>__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()); } } [IteratorStateMachine(typeof(<UnloadDungeonBundleForAllPlayers>d__12))] private static IEnumerator UnloadDungeonBundleForAllPlayers(orig_EndOfGame orig, StartOfRound self, int bodiesInsured, int connectedPlayersOnServer, int scrapCollected) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <UnloadDungeonBundleForAllPlayers>d__12(0) { orig = orig, self = self, bodiesInsured = bodiesInsured, connectedPlayersOnServer = connectedPlayersOnServer, scrapCollected = scrapCollected }; } [IteratorStateMachine(typeof(<LoadDungeonBundle>d__13))] private static IEnumerator LoadDungeonBundle() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadDungeonBundle>d__13(0); } private static void StartOfRoundOnClientDisconnect(orig_OnClientDisconnect orig, StartOfRound self, ulong clientid) { orig.Invoke(self, clientid); if (((NetworkBehaviour)self).IsServer && self.inShipPhase) { NetworkSingleton<DawnDungeonNetworker>.Instance?.HostRebroadcastQueue(); } } private static void AdjustFireExits(DungeonFlow dungeonFlow) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown EntranceTeleport[] array = (from e in Object.FindObjectsByType<EntranceTeleport>((FindObjectsInactive)0, (FindObjectsSortMode)0) where e.entranceId != 0 select e).ToArray(); for (int i = 0; i < array.Length; i++) { EntranceTeleport val = array[i]; val.entranceId = i + 1; } foreach (GlobalPropSettings item in dungeonFlow.GlobalProps.Where((GlobalPropSettings p) => p.ID == DawnDungeonInfo.FireExitGlobalPropID)) { 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) { 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 dawnInfo = RoundManagerRefs.Instance.dungeonFlowTypes[val.id].dungeonFlow.GetDawnInfo(); if (!dawnInfo.ShouldSkipRespectOverride()) { SpawnWeightContext ctx = new SpawnWeightContext(level.GetDawnInfo(), null, TimeOfDayRefs.GetCurrentWeatherEffect(level)?.GetDawnInfo()).WithExtra(SpawnWeightExtraKeys.RoutingPriceKey, level.GetDawnInfo().DawnPurchaseInfo.Cost.Provide()); int valueOrDefault = (dawnInfo.Weights?.GetFor(in ctx)).GetValueOrDefault(); val.rarity = valueOrDefault.Clamp0(); } } } 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() { Dictionary<string, WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>> dictionary = new Dictionary<string, WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>>(); foreach (DawnMoonInfo value3 in LethalContent.Moons.Values) { SelectableLevel level = value3.Level; List<IntWithRarity> list = level.dungeonFlowTypes.ToList(); if (LethalLevelLoaderCompat.Enabled) { list.AddRange(LethalLevelLoaderCompat.GetCustomDungeonsWithRarities(level)); } foreach (IntWithRarity item in list) { DungeonFlow dungeonFlow = RoundManagerRefs.Instance.dungeonFlowTypes[item.id].dungeonFlow; if (!dictionary.TryGetValue(((Object)dungeonFlow).name, out var value)) { value = new WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>(); dictionary[((Object)dungeonFlow).name] = value; } Debuggers.Dungeons?.Log($"Grabbing weight {item.rarity} to {((Object)dungeonFlow).name} on level {level.PlanetName}"); value.AddWeight(value3.TypedKey, item.rarity); } } IndoorMapType[] dungeonFlowTypes = RoundManagerRefs.Instance.dungeonFlowTypes; foreach (IndoorMapType val in dungeonFlowTypes) { if (val == null || (Object)(object)val.dungeonFlow == (Object)null || val.dungeonFlow.HasDawnInfo()) { 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}"); val.dungeonFlow.SetDawnInfo(LethalContent.Dungeons[namespacedKey]); continue; } HashSet<NamespacedKey> tags = new HashSet<NamespacedKey> { DawnLibTags.IsExternal }; CollectLLLTags(val.dungeonFlow, tags); dictionary.TryGetValue(((Object)val.dungeonFlow).name, out var value2); if (value2 == null) { value2 = new WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>(); } PersistentDataContainer persistentDataContainer = new PersistentDataContainer(Path.Combine(PersistentDataHandler.RootPath, "dungeon_" + namespacedKey.Namespace + "_" + namespacedKey.Key)); if (!persistentDataContainer.Has(StingerPlayedKey)) { persistentDataContainer.Set(StingerPlayedKey, 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 dawnDungeonInfo = new DawnDungeonInfo(namespacedKey, tags, val.dungeonFlow, value2.Build(), val.MapTileSize, stingerDetail, string.Empty, dungeonClampRange, extraScrapGeneration, persistentDataContainer); val.dungeonFlow.SetDawnInfo(dawnDungeonInfo); LethalContent.Dungeons.Register(dawnDungeonInfo); } 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}"); val.SetDawnInfo(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); val.SetDawnInfo(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) { Debuggers.Dungeons?.Log("tileSet.name: " + ((Object)item).name); NamespacedKey<DawnTileSetInfo> namespacedKey2; if (value.Key.IsVanilla()) { string text2 = FormatTileSetName(item); namespacedKey2 = DungeonTileSetKeys.GetByReflection(text2); if (namespacedKey2 == null) { DawnPlugin.Logger.LogWarning((object)$"tileset: '{((Object)item).name}' (part of {namespacedKey}) is vanilla, but DawnLib couldn't get a corresponding NamespacedKey, tileset has formatted name: {text2}!"); continue; } } else { namespacedKey2 = NamespacedKey<DawnTileSetInfo>.From(value.Key.Namespace, ((Object)item).name); } if (LethalContent.TileSets.ContainsKey(namespacedKey2)) { Debuggers.Dungeons?.Log($"LethalContent.TileSets already contains {namespacedKey2}"); item.SetDawnInfo(LethalContent.TileSets[namespacedKey2]); continue; } HashSet<NamespacedKey> hashSet2 = new HashSet<NamespacedKey>(); if (value.HasTag(DawnLibTags.IsExternal)) { hashSet2.Add(DawnLibTags.IsExternal); } DawnTileSetInfo dawnTileSetInfo = new DawnTileSetInfo(namespacedKey2, hashSet2, ConstantPredicate.True, item, val.BranchCapTileSets.Contains(item), val.TileSets.Contains(item), null); dawnArchetypeInfo.AddTileSet(dawnTileSetInfo); item.SetDawnInfo(dawnTileSetInfo); LethalContent.TileSets.Register(dawnTileSetInfo); } } } LethalContent.Archetypes.Freeze(); LethalContent.TileSets.Freeze(); } 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) { foreach (KeyValuePair<string, string> internalToHumanDungeonName in _internalToHumanDungeonNames) { internalToHumanDungeonName.Deconstruct(out var key, out var value); string oldValue = key; string newValue = value; input = input.Replace(oldValue, newValue); } return input; } 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.GetUsedArchetypes(); foreach (DungeonArchetype val in usedArchetypes) { if ((Object)(object)val == (Object)null) { Debuggers.Dungeons?.Log("Archetype is null in dungeonflow: " + ((Object)dungeonFlow).name); continue; } Debuggers.Dungeons?.Log("Injecting tile sets for " + ((Object)val).name); foreach (DawnTileSetInfo tileSet in val.GetDawnInfo().TileSets) { if (tileSet.ShouldSkipIgnoreOverride()) { continue; } val.BranchCapTileSets.Remove(tileSet.TileSet); val.TileSets.Remove(tileSet.TileSet); if (tileSet.InjectionPredicate.Evaluate()) { if (tileSet.IsBranchCap) { val.BranchCapTileSets.Add(tileSet.TileSet); } if (tileSet.IsRegular) { val.TileSets.Add(tileSet.TileSet); } } } } } } public class DawnArchetypeInfo : DawnBaseInfo<DawnArchetypeInfo> { private List<DawnTileSetInfo> _tileSets = new List<DawnTileSetInfo>(); public DungeonArchetype DungeonArchetype { get; } public IReadOnlyList<DawnTileSetInfo> TileSets => _tileSets.AsReadOnly(); public DawnDungeonInfo ParentInfo { get; internal set; } internal DawnArchetypeInfo(NamespacedKey<DawnArchetypeInfo> key, HashSet<NamespacedKey> tags, DungeonArchetype archetype, IDataContainer? customData) : base(key, tags, customData) { DungeonArchetype = archetype; } public void AddTileSet(DawnTileSetInfo info) { if (LethalContent.Dungeons.IsFrozen) { throw new RegistryFrozenException(); } _tileSets.Add(info); } } public class DawnDungeonInfo : DawnBaseInfo<DawnDungeonInfo> { internal List<DoorwaySocket> sockets = new List<DoorwaySocket>(); internal List<Doorway> doorways = new List<Doorway>(); internal List<SpawnSyncedObject> spawnSyncedObjects = new List<SpawnSyncedObject>(); internal List<Tile> tiles = new List<Tile>(); public static int FireExitGlobalPropID = 1231; public DungeonFlow DungeonFlow { get; } public string AssetBundlePath { get; } public ProviderTable<int?, DawnMoonInfo, SpawnWeightContext> Weights { get; private set; } public float MapTileSize { get; private set; } public DawnStingerDetail StingerDetail { get; private set; } public BoundedRange DungeonClampRange { get; private set; } public int ExtraScrapGeneration { get; private set; } public IReadOnlyList<Tile> Tiles => tiles.AsReadOnly(); public IReadOnlyList<Doorway> Doorways => doorways.AsReadOnly(); public IReadOnlyList<SpawnSyncedObject> SpawnSyncedObjects => spawnSyncedObjects.AsReadOnly(); public IReadOnlyList<DoorwaySocket> Sockets => sockets.AsReadOnly(); internal DawnDungeonInfo(NamespacedKey<DawnDungeonInfo> key, HashSet<NamespacedKey> tags, DungeonFlow dungeonFlow, ProviderTable<int?, DawnMoonInfo, SpawnWeightContext> weights, float mapTileSize, DawnStingerDetail stingerDetail, string assetBundlePath, BoundedRange dungeonClampRange, int extraScrapGeneration, IDataContainer? customData) : base(key, tags, customData) { DungeonFlow = dungeonFlow; Weights = weights; MapTileSize = mapTileSize; StingerDetail = stingerDetail; AssetBundlePath = assetBundlePath; DungeonClampRange = dungeonClampRange; ExtraScrapGeneration = extraScrapGeneration; if (!ShouldSkipIgnoreOverride()) { return; } sockets = new List<DoorwaySocket>(); List<TileSet> list = new List<TileSet>(); TileSet[] usedTileSets = DungeonFlow.GetUsedTileSets(); foreach (TileSet val in usedTileSets) { if ((Object)(object)val == (Object)null) { DawnPlugin.Logger.LogWarning((object)("TileSet is null in dungeonflow: " + ((Object)DungeonFlow).name)); } else if (!list.Contains(val)) { list.Add(val); } } foreach (TileInjectionRule tileInjectionRule in DungeonFlow.TileInjectionRules) { if ((Object)(object)tileInjectionRule.TileSet == (Object)null) { DawnPlugin.Logger.LogWarning((object)"TileSet is null in a tileInjectionRule"); } else if (!list.Contains(tileInjectionRule.TileSet)) { list.Add(tileInjectionRule.TileSet); } } foreach (TileSet item in list) { foreach (GameObjectChance weight in item.TileWeights.Weights) { if ((Object)(object)weight.Value == (Object)null) { DawnPlugin.Logger.LogWarning((object)("GameObject is null in tileSet: " + ((Object)item).name)); continue; } Tile[] componentsInChildren = weight.Value.GetComponentsInChildren<Tile>(); foreach (Tile val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { DawnPlugin.Logger.LogWarning((object)("Tile is null in tileSet: " + ((Object)item).name)); } else if (!tiles.Contains(val2)) { tiles.Add(val2); } } } } doorways = new List<Doorway>(); spawnSyncedObjects = new List<SpawnSyncedObject>(); foreach (Tile tile in Tiles) { Doorway[] componentsInChildren2 = ((Component)tile).gameObject.GetComponentsInChildren<Doorway>(); foreach (Doorway val3 in componentsInChildren2) { if (!Doorways.Contains(val3)) { doorways.Add(val3); } if (!Sockets.Contains(val3.socket)) { if ((Object)(object)val3.socket == (Object)null) { DawnPlugin.Logger.LogWarning((object)("DungeonFlow: " + ((Object)DungeonFlow).name + " has a null socket in doorway: " + ((Object)val3).name + " from Tile: " + ((Object)tile).name)); continue; } sockets.Add(val3.socket); } foreach (GameObjectWeight connectorPrefabWeight in val3.ConnectorPrefabWeights) { SpawnSyncedObject[] componentsInChildren3 = connectorPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>(); foreach (SpawnSyncedObject val4 in componentsInChildren3) { if (!SpawnSyncedObjects.Contains(val4)) { spawnSyncedObjects.Add(val4); } } } foreach (GameObjectWeight blockerPrefabWeight in val3.BlockerPrefabWeights) { SpawnSyncedObject[] componentsInChildren4 = blockerPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>(); foreach (SpawnSyncedObject val5 in componentsInChildren4) { if (!SpawnSyncedObjects.Contains(val5)) { spawnSyncedObjects.Add(val5); } } } } SpawnSyncedObject[] componentsInChildren5 = ((Component)tile).gameObject.GetComponentsInChildren<SpawnSyncedObject>(); foreach (SpawnSyncedObject val6 in componentsInChildren5) { if (!SpawnSyncedObjects.Contains(val6)) { spawnSyncedObjects.Add(val6); } } } } } public class DawnStingerDetail { public AudioClip? FirstTimeAudio { get; private set; } public bool PlaysMoreThanOnce { get; private set; } public float PlayChance { get; private set; } public FuncProvider<bool> AllowStingerToPlay { get; private set; } public DawnStingerDetail(AudioClip? firstTimeAudio, bool playsMoreThanOnce, float playChance, FuncProvider<bool> allowStingerToPlay) { FirstTimeAudio = firstTimeAudio; PlaysMoreThanOnce = playsMoreThanOnce; PlayChance = playChance; AllowStingerToPlay = allowStingerToPlay; base..ctor(); } } public class DawnTileSetInfo : DawnBaseInfo<DawnTileSetInfo> { public TileSet TileSet { get; } public bool IsBranchCap { get; } public bool IsRegular { get; } public IPredicate InjectionPredicate { get; } internal DawnTileSetInfo(NamespacedKey<DawnTileSetInfo> key, HashSet<NamespacedKey> tags, IPredicate injectionRule, TileSet tileSet, bool isBranchCap, bool isRegular, IDataContainer? customData) : base(key, tags, customData) { TileSet = tileSet; IsBranchCap = isBranchCap; IsRegular = isRegular; InjectionPredicate = injectionRule; } } public static class DungeonArchetypeExtensions { public static DawnArchetypeInfo GetDawnInfo(this DungeonArchetype archetype) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnArchetypeInfo)((IDawnObject)archetype).DawnInfo; } internal static bool HasDawnInfo(this DungeonArchetype archetype) { return archetype.GetDawnInfo() != null; } internal static void SetDawnInfo(this DungeonArchetype archetype, DawnArchetypeInfo archetypeInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)archetype).DawnInfo = archetypeInfo; } } public static class DungeonFlowExtensions { public static DawnDungeonInfo GetDawnInfo(this DungeonFlow dungeonFlow) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return (DawnDungeonInfo)((IDawnObject)dungeonFlow).DawnInfo; } public static bool TryGetDawnInfo(this DungeonFlow dungeonFlow, [NotNullWhen(true)] out DawnDungeonInfo? dungeonInfo) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) dungeonInfo = (DawnDungeonInfo)((IDawnObject)dungeonFlow).DawnInfo; return dungeonInfo != null; } internal static bool HasDawnInfo(this DungeonFlow dungeonFlow) { return dungeonFlow.GetDawnInfo() != null; } internal static void SetDawnInfo(this DungeonFlow dungeonFlow, DawnDungeonInfo dungeonInfo) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ((IDawnObject)dungeonFlow).DawnInfo = dungeonInfo; } } public class DungeonFlowInfoBuilder : BaseInfoBuilder<DawnDungeonInfo, DungeonFlow, DungeonFlowInfoBuilder> { private float _mapTileSize; private AudioClip? _firstTimeAudio; private ProviderTable<int?, DawnMoonInfo, SpawnWeightContext> _weights; private string _assetBundlePath = string.Empty; private BoundedRange _dungeonRangeClamp = new BoundedRange(0f, 999f); private bool _stingerPlaysMoreThanOnce; private float _stingerPlayChance = 100f; private FuncProvider<bool> _allowStingerToPlay = new FuncProvider<bool>(() => true); private int _extraScrapGeneration; internal DungeonFlowInfoBuilder(NamespacedKey<DawnDungeonInfo> key, DungeonFlow value) : base(key, value) { } public DungeonFlowInfoBuilder SetArchetypeTileSetMapping(string archetypeName, IEnumerable<string> tileSetNames) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GraphLine val = new GraphLine(base.value); base.value.Lines.Add(val); TileSet[] array = base.value.GetUsedTileSets() ?? Array.Empty<TileSet>(); Dictionary<string, TileSet> dictionary = new Dictionary<string, TileSet>(StringComparer.Ordinal); TileSet[] array2 = array; foreach (TileSet val2 in array2) { if (!dictionary.ContainsKey(((Object)val2).name)) { dictionary.Add(((Object)val2).name, val2); } } List<TileSet> list = new List<TileSet>(); foreach (string tileSetName in tileSetNames) { string name = tileSetName.Trim(); if (!dictionary.TryGetValue(name, out var val3)) { val3 = ScriptableObject.CreateInstance<TileSet>(); ((Object)val3).name = name; dictionary.Add(name, val3); } if (!list.Contains(val3)) { list.Add(val3); } } DungeonArchetype val4 = null; DungeonArchetype[] usedArchetypes = base.value.GetUsedArchetypes(); if (usedArchetypes != null) { DungeonArchetype[] array3 = usedArchetypes; foreach (DungeonArchetype val5 in array3) { if (!((Object)(object)val5
BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.dusk.dll
Decompiled 4 days 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.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 WeatherRegistry; using WeatherRegistry.Modules; 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("0.9.12.0")] [assembly: AssemblyInformationalVersion("0.9.12+f11bddf4b9fdcd9f76adee794e9e867ff12f8841")] [assembly: AssemblyProduct("DawnLib.DuskMod")] [assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib.dusk")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.12.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] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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; [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.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 : Attribute { public string BundleFile { get; private set; } public LoadFromBundleAttribute(string bundleFile) { BundleFile = bundleFile; base..ctor(); } } [AttributeUsage(AttributeTargets.Field)] public class AssertAssetInCorrectBundle : PropertyAttribute { } [AttributeUsage(AttributeTargets.Field)] public class AssertFieldNotNull : PropertyAttribute { } [AttributeUsage(AttributeTargets.Field)] public class AssertNotEmpty : PropertyAttribute { } [AttributeUsage(AttributeTargets.Class, Inherited = false)] public sealed class ContentOrderAttribute : Attribute { public int Order { get; } public ContentOrderAttribute(int order) { Order = order; base..ctor(); } } [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public sealed class DefaultKeySourceAttribute : PropertyAttribute { public string MemberName { get; } public bool Normalize { get; } public DefaultKeySourceAttribute(string memberName, bool normalize = true) { MemberName = memberName; Normalize = normalize; ((PropertyAttribute)this)..ctor(); } } [AttributeUsage(AttributeTargets.Field)] public class DontDrawIfEmpty : PropertyAttribute { public string? GroupId { get; } public string? Header { get; } public DontDrawIfEmpty(string? groupId = null, string? header = null) { GroupId = groupId; Header = header; ((PropertyAttribute)this)..ctor(); } } [AttributeUsage(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.")); } } } else { DefaultBundle bundle = new DefaultBundle(AssetBundle.LoadFromFile(fullPath)) { AssetBundleData = assetBundle }; LoadAllContent(bundle); } } } } [CreateAssetMenu(fileName = "Mod Information", menuName = "DawnLib/Mod Information", order = -10)] public class DuskModInformation : ScriptableObject { [field: SerializeField] public string AuthorName { get; internal set; } [field: SerializeField] public string ModName { get; internal set; } [field: SerializeField] public string Version { get; internal set; } [field: SerializeField] public TextAsset? READMEFile { get; private set; } [field: SerializeField] public TextAsset? ChangelogFile { get; private set; } [field: SerializeField] public string ModDescription { get; internal 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] public List<string> ExtraDependencies { get; internal set; } = new List<string>(); [field: SerializeField] public string WebsiteUrl { get; internal set; } [field: SerializeField] public Sprite? ModIcon { get; internal set; } 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 : IDisposable { [CompilerGenerated] private ConfigFile <file>P; [CompilerGenerated] private string <heading>P; public ConfigContext(ConfigFile file, string heading) { <file>P = file; <heading>P = heading; base..ctor(); } public void Dispose() { } public ConfigEntry<T> Bind<T>(string name, string description, T defaultValue) { return ConfigFileExtensions.CleanedBind<T>(<file>P, <heading>P, name, defaultValue, description); } } public class ConfigManager { public ConfigFile File { get; } public ConfigManager(ConfigFile file) { File = file; base..ctor(); } public ConfigContext CreateConfigSection(string header) { return new ConfigContext(File, header); } public ConfigContext CreateConfigSectionForBundleData(AssetBundleData data) { return CreateConfigSection(data.configName + " Options"); } public ConfigEntryBase CreateDynamicConfig(DuskDynamicConfig configDefinition, ConfigContext context) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) ConfigContext context2 = context; DuskDynamicConfig configDefinition2 = configDefinition; return (ConfigEntryBase)(configDefinition2.DynamicConfigType switch { DuskDynamicConfigType.String => Bind<string>(configDefinition2.defaultString), DuskDynamicConfigType.Int => Bind<int>(configDefinition2.defaultInt), DuskDynamicConfigType.Bool => Bind<bool>(configDefinition2.defaultBool), DuskDynamicConfigType.Float => Bind<float>(configDefinition2.defaultFloat), DuskDynamicConfigType.BoundedRange => Bind<BoundedRange>(configDefinition2.defaultBoundedRange), DuskDynamicConfigType.AnimationCurve => Bind<AnimationCurve>(configDefinition2.defaultAnimationCurve), DuskDynamicConfigType.Vector3 => Bind<Vector3>(configDefinition2.defaultVector3), DuskDynamicConfigType.Color => Bind<Color>(configDefinition2.defaultColor), _ => throw new ArgumentOutOfRangeException($"DynamicConfigType of '{configDefinition2.DynamicConfigType}' is not yet internally implemented!!"), }); ConfigEntryBase Bind<T>(T defaultValue) { return (ConfigEntryBase)(object)context2.Bind(configDefinition2.settingName, configDefinition2.Description, defaultValue); } } 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); } } 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 } [Serializable] public class IntComparison { [SerializeField] public int Value; [SerializeField] public ComparisonOperation ComparisonOperation; } [Serializable] public class IntComparisonConfigWeight : IOperationWithValue { [SerializeField] public IntComparison IntComparison; [SerializeField] public MathOperation MathOperation; [SerializeField] [Range(-9999f, 9999f)] public float Weight; private static Regex _splitRegex = new Regex("\\s+"); public MathOperation Operation => MathOperation; public float Value => Weight; public static string ConvertToString(IntComparisonConfigWeight input) { string text = input.IntComparison.ComparisonOperation switch { ComparisonOperation.Equal => "==", ComparisonOperation.NotEqual => "!=", ComparisonOperation.Greater => ">", ComparisonOperation.Less => "<", ComparisonOperation.GreaterOrEqual => ">=", ComparisonOperation.LessOrEqual => "<=", _ => "==", }; string text2 = input.MathOperation switch { MathOperation.Additive => "+", MathOperation.Subtractive => "-", MathOperation.Multiplicative => "*", MathOperation.Divisive => "/", _ => "+", }; return $"{text}{input.IntComparison.Value}={text2}{input.Weight}"; } public static string ConvertManyToString(List<IntComparisonConfigWeight> input) { string text = string.Empty; foreach (IntComparisonConfigWeight item in input) { text = text + ConvertToString(item) + ","; } return StringExtensions.RemoveEnd(text, ","); } public static IntComparisonConfigWeight ConvertFromString(string input) { DebugLogSource weights = Debuggers.Weights; if (weights != null) { weights.Log((object)("Converting IntComparisonConfigWeight from string: " + input)); } if (string.IsNullOrWhiteSpace(input)) { DuskPlugin.Logger.LogWarning((object)"Input string was null or empty."); return new IntComparisonConfigWeight(); } Match match = Regex.Match(input.Trim(), "^(==|!=|<=|>=|<|>)(-?\\d+)=([\\+\\-\\*/])(-?\\d*\\.?\\d+)$"); if (!match.Success) { DuskPlugin.Logger.LogWarning((object)("Invalid IntComparisonConfigWeight format: " + input)); return new IntComparisonConfigWeight(); } string value = match.Groups[1].Value; string value2 = match.Groups[2].Value; string value3 = match.Groups[3].Value; string value4 = match.Groups[4].Value; ComparisonOperation comparisonOperation = value switch { "==" => ComparisonOperation.Equal, "!=" => ComparisonOperation.NotEqual, "<" => ComparisonOperation.Less, ">" => ComparisonOperation.Greater, "<=" => ComparisonOperation.Less, ">=" => ComparisonOperation.Greater, _ => ComparisonOperation.Equal, }; if (!int.TryParse(value2, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { DuskPlugin.Logger.LogWarning((object)("Invalid comparison value in input: " + input)); return new IntComparisonConfigWeight(); } MathOperation mathOperation = value3[0] switch { '+' => MathOperation.Additive, '-' => MathOperation.Subtractive, '*' => MathOperation.Multiplicative, '/' => MathOperation.Divisive, _ => MathOperation.Additive, }; if (!float.TryParse(value4, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { DuskPlugin.Logger.LogWarning((object)("Invalid weight value in input: " + input)); result2 = 0f; } IntComparisonConfigWeight intComparisonConfigWeight = new IntComparisonConfigWeight { IntComparison = new IntComparison { Value = result, ComparisonOperation = comparisonOperation }, MathOperation = mathOperation, Weight = Mathf.Abs(result2) }; DebugLogSource weights2 = Debuggers.Weights; if (weights2 != null) { weights2.Log((object)("Converted IntComparisonConfigWeight: " + ConvertToString(intComparisonConfigWeight))); } return intComparisonConfigWeight; } public static List<IntComparisonConfigWeight> ConvertManyFromStringList(List<string> input) { List<IntComparisonConfigWeight> list = new List<IntComparisonConfigWeight>(input.Count); foreach (string item in input) { list.Add(ConvertFromString(item.Trim().ToLowerInvariant().Replace(" ", "_"))); } return list; } public static List<IntComparisonConfigWeight> ConvertManyFromString(string input) { if (string.IsNullOrWhiteSpace(input)) { return new List<IntComparisonConfigWeight>(); } string[] array = input.Split(',', StringSplitOptions.RemoveEmptyEntries); List<IntComparisonConfigWeight> list = new List<IntComparisonConfigWeight>(array.Length); string[] array2 = array; foreach (string text in array2) { string input2 = _splitRegex.Replace(text.Trim().ToLowerInvariant(), "_"); list.Add(ConvertFromString(input2)); } return list; } } public abstract class ContentHandler { [CompilerGenerated] private DuskMod <mod>P; protected ContentHandler(DuskMod mod) { <mod>P = mod; base..ctor(); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] protected bool IsContentEnabled(string bundleName) { if (!<mod>P.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>P.ConfigManager.CreateConfigSectionForBundleData(assetBundleData); ConfigEntry<bool> val = configContext.Bind("Enabled", "Whether " + configName + " is enabled.", defaultValue: true); <mod>P._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>P.TryGetBundleDataFromName(assetBundleName, out AssetBundleData data)) { ManualLogSource? logger = <mod>P.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>P.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>P, assetBundleName }); asset.AssetBundleData = data; 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>P); duskContentDefinition.RegisterPost(<mod>P); duskContentDefinition.RegisterConfigs(<mod>P); } } 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 { public bool Completed { get; set; } public AchievementSaveData(bool completed) { Completed = completed; base..ctor(); } } [AddComponentMenu("DawnLib/Achievements/Achivement 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 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 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 DuskMod mod2 = mod; ((TMP_Text)_modNameText).text = mod2.ModInformation.ModName; if ((Object)(object)mod2.ModInformation.ModIcon != (Object)null) { _modIcon.sprite = mod2.ModInformation.ModIcon; ((Graphic)_modIcon).color = Color.white; } List<DuskAchievementDefinition> list = (from a in DuskModContent.Achievements.Values.Where((DuskAchievementDefinition a) => a.Mod == mod2).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 + " - " + mod2.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.Where((DuskAchievementDefinition a) => a.Mod == duskMod).Count() > 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); ((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> { [CompilerGenerated] private sealed class <ShowNextAchievement>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AchievementUIGetCanvas <>4__this; private GameObject <achievementElement>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ShowNextAchievement>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <achievementElement>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown int num = <>1__state; AchievementUIGetCanvas achievementUIGetCanvas = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; <achievementElement>5__2.GetComponent<Animator>().SetTrigger(SlideOut); <>2__current = (object)new WaitForSeconds(3f); <>1__state = 2; return true; case 2: <>1__state = -1; Object.Destroy((Object)(object)<achievementElement>5__2); <achievementElement>5__2 = null; break; } if (achievementUIGetCanvas.achievementQueue.Count > 0) { DuskAchievementDefinition duskAchievementDefinition = achievementUIGetCanvas.achievementQueue.Dequeue(); <achievementElement>5__2 = Object.Instantiate<GameObject>(achievementUIGetCanvas._achievementGetUIElementPrefab, achievementUIGetCanvas.achievementContent.transform); AchievementUIElement component = <achievementElement>5__2.GetComponent<AchievementUIElement>(); component.SetupAchievementUI(duskAchievementDefinition); if ((Object)(object)duskAchievementDefinition.FinishAchievementAudioClip != (Object)null) { component.audioSource.clip = duskAchievementDefinition.FinishAchievementAudioClip; } component.audioSource.Play(); <>2__current = (object)new WaitForSeconds(duskAchievementDefinition.PopupTime); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } 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()); } } [IteratorStateMachine(typeof(<ShowNextAchievement>d__7))] private IEnumerator ShowNextAchievement() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ShowNextAchievement>d__7(0) { <>4__this = this }; } } 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 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 ResetAchievementProgress(this Registry<DuskAchievementDefinition> registry, NamespacedKey<DuskAchievementDefinition> achievementKey) { DuskAchievementDefinition duskAchievementDefinition = default(DuskAchievementDefinition); if (registry.TryGetValue(achievementKey, ref duskAchievementDefinition)) { duskAchievementDefinition.ResetProgress(); } } } 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) { DuskMod mod2 = mod; base.Register(mod2); DuskAchievementHandler.OnAchievementUnlocked = (Action<DuskAchievementDefinition>)Delegate.Combine(DuskAchievementHandler.OnAchievementUnlocked, (Action<DuskAchievementDefinition>)delegate(DuskAchievementDefinition definition) { if (definition.Mod == mod2 && 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); foreach (GameObjectChance weight in TilesToAdd.TileWeights.Weights) { DawnLib.FixDoorwaySockets(weight.Value); } 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.op_Implicit((Object)(object)Predicate)) { builder.SetInjectionPredicate((IPredicate)(object)Predicate); } }); LethalContent.Archetypes.BeforeFreeze += delegate { DawnArchetypeInfo val = default(DawnArchetypeInfo); foreach (NamespacedKey<DawnArchetypeInfo> archetypeKey in archetypeKeys) { if (LethalContent.Archetypes.TryGetValue(archetypeKey, ref val)) { val.AddTileSet(tileSetInfo); } } }; } 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> { [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: Space(2f)] [field: SerializeField] public int ExtraScrapGeneration { get; private set; } [field: Header("Configs | Generation")] [field: SerializeField] public bool GenerateSpawnWeightsConfig { get; private set; } = true; [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; } [Obsolete] [field: DontDrawIfEmpty("obsolete", "Obsolete")] [field: SerializeField] public string MoonSpawnWeights { get; private set; } [Obsolete] [field: SerializeField] [field: DontDrawIfEmpty("obsolete", "Obsolete")] public string WeatherSpawnWeights { get; private set; } internal string MoonSpawnWeightsCompat => MoonSpawnWeights; internal string WeatherSpawnWeightsCompat => WeatherSpawnWeights; public SpawnWeightsPreset SpawnWeights { get; private set; } = new SpawnWeightsPreset(); 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 DuskMod mod2 = mod; base.Register(mod2); if (DungeonRangeClamp.Min == 0f && DungeonRangeClamp.Max == 0f) { DungeonRangeClamp = new BoundedRange(0f, 999f); } using ConfigContext section = mod2.ConfigManager.CreateConfigSectionForBundleData(AssetBundleData); Config = CreateDungeonConfig(section); base.BaseConfig = Config; List<NamespacedConfigWeight> moonConfig = NamespacedConfigWeight.ConvertManyFromString(MoonSpawnWeightsCompat); if (MoonSpawnWeightsConfig.Count > 0) { moonConfig = MoonSpawnWeightsConfig; } if (Config.MoonSpawnWeights != null) { moonConfig = NamespacedConfigWeight.ConvertManyFromString(Config.MoonSpawnWeights.Value); } List<NamespacedConfigWeight> weatherConfig = NamespacedConfigWeight.ConvertManyFromString(WeatherSpawnWeightsCompat); if (WeatherSpawnWeightsConfig.Count > 0) { weatherConfig = WeatherSpawnWeightsConfig; } if (Config.WeatherSpawnWeights != null) { weatherConfig = NamespacedConfigWeight.ConvertManyFromString(Config.WeatherSpawnWeights.Value); } List<IntComparisonConfigWeight> routePriceConfig = IntComparisonConfigWeight.ConvertManyFromString(string.Empty); if (RouteSpawnWeightsConfig.Count > 0) { routePriceConfig = RouteSpawnWeightsConfig; } if (Config.RouteSpawnWeights != null) { routePriceConfig = IntComparisonConfigWeight.ConvertManyFromString(Config.RouteSpawnWeights.Value); } SpawnWeights.SetupSpawnWeightsPreset(moonConfig, new List<NamespacedConfigWeight>(), weatherConfig); SpawnWeights.AddRule(new RoutePriceRule(new RoutePriceWeightTransformer(routePriceConfig))); DawnLib.DefineDungeon(base.TypedKey, DungeonFlowReference.FlowAssetName, (Action<DungeonFlowInfoBuilder>)delegate(DungeonFlowInfoBuilder builder) { DungeonFlowReference.ArchetypeTileSetMapping[] archetypeTileSets = DungeonFlowReference.ArchetypeTileSets; foreach (DungeonFlowReference.ArchetypeTileSetMapping archetypeTileSetMapping in archetypeTileSets) { builder.SetArchetypeTileSetMapping(archetypeTileSetMapping.ArchetypeName, (IEnumerable<string>)archetypeTileSetMapping.TileSetNames); } builder.SetAssetBundlePath(mod2.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<WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>>)delegate(WeightTableBuilder<DawnMoonInfo, SpawnWeightContext> weightBuilder) { weightBuilder.SetGlobalWeight((IWeighted)(object)SpawnWeights); }); ApplyTagsTo((BaseInfoBuilder)(object)builder); }); } 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.Count > 0) ? NamespacedConfigWeight.ConvertManyToString(MoonSpawnWeightsConfig) : MoonSpawnWeightsCompat) : null), WeatherSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Weather Weights", "Preset weather weights for " + EntityNameReference + ".", (WeatherSpawnWeightsConfig.Count > 0) ? NamespacedConfigWeight.ConvertManyToString(WeatherSpawnWeightsConfig) : WeatherSpawnWeightsCompat) : 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.Count > 0) ? NamespacedConfigWeight.ConvertManyToString(MoonSpawnWeightsConfig) : MoonSpawnWeightsCompat); DuskBaseConfig.AssignValueIfNotNull(dungeonConfig.WeatherSpawnWeights, (WeatherSpawnWeightsConfig.Count > 0) ? NamespacedConfigWeight.ConvertManyToString(WeatherSpawnWeightsConfig) : WeatherSpawnWeightsCompat); 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(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 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 } [CreateAssetMenu(fileName = "New Enemy Definition", menuName = "DawnLib/Definitions/Enemy Definition")] public class DuskEnemyDefinition : DuskContentDefinition<DawnEnemyInfo> { [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 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; [Obsolete] [field: SerializeField] [field: DontDrawIfEmpty("obsolete", "Obsolete")] public string MoonSpawnWeights { get; private set; } [Obsolete] [field: SerializeField] [field: DontDrawIfEmpty("obsolete", "Obsolete")] public string InteriorSpawnWeights { get; private set; } [Obsolete] [field: SerializeField] [field: DontDrawIfEmpty("obsolete", "Obsolete")] public string WeatherSpawnWeights { get; private set; } internal string MoonSpawnWeightsCompat => MoonSpawnWeights; internal string InteriorSpawnWeightsCompat => InteriorSpawnWeights; internal string WeatherSpawnWeightsCompat => WeatherSpawnWeights; public SpawnWeightsPreset SpawnWeights { get; private set; } = new SpawnWeightsPreset(); 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; } } List<NamespacedConfigWeight> moonConfig = NamespacedConfigWeight.ConvertManyFromString(MoonSpawnWeightsCompat); if (MoonSpawnWeightsConfig.Count > 0) { moonConfig = MoonSpawnWeightsConfig; } if (Config.MoonSpawnWeights != null) { moonConfig = NamespacedConfigWeight.ConvertManyFromString(Config.MoonSpawnWeights.Value); } List<NamespacedConfigWeight> interiorConfig = NamespacedConfigWeight.ConvertManyFromString(InteriorSpawnWeightsCompat); if (InteriorSpawnWeightsConfig.Count > 0) { interiorConfig = InteriorSpawnWeightsConfig; } if (Config.InteriorSpawnWeights != null) { interiorConfig = NamespacedConfigWeight.ConvertManyFromString(Config.InteriorSpawnWeights.Value); } List<NamespacedConfigWeight> weatherConfig = NamespacedConfigWeight.ConvertManyFromString(WeatherSpawnWeightsCompat); if (WeatherSpawnWeightsConfig.Count > 0) { weatherConfig = WeatherSpawnWeightsConfig; } if (Config.WeatherSpawnWeights != null) { weatherConfig = NamespacedConfigWeight.ConvertManyFromString(Config.WeatherSpawnWeights.Value); } List<IntComparisonConfigWeight> routePriceConfig = IntComparisonConfigWeight.ConvertManyFromString(string.Empty); if (RouteSpawnWeightsConfig.Count > 0) { routePriceConfig = RouteSpawnWeightsConfig; } if (Config.RouteSpawnWeights != null) { routePriceConfig = IntComparisonConfigWeight.ConvertManyFromString(Config.RouteSpawnWeights.Value); } SpawnWeights.SetupSpawnWeightsPreset(moonConfig, interiorConfig, weatherConfig); SpawnWeights.AddRule(new RoutePriceRule(new RoutePriceWeightTransformer(routePriceConfig))); 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<WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>>)delegate(WeightTableBuilder<DawnMoonInfo, SpawnWeightContext> weightBuilder) { weightBuilder.SetGlobalWeight((IWeighted)(object)SpawnWeights); }); }); } if (SpawnTable.HasFlag(SpawnTable.Outside)) { builder.DefineOutside((Action<EnemyLocationBuilder>)delegate(EnemyLocationBuilder outsideBuilder) { outsideBuilder.SetWeights((Action<WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>>)delegate(WeightTableBuilder<DawnMoonInfo, SpawnWeightContext> weightBuilder) { weightBuilder.SetGlobalWeight((IWeighted)(object)SpawnWeights); }); }); } if (SpawnTable.HasFlag(SpawnTable.Inside)) { builder.DefineInside((Action<EnemyLocationBuilder>)delegate(EnemyLocationBuilder insideBuilder) { insideBuilder.SetWeights((Action<WeightTableBuilder<DawnMoonInfo, SpawnWeightContext>>)delegate(WeightTableBuilder<DawnMoonInfo, SpawnWeightContext> weightBuilder) { weightBuilder.SetGlobalWeight((IWeighted)(object)SpawnWeights); }); }); } if (!string.IsNullOrWhiteSpace(BestiaryNodeText)) { builder.CreateBestiaryNode(BestiaryNodeText); builder.CreateNameKeyword(BestiaryWordOverride); } 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.Count > 0) ? NamespacedConfigWeight.ConvertManyToString(MoonSpawnWeightsConfig) : MoonSpawnWeightsCompat) : null), InteriorSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Interior Weights", "Preset interior weights for " + EntityNameReference + ".", (InteriorSpawnWeightsConfig.Count > 0) ? NamespacedConfigWeight.ConvertManyToString(InteriorSpawnWeightsConfig) : InteriorSpawnWeightsCompat) : null), WeatherSpawnWeights = (GenerateSpawnWeightsConfig ? section.Bind(EntityNameReference + " | Preset Weather Weights", "Preset weather weights
BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.compatibility.dll
Decompiled 4 days 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("0.9.12.0")] [assembly: AssemblyInformationalVersion("0.9.12+f11bddf4b9fdcd9f76adee794e9e867ff12f8841")] [assembly: AssemblyProduct("DawnLib.Compatibility")] [assembly: AssemblyTitle("com.github.teamxiaolan.dawnlib.compatibility")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.12.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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", "0.9.12")] [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 v0.9.12 has loaded!"); } } internal class DawnTaggableCondition : Condition { [CompilerGenerated] private Func<ITaggable?> <generator>P; private NamespacedKey? _key; public string Value { get; private set; } public DawnTaggableCondition(Func<ITaggable?> generator) { <generator>P = generator; ((Condition)this)..ctor(); } public override bool Evaluate(IContext context) { if (_key == null) { _key = NamespacedKey.ForceParse(Value); } ITaggable val = <generator>P(); 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.GetDawnInfo(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 null; } return (ITaggable?)(object)((!Object.op_Implicit((Object)(object)RoundManager.Instance.dungeonGenerator)) ? null : DungeonFlowExtensions.GetDawnInfo(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 = "0.9.12"; } }
BepInEx/plugins/DawnLib/com.github.teamxiaolan.dawnlib.interfaces.dll
Decompiled 4 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using DunGen; using DunGen.Graph; using GameNetcodeStuff; using InjectionLibrary.Attributes; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RequiresInjections] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("Newtonsoft.Json")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: AssemblyCompany("XuXiaolan,loaforc")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.9.12.0")] [assembly: AssemblyInformationalVersion("0.9.12+f11bddf4b9fdcd9f76adee794e9e867ff12f8841")] [assembly: AssemblyProduct("DawnLibInterfaces")] [assembly: AssemblyTitle("DawnLibInterfaces")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.12.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 { [InjectInterface(typeof(Terminal))] public interface ITerminal { string DawnLastCommand { get; set; } TerminalKeyword DawnLastNoun { get; set; } TerminalKeyword DawnLastVerb { get; set; } } [InjectInterface(typeof(TerminalKeyword))] public interface ITerminalKeyword { public enum DawnKeywordType { Unset, Core, TerminalObject, Moons, Vehicles, Store, Bestiary, SigurdLog, TerminalEvent, DawnCommand, Other } DawnKeywordType DawnKeywordPriority { get; set; } bool DawnAcceptAdditionalText { get; set; } string DawnKeywordDescription { get; set; } string DawnKeywordCategory { get; set; } } [InjectInterface(typeof(TerminalNode))] public interface ITerminalNode { Func<string> DynamicDisplayText { get; set; } } internal static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.teamxiaolan.dawnlib.interfaces"; public const string PLUGIN_NAME = "DawnLibInterfaces"; public const string PLUGIN_VERSION = "0.9.12"; } } namespace Dawn.Interfaces { [HandleErrors(/*Could not decode attribute arguments.*/)] [InjectInterface(typeof(EnemyAINestSpawnObject))] [InjectInterface(typeof(RandomMapObject))] [InjectInterface(typeof(PlaceableShipObject))] [InjectInterface(typeof(HauntedMaskItem))] internal interface IAwakeMethod { [HandleErrors(/*Could not decode attribute arguments.*/)] void Awake(); } [InjectInterface(typeof(EnemyAI))] [InjectInterface(typeof(GrabbableObject))] [InjectInterface(typeof(EnemyAINestSpawnObject))] public interface ICurrentEntityReplacement { object? CurrentEntityReplacement { get; set; } } [InjectInterface(typeof(SelectableLevel))] [InjectInterface(typeof(WeatherEffect))] [InjectInterface(typeof(EnemyType))] [InjectInterface(typeof(Item))] [InjectInterface(typeof(UnlockableItem))] [InjectInterface(typeof(TileSet))] [InjectInterface(typeof(DungeonArchetype))] [InjectInterface(typeof(DungeonFlow))] [InjectInterface(typeof(BuyableVehicle))] [InjectInterface(typeof(FootstepSurface))] [InjectInterface(typeof(TerminalNode))] [InjectInterface(typeof(IndoorMapHazardType))] [InjectInterface(typeof(SpawnableOutsideObject))] public interface IDawnObject { object DawnInfo { get; set; } } [InjectInterface(typeof(GrabbableObject))] public interface IDawnSaveData { JToken GetDawnDataToSave() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return JToken.op_Implicit(((GrabbableObject)this).GetItemDataToSave()); } void LoadDawnSaveData(JToken saveData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)saveData.Type == 6) { ((GrabbableObject)this).LoadItemSaveData((int)saveData); } } } [InjectInterface(typeof(ScanNodeProperties))] public interface IDawnScanNode { object RectTransformInfo { get; set; } } [InjectInterface(typeof(PlayerControllerB))] [InjectInterface(typeof(MaskedPlayerEnemy))] public interface IDawnSurface { object? CurrentDawnSurface { get; set; } } [HandleErrors(/*Could not decode attribute arguments.*/)] [InjectInterface(typeof(PlaceableShipObject))] internal interface IOnDestroyMethod { [HandleErrors(/*Could not decode attribute arguments.*/)] void OnDestroy(); } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }