Decompiled source of Hard Item Randomizer v1.0.6

plugins/Newtonsoft.Json.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("13.0.4.30916")]
[assembly: AssemblyInformationalVersion("13.0.4+4e13299d4b0ec96bd4df9954ef646bd2d1b5bf2a")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET .NET Standard 2.0")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)]
	internal sealed class DynamicallyAccessedMembersAttribute : Attribute
	{
		public DynamicallyAccessedMemberTypes MemberTypes { get; }

		public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
		{
			MemberTypes = memberTypes;
		}
	}
	[Flags]
	internal enum DynamicallyAccessedMemberTypes
	{
		None = 0,
		PublicParameterlessConstructor = 1,
		PublicConstructors = 3,
		NonPublicConstructors = 4,
		PublicMethods = 8,
		NonPublicMethods = 0x10,
		PublicFields = 0x20,
		NonPublicFields = 0x40,
		PublicNestedTypes = 0x80,
		NonPublicNestedTypes = 0x100,
		PublicProperties = 0x200,
		NonPublicProperties = 0x400,
		PublicEvents = 0x800,
		NonPublicEvents = 0x1000,
		Interfaces = 0x2000,
		All = -1
	}
	[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class FeatureGuardAttribute : Attribute
	{
		public Type FeatureType { get; }

		public FeatureGuardAttribute(Type featureType)
		{
			FeatureType = featureType;
		}
	}
	[AttributeUsage(AttributeTargets.Property, Inherited = false)]
	internal sealed class FeatureSwitchDefinitionAttribute : Attribute
	{
		public string SwitchName { get; }

		public FeatureSwitchDefinitionAttribute(string switchName)
		{
			SwitchName = switchName;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class RequiresDynamicCodeAttribute : Attribute
	{
		public string Message { get; }

		public string? Url { get; set; }

		public RequiresDynamicCodeAttribute(string message)
		{
			Message = message;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class RequiresUnreferencedCodeAttribute : Attribute
	{
		public string Message { get; }

		public string? Url { get; set; }

		public RequiresUnreferencedCodeAttribute(string message)
		{
			Message = message;
		}
	}
	[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
	internal sealed class UnconditionalSuppressMessageAttribute : Attribute
	{
		public string Category { get; }

		public string CheckId { get; }

		public string? Scope { get; set; }

		public string? Target { get; set; }

		public string? MessageId { get; set; }

		public string? Justification { get; set; }

		public UnconditionalSuppressMessageAttribute(string category, string checkId)
		{
			Category = category;
			CheckId = checkId;
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	public class DefaultJsonNameTable : JsonNameTable
	{
		private class Entry
		{
			internal readonly string Value;

			internal readonly int HashCode;

			internal Entry Next;

			internal Entry(string value, int hashCode, Entry next)
			{
				Value = value;
				HashCode = hashCode;
				Next = next;
			}
		}

		private static readonly int HashCodeRandomizer;

		private int _count;

		private Entry[] _entries;

		private int _mask = 31;

		static DefaultJsonNameTable()
		{
			HashCodeRandomizer = Environment.TickCount;
		}

		public DefaultJsonNameTable()
		{
			_entries = new Entry[_mask + 1];
		}

		public override string? Get(char[] key, int start, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			num += (num << 7) ^ key[start];
			int num2 = start + length;
			for (int i = start + 1; i < num2; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			int num3 = Volatile.Read(ref _mask);
			int num4 = num & num3;
			for (Entry entry = _entries[num4]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
				{
					return entry.Value;
				}
			}
			return null;
		}

		public string Add(string key)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			int length = key.Length;
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			for (int i = 0; i < key.Length; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
				{
					return entry.Value;
				}
			}
			return AddEntry(key, num);
		}

		private string AddEntry(string str, int hashCode)
		{
			int num = hashCode & _mask;
			Entry entry = new Entry(str, hashCode, _entries[num]);
			_entries[num] = entry;
			if (_count++ == _mask)
			{
				Grow();
			}
			return entry.Value;
		}

		private void Grow()
		{
			Entry[] entries = _entries;
			int num = _mask * 2 + 1;
			Entry[] array = new Entry[num + 1];
			for (int i = 0; i < entries.Length; i++)
			{
				Entry entry = entries[i];
				while (entry != null)
				{
					int num2 = entry.HashCode & num;
					Entry next = entry.Next;
					entry.Next = array[num2];
					array[num2] = entry;
					entry = next;
				}
			}
			_entries = array;
			Volatile.Write(ref _mask, num);
		}

		private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
		{
			if (str1.Length != str2Length)
			{
				return false;
			}
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i] != str2[str2Start + i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[]? array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type? _namingStrategyType;

		private object[]? _namingStrategyParameters;

		public string? Id { get; set; }

		public string? Title { get; set; }

		public string? Description { get; set; }

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[]? NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy? NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		private static string ToStringInternal(BigInteger value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				if (nullable)
				{
					return Null;
				}
				return "0.0";
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (StringUtils.IndexOf(text, '.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string? value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string? value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value)
		{
			return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
		{
			StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static object? DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static object? DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static object? DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static T? DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		[DebuggerStepThrough]
		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (settings == null || !settings.CheckAdditionalContent)
			{
				return;
			}
			while (jsonReader.Read())
			{
				if (jsonReader.TokenType != JsonToken.Comment)
				{
					throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
				}
			}
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeXmlNode(XmlNode? node)
		{
			return SerializeXmlNode(node, Formatting.None);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XmlDocument? DeserializeXmlNode(string value)
		{
			return DeserializeXmlNode(value, null);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeXNode(XObject? node)
		{
			return SerializeXNode(node, Formatting.None);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeXNode(XObject? node, Formatting formatting)
		{
			return SerializeXNode(node, formatting, omitRootObject: false);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XDocument? DeserializeXNode(string value)
		{
			return DeserializeXNode(value, null);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
		[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);

		public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	public abstract class JsonConverter<T> : JsonConverter
	{
		public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
			{
				throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			WriteJson(writer, (T)value, serializer);
		}

		public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);

		public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			bool flag = existingValue == null;
			if (!flag && !(existingValue is T))
			{
				throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
		}

		public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);

		public sealed override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[]? ConverterParameters { get; }

		public JsonConverterAttribute(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception? innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	public abstract class JsonNameTable
	{
		public abstract string? Get(char[] key, int start, int length);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal MissingMemberHandling? _missingMemberHandling;

		internal Required? _itemRequired;

		internal NullValueHandling? _itemNullValueHandling;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling.GetValueOrDefault();
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired.GetValueOrDefault();
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[18]
		{
			'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
			'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
		};

		internal JsonContainerType Type;

		internal int Position;

		internal string? PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					if (writer == null)
					{
						writer = new StringWriter(sb);
					}
					JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
					sb.Append("']");
				}
				else
				{
					if (sb.Length > 0)
					{
						sb.Append('.');
					}
					sb.Append(propertyName);
				}
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			if (type != JsonContainerType.Array)
			{
				return type == JsonContainerType.Constructor;
			}
			return true;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			StringWriter writer = null;
			char[] buffer = null;
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder, ref writer, ref buffer);
				}
			}
			currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType { get; set; }

		public object[]? NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling.GetValueOrDefault();
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order.GetValueOrDefault();
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required.GetValueOrDefault();
			}
			set
			{
				_required = value;
			}
		}

		public string? PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object? _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo? _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string? _dateFormatString;

		private List<JsonPosition>? _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string? DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object? Value => _value;

		public virtual Type? ValueType => _value?.GetType();

		public virtual int Depth
		{
			get
			{
				int num = _stack?.Count ?? 0;
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
		}

		public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TokenType == JsonToken.PropertyName)
			{
				await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
				{
				}
			}
		}

		internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
		{
			if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
			{
				throw CreateUnexpectedEndException();
			}
		}

		public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
		}

		public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
		}

		internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
		{
			List<byte> buffer = new List<byte>();
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(buffer));
			byte[] array = buffer.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
		}

		public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
		}

		public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
		}

		public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return Task.FromResult(ReadAsDouble());
		}

		public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
		}

		public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
		}

		internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
		{
			bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (flag)
			{
				flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			return flag;
		}

		internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType = TokenType;
			if (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				return MoveToContentFromNonContentAsync(cancellationToken);
			}
			return AsyncUtils.True;
		}

		private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType;
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					return false;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment);
			return true;
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			_maxDepth = 64;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
			{
				return;
			}
			_hasExceededMaxDepth = true;
			throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is int)
				{
					return (int)value;
				}
				int num;
				if (value is BigInteger bigInteger)
				{
					num = (int)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Integer, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string? ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken))
				{
					object value = Value;
					if (value != null)
					{
						string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
						SetToken(JsonToken.String, text, updateIndex: false);
						return text;
					}
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[]? ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.StartObject:
			{
				ReadIntoWrappedTypeObject();
				byte[] array2 = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array2, updateIndex: false);
				return array2;
			}
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if (Value is Guid guid)
				{
					byte[] array = guid.ToByteArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(list));
			byte[] array = list.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
		{
			switch (TokenType)
			{
			case JsonToken.None:
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			case JsonToken.Integer:
				buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
				return false;
			case JsonToken.EndArray:
				return true;
			case JsonToken.Comment:
				return false;
			default:
				throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is double)
				{
					return (double)value;
				}
				double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is decimal)
				{
					return (decimal)value;
				}
				decimal num;
				if (value is BigInteger bigInteger)
				{
					num = (decimal)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset dateTimeOffset)
				{
					SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
				return ReadDateTimeString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime dateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value != null && Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
		{
			if (!ReadForType(contract, hasConverter))
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadForType(JsonContract? contract, bool hasConverter)
		{
			if (hasConverter)
			{
				return Read();
			}
			switch (contract?.InternalReadType ?? ReadType.Read)
			{
			case ReadType.Read:
				return ReadAndMoveToContent();
			case ReadType.ReadAsInt32:
				ReadAsInt32();
				break;
			case ReadType.ReadAsInt64:
			{
				bool result = ReadAndMoveToContent();
				if (TokenType == JsonToken.Undefined)
				{
					throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
				}
				return result;
			}
			case ReadType.ReadAsDecimal:
				ReadAsDecimal();
				break;
			case ReadType.ReadAsDouble:
				ReadAsDouble();
				break;
			case ReadType.ReadAsBytes:
				ReadAsBytes();
				break;
			case ReadType.ReadAsBoolean:
				ReadAsBoolean();
				break;
			case ReadType.ReadAsString:
				ReadAsString();
				break;
			case ReadType.ReadAsDateTime:
				ReadAsDateTime();
				break;
			case ReadType.ReadAsDateTimeOffset:
				ReadAsDateTimeOffset();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return TokenType != JsonToken.None;
		}

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, path, lineNumber, linePosition, ex);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
		}
	}
	[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
	[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection? _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter? _traceWriter;

		internal IEqualityComparer? _equalityComparer;

		internal ISerializationBinder _serializationBinder;

		internal StreamingContext _context;

		private IReferenceResolver? _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string? _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver? ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public virtual SerializationBinder Binder
		{
			get
			{
				if (_serializationBinder is SerializationBinder result)
				{
					return result;
				}
				if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
			}
		}

		public virtual ISerializationBinder SerializationBinder
		{
			get
			{
				return _serializationBinder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = value;
			}
		}

		public virtual ITraceWriter? TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer? EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting.GetValueOrDefault();
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling.GetValueOrDefault();
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling.GetValueOrDefault(DateTimeZoneHandling.RoundtripKind);
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling.GetValueOrDefault(DateParseHandling.DateTime);
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling.GetValueOrDefault();
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling.GetValueOrDefault();
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling.GetValueOrDefault();
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent.GetValueOrDefault();
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_serializationBinder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormatHandling.HasValue)
			{
				serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.SerializationBinder != null)
			{
				serializer.SerializationBinder = settings.SerializationBinder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		[DebuggerStepThrough]
		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		[DebuggerStepThrough]
		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		[DebuggerStepThrough]
		public object? Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		[DebuggerStepThrough]
		public T? Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader, Type? objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling

plugins/SilksongItemRandomizer.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GlobalEnums;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SilksongItemRandomizer.Hazard;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SilksongItemRandomizer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("SilksongItemRandomizer")]
[assembly: AssemblyTitle("SilksongItemRandomizer")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/YourGitHubUsername/SilksongItemRandomizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	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")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace SilksongItemRandomizer
{
	[HarmonyPatch(typeof(HeroController), "SetBenchRespawn", new Type[]
	{
		typeof(RespawnMarker),
		typeof(string),
		typeof(int)
	})]
	public static class BenchRespawnPatch
	{
		[CompilerGenerated]
		private sealed class <DelayedCrestRefresh>d__3 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public HeroController hero;

			private object <currentCrestObj>5__1;

			private string <currentCrest>5__2;

			private float <last>5__3;

			private string <targetCrest>5__4;

			private MethodInfo <setEquippedMethod>5__5;

			private Exception <ex>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedCrestRefresh>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<currentCrestObj>5__1 = null;
				<currentCrest>5__2 = null;
				<targetCrest>5__4 = null;
				<setEquippedMethod>5__5 = null;
				<ex>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(15f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					try
					{
						<currentCrestObj>5__1 = PlayerData.instance.CurrentCrestID;
						if (<currentCrestObj>5__1 == null)
						{
							return false;
						}
						<currentCrest>5__2 = <currentCrestObj>5__1.ToString();
						if (string.IsNullOrEmpty(<currentCrest>5__2))
						{
							return false;
						}
						if (_lastRefreshTime.TryGetValue(<currentCrest>5__2, out <last>5__3) && Time.time - <last>5__3 < 30f)
						{
							Plugin.Log.LogInfo((object)("纹章 " + <currentCrest>5__2 + " 在冷却期内,跳过刷新"));
							return false;
						}
						<targetCrest>5__4 = CrestRandomizer.GetMappedCrestName(<currentCrest>5__2);
						if (string.IsNullOrEmpty(<targetCrest>5__4))
						{
							return false;
						}
						if (<currentCrest>5__2 != <targetCrest>5__4)
						{
							Plugin.Log.LogInfo((object)("延迟15秒后检测到纹章不一致: 当前=" + <currentCrest>5__2 + ", 目标=" + <targetCrest>5__4 + ",开始刷新"));
							<setEquippedMethod>5__5 = typeof(ToolItemManager).GetMethod("SetEquippedCrest", new Type[1] { typeof(string) });
							if (<setEquippedMethod>5__5 != null)
							{
								<setEquippedMethod>5__5.Invoke(null, new object[1] { <targetCrest>5__4 });
							}
							if ((Object)(object)hero != (Object)null)
							{
								hero.ResetAllCrestState();
							}
							_lastRefreshTime[<currentCrest>5__2] = Time.time;
							Plugin.Log.LogInfo((object)("延迟刷新完成,当前装备: " + <targetCrest>5__4));
							<setEquippedMethod>5__5 = null;
						}
						<currentCrestObj>5__1 = null;
						<currentCrest>5__2 = null;
						<targetCrest>5__4 = null;
					}
					catch (Exception ex)
					{
						<ex>5__6 = ex;
						Plugin.Log.LogError((object)$"DelayedCrestRefresh异常: {<ex>5__6}");
					}
					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 Dictionary<string, float> _lastRefreshTime = new Dictionary<string, float>();

		private const float COOLDOWN = 30f;

		private static void Postfix(HeroController __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null) && PlayerData.instance != null)
				{
					((MonoBehaviour)__instance).StartCoroutine(DelayedCrestRefresh(__instance));
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"BenchRespawnPatch异常: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<DelayedCrestRefresh>d__3))]
		private static IEnumerator DelayedCrestRefresh(HeroController hero)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedCrestRefresh>d__3(0)
			{
				hero = hero
			};
		}

		public static void ResetCooldown()
		{
			_lastRefreshTime.Clear();
			Plugin.Log.LogInfo((object)"纹章刷新冷却已清空");
		}
	}
	[HarmonyPatch(typeof(ToolCrest), "Unlock")]
	public static class CrestRandomizePatch
	{
		private static List<ToolCrest>? _allCrests;

		private static HashSet<int> _processedInstanceIds = new HashSet<int>();

		public static List<ToolCrest>? CrestList => _allCrests;

		public static void Initialize()
		{
			_allCrests = Resources.FindObjectsOfTypeAll<ToolCrest>().ToList();
		}

		public static void ResetProcessedIds()
		{
			_processedInstanceIds.Clear();
		}

		[HarmonyPrefix]
		private static bool Prefix(ToolCrest __instance)
		{
			try
			{
				if (_processedInstanceIds.Contains(((Object)__instance).GetInstanceID()))
				{
					return true;
				}
				_processedInstanceIds.Add(((Object)__instance).GetInstanceID());
				string name = __instance.name;
				string mappedCrestName = CrestRandomizer.GetMappedCrestName(name);
				if (string.IsNullOrEmpty(mappedCrestName))
				{
					return true;
				}
				if (mappedCrestName == name)
				{
					Plugin.Log.LogInfo((object)("纹章 " + name + " 映射到自身,放行原解锁"));
					return true;
				}
				if (_allCrests == null || _allCrests.Count == 0)
				{
					Initialize();
				}
				ToolCrest val = null;
				if (_allCrests != null)
				{
					foreach (ToolCrest allCrest in _allCrests)
					{
						if (allCrest.name == mappedCrestName)
						{
							val = allCrest;
							break;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)("无法找到目标纹章 " + mappedCrestName + ",放行原解锁"));
					return true;
				}
				val.Unlock();
				PlayerData instance = PlayerData.instance;
				if (instance != null && instance.CurrentCrestID == name)
				{
					typeof(ToolItemManager).GetMethod("SetEquippedCrest", new Type[1] { typeof(string) })?.Invoke(null, new object[1] { mappedCrestName });
				}
				return false;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"CrestRandomizePatch异常: {arg}");
				return true;
			}
		}
	}
	public static class CrestRandomizer
	{
		private static Dictionary<string, string> _crestMappings = new Dictionary<string, string>();

		private static List<ToolCrest>? _allCrests;

		private static string FilePath => Path.Combine(Paths.ConfigPath, "SilksongItemRandomizer", "crest_mappings.json");

		public static List<ToolCrest>? CrestList => _allCrests;

		public static void Initialize()
		{
			_allCrests = Resources.FindObjectsOfTypeAll<ToolCrest>().ToList();
			LoadMappings();
			if (_allCrests.Count > 0 && _crestMappings.Count < _allCrests.Count)
			{
				Plugin.Log.LogInfo((object)$"映射不完整(现有 {_crestMappings.Count}/{_allCrests.Count}),重新生成完整映射");
				GenerateAllMappings();
			}
			Plugin.Log.LogInfo((object)$"纹章随机初始化完成,共 {_crestMappings.Count} 个映射");
		}

		public static void ResetMappings()
		{
			_crestMappings.Clear();
			if (File.Exists(FilePath))
			{
				File.Delete(FilePath);
			}
			Plugin.Log.LogInfo((object)"纹章映射已重置");
		}

		private static void LoadMappings()
		{
			try
			{
				if (File.Exists(FilePath))
				{
					string text = File.ReadAllText(FilePath);
					_crestMappings = JsonConvert.DeserializeObject<Dictionary<string, string>>(text) ?? new Dictionary<string, string>();
				}
				else
				{
					_crestMappings.Clear();
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"加载纹章映射失败: {arg}");
				_crestMappings.Clear();
			}
		}

		private static void SaveMappings()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(FilePath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				string contents = JsonConvert.SerializeObject((object)_crestMappings, (Formatting)1);
				File.WriteAllText(FilePath, contents);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"保存纹章映射失败: {arg}");
			}
		}

		private static void GenerateAllMappings()
		{
			if (_allCrests == null || _allCrests.Count == 0)
			{
				return;
			}
			int value = Plugin.RandomSeed.Value;
			Random rng = new Random(value);
			List<ToolCrest> source2 = _allCrests.OrderBy((ToolCrest x) => rng.Next()).ToList();
			foreach (ToolCrest source in _allCrests)
			{
				List<ToolCrest> list = source2.Where((ToolCrest c) => c.name != source.name).ToList();
				if (list.Count == 0)
				{
					_crestMappings[source.name] = source.name;
					continue;
				}
				int index = rng.Next(list.Count);
				string name = list[index].name;
				_crestMappings[source.name] = name;
			}
			SaveMappings();
			Plugin.Log.LogInfo((object)$"已为所有 {_allCrests.Count} 个纹章预生成映射");
		}

		public static string GetMappedCrestName(string sourceCrestName)
		{
			if (_crestMappings.TryGetValue(sourceCrestName, out string value))
			{
				return value;
			}
			Plugin.Log.LogWarning((object)("警告:纹章 " + sourceCrestName + " 没有映射,返回自身"));
			return sourceCrestName;
		}
	}
	[HarmonyPatch(typeof(CurrencyObjectBase), "Collect")]
	public class CurrencyCollectPatch
	{
		private static int _consecutiveMisses;

		private const int PITY_THRESHOLD = 105;

		private static int _dropCount;

		private static bool _hasGivenKey;

		private const int KEY_GUARANTEE_MAX = 30;

		private static string keyName;

		private static int _silkSpearAttempts;

		private static bool _silkSpearGiven;

		private const int SILK_SPEAR_PITY = 200;

		private static SavedItem? _silkSpearItem;

		static CurrencyCollectPatch()
		{
			_consecutiveMisses = 0;
			_dropCount = 0;
			_hasGivenKey = false;
			keyName = "Simple Key";
			_silkSpearAttempts = 0;
			_silkSpearGiven = false;
			SavedItem[] source = Resources.FindObjectsOfTypeAll<SavedItem>();
			_silkSpearItem = ((IEnumerable<SavedItem>)source).FirstOrDefault((Func<SavedItem, bool>)((SavedItem item) => ((Object)item).name == "Silk Spear"));
			if ((Object)(object)_silkSpearItem == (Object)null)
			{
				Plugin.Log.LogWarning((object)"未找到丝矛物品(Silk Spear),丝矛200次保底将禁用。");
			}
		}

		public static void ResetCounters()
		{
			_consecutiveMisses = 0;
			_dropCount = 0;
			_hasGivenKey = false;
			_silkSpearAttempts = 0;
			_silkSpearGiven = false;
			Plugin.Log.LogInfo((object)"货币保底计数器已重置");
		}

		private static void Postfix(bool __result)
		{
			try
			{
				if (!__result)
				{
					return;
				}
				_dropCount++;
				_silkSpearAttempts++;
				if (!_hasGivenKey && _dropCount <= 30)
				{
					SavedItem val = ((IEnumerable<SavedItem>)Resources.FindObjectsOfTypeAll<SavedItem>()).FirstOrDefault((Func<SavedItem, bool>)((SavedItem item) => ((Object)item).name == keyName));
					if ((Object)(object)val != (Object)null)
					{
						val.TryGet(false, true);
						Plugin.Log.LogInfo((object)$"钥匙保底触发(第{_dropCount}次)");
						_hasGivenKey = true;
					}
				}
				if ((Object)(object)_silkSpearItem != (Object)null && !_silkSpearGiven && _silkSpearAttempts >= 200)
				{
					Plugin.Log.LogInfo((object)"丝矛保底触发");
					if (_silkSpearItem.TryGet(false, true))
					{
						Plugin.Log.LogInfo((object)"丝矛保底成功给予");
						Plugin.ShowNotification("获得丝矛!");
						_silkSpearGiven = true;
					}
					else
					{
						Plugin.Log.LogError((object)"丝矛保底失败");
						_silkSpearGiven = true;
					}
				}
				else if (_consecutiveMisses >= 104 || ItemRandomizer.RandomChance(1f / 105f))
				{
					SavedItem randomItem = ItemRandomizer.GetRandomItem();
					if ((Object)(object)randomItem != (Object)null)
					{
						randomItem.TryGet(false, true);
					}
					_consecutiveMisses = 0;
				}
				else
				{
					_consecutiveMisses++;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Exception in CurrencyCollectPatch: {arg}");
			}
		}
	}
	public static class ItemRandomizer
	{
		private static List<SavedItem>? _allItems;

		private static Random? _rng;

		public static readonly HashSet<string> ExcludedNames = new HashSet<string> { "Steel Spines", "Common Spine", "Plasmium", "Sliver Bell", "Seared Organ", "Shredded Organ", "Skewered Organ", "Ragpelt" };

		public static Random? Rng => _rng;

		public static void Initialize(int seed)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			SavedItem[] source = Resources.FindObjectsOfTypeAll<SavedItem>();
			_allItems = source.Where((SavedItem item) => (item is CollectableItem || item is ToolBase || item is CollectableRelic) && !ExcludedNames.Contains(((Object)item).name)).ToList();
			if (_allItems.Count == 0)
			{
				ManualLogSource log = Plugin.Log;
				Scene activeScene = SceneManager.GetActiveScene();
				log.LogWarning((object)("No eligible items found! Current scene: " + ((Scene)(ref activeScene)).name));
			}
			else
			{
				_rng = ((seed == 0) ? new Random() : new Random(seed));
			}
		}

		public static SavedItem? GetRandomItem()
		{
			if (_allItems == null || _allItems.Count == 0 || _rng == null)
			{
				Plugin.Log.LogWarning((object)"GetRandomItem: _allItems or _rng is null");
				return null;
			}
			for (int i = 0; i < 100; i++)
			{
				int index = _rng.Next(_allItems.Count);
				SavedItem val = _allItems[index];
				if (!((Object)(object)val == (Object)null) && !ExcludedNames.Contains(((Object)val).name))
				{
					return val;
				}
			}
			Plugin.Log.LogWarning((object)"GetRandomItem failed after 100 attempts, returning null");
			return null;
		}

		public static bool RandomChance(float probability)
		{
			if (_rng == null)
			{
				return false;
			}
			return _rng.NextDouble() < (double)probability;
		}

		public static SavedItem? PeekRandomItem(Random rng)
		{
			if (_allItems == null || _allItems.Count == 0 || rng == null)
			{
				return null;
			}
			for (int i = 0; i < 100; i++)
			{
				int index = rng.Next(_allItems.Count);
				SavedItem val = _allItems[index];
				if (!((Object)(object)val == (Object)null) && !ExcludedNames.Contains(((Object)val).name))
				{
					return val;
				}
			}
			return null;
		}

		public static List<SavedItem> GetAllItems()
		{
			return _allItems;
		}
	}
	[HarmonyPatch(typeof(CollectableItemPickup), "DoPickupAction")]
	public class PickupPatch
	{
		private static readonly Dictionary<string, string> ToolToSkillField = new Dictionary<string, string>
		{
			{ "Silk Spear", "hasNeedleThrow" },
			{ "Thread Sphere", "hasThreadSphere" },
			{ "Harpoon Dash", "hasHarpoonDash" },
			{ "Silk Charge", "hasSilkCharge" },
			{ "Silk Bomb", "hasSilkBomb" },
			{ "Silk Boss Needle", "hasSilkBossNeedle" },
			{ "Needolin", "hasNeedolin" },
			{ "Dash", "hasDash" },
			{ "Brolly", "hasBrolly" },
			{ "DoubleJump", "hasDoubleJump" },
			{ "Charge Slash", "hasChargeSlash" },
			{ "SuperJump", "hasSuperJump" },
			{ "Wall Jump", "hasWallJump" }
		};

		private static void Prefix(CollectableItemPickup __instance, ref bool __runOriginal)
		{
			//IL_0084: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!__runOriginal || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				SavedItem item = __instance.Item;
				if ((Object)(object)item == (Object)null || ItemRandomizer.ExcludedNames.Contains(((Object)item).name))
				{
					return;
				}
				SavedItem randomItem = ItemRandomizer.GetRandomItem();
				if ((Object)(object)randomItem == (Object)null)
				{
					return;
				}
				object[] array = new object[4];
				Scene scene = ((Component)__instance).gameObject.scene;
				array[0] = ((Scene)(ref scene)).name;
				array[1] = ((Component)__instance).transform.position.x;
				array[2] = ((Component)__instance).transform.position.y;
				array[3] = ((Component)__instance).transform.position.z;
				string key = string.Format("{0}_{1:F1}_{2:F1}_{3:F1}", array);
				if (item is CollectableRelic || item is ToolItem)
				{
					Plugin.AddDestroyedPickupKey(key);
					Plugin.Log.LogInfo((object)("特殊点 " + ((Object)item).name + " 强制销毁,给予随机物品 " + ((Object)randomItem).name));
					bool flag = false;
					ToolItem val = (ToolItem)(object)((randomItem is ToolItem) ? randomItem : null);
					if (val != null)
					{
						string skillFieldName = GetSkillFieldName(val.name);
						if (!string.IsNullOrEmpty(skillFieldName))
						{
							PlayerData instance = PlayerData.instance;
							if (instance != null)
							{
								FieldInfo field = ((object)instance).GetType().GetField(skillFieldName, BindingFlags.Instance | BindingFlags.Public);
								if (field != null && field.FieldType == typeof(bool))
								{
									field.SetValue(instance, true);
									flag = true;
								}
							}
						}
						try
						{
							MethodInfo methodInfo = typeof(ToolItem).GetMethod("Unlock", new Type[2]
							{
								typeof(Action),
								typeof(PopupFlags)
							}) ?? typeof(ToolItem).GetMethod("Unlock", Type.EmptyTypes);
							if (methodInfo != null)
							{
								if (methodInfo.GetParameters().Length == 0)
								{
									methodInfo.Invoke(val, null);
								}
								else
								{
									methodInfo.Invoke(val, new object[2]
									{
										null,
										(object)(PopupFlags)3
									});
								}
								flag = true;
							}
							else
							{
								Plugin.Log.LogError((object)"无法找到 ToolItem.Unlock 方法");
							}
						}
						catch (Exception arg)
						{
							Plugin.Log.LogError((object)$"Unlock 调用失败: {arg}");
						}
					}
					else
					{
						flag = randomItem.TryGet(false, true);
					}
					if (flag)
					{
						RecentItemsUI.AddItem(randomItem);
						Plugin.Log.LogInfo((object)("特殊点物品 " + ((Object)randomItem).name + " 给予成功"));
					}
					else
					{
						Plugin.Log.LogError((object)("特殊点物品 " + ((Object)randomItem).name + " 给予失败!"));
					}
					__runOriginal = false;
					Object.Destroy((Object)(object)((Component)__instance).gameObject);
				}
				else
				{
					Plugin.AddDestroyedPickupKey(key);
					Plugin.Log.LogInfo((object)("普通点 " + ((Object)item).name + " 强制销毁,给予随机物品 " + ((Object)randomItem).name));
					if (randomItem.TryGet(false, true))
					{
						RecentItemsUI.AddItem(randomItem);
						Plugin.Log.LogInfo((object)("普通点物品 " + ((Object)randomItem).name + " 给予成功"));
					}
					else
					{
						Plugin.Log.LogError((object)("普通点物品 " + ((Object)randomItem).name + " 给予失败!"));
					}
					__runOriginal = false;
					Object.Destroy((Object)(object)((Component)__instance).gameObject);
				}
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogError((object)$"Exception in PickupPatch.Prefix: {arg2}");
			}
		}

		private static string GetSkillFieldName(string toolName)
		{
			ToolToSkillField.TryGetValue(toolName, out string value);
			return value;
		}
	}
	[HarmonyPatch(typeof(ShopItemStats), "SetPurchased")]
	public static class ShopItemStats_Purchase_Patch
	{
		[CompilerGenerated]
		private sealed class <DelayedRebuild>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ShopMenuStock shop;

			private MethodInfo <buildMethod>5__1;

			private Exception <ex>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayedRebuild>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<buildMethod>5__1 = null;
				<ex>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					try
					{
						<buildMethod>5__1 = typeof(ShopMenuStock).GetMethod("BuildItemList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (<buildMethod>5__1 != null)
						{
							<buildMethod>5__1.Invoke(shop, null);
							Plugin.Log.LogInfo((object)"商店重建完成");
						}
						else
						{
							Plugin.Log.LogError((object)"未找到 BuildItemList 方法");
						}
						<buildMethod>5__1 = null;
					}
					catch (Exception ex)
					{
						<ex>5__2 = ex;
						Plugin.Log.LogError((object)$"商店重建异常: {<ex>5__2}");
					}
					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 void Prefix()
		{
			try
			{
				ToolUnlockPatch.IsShopPurchase = true;
			}
			catch
			{
			}
		}

		private static void Postfix(ShopItemStats __instance)
		{
			try
			{
				ToolUnlockPatch.IsShopPurchase = false;
				if ((Object)(object)((__instance != null) ? __instance.Item : null) == (Object)null)
				{
					Plugin.Log.LogWarning((object)"购买实例或物品为空,跳过处理");
					return;
				}
				string name = ((Object)__instance.Item).name;
				if (string.IsNullOrEmpty(name) || !name.Contains("_"))
				{
					Plugin.Log.LogWarning((object)("永久ID格式错误: " + name + ",仅隐藏物体"));
					((Component)__instance).gameObject.SetActive(false);
					return;
				}
				ShopMenuStock_BuildItemList_Patch.SetCount(name, 0);
				ShopMenuStock componentInParent = ((Component)__instance).GetComponentInParent<ShopMenuStock>();
				if ((Object)(object)componentInParent == (Object)null)
				{
					Plugin.Log.LogError((object)"无法获取 ShopMenuStock");
					return;
				}
				((Component)__instance).gameObject.SetActive(false);
				((MonoBehaviour)componentInParent).StartCoroutine(DelayedRebuild(componentInParent));
				Plugin.Log.LogInfo((object)("永久ID " + name + " 已购买,触发商店重建"));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"购买后处理异常: {arg}");
				if ((Object)(object)__instance != (Object)null)
				{
					((Component)__instance).gameObject.SetActive(false);
				}
			}
		}

		[IteratorStateMachine(typeof(<DelayedRebuild>d__2))]
		private static IEnumerator DelayedRebuild(ShopMenuStock shop)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedRebuild>d__2(0)
			{
				shop = shop
			};
		}
	}
	[HarmonyPatch(typeof(ShopMenuStock), "BuildItemList")]
	public static class ShopMenuStock_BuildItemList_Patch
	{
		private static Dictionary<string, int> _slotCounts = new Dictionary<string, int>();

		private static string FilePath => Path.Combine(Paths.ConfigPath, "SilksongItemRandomizer", "shop_slots.json");

		private static void LoadCounts()
		{
			try
			{
				if (File.Exists(FilePath))
				{
					string text = File.ReadAllText(FilePath);
					_slotCounts = JsonConvert.DeserializeObject<Dictionary<string, int>>(text) ?? new Dictionary<string, int>();
				}
				else
				{
					_slotCounts.Clear();
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"加载商店槽位计数失败: {arg}");
				_slotCounts.Clear();
			}
		}

		private static void SaveCounts()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(FilePath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				string contents = JsonConvert.SerializeObject((object)_slotCounts, (Formatting)1);
				File.WriteAllText(FilePath, contents);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"保存商店槽位计数失败: {arg}");
			}
		}

		public static int GetCount(string permanentId)
		{
			int value;
			return (!_slotCounts.TryGetValue(permanentId, out value)) ? 1 : value;
		}

		public static void SetCount(string permanentId, int count)
		{
			_slotCounts[permanentId] = count;
			SaveCounts();
		}

		public static void ResetAllCounts()
		{
			_slotCounts.Clear();
			if (File.Exists(FilePath))
			{
				File.Delete(FilePath);
			}
			Plugin.Log.LogInfo((object)"商店槽位计数已重置");
		}

		private static void Postfix(ShopMenuStock __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				LoadCounts();
				__instance.availableStock.Clear();
				float num = 0f;
				foreach (ShopItemStats item2 in __instance.spawnedStock)
				{
					if ((Object)(object)item2 == (Object)null)
					{
						continue;
					}
					ShopItem item = item2.Item;
					string text = ((item != null) ? ((Object)item).name : null);
					if (string.IsNullOrEmpty(text) || !text.Contains("_"))
					{
						int num2 = __instance.spawnedStock.IndexOf(item2);
						text = $"{name}_{num2}";
					}
					int count = GetCount(text);
					if (count <= 0)
					{
						((Component)item2).gameObject.SetActive(false);
						continue;
					}
					int price;
					SavedItem orCreateShopItem = ShopRandomizer.GetOrCreateShopItem(text, out price);
					if ((Object)(object)orCreateShopItem == (Object)null)
					{
						Plugin.Log.LogWarning((object)("商店随机:永久ID " + text + " 获取物品失败,跳过"));
						continue;
					}
					ShopItem val = CreateShopItem(orCreateShopItem, price, text);
					if (!((Object)(object)val == (Object)null))
					{
						item2.SetItem(val);
						((Component)item2).transform.localPosition = new Vector3(0f, num, 0f);
						item2.ItemNumber = __instance.availableStock.Count;
						__instance.availableStock.Add(item2);
						num += __instance.yDistance;
						((Component)item2).gameObject.SetActive(true);
						item2.UpdateAppearance();
						Plugin.Log.LogInfo((object)$"商店重建:永久ID {text} -> {((Object)orCreateShopItem).name} 价格 {price}");
					}
				}
				foreach (ShopSubItemStats spawnedSubItem in __instance.spawnedSubItems)
				{
					((Component)spawnedSubItem).gameObject.SetActive(false);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"商店重建补丁异常: {arg}");
			}
		}

		private static ShopItem CreateShopItem(SavedItem savedItem, int price, string permanentId)
		{
			ShopItem val = ShopItem.CreateTemp(((Object)savedItem).name);
			((Object)val).name = permanentId;
			FieldInfo field = typeof(ShopItem).GetField("savedItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(val, savedItem);
				FieldInfo field2 = typeof(ShopItem).GetField("cost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 != null)
				{
					field2.SetValue(val, price);
					FieldInfo field3 = typeof(ShopItem).GetField("costReference", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field3 != null)
					{
						field3.SetValue(val, null);
					}
					FieldInfo field4 = typeof(ShopItem).GetField("currencyType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field4 != null)
					{
						field4.SetValue(val, (object)(CurrencyType)0);
					}
					ClearField(val, "playerDataBoolName");
					ClearField(val, "playerDataIntName");
					ClearField(val, "requiredItem");
					ClearField(val, "upgradeFromItem");
					if (val.questsAppearConditions == null)
					{
						val.questsAppearConditions = (QuestTest[])(object)new QuestTest[0];
					}
					return val;
				}
				Plugin.Log.LogError((object)"未找到 cost 字段");
				return null;
			}
			Plugin.Log.LogError((object)"未找到 savedItem 字段");
			return null;
		}

		private static void ClearField(object obj, string fieldName)
		{
			FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && field.FieldType.IsClass)
			{
				field.SetValue(obj, null);
			}
		}
	}
	public static class ShopRandomizer
	{
		private static Dictionary<string, SavedItem> _shopItemCache = new Dictionary<string, SavedItem>();

		private static Dictionary<string, int> _shopPriceCache = new Dictionary<string, int>();

		public static void ResetCache()
		{
			_shopItemCache.Clear();
			_shopPriceCache.Clear();
			Plugin.Log.LogInfo((object)"商店随机缓存已清空");
		}

		public static SavedItem GetOrCreateShopItem(string permanentId, out int price)
		{
			if (_shopItemCache.TryGetValue(permanentId, out SavedItem value))
			{
				if (!IsItemOwned(value))
				{
					price = (_shopPriceCache.TryGetValue(permanentId, out var value2) ? value2 : GetDefaultPrice(value));
					return value;
				}
				Plugin.Log.LogInfo((object)("商店槽位 " + permanentId + " 的物品 " + ((Object)value).name + " 已拥有,重新生成"));
			}
			string[] array = permanentId.Split('_');
			string sceneName = string.Join("_", array.Take(array.Length - 1));
			int originalIndex = int.Parse(array.Last());
			int price2;
			SavedItem val = GenerateRandomShopItem(sceneName, originalIndex, permanentId, out price2);
			_shopItemCache[permanentId] = val;
			_shopPriceCache[permanentId] = price2;
			price = price2;
			return val;
		}

		public static SavedItem GetOrCreateShopItem(string sceneName, int slotIndex, out int price)
		{
			string permanentId = $"{sceneName}_{slotIndex}";
			return GetOrCreateShopItem(permanentId, out price);
		}

		private static SavedItem GenerateRandomShopItem(string sceneName, int originalIndex, string permanentId, out int price)
		{
			int value = Plugin.RandomSeed.Value;
			int hashCode = permanentId.GetHashCode();
			int seed = value ^ hashCode;
			Random random = new Random(seed);
			List<SavedItem> allItems = ItemRandomizer.GetAllItems();
			if (allItems == null || allItems.Count == 0)
			{
				price = 0;
				return null;
			}
			List<SavedItem> list = allItems.Where((SavedItem item) => !IsItemOwned(item) && !(item is ToolCrest)).ToList();
			if (list.Count == 0)
			{
				Plugin.Log.LogWarning((object)("商店随机池为空,使用所有物品中的第一个 (永久ID: " + permanentId + ")"));
				price = GetDefaultPrice(allItems[0]);
				return allItems[0];
			}
			int index = random.Next(list.Count);
			SavedItem val = list[index];
			price = GenerateRandomPrice(val, random);
			return val;
		}

		private static bool IsItemOwned(SavedItem item)
		{
			try
			{
				if (!item.CanGetMore())
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static int GenerateRandomPrice(SavedItem item, Random rng)
		{
			int defaultPrice = GetDefaultPrice(item);
			float num = (float)(rng.NextDouble() * 1.95 + 0.05);
			return Mathf.RoundToInt((float)defaultPrice * num);
		}

		private static int GetDefaultPrice(SavedItem item)
		{
			FieldInfo field = ((object)item).GetType().GetField("cost", BindingFlags.Instance | BindingFlags.Public);
			if (field != null && field.FieldType == typeof(int))
			{
				return (int)field.GetValue(item);
			}
			return 100;
		}
	}
	[BepInPlugin("YourName.SilksongItemRandomizer", "Silksong Item Randomizer", "1.0.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <DestroyMarkedPickups>d__25 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Scene scene;

			public Plugin <>4__this;

			private CollectableItemPickup[] <pickups>5__1;

			private CollectableItemPickup[] <>s__2;

			private int <>s__3;

			private CollectableItemPickup <p>5__4;

			private string <key>5__5;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DestroyMarkedPickups>d__25(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<pickups>5__1 = null;
				<>s__2 = null;
				<p>5__4 = null;
				<key>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<pickups>5__1 = Resources.FindObjectsOfTypeAll<CollectableItemPickup>();
					Log.LogInfo((object)$"[DestroyMarkedPickups] 开始检查场景 {((Scene)(ref scene)).name},已记录键数:{_destroyedPickupKeys.Count}");
					<>s__2 = <pickups>5__1;
					for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++)
					{
						<p>5__4 = <>s__2[<>s__3];
						if (!(((Component)<p>5__4).gameObject.scene != scene))
						{
							<key>5__5 = $"{((Scene)(ref scene)).name}_{((Component)<p>5__4).transform.position.x:F1}_{((Component)<p>5__4).transform.position.y:F1}_{((Component)<p>5__4).transform.position.z:F1}";
							if (_destroyedPickupKeys.Contains(<key>5__5))
							{
								Object.Destroy((Object)(object)((Component)<p>5__4).gameObject);
								Log.LogInfo((object)("[DestroyMarkedPickups] 销毁已标记点: " + <key>5__5));
							}
							<key>5__5 = null;
							<p>5__4 = null;
						}
					}
					<>s__2 = null;
					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();
			}
		}

		[CompilerGenerated]
		private sealed class <InitializeAfterLoad>d__24 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public int seed;

			public Plugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitializeAfterLoad>d__24(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					ItemRandomizer.Initialize(seed);
					ToolUnlockPatch.Initialize();
					CrestRandomizer.Initialize();
					Log.LogInfo((object)$"种子: {seed}");
					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();
			}
		}

		internal static ManualLogSource Log;

		private static HashSet<string> _destroyedPickupKeys = new HashSet<string>();

		private static string _notificationMessage = null;

		private static float _notificationEndTime = 0f;

		private static GUIStyle _notificationStyle;

		public static ConfigEntry<int> RandomSeed { get; private set; }

		public static Plugin Instance { get; private set; }

		private static string DestroyedPickupsFilePath
		{
			get
			{
				string text = Path.Combine(Paths.ConfigPath, "SilksongItemRandomizer");
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
				}
				return Path.Combine(text, "destroyed_pickups.json");
			}
		}

		public static void ShowNotification(string message, float duration = 3f)
		{
			_notificationMessage = message;
			_notificationEndTime = Time.time + duration;
		}

		private Texture2D MakeTexture(int width, int height, Color col)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			RandomSeed = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RandomSeed", 0, "随机种子 (0 表示随机)");
			Harmony.CreateAndPatchAll(typeof(PickupPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(CurrencyCollectPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(TryGetPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(ToolUnlockPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(CrestRandomizePatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(ShopMenuStock_BuildItemList_Patch), (string)null);
			Harmony.CreateAndPatchAll(typeof(ShopItemStats_Purchase_Patch), (string)null);
			Harmony.CreateAndPatchAll(typeof(SilkSpearPityPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(BenchRespawnPatch), (string)null);
			HazardSpawner.Initialize();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((MonoBehaviour)this).StartCoroutine(InitializeAfterLoad(RandomSeed.Value));
			LoadDestroyedKeys();
			Log.LogInfo((object)"SilksongItemRandomizer loaded");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StartCoroutine(DestroyMarkedPickups(scene));
		}

		private void LoadDestroyedKeys()
		{
			string destroyedPickupsFilePath = DestroyedPickupsFilePath;
			if (File.Exists(destroyedPickupsFilePath))
			{
				try
				{
					string text = File.ReadAllText(destroyedPickupsFilePath);
					List<string> list = JsonConvert.DeserializeObject<List<string>>(text);
					_destroyedPickupKeys = ((list != null) ? new HashSet<string>(list) : new HashSet<string>());
					return;
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"加载特殊点消失记录失败: {arg}");
					_destroyedPickupKeys = new HashSet<string>();
					return;
				}
			}
			_destroyedPickupKeys = new HashSet<string>();
		}

		private void SaveDestroyedKeys()
		{
			string destroyedPickupsFilePath = DestroyedPickupsFilePath;
			try
			{
				List<string> list = _destroyedPickupKeys.ToList();
				string contents = JsonConvert.SerializeObject((object)list, (Formatting)1);
				File.WriteAllText(destroyedPickupsFilePath, contents);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"保存特殊点消失记录失败: {arg}");
			}
		}

		public static void AddDestroyedPickupKey(string key)
		{
			_destroyedPickupKeys.Add(key);
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.SaveDestroyedKeys();
			}
			else
			{
				Log.LogError((object)"AddDestroyedPickupKey: Instance is null");
			}
		}

		public static void ResetDestroyedPickupKeys()
		{
			_destroyedPickupKeys.Clear();
			string destroyedPickupsFilePath = DestroyedPickupsFilePath;
			if (File.Exists(destroyedPickupsFilePath))
			{
				File.Delete(destroyedPickupsFilePath);
			}
		}

		public static void ResetAllStaticData()
		{
			CrestRandomizer.ResetMappings();
			CrestRandomizePatch.ResetProcessedIds();
			CurrencyCollectPatch.ResetCounters();
			ResetDestroyedPickupKeys();
			ShopRandomizer.ResetCache();
			ShopMenuStock_BuildItemList_Patch.ResetAllCounts();
			Log.LogInfo((object)"物品随机MOD所有静态数据已重置");
			Log.LogInfo((object)"物品随机MOD所有静态数据已重置");
		}

		[IteratorStateMachine(typeof(<InitializeAfterLoad>d__24))]
		private IEnumerator InitializeAfterLoad(int seed)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitializeAfterLoad>d__24(0)
			{
				<>4__this = this,
				seed = seed
			};
		}

		[IteratorStateMachine(typeof(<DestroyMarkedPickups>d__25))]
		private IEnumerator DestroyMarkedPickups(Scene scene)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DestroyMarkedPickups>d__25(0)
			{
				<>4__this = this,
				scene = scene
			};
		}

		private void Update()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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)
			RecentItemsUI.UpdateAutoHide();
			if (Input.GetKeyDown((KeyCode)286))
			{
				RecentItemsUI.Toggle();
				Log.LogInfo((object)("最近获得物品UI " + (RecentItemsUI.IsVisible ? "显示" : "隐藏")));
			}
			if (Input.GetKeyDown((KeyCode)289))
			{
				DumpAllMappings();
			}
			if (Input.GetKeyDown((KeyCode)290))
			{
				HeroController instance = HeroController.instance;
				if ((Object)(object)instance != (Object)null)
				{
					Vector3 val = instance.transform.position + HazardSpawner.GetSpawnOffset();
					HazardSpawner.SpawnCustomHazard(val);
					Log.LogInfo((object)$"在玩家位置 + 偏移生成 hazard,最终坐标: {val}");
				}
			}
		}

		private void OnGUI()
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			RecentItemsUI.Draw();
			HazardSpawner.DrawUI();
			if (_notificationMessage != null && Time.time <= _notificationEndTime)
			{
				if (_notificationStyle == null)
				{
					_notificationStyle = new GUIStyle(GUI.skin.box);
					_notificationStyle.fontSize = 40;
					_notificationStyle.alignment = (TextAnchor)4;
					_notificationStyle.normal.textColor = Color.white;
					_notificationStyle.normal.background = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.7f));
				}
				float num = 600f;
				float num2 = 120f;
				float num3 = ((float)Screen.width - num) / 2f;
				float num4 = Screen.height / 2 - 100;
				GUI.Box(new Rect(num3, num4, num, num2), _notificationMessage, _notificationStyle);
			}
			else
			{
				_notificationMessage = null;
			}
		}

		private void DumpAllMappings()
		{
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			int value = RandomSeed.Value;
			Log.LogInfo((object)$"===== 当前种子: {value} =====");
			List<ToolCrest> crestList = CrestRandomizer.CrestList;
			if (crestList != null && crestList.Count > 0)
			{
				Log.LogInfo((object)"--- 纹章映射 ---");
				foreach (ToolCrest item2 in crestList)
				{
					string name = item2.name;
					string mappedCrestName = CrestRandomizer.GetMappedCrestName(name);
					Log.LogInfo((object)("  " + name + " -> " + mappedCrestName));
				}
			}
			Log.LogInfo((object)"--- 当前场景拾取点映射 ---");
			CollectableItemPickup[] source = Resources.FindObjectsOfTypeAll<CollectableItemPickup>();
			List<CollectableItemPickup> list = source.Where(delegate(CollectableItemPickup p)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				_ = ((Component)p).gameObject.scene;
				Scene scene = ((Component)p).gameObject.scene;
				return ((Scene)(ref scene)).isLoaded;
			}).ToList();
			if (list.Count == 0)
			{
				Log.LogInfo((object)"当前场景无拾取点。");
			}
			else
			{
				foreach (CollectableItemPickup item3 in list)
				{
					SavedItem item = item3.Item;
					if (!((Object)(object)item == (Object)null))
					{
						int seed = value + ((Object)item3).GetInstanceID();
						Random rng = new Random(seed);
						SavedItem val = ItemRandomizer.PeekRandomItem(rng);
						if ((Object)(object)val != (Object)null)
						{
							Log.LogInfo((object)$"  {((Object)item).name} (位置 {((Component)item3).transform.position}) -> {((Object)val).name}");
						}
						else
						{
							Log.LogInfo((object)("  " + ((Object)item).name + " -> 随机失败"));
						}
					}
				}
			}
			Log.LogInfo((object)"===============================");
		}
	}
	public static class RecentItemsUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DoWindow;
		}

		private static Queue<SavedItem> recentItems = new Queue<SavedItem>();

		private const int MaxItems = 5;

		private static Rect windowRect = new Rect(20f, 300f, 700f, 600f);

		private static bool _showWindow = false;

		private static float hideTime = 0f;

		public static bool IsVisible => _showWindow;

		public static void AddItem(SavedItem item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				recentItems.Enqueue(item);
				while (recentItems.Count > 5)
				{
					recentItems.Dequeue();
				}
				_showWindow = true;
				hideTime = Time.time + 10f;
			}
		}

		public static void Toggle()
		{
			_showWindow = !_showWindow;
			if (_showWindow)
			{
				hideTime = float.MaxValue;
			}
		}

		public static void UpdateAutoHide()
		{
			if (_showWindow && Time.time >= hideTime)
			{
				_showWindow = false;
			}
		}

		public static void Draw()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			if (_showWindow)
			{
				Rect val = windowRect;
				object obj = <>O.<0>__DoWindow;
				if (obj == null)
				{
					WindowFunction val2 = DoWindow;
					<>O.<0>__DoWindow = val2;
					obj = (object)val2;
				}
				windowRect = GUILayout.Window(999, val, (WindowFunction)obj, "最近获得物品", Array.Empty<GUILayoutOption>());
			}
		}

		private static void DoWindow(int id)
		{
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			int fontSize = GUI.skin.label.fontSize;
			GUI.skin.label.fontSize = 32;
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			SavedItem[] array = recentItems.ToArray();
			Rect val3 = default(Rect);
			foreach (SavedItem val in array)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				Sprite val2 = null;
				try
				{
					val2 = ((val != null) ? val.GetPopupIcon() : null);
				}
				catch
				{
				}
				float num = 96f;
				float num2 = 96f;
				((Rect)(ref val3))..ctor(0f, 0f, 1f, 1f);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.texture != (Object)null)
				{
					Rect textureRect = val2.textureRect;
					float num3 = ((Texture)val2.texture).width;
					float num4 = ((Texture)val2.texture).height;
					((Rect)(ref val3))..ctor(((Rect)(ref textureRect)).x / num3, ((Rect)(ref textureRect)).y / num4, ((Rect)(ref textureRect)).width / num3, ((Rect)(ref textureRect)).height / num4);
					if (((Rect)(ref textureRect)).width > 0f && ((Rect)(ref textureRect)).height > 0f)
					{
						num2 = num * (((Rect)(ref textureRect)).height / ((Rect)(ref textureRect)).width);
						if (num2 > 180f)
						{
							num2 = 180f;
						}
					}
				}
				Rect rect = GUILayoutUtility.GetRect(num, num2, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(num),
					GUILayout.Height(num2)
				});
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.texture != (Object)null)
				{
					GUI.DrawTextureWithTexCoords(rect, (Texture)(object)val2.texture, val3);
				}
				else
				{
					GUI.Box(rect, "");
					GUI.Label(rect, "?", new GUIStyle(GUI.skin.label)
					{
						alignment = (TextAnchor)4,
						fontSize = 36
					});
				}
				string text = "未知物品";
				try
				{
					MethodInfo methodInfo = ((object)val)?.GetType().GetMethod("GetCollectionName", BindingFlags.Instance | BindingFlags.Public);
					text = ((!(methodInfo != null)) ? ((val != null) ? val.GetPopupName() : null) : (methodInfo.Invoke(val, null) as string));
					if (string.IsNullOrEmpty(text))
					{
						text = ((val != null) ? ((Object)val).name : null) ?? "未知物品";
					}
				}
				catch
				{
					text = ((val != null) ? ((Object)val).name : null) ?? "未知物品";
				}
				GUILayout.Label("• " + text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num2) });
				GUILayout.EndHorizontal();
			}
			GUILayout.EndVertical();
			GUI.DragWindow();
			GUI.skin.label.fontSize = fontSize;
		}
	}
	[HarmonyPatch(typeof(CurrencyObjectBase), "Collect")]
	public static class SilkSpearPityPatch
	{
		private static int _silkSpearAttempts;

		private static bool _silkSpearGiven;

		private const int SILK_SPEAR_PITY = 200;

		private static SavedItem? _silkSpearItem;

		public static bool IsGivingSilkSpear;

		static SilkSpearPityPatch()
		{
			_silkSpearAttempts = 0;
			_silkSpearGiven = false;
			IsGivingSilkSpear = false;
			SavedItem[] source = Resources.FindObjectsOfTypeAll<SavedItem>();
			_silkSpearItem = ((IEnumerable<SavedItem>)source).FirstOrDefault((Func<SavedItem, bool>)((SavedItem item) => ((Object)item).name == "Silk Spear"));
			if ((Object)(object)_silkSpearItem == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[丝矛独立补丁] 未找到丝矛物品,保底将禁用。");
			}
			else
			{
				Plugin.Log.LogInfo((object)("[丝矛独立补丁] 丝矛物品已找到: " + ((Object)_silkSpearItem).name));
			}
		}

		public static void ResetCounter()
		{
			_silkSpearAttempts = 0;
			_silkSpearGiven = false;
			Plugin.Log.LogInfo((object)"[丝矛独立补丁] 计数器已重置");
		}

		private static void Postfix(bool __result)
		{
			if (!__result || (Object)(object)_silkSpearItem == (Object)null || _silkSpearGiven)
			{
				return;
			}
			_silkSpearAttempts++;
			if (_silkSpearGiven || _silkSpearAttempts < 200)
			{
				return;
			}
			Plugin.Log.LogInfo((object)$"[丝矛独立补丁] 保底触发(第{_silkSpearAttempts}次)");
			bool flag = false;
			IsGivingSilkSpear = true;
			SavedItem? silkSpearItem = _silkSpearItem;
			ToolItem val = (ToolItem)(object)((silkSpearItem is ToolItem) ? silkSpearItem : null);
			if (val != null)
			{
				try
				{
					MethodInfo methodInfo = typeof(ToolItem).GetMethod("Unlock", Type.EmptyTypes) ?? typeof(ToolItem).GetMethod("Unlock", new Type[2]
					{
						typeof(Action),
						typeof(PopupFlags)
					});
					if (methodInfo != null)
					{
						if (methodInfo.GetParameters().Length == 0)
						{
							methodInfo.Invoke(val, null);
						}
						else
						{
							methodInfo.Invoke(val, new object[2]
							{
								null,
								(object)(PopupFlags)3
							});
						}
						flag = true;
					}
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"[丝矛独立补丁] Unlock 失败: {arg}");
				}
			}
			else
			{
				flag = _silkSpearItem.TryGet(false, true);
			}
			IsGivingSilkSpear = false;
			if (flag)
			{
				Plugin.Log.LogInfo((object)"[丝矛独立补丁] 丝矛成功给予");
				Plugin.ShowNotification("获得丝矛!");
				_silkSpearGiven = true;
			}
			else
			{
				Plugin.Log.LogError((object)"[丝矛独立补丁] 丝矛给予失败");
				_silkSpearGiven = true;
			}
		}
	}
	public static class ToolUnlockPatch
	{
		private static List<ToolItem>? _allTools;

		public static bool IsShopPurchase;

		public static void Initialize()
		{
			_allTools = Resources.FindObjectsOfTypeAll<ToolItem>().ToList();
			if (_allTools.Count == 0)
			{
				Plugin.Log.LogWarning((object)"No ToolItem found! Tool randomizer may not work.");
			}
		}

		[HarmonyPatch(typeof(ToolItem), "Unlock")]
		[HarmonyPrefix]
		private static bool Prefix(ToolItem __instance, Action afterTutorialMsg, PopupFlags popupFlags)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (IsShopPurchase)
				{
					return true;
				}
				if (_allTools == null || _allTools.Count == 0)
				{
					Initialize();
					if (_allTools == null || _allTools.Count == 0)
					{
						Plugin.Log.LogWarning((object)"Tool list empty, cannot randomize.");
						return true;
					}
				}
				ToolItem val = _allTools[ItemRandomizer.Rng.Next(_allTools.Count)];
				if ((Object)(object)val == (Object)(object)__instance)
				{
					return true;
				}
				Plugin.Log.LogInfo((object)("工具随机: " + (((__instance != null) ? __instance.name : null) ?? "null") + " -> " + val.name));
				val.Unlock(afterTutorialMsg, popupFlags);
				return false;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Exception in ToolUnlockPatch.Prefix: {arg}");
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(SavedItem), "TryGet")]
	public class TryGetPatch
	{
		private static bool _isProcessing;

		private static void Postfix(SavedItem __instance, bool __result)
		{
			try
			{
				if (_isProcessing || !__result)
				{
					return;
				}
				if (((Object)__instance).name != "Rosary_Set_Frayed")
				{
					RecentItemsUI.AddItem(__instance);
				}
				_isProcessing = true;
				try
				{
					UnlockRandomAttack();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Error unlocking attack: {arg}");
				}
				finally
				{
					_isProcessing = false;
				}
			}
			catch (Exception arg2)
			{
				Plugin.Log.LogError((object)$"Unhandled exception in TryGetPatch.Postfix: {arg2}");
			}
		}

		private static void UnlockRandomAttack()
		{
			Type type = Type.GetType("StartingAbilityPicker.Plugin, StartingAbilityPicker");
			if (type == null)
			{
				return;
			}
			FieldInfo field = type.GetField("AllowUpwardAttack", BindingFlags.Static | BindingFlags.Public);
			FieldInfo field2 = type.GetField("AllowLeftAttack", BindingFlags.Static | BindingFlags.Public);
			FieldInfo field3 = type.GetField("AllowRightAttack", BindingFlags.Static | BindingFlags.Public);
			if (field == null || field2 == null || field3 == null)
			{
				return;
			}
			bool flag = (bool)field.GetValue(null);
			bool flag2 = (bool)field2.GetValue(null);
			bool flag3 = (bool)field3.GetValue(null);
			List<string> list = new List<string>();
			if (!flag)
			{
				list.Add("upward");
			}
			if (!flag2)
			{
				list.Add("left");
			}
			if (!flag3)
			{
				list.Add("right");
			}
			if (list.Count == 0 || ItemRandomizer.Rng == null || ItemRandomizer.Rng.NextDouble() > 0.05)
			{
				return;
			}
			string text = list[ItemRandomizer.Rng.Next(list.Count)];
			PlayerData instance = PlayerData.instance;
			if (instance != null)
			{
				switch (text)
				{
				case "upward":
					field.SetValue(null, true);
					instance.SetBool("AllowUpwardAttack", true);
					Plugin.Log.LogInfo((object)"Attack direction unlocked via item: upward (saved to PlayerData)");
					break;
				case "left":
					field2.SetValue(null, true);
					instance.SetBool("AllowLeftAttack", true);
					Plugin.Log.LogInfo((object)"Attack direction unlocked via item: left (saved to PlayerData)");
					break;
				case "right":
					field3.SetValue(null, true);
					instance.SetBool("AllowRightAttack", true);
					Plugin.Log.LogInfo((object)"Attack direction unlocked via item: right (saved to PlayerData)");
					break;
				}
			}
		}
	}
}
namespace SilksongItemRandomizer.Hazard
{
	public class HazardDebug : MonoBehaviour
	{
		private void OnTriggerEnter2D(Collider2D other)
		{
			if (((Component)other).CompareTag("Hero") || ((Component)other).CompareTag("Player"))
			{
				Plugin.Log.LogInfo((object)"【调试】玩家进入 hazard 触发器!");
			}
		}
	}
	public static class HazardSpawner
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DoUIWindow;

			public static UnityAction<Scene, LoadSceneMode> <1>__OnSceneLoaded;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass28_0
		{
			public Vector3 spawnPos;

			internal bool <AutoGenerateForSceneCoroutine>b__0(Vector3 pos)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				return Vector3.Distance(pos, spawnPos) < 2f;
			}
		}

		[CompilerGenerated]
		private sealed class <AutoGenerateForSceneCoroutine>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string sceneName;

			private List<Vector3> <positions>5__1;

			private int <maxAttempts>5__2;

			private int <generated>5__3;

			private Random <rand>5__4;

			private int <attempt>5__5;

			private Vector3 <center>5__6;

			private Vector2 <randomPoint>5__7;

			private RaycastHit2D <hit>5__8;

			private <>c__DisplayClass28_0 <>8__9;

			private bool <tooClose>5__10;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AutoGenerateForSceneCoroutine>d__28(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<positions>5__1 = null;
				<rand>5__4 = null;
				<>8__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d5: 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_0152: Unknown result type (might be due to invalid IL or missing references)
				//IL_020c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0211: Unknown result type (might be due to invalid IL or missing references)
				//IL_0216: Unknown result type (might be due to invalid IL or missing references)
				//IL_026c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0283: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (_sceneRecords.ContainsKey(sceneName))
					{
						Plugin.Log.LogInfo((object)("场景 " + sceneName + " 已有记录,跳过生成"));
						return false;
					}
					if (_sceneHazardCount <= 0)
					{
						Plugin.Log.LogInfo((object)("场景 " + sceneName + " 生成数量为 0,跳过"));
						return false;
					}
					Plugin.Log.LogInfo((object)$"开始为场景 {sceneName} 自动生成 {_sceneHazardCount} 个 hazard");
					<positions>5__1 = new List<Vector3>();
					<maxAttempts>5__2 = 200;
					<generated>5__3 = 0;
					<rand>5__4 = ((_currentSeed != 0) ? new Random(_currentSeed + sceneName.GetHashCode()) : new Random());
					<attempt>5__5 = 0;
					while (<attempt>5__5 < <maxAttempts>5__2 && <generated>5__3 < _sceneHazardCount)
					{
						<center>5__6 = new Vector3(0f, 0f, 0f);
						if ((Object)(object)Object.FindObjectOfType<HeroController>() != (Object)null)
						{
							<center>5__6 = Object.FindObjectOfType<HeroController>().transform.position;
						}
						<randomPoint>5__7 = new Vector2(<center>5__6.x + (float)(<rand>5__4.NextDouble() * 100.0 - 50.0), <center>5__6.y + (float)(<rand>5__4.NextDouble() * 100.0 - 50.0));
						<hit>5__8 = Physics2D.Raycast(<randomPoint>5__7, Vector2.down, 100f, GROUND_LAYER_MASK);
						if ((Object)(object)((RaycastHit2D)(ref <hit>5__8)).collider != (Object)null)
						{
							<>8__9 = new <>c__DisplayClass28_0();
							<>8__9.spawnPos = Vector2.op_Implicit(((RaycastHit2D)(ref <hit>5__8)).point);
							<>8__9.spawnPos.y += 0.1f;
							<tooClose>5__10 = <positions>5__1.Any((Vector3 pos) => Vector3.Distance(pos, <>8__9.spawnPos) < 2f);
							if (!<tooClose>5__10)
							{
								SpawnCustomHazard(<>8__9.spawnPos);
								<positions>5__1.Add(<>8__9.spawnPos);
								<generated>5__3++;
							}
							<>8__9 = null;
						}
						<attempt>5__5++;
					}
					_sceneRecords[sceneName] = <positions>5__1;
					SaveSceneRecords();
					Plugin.Log.LogInfo((object)$"场景 {sceneName} 自动生成完成,实际生成 {<generated>5__3} 个");
					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 List<GameObject> _spawnedHazards = new List<GameObject>();

		private static List<Sprite> _lavaSprites = new List<Sprite>();

		private static readonly int GROUND_LAYER_MASK = 1049344;

		private static Vector3 _spawnOffset = Vector3.zero;

		private static Vector2 _boxSize = new Vector2(6f, 2f);

		private static Vector2 _boxOffset = new Vector2(0f, 0f);

		private static int _damage = 2;

		private static HazardType _hazardType = (HazardType)4;

		private static Vector2 _visualSize = new Vector2(1.5f, 1.5f);

		private static Vector2 _visualOffset = new Vector2(0f, -1f);

		private static bool _sceneHazardMode = true;

		private static int _sceneHazardCount = 2;

		private static int _currentSeed;

		private static Dictionary<string, List<Vector3>> _sceneRecords = new Dictionary<string, List<Vector3>>();

		private static string _sceneRecordFilePath;

		private static bool _sceneLoadedHandlerRegistered = false;

		private static string _logFilePath;

		private static readonly object _logLock = new object();

		private static bool _uiVisible = false;

		private static Rect _uiRect = new Rect(0f, 0f, 500f, 500f);

		public static void ToggleUI()
		{
			_uiVisible = !_uiVisible;
		}

		public static void DrawUI()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			if (_uiVisible)
			{
				Rect uiRect = _uiRect;
				object obj = <>O.<0>__DoUIWindow;
				if (obj == null)
				{
					WindowFunction val = DoUIWindow;
					<>O.<0>__DoUIWindow = val;
					obj = (object)val;
				}
				_uiRect = GUILayout.Window(999, uiRect, (WindowFunction)obj, "Hazard 参数调整", Array.Empty<GUILayoutOption>());
			}
		}

		private static void DoUIWindow(int id)
		{
		}

		public static void Initialize()
		{
			LoadLocalSprites();
			Physics2D.IgnoreLayerCollision(17, 8, false);
			string text = Path.Combine(Paths.ConfigPath, "SilksongItemRandomizer");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			_logFilePath = Path.Combine(text, "HazardSpawnLog.json");
			_sceneRecordFilePath = Path.Combine(text, "hazard_scene_records.json");
			LoadSceneRecords();
			if (!_sceneLoadedHandlerRegistered)
			{
				SceneManager.sceneLoaded += OnSceneLoaded;
				_sceneLoadedHandlerRegistered = true;
			}
			Plugin.Log.LogInfo((object)("HazardSpawner 初始化完成,日志文件: " + _logFilePath));
		}

		private static void LoadLocalSprites()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			_lavaSprites.Clear();
			string text = Path.Combine(Paths.PluginPath, "SilksongItemRandomizer", "Textures", "Lava");
			Plugin.Log.LogInfo((object)("[LoadLocalSprites] 路径: " + text));
			if (!Directory.Exists(text))
			{
				Plugin.Log.LogError((object)("文件夹不存在!请确保贴图放在: " + text));
				return;
			}
			string[] array = (from f in Directory.GetFiles(text, "*.*")
				where f.EndsWith(".jpg") || f.EndsWith(".jpeg") || f.EndsWith(".png")
				orderby f
				select f).ToArray();
			Plugin.Log.LogInfo((object)$"找到 {array.Length} 个图片文件");
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				try
				{
					byte[] array3 = File.ReadAllBytes(text2);
					Texture2D val = new Texture2D(2, 2);
					if (ImageConversion.LoadImage(val, array3))
					{
						Sprite item = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
						_lavaSprites.Add(item);
						Plugin.Log.LogInfo((object)$"加载成功: {Path.GetFileName(text2)} {((Texture)val).width}x{((Texture)val).height}");
					}
					else
					{
						Plugin.Log.LogError((object)("加载失败: " + Path.GetFileName(text2)));
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("加载异常: " + text2 + " - " + ex.Message));
				}
			}
			Plugin.Log.LogInfo((object)$"共加载 {_lavaSprites.Count} 张精灵");
		}

		private static void LoadSceneRecords()
		{
			if (File.Exists(_sceneRecordFilePath))
			{
				try
				{
					string text = File.ReadAllText(_sceneRecordFilePath);
					_sceneRecords = JsonConvert.DeserializeObject<Dictionary<string, List<Vector3>>>(text) ?? new Dictionary<string, List<Vector3>>();
					Plugin.Log.LogInfo((object)$"已加载 {_sceneRecords.Count} 个场景的 hazard 记录");
					return;
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"加载场景记录失败: {arg}");
					_sceneRecords = new Dictionary<string, List<Vector3>>();
					return;
				}
			}
			_sceneRecords = new Dictionary<string, List<Vector3>>();
		}

		private static void SaveSceneRecords()
		{
			try
			{
				string contents = JsonConvert.SerializeObject((object)_sceneRecords, (Formatting)1);
				File.WriteAllText(_sceneRecordFilePath, contents);
				Plugin.Log.LogInfo((object)$"已保存 {_sceneRecords.Count} 个场景的 hazard 记录");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"保存场景记录失败: {arg}");
			}
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (_sceneHazardMode && !(((Scene)(ref scene)).name == "Menu_Title") && !(((Scene)(ref scene)).name == "Menu") && !(((Scene)(ref scene)).name == "Loading") && !((Scene)(ref scene)).name.Contains("Menu") && (Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(AutoGenerateForSceneCoroutine(((Scene)(ref scene)).name));
			}
		}

		[IteratorStateMachine(typeof(<AutoGenerateForSceneCoroutine>d__28))]
		private static IEnumerator AutoGenerateForSceneCoroutine(string sceneName)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AutoGenerateForSceneCoroutine>d__28(0)
			{
				sceneName = sceneName
			};
		}

		public static void SetSceneHazardMode(bool enabled)
		{
			_sceneHazardMode = enabled;
			Plugin.Log.LogInfo((object)$"场景 Hazard 自动生成模式设置为 {enabled}");
		}

		public static void SetSceneHazardCount(int count)
		{
			_sceneHazardCount = Mathf.Max(0, count);
			Plugin.Log.LogInfo((object)$"场景 Hazard 生成数量设置为 {_sceneHazardCount}");
		}

		public static void SetSeed(int seed)
		{
			_currentSeed = seed;
			Plugin.Log.LogInfo((object)$"HazardSpawner 种子已设置为 {seed}");
		}

		public static void ResetSceneRecords()
		{
			_sceneRecords.Clear();
			SaveSceneRecords();
			Plugin.Log.LogInfo((object)"Hazard 场景记录已重置");
		}

		public static void ResetWorld()
		{
			ClearAll();
			ResetSceneRecords();
			Plugin.Log.LogInfo((object)"HazardSpawner 世界已重置");
		}

		public static void SpawnCustomHazard(Vector3 position)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			Physics2D.IgnoreLayerCollision(17, 8, false);
			GameObject val = new GameObject("CustomHazard_Manual");
			val.transform.position = position;
			val.layer = 17;
			DamageHero val2 = val.AddComponent<DamageHero>();
			val2.hazardType = _hazardType;
			val2.damageDealt = _damage;
			val2.canClashTink = false;
			val2.OnDamagedHero = new UnityEvent();
			BoxCollider2D val3 = val.AddComponent<BoxCollider2D>();
			((Collider2D)val3).isTrigger = true;
			val3.size = _boxSize;
			((Collider2D)val3).offset = _boxOffset;
			val.AddComponent<HazardDebug>();
			val.AddComponent<NonBouncer>();
			val.AddComponent<PersonalObjectPool>();
			val.AddComponent<DamageEnemies>();
			LavaBox val4 = val.AddComponent<LavaBox>();
			val4.isLavaFall = false;
			val.SetActive(false);
			val.SetActive(true);
			AddVisual(val);
			_spawnedHazards.Add(val);
			Plugin.Log.LogInfo((object)$"生成 hazard 于 {position}");
			RecordSpawnToLog(position);
		}

		private static void AddVisual(GameObject parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("LavaVisual");
			val.transform.SetParent(parent.transform);
			val.transform.localPosition = new Vector3(_visualOffset.x, _visualOffset.y, 0f);
			val.transform.localScale = new Vector3(_visualSize.x, _visualSize.y, 1f);
			SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
			if (_lavaSprites.Count > 0)
			{
				val2.sprite = _lavaSprites[0];
			}
			else
			{
				val2.sprite = CreateColorSprite(Color.red);
			}
			((Renderer)val2).sortingLayerName = "Default";
			((Renderer)val2).sortingOrder = 100;
		}

		private static Sprite CreateColorSprite(Color color)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f));
		}

		private static void RecordSpawnToLog(Vector3 position)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			var anon = new
			{
				timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
				posX = position.x,
				posY = position.y,
				posZ = position.z,
				boxSizeX = _boxSize.x,
				boxSizeY = _boxSize.y,
				visualSizeX = _visualSize.x,
				visualSizeY = _visualSize.y,
				damage = _damage,
				hazardType = ((object)(HazardType)(ref _hazardType)).ToString()
			};
			string value = JsonConvert.SerializeObject((object)anon);
			lock (_logLock)
			{
				try
				{
					using StreamWriter streamWriter = new StreamWriter(_logFilePath, append: true);
					streamWriter.WriteLine(value);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("写入日志失败: " + ex.Message));
				}
			}
		}

		public static void SpawnAtPlayer()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			HeroController instance = HeroController.instance;
			if ((Object)(object)instance != (Object)null)
			{
				SpawnCustomHazard(instance.transform.position + _spawnOffset);
			}
		}

		public static Vector3 GetSpawnOffset()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return _spawnOffset;
		}

		public static void ClearAll()
		{
			foreach (GameObject spawnedHazard in _spawnedHazards)
			{
				if ((Object)(object)spawnedHazard != (Object)null)
				{
					Object.Destroy((Object)(object)spawnedHazard);
				}
			}
			_spawnedHazards.Clear();
			Plugin.Log.LogInfo((object)"已清除所有生成的 hazard");
		}
	}
}

plugins/SkillRandomizerMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SkillRandomizerMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("SkillRandomizerMod")]
[assembly: AssemblyTitle("SkillRandomizerMod")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/YourName/SkillRandomizerMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	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")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace SkillTriggerMod
{
	[BepInPlugin("YourName.SkillTriggerMod", "Skill Trigger Mod", "1.0.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <CreateTriggerDelayed>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public (string scene, float x, float y, float z) target;

			public int index;

			public Plugin <>4__this;

			private Vector3 <pos>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CreateTriggerDelayed>d__28(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<pos>5__1 = new Vector3(target.x, target.y, target.z);
					<>4__this.CreateTriggerAt(<pos>5__1, target.scene, index);
					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();
			}
		}

		[CompilerGenerated]
		private sealed class <DisableShrinesAfterStart>d__25 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private int <i>5__1;

			private Scene <scene>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DisableShrinesAfterStart>d__25(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(5f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<i>5__1 = 0;
					while (<i>5__1 < SceneManager.sceneCount)
					{
						<scene>5__2 = SceneManager.GetSceneAt(<i>5__1);
						if (((Scene)(ref <scene>5__2)).isLoaded)
						{
							<>4__this.DisableShrinesInScene(<scene>5__2);
						}
						<i>5__1++;
					}
					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();
			}
		}

		[CompilerGenerated]
		private sealed class <InitializeRandomizer>d__23 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InitializeRandomizer>d__23(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					SkillRandomizer.SetSeed(RandomSeed.Value);
					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();
			}
		}

		internal static ManualLogSource Log;

		internal static HashSet<string> _triggeredRecords = new HashSet<string>();

		private static string _notificationMessage = null;

		private static float _notificationEndTime = 0f;

		private static GUIStyle _notificationStyle;

		private readonly List<(string scene, float x, float y, float z)> targetPositions = new List<(string, float, float, float)>
		{
			("Mosstown_02", 86.922f, 52.568f, 0.004f),
			("Crawl_05", 23.032f, 16.568f, 0.004f),
			("Shellwood_10", 40.643f, 79.57f, 0.004f),
			("Greymoor_22", 39.783f, 36.826f, 0.004f),
			("Bone_East_05", 100.062f, 13.568f, 0.004f)
		};

		private readonly string[] shrineKeywords = new string[5] { "bind orb", "shrine weaver ability", "weaver_shrine", "bellshrine", "dash shrine" };

		public static ConfigEntry<int> RandomSeed { get; private set; }

		private static string TriggerRecordsPath => Path.Combine(Paths.ConfigPath, "SkillTriggerMod", "trigger_records.json");

		internal static Plugin Instance { get; private set; }

		public static void ShowNotification(string message, float duration = 3f)
		{
			_notificationMessage = message;
			_notificationEndTime = Time.time + duration;
		}

		private void OnGUI()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if (_notificationMessage == null || Time.time > _notificationEndTime)
			{
				_notificationMessage = null;
				return;
			}
			if (_notificationStyle == null)
			{
				_notificationStyle = new GUIStyle(GUI.skin.box);
				_notificationStyle.fontSize = 40;
				_notificationStyle.alignment = (TextAnchor)4;
				_notificationStyle.normal.textColor = Color.white;
				_notificationStyle.normal.background = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.8f));
				_notificationStyle.border = new RectOffset(20, 20, 10, 10);
			}
			float num = 600f;
			float num2 = 120f;
			float num3 = ((float)Screen.width - num) / 2f;
			float num4 = Screen.height / 2 - 100;
			GUI.Box(new Rect(num3, num4, num, num2), _notificationMessage, _notificationStyle);
		}

		private Texture2D MakeTexture(int width, int height, Color col)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			RandomSeed = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RandomSeed", 0, "随机种子 (0 表示随机)");
			LoadTriggerRecords();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((MonoBehaviour)this).StartCoroutine(DisableShrinesAfterStart());
			((MonoBehaviour)this).StartCoroutine(InitializeRandomizer());
		}

		private void LoadTriggerRecords()
		{
			try
			{
				if (File.Exists(TriggerRecordsPath))
				{
					string text = File.ReadAllText(TriggerRecordsPath);
					List<string> list = JsonConvert.DeserializeObject<List<string>>(text);
					_triggeredRecords = ((list != null) ? new HashSet<string>(list) : new HashSet<string>());
				}
				else
				{
					_triggeredRecords.Clear();
				}
				Log.LogInfo((object)$"技能触发器记录已加载,共 {_triggeredRecords.Count} 条");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"加载技能触发器记录失败: {arg}");
				_triggeredRecords.Clear();
			}
		}

		internal void SaveTriggerRecords()
		{
			try
			{
				string directoryName = Path.GetDirectoryName(TriggerRecordsPath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				string contents = JsonConvert.SerializeObject((object)_triggeredRecords.ToList(), (Formatting)1);
				File.WriteAllText(TriggerRecordsPath, contents);
				Log.LogInfo((object)$"技能触发器记录已保存,共 {_triggeredRecords.Count} 条");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"保存技能触发器记录失败: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<InitializeRandomizer>d__23))]
		private IEnumerator InitializeRandomizer()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InitializeRandomizer>d__23(0)
			{
				<>4__this = this
			};
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		[IteratorStateMachine(typeof(<DisableShrinesAfterStart>d__25))]
		private IEnumerator DisableShrinesAfterStart()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DisableShrinesAfterStart>d__25(0)
			{
				<>4__this = this
			};
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			DisableShrinesInScene(scene);
			for (int i = 0; i < targetPositions.Count; i++)
			{
				(string, float, float, float) target = targetPositions[i];
				if (target.Item1 == ((Scene)(ref scene)).name)
				{
					((MonoBehaviour)this).StartCoroutine(CreateTriggerDelayed(target, i));
					break;
				}
			}
		}

		private void DisableShrinesInScene(Scene scene)
		{
			GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
			GameObject[] array = rootGameObjects;
			foreach (GameObject val in array)
			{
				Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
				foreach (Transform val2 in componentsInChildren)
				{
					GameObject gameObject = ((Component)val2).gameObject;
					string text = ((Object)gameObject).name.ToLower();
					string[] array2 = shrineKeywords;
					foreach (string value in array2)
					{
						if (text.Contains(value))
						{
							Collider2D[] components = gameObject.GetComponents<Collider2D>();
							Collider2D[] array3 = components;
							foreach (Collider2D val3 in array3)
							{
								((Behaviour)val3).enabled = false;
							}
							Collider[] components2 = gameObject.GetComponents<Collider>();
							Collider[] array4 = components2;
							foreach (Collider val4 in array4)
							{
								val4.enabled = false;
							}
							PlayMakerFSM[] components3 = gameObject.GetComponents<PlayMakerFSM>();
							PlayMakerFSM[] array5 = components3;
							foreach (PlayMakerFSM val5 in array5)
							{
								((Behaviour)val5).enabled = false;
							}
							break;
						}
					}
				}
			}
		}

		[IteratorStateMachine(typeof(<CreateTriggerDelayed>d__28))]
		private IEnumerator CreateTriggerDelayed((string scene, float x, float y, float z) target, int index)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CreateTriggerDelayed>d__28(0)
			{
				<>4__this = this,
				target = target,
				index = index
			};
		}

		private void CreateTriggerAt(Vector3 position, string sceneName, int index)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			string text = $"SkillTriggered_{sceneName}_{index}";
			if (!_triggeredRecords.Contains(text))
			{
				GameObject val = new GameObject($"SkillTrigger_{sceneName}_{index}");
				val.transform.position = position;
				BoxCollider2D val2 = val.AddComponent<BoxCollider2D>();
				((Collider2D)val2).isTrigger = true;
				val2.size = new Vector2(8f, 8f);
				SkillTrigger skillTrigger = val.AddComponent<SkillTrigger>();
				skillTrigger.SetInfo(sceneName, index, text);
				Scene sceneByName = SceneManager.GetSceneByName(sceneName);
				if (((Scene)(ref sceneByName)).IsValid())
				{
					SceneManager.MoveGameObjectToScene(val, sceneByName);
					Log.LogInfo((object)$"触发器创建: {sceneName} 索引 {index}");
				}
				else
				{
					Log.LogError((object)("触发器创建失败: " + sceneName));
					Object.Destroy((Object)(object)val);
				}
			}
		}

		public static void ResetAllRecords()
		{
			_triggeredRecords.Clear();
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.SaveTriggerRecords();
			}
			Log.LogInfo((object)"所有技能触发器记录已重置");
		}
	}
	public class SkillTrigger : MonoBehaviour
	{
		private bool _triggered = false;

		private string _sceneName;

		private int _index;

		private string _recordKey;

		public void SetInfo(string sceneName, int index, string recordKey)
		{
			_sceneName = sceneName;
			_index = index;
			_recordKey = recordKey;
		}

		private void OnTriggerEnter2D(Collider2D other)
		{
			if (!_triggered && (((Component)other).CompareTag("Hero") || ((Component)other).CompareTag("Player")))
			{
				_triggered = true;
				if (_sceneName == "Shellwood_10")
				{
					SkillRandomizer.GiveWallJump();
				}
				else
				{
					SkillRandomizer.GiveRandomSkill();
				}
				Plugin._triggeredRecords.Add(_recordKey);
				Plugin.Instance.SaveTriggerRecords();
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public static class SkillRandomizer
	{
		private static readonly Dictionary<string, string> SkillDisplayNames = new Dictionary<string, string>
		{
			{ "hasNeedleThrow", "飞针" },
			{ "hasThreadSphere", "丝线球" },
			{ "hasHarpoonDash", "鱼叉冲刺" },
			{ "hasSilkCharge", "丝线冲刺" },
			{ "hasSilkBomb", "丝线炸弹" },
			{ "hasSilkBossNeedle", "丝线针" },
			{ "hasNeedolin", "针线" },
			{ "hasDash", "冲刺" },
			{ "hasBrolly", "伞" },
			{ "hasDoubleJump", "二段跳" },
			{ "hasChargeSlash", "蓄力斩" },
			{ "hasSuperJump", "超级跳" },
			{ "hasWallJump", "爬墙" }
		};

		private static readonly List<string> AllSkillFields = SkillDisplayNames.Keys.ToList();

		private static Random? _rng;

		private static int _currentSeed;

		public static void SetSeed(int seed)
		{
			_currentSeed = seed;
			_rng = ((seed == 0) ? new Random() : new Random(seed));
		}

		private static void EnsureRng()
		{
			if (_rng == null)
			{
				_rng = new Random();
			}
		}

		public static void GiveRandomSkill()
		{
			EnsureRng();
			try
			{
				PlayerData instance = PlayerData.instance;
				if (instance == null)
				{
					return;
				}
				List<string> list = new List<string>();
				foreach (string allSkillField in AllSkillFields)
				{
					FieldInfo field = typeof(PlayerData).GetField(allSkillField, BindingFlags.Instance | BindingFlags.Public);
					if (field != null && field.FieldType == typeof(bool) && !(bool)field.GetValue(instance))
					{
						list.Add(allSkillField);
					}
				}
				if (list.Count == 0)
				{
					GiveWallJump();
					return;
				}
				string text = list[_rng.Next(list.Count)];
				FieldInfo field2 = typeof(PlayerData).GetField(text, BindingFlags.Instance | BindingFlags.Public);
				if (field2 != null)
				{
					field2.SetValue(instance, true);
					string value;
					string text2 = (SkillDisplayNames.TryGetValue(text, out value) ? value : text.Replace("has", ""));
					Plugin.ShowNotification("获得技能: " + text2);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"SkillRandomizer 出错: {arg}");
			}
		}

		public static void GiveWallJump()
		{
			try
			{
				PlayerData instance = PlayerData.instance;
				if (instance == null)
				{
					return;
				}
				string[] array = new string[3] { "hasWallJump", "hasWalljump", "hasWallJumpUnlocked" };
				string[] array2 = array;
				foreach (string name in array2)
				{
					FieldInfo field = typeof(PlayerData).GetField(name, BindingFlags.Instance | BindingFlags.Public);
					if (field != null && field.FieldType == typeof(bool))
					{
						if (!(bool)field.GetValue(instance))
						{
							field.SetValue(instance, true);
							Plugin.ShowNotification("获得技能: 爬墙");
						}
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"GiveWallJump 出错: {arg}");
			}
		}
	}
}

plugins/StartingAbilityPicker.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("StartingAbilityPicker")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("StartingAbilityPicker")]
[assembly: AssemblyTitle("StartingAbilityPicker")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/YourGitHubUsername/StartingAbilityPicker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	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")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace StartingAbilityPicker
{
	[BepInPlugin("YourName.StartingAbilityPicker", "Starting Ability Picker", "1.0.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <ShowUIAuto>d__60 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ShowUIAuto>d__60(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (<>4__this.currentProfileID != -1)
					{
						<>4__this.allowUpward = AllowUpwardAttack;
						<>4__this.allowLeft = AllowLeftAttack;
						<>4__this.allowRight = AllowRightAttack;
						<>4__this.itemCount = StartingItemCount.Value;
						<>4__this.resetPickups = false;
						<>4__this.seedInput = RandomSeed.Value.ToString();
						<>4__this.showUI = true;
						Log.LogInfo((object)"加载存档,自动打开开局选项界面");
					}
					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();
			}
		}

		internal static ManualLogSource Log;

		public static bool AllowLeftAttack = false;

		public static bool AllowRightAttack = false;

		public static bool AllowUpwardAttack = false;

		private static Dictionary<string, string> _abilityConfig = new Dictionary<string, string>();

		private bool _sceneHazardMode = false;

		private int _sceneHazardCount = 2;

		private bool _sceneHazardUIOpen = false;

		private bool skillMode = false;

		private int skillTotal = 0;

		private int skillV = 0;

		private int skillH = 0;

		private int skillS = 0;

		private int skillA = 0;

		private const int MaxVertical = 5;

		private const int MaxHorizontal = 4;

		private const int MaxSpecial = 4;

		private const int MaxAttack = 5;

		private bool _lastSceneWasMenu = true;

		private bool showUI = false;

		private Rect uiWindowRect;

		private bool allowUpward = false;

		private bool allowLeft = false;

		private bool allowRight = false;

		private int itemCount = 0;

		private bool resetPickups = false;

		private string seedInput = "";

		private static HashSet<int> chosenProfileSet = new HashSet<int>();

		private static string _notificationMessage = null;

		private static float _notificationEndTime = 0f;

		private static GUIStyle _notificationStyle;

		public static ConfigEntry<string> ChosenProfiles { get; private set; }

		public static ConfigEntry<int> StartingSkillCount { get; private set; }

		public static ConfigEntry<int> StartingItemCount { get; private set; }

		public static ConfigEntry<int> RandomSeed { get; private set; }

		private static string AbilityConfigPath => Path.Combine(Paths.ConfigPath, "StartingAbilityPicker", "ability_config.json");

		private int currentProfileID => ((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.profileID : (-1);

		public static void ShowNotification(string message, float duration = 3f)
		{
			_notificationMessage = message;
			_notificationEndTime = Time.time + duration;
		}

		private Texture2D MakeTexture(int width, int height, Color col)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = col;
			}
			Texture2D val = new Texture2D(width, height);
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"StartingAbilityPicker loaded! Press F7 to open starting options.");
			ChosenProfiles = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ChosenProfiles", "", "已选择过开局选项的存档ID列表");
			StartingSkillCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "StartingSkillCount", 0, "开局随机技能数量 (0-5)");
			StartingItemCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "StartingItemCount", 0, "开局随机物品数量 (0-5)");
			RandomSeed = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RandomSeed", 0, "随机种子 (0 表示随机)");
			LoadChosenProfiles();
			EnsureRandomSeed();
			LoadAbilityConfig();
			SceneManager.sceneLoaded += OnSceneLoaded;
			Harmony.CreateAndPatchAll(typeof(AttackPatch), (string)null);
		}

		private void LoadAbilityConfig()
		{
			try
			{
				if (File.Exists(AbilityConfigPath))
				{
					string text = File.ReadAllText(AbilityConfigPath);
					_abilityConfig = JsonConvert.DeserializeObject<Dictionary<string, string>>(text) ?? new Dictionary<string, string>();
				}
				else
				{
					_abilityConfig.Clear();
				}
				AllowUpwardAttack = _abilityConfig.TryGetValue("AllowUpwardAttack", out string value) && value == "true";
				AllowLeftAttack = _abilityConfig.TryGetValue("AllowLeftAttack", out string value2) && value2 == "true";
				AllowRightAttack = _abilityConfig.TryGetValue("AllowRightAttack", out string value3) && value3 == "true";
				if (_abilityConfig.TryGetValue("SceneHazardMode", out string value4) && bool.TryParse(value4, out var result))
				{
					_sceneHazardMode = result;
				}
				else
				{
					_sceneHazardMode = false;
				}
				if (_abilityConfig.TryGetValue("SceneHazardCount", out string value5) && int.TryParse(value5, out var result2))
				{
					_sceneHazardCount = Mathf.Clamp(result2, 0, 4);
				}
				else
				{
					_sceneHazardCount = 2;
				}
				Log.LogInfo((object)$"[LoadAbilityConfig] Loaded: up={AllowUpwardAttack}, left={AllowLeftAttack}, right={AllowRightAttack}, sceneHazardMode={_sceneHazardMode}, sceneHazardCount={_sceneHazardCount}");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"加载配置失败: {arg}");
			}
		}

		private void SaveAbilityConfig()
		{
			try
			{
				_abilityConfig["AllowUpwardAttack"] = AllowUpwardAttack.ToString();
				_abilityConfig["AllowLeftAttack"] = AllowLeftAttack.ToString();
				_abilityConfig["AllowRightAttack"] = AllowRightAttack.ToString();
				_abilityConfig["SceneHazardMode"] = _sceneHazardMode.ToString();
				_abilityConfig["SceneHazardCount"] = _sceneHazardCount.ToString();
				string directoryName = Path.GetDirectoryName(AbilityConfigPath);
				if (!Directory.Exists(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				string contents = JsonConvert.SerializeObject((object)_abilityConfig, (Formatting)1);
				File.WriteAllText(AbilityConfigPath, contents);
				Log.LogInfo((object)$"[SaveAbilityConfig] Saved: up={AllowUpwardAttack}, left={AllowLeftAttack}, right={AllowRightAttack}, sceneHazardMode={_sceneHazardMode}, sceneHazardCount={_sceneHazardCount}");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"保存配置失败: {arg}");
			}
		}

		private void NotifyHazardSettings()
		{
			try
			{
				Type type = Type.GetType("SilksongItemRandomizer.Hazard.HazardSpawner, SilksongItemRandomizer");
				if (type == null)
				{
					Log.LogError((object)"未找到 HazardSpawner 类型");
					return;
				}
				type.GetMethod("SetSceneHazardMode", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { _sceneHazardMode });
				type.GetMethod("SetSceneHazardCount", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { _sceneHazardCount });
				Log.LogInfo((object)$"已通知 HazardSpawner: 模式={_sceneHazardMode}, 数量={_sceneHazardCount}");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"反射调用失败: {arg}");
			}
		}

		private void EnsureRandomSeed()
		{
			if (RandomSeed.Value == 0)
			{
				int num = new Random().Next(1, int.MaxValue);
				RandomSeed.Value = num;
				((BaseUnityPlugin)this).Config.Save();
				Log.LogInfo((object)$"已自动生成真实种子: {num}");
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name != "Menu_Title" && ((Scene)(ref scene)).name != "Menu" && ((Scene)(ref scene)).name != "Loading" && (Object)(object)HeroController.instance != (Object)null)
			{
				if (_lastSceneWasMenu)
				{
					((MonoBehaviour)this).StartCoroutine(ShowUIAuto());
					_lastSceneWasMenu = false;
				}
				LoadAbilityConfig();
				try
				{
					PlayerData instance = PlayerData.instance;
					if (instance != null)
					{
						skillMode = instance.GetBool("SkillRandomMode");
						skillTotal = instance.GetInt("SkillTotalCount");
						skillV = instance.GetInt("SkillVerticalCount");
						skillH = instance.GetInt("SkillHorizontalCount");
						skillS = instance.GetInt("SkillSpecialCount");
						skillA = instance.GetInt("SkillAttackCount");
						if (!skillMode && skillTotal == 0)
						{
							skillTotal = StartingSkillCount.Value;
						}
					}
					return;
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"加载技能随机设置失败: {arg}");
					return;
				}
			}
			if (((Scene)(ref scene)).name == "Menu_Title" || ((Scene)(ref scene)).name == "Menu")
			{
				_lastSceneWasMenu = true;
			}
		}

		[IteratorStateMachine(typeof(<ShowUIAuto>d__60))]
		private IEnumerator ShowUIAuto()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShowUIAuto>d__60(0)
			{
				<>4__this = this
			};
		}

		private void LoadChosenProfiles()
		{
			chosenProfileSet.Clear();
			string[] array = ChosenProfiles.Value.Split(',');
			foreach (string text in array)
			{
				if (int.TryParse(text.Trim(), out var result))
				{
					chosenProfileSet.Add(result);
				}
			}
		}

		private void SaveChosenProfiles()
		{
			ChosenProfiles.Value = string.Join(",", chosenProfileSet);
			((BaseUnityPlugin)this).Config.Save();
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)288) && currentProfileID != -1)
			{
				showUI = !showUI;
				if (showUI)
				{
					allowUpward = AllowUpwardAttack;
					allowLeft = AllowLeftAttack;
					allowRight = AllowRightAttack;
					itemCount = StartingItemCount.Value;
					resetPickups = false;
					seedInput = RandomSeed.Value.ToString();
				}
			}
		}

		private void OnGUI()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (showUI)
			{
				uiWindowRect = new Rect(20f, (float)((Screen.height - 950) / 2), 650f, 950f);
				uiWindowRect = GUILayout.Window(100, uiWindowRect, new WindowFunction(DrawUIWindow), "开局选项", Array.Empty<GUILayoutOption>());
			}
			if (_notificationMessage != null && Time.time <= _notificationEndTime)
			{
				if (_notificationStyle == null)
				{
					_notificationStyle = new GUIStyle(GUI.skin.box);
					_notificationStyle.fontSize = 40;
					_notificationStyle.alignment = (TextAnchor)4;
					_notificationStyle.normal.textColor = Color.white;
					_notificationStyle.normal.background = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.7f));
				}
				float num = 600f;
				float num2 = 120f;
				float num3 = ((float)Screen.width - num) / 2f;
				float num4 = Screen.height / 2 - 100;
				GUI.Box(new Rect(num3, num4, num, num2), _notificationMessage, _notificationStyle);
			}
			else
			{
				_notificationMessage = null;
			}
		}

		private void DrawUIWindow(int windowID)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_10d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_10f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_112d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1166: Unknown result type (might be due to invalid IL or missing references)
			//IL_118f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0956: Unknown result type (might be due to invalid IL or missing references)
			//IL_094f: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ca0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c99: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d51: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d07: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d30: Unknown result type (might be due to invalid IL or missing references)
			Color color = GUI.color;
			GUI.color = Color.black;
			GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref uiWindowRect)).width, ((Rect)(ref uiWindowRect)).height), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUI.skin.label.fontSize = 20;
			GUI.skin.toggle.fontSize = 20;
			GUI.skin.button.fontSize = 24;
			GUI.skin.horizontalSlider.fontSize = 18;
			GUI.skin.textField.fontSize = 18;
			GUILayout.Label("当前存档开局设置:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUILayout.Space(15f);
			bool flag = chosenProfileSet.Contains(currentProfileID);
			if (flag)
			{
				GUILayout.Label("(此存档已设置过,只能查看)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
				GUI.backgroundColor = new Color(0.8f, 0.5f, 0.2f);
				if (GUILayout.Button("重置本存档设置", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(45f) }))
				{
					chosenProfileSet.Remove(currentProfileID);
					SaveChosenProfiles();
					flag = false;
					allowUpward = false;
					allowLeft = false;
					allowRight = false;
					itemCount = 0;
					resetPickups = false;
					skillMode = false;
					skillTotal = 0;
					skillV = (skillH = (skillS = (skillA = 0)));
					return;
				}
				GUI.backgroundColor = Color.white;
			}
			GUILayout.Space(20f);
			GUILayout.Label("攻击方向选择:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
			GUILayout.Space(5f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.color = Color.gray;
			GUILayout.Label("下劈 (默认)", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(200f),
				GUILayout.Height(40f)
			});
			GUI.enabled = false;
			GUILayout.Toggle(true, "", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(40f),
				GUILayout.Height(40f)
			});
			GUI.enabled = !flag;
			GUI.color = Color.white;
			GUILayout.EndHorizontal();
			GUI.color = (allowUpward ? Color.green : Color.white);
			bool flag2 = GUILayout.Toggle(allowUpward, "上劈", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			if (flag2 != allowUpward && !flag)
			{
				allowUpward = flag2;
			}
			GUI.color = (allowLeft ? Color.green : Color.white);
			bool flag3 = GUILayout.Toggle(allowLeft, "左劈", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			if (flag3 != allowLeft && !flag)
			{
				allowLeft = flag3;
			}
			GUI.color = (allowRight ? Color.green : Color.white);
			bool flag4 = GUILayout.Toggle(allowRight, "右劈", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			if (flag4 != allowRight && !flag)
			{
				allowRight = flag4;
			}
			GUI.color = Color.white;
			GUILayout.Space(20f);
			GUILayout.Label("技能随机模式:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.color = (skillMode ? Color.white : Color.green);
			if (GUILayout.Button("总随机", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(150f)
			}) && !flag)
			{
				skillMode = false;
			}
			GUI.color = (skillMode ? Color.green : Color.white);
			if (GUILayout.Button("分类随机", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(40f),
				GUILayout.Width(150f)
			}) && !flag)
			{
				skillMode = true;
			}
			GUI.color = Color.white;
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			if (!skillMode)
			{
				GUILayout.Label("开局随机技能总数量:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(skillTotal.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(35f),
					GUILayout.Height(40f)
				});
				int num = (int)GUILayout.HorizontalSlider((float)skillTotal, 0f, 13f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (num != skillTotal && !flag)
				{
					skillTotal = num;
				}
				GUILayout.EndHorizontal();
				GUILayout.Space(10f);
			}
			else
			{
				GUILayout.Label("分类随机数量:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
				GUILayout.Label($"垂直技能 (0-{5})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(skillV.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(35f),
					GUILayout.Height(40f)
				});
				int num2 = (int)GUILayout.HorizontalSlider((float)skillV, 0f, 5f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (num2 != skillV && !flag)
				{
					skillV = num2;
				}
				GUILayout.EndHorizontal();
				GUILayout.Label($"水平技能 (0-{4})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(skillH.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(35f),
					GUILayout.Height(40f)
				});
				int num3 = (int)GUILayout.HorizontalSlider((float)skillH, 0f, 4f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (num3 != skillH && !flag)
				{
					skillH = num3;
				}
				GUILayout.EndHorizontal();
				GUILayout.Label($"特殊技能 (0-{4})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(skillS.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(35f),
					GUILayout.Height(40f)
				});
				int num4 = (int)GUILayout.HorizontalSlider((float)skillS, 0f, 4f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (num4 != skillS && !flag)
				{
					skillS = num4;
				}
				GUILayout.EndHorizontal();
				GUILayout.Label($"攻击技能 (0-{5})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(skillA.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(35f),
					GUILayout.Height(40f)
				});
				int num5 = (int)GUILayout.HorizontalSlider((float)skillA, 0f, 5f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
				if (num5 != skillA && !flag)
				{
					skillA = num5;
				}
				GUILayout.EndHorizontal();
				GUILayout.Space(10f);
			}
			GUILayout.Label("开局随机物品数量:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(itemCount.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(35f),
				GUILayout.Height(40f)
			});
			int num6 = (int)GUILayout.HorizontalSlider((float)itemCount, 0f, 10f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) });
			if (num6 != itemCount && !flag)
			{
				itemCount = num6;
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(15f);
			GUI.color = (_sceneHazardUIOpen ? Color.green : Color.white);
			if (GUILayout.Button("场景随机" + (_sceneHazardUIOpen ? " ▼" : " ▶"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
			{
				_sceneHazardUIOpen = !_sceneHazardUIOpen;
			}
			GUI.color = Color.white;
			if (_sceneHazardUIOpen)
			{
				GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Space(10f);
				GUILayout.Label("场景随机设置:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("启用:", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(60f),
					GUILayout.Height(35f)
				});
				bool flag5 = GUILayout.Toggle(_sceneHazardMode, _sceneHazardMode ? "开" : "关", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) });
				if (flag5 != _sceneHazardMode && !flag)
				{
					_sceneHazardMode = flag5;
					SaveAbilityConfig();
					NotifyHazardSettings();
				}
				GUILayout.EndHorizontal();
				if (_sceneHazardMode)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label("每个场景生成数量:", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(150f),
						GUILayout.Height(35f)
					});
					if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(40f),
						GUILayout.Height(35f)
					}) && !flag)
					{
						_sceneHazardCount = Mathf.Max(0, _sceneHazardCount - 1);
						SaveAbilityConfig();
						NotifyHazardSettings();
					}
					GUILayout.Label(_sceneHazardCount.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(40f),
						GUILayout.Height(35f)
					});
					if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(40f),
						GUILayout.Height(35f)
					}) && !flag)
					{
						_sceneHazardCount = Mathf.Min(4, _sceneHazardCount + 1);
						SaveAbilityConfig();
						NotifyHazardSettings();
					}
					GUILayout.Label("(最大 4)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
					GUILayout.EndHorizontal();
				}
				GUILayout.Space(10f);
				GUILayout.EndVertical();
			}
			GUILayout.Space(25f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("种子", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(60f),
				GUILayout.Height(40f)
			});
			seedInput = GUILayout.TextField(seedInput, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(160f),
				GUILayout.Height(40f)
			});
			GUILayout.EndHorizontal();
			GUILayout.Space(5f);
			GUI.color = (resetPickups ? Color.red : Color.white);
			bool flag6 = GUILayout.Toggle(resetPickups, "重置种子世界(含技能触发器)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			if (flag6 != resetPickups && !flag)
			{
				resetPickups = flag6;
			}
			GUI.color = Color.white;
			if (resetPickups)
			{
				GUI.color = Color.yellow;
				GUILayout.Label("警告:重置后当前种子世界将重新生成,所有拾取点会重生,技能触发器也会重置。", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(70f) });
				GUI.color = Color.white;
			}
			GUILayout.Space(35f);
			GUI.enabled = !flag;
			GUI.backgroundColor = Color.green;
			if (GUILayout.Button("确认", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(50f) }) && !flag)
			{
				AllowUpwardAttack = allowUpward;
				AllowLeftAttack = allowLeft;
				AllowRightAttack = allowRight;
				SaveAbilityConfig();
				try
				{
					PlayerData instance = PlayerData.instance;
					if (instance != null)
					{
						instance.SetBool("AllowUpwardAttack", allowUpward);
						instance.SetBool("AllowLeftAttack", allowLeft);
						instance.SetBool("AllowRightAttack", allowRight);
						instance.SetBool("SkillRandomMode", skillMode);
						instance.SetInt("SkillTotalCount", skillTotal);
						instance.SetInt("SkillVerticalCount", skillV);
						instance.SetInt("SkillHorizontalCount", skillH);
						instance.SetInt("SkillSpecialCount", skillS);
						instance.SetInt("SkillAttackCount", skillA);
					}
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"保存到 PlayerData 失败: {arg}");
				}
				StartingSkillCount.Value = skillTotal;
				StartingItemCount.Value = itemCount;
				((BaseUnityPlugin)this).Config.Save();
				chosenProfileSet.Add(currentProfileID);
				SaveChosenProfiles();
				if (resetPickups)
				{
					ResetSeedWorld();
				}
				if (!skillMode)
				{
					for (int i = 0; i < skillTotal; i++)
					{
						SkillRandomizer.GiveRandomSkill();
					}
				}
				else
				{
					for (int j = 0; j < skillV; j++)
					{
						SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.VerticalSkills);
					}
					for (int k = 0; k < skillH; k++)
					{
						SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.HorizontalSkills);
					}
					for (int l = 0; l < skillS; l++)
					{
						SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.SpecialSkills);
					}
					for (int m = 0; m < skillA; m++)
					{
						SkillRandomizer.GiveRandomSkillFromCategory(SkillRandomizer.AttackSkills);
					}
				}
				for (int n = 0; n < itemCount; n++)
				{
					SavedItem randomItem = ItemRandomizer.GetRandomItem();
					if ((Object)(object)randomItem != (Object)null)
					{
						randomItem.TryGet(false, true);
					}
				}
				showUI = false;
				Log.LogInfo((object)string.Format("开局设置已保存: 上劈={0}, 左劈={1}, 右劈={2}, 技能模式={3}, 技能V={4}, H={5}, S={6}, A={7}, 物品={8}, 重置种子={9}, 场景随机启用={10}, 数量={11}", allowUpward, allowLeft, allowRight, skillMode ? "分类" : "总", skillV, skillH, skillS, skillA, itemCount, resetPickups, _sceneHazardMode, _sceneHazardCount));
			}
			GUI.backgroundColor = Color.white;
			GUI.enabled = true;
			GUI.backgroundColor = new Color(0.8f, 0.2f, 0.2f);
			if (GUILayout.Button("关闭", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
			{
				showUI = false;
			}
			GUI.backgroundColor = Color.white;
			GUILayout.Space(15f);
			int fontSize = GUI.skin.label.fontSize;
			GUI.skin.label.fontSize = 26;
			GUI.color = Color.yellow;
			GUILayout.Label("提示: 按 F7 呼出此窗口", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUI.color = Color.white;
			GUI.skin.label.fontSize = fontSize;
			GUILayout.EndVertical();
			GUI.DragWindow();
		}

		private void ResetSeedWorld()
		{
			int num;
			if (int.TryParse(seedInput, out var result))
			{
				if (result != RandomSeed.Value)
				{
					num = result;
				}
				else
				{
					num = new Random().Next(1, int.MaxValue);
					Log.LogInfo((object)$"输入种子与原种子相同,自动生成新种子: {num}");
				}
			}
			else
			{
				num = new Random().Next(1, int.MaxValue);
				Log.LogInfo((object)$"输入无效,自动生成新种子: {num}");
			}
			seedInput = num.ToString();
			RandomSeed.Value = num;
			((BaseUnityPlugin)this).Config.Save();
			try
			{
				string path = Path.Combine(Paths.ConfigPath, "SilksongItemRandomizer", "destroyed_pickups.json");
				if (File.Exists(path))
				{
					File.Delete(path);
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"删除拾取点记录失败: {arg}");
			}
			try
			{
				Type type = Type.GetType("SilksongItemRandomizer.Plugin, SilksongItemRandomizer");
				if (type != null)
				{
					PropertyInfo property = type.GetProperty("RandomSeed", BindingFlags.Static | BindingFlags.Public);
					if (property != null)
					{
						ConfigEntry<int> val = property.GetValue(null) as ConfigEntry<int>;
						val.Value = num;
					}
					type.GetMethod("ResetDestroyedPickupKeys", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
				}
			}
			catch (Exception arg2)
			{
				Log.LogError((object)$"重置物品随机MOD内存数据失败: {arg2}");
			}
			try
			{
				string path2 = Path.Combine(Paths.ConfigPath, "SkillTriggerMod", "trigger_records.json");
				if (File.Exists(path2))
				{
					File.Delete(path2);
				}
				Log.LogInfo((object)"已删除技能触发器记录文件");
			}
			catch (Exception arg3)
			{
				Log.LogError((object)$"删除技能触发器记录失败: {arg3}");
			}
			try
			{
				Type type2 = Type.GetType("SkillTriggerMod.Plugin, SkillTriggerMod");
				if (type2 != null)
				{
					PropertyInfo property2 = type2.GetProperty("RandomSeed", BindingFlags.Static | BindingFlags.Public);
					if (property2 != null)
					{
						ConfigEntry<int> val2 = property2.GetValue(null) as ConfigEntry<int>;
						val2.Value = num;
					}
					Type type3 = Type.GetType("SkillTriggerMod.SkillRandomizer, SkillTriggerMod");
					if (type3 != null)
					{
						type3.GetMethod("SetSeed", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { num });
					}
				}
			}
			catch (Exception arg4)
			{
				Log.LogError((object)$"重置技能随机MOD种子失败: {arg4}");
			}
			try
			{
				Type type4 = Type.GetType("SilksongItemRandomizer.CrestRandomizer, SilksongItemRandomizer");
				if (type4 != null)
				{
					type4.GetMethod("ResetMappings", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
					type4.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
				}
				Type.GetType("SilksongItemRandomizer.CrestRandomizePatch, SilksongItemRandomizer")?.GetMethod("ResetProcessedIds", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
				Type.GetType("SilksongItemRandomizer.BenchRespawnPatch, SilksongItemRandomizer")?.GetMethod("ResetCooldown", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
			}
			catch (Exception arg5)
			{
				Log.LogError((object)$"清空纹章相关标记失败: {arg5}");
			}
			try
			{
				Type type5 = Type.GetType("SilksongItemRandomizer.Hazard.HazardSpawner, SilksongItemRandomizer");
				if (type5 != null)
				{
					type5.GetMethod("SetSeed", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { num });
					type5.GetMethod("ResetSceneRecords", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null);
					type5.GetMethod("SetSceneHazardMode", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { _sceneHazardMode });
					type5.GetMethod("SetSceneHazardCount", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, new object[1] { _sceneHazardCount });
					Log.LogInfo((object)"已通知 HazardSpawner 重置世界,种子已更新");
				}
			}
			catch (Exception arg6)
			{
				Log.LogError((object)$"重置 HazardSpawner 世界失败: {arg6}");
			}
			Log.LogInfo((object)"请重载当前场景以使所有随机世界重置。");
		}
	}
	[HarmonyPatch(typeof(HeroController), "DoAttack")]
	public class AttackPatch
	{
		private static void Prefix(HeroController __instance, ref bool __runOriginal)
		{
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!__runOriginal)
				{
					return;
				}
				FieldInfo field = typeof(HeroController).GetField("inputHandler", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field == null)
				{
					return;
				}
				object value = field.GetValue(__instance);
				if (value == null)
				{
					return;
				}
				FieldInfo field2 = value.GetType().GetField("inputActions", BindingFlags.Instance | BindingFlags.Public);
				if (field2 == null)
				{
					return;
				}
				object value2 = field2.GetValue(value);
				if (value2 == null)
				{
					return;
				}
				FieldInfo field3 = value2.GetType().GetField("Up");
				FieldInfo field4 = value2.GetType().GetField("Down");
				if (field3 == null || field4 == null)
				{
					return;
				}
				object value3 = field3.GetValue(value2);
				object value4 = field4.GetValue(value2);
				PropertyInfo propertyInfo = value3?.GetType().GetProperty("IsPressed");
				if (!(propertyInfo == null))
				{
					bool flag = (bool)propertyInfo.GetValue(value3);
					bool flag2 = (bool)propertyInfo.GetValue(value4);
					bool flag3 = true;
					try
					{
						FieldInfo field5 = typeof(HeroController).GetField("facingRight", BindingFlags.Instance | BindingFlags.NonPublic);
						flag3 = ((!(field5 != null)) ? (__instance.transform.localScale.x > 0f) : ((bool)field5.GetValue(__instance)));
					}
					catch
					{
					}
					bool allowUpwardAttack = Plugin.AllowUpwardAttack;
					bool allowLeftAttack = Plugin.AllowLeftAttack;
					bool allowRightAttack = Plugin.AllowRightAttack;
					bool flag4 = true;
					if (!(flag ? allowUpwardAttack : ((flag2 && (__instance.allowAttackCancellingDownspikeRecovery || !__instance.cState.onGround)) || ((!flag3) ? allowRightAttack : allowLeftAttack))))
					{
						__runOriginal = false;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Exception in AttackPatch: {arg}");
				__runOriginal = true;
			}
		}
	}
	public static class SkillRandomizer
	{
		private static readonly Dictionary<string, string> SkillDisplayNames = new Dictionary<string, string>
		{
			{ "hasNeedleThrow", "飞针" },
			{ "hasThreadSphere", "丝线球" },
			{ "hasHarpoonDash", "鱼叉冲刺" },
			{ "hasSilkCharge", "丝线冲刺" },
			{ "hasSilkBomb", "丝线炸弹" },
			{ "hasSilkBossNeedle", "丝线针" },
			{ "hasNeedolin", "针线" },
			{ "hasDash", "冲刺" },
			{ "hasBrolly", "伞" },
			{ "hasDoubleJump", "二段跳" },
			{ "hasChargeSlash", "蓄力斩" },
			{ "hasSuperJump", "超级跳" },
			{ "hasWallJump", "爬墙" }
		};

		public static readonly List<string> VerticalSkills = new List<string> { "hasSuperJump", "hasDoubleJump", "hasWallJump", "hasBrolly", "hasHarpoonDash" };

		public static readonly List<string> HorizontalSkills = new List<string> { "hasDash", "hasBrolly", "hasHarpoonDash", "hasSilkCharge" };

		public static readonly List<string> SpecialSkills = new List<string> { "hasNeedolin", "hasChargeSlash", "hasBrolly", "hasHarpoonDash" };

		public static readonly List<string> AttackSkills = new List<string> { "hasSilkBomb", "hasSilkBossNeedle", "hasThreadSphere", "hasSilkSpear", "hasSilkCharge" };

		private static readonly List<string> AllSkillFields = SkillDisplayNames.Keys.ToList();

		private static Random? _rng;

		private static int _currentSeed;

		public static void SetSeed(int seed)
		{
			_currentSeed = seed;
			_rng = ((seed == 0) ? new Random() : new Random(seed));
		}

		public static void ResetSeed()
		{
			SetSeed(_currentSeed);
		}

		private static void EnsureRng()
		{
			if (_rng == null)
			{
				_rng = new Random();
				Plugin.Log.LogWarning((object)"SkillRandomizer RNG was not initialized, using default seed.");
			}
		}

		public static void GiveRandomSkill()
		{
			EnsureRng();
			try
			{
				PlayerData playerData = PlayerData.instance;
				if (playerData == null)
				{
					return;
				}
				List<string> list = AllSkillFields.Where(delegate(string fieldName)
				{
					FieldInfo field2 = typeof(PlayerData).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
					if (field2 != null && field2.FieldType == typeof(bool))
					{
						bool flag = (bool)field2.GetValue(playerData);
						return !flag;
					}
					return false;
				}).ToList();
				if (list.Count == 0)
				{
					GiveWallJump();
					return;
				}
				string text = list[_rng.Next(list.Count)];
				FieldInfo field = typeof(PlayerData).GetField(text, BindingFlags.Instance | BindingFlags.Public);
				if (field != null)
				{
					field.SetValue(playerData, true);
					string value;
					string text2 = (SkillDisplayNames.TryGetValue(text, out value) ? value : text.Replace("has", ""));
					Plugin.ShowNotification("获得技能: " + text2);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"SkillRandomizer 出错: {arg}");
			}
		}

		public static void GiveRandomSkillFromCategory(List<string> categoryFields)
		{
			EnsureRng();
			try
			{
				PlayerData playerData = PlayerData.instance;
				if (playerData == null)
				{
					return;
				}
				List<string> list = categoryFields.Where(delegate(string fieldName)
				{
					FieldInfo field2 = typeof(PlayerData).GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
					if (field2 != null && field2.FieldType == typeof(bool))
					{
						bool flag = (bool)field2.GetValue(playerData);
						return !flag;
					}
					return false;
				}).ToList();
				if (list.Count != 0)
				{
					string text = list[_rng.Next(list.Count)];
					FieldInfo field = typeof(PlayerData).GetField(text, BindingFlags.Instance | BindingFlags.Public);
					if (field != null)
					{
						field.SetValue(playerData, true);
						string value;
						string text2 = (SkillDisplayNames.TryGetValue(text, out value) ? value : text.Replace("has", ""));
						Plugin.ShowNotification("获得技能: " + text2);
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"SkillRandomizer 出错: {arg}");
			}
		}

		public static void GiveWallJump()
		{
			try
			{
				PlayerData instance = PlayerData.instance;
				if (instance == null)
				{
					return;
				}
				string[] array = new string[3] { "hasWallJump", "hasWalljump", "hasWallJumpUnlocked" };
				string[] array2 = array;
				foreach (string name in array2)
				{
					FieldInfo field = typeof(PlayerData).GetField(name, BindingFlags.Instance | BindingFlags.Public);
					if (field != null && field.FieldType == typeof(bool))
					{
						if (!(bool)field.GetValue(instance))
						{
							field.SetValue(instance, true);
							Plugin.ShowNotification("获得技能: 爬墙");
						}
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"GiveWallJump 出错: {arg}");
			}
		}
	}
	public static class ItemRandomizer
	{
		private static List<SavedItem> _allItems;

		private static Random _rng = new Random();

		public static SavedItem GetRandomItem()
		{
			if (_allItems == null)
			{
				_allItems = (from item in Resources.FindObjectsOfTypeAll<SavedItem>()
					where item is CollectableItem || item is ToolBase
					select item).ToList();
			}
			if (_allItems.Count == 0)
			{
				return null;
			}
			return _allItems[_rng.Next(_allItems.Count)];
		}
	}
}