using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Silksong.PurenailUtil.Collections.Json; [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("Silksong.PurenailUtil")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+5d4b6126a54fb7ca92e7f6254ff7f0ca9a9f7e91")] [assembly: AssemblyProduct("Silksong.PurenailUtil")] [assembly: AssemblyTitle("PurenailUtil")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dplochcoder/Silksong.PurenailUtil")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class OverloadResolutionPriorityAttribute : Attribute { public int Priority { get; } public OverloadResolutionPriorityAttribute(int priority) { Priority = priority; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class ParamCollectionAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace Silksong.PurenailUtil.Collections { public static class EmptyCollection { public static readonly IReadOnlyList Instance = Array.Empty(); } [JsonConverter(typeof(AbstractJsonConvertibleConverter))] public class HashMultimap : AbstractJsonConvertible>>, IEnumerable<(K, IReadOnlyCollection)>, IEnumerable { private readonly Dictionary> dict = new Dictionary>(); public IReadOnlyCollection Keys => dict.Keys; public IEnumerable Values => dict.Values.SelectMany((HashSet v) => v); internal override Dictionary> ConvertToRep() { return dict; } internal override void ReadRep(Dictionary> value) { foreach (KeyValuePair> item in value) { Add(item.Key, item.Value); } } public bool TryGetValues(K key, out IReadOnlyCollection values) { if (dict.TryGetValue(key, out HashSet value)) { values = value; return true; } values = EmptyCollection.Instance; return false; } public IReadOnlyCollection Get(K key) { if (!dict.TryGetValue(key, out HashSet value)) { return EmptyCollection.Instance; } return value; } public void Clear() { dict.Clear(); } public bool Add(K key, V value) { if (dict.TryGetValue(key, out HashSet value2)) { return value2.Add(value); } dict.Add(key, new HashSet { value }); return true; } public bool Add(K key, IEnumerable values) { if (dict.TryGetValue(key, out HashSet value)) { bool flag = false; { foreach (V value2 in values) { flag |= value.Add(value2); } return flag; } } HashSet hashSet = new HashSet(); foreach (V value3 in values) { hashSet.Add(value3); } value = hashSet; if (value.Count == 0) { return false; } dict[key] = value; return true; } public bool Remove(K key) { return dict.Remove(key); } public bool Remove(K key, V value) { if (dict.TryGetValue(key, out HashSet value2) && value2.Remove(value)) { if (value2.Count == 0) { dict.Remove(key); } return true; } return false; } public bool Remove(K key, IEnumerable values) { if (dict.TryGetValue(key, out HashSet value)) { bool flag = false; foreach (V value2 in values) { flag |= value.Remove(value2); } if (value.Count == 0) { dict.Remove(key); } return flag; } return false; } private IEnumerable<(K, IReadOnlyCollection)> EnumeateSets() { return dict.Select>, (K, IReadOnlyCollection)>((KeyValuePair> e) => ((K Key, IReadOnlyCollection))(Key: e.Key, e.Value)); } public IEnumerator<(K, IReadOnlyCollection)> GetEnumerator() { return EnumeateSets().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return EnumeateSets().GetEnumerator(); } } [JsonConverter(typeof(AbstractJsonConvertibleConverter))] public class HashMultiset : AbstractJsonConvertible>, ICollection, IEnumerable, IEnumerable { private readonly Dictionary elements = new Dictionary(); private int total; public IReadOnlyCollection Distinct => elements.Keys; public IEnumerable<(T, int)> Counts => elements.Select((KeyValuePair e) => (Key: e.Key, Value: e.Value)); public bool IsEmpty => elements.Count == 0; int ICollection.Count => total; public bool IsReadOnly => false; internal override List<(T, int)> ConvertToRep() { return elements.Select((KeyValuePair e) => (Key: e.Key, Value: e.Value)).ToList(); } internal override void ReadRep(List<(T, int)> value) { foreach (var (element, count) in value) { Add(element, count); } } public HashMultiset() { } public HashMultiset(HashMultiset copy) { foreach (KeyValuePair element in copy.elements) { elements[element.Key] = element.Value; } total = copy.total; } public HashMultiset(IEnumerable elements) { foreach (T element in elements) { Add(element); } } public bool Contains(T element) { return elements.ContainsKey(element); } public int Count(T element) { if (!elements.TryGetValue(element, out var value)) { return 0; } return value; } public void Clear() { elements.Clear(); } public void Add(T element, int count) { if (count != 0) { if (count < 0) { throw new ArgumentException(string.Format("{0}: {1}", "count", count)); } elements[element] = Count(element) + count; total += count; } } public void Add(T element) { Add(element, 1); } public void AddRange(IEnumerable elements) { foreach (T element in elements) { Add(element); } } public bool Set(T element, int count) { if (count < 0) { throw new ArgumentException(string.Format("{0}: {1}", "count", count)); } int num = Count(element); if (count == num) { return false; } total += count - num; if (count == 0) { elements.Remove(element); } else { elements[element] = count; } return true; } public int Remove(T element, int count) { if (count == 0) { return 0; } if (count < 0) { throw new ArgumentException(string.Format("{0}: {1}", "count", count)); } int num = Count(element); if (num == 0) { return 0; } if (count >= num) { elements.Remove(element); total -= num; return num; } elements[element] = num - count; total -= count; return count; } public bool Remove(T item) { return Remove(item, 1) > 0; } public void CopyTo(T[] array, int arrayIndex) { using IEnumerator enumerator = GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; array[arrayIndex++] = current; } } private IEnumerable Enumerate() { foreach (KeyValuePair e in elements) { for (int i = 0; i < e.Value; i++) { yield return e.Key; } } } public IEnumerator GetEnumerator() { return Enumerate().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return Enumerate().GetEnumerator(); } } [JsonConverter(typeof(AbstractJsonConvertibleConverter))] public class HashMultitable : AbstractJsonConvertible>>, IEnumerable<((K1, K2), IReadOnlyCollection)>, IEnumerable { private readonly HashTable> table = new HashTable>(); internal override HashTable> ConvertToRep() { return table; } internal override void ReadRep(HashTable> value) { foreach (var (tuple2, values) in value) { Add(tuple2.Item1, tuple2.Item2, values); } } public void Clear() { table.Clear(); } public bool TryGetValues(K1 key1, K2 key2, out IReadOnlyCollection values) { if (table.TryGetValue(key1, key2, out HashSet value)) { values = value; return true; } values = EmptyCollection.Instance; return false; } public IReadOnlyCollection Get(K1 key1, K2 key2) { if (!TryGetValues(key1, key2, out IReadOnlyCollection values)) { return EmptyCollection.Instance; } return values; } public bool Add(K1 key1, K2 key2, V value) { if (table.TryGetValue(key1, key2, out HashSet value2)) { return value2.Add(value); } table.Set(key1, key2, new HashSet { value }); return true; } public bool Add(K1 key1, K2 key2, IEnumerable values) { if (table.TryGetValue(key1, key2, out HashSet value)) { bool flag = false; { foreach (V value2 in values) { flag |= value.Add(value2); } return flag; } } HashSet hashSet = new HashSet(); foreach (V value3 in values) { hashSet.Add(value3); } value = hashSet; if (value.Count == 0) { return false; } table.Set(key1, key2, value); return true; } public bool Remove(K1 key) { return table.Remove(key); } public bool Remove(K1 key1, K2 key2) { return table.Remove(key1, key2); } public bool Remove(K1 key1, K2 key2, V value) { if (table.TryGetValue(key1, key2, out HashSet value2) && value2.Remove(value)) { if (value2.Count == 0) { table.Remove(key1, key2); } return true; } return false; } public bool Remove(K1 key1, K2 key2, IEnumerable values) { if (table.TryGetValue(key1, key2, out HashSet value)) { bool flag = false; foreach (V value2 in values) { flag |= value.Remove(value2); } if (value.Count == 0) { table.Remove(key1, key2); } return flag; } return false; } private IEnumerable<((K1, K2), IReadOnlyCollection)> EnumerateEntries() { return table.Select<((K1, K2), HashSet), ((K1, K2), IReadOnlyCollection)>((((K1, K2), HashSet) e) => (((K1, K2), IReadOnlyCollection))(e.Item1, e.Item2)); } public IEnumerator<((K1, K2), IReadOnlyCollection)> GetEnumerator() { return EnumerateEntries().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return EnumerateEntries().GetEnumerator(); } } [JsonConverter(typeof(AbstractJsonConvertibleConverter))] public class HashTable : AbstractJsonConvertible>>, IEnumerable<((K1, K2), V)>, IEnumerable { private readonly Dictionary> table = new Dictionary>(); public V this[K1 key1, K2 key2] { get { if (!TryGetValue(key1, key2, out var value)) { throw new KeyNotFoundException($"({key1}, {key2})"); } return value; } set { Set(key1, key2, value); } } internal override Dictionary> ConvertToRep() { return table; } internal override void ReadRep(Dictionary> value) { foreach (KeyValuePair> item in value) { foreach (KeyValuePair item2 in item.Value) { Set(item.Key, item2.Key, item2.Value); } } } public void Clear() { table.Clear(); } public bool TryGetValue(K1 key1, K2 key2, [MaybeNullWhen(false)] out V value) { if (table.TryGetValue(key1, out Dictionary value2) && value2.TryGetValue(key2, out value)) { return true; } value = default(V); return false; } public void Set(K1 key1, K2 key2, V value) { if (table.TryGetValue(key1, out Dictionary value2)) { value2[key2] = value; return; } value2 = new Dictionary(); value2.Add(key2, value); table.Add(key1, value2); } public bool Remove(K1 key) { return table.Remove(key); } public bool Remove(K1 key1, K2 key2) { if (table.TryGetValue(key1, out Dictionary value) && value.Remove(key2)) { if (value.Count == 0) { table.Remove(key1); } return true; } return false; } private IEnumerable<((K1, K2), V)> EnumerateEntries() { foreach (KeyValuePair> e1 in table) { foreach (KeyValuePair item in e1.Value) { yield return ((e1.Key, item.Key), item.Value); } } } public IEnumerator<((K1, K2), V)> GetEnumerator() { return EnumerateEntries().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return EnumerateEntries().GetEnumerator(); } } [JsonConverter(typeof(AbstractJsonConvertibleConverter))] public class ListMultimap : AbstractJsonConvertible>>, IEnumerable<(K, IReadOnlyList)>, IEnumerable { private readonly Dictionary> dict = new Dictionary>(); public IReadOnlyCollection Keys => dict.Keys; public IEnumerable Values => dict.Values.SelectMany((List v) => v); internal override Dictionary> ConvertToRep() { return dict; } internal override void ReadRep(Dictionary> value) { foreach (KeyValuePair> item in value) { Add(item.Key, item.Value); } } public bool TryGetValues(K key, out IReadOnlyList values) { if (dict.TryGetValue(key, out List value)) { values = value; return true; } values = EmptyCollection.Instance; return false; } public IReadOnlyList Get(K key) { if (!dict.TryGetValue(key, out List value)) { return EmptyCollection.Instance; } return value; } public void Clear() { dict.Clear(); } public void Add(K key, V value) { if (dict.TryGetValue(key, out List value2)) { value2.Add(value); return; } dict.Add(key, new List(1) { value }); } public void Add(K key, IEnumerable values) { if (dict.TryGetValue(key, out List value)) { value.AddRange(values); } else { dict.Add(key, values.ToList()); } } public bool Remove(K key) { return dict.Remove(key); } public bool Remove(K key, V value) { if (dict.TryGetValue(key, out List value2) && value2.Remove(value)) { if (value2.Count == 0) { dict.Remove(key); } return true; } return false; } public bool Remove(K key, IEnumerable values) { if (dict.TryGetValue(key, out List value)) { bool flag = false; foreach (V value2 in values) { flag |= value.Remove(value2); } if (value.Count == 0) { dict.Remove(key); } return flag; } return false; } private IEnumerable<(K, IReadOnlyList)> EnumeateLists() { return dict.Select>, (K, IReadOnlyList)>((KeyValuePair> e) => ((K Key, IReadOnlyList))(Key: e.Key, e.Value)); } public IEnumerator<(K, IReadOnlyList)> GetEnumerator() { return EnumeateLists().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return EnumeateLists().GetEnumerator(); } } } namespace Silksong.PurenailUtil.Collections.Json { public abstract class AbstractJsonConvertible { internal abstract Type GetRepType(); internal abstract object ConvertToRepRaw(); internal abstract void ReadRepRaw(object value); } public abstract class AbstractJsonConvertible : AbstractJsonConvertible where RepT : class { internal override Type GetRepType() { return typeof(RepT); } internal override object ConvertToRepRaw() { return ConvertToRep(); } internal abstract RepT ConvertToRep(); internal override void ReadRepRaw(object value) { ReadRep((RepT)value); } internal abstract void ReadRep(RepT value); } internal class AbstractJsonConvertibleConverter : JsonConverter { public override AbstractJsonConvertible? ReadJson(JsonReader reader, Type objectType, AbstractJsonConvertible? existingValue, bool hasExistingValue, JsonSerializer serializer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)reader.TokenType == 11) { return null; } AbstractJsonConvertible abstractJsonConvertible = (hasExistingValue ? existingValue : ((AbstractJsonConvertible)Activator.CreateInstance(objectType))); object value = serializer.Deserialize(reader, abstractJsonConvertible.GetRepType()); abstractJsonConvertible.ReadRepRaw(value); return abstractJsonConvertible; } public override void WriteJson(JsonWriter writer, AbstractJsonConvertible? value, JsonSerializer serializer) { if (value != null) { serializer.Serialize(writer, value.ConvertToRepRaw(), value.GetRepType()); } else { serializer.Serialize(writer, (object)null); } } } }