Decompiled source of Polyfill v0.13.20

Mods/Polyfill.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using HarmonyLib;
using Hash.Api;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Managing;
using Il2CppFishNet.Managing.Object;
using Il2CppFishNet.Managing.Server;
using Il2CppFishNet.Object;
using Il2CppInterop.Common;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.Building.Doors;
using Il2CppScheduleOne.Cartel;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.Employees;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Instancing;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.NPCs.CharacterClasses;
using Il2CppScheduleOne.NPCs.Framework;
using Il2CppScheduleOne.NPCs.Schedules;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Police;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Handover;
using Il2CppScheduleOne.UI.Input;
using Il2CppScheduleOne.UI.Stations;
using Il2CppScheduleOne.Weather;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Polyfill.Boot;
using Polyfill.Contract;
using Polyfill.Core;
using Polyfill.ModFixes;
using Polyfill.Report;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "Polyfill", "0.13.20", "DooDesch", "https://github.com/DooDesch-Mods/ScheduleOne-Polyfill")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DooDesch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © DooDesch")]
[assembly: AssemblyFileVersion("0.13.20.0")]
[assembly: AssemblyInformationalVersion("0.13.20+7326413858891662af71f4d0098defca82a71120")]
[assembly: AssemblyProduct("Polyfill")]
[assembly: AssemblyTitle("Polyfill")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially created with the assistance of Generative AI.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic/OpenAI")]
[assembly: AssemblyVersion("0.13.20.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DooDesch
{
	internal static class ModVersion
	{
		internal const string Current = "0.13.20";
	}
}
namespace Hash.Api
{
	public static class HashCommands
	{
		private const string BridgeTypeName = "Hash.Bridge.HashBridge, Hash";

		private static readonly List<string[]> _pending = new List<string[]>();

		private static Action<string, string, string, string> _declare;

		private static bool _bound;

		public static bool Available
		{
			get
			{
				Bind();
				return _bound;
			}
		}

		private static string Owner
		{
			get
			{
				try
				{
					return Assembly.GetExecutingAssembly().GetName().Name ?? "";
				}
				catch
				{
					return "";
				}
			}
		}

		public static void Add(string word, string description, string example = null)
		{
			if (!string.IsNullOrEmpty(word))
			{
				Bind();
				if (_declare != null)
				{
					Safely(word, description, example);
					return;
				}
				_pending.Add(new string[3]
				{
					word,
					description ?? "",
					example ?? ""
				});
			}
		}

		private static void Safely(string word, string description, string example)
		{
			try
			{
				_declare(word, description ?? "", example ?? "", Owner);
			}
			catch
			{
			}
		}

		private static void Bind()
		{
			if (_bound)
			{
				return;
			}
			try
			{
				Type type = Type.GetType("Hash.Bridge.HashBridge, Hash", throwOnError: false);
				if (type == null)
				{
					return;
				}
				_declare = type.GetField("Declare", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as Action<string, string, string, string>;
				if (_declare == null)
				{
					return;
				}
				_bound = true;
				foreach (string[] item in _pending)
				{
					Safely(item[0], item[1], item[2]);
				}
				_pending.Clear();
			}
			catch
			{
			}
		}
	}
}
namespace Polyfill.Boot
{
	internal sealed class MelonConsentStore : IConsentStore
	{
		private const string Category = "Polyfill";

		internal static void Install()
		{
			Consent.Use(new MelonConsentStore());
		}

		public bool TryReadBool(string key, out bool value)
		{
			return Read(key, fallback: false, out value);
		}

		public bool TryReadInt(string key, out int value)
		{
			return Read(key, 0, out value);
		}

		private static bool Read<T>(string key, T fallback, out T value)
		{
			value = fallback;
			try
			{
				MelonPreferences_Category val = MelonPreferences.GetCategory("Polyfill") ?? MelonPreferences.CreateCategory("Polyfill");
				if (val == null)
				{
					return false;
				}
				MelonPreferences_Entry<T> val2 = val.GetEntry<T>(key) ?? val.CreateEntry<T>(key, fallback, key, Describe(key), false, false, (ValueValidator)null, (string)null);
				value = val2.Value;
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static string Describe(string key)
		{
			return key switch
			{
				"ShareFindings" => "Send anonymous findings - which mod, which symbol, repaired or not. Never your name, your paths or your save.", 
				"ShareFindingsAnswered" => "Whether the question has been answered. Clear this to be asked again.", 
				"ShareFindingsAsked" => "How many launches have asked. After three, the question stops.", 
				_ => key, 
			};
		}

		public void Write<T>(string key, T value, string description)
		{
			try
			{
				MelonPreferences_Category val = MelonPreferences.GetCategory("Polyfill") ?? MelonPreferences.CreateCategory("Polyfill");
				if (val != null)
				{
					MelonPreferences_Entry<T> entry = val.GetEntry<T>(key);
					if (entry == null)
					{
						val.CreateEntry<T>(key, value, key, description, false, false, (ValueValidator)null, (string)null);
					}
					else
					{
						entry.Value = value;
					}
				}
			}
			catch
			{
			}
		}

		public void Flush()
		{
			try
			{
				MelonPreferences.Save();
			}
			catch
			{
			}
		}
	}
}
namespace Polyfill.Core
{
	internal sealed class GeneratorIdentity
	{
		internal string GameAssemblyHash;

		internal string UnityVersion;

		internal string DumperVersion;

		internal string DumperScrsVersion;

		internal string Loader;

		internal bool IsKnown => !string.IsNullOrEmpty(GameAssemblyHash);

		internal string Digest()
		{
			string text = GameAssemblyHash ?? "";
			if (text.Length > 16)
			{
				text = text.Substring(0, 16);
			}
			return $"{text}/{UnityVersion}/{DumperVersion}/{DumperScrsVersion}/{Loader}";
		}

		internal static GeneratorIdentity Read()
		{
			GeneratorIdentity generatorIdentity = new GeneratorIdentity
			{
				Loader = MelonLoaderVersion()
			};
			string text = ConfigPath();
			if (text == null || !File.Exists(text))
			{
				return generatorIdentity;
			}
			try
			{
				string[] array = File.ReadAllLines(text);
				foreach (string text2 in array)
				{
					int num = text2.IndexOf('=');
					if (num > 0)
					{
						string text3 = text2.Substring(0, num).Trim();
						string text4 = text2.Substring(num + 1).Trim().Trim('"');
						switch (text3)
						{
						case "GameAssemblyHash":
							generatorIdentity.GameAssemblyHash = text4;
							break;
						case "UnityVersion":
							generatorIdentity.UnityVersion = text4;
							break;
						case "DumperVersion":
							generatorIdentity.DumperVersion = text4;
							break;
						case "DumperSCRSVersion":
							generatorIdentity.DumperScrsVersion = text4;
							break;
						}
					}
				}
			}
			catch
			{
			}
			return generatorIdentity;
		}

		internal static string ConfigPath()
		{
			try
			{
				string melonLoaderDirectory = MelonEnvironment.MelonLoaderDirectory;
				if (string.IsNullOrEmpty(melonLoaderDirectory))
				{
					return null;
				}
				return Path.Combine(melonLoaderDirectory, "Dependencies", "Il2CppAssemblyGenerator", "Config.cfg");
			}
			catch
			{
				return null;
			}
		}

		private static string MelonLoaderVersion()
		{
			try
			{
				return typeof(MelonPlugin).Assembly.GetName().Version?.ToString() ?? "?";
			}
			catch
			{
				return "?";
			}
		}
	}
}
namespace Polyfill.Contract
{
	internal static class BorrowedAppClones
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string CloneMethod;

			internal string HookMethod;

			internal string Field;

			internal string Site => Type + "/" + CloneMethod;
		}

		internal const string FixId = "borrowed-app-layout";

		internal const string GameVersions = "0.4.6*,0.4.7*";

		internal const string Because = "it switches off the vertical layout group the clone inherits from the game's product manager, at the moment the mod builds its app";

		internal const string Repaired = "the fix borrowed-app-layout switched off the vertical layout group the clone inherited, so the app's own panels decide where they go";

		internal static readonly Entry[] All = new Entry[3]
		{
			new Entry
			{
				Type = "MediaPlayer.PhoneIntegration",
				CloneMethod = "SpawnApp",
				HookMethod = "ClearContainer",
				Field = null
			},
			new Entry
			{
				Type = "Tweakables.TweakablesApp",
				CloneMethod = "ClonePanel",
				HookMethod = "ClonePanel",
				Field = "_appPanel"
			},
			new Entry
			{
				Type = "ElDiablo59WagesManager.WagesApp",
				CloneMethod = "BuildAppRoot",
				HookMethod = "BuildAppRoot",
				Field = "_appRoot"
			}
		};

		private static readonly VersionRange Range = VersionRange.Parse("0.4.6*,0.4.7*");

		internal static Entry At(string site)
		{
			if (string.IsNullOrEmpty(site))
			{
				return null;
			}
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (string.Equals(entry.Site, site, StringComparison.Ordinal))
				{
					return entry;
				}
			}
			return null;
		}

		internal static bool RunsOn(GameVersion game)
		{
			return Range.Allows(game);
		}
	}
	internal static class CommandTable
	{
		internal sealed class Command
		{
			internal string Name;

			internal string Help;

			internal string Example;
		}

		internal static readonly Command[] All = new Command[12]
		{
			C("polyfill", "what Polyfill found in your mods at startup", "polyfill"),
			C("polyfilllist", "every mod, with its verdict", "polyfilllist"),
			C("polyfillshow", "everything one mod asks for that is missing", "polyfillshow hitman"),
			C("polyfillunfixed", "only what cannot be pointed at anything", "polyfillunfixed hitman"),
			C("polyfillexport", "write one file with everything, ready to send", "polyfillexport"),
			C("polyfillprobe", "can the runtime resolve this type, and does Type::Member really run?", "polyfillprobe Il2CppScheduleOne.UI.InputPromptsCanvas::LoadModule objectselector"),
			C("polyfillprefab", "does the game still have this prefab, and what is near it", "polyfillprefab Basic Metal Glass Door"),
			C("polyfillfixes", "the per-mod fixes, and switch one off", "polyfillfixes off s1mapi-prefabs"),
			C("polyfillrestore", "undo every repair, restart to take effect", "polyfillrestore"),
			C("polyfillregen", "have MelonLoader rebuild the game's generated assemblies", "polyfillregen"),
			C("polyfillshare", "share anonymous findings, or see what would be sent", "polyfillshare show"),
			C("polyfillhelp", "list the polyfill commands", "polyfillhelp")
		};

		internal static bool Owns(string command)
		{
			if (string.IsNullOrEmpty(command))
			{
				return false;
			}
			Command[] all = All;
			for (int i = 0; i < all.Length; i++)
			{
				if (string.Equals(all[i].Name, command, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static Command C(string name, string help, string example)
		{
			return new Command
			{
				Name = name,
				Help = help,
				Example = example
			};
		}
	}
	internal interface IConsentStore
	{
		bool TryReadBool(string key, out bool value);

		bool TryReadInt(string key, out int value);

		void Write<T>(string key, T value, string description);

		void Flush();
	}
	internal static class Consent
	{
		internal sealed class State
		{
			internal bool Sharing;

			internal bool Answered;

			internal int Asked;
		}

		internal const string SharingKey = "ShareFindings";

		internal const string AnsweredKey = "ShareFindingsAnswered";

		internal const string AskedKey = "ShareFindingsAsked";

		private static IConsentStore _store;

		internal static bool Sharing => Read().Sharing;

		internal static void Use(IConsentStore store)
		{
			_store = store;
		}

		internal static State Read()
		{
			State state = new State();
			IConsentStore store = _store;
			if (store == null)
			{
				return state;
			}
			try
			{
				if (store.TryReadBool("ShareFindings", out var value))
				{
					state.Sharing = value;
				}
				if (store.TryReadBool("ShareFindingsAnswered", out var value2))
				{
					state.Answered = value2;
				}
				if (store.TryReadInt("ShareFindingsAsked", out var value3))
				{
					state.Asked = value3;
				}
			}
			catch
			{
			}
			return state;
		}

		internal static void Write(bool sharing, bool answered)
		{
			IConsentStore store = _store;
			if (store == null)
			{
				return;
			}
			try
			{
				store.Write("ShareFindings", sharing, "Send anonymous findings - which mod, which symbol, repaired or not. Never your name, your paths or your save.");
				store.Write("ShareFindingsAnswered", answered, "Whether the question has been answered. Clear this to be asked again.");
				store.Flush();
			}
			catch
			{
			}
		}

		internal static void CountOneAsk(State state)
		{
			IConsentStore store = _store;
			if (store == null)
			{
				return;
			}
			try
			{
				store.Write("ShareFindingsAsked", state.Asked + 1, "How many launches have asked. After three, the question stops.");
				store.Flush();
			}
			catch
			{
			}
		}
	}
	internal static class CoveredElsewhere
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Member;

			internal string FixId;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[3]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.AmountSelector",
				Member = "get_onPriceChanged",
				FixId = "amount-changed-after-override",
				Because = "the UnityEvent this returned cannot be handed back - interop wrappers are pooled by weak reference, so it could not be the same object twice - but the change it announced is raised again when a mod replaces the setter that used to raise it"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Handover.HandoverScreen",
				Member = "get_OriginalItemLocations",
				FixId = "otc-smart-fill-tracking",
				Because = "the dictionary and the nested enum it was keyed by are both gone, and nothing of that shape can be handed back - but it was write-only bookkeeping even in 0.4.5f2, so the fix drops the call instead of answering it"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Handover.HandoverScreen/EItemSource",
				Member = null,
				FixId = "otc-smart-fill-tracking",
				Because = "the enum only ever typed HandoverScreen.OriginalItemLocations, and 0.4.6 deleted both - a copy would have its own identity and could not satisfy the signature. The one method that names it is OverTheCounter's TrackItemAsPlayer, and the fix takes the call to it out, so nothing reaches the name"
			}
		};

		internal static Entry For(string type, string member)
		{
			if (type == null || member == null)
			{
				return null;
			}
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (string.Equals(entry.Type, type, StringComparison.Ordinal) && string.Equals(entry.Member, member, StringComparison.Ordinal))
				{
					return entry;
				}
			}
			return null;
		}

		internal static Entry ForType(string type)
		{
			if (type == null)
			{
				return null;
			}
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (entry.Member == null && string.Equals(entry.Type, type, StringComparison.Ordinal))
				{
					return entry;
				}
			}
			return null;
		}
	}
	internal static class FoldedAims
	{
		private const string Slot = "doodesch.polyfill.folded-aims";

		private static readonly object Gate = new object();

		internal static void Add(MethodInfo patch, Type aimedAt)
		{
			if (patch == null || aimedAt == null)
			{
				return;
			}
			lock (Gate)
			{
				Dictionary<MethodInfo, List<Type>> dictionary = AppDomain.CurrentDomain.GetData("doodesch.polyfill.folded-aims") as Dictionary<MethodInfo, List<Type>>;
				if (dictionary == null)
				{
					dictionary = new Dictionary<MethodInfo, List<Type>>();
					AppDomain.CurrentDomain.SetData("doodesch.polyfill.folded-aims", dictionary);
				}
				lock (dictionary)
				{
					if (!dictionary.TryGetValue(patch, out var value))
					{
						value = (dictionary[patch] = new List<Type>());
					}
					if (!value.Contains(aimedAt))
					{
						value.Add(aimedAt);
					}
				}
			}
		}

		internal static Type[] For(MethodInfo patch)
		{
			if (patch == null)
			{
				return null;
			}
			if (!(AppDomain.CurrentDomain.GetData("doodesch.polyfill.folded-aims") is Dictionary<MethodInfo, List<Type>> dictionary))
			{
				return null;
			}
			lock (dictionary)
			{
				List<Type> value;
				return dictionary.TryGetValue(patch, out value) ? value.ToArray() : null;
			}
		}

		internal static bool Has(MethodInfo patch)
		{
			return For(patch) != null;
		}
	}
	internal readonly struct GameVersion : IComparable<GameVersion>, IEquatable<GameVersion>
	{
		internal readonly int[] Parts;

		internal readonly string Raw;

		internal static readonly GameVersion Unknown = new GameVersion(null, "");

		internal bool IsKnown
		{
			get
			{
				if (Parts != null)
				{
					return Parts.Length != 0;
				}
				return false;
			}
		}

		private GameVersion(int[] parts, string raw)
		{
			Parts = parts;
			Raw = raw;
		}

		internal static bool TryParse(string text, out GameVersion version)
		{
			version = Unknown;
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			List<int> list = new List<int>(4);
			long num = 0L;
			bool flag = false;
			foreach (char c in text)
			{
				if (c >= '0' && c <= '9')
				{
					if (num < 214748364)
					{
						num = num * 10 + (c - 48);
					}
					flag = true;
				}
				else if (flag)
				{
					list.Add((int)num);
					num = 0L;
					flag = false;
				}
			}
			if (flag)
			{
				list.Add((int)num);
			}
			if (list.Count == 0)
			{
				return false;
			}
			version = new GameVersion(list.ToArray(), text);
			return true;
		}

		internal static GameVersion Parse(string text)
		{
			if (!TryParse(text, out var version))
			{
				return Unknown;
			}
			return version;
		}

		public int CompareTo(GameVersion other)
		{
			int[] array = Parts ?? Array.Empty<int>();
			int[] array2 = other.Parts ?? Array.Empty<int>();
			int num = Math.Min(array.Length, array2.Length);
			for (int i = 0; i < num; i++)
			{
				if (array[i] != array2[i])
				{
					if (array[i] >= array2[i])
					{
						return 1;
					}
					return -1;
				}
			}
			return array.Length.CompareTo(array2.Length);
		}

		internal bool StartsWith(GameVersion prefix, int count)
		{
			if (Parts == null || prefix.Parts == null)
			{
				return false;
			}
			if (count > prefix.Parts.Length || count > Parts.Length)
			{
				return false;
			}
			for (int i = 0; i < count; i++)
			{
				if (Parts[i] != prefix.Parts[i])
				{
					return false;
				}
			}
			return true;
		}

		public bool Equals(GameVersion other)
		{
			if (CompareTo(other) == 0)
			{
				return IsKnown == other.IsKnown;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is GameVersion other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			int num = 17;
			if (Parts != null)
			{
				int[] parts = Parts;
				foreach (int num2 in parts)
				{
					num = num * 31 + num2;
				}
			}
			return num;
		}

		public override string ToString()
		{
			if (!IsKnown)
			{
				return "unknown";
			}
			return Raw;
		}

		public static bool operator <(GameVersion a, GameVersion b)
		{
			return a.CompareTo(b) < 0;
		}

		public static bool operator >(GameVersion a, GameVersion b)
		{
			return a.CompareTo(b) > 0;
		}

		public static bool operator <=(GameVersion a, GameVersion b)
		{
			return a.CompareTo(b) <= 0;
		}

		public static bool operator >=(GameVersion a, GameVersion b)
		{
			return a.CompareTo(b) >= 0;
		}

		public static bool operator ==(GameVersion a, GameVersion b)
		{
			return a.Equals(b);
		}

		public static bool operator !=(GameVersion a, GameVersion b)
		{
			return !a.Equals(b);
		}
	}
	internal static class GameVersionSource
	{
		private static string _raw;

		internal static string Raw => _raw ?? (_raw = Read());

		internal static GameVersion Current => GameVersion.Parse(Raw);

		private static string Read()
		{
			string[] array = new string[2] { "MelonLoader.InternalUtils.UnityInformationHandler, MelonLoader", "MelonLoader.MelonUtils, MelonLoader" };
			foreach (string typeName in array)
			{
				try
				{
					if ((Type.GetType(typeName, throwOnError: false)?.GetProperty("GameVersion", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(null) is string { Length: >0 } text)
					{
						return text;
					}
				}
				catch
				{
				}
			}
			return "unknown";
		}

		internal static string Disagreement(string other)
		{
			if (string.IsNullOrEmpty(other))
			{
				return null;
			}
			if (GameVersion.Parse(other) == Current)
			{
				return null;
			}
			return $"MelonLoader says the game is '{Raw}' and Unity says '{other}'. Polyfill went with " + "MelonLoader's, which is the one every version decision was made against.";
		}
	}
	internal static class SplitScreens
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Station;

			internal string StationName;

			internal bool HasRemoveUi;
		}

		private const string Stations = "Il2CppScheduleOne.UI.Stations.";

		private const string Objects = "Il2CppScheduleOne.ObjectScripts.";

		internal static readonly Entry[] All = new Entry[5]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Stations.PackagingStationCanvas",
				Station = "Il2CppScheduleOne.ObjectScripts.PackagingStation",
				StationName = "station",
				HasRemoveUi = true
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Stations.BrickPressCanvas",
				Station = "Il2CppScheduleOne.ObjectScripts.BrickPress",
				StationName = "press",
				HasRemoveUi = true
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Stations.LabOvenCanvas",
				Station = "Il2CppScheduleOne.ObjectScripts.LabOven",
				StationName = "oven",
				HasRemoveUi = true
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Stations.CauldronCanvas",
				Station = "Il2CppScheduleOne.ObjectScripts.Cauldron",
				StationName = "cauldron",
				HasRemoveUi = true
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Stations.DryingRackCanvas",
				Station = "Il2CppScheduleOne.ObjectScripts.DryingRack",
				StationName = "rack",
				HasRemoveUi = false
			}
		};
	}
	internal static class GrownOverloads
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Name;

			internal string[] OldParameters;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[7]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.StorageMenu",
				Name = "Open",
				OldParameters = new string[3] { "System.String", "System.String", "Il2CppScheduleOne.ItemFramework.IItemSlotOwner" },
				Because = "0.4.6 gave every StorageMenu.Open a closing callback"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.StorageMenu",
				Name = "Open",
				OldParameters = new string[3] { "Il2CppScheduleOne.ItemFramework.IItemSlotOwner", "System.String", "System.String" },
				Because = "0.4.6 gave every StorageMenu.Open a closing callback"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.StorageMenu",
				Name = "Open",
				OldParameters = new string[1] { "Il2CppScheduleOne.Storage.StorageEntity" },
				Because = "the third Open took the same trailing callback as its two siblings and was missed when they were listed (0.4.5f2 Open_Public_Virtual_New_Void_StorageEntity_0 against 0.4.6f13 ..._StorageEntity_Action_0)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.Economy.CustomerData",
				Name = "GetOrderDays",
				OldParameters = new string[2] { "System.Single", "System.Single" },
				Because = "GetOrderDays stopped returning the list and started filling one it is handed"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.BlackOverlay",
				Name = "Open",
				OldParameters = new string[1] { "System.Single" },
				Because = "0.4.7 gave BlackOverlay.Open a completion callback after the fade time, defaulting to null (BlackOverlay.cs Open(float fadeTime = 0.5f, Action onComplete = null) on 0.4.7f6)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.BlackOverlay",
				Name = "Close",
				OldParameters = new string[1] { "System.Single" },
				Because = "0.4.7 gave BlackOverlay.Close the same completion callback as Open, defaulting to null (BlackOverlay.cs Close(float fadeTime = 0.5f, Action onComplete = null) on 0.4.7f6)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.DevUtilities.IconGenerator",
				Name = "GeneratePackagingIcon",
				OldParameters = new string[2] { "System.String", "System.String" },
				Because = "0.4.7 gave GeneratePackagingIcon a trailing iconSize defaulting to 512 (IconGenerator.cs:79 on 0.4.7f6); unlisted, a patch naming no parameters (S1API's packaging-icon patches) found two methods and lost its whole patch class"
			}
		};

		internal static bool Doubled(string type, string name)
		{
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (entry.Name == name && string.Equals(entry.Type, type, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool IsStandIn(string type, string name, int parameterCount)
		{
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (entry.Name == name && entry.OldParameters.Length == parameterCount && string.Equals(entry.Type, type, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		internal static MethodInfo Find(Type type, string name, string[] parameters, bool exact)
		{
			MethodInfo methodInfo = null;
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (methodInfo2.Name != name || methodInfo2.DeclaringType != type)
				{
					continue;
				}
				ParameterInfo[] parameters2 = methodInfo2.GetParameters();
				if (exact ? (parameters2.Length != parameters.Length) : (parameters2.Length <= parameters.Length))
				{
					continue;
				}
				bool flag = true;
				for (int j = 0; j < parameters.Length; j++)
				{
					if (parameters2[j].ParameterType.FullName != parameters[j])
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					if (methodInfo != null)
					{
						return null;
					}
					methodInfo = methodInfo2;
				}
			}
			return methodInfo;
		}

		internal static MethodInfo RealFor(MethodBase standIn)
		{
			Type type = standIn?.DeclaringType;
			if (type == null)
			{
				return null;
			}
			ParameterInfo[] parameters = standIn.GetParameters();
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (entry.Name != standIn.Name || entry.OldParameters.Length != parameters.Length || !string.Equals(entry.Type, type.FullName, StringComparison.Ordinal))
				{
					continue;
				}
				bool flag = true;
				for (int j = 0; j < parameters.Length; j++)
				{
					if (parameters[j].ParameterType.FullName != entry.OldParameters[j])
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return Find(type, entry.Name, entry.OldParameters, exact: false);
				}
			}
			return null;
		}
	}
	internal static class Headless
	{
		private static bool _asked;

		private static bool _answer;

		private static string _why;

		internal static bool Yes(out string why)
		{
			if (!_asked)
			{
				_asked = true;
				_answer = Look(out _why);
			}
			why = _why;
			return _answer;
		}

		internal static bool Yes()
		{
			string why;
			return Yes(out why);
		}

		private static bool Look(out string why)
		{
			why = null;
			try
			{
				string[] commandLineArgs = Environment.GetCommandLineArgs();
				for (int i = 0; i < commandLineArgs.Length; i++)
				{
					switch (commandLineArgs[i].TrimStart('-').ToLowerInvariant())
					{
					case "batchmode":
						why = "the game is running in batch mode";
						return true;
					case "nographics":
						why = "the game is running without graphics";
						return true;
					case "dedicated-server":
					case "dedicatedserver":
						why = "this is a dedicated server";
						return true;
					}
				}
			}
			catch (Exception)
			{
			}
			return false;
		}
	}
	internal interface ILog
	{
		void Msg(string message);

		void Warning(string message);

		void Error(string message);
	}
	internal static class NameOnlyTargets
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Name;

			internal string[] Parameters;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[3]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.Quests.Contract",
				Name = "GetProductListMatch",
				Parameters = new string[2] { "List<ItemInstance>", "Int32&" },
				Because = "0.4.6 had one GetProductListMatch(List<ItemInstance>, out int) (Contract.cs:313 on 0.4.6f13); 0.4.7 added GetProductListMatch(List<ProductItemInstance>, out int), which copies its list and calls the first (Contract.cs:312-322 on 0.4.7f6)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.AvatarFramework.Avatar",
				Name = "EnableRagdoll",
				Parameters = new string[0],
				Because = "0.4.7's EnableRagdoll() takes no force; the two-argument form beside it is the one Polyfill puts back for callers"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.Combat.CombatBehaviour",
				Name = "SetMovementSpeed",
				Parameters = new string[1] { "Single" },
				Because = "0.4.7's SetMovementSpeed(normalizedSpeed) is the game's; the three-argument form beside it is the one Polyfill puts back for callers"
			}
		};

		internal static Entry For(string type, string name)
		{
			if (type == null || name == null)
			{
				return null;
			}
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (entry.Name == name && string.Equals(entry.Type, type, StringComparison.Ordinal))
				{
					return entry;
				}
			}
			return null;
		}

		internal static MethodInfo Find(Type type, Entry entry)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != entry.Name || methodInfo.DeclaringType != type)
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length == entry.Parameters.Length)
				{
					bool flag = true;
					for (int j = 0; j < parameters.Length && flag; j++)
					{
						flag = Spell(parameters[j].ParameterType) == entry.Parameters[j];
					}
					if (flag)
					{
						return methodInfo;
					}
				}
			}
			return null;
		}

		internal static string Spell(Type type)
		{
			if (type.IsByRef)
			{
				return Spell(type.GetElementType()) + "&";
			}
			if (!type.IsGenericType)
			{
				return type.Name;
			}
			Type[] genericArguments = type.GetGenericArguments();
			string[] array = new string[genericArguments.Length];
			for (int i = 0; i < genericArguments.Length; i++)
			{
				array[i] = Spell(genericArguments[i]);
			}
			return Bare(type.Name) + "<" + string.Join(",", array) + ">";
		}

		internal static string Bare(string name)
		{
			int num = name.IndexOf('`');
			if (num >= 0)
			{
				return name.Substring(0, num);
			}
			return name;
		}
	}
	internal static class NarrowedOverloads
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Name;

			internal string[] RealParameters;

			internal string ParameterName;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[1]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Phone.CounterofferInterface",
				Name = "ChangeQuantity",
				RealParameters = new string[1] { "System.Single" },
				ParameterName = "change",
				Because = "the quantity step took an int until 0.4.5f2 and takes a float now, and a second ChangeQuantity(string) arrived beside it for the text box (CounterofferInterface.cs:191-207)"
			}
		};
	}
	internal static class PolyfillPaths
	{
		internal const string BackupSuffix = ".polyfill-orig";

		internal const string TempSuffix = ".polyfill-tmp";

		internal const string FolderName = "Polyfill";

		internal const string LastRunFile = "last-run.txt";

		internal const string ReportFile = "polyfill-report.txt";

		internal const string StampFileName = "interop.stamp";

		internal const string RestorePendingFile = "restore-pending";

		internal static string Folder(string userDataDirectory)
		{
			return Path.Combine(userDataDirectory ?? ".", "Polyfill");
		}

		internal static string LastRun(string userDataDirectory)
		{
			return Path.Combine(Folder(userDataDirectory), "last-run.txt");
		}

		internal static string Report(string userDataDirectory)
		{
			return Path.Combine(Folder(userDataDirectory), "polyfill-report.txt");
		}

		internal static string Stamp(string userDataDirectory)
		{
			return Path.Combine(Folder(userDataDirectory), "interop.stamp");
		}

		internal static string RestorePending(string userDataDirectory)
		{
			return Path.Combine(Folder(userDataDirectory), "restore-pending");
		}

		internal static string Backup(string assemblyPath)
		{
			return assemblyPath + ".polyfill-orig";
		}
	}
	internal static class ReaimedPatches
	{
		private const string Slot = "doodesch.polyfill.reaimed-patches";

		private static readonly object Gate = new object();

		internal static void Add(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return;
			}
			lock (Gate)
			{
				List<string> list = AppDomain.CurrentDomain.GetData("doodesch.polyfill.reaimed-patches") as List<string>;
				if (list == null)
				{
					list = new List<string>();
					AppDomain.CurrentDomain.SetData("doodesch.polyfill.reaimed-patches", list);
				}
				lock (list)
				{
					if (!list.Contains(key))
					{
						list.Add(key);
					}
				}
			}
		}

		internal static string[] All()
		{
			if (!(AppDomain.CurrentDomain.GetData("doodesch.polyfill.reaimed-patches") is List<string> list))
			{
				return Array.Empty<string>();
			}
			lock (list)
			{
				return list.ToArray();
			}
		}
	}
	internal static class RenamedMethods
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string OldName;

			internal string NewName;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[10]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.ObjectScripts.PackagingStation",
				OldName = "Open",
				NewName = "Use",
				Because = "0.4.5f2 PackagingStation.Open() set the camera up and opened the canvas; 0.4.6f13 Use() pushes a state and opens the canvas, on the same type (PackagingStation.cs:405)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Handover.HandoverScreenPriceSelector",
				OldName = "SetPrice",
				NewName = "SetAmount",
				Because = "the price control became the game's general amount box in 0.4.6, and SetPrice(float) became SetAmount(float) on it (AmountSelector.cs:61)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Stations.ChemistryStationCanvas",
				OldName = "BeginButtonPressed",
				NewName = "BeginTask",
				Because = "0.4.5f2 ChemistryStationCanvas had one begin method, the public BeginButtonPressed(); 0.4.6 ChemistryStationInterface has one, the private BeginTask(), which Awake adds to BeginButton.onClick and Update calls on Submit (ChemistryStationInterface.cs:50, :67 and :190 on 0.4.6f13)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Handover.HandoverScreen",
				OldName = "Open",
				NewName = "OnOpen",
				Because = "0.4.7 split Open into Open_Contract, Open_Sample, Open_Offer and Open_SpecialCustomer, and each ends in OnOpen(EMode mode), which does what the end of Open did (HandoverScreen.cs:148-174, OnOpen at :181 on 0.4.7f6)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.PlayerScripts.Player",
				OldName = "RpcLogic___ReceivePlayerNameData_3895153758",
				NewName = "RpcLogic___SetPlayerNameAndId_Client_3895153758",
				Because = "0.4.7 renamed the client half of the player name RPC to SetPlayerNameAndId_Client with the same (conn, playerName, id) and the same signature hash; its body sets PlayerName and PlayerCode and logs \"Received player name data\" (Player.cs on 0.4.7f6)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.Economy.Supplier",
				OldName = "CreateMessageConversation",
				NewName = "OnMessageConversationAssigned",
				Because = "0.4.7 builds the conversation elsewhere and hands it to the NPC; a supplier sets up its own sendable messages (dead drop, meet-up, pay debt) in OnMessageConversationAssigned (Supplier.cs on 0.4.7f6), which is the moment a patch after CreateMessageConversation was waiting for. A postfix means the same thing; a prefix does not: on 0.4.6 it ran before the conversation existed and returning false stopped it being made, while on 0.4.7 it runs after the conversation is assigned, cannot stop that, and runs again if the conversation is reassigned"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.Economy.Customer",
				OldName = "HandoverChosen",
				NewName = "CompleteContractDialogueChosen",
				Because = "the dialogue choice that hands over for a contract: 0.4.7's CompleteContractDialogueChosen skips the dialogue's end and opens the contract handover screen (Customer.cs on 0.4.7f6)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.Trash.TrashItem",
				OldName = "Start",
				NewName = "Initialize",
				Because = "0.4.6 gave a new trash item its GUID and velocity right after Instantiate and Unity ran its Start a frame later (TrashManager.cs:165-172, TrashItem.cs:110-116 on 0.4.6f13); 0.4.7 has no Start and calls Initialize(guid, initialVelocity) once on every item and bag it creates (TrashItem.cs:62-69, TrashManager.cs:198, :242 on 0.4.7f6). A postfix sees the same finished item; a prefix runs before the GUID is set, where on 0.4.6 it ran after"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.AvatarFramework.Avatar",
				OldName = "LateUpdate",
				NewName = "Update",
				Because = "Avatar declared Update() and LateUpdate() up to 0.4.3f3 and only Update() from 0.4.4f10 on (s1-codearchiver 9581d62, AvatarFramework/Avatar.cs); Update is the one method Unity still calls on it every frame (Avatar.cs:147 on 0.4.6f13, :133 on 0.4.7f7)"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.Product.ProductIconManager",
				OldName = "GenerateIcons",
				NewName = "GenerateRuntimeIcons",
				Because = "0.4.6's GenerateIcons(productID) made one icon per packaging and returned the product's own sprite; 0.4.7f12 GenerateRuntimeIcons(productID) does the same, and the product creation methods assign its result to the new definition's Icon (ProductIconManager.cs:74-109 on 0.4.7f12)"
			}
		};

		internal static string Successor(string type, string oldName)
		{
			if (type == null || oldName == null)
			{
				return null;
			}
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (string.Equals(entry.Type, type, StringComparison.Ordinal) && string.Equals(entry.OldName, oldName, StringComparison.Ordinal))
				{
					return entry.NewName;
				}
			}
			return null;
		}

		internal static string Because(string type, string oldName)
		{
			if (type == null || oldName == null)
			{
				return null;
			}
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (string.Equals(entry.Type, type, StringComparison.Ordinal) && string.Equals(entry.OldName, oldName, StringComparison.Ordinal))
				{
					return entry.Because;
				}
			}
			return null;
		}
	}
	internal static class RenamedParameters
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Method;

			internal int ParameterCount;

			internal int Index;

			internal string OldName;

			internal string NewName;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[2]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.Shop.ShopInterface",
				Method = "SetIsOpen",
				ParameterCount = 1,
				Index = 0,
				OldName = "isOpen",
				NewName = "open",
				Because = "the flag kept its type and its meaning and lost its name in 0.4.6"
			},
			new Entry
			{
				Type = "Il2CppScheduleOne.UI.AmountSelector",
				Method = "SetAmount",
				ParameterCount = 1,
				Index = 0,
				OldName = "price",
				NewName = "amount",
				Because = "SetPrice(float price) became SetAmount(float amount) when the handover price control turned into the game's general amount box (AmountSelector.cs:61)"
			}
		};

		internal static IEnumerable<Entry> For(string type, string method, int parameterCount)
		{
			Entry[] all = All;
			foreach (Entry entry in all)
			{
				if (entry.Method == method && entry.ParameterCount == parameterCount && string.Equals(entry.Type, type, StringComparison.Ordinal))
				{
					yield return entry;
				}
			}
		}
	}
	internal static class RenamedTypes
	{
		internal static readonly string[] StandIns = new string[12]
		{
			"Il2CppScheduleOne.UI.Stations.MixingStationCanvas", "Il2CppScheduleOne.UI.Stations.ChemistryStationCanvas", "Il2CppScheduleOne.UI.Stations.CauldronCanvas", "Il2CppScheduleOne.UI.Stations.DryingRackCanvas", "Il2CppScheduleOne.UI.Handover.HandoverScreenPriceSelector", "Il2CppScheduleOne.Weather.WeatherConditions", "Il2CppScheduleOne.DevUtilities.ExitAction", "Il2CppScheduleOne.UI.ATM.ATMInterface", "Il2CppScheduleOne.UI.Stations.Drying_rack.DryingOperationUI", "Il2CppScheduleOne.UI.MainMenu.MainMenuScreen",
			"Il2CppScheduleOne.Dialogue.DialogueContainer", "Il2CppScheduleOne.AvatarFramework.Customization.CharacterCreator"
		};

		internal static bool IsStandIn(string fullName)
		{
			if (fullName == null)
			{
				return false;
			}
			string[] standIns = StandIns;
			for (int i = 0; i < standIns.Length; i++)
			{
				if (string.Equals(standIns[i], fullName, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class ReplacedMethods
	{
		internal sealed class Replacement
		{
			internal string Name;

			internal string[] Parameters = new string[0];

			internal object[] Arguments = new object[0];
		}

		internal sealed class Entry
		{
			internal string Type;

			internal string OldName;

			internal string[] Parameters;

			internal string[] ParameterNames;

			internal Replacement[] Replacements;

			internal string Because;
		}

		private const string Bool = "System.Boolean";

		private const string Management = "Il2CppScheduleOne.UI.Management.";

		internal static readonly Entry[] All = new Entry[2]
		{
			Selector("ObjectSelector"),
			Selector("TransitEntitySelector")
		};

		private static Entry Selector(string type)
		{
			Entry entry = new Entry();
			entry.Type = "Il2CppScheduleOne.UI.Management." + type;
			entry.OldName = "Close";
			entry.Parameters = new string[2] { "System.Boolean", "System.Boolean" };
			entry.ParameterNames = new string[2] { "returnToClipboard", "pushChanges" };
			entry.Replacements = new Replacement[2]
			{
				new Replacement
				{
					Name = "CloseAndSubmit",
					Arguments = new object[2] { true, true }
				},
				new Replacement
				{
					Name = "CloseAndCancel",
					Arguments = new object[2] { true, false }
				}
			};
			entry.Because = "0.4.5f2 " + type + ".Close(bool returnToClipboard, bool pushChanges); 0.4.6f13 has CloseAndSubmit and CloseAndCancel over a shared OnClose that always returns to the clipboard (ObjectSelector.cs:120-143)";
			return entry;
		}
	}
	internal static class ReshapedMethods
	{
		internal static readonly (string Type, string Name, int StandInArity, string Because)[] All = new(string, string, int, string)[3]
		{
			("Il2CppScheduleOne.PlayerScripts.PlayerManager", "TryGetPlayerData", 6, "0.4.7 bundles the five out values into one FullPlayerData and takes whether the asker is the host"),
			("Il2CppScheduleOne.Economy.Customer", "ProcessHandover", 5, "0.4.7 dropped the leading outcome argument along with the enum, so a patch naming it binds only on the stand-in"),
			("Il2CppScheduleOne.Economy.Customer", "ProcessHandoverServerSide", 7, "the server half of the handover lost the same leading outcome as ProcessHandover")
		};

		internal static int StandIn(string type, string name)
		{
			(string, string, int, string)[] all = All;
			for (int i = 0; i < all.Length; i++)
			{
				(string, string, int, string) tuple = all[i];
				if (tuple.Item2 == name && string.Equals(tuple.Item1, type, StringComparison.Ordinal))
				{
					return tuple.Item3;
				}
			}
			return -1;
		}
	}
	internal static class Outcome
	{
		internal const string Applied = "applied";

		internal const string Refused = "refused";

		internal const string StoodDown = "stood-down";

		internal const string None = "none";
	}
	internal sealed class Finding
	{
		internal string Kind;

		internal bool Note;

		internal string Scope;

		internal string Symbol;

		internal string Reason;

		internal string Hint;

		internal string Site;

		internal string Outcome = "none";

		internal string OutcomeDetail;

		internal bool Covered;

		internal string RepairKey;

		internal bool Fixable => !string.IsNullOrEmpty(Hint);
	}
	internal sealed class ModReport
	{
		internal string Path;

		internal string AssemblyName;

		internal string Name;

		internal string Version;

		internal string Author;

		internal int TypeRefs;

		internal int MemberRefs;

		internal int HarmonyTargetsChecked;

		internal readonly List<Finding> Findings = new List<Finding>();

		internal readonly List<string> Namespaces = new List<string>();

		internal string Display
		{
			get
			{
				if (string.IsNullOrEmpty(Name))
				{
					if (string.IsNullOrEmpty(AssemblyName))
					{
						return System.IO.Path.GetFileName(Path ?? "");
					}
					return AssemblyName;
				}
				return Name;
			}
		}

		internal string Verdict
		{
			get
			{
				bool flag = false;
				foreach (Finding finding in Findings)
				{
					if (!finding.Note)
					{
						flag = true;
						if (!(finding.Outcome == "applied") && !finding.Covered)
						{
							return "blocked";
						}
					}
				}
				if (!flag)
				{
					return "clean";
				}
				return "adaptable";
			}
		}
	}
	internal sealed class RunReport
	{
		internal const int Format = 2;

		internal const string HeaderPrefix = "# polyfill-report ";

		private const char CarriageReturn = '\r';

		internal string Generated = "";

		internal string Game = "?";

		internal string Interop = "";

		internal int AssemblyCount;

		internal readonly List<ModReport> Mods = new List<ModReport>();

		internal readonly List<string> Dropped = new List<string>();

		internal string Problem;

		internal string Text()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("# polyfill-report " + 2);
			stringBuilder.AppendLine("# generated=" + Escape(Generated));
			stringBuilder.AppendLine("# game=" + Escape(Game));
			stringBuilder.AppendLine("# interop=" + Escape(Interop));
			stringBuilder.AppendLine("# assemblies=" + AssemblyCount);
			stringBuilder.AppendLine("# mods=" + Mods.Count);
			foreach (ModReport mod in Mods)
			{
				stringBuilder.AppendLine(string.Join("|", "M", Escape(mod.Path), Escape(mod.AssemblyName), Escape(mod.Name), Escape(mod.Version), Escape(mod.Author), mod.Verdict, mod.TypeRefs.ToString(), mod.MemberRefs.ToString(), mod.HarmonyTargetsChecked.ToString(), mod.Findings.Count.ToString()));
				foreach (Finding finding in mod.Findings)
				{
					stringBuilder.AppendLine(string.Join("|", "F", Escape(mod.Path), Escape(finding.Kind), Escape(finding.Scope), Escape(finding.Symbol), Escape(finding.Reason), Escape(finding.Hint), Escape(finding.Site), Escape(finding.Outcome), Escape(finding.OutcomeDetail)));
				}
			}
			foreach (ModReport mod2 in Mods)
			{
				if (mod2.Namespaces.Count > 0)
				{
					stringBuilder.AppendLine(string.Join("|", "N", Escape(mod2.Path), Escape(string.Join(",", mod2.Namespaces))));
				}
			}
			foreach (string item in Dropped)
			{
				stringBuilder.AppendLine("D|" + Escape(item));
			}
			return stringBuilder.ToString();
		}

		internal static RunReport Read(IEnumerable<string> lines)
		{
			RunReport runReport = new RunReport();
			Dictionary<string, ModReport> dictionary = new Dictionary<string, ModReport>(StringComparer.OrdinalIgnoreCase);
			bool flag = false;
			foreach (string line in lines)
			{
				if (line == null)
				{
					continue;
				}
				string text = line.TrimEnd('\r');
				if (!flag)
				{
					if (!text.StartsWith("# polyfill-report ", StringComparison.Ordinal))
					{
						runReport.Problem = "this is not a Polyfill report";
						return runReport;
					}
					string text2 = text.Substring("# polyfill-report ".Length).Trim();
					if (!int.TryParse(text2, out var result))
					{
						runReport.Problem = "the format is written as '" + text2 + "', which is not a number";
						return runReport;
					}
					if (result > 2)
					{
						runReport.Problem = $"it is format {result} and this build reads {2}. " + "Polyfill.dll in Mods/ and Polyfill.Boot.dll in Plugins/ are from different releases - update both.";
						return runReport;
					}
					flag = true;
				}
				else if (text.StartsWith("# game=", StringComparison.Ordinal))
				{
					runReport.Game = text.Substring(7);
				}
				else if (text.StartsWith("# interop=", StringComparison.Ordinal))
				{
					runReport.Interop = text.Substring(10);
				}
				else if (text.StartsWith("# generated=", StringComparison.Ordinal))
				{
					runReport.Generated = text.Substring(12);
				}
				else if (text.StartsWith("# assemblies=", StringComparison.Ordinal))
				{
					runReport.AssemblyCount = Int(text.Substring(13));
				}
				else
				{
					if (text.Length == 0 || text[0] == '#')
					{
						continue;
					}
					string[] array = text.Split('|');
					switch (array[0])
					{
					case "M":
						if (array.Length >= 10)
						{
							ModReport modReport = new ModReport
							{
								Path = array[1],
								AssemblyName = array[2],
								Name = array[3],
								Version = array[4],
								Author = array[5],
								TypeRefs = Int(array[7]),
								MemberRefs = Int(array[8]),
								HarmonyTargetsChecked = Int(array[9])
							};
							runReport.Mods.Add(modReport);
							dictionary[modReport.Path] = modReport;
						}
						break;
					case "F":
					{
						if (array.Length >= 8 && dictionary.TryGetValue(array[1], out var value))
						{
							value.Findings.Add(new Finding
							{
								Kind = array[2],
								Scope = array[3],
								Symbol = array[4],
								Reason = array[5],
								Hint = array[6],
								Site = array[7],
								Outcome = ((array.Length > 8) ? array[8] : "none"),
								OutcomeDetail = ((array.Length > 9) ? array[9] : "")
							});
						}
						break;
					}
					case "N":
					{
						if (array.Length < 3 || !dictionary.TryGetValue(array[1], out var value2))
						{
							break;
						}
						string[] array2 = array[2].Split(',');
						foreach (string text3 in array2)
						{
							if (!string.IsNullOrEmpty(text3))
							{
								value2.Namespaces.Add(text3);
							}
						}
						break;
					}
					case "D":
						if (array.Length >= 2)
						{
							runReport.Dropped.Add(array[1]);
						}
						break;
					}
				}
			}
			if (!flag)
			{
				runReport.Problem = "the file is empty";
			}
			return runReport;
		}

		internal static int Correct(string[] lines, ModReport mod, Finding finding)
		{
			if (lines == null || mod == null || finding == null)
			{
				return 0;
			}
			string text = Escape(mod.Path);
			string text2 = Escape(finding.Kind);
			string text3 = Escape(finding.Symbol);
			string text4 = Escape(finding.Site);
			int num = 0;
			int num2 = -1;
			for (int i = 0; i < lines.Length; i++)
			{
				string text5 = (lines[i] ?? "").TrimEnd('\r');
				if (text5.StartsWith("M|", StringComparison.Ordinal))
				{
					string[] array = text5.Split('|');
					if (array.Length > 6 && array[1] == text)
					{
						num2 = i;
					}
				}
				else if (text5.StartsWith("F|", StringComparison.Ordinal))
				{
					string[] array2 = text5.Split('|');
					if (array2.Length >= 10 && !(array2[1] != text) && !(array2[2] != text2) && !(array2[4] != text3) && !(array2[7] != text4))
					{
						array2[8] = Escape(finding.Outcome);
						array2[9] = Escape(finding.OutcomeDetail);
						lines[i] = string.Join("|", array2);
						num++;
					}
				}
			}
			if (num > 0 && num2 >= 0)
			{
				string[] array3 = lines[num2].TrimEnd('\r').Split('|');
				array3[6] = mod.Verdict;
				lines[num2] = string.Join("|", array3);
			}
			return num;
		}

		private static int Int(string s)
		{
			if (!int.TryParse(s, out var result))
			{
				return 0;
			}
			return result;
		}

		internal static string Escape(string value)
		{
			if (!string.IsNullOrEmpty(value))
			{
				return value.Replace('|', '/').Replace('\r', ' ').Replace('\n', ' ');
			}
			return "";
		}
	}
	internal static class SplitMethods
	{
		internal sealed class Entry
		{
			internal string Type;

			internal string Name;

			internal string[] StandInParameters;

			internal string[] RealParameters;

			internal string Because;
		}

		internal static readonly Entry[] All = new Entry[1]
		{
			new Entry
			{
				Type = "Il2CppScheduleOne.Tools.ManagementClipboard",
				Name = "Close",
				StandInParameters = new string[1] { "System.Boolean" },
				RealParameters = new string[0],
				Because = "the player's own exit calls Close() and never the flagged one, so a mod's postfix on the old signature stopped seeing ordinary closes"
			}
		};
	}
	internal sealed class VersionDb
	{
		internal static class Op
		{
			internal const string Rename = "R";

			internal const string Removed = "-";

			internal const string Ambiguous = "?";

			internal const string Merge = "M";
		}

		internal static class Origin
		{
			internal const string Derived = "derived";

			internal const string Curated = "curated";

			internal const string Override = "override";
		}

		internal sealed class Row
		{
			internal string Op;

			internal string Kind;

			internal string Type;

			internal string From;

			internal string To;

			internal string RuleName;

			internal string Confidence;

			internal string Note;

			internal string Origin;

			internal int Arity;

			internal string Key => Kind + "|" + Type + "|" + From + "|" + Arity;

			internal string NameKey => Kind + "|" + Type + "|" + From;
		}

		internal sealed class Step
		{
			internal GameVersion From;

			internal GameVersion To;

			internal string Source = "";

			internal readonly Dictionary<string, Row> Renames = new Dictionary<string, Row>(StringComparer.Ordinal);

			internal readonly Dictionary<string, Row> Removed = new Dictionary<string, Row>(StringComparer.Ordinal);

			internal readonly HashSet<string> Refused = new HashSet<string>(StringComparer.Ordinal);
		}

		internal const string HeaderPrefix = "# polyfill-versiondb ";

		internal const int Format = 1;

		private readonly List<Step> _steps = new List<Step>();

		private readonly Dictionary<string, Row> _overrides = new Dictionary<string, Row>(StringComparer.Ordinal);

		private readonly List<VersionRange> _overrideRanges = new List<VersionRange>();

		internal readonly List<string> Notes = new List<string>();

		internal int RenameCount { get; private set; }

		internal int StepCount => _steps.Count;

		internal GameVersion Newest
		{
			get
			{
				if (_steps.Count != 0)
				{
					List<Step> steps = _steps;
					return steps[steps.Count - 1].To;
				}
				return GameVersion.Unknown;
			}
		}

		internal static VersionDb Load(IEnumerable<(string Name, IEnumerable<string> Lines)> files)
		{
			VersionDb versionDb = new VersionDb();
			Dictionary<string, Step> dictionary = new Dictionary<string, Step>(StringComparer.Ordinal);
			foreach (var file in files)
			{
				try
				{
					versionDb.ReadOne(file.Name, file.Lines, dictionary);
				}
				catch (Exception ex)
				{
					versionDb.Notes.Add(file.Name + " could not be read (" + ex.Message + ")");
				}
			}
			versionDb._steps.AddRange(dictionary.Values);
			versionDb._steps.Sort((Step a, Step b) => a.From.CompareTo(b.From));
			foreach (Step step in versionDb._steps)
			{
				versionDb.RenameCount += step.Renames.Count;
			}
			return versionDb;
		}

		private void ReadOne(string name, IEnumerable<string> lines, Dictionary<string, Step> steps)
		{
			Step step = null;
			VersionRange range = null;
			bool flag = false;
			List<Row> list = new List<Row>();
			foreach (string line in lines)
			{
				if (line == null)
				{
					continue;
				}
				string text = line.TrimEnd('\r');
				if (!flag)
				{
					if (!text.StartsWith("# polyfill-versiondb ", StringComparison.Ordinal))
					{
						Notes.Add(name + " is not a version database");
						return;
					}
					if (!int.TryParse(text.Substring("# polyfill-versiondb ".Length).Trim(), out var result) || result > 1)
					{
						Notes.Add(name + " is a newer format than this build reads; skipped");
						return;
					}
					flag = true;
				}
				else if (text.StartsWith("# from=", StringComparison.Ordinal))
				{
					(step ?? (step = new Step())).From = GameVersion.Parse(text.Substring(7));
				}
				else if (text.StartsWith("# to=", StringComparison.Ordinal))
				{
					(step ?? (step = new Step())).To = GameVersion.Parse(text.Substring(5));
				}
				else if (text.StartsWith("# source=", StringComparison.Ordinal))
				{
					(step ?? (step = new Step())).Source = text.Substring(9);
				}
				else if (text.StartsWith("# applies=", StringComparison.Ordinal))
				{
					if (!VersionRange.TryParse(text.Substring(10), out range, out var problem))
					{
						Notes.Add($"{name} applies to '{text.Substring(10)}', which is not a range ({problem})");
						return;
					}
				}
				else
				{
					if (text.Length == 0 || text[0] == '#')
					{
						continue;
					}
					Row row = Parse(text);
					if (row == null)
					{
						continue;
					}
					if (range != null)
					{
						TakeOverride(name, row, range);
						continue;
					}
					if (step == null)
					{
						Notes.Add(name + " has rows but no step");
						return;
					}
					switch (row.Op)
					{
					case "R":
						list.Add(row);
						break;
					case "-":
						step.Removed[row.Key] = row;
						break;
					case "?":
					case "M":
						step.Refused.Add(row.NameKey);
						break;
					}
				}
			}
			if (range != null)
			{
				return;
			}
			if (step == null || !step.From.IsKnown || !step.To.IsKnown)
			{
				Notes.Add(name + " does not say which two builds it is between");
				return;
			}
			Dictionary<string, Row> dictionary = new Dictionary<string, Row>(StringComparer.Ordinal);
			foreach (Row item in list)
			{
				if (step.Renames.TryGetValue(item.Key, out var value))
				{
					step.Refused.Add(item.NameKey);
					step.Renames.Remove(item.Key);
					Notes.Add($"{name}: {item.Type}.{item.From} is renamed twice in one step ({value.To} and {item.To}); neither is used");
					continue;
				}
				string key = item.Kind + "|" + item.Type + "|" + item.To + "|" + item.Arity;
				if (dictionary.TryGetValue(key, out var value2))
				{
					step.Refused.Add(item.NameKey);
					step.Refused.Add(value2.NameKey);
					step.Renames.Remove(value2.Key);
					Notes.Add($"{name}: {value2.From} and {item.From} both became {item.To} on {item.Type}; " + "neither is used");
				}
				else
				{
					dictionary[key] = item;
					step.Renames[item.Key] = item;
				}
			}
			string text2 = step.From.ToString() + "->" + step.To;
			if (steps.ContainsKey(text2))
			{
				Notes.Add(name + " replaces the step " + text2 + " that was loaded before it");
			}
			steps[text2] = step;
		}

		private void TakeOverride(string name, Row row, VersionRange applies)
		{
			if (row.Origin == "override" && string.IsNullOrEmpty(row.Note))
			{
				Notes.Add($"{name}: {row.Type}.{row.From} overrides the history with no reason given; skipped");
			}
			else if (_overrides.ContainsKey(row.Key))
			{
				Notes.Add($"{name}: {row.Type}.{row.From} is decided twice by hand; neither is used");
				_overrides.Remove(row.Key);
			}
			else
			{
				_overrides[row.Key] = row;
				_overrideRanges.Add(applies);
			}
		}

		private static Row Parse(string line)
		{
			string[] array = line.Split('|');
			if (array.Length < 10)
			{
				return null;
			}
			int result;
			return new Row
			{
				Op = array[0],
				Kind = array[1],
				Type = array[2],
				From = array[3],
				To = array[4],
				Arity = (int.TryParse(array[5], out result) ? result : 0),
				Origin = array[6],
				RuleName = array[7],
				Confidence = array[8],
				Note = array[9]
			};
		}

		internal string Successor(string kind, string type, string name, int arity, GameVersion game)
		{
			string key = kind + "|" + type + "|" + name + "|" + arity;
			if (_overrides.TryGetValue(key, out var value))
			{
				return value.To;
			}
			string text = name;
			foreach (Step step in _steps)
			{
				if (game.IsKnown && step.To > game)
				{
					break;
				}
				string text2 = kind + "|" + type + "|" + text;
				if (step.Refused.Contains(text2))
				{
					return null;
				}
				if (step.Renames.TryGetValue(text2 + "|" + arity, out var value2))
				{
					text = value2.To;
				}
			}
			if (!(text == name))
			{
				return text;
			}
			return null;
		}

		internal string RemovedIn(string kind, string type, string name, int arity)
		{
			string key = kind + "|" + type + "|" + name + "|" + arity;
			foreach (Step step in _steps)
			{
				if (step.Removed.ContainsKey(key))
				{
					return step.To.ToString();
				}
			}
			return null;
		}

		internal bool WasRefused(string kind, string type, string name)
		{
			string item = kind + "|" + type + "|" + name;
			foreach (Step step in _steps)
			{
				if (step.Refused.Contains(item))
				{
					return true;
				}
			}
			return false;
		}

		internal IEnumerable<string> Versions()
		{
			foreach (Step step in _steps)
			{
				yield return step.From.ToString();
			}
			if (_steps.Count > 0)
			{
				List<Step> steps = _steps;
				yield return steps[steps.Count - 1].To.ToString();
			}
		}

		internal string Gap()
		{
			for (int i = 1; i < _steps.Count; i++)
			{
				if (_steps[i - 1].To != _steps[i].From)
				{
					return $"{_steps[i - 1].To} is followed by a step that starts at {_steps[i].From}";
				}
			}
			return null;
		}
	}
	internal sealed class VersionRange
	{
		private enum Kind
		{
			Any,
			Prefix,
			AtLeast,
			Above,
			AtMost,
			Below,
			Between,
			Exact
		}

		private readonly struct Term
		{
			internal readonly Kind Kind;

			internal readonly GameVersion Low;

			internal readonly GameVersion High;

			internal readonly int PrefixParts;

			internal Term(Kind kind, GameVersion low, GameVersion high = default(GameVersion), int prefixParts = 0)
			{
				Kind = kind;
				Low = low;
				High = high;
				PrefixParts = prefixParts;
			}
		}

		private readonly Term[] _terms;

		internal static readonly VersionRange Any = new VersionRange(new Term[1]
		{
			new Term(Kind.Any, GameVersion.Unknown)
		}, "*");

		internal static readonly VersionRange None = new VersionRange(Array.Empty<Term>(), "nothing");

		internal string Text { get; }

		private VersionRange(Term[] terms, string text)
		{
			_terms = terms;
			Text = text;
		}

		internal static VersionRange Parse(string text)
		{
			if (!TryParse(text, out var range, out var problem))
			{
				throw new FormatException("'" + text + "' is not a version range: " + problem);
			}
			return range;
		}

		internal static bool TryParse(string text, out VersionRange range, out string problem)
		{
			range = null;
			problem = null;
			if (string.IsNullOrWhiteSpace(text))
			{
				range = Any;
				return true;
			}
			List<Term> list = new List<Term>();
			string[] array = text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length == 0)
				{
					continue;
				}
				if (text2 == "*")
				{
					list.Add(new Term(Kind.Any, GameVersion.Unknown));
					continue;
				}
				if (text2.EndsWith("*", StringComparison.Ordinal))
				{
					if (!GameVersion.TryParse(text2.Substring(0, text2.Length - 1).TrimEnd('.', 'f', ' '), out var version))
					{
						problem = "'" + text2 + "' has no version in front of the star";
						return false;
					}
					list.Add(new Term(Kind.Prefix, version, default(GameVersion), version.Parts.Length));
					continue;
				}
				int num = text2.IndexOf("..", StringComparison.Ordinal);
				if (num > 0)
				{
					if (!GameVersion.TryParse(text2.Substring(0, num), out var version2) || !GameVersion.TryParse(text2.Substring(num + 2), out var version3))
					{
						problem = "'" + text2 + "' is not two versions with .. between them";
						return false;
					}
					if (version2 > version3)
					{
						problem = "'" + text2 + "' starts after it ends";
						return false;
					}
					list.Add(new Term(Kind.Between, version2, version3));
					continue;
				}
				Kind kind = Kind.Exact;
				string text3 = text2;
				if (text3.StartsWith(">=", StringComparison.Ordinal))
				{
					kind = Kind.AtLeast;
					text3 = text3.Substring(2);
				}
				else if (text3.StartsWith("<=", StringComparison.Ordinal))
				{
					kind = Kind.AtMost;
					text3 = text3.Substring(2);
				}
				else if (text3.StartsWith(">", StringComparison.Ordinal))
				{
					kind = Kind.Above;
					text3 = text3.Substring(1);
				}
				else if (text3.StartsWith("<", StringComparison.Ordinal))
				{
					kind = Kind.Below;
					text3 = text3.Substring(1);
				}
				if (!GameVersion.TryParse(text3.Trim(), out var version4))
				{
					problem = "'" + text2 + "' has no version in it";
					return false;
				}
				list.Add(new Term(kind, version4));
			}
			if (list.Count == 0)
			{
				problem = "it is empty";
				return false;
			}
			range = new VersionRange(list.ToArray(), text);
			return true;
		}

		internal bool Allows(GameVersion version)
		{
			return Matches(version, unknownAnswer: false);
		}

		internal bool AllowsOrUnknown(GameVersion version)
		{
			return Matches(version, unknownAnswer: true);
		}

		internal bool Allows(string version)
		{
			return Allows(GameVersion.Parse(version));
		}

		internal bool AllowsOrUnknown(string version)
		{
			return AllowsOrUnknown(GameVersion.Parse(version));
		}

		private bool Matches(GameVersion version, bool unknownAnswer)
		{
			Term[] terms = _terms;
			for (int i = 0; i < terms.Length; i++)
			{
				Term term = terms[i];
				if (term.Kind == Kind.Any)
				{
					return true;
				}
				if (!version.IsKnown)
				{
					return unknownAnswer;
				}
				if (term.Kind switch
				{
					Kind.Prefix => version.StartsWith(term.Low, term.PrefixParts), 
					Kind.AtLeast => version >= term.Low, 
					Kind.Above => version > term.Low, 
					Kind.AtMost => version <= term.Low, 
					Kind.Below => version < term.Low, 
					Kind.Between => version >= term.Low && version <= term.High, 
					_ => version == term.Low, 
				})
				{
					return true;
				}
			}
			return false;
		}

		public override string ToString()
		{
			return Text;
		}

		internal IEnumerable<GameVersion> Bounds()
		{
			Term[] terms = _terms;
			for (int i = 0; i < terms.Length; i++)
			{
				Term term = terms[i];
				if (term.Kind != Kind.Any)
				{
					if (term.Low.IsKnown)
					{
						yield return term.Low;
					}
					if (term.Kind == Kind.Between && term.High.IsKnown)
					{
						yield return term.High;
					}
				}
			}
		}

		internal string Describe()
		{
			StringBuilder stringBuilder = new StringBuilder();
			Term[] terms = _terms;
			for (int i = 0; i < terms.Length; i++)
			{
				Term term = terms[i];
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(", ");
				}
				StringBuilder stringBuilder2 = stringBuilder;
				stringBuilder2.Append(term.Kind switch
				{
					Kind.Any => "any build", 
					Kind.Prefix => term.Low.ToString() + " and its builds", 
					Kind.AtLeast => term.Low.ToString() + " and newer", 
					Kind.Above => "newer than " + term.Low, 
					Kind.AtMost => term.Low.ToString() + " and older", 
					Kind.Below => "older than " + term.Low, 
					Kind.Between => term.Low.ToString() + " to " + term.High, 
					_ => term.Low.ToString(), 
				});
			}
			return stringBuilder.ToString();
		}
	}
}
namespace Polyfill.ModFixes
{
	internal sealed class AmountChangedAfterOverride : Fix
	{
		private static Instance _log;

		private static bool _said;

		private static readonly HashSet<string> Complained = new HashSet<string>();

		internal override string Id => "amount-changed-after-override";

		internal override string Mod => "Tweakables";

		internal override string ModVersions => "*";

		internal override string GameVersions => ">=0.4.6";

		internal override string What => "raising the deal cap tells the rest of the screen the price moved, so it does not show a stale number";

		internal override string StandsDownBecause => "the field this mod used to announce a price change with does not exist in 0.4.6, and the event that replaced it is only raised by the method the mod replaces.";

		internal override bool Apply(Instance log)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			_log = log;
			Type type = AccessTools.TypeByName("Il2CppScheduleOne.UI.AmountSelector");
			if (type == null)
			{
				log.Warning("[fix] amount-changed-after-override: Il2CppScheduleOne.UI.AmountSelector is not on this build, so there is nothing to listen to.");
				return false;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "SetAmount", new Type[1] { typeof(float) }, (Type[])null);
			if (methodInfo == null)
			{
				log.Warning("[fix] amount-changed-after-override: AmountSelector.SetAmount(float) is not here, so the moment the notification goes missing cannot be found.");
				return false;
			}
			new Harmony("doodesch.polyfill.fixes").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(AmountChangedAfterOverride), "After", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}

		private static void After(object __instance, bool __runOriginal)
		{
			if (__runOriginal || __instance == null)
			{
				return;
			}
			try
			{
				Type type = __instance.GetType();
				object obj = AccessTools.PropertyGetter(type, "OnAmountChanged")?.Invoke(__instance, null);
				if (obj == null)
				{
					return;
				}
				object obj2 = AccessTools.PropertyGetter(type, "SelectedAmount")?.Invoke(__instance, null);
				if (obj2 == null)
				{
					Complain("the selector has no SelectedAmount to announce");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(obj.GetType(), "Invoke", new Type[1] { typeof(float) }, (Type[])null);
				if (methodInfo == null)
				{
					Complain("the event on this build takes something other than a single float, so what to pass it cannot be worked out without guessing");
					return;
				}
				methodInfo.Invoke(obj, new object[1] { obj2 });
				if (!_said)
				{
					_said = true;
					Instance log = _log;
					if (log != null)
					{
						log.Msg("[fix] amount-changed-after-override: a mod replaced the amount box's own setter, so Polyfill raises the change event it would have raised.");
					}
				}
			}
			catch (Exception ex)
			{
				Complain("could not raise the change event: " + ex.GetType().Name + ": " + ex.Message);
			}
		}

		private static void Complain(string why)
		{
			if (Complained.Add(why))
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] amount-changed-after-override: " + why + ". Whatever listens for a price change will not hear this one.");
				}
				Fixes.Record("amount-changed-after-override", "did nothing: " + why);
			}
		}
	}
	internal sealed class AutoRestockOscarLookup : Fix
	{
		private static Instance _log;

		private static int _skipped;

		internal override string Id => "autorestock-oscar-lookup";

		internal override string Mod => "AutoRestock";

		internal override string ModVersions => "*";

		internal override string GameVersions => ">=0.4.7";

		internal override string What => "AutoRestock starts after a save loads and restocks again";

		internal override bool Apply(Instance log)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("AutoRestock.Manager");
			if (type == null)
			{
				log.Warning("[fix] autorestock-oscar-lookup: AutoRestock.Manager is not in this AutoRestock; nothing was changed.");
				return false;
			}
			List<MethodInfo> list = (from m in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).SelectMany((Type t) => t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
				where m.Name.StartsWith("<Initialize>", StringComparison.Ordinal) && m.ReturnType == typeof(bool) && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType.Name == "NPC"
				select m).ToList();
			if (list.Count != 1)
			{
				log.Warning($"[fix] autorestock-oscar-lookup: expected one NPC search in AutoRestock's Initialize, found {list.Count}; nothing was changed.");
				return false;
			}
			_log = log;
			new Harmony("doodesch.polyfill.fixes").Patch((MethodBase)list[0], (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(AutoRestockOscarLookup), "NotOscar", (Type[])null), (HarmonyMethod)null);
			return true;
		}

		private static Exception NotOscar(Exception __exception, ref bool __result)
		{
			if (__exception == null)
			{
				return null;
			}
			__result = false;
			_skipped++;
			if (_skipped == 1)
			{
				_log.Warning("[fix] autorestock-oscar-lookup: skipped an NPC without game data while AutoRestock looked for Oscar (" + __exception.GetBaseException().Message.Split('\n')[0].Trim() + ").");
			}
			Fixes.Record("autorestock-oscar-lookup", "skipped an NPC without game data");
			return null;
		}
	}
	internal sealed class AvatarSettingsBridge : Fix
	{
		private sealed class Look
		{
			internal object Naked;

			internal object Worn;

			internal List<object> Clothes;

			internal bool ReplacesOutfit;
		}

		private enum Kind
		{
			Face,
			Body,
			Hair,
			Accessory
		}

		private sealed class Legacy
		{
			internal string Path;

			internal Kind Kind;

			internal int Order;

			internal object Equivalent;

			private static Catalogue _index;

			internal bool IsMouth => Name.StartsWith("Face_", StringComparison.OrdinalIgnoreCase);

			internal bool IsFacialHair => Name.StartsWith("FacialHair_", StringComparison.OrdinalIgnoreCase);

			private string Name => Path.Substring(Path.LastIndexOf('/') + 1);

			internal static Catalogue Index => _index ?? (_index = Catalogue.Build());
		}

		private sealed class Catalogue
		{
			internal readonly Dictionary<string, Legacy> ById = new Dictionary<string, Legacy>(StringComparer.OrdinalIgnoreCase);

			private readonly Dictionary<string, Legacy> _byPath = new Dictionary<string, Legacy>(StringComparer.OrdinalIgnoreCase);

			internal static Catalogue Build()
			{
				Catalogue catalogue = new Catalogue();
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				foreach (AvatarLayer item in Resources.LoadAll<AvatarLayer>("Avatar/Layers"))
				{
					if (!((Object)(object)item == (Object)null))
					{
						bool flag = (Object)(object)((Il2CppObjectBase)item).TryCast<FaceLayer>() != (Object)null;
						if (catalogue.Add(item.AssetPath, (!flag) ? Kind.Body : Kind.Face, item.Order, Get(item, "AvatarObjectEquivalent")))
						{
							num++;
						}
						else
						{
							num3++;
						}
					}
				}
				string[] array = new string[2] { "Avatar/Hair", "Avatar/Accessories" };
				for (int i = 0; i < array.Length; i++)
				{
					foreach (GameObject item2 in Resources.LoadAll<GameObject>(array[i]))
					{
						Accessory val = (((Object)(object)item2 == (Object)null) ? null : item2.GetComponent<Accessory>());
						if (!((Object)(object)val == (Object)null))
						{
							Kind kind = (((Object)(object)((Il2CppObjectBase)val).TryCast<Hair>() != (Object)null) ? Kind.Hair : Kind.Accessory);
							if (catalogue.Add(val.AssetPath, kind, 0, Get(val, "AvatarObjectEquivalent")))
							{
								num2++;
							}
							else
							{
								num3++;
							}
						}
					}
				}
				Instance log = _log;
				if (log != null)
				{
					log.Msg($"[fix] avatar-settings-bridge: {num} legacy layer(s) and {num2} hair/accessory prefab(s) map to 0.4.7 objects; {num3} do not.");
				}
				return catalogue;
			}

			private bool Add(string path, Kind kind, int order, object equivalent)
			{
				if (string.IsNullOrEmpty(path) || equivalent == null)
				{
					return false;
				}
				Legacy value = new Legacy
				{
					Path = path,
					Kind = kind,
					Order = order,
					Equivalent = equivalent
				};
				_byPath.TryAdd(path, value);
				ById.TryAdd((string)Get(equivalent, "Id"), value);
				return true;
			}

			internal object Equivalent(string path)
			{
				if (_byPath.TryGetValue(path, out var value))
				{
					return value.Equivalent;
				}
				Object val = Resources.Load(path);
				if (val == (Object)null)
				{
					return null;
				}
				AvatarLayer val2 = ((Il2CppObjectBase)val).TryCast<AvatarLayer>();
				if ((Object)(object)val2 != (Object)null)
				{
					return Get(val2, "AvatarObjectEquivalent");
				}
				GameObject obj = ((Il2CppObjectBase)val).TryCast<GameObject>();
				Accessory val3 = ((obj != null) ? obj.GetComponent<Accessory>() : null);
				if (!((Object)(object)val3 == (Object)null))
				{
					return Get(val3, "AvatarObjectEquivalent");
				}
				return null;
			}

			internal int Order(string path)
			{
				if (_byPath.TryGetValue(path, out var value))
				{
					return value.Order;
				}
				Object obj = Resources.Load(path);
				AvatarLayer val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<AvatarLayer>() : null);
				if (!((Object)(object)val == (Object)null))
				{
					return val.Order;
				}
				return 0;
			}
		}

		private const float HeightScale = 1.875f;

		private const int NakedMaxOrder = 19;

		private static Instance _log;

		private static Type _naked;

		private static Type _nakedObject;

		private static Type _outfit;

		private static Type _serialized;

		private static Type _list;

		private static readonly Dictionary<int, AvatarSettings> Applied = new Dictionary<int, AvatarSettings>();

		private static readonly Dictionary<int, List<object>> Worn = new Dictionary<int, List<object>>();

		private static bool _applying;

		private static Il2CppReferenceArray<AvatarSettings> _goonBases;

		private static int _goonBasesFor;

		internal override string Id => "avatar-settings-bridge";

		internal override string Mod => "*";

		internal override string ModVersions => "*";

		internal override string GameVersions => ">=0.4.7";

		internal override string What => "a mod that sets a character's look the 0.4.6 way (custom NPCs, look editors) gets that look";

		internal override string StandsDownBecause => "a mod that sets a character's look through avatar settings leaves that character looking the way the game made it.";

		internal override bool Apply(Instance log)
		{
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Expected O, but got Unknown
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Expected O, but got Unknown
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Expected O, but got Unknown
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Expected O, but got Unknown
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Expected O, but got Unknown
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Expected O, but got Unknown
			_log = log;
			Type? typeFromHandle = typeof(Avatar);
			MethodInfo methodInfo = Declared(typeFromHandle, "get_CurrentSettings", 0);
			MethodInfo methodInfo2 = Declared(typeFromHandle, "LoadAvatarSettings", 1);
			MethodInfo methodInfo3 = Declared(typeof(Appearance), "set_AvatarSettings", 1);
			MethodInfo methodInfo4 = Declared(typeFromHandle, "LoadNakedSettings", 3);
			MethodInfo methodInfo5 = Declared(typeof(GoonPool), "get_MaleBaseAppearances", 0);
			if (methodInfo == null && methodInfo2 == null && methodInfo3 == null && methodInfo4 == null && methodInfo5 == null)
			{
				log.Msg("[fix] " + Id + ": no mod uses CurrentSettings, LoadAvatarSettings, LoadNakedSettings, an NPC's AvatarSettings or the goon pool's base appearances; nothing to translate.");
				return false;
			}
			_naked = AccessTools.TypeByName("Il2CppScheduleOne.Core.Avatar.NakedAppearance");
			_nakedObject = AccessTools.TypeByName("Il2CppScheduleOne.Core.Avatar.NakedAppearanceObject");
			_outfit = AccessTools.TypeByName("Il2CppScheduleOne.Core.Avatar.Outfit");
			_serialized = AccessTools.TypeByName("Il2CppScheduleOne.Core.Avatar.SerializedAvatarObject");
			Type type = AccessTools.TypeByName("Il2CppScheduleOne.Avatar.AvatarAppearance");
			if (_naked == null || _nakedObject == null || _outfit == null || _serialized == null || type == null)
			{
				log.Warning($"[fix] {Id}: the 0.4.7 appearance types are not all here (NakedAppearance {_naked != null}, NakedAppearanceObject {_nakedObject != null}, Outfit {_outfit != null}, SerializedAvatarObject {_serialized != null}, AvatarAppearance {type != null}).");
				return false;
			}
			_list = typeof(List<>).MakeGenericType(_serialized);
			Harmony val = new Harmony("doodesch.polyfill.avatarsettings");
			MethodInfo methodInfo6 = type.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.Name == "ApplyOutfit" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == _list);
			MethodInfo methodInfo7 = Declared(type, "RemoveOutfit", 0);
			if (methodInfo6 == null || methodInfo7 == null)
			{
				log.Warning("[fix] " + Id + ": AvatarAppearance.ApplyOutfit(List) or RemoveOutfit is not here.");
				return false;
			}
			val.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(typeof(AvatarSettingsBridge), "Dressed", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(typeof(AvatarSettingsBridge), "Undressed", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MethodInfo methodInfo8 = Declared(type, "ApplyNakedAppearance", 1);
			if (methodInfo8 == null)
			{
				log.Warning("[fix] " + Id + ": AvatarAppearance.ApplyNakedAppearance is not here.");
				return false;
			}
			val.Patch((MethodBase)methodInfo8, (HarmonyMethod)null, new HarmonyMethod(typeof(AvatarSettingsBridge), "BodyChanged", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			if (methodInfo != null)
			{
				val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AvatarSettingsBridge), "Current", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo2 != null)
			{
				val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(AvatarSettingsBridge), "Load", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo3 != null)
			{
				val.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(AvatarSettingsBridge), "SetDataLook", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo4 != null)
			{
				val.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(AvatarSettingsBridge), "LoadNaked", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo5 != null)
			{
				val.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(AvatarSettingsBridge), "GoonBases", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			IEnumerable<string> values = new string[5]
			{
				(methodInfo != null) ? "CurrentSettings" : null,
				(methodInfo2 != null) ? "LoadAvatarSettings" : null,
				(methodInfo4 != null) ? "LoadNakedSettings" : null,
				(methodInfo3 != null) ? "an NPC's AvatarSettings" : null,
				(methodInfo5 != null) ? "the goon pool's base appearances" : null
			}.Where((string x) => x != null);
			log.Msg($"[fix] {Id}: {string.Join(", ", values)} now translate to the 0.4.7 appearance.");
			return true;
		}

		private static MethodInfo Declared(Type type, string name, int arity)
		{
			return type.GetMethods(AccessTools.all).FirstOrDefault((MethodInfo m) => m.DeclaringType == type && m.Name == name && m.GetParameters().Length == arity);
		}

		private static void Dressed(object __instance, object wornObjects)
		{
			try
			{
				List<object> list = new List<object>();
				if (wornObjects != null)
				{
					int num = (int)Get(wornObjects, "Count");
					PropertyInfo property = wornObjects.GetType().GetProperty("Item");
					for (int i = 0; i < num; i++)
					{
						list.Add(property.GetValue(wornObjects, new object[1] { i }));
					}
				}
				Worn[Instance(__instance)] = list;
			}
			catch (Exception ex)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: could not note an outfit: " + ex.Message);
				}
			}
		}

		private static void Undressed(object __instance)
		{
			try
			{
				Worn.Remove(Instance(__instance));
			}
			catch (Exception ex)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: could not note an undress: " + ex.Message);
				}
			}
		}

		private static void BodyChanged(object __instance)
		{
			if (_applying)
			{
				return;
			}
			try
			{
				object obj = Get(__instance, "gameObject");
				GameObject val = (GameObject)((obj is GameObject) ? obj : null);
				Avatar val2 = ((val != null) ? val.GetComponentInParent<Avatar>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Applied.Remove(((Object)val2).GetInstanceID());
				}
			}
			catch (Exception ex)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: could not note a body change: " + ex.Message);
				}
			}
		}

		private static bool Current(Avatar __instance, ref AvatarSettings __result)
		{
			try
			{
				int instanceID = ((Object)__instance).GetInstanceID();
				if (Applied.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
				{
					__result = value;
					return false;
				}
				__result = Describe(__instance);
				if ((Object)(object)__result != (Object)null)
				{
					Applied[instanceID] = __result;
				}
			}
			catch (Exception ex)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: CurrentSettings could not be built: " + ex);
				}
				__result = null;
			}
			return false;
		}

		private static AvatarSettings Describe(Avatar avatar)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			object obj = Get(avatar, "Appearance");
			object obj2 = ((obj == null) ? null : Get(obj, "AppliedNakedAppearance"));
			if (obj2 == null)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Msg("[fix] avatar-settings-bridge: " + Who(avatar) + " has no appearance yet; CurrentSettings is null.");
				}
				return null;
			}
			AvatarSettings val = DescribeBody(obj2);
			Catalogue index = Legacy.Index;
			Worn.TryGetValue(Instance(obj), out var value);
			object target = Activator.CreateInstance(_list);
			foreach (object item in value ?? new List<object>())
			{
				if (!index.ById.TryGetValue(ObjectId(item), out var value2))
				{
					Call(target, "Add", item);
				}
				else if (value2.Kind == Kind.Accessory)
				{
					val.AccessorySettings.Add(Accessory(value2.Path, Tint(item)));
				}
				else
				{
					val.BodyLayerSettings.Add(Layer(value2.Path, Tint(item)));
				}
			}
			object obj3 = Cast(ScriptableObject.CreateInstance(Il2CppType.From(_outfit)), _outfit);
			Set(obj3, "AvatarObjects", Call(target, "ToArray"));
			Set(val, "EquivalentOutfit", obj3);
			return val;
		}

		private static AvatarSettings DescribeBody(object naked)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			AvatarSettings val = ScriptableObject.CreateInstance<AvatarSettings>();
			val.Height = (float)Get(naked, "Height") / 1.875f;
			val.Gender = (float)Get(naked, "Gender");
			val.Weight = (float)Get(naked, "Weight");
			val.SkinColor = (Color)Get(naked, "SkinColor");
			val.HairColor = (Color)Get(naked, "HairColor");
			object target = Get(naked, "LeftEyebrowSettings");
			val.EyebrowScale = (float)Get(target, "Scale");
			val.EyebrowThickness = (float)Get(target, "Thickness");
			val.EyebrowRestingHeight = (float)Get(target, "RestingHeight");
			val.EyebrowRestingAngle = (float)Get(target, "RestingAngle");
			object target2 = Get(naked, "LeftEyeSettings");
			val.EyeBallTint = (Color)Get(target2, "EyeballColor");
			val.PupilDilation = (float)Get(target2, "PupilDilation");
			val.LeftEyeRestingState = Lid(Get(naked, "LeftEyelidSettings"));
			val.RightEyeRestingState = Lid(Get(naked, "RightEyelidSettings"));
			string path = "";
			string path2 = "";
			List<LayerSetting> list = new List<LayerSetting>();
			Catalogue index = Legacy.Index;
			foreach (object item in Objects(Get(naked, "AvatarObjects")))
			{
				if (!index.ById.TryGetValue(ObjectId(item), out var value))
				{
					continue;
				}
				switch (value.Kind)
				{
				case Kind.Hair:
					val.HairPath = value.Path;
					break;
				case Kind.Face:
					if (value.IsMouth)
					{
						path = value.Path;
					}
					else if (value.IsFacialHair)
					{
						path2 = value.Path;
					}
					else
					{
						list.Add(Layer(value.Path, Tint(item)));
					}
					break;
				case Kind.Body:
					val.BodyLayerSettings.Add(Layer(value.Path, Tint(item)));
					break;
				case Kind.Accessory:
					val.AccessorySettings.Add(Accessory(value.Path, Tint(item)));
					break;
				}
			}
			val.FaceLayerSettings.Add(Layer(path, Color.white));
			val.FaceLayerSettings.Add(Layer(path2, val.HairColor));
			foreach (LayerSetting item2 in list)
			{
				val.FaceLayerSettings.Add(item2);
			}
			object obj = Cast(ScriptableObject.CreateInstance(Il2CppType.From(_nakedObject)), _nakedObject);
			Set(obj, "Appearance", Call(naked, "Clone"));
			Set(val, "EquivalentNakedAppearance", obj);
			return val;
		}

		private static bool Load(Avatar __instance, AvatarSettings settings)
		{
			if ((Object)(object)settings == (Object)null)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: LoadAvatarSettings(null) on " + Who(__instance) + "; ignored.");
				}
				return false;
			}
			try
			{
				Apply(__instance, settings);
			}
			catch (Exception ex)
			{
				Instance log2 = _log;
				if (log2 != null)
				{
					log2.Warning("[fix] avatar-settings-bridge: " + Who(__instance) + " could not take its settings: " + ex);
				}
			}
			return false;
		}

		private static void Apply(Avatar avatar, AvatarSettings settings)
		{
			object obj = Get(avatar, "Appearance");
			if (obj == null)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: " + Who(avatar) + " has no Appearance; settings not applied.");
				}
				return;
			}
			Look look = Translate(settings, Who(avatar));
			_applying = true;
			try
			{
				Call(obj, "ApplyNakedAppearance", look.Naked);
				if (look.ReplacesOutfit)
				{
					Call(obj, "ApplyOutfit", look.Worn);
				}
			}
			finally
			{
				_applying = false;
			}
			Applied[((Object)avatar).GetInstanceID()] = settings;
			if ((Object)(object)settings.ImpostorTexture != (Object)null)
			{
				Call(avatar, "SetImpostorTexture", settings.ImpostorTexture);
			}
		}

		private static bool LoadNaked(Avatar __instance, AvatarSettings settings, bool keepOldLayers, int maxLayerOrder)
		{
			if ((Object)(object)settings == (Object)null)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: LoadNakedSettings(null) on " + Who(__instance) + "; ignored.");
				}
				return false;
			}
			try
			{
				ApplyNaked(__instance, settings, keepOldLayers, maxLayerOrder);
			}
			catch (Exception ex)
			{
				Instance log2 = _log;
				if (log2 != null)
				{
					log2.Warning("[fix] avatar-settings-bridge: " + Who(__instance) + " could not take its naked settings: " + ex);
				}
			}
			return false;
		}

		private static void ApplyNaked(Avatar avatar, AvatarSettings settings, bool keepOldLayers, int maxOrder)
		{
			object obj = Get(avatar, "Appearance");
			if (obj == null)
			{
				Instance log = _log;
				if (log != null)
				{
					log.Warning("[fix] avatar-settings-bridge: " + Who(avatar) + " has no Appearance; naked settings not applied.");
				}
				return;
			}
			Catalogue index = Legacy.Index;
			Look look = Translate(settings, Who(avatar), maxOrder);
			object obj2 = Get(obj, "AppliedNakedAppearance");
			if (obj2 != null)
			{
				foreach (object item in Objects(Get(obj2, "AvatarObjects")))
				{
					if (index.ById.TryGetValue(ObjectId(item), out var value) && value.Kind == Kind.Body && Kept(value))
					{
						Call(look.Naked, "AddAvatarObject", item);
					}
				}
			}
			Worn.TryGetValue(Instance(obj), out var value2);
			object obj3 = Activator.CreateInstance(_list);
			int num = 0;
			foreach (object item2 in value2 ?? new List<object>())
			{
				if (index.ById.TryGetValue(ObjectId(item2), out var value3) && value3.Kind == Kind.Body && !Kept(value3))
				{
					num++;
					continue;
				}
				Call(obj3, "Add", item2);
			}
			foreach (object clothe in look.Clothes)
			{
				Call(obj3, "Add", clothe);
			}
			_applying = true;
			try
			{
				Call(obj, "ApplyNakedAppearance", look.Naked);
				if (num > 0 || look.Clothes.Count > 0)
				{
					Call(obj, "ApplyOutfit", obj3);
				}
			}
			finally
			{
				_applying = false;
			}
			Applied.Remove(((Object)avatar).GetInstanceID());
			Instance log2 = _log;
			if (log2 != null)
			{
				log2.Msg($"[fix] avatar-settings-bridge: {Who(avatar)} took the body '{((Object)settings).name}' (clothing layers: {num} taken off, {look.Clothes.Count} put on).");
			}
			bool Kept(Legacy layer)
			{
				if (keepOldLayers)
				{
					return Fits(layer.Order, maxOrder);
				}
				return false;
			}
		}

		private static bool Fits(int order, int maxOrder)
		{
			if (maxOrder > -1)
			{
				return order <= maxOrder;
			}
			return true;
		}

		private static bool GoonBases(GoonPool __instance, ref Il2CppReferenceArray<AvatarSettings> __result)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				int instanceID = ((Object)__instance).GetInstanceID();
				if (_goonBases != null && _goonBasesFor == instanceID && ((IEnumerable<AvatarSettings>)_goonBases).All((AvatarSettings entry) => (Object)(object)entry != (Object)null))
				{
					__result = _goonBases;
					return false;
				}
				List<AvatarSettings> list = new List<AvatarSettings>();
				foreach (object item in Objects(Get(__instance, "_maleAppearances")))
				{
					object obj = ((item == null) ? null : Get(item, "Appearance"));
					if (obj == null)
					{
						Instance log = _log;
						if (log != null)
						{
							log.Warning("[fix] avatar-settings-bridge: a male goon appearance holds no body; left out.");
						}
					}
					else
					{
						AvatarSettings val = DescribeBody(obj);
						((Object)val).name = ((Object)item).name;
						((Object)val).hideFlags = (HideFlags)32;
						list.Add(val);
					}
				}
				_goonBases = new Il2CppReferenceArray<AvatarSettings>(list.ToArray());
				_goonBasesFor = instanceID;
				__result = _goonBases;
				Instance log2 = _log;
				if (log2 != null)
				{
					log2.Msg($"[fix] avatar-settings-bridge: the goon pool's {list.Count} male bodies are described " + "as base appearances.");
				}
			}
			catch (Exception ex)
			{
				Instance log3 = _log;
				if (log3 != null)
				{
					log3.Warning("[fix] avatar-settings-bridge: the goon pool's base appearances could not be built: " + ex);
				}
				__result = null;
			}
			return false;
		}

		private static Look Translate(AvatarSettings settings, string who, int maxOrder = -1)
		{
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Unknown result type (might be due to invalid IL or

Plugins/Polyfill.Boot.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Melons;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;
using Polyfill.Boot;
using Polyfill.Bridges;
using Polyfill.Bridges.Steps.S0_4_5f2_To_0_4_6f5;
using Polyfill.Bridges.Steps.S0_4_6f13_To_0_4_7f5;
using Polyfill.Contract;
using Polyfill.Core;
using Polyfill.Dynamic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Plugin), "Polyfill.Boot", "0.13.20", "DooDesch", "https://github.com/DooDesch-Mods/ScheduleOne-Polyfill")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonPriority(int.MinValue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DooDesch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © DooDesch")]
[assembly: AssemblyFileVersion("0.13.20.0")]
[assembly: AssemblyInformationalVersion("0.13.20+7326413858891662af71f4d0098defca82a71120")]
[assembly: AssemblyProduct("Polyfill.Boot")]
[assembly: AssemblyTitle("Polyfill.Boot")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially created with the assistance of Generative AI.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic/OpenAI")]
[assembly: AssemblyVersion("0.13.20.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DooDesch
{
	internal static class ModVersion
	{
		internal const string Current = "0.13.20";
	}
}
namespace Polyfill.Bridges
{
	internal sealed class Bridge
	{
		internal string Assembly;

		internal string DeclaringType;

		internal string OldName;

		internal int ParameterCount;

		internal string Because;

		internal Func<ModuleDefinition, TypeDefinition, MethodDefinition> Emit;

		internal string Creates;

		internal string[] ParameterTypes;

		internal BridgeSet Set;

		internal bool AllowOverload;

		internal bool Unprompted;

		internal string Id
		{
			get
			{
				string text = DeclaringType ?? "";
				int num = text.LastIndexOfAny(new char[2] { '.', '/' });
				if (num >= 0)
				{
					text = text.Substring(num + 1);
				}
				string text2 = (OldName ?? "").Replace("get_", "get-").Replace("set_", "set-");
				string text3 = (text + "-" + text2).ToLowerInvariant();
				string[] parameterTypes = ParameterTypes;
				if (parameterTypes != null && parameterTypes.Length > 0)
				{
					string text4 = ParameterTypes[0];
					int num2 = text4.LastIndexOfAny(new char[2] { '.', '/' });
					text3 = text3 + "-" + ((num2 >= 0) ? text4.Substring(num2 + 1) : text4).ToLowerInvariant();
				}
				return text3;
			}
		}

		internal bool Fits(IReadOnlyList<string> parameterTypes)
		{
			if (ParameterTypes == null)
			{
				return true;
			}
			if (parameterTypes == null || parameterTypes.Count != ParameterTypes.Length)
			{
				return false;
			}
			for (int i = 0; i < ParameterTypes.Length; i++)
			{
				if (!string.Equals(ParameterTypes[i], parameterTypes[i], StringComparison.Ordinal))
				{
					return false;
				}
			}
			return true;
		}

		internal bool Verified(GameVersion game)
		{
			if (Set != null)
			{
				return Set.VerifiedRange.Allows(game);
			}
			return true;
		}
	}
	internal sealed class TypeRename
	{
		internal string Assembly;

		internal string OldFullName;

		internal string NewFullName;

		internal string Because;

		internal bool ByNativeClass;

		internal Answer[] Answers;

		internal BridgeSet Set;
	}
	internal sealed class Answer
	{
		internal string Name;

		internal string Returns;

		internal string[] Takes;

		internal Func<ModuleDefinition, TypeDefinition, TypeDefinition, MethodDefinition> Emit;
	}
	internal abstract class BridgeSet
	{
		private List<Bridge> _bridges;

		private List<TypeRename> _renames;

		private VersionRange _verified;

		internal abstract string Step { get; }

		internal abstract string From { get; }

		internal abstract string VerifiedTo { get; }

		internal IReadOnlyList<TypeRename> Renames
		{
			get
			{
				if (_renames != null)
				{
					return _renames;
				}
				_renames = new List<TypeRename>();
				foreach (TypeRename item in DeclareRenames())
				{
					if (item != null)
					{
						item.Set = this;
						_renames.Add(item);
					}
				}
				return _renames;
			}
		}

		internal IReadOnlyList<Bridge> Bridges
		{
			get
			{
				if (_bridges != null)
				{
					return _bridges;
				}
				_bridges = new List<Bridge>();
				foreach (Bridge item in Declare())
				{
					if (item != null)
					{
						item.Set = this;
						_bridges.Add(item);
					}
				}
				return _bridges;
			}
		}

		internal VersionRange VerifiedRange => _verified ?? (_verified = VersionRange.Parse(From + ".." + VerifiedTo));

		internal abstract IEnumerable<Bridge> Declare();

		internal virtual IEnumerable<TypeRename> DeclareRenames()
		{
			return Array.Empty<TypeRename>();
		}
	}
	internal static class Registry
	{
		private static readonly BridgeSet[] Sets = new BridgeSet[5]
		{
			new Production(),
			new Polyfill.Bridges.Steps.S0_4_6f13_To_0_4_7f5.Set(),
			new Forwards(),
			new Judged(),
			new Polyfill.Bridges.Steps.S0_4_5f2_To_0_4_6f5.Set()
		};

		internal static IEnumerable<BridgeSet> All => Sets;

		internal static IEnumerable<Bridge> Bridges()
		{
			BridgeSet[] sets = Sets;
			foreach (BridgeSet bridgeSet in sets)
			{
				foreach (Bridge bridge in bridgeSet.Bridges)
				{
					yield return bridge;
				}
			}
		}

		internal static Bridge Find(string assembly, string declaringType, string oldName, int parameterCount, IReadOnlyList<string> parameterTypes = null)
		{
			Bridge bridge = null;
			foreach (Bridge item in Bridges())
			{
				if (item.OldName != oldName || item.DeclaringType != declaringType || item.ParameterCount != parameterCount || !string.Equals(item.Assembly, assembly, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				if (item.ParameterTypes == null)
				{
					if (bridge == null)
					{
						bridge = item;
					}
				}
				else if (item.Fits(parameterTypes))
				{
					return item;
				}
			}
			if (parameterTypes != null)
			{
				foreach (Bridge item2 in Bridges())
				{
					if (item2.OldName == oldName && item2.DeclaringType == declaringType && item2.ParameterCount == parameterCount && item2.ParameterTypes != null && string.Equals(item2.Assembly, assembly, StringComparison.OrdinalIgnoreCase))
					{
						return null;
					}
				}
			}
			return bridge;
		}

		internal static Bridge FindByName(string assembly, string declaringType, string name, int parameterCount)
		{
			Bridge bridge = null;
			foreach (Bridge item in Bridges())
			{
				if (!(item.OldName != name) && !(item.DeclaringType != declaringType) && string.Equals(item.Assembly, assembly, StringComparison.OrdinalIgnoreCase) && (parameterCount < 0 || item.ParameterCount == parameterCount))
				{
					if (bridge != null)
					{
						return null;
					}
					bridge = item;
				}
			}
			return bridge;
		}

		internal static Bridge Creator(string assembly, string typeFullName)
		{
			Bridge bridge = null;
			foreach (Bridge item in Bridges())
			{
				if (!(item.Creates != typeFullName) && string.Equals(item.Assembly, assembly, StringComparison.OrdinalIgnoreCase))
				{
					if (bridge != null)
					{
						return null;
					}
					bridge = item;
				}
			}
			return bridge;
		}

		internal static TypeRename FindType(string assembly, string oldFullName)
		{
			BridgeSet[] sets = Sets;
			for (int i = 0; i < sets.Length; i++)
			{
				foreach (TypeRename rename in sets[i].Renames)
				{
					if (rename.OldFullName == oldFullName && string.Equals(rename.Assembly, assembly, StringComparison.OrdinalIgnoreCase))
					{
						return rename;
					}
				}
			}
			return null;
		}

		internal static string PastTheHorizon(GameVersion game)
		{
			if (!game.IsKnown)
			{
				return null;
			}
			GameVersion gameVersion = GameVersion.Unknown;
			BridgeSet[] sets = Sets;
			for (int i = 0; i < sets.Length; i++)
			{
				GameVersion gameVersion2 = GameVersion.Parse(sets[i].VerifiedTo);
				if (!gameVersion.IsKnown || gameVersion2 > gameVersion)
				{
					gameVersion = gameVersion2;
				}
			}
			if (!gameVersion.IsKnown || game <= gameVersion)
			{
				return null;
			}
			return $"Schedule I {game} is newer than anything these repairs were read against ({gameVersion}). " + "They still run: each one checks the game you have before it does anything. What no longer fits is named in the log and in `polyfillexport`, which is what turns it into an update.";
		}
	}
	internal static class Shapes
	{
		internal static Bridge Defaulted(string declaringType, string name, string[] leading, object[] defaults, string because)
		{
			return new Bridge
			{
				Assembly = "Assembly-CSharp",
				DeclaringType = declaringType,
				OldName = name,
				ParameterCount = leading.Length,
				ParameterTypes = leading,
				AllowOverload = true,
				Because = because,
				Emit = (ModuleDefinition module, TypeDefinition type) => EmitWithDefaults(module, type, name, leading, defaults)
			};
		}

		internal static MethodDefinition EmitWithDefaults(ModuleDefinition module, TypeDefinition type, string name, string[] leading, object[] defaults)
		{
			//IL_000c: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			int num = leading.Length;
			MethodDefinition val = null;
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (((MemberReference)current).Name != name || ((MethodReference)current).Parameters.Count != num + defaults.Length)
					{
						continue;
					}
					bool flag = true;
					for (int i = 0; i < num; i++)
					{
						if (((MemberReference)((ParameterReference)((MethodReference)current).Parameters[i]).ParameterType).FullName != leading[i])
						{
							flag = false;
							break;
						}
					}
					if (flag)
					{
						if (val != null)
						{
							return null;
						}
						val = current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (val == null || ((MethodReference)val).HasGenericParameters)
			{
				return null;
			}
			MethodDefinition val2 = new MethodDefinition(name, (MethodAttributes)(0x86 | (val.IsStatic ? 16 : 0)), module.ImportReference(((MethodReference)val).ReturnType));
			for (int j = 0; j < num; j++)
			{
				((MethodReference)val2).Parameters.Add(new ParameterDefinition(((ParameterReference)((MethodReference)val).Parameters[j]).Name, (ParameterAttributes)0, module.ImportReference(((ParameterReference)((MethodReference)val).Parameters[j]).ParameterType)));
			}
			ILProcessor iLProcessor = val2.Body.GetILProcessor();
			if (!val.IsStatic)
			{
				iLProcessor.Emit(OpCodes.Ldarg_0);
			}
			Enumerator<ParameterDefinition> enumerator2 = ((MethodReference)val2).Parameters.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					ParameterDefinition current2 = enumerator2.Current;
					iLProcessor.Emit(OpCodes.Ldarg, current2);
				}
			}
			finally
			{
				((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			for (int k = 0; k < defaults.Length; k++)
			{
				TypeReference parameterType = ((ParameterReference)((MethodReference)val).Parameters[num + k]).ParameterType;
				if (!PushConstant(iLProcessor, defaults[k], parameterType))
				{
					return null;
				}
			}
			iLProcessor.Emit(OpCodes.Call, module.ImportReference((MethodReference)(object)val));
			iLProcessor.Emit(OpCodes.Ret);
			return val2;
		}

		internal static bool PushConstant(ILProcessor il, object value, TypeReference expected)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Invalid comparison between Unknown and I4
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (value == null && !expected.IsValueType)
			{
				il.Emit(OpCodes.Ldnull);
				return true;
			}
			if (!(value is bool flag))
			{
				if (!(value is int num))
				{
					if (!(value is float num2))
					{
						if (value is string text && (int)expected.MetadataType == 14)
						{
							il.Emit(OpCodes.Ldstr, text);
							return true;
						}
					}
					else if ((int)expected.MetadataType == 12)
					{
						il.Emit(OpCodes.Ldc_R4, num2);
						return true;
					}
				}
				else if ((int)expected.MetadataType == 8)
				{
					il.Emit(OpCodes.Ldc_I4, num);
					return true;
				}
			}
			else if ((int)expected.MetadataType == 2)
			{
				il.Emit(flag ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
				return true;
			}
			return false;
		}

		internal static void EmitDefault(MethodDefinition method, ILProcessor il, TypeReference type)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!type.IsValueType)
			{
				il.Emit(OpCodes.Ldnull);
				return;
			}
			VariableDefinition val = new VariableDefinition(type);
			method.Body.Variables.Add(val);
			il.Emit(OpCodes.Ldloca_S, val);
			il.Emit(OpCodes.Initobj, type);
			il.Emit(OpCodes.Ldloc_S, val);
		}

		internal static MethodDefinition Getter(TypeDefinition type, string member)
		{
			return Method(type, "get_" + member, 0);
		}

		internal static MethodDefinition MethodUp(TypeDefinition type, string name, int parameters)
		{
			TypeDefinition val = type;
			while (val != null)
			{
				MethodDefinition val2 = Method(val, name, parameters);
				if (val2 != null)
				{
					return val2;
				}
				TypeDefinition val3 = null;
				try
				{
					TypeReference baseType = val.BaseType;
					val3 = ((baseType != null) ? baseType.Resolve() : null);
				}
				catch
				{
				}
				if (val3 == val)
				{
					return null;
				}
				val = val3;
			}
			return null;
		}

		internal static MethodDefinition Method(TypeDefinition type, string name, int parameters)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (type == null)
			{
				return null;
			}
			Enumerator<MethodDefinition> enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == name && ((MethodReference)current).Parameters.Count == parameters)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return null;
		}

		internal static MethodReference GenericUp(ModuleDefinition module, TypeDefinition from, string name, TypeReference argument)
		{
			//IL_000d: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			TypeDefinition val = from;
			while (val != null)
			{
				Enumerator<MethodDefinition> enumerator = val.Methods.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						MethodDefinition current = enumerator.Current;
						if (!(((MemberReference)current).Name != name) && ((MethodReference)current).Parameters.Count == 0 && ((MethodReference)current).GenericParameters.Count == 1 && !current.IsStatic)
						{
							GenericInstanceMethod val2 = new GenericInstanceMethod(module.ImportReference((MethodReference)(object)current));
							val2.GenericArguments.Add(module.ImportReference(argument));
							return (MethodReference)val2;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
				TypeReference baseType = val.BaseType;
				TypeDefinition val3 = ((baseType != null) ? baseType.Resolve() : null);
				if (val3 == val)
				{
					return null;
				}
				val = val3;
			}
			return null;
		}

		internal static MethodReference Against(ModuleDefinition module, MethodDefinition method, TypeReference owner)
		{
			//IL_000d: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_003d: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			MethodReference val = new MethodReference(((MemberReference)method).Name, ((MethodReference)method).ReturnType, owner)
			{
				HasThis = ((MethodReference)method).HasThis,
				ExplicitThis = ((MethodReference)method).ExplicitThis,
				CallingConvention = ((MethodReference)method).CallingConvention
			};
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)method).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					val.Parameters.Add(new ParameterDefinition(((ParameterReference)current).ParameterType));
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<GenericParameter> enumerator2 = ((MethodReference)method).GenericParameters.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					GenericParameter current2 = enumerator2.Current;
					val.GenericParameters.Add(new GenericParameter(((MemberReference)current2).Name, (IGenericParameterProvider)(object)val));
				}
				return val;
			}
			finally
			{
				((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		internal static TypeDefinition Nested(TypeDefinition type, string name)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (type == null)
			{
				return null;
			}
			Enumerator<TypeDefinition> enumerator = type.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					TypeDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == name)
					{
						return current;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return null;
		}
	}
}
namespace Polyfill.Bridges.Steps.S0_4_6f13_To_0_4_7f5
{
	internal sealed class Forwards : BridgeSet
	{
		internal const string Movement = "Il2CppScheduleOne.NPCs.NPCMovement";

		private const string Health = "Il2CppScheduleOne.NPCs.NPCHealth";

		internal const string AvatarType = "Il2CppScheduleOne.AvatarFramework.Avatar";

		internal const string Animation = "Il2CppScheduleOne.AvatarFramework.Animation.AvatarAnimation";

		private const string Impostor = "Il2CppScheduleOne.Avatar.Impostors.AvatarImpostor";

		private const string Clothing = "Il2CppScheduleOne.Clothing.ClothingDefinition";

		private const string ApplicationType = "Il2CppScheduleOne.Clothing.EClothingApplicationType";

		private const string OldBelt = "Il2CppScheduleOne.AvatarFramework.PoliceBelt";

		internal const string SpeedStack = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593)";

		internal const string Culling = "0.4.7 moved culling onto Avatar: every 0.1s InvokeRepeating(\"UpdateAnimationActive\") decides it from the player camera and sets IsCulled, hiding BodyContainer and showing the impostor (Avatar.cs:128, :220-250 on 0.4.7f6); AvatarAnimation has no AllowCulling of its own";

		internal const string Layers = "0.4.7 dresses avatars in prefab AvatarObjects through Avatar.Appearance and has no texture body layers, clothing paths or combined layer (AvatarAppearance.cs on 0.4.7f6); the member is put back empty";

		private const string Belt = "0.4.7's officer keeps a ScheduleOne.Law.PoliceBelt in PoliceOfficer.PoliceBelt, found in Awake (PoliceOfficer.cs:128, :161 on 0.4.7f6); the AvatarFramework.PoliceBelt the old field held is no longer on an officer";

		private const string PlayerType = "Il2CppScheduleOne.PlayerScripts.Player";

		private const string ParkingSpot = "Il2CppScheduleOne.Map.ParkingSpot";

		private const string TrashItem = "Il2CppScheduleOne.Trash.TrashItem";

		private const string CanGoInContainer = "renamed: 0.4.7's TrashItem keeps the flag in _canGoInTrashContainer, serialized under the old name, and reads it where the bag, the bin and the grabber read the field (TrashItem.cs:52, :164, :185 on 0.4.6f13; :33-34, :71-73 on 0.4.7f6)";

		private const string DraggableType = "Il2CppScheduleOne.Dragging.Draggable";

		private const string Interactable = "renamed: 0.4.6's draggable held its InteractableObject in IntObj (Draggable.cs:34, :84-87 on 0.4.6f13); 0.4.7 keeps it in _interactable and fills it itself in Awake when it is empty (Draggable.cs:30, :88-102 on 0.4.7f7)";

		private const string CentreOfMass = "0.4.6's draggable read CreateCoM once, in Awake, to add a CenterOfMass child it was then dragged by (Draggable.cs:39, :89-96 on 0.4.6f13); 0.4.7's draggable adds no such child and is dragged by its own position or its serialized DragOrigin (Draggable.cs:34, :88-108, :159-163 on 0.4.7f7), so the flag reads false and a value written to it has no reader";

		private const string Grabber = "Il2CppScheduleOne.Equipping.Equippable_TrashGrabber";

		private const string EquippedGrabber = "0.4.6's grabber kept the equipped one in a static Instance, set in Equip, and IsEquipped was Instance != null (Equippable_TrashGrabber.cs:47-49, :62 on 0.4.6f13); 0.4.7 has no static and asks the local inventory: isAnythingEquipped and Equippable is Equippable_TrashGrabber (TrashItemDraggable.cs:65-78 on 0.4.7f6)";

		private const string ParentLot = "renamed: 0.4.7's ParkingSpot keeps its lot in _parentParentLot, read and filled by the same Awake and Init that used ParentLot (ParkingSpot.cs:8, :20-38 on 0.4.6f13; :12, :21-39 on 0.4.7f6)";

		private const string CrimeData = "Il2CppScheduleOne.PlayerScripts.PlayerCrimeData";

		private const string NearestOfficer = "renamed: 0.4.7's PlayerCrimeData keeps the closest aware officer in NearestActivePoliceOfficer, the field 0.4.6f13 called NearestOfficer, and CheckNearestOfficer still writes it every 0.2 s (PlayerCrimeData.cs:71, :541-547, :763 on 0.4.7f12)";

		internal override string Step => "0.4.6f13 -> 0.4.7f5 (forwards)";

		internal override string From => "0.4.7f5";

		internal override string VerifiedTo => "0.4.7f6";

		internal override IEnumerable<Bridge> Declare()
		{
			return new Bridge[59]
			{
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "get_WalkSpeed",
					ParameterCount = 0,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); the walk speed is NPCData.Movement.WalkSpeed, which NPCMovement exposes as DefaultWalkSpeed (NPCMovement.cs:205)",
					Emit = EmitWalkSpeed
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "set_WalkSpeed",
					ParameterCount = 1,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); 0.4.5's WalkSpeed was a field on NPCMovement the agent speed was lerped from (NPCMovement.cs:99, :424 on 0.4.5f2). 0.4.7 sets the walk speed with SpeedController.SetDefaultSpeed, the call NPC.cs:553 makes with NPCData.Movement.WalkSpeed, and the getter above reads it back. The 0.4.5 step's bridge goes through npc.NPCData, and 0.4.7's NPCMovement keeps its NPC in _npc",
					Emit = EmitSetWalkSpeed
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "get_RunSpeed",
					ParameterCount = 0,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); the top speed is the controller's _maxSpeed (NPCData.Movement.MaxSpeed, 7 by default beside a 1.8 walk), which a normalized control of 1 runs at",
					Emit = EmitRunSpeed
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "set_RunSpeed",
					ParameterCount = 1,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); the top speed is the controller's _maxSpeed, set with SetMaxSpeed (NPCSpeedController.cs:35 on 0.4.7f12), which the getter above reads back. The 0.4.5 step's bridge goes through npc.NPCData, and 0.4.7's NPCMovement keeps its NPC in _npc",
					Emit = EmitSetRunSpeed
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "get_MovementSpeedScale",
					ParameterCount = 0,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); 0.4.5's MovementSpeedScale was the walk-to-run position the agent speed was lerped with. 0.4.7 has the resulting speed as MoveSpeed between DefaultSpeed and _maxSpeed (NPCSpeedController.cs:17-19, :109-121 on 0.4.7f12), so the position is read back from those. The 0.4.5 step's bridge needs ActiveSpeedControl, which 0.4.7 does not have",
					Emit = EmitGetSpeedScale
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "set_MovementSpeedScale",
					ParameterCount = 1,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); writing the scale wrote the base speed, and 0.4.7's base speed is the priority-0 \"default\" control SetDefaultSpeed writes (NPCSpeedController.cs:29-33 on 0.4.7f12). Every behaviour's control has priority 1 or more and still outranks it. The 0.4.5 step's bridge needs ActiveSpeedControl, which 0.4.7 does not have",
					Emit = EmitSetSpeedScale
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCHealth",
					OldName = "get_Invincible",
					ParameterCount = 0,
					Because = "0.4.7 copies NPCData.Health.Invincible into NPCHealth._invincible once and reads only the copy (NPCHealth.cs:35, :118, :232, :251, :270 on 0.4.7f12). The 0.4.5 step's bridge goes through npc.NPCData, and 0.4.7's NPCHealth keeps its NPC in _npc",
					Emit = (ModuleDefinition module, TypeDefinition health) => EmitGetterRename(module, health, "get_Invincible", "_invincible")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCHealth",
					OldName = "set_Invincible",
					ParameterCount = 1,
					Because = "0.4.7 decides on NPCHealth._invincible alone (NPCHealth.cs:232, :251, :270 on 0.4.7f12), so the old setter writes that; writing NPCData.Health.Invincible after the NPC is up changes nothing",
					Emit = (ModuleDefinition module, TypeDefinition health) => EmitSetterRename(module, health, "set_Invincible", "_invincible")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPCMovement",
					OldName = "UpdateSpeed",
					ParameterCount = 0,
					Because = "0.4.7 replaced NPCMovement's walk/run speeds and pause flag with NPCSpeedController: the highest-priority speed control sets the speed, normalized ones as a fraction of _maxSpeed, times the multiplier (NPCSpeedController.cs RecalculateMoveSpeed on 0.4.7f6), and every change is pushed to the NavMeshAgent (NPCMovement.cs:620, :1593); the controller recalculates on every change, so updating the speed is re-applying the current multiplier, which recalculates and pushes it to the agent",
					Emit = EmitUpdateSpeed
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.Behaviour.NPCBehaviour",
					OldName = "ConsumeProduct",
					ParameterCount = 2,
					Because = "renamed: 0.4.7 has ConsumeProduct_Server(product, removeFromInventory) with the same arguments (NPCBehaviour.cs:163 on 0.4.7f6)",
					Emit = EmitConsumeProduct
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Messaging.MSGConversation",
					OldName = "set_contactName",
					ParameterCount = 1,
					Because = "0.4.7 reads a conversation's name from its MessageContactInfo (ContactName => _sender.Name, MSGConversation.cs:35, :79 on 0.4.7f6); renaming is writing _name into a copy of _sender and storing the copy back",
					Emit = EmitSetContactName
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.NPCs.NPC",
					OldName = "SetPanicked",
					ParameterCount = 0,
					Because = "renamed in 0.4.4: SetPanicked became the server RPC SetPanicked_Server, callable by a client, which panics the NPC on every peer (NPC.cs:1178-1190, :2925-2942 on 0.4.7f12); vanilla's own panic response calls exactly that (NPCResponses_Civilian.cs:208)",
					Emit = (ModuleDefinition module, TypeDefinition npc) => EmitForward(module, npc, "SetPanicked", "SetPanicked_Server")
				},
				Shapes.Defaulted("Il2CppScheduleOne.NPCs.Relation.NPCRelationData", "SetRelationship", new string[1] { "System.Single" }, new object[1] { true }, "SetRelationship took a network flag in 0.4.3, and the one-argument form sent the new value to every peer, which network = true does (NPCRelationData.cs:80-95 on 0.4.7f12)"),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.AvatarFramework.Animation.AvatarAnimation",
					OldName = "get_IsAvatarCulled",
					ParameterCount = 0,
					Because = "0.4.7 moved culling onto Avatar: every 0.1s InvokeRepeating(\"UpdateAnimationActive\") decides it from the player camera and sets IsCulled, hiding BodyContainer and showing the impostor (Avatar.cs:128, :220-250 on 0.4.7f6); AvatarAnimation has no AllowCulling of its own; culled is Avatar.IsCulled",
					Emit = EmitIsAvatarCulled
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Avatar.Impostors.AvatarImpostor",
					OldName = "DisableImpostor",
					ParameterCount = 0,
					Because = "0.4.7's impostor is Enable()/Disable() (AvatarImpostor.cs on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition impostor) => EmitForward(module, impostor, "DisableImpostor", "Disable")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Avatar.Impostors.AvatarImpostor",
					OldName = "get_HasTexture",
					ParameterCount = 0,
					Because = "0.4.7's impostor records whether a texture was set in _impostorSet (SetTexture, AvatarImpostor.cs on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition impostor) => EmitGetterRename(module, impostor, "get_HasTexture", "_impostorSet")
				},
				NullGetter("Il2CppScheduleOne.AvatarFramework.Avatar", "get_BodyMeshes", ReferenceArrayOf("UnityEngine.CoreModule", "UnityEngine", "SkinnedMeshRenderer")),
				NullGetter("Il2CppScheduleOne.AvatarFramework.Avatar", "get_ShapeKeyMeshes", ReferenceArrayOf("UnityEngine.CoreModule", "UnityEngine", "SkinnedMeshRenderer")),
				NullGetter("Il2CppScheduleOne.AvatarFramework.Avatar", "get_FaceMesh", (ModuleDefinition module) => TypeIn(module, "UnityEngine.CoreModule", "UnityEngine", "SkinnedMeshRenderer")),
				Empty("Il2CppScheduleOne.Clothing.ClothingDefinition", "get_ClothingAssetPath", 0, (ModuleDefinition m) => m.TypeSystem.String, "0.4.7 dresses avatars in prefab AvatarObjects through Avatar.Appearance and has no texture body layers, clothing paths or combined layer (AvatarAppearance.cs on 0.4.7f6); the member is put back empty"),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Clothing.ClothingDefinition",
					OldName = "get_ApplicationType",
					ParameterCount = 0,
					Creates = "Il2CppScheduleOne.Clothing.EClothingApplicationType",
					Because = "0.4.7 dresses avatars in prefab AvatarObjects through Avatar.Appearance and has no texture body layers, clothing paths or combined layer (AvatarAppearance.cs on 0.4.7f6); the member is put back empty; the enum is put back so the member can name it, and every item answers BodyLayer (0), the one kind a caller cannot paint without a path",
					Emit = delegate(ModuleDefinition module, TypeDefinition clothing)
					{
						//IL_0012: Unknown result type (might be due to invalid IL or missing references)
						//IL_0018: Expected O, but got Unknown
						//IL_0024: 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)
						TypeDefinition val = ApplicationTypeEnum(module);
						MethodDefinition val2 = new MethodDefinition("get_ApplicationType", (MethodAttributes)2182, (TypeReference)(object)val);
						ILProcessor iLProcessor = val2.Body.GetILProcessor();
						iLProcessor.Emit(OpCodes.Ldc_I4_0);
						iLProcessor.Emit(OpCodes.Ret);
						return AsProperty(clothing, val2);
					}
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.PlayerClothing",
					OldName = "InsertClothing",
					ParameterCount = 1,
					Because = "renamed: 0.4.7's PlayerClothing.InsertClothingItem(ClothingInstance) puts an item into the slot its definition names, as InsertClothing did (PlayerClothing.cs:47 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition clothing) => EmitForward1(module, clothing, "InsertClothing", "InsertClothingItem")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Police.PoliceOfficer",
					OldName = "get_belt",
					ParameterCount = 0,
					Because = "0.4.7's officer keeps a ScheduleOne.Law.PoliceBelt in PoliceOfficer.PoliceBelt, found in Awake (PoliceOfficer.cs:128, :161 on 0.4.7f6); the AvatarFramework.PoliceBelt the old field held is no longer on an officer; the old field answers null, so a caller that fills it when empty does nothing",
					Emit = (ModuleDefinition module, TypeDefinition officer) => AsProperty(officer, EmitEmpty(module, "get_belt", (TypeReference)(object)module.GetType("Il2CppScheduleOne.AvatarFramework.PoliceBelt")))
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Police.PoliceOfficer",
					OldName = "set_belt",
					ParameterCount = 1,
					Because = "0.4.7's officer keeps a ScheduleOne.Law.PoliceBelt in PoliceOfficer.PoliceBelt, found in Awake (PoliceOfficer.cs:128, :161 on 0.4.7f6); the AvatarFramework.PoliceBelt the old field held is no longer on an officer; the officer finds its own belt in Awake, so storing one has nothing to do",
					Emit = (ModuleDefinition module, TypeDefinition officer) => AsProperty(officer, EmitEmpty(module, "set_belt", module.TypeSystem.Void, (TypeReference)module.GetType("Il2CppScheduleOne.AvatarFramework.PoliceBelt")))
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Storage.StorableItemInstance",
					OldName = "get_StoredItem",
					ParameterCount = 0,
					Because = "renamed on 0.4.7f7: the IL2CPP interop of 0.4.7f7 has StorableItemInstance.StoredItemPrefab (still virtual, overridden by ProductItemInstance) and no StoredItem. 0.4.7f6 still has StoredItem (StorableItemInstance.cs:11), so there the member is present and nothing is added",
					Emit = (ModuleDefinition module, TypeDefinition item) => EmitGetterRename(module, item, "get_StoredItem", "StoredItemPrefab")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.UI.DailySummary",
					OldName = "get_IsOpen",
					ParameterCount = 0,
					Because = "renamed in place: 0.4.6's DailySummary.IsOpen was set in Open and cleared in Close (DailySummary.cs:55, 72 on 0.4.6f13); 0.4.7 calls it IsInProgress, set when the summary starts and cleared in Close (DailySummary.cs:54, 73-77, 117-127 on 0.4.7f12)",
					Emit = (ModuleDefinition module, TypeDefinition summary) => EmitGetterRename(module, summary, "get_IsOpen", "IsInProgress")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.UI.RankUpCanvas",
					OldName = "get_IsRunning",
					ParameterCount = 0,
					Because = "renamed in place: RankUpCanvas.IsRunning on 0.4.6f13 (RankUpCanvas.cs:52) is IsInProgress on 0.4.7f12 (RankUpCanvas.cs:52, set in StartEvent :70, cleared in EndEvent :145)",
					Emit = (ModuleDefinition module, TypeDefinition canvas) => EmitGetterRename(module, canvas, "get_IsRunning", "IsInProgress")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.UI.RegionUnlockedCanvas",
					OldName = "get_IsRunning",
					ParameterCount = 0,
					Because = "renamed in place: RegionUnlockedCanvas.IsRunning on 0.4.6f13 (RegionUnlockedCanvas.cs:27) is IsInProgress on 0.4.7f12 (RegionUnlockedCanvas.cs:28, set in StartEvent :38, cleared in EndEvent :76)",
					Emit = (ModuleDefinition module, TypeDefinition canvas) => EmitGetterRename(module, canvas, "get_IsRunning", "IsInProgress")
				},
				Empty("Il2CppScheduleOne.Property.Property", "set_EmployeeContainer", 1, (ModuleDefinition m) => m.TypeSystem.Void, "0.4.6's Property declared a public Transform EmployeeContainer and no game code read or wrote it (Property.cs:83 is its only mention in Assembly-CSharp on 0.4.6f13); 0.4.7 dropped the field (Property.cs on 0.4.7f6), so a mod that fills it in while it builds a property has nothing left to tell the game", (ModuleDefinition module) => TypeIn(module, "UnityEngine.CoreModule", "UnityEngine", "Transform")),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Map.ParkingSpot",
					OldName = "set_ParentLot",
					ParameterCount = 1,
					Because = "renamed: 0.4.7's ParkingSpot keeps its lot in _parentParentLot, read and filled by the same Awake and Init that used ParentLot (ParkingSpot.cs:8, :20-38 on 0.4.6f13; :12, :21-39 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition spot) => EmitSetterRename(module, spot, "set_ParentLot", "_parentParentLot")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Map.ParkingSpot",
					OldName = "get_ParentLot",
					ParameterCount = 0,
					Because = "renamed: 0.4.7's ParkingSpot keeps its lot in _parentParentLot, read and filled by the same Awake and Init that used ParentLot (ParkingSpot.cs:8, :20-38 on 0.4.6f13; :12, :21-39 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition spot) => EmitGetterRename(module, spot, "get_ParentLot", "_parentParentLot")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.PlayerCrimeData",
					OldName = "get_NearestOfficer",
					ParameterCount = 0,
					Because = "renamed: 0.4.7's PlayerCrimeData keeps the closest aware officer in NearestActivePoliceOfficer, the field 0.4.6f13 called NearestOfficer, and CheckNearestOfficer still writes it every 0.2 s (PlayerCrimeData.cs:71, :541-547, :763 on 0.4.7f12)",
					Emit = (ModuleDefinition module, TypeDefinition data) => EmitGetterRename(module, data, "get_NearestOfficer", "NearestActivePoliceOfficer")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.PlayerCrimeData",
					OldName = "set_NearestOfficer",
					ParameterCount = 1,
					Because = "renamed: 0.4.7's PlayerCrimeData keeps the closest aware officer in NearestActivePoliceOfficer, the field 0.4.6f13 called NearestOfficer, and CheckNearestOfficer still writes it every 0.2 s (PlayerCrimeData.cs:71, :541-547, :763 on 0.4.7f12)",
					Emit = (ModuleDefinition module, TypeDefinition data) => EmitSetterRename(module, data, "set_NearestOfficer", "NearestActivePoliceOfficer")
				},
				Empty("Il2CppScheduleOne.Trash.TrashItem", "set_CurrentProperty", 1, (ModuleDefinition m) => m.TypeSystem.Void, "0.4.6's trash kept the owned property it lies in as a cache that only its own RecheckProperty read and refreshed (TrashItem.cs:66, :249-263 on 0.4.6f13); 0.4.7's trash records no property and the getter put back for it answers from the bounds each time, so a value written here has no reader", (ModuleDefinition module) => (TypeReference)(object)module.GetType("Il2CppScheduleOne.Property.Property")),
				Empty("Il2CppScheduleOne.NPCs.NPCMovement", "WarpToNavMesh", 0, (ModuleDefinition m) => m.TypeSystem.Void, "0.4.6's NPCMovement.WarpToNavMesh() had an empty body (NPCMovement.cs:964-966 on 0.4.6f13) and 0.4.7 dropped the method (NPCMovement.cs on 0.4.7f6); the call did nothing and does nothing"),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "get_CanGoInContainer",
					ParameterCount = 0,
					Because = "renamed: 0.4.7's TrashItem keeps the flag in _canGoInTrashContainer, serialized under the old name, and reads it where the bag, the bin and the grabber read the field (TrashItem.cs:52, :164, :185 on 0.4.6f13; :33-34, :71-73 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition trash) => EmitGetterRename(module, trash, "get_CanGoInContainer", "_canGoInTrashContainer")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "set_CanGoInContainer",
					ParameterCount = 1,
					Because = "renamed: 0.4.7's TrashItem keeps the flag in _canGoInTrashContainer, serialized under the old name, and reads it where the bag, the bin and the grabber read the field (TrashItem.cs:52, :164, :185 on 0.4.6f13; :33-34, :71-73 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition trash) => EmitSetterRename(module, trash, "set_CanGoInContainer", "_canGoInTrashContainer")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.GameTime.TimeManager",
					OldName = "SetTimeAndSync",
					ParameterCount = 1,
					Because = "0.4.6's SetTimeAndSync(time) set the time on the host and sent it to everyone through SetTimeData_Client (TimeManager.cs:317-326 on 0.4.6f13); 0.4.7's SetTime_Server(time) makes the same host check and the same send, and that send runs on the host too and sets the time there (TimeManager.cs:196-198, :321-331, :614-623 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition time) => EmitForward1(module, time, "SetTimeAndSync", "SetTime_Server")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.Player",
					OldName = "SetVisibleToLocalPlayer",
					ParameterCount = 1,
					Because = "0.4.6's SetVisibleToLocalPlayer(vis) recorded the flag, moved the avatar to the Player or the Invisible layer and called SetThirdPersonMeshesVisibility(vis) (Player.cs:1231-1243 on 0.4.6f13); 0.4.7's SetThirdPersonMeshesVisibility moves the avatar to that layer itself (Player.cs:1649-1669 on 0.4.7f6) and the flag is still on the player (Player.cs:446)",
					Emit = EmitSetVisibleToLocalPlayer
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Dialogue.DialogueController",
					OldName = "get_GenericDialogue",
					ParameterCount = 0,
					Because = "0.4.6's controller held the dialogue StartGenericDialogue opens in its GenericDialogue field (DialogueController.cs:82, :129-147 on 0.4.6f13); 0.4.7's controller opens the one the DialogueManager holds and reads it through _genericConversation (DialogueController.cs:112, :143-161 on 0.4.7f6)",
					Emit = EmitGenericDialogue
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Equipping.Equippable_TrashGrabber",
					OldName = "get_Instance",
					ParameterCount = 0,
					Because = "0.4.6's grabber kept the equipped one in a static Instance, set in Equip, and IsEquipped was Instance != null (Equippable_TrashGrabber.cs:47-49, :62 on 0.4.6f13); 0.4.7 has no static and asks the local inventory: isAnythingEquipped and Equippable is Equippable_TrashGrabber (TrashItemDraggable.cs:65-78 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition grabber) => EmitEquippedGrabber(module, grabber, "get_Instance", asFlag: false)
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Equipping.Equippable_TrashGrabber",
					OldName = "get_IsEquipped",
					ParameterCount = 0,
					Because = "0.4.6's grabber kept the equipped one in a static Instance, set in Equip, and IsEquipped was Instance != null (Equippable_TrashGrabber.cs:47-49, :62 on 0.4.6f13); 0.4.7 has no static and asks the local inventory: isAnythingEquipped and Equippable is Equippable_TrashGrabber (TrashItemDraggable.cs:65-78 on 0.4.7f6)",
					Emit = (ModuleDefinition module, TypeDefinition grabber) => EmitEquippedGrabber(module, grabber, "get_IsEquipped", asFlag: true)
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "SetPhysicsActive",
					ParameterCount = 1,
					Because = "0.4.6's trash rested kinematic and SetPhysicsActive(true) woke it: called when it was dragged or hit, undone a minute later (TrashItem.cs:91-107, :265-292 on 0.4.6f13). 0.4.7's trash is never kinematic and rests asleep, so nothing would wake a body made kinematic (TrashItem.cs:48-60, Draggable.cs:224-240 on 0.4.7f6): true makes it non-kinematic and wakes it, false puts it to sleep, which a drag or a hit ends as it did on 0.4.6",
					Emit = EmitSetPhysicsActive
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "get_Draggable",
					ParameterCount = 0,
					Because = "0.4.6's trash item held its Draggable in a public field (TrashItem.cs:41 on 0.4.6f13); 0.4.7 keeps a TrashItemDraggable, which is a Draggable, in _draggable (TrashItem.cs:38, :51, TrashItemDraggable.cs:9 on 0.4.7f6)",
					Emit = EmitTrashDraggable
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "get_colliders",
					ParameterCount = 0,
					Because = "0.4.6's trash item kept GetComponentsInChildren<Collider>() in its colliders field (TrashItem.cs:54, :133-136 on 0.4.6f13); 0.4.7 keeps no such list (TrashItem.cs on 0.4.7f6), so the getter collects them when asked",
					Emit = EmitTrashColliders
				},
				Empty("Il2CppScheduleOne.Trash.TrashItem", "set_colliders", 1, (ModuleDefinition m) => m.TypeSystem.Void, "0.4.6's trash item kept its colliders in a field a mod could fill (TrashItem.cs:54 on 0.4.6f13); 0.4.7 keeps no list (TrashItem.cs on 0.4.7f7) and the getter put back for it collects them each time, so a list written here has no reader", ReferenceArrayOf("UnityEngine.PhysicsModule", "UnityEngine", "Collider")),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "SetCollidersEnabled",
					ParameterCount = 1,
					Because = "0.4.6's SetCollidersEnabled(enabled) set enabled on each collider in the item's list (TrashItem.cs:294-304 on 0.4.6f13); 0.4.7 keeps no list, so the switch is the body's detectCollisions: off takes all of the body's colliders out of the simulation, on puts back those that are enabled and leaves one a mod disabled itself disabled",
					Emit = EmitSetCollidersEnabled
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "SetContinuousCollisionDetection",
					ParameterCount = 0,
					Because = "0.4.6's SetContinuousCollisionDetection() made the body continuous and active and went back to discrete a minute later (TrashItem.cs:266-281 on 0.4.6f13); 0.4.7 makes a body continuous while it is dragged and gives it its own mode back on release (Draggable.cs:224-242, :266-275 on 0.4.7f7), so the body goes continuous, non-kinematic and awake here and the next drag puts its mode back",
					Emit = EmitSetContinuousCollisionDetection
				},
				Empty("Il2CppScheduleOne.Trash.TrashItem", "InitializeSaveable", 0, (ModuleDefinition m) => m.TypeSystem.Void, "0.4.6's trash item was a saveable of its own and InitializeSaveable() registered it with the SaveManager, from Start (TrashItem.cs:110-121 on 0.4.6f13); 0.4.7's trash is no saveable and the TrashManager writes every item on its list (TrashItem.cs:13, :105-108, TrashManager.cs:301-306 on 0.4.7f7), so there is nothing to register"),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashItem",
					OldName = "set_Draggable",
					ParameterCount = 1,
					Because = "0.4.6's trash item held its Draggable in a public field a mod could write (TrashItem.cs:41 on 0.4.6f13); 0.4.7 holds a TrashItemDraggable in _draggable, finds it itself in Awake and only asks it whether it is being dragged (TrashItem.cs:38, :51, :80-83 on 0.4.7f7), so a draggable of that kind is stored and any other value leaves the one Awake found",
					Emit = EmitSetTrashDraggable
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Dragging.Draggable",
					OldName = "get_IntObj",
					ParameterCount = 0,
					Because = "renamed: 0.4.6's draggable held its InteractableObject in IntObj (Draggable.cs:34, :84-87 on 0.4.6f13); 0.4.7 keeps it in _interactable and fills it itself in Awake when it is empty (Draggable.cs:30, :88-102 on 0.4.7f7)",
					Emit = (ModuleDefinition module, TypeDefinition draggable) => EmitGetterRename(module, draggable, "get_IntObj", "_interactable")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Dragging.Draggable",
					OldName = "set_IntObj",
					ParameterCount = 1,
					Because = "renamed: 0.4.6's draggable held its InteractableObject in IntObj (Draggable.cs:34, :84-87 on 0.4.6f13); 0.4.7 keeps it in _interactable and fills it itself in Awake when it is empty (Draggable.cs:30, :88-102 on 0.4.7f7)",
					Emit = (ModuleDefinition module, TypeDefinition draggable) => EmitSetterRename(module, draggable, "set_IntObj", "_interactable")
				},
				Empty("Il2CppScheduleOne.Dragging.Draggable", "get_CreateCoM", 0, (ModuleDefinition m) => m.TypeSystem.Boolean, "0.4.6's draggable read CreateCoM once, in Awake, to add a CenterOfMass child it was then dragged by (Draggable.cs:39, :89-96 on 0.4.6f13); 0.4.7's draggable adds no such child and is dragged by its own position or its serialized DragOrigin (Draggable.cs:34, :88-108, :159-163 on 0.4.7f7), so the flag reads false and a value written to it has no reader"),
				Empty("Il2CppScheduleOne.Dragging.Draggable", "set_CreateCoM", 1, (ModuleDefinition m) => m.TypeSystem.Void, "0.4.6's draggable read CreateCoM once, in Awake, to add a CenterOfMass child it was then dragged by (Draggable.cs:39, :89-96 on 0.4.6f13); 0.4.7's draggable adds no such child and is dragged by its own position or its serialized DragOrigin (Draggable.cs:34, :88-108, :159-163 on 0.4.7f7), so the flag reads false and a value written to it has no reader", (ModuleDefinition m) => m.TypeSystem.Boolean),
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Trash.TrashManager",
					OldName = "get_TRASH_ITEM_LIMIT",
					ParameterCount = 0,
					Because = "renamed: the 2000 item limit is TrashItemLimit on 0.4.7 (TrashManager.cs:33 on 0.4.6f13; :34 on 0.4.7f6)",
					Emit = EmitTrashItemLimit
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.PlayerMovement",
					OldName = "SetPlayerRotation",
					ParameterCount = 1,
					Because = "renamed: 0.4.6's SetPlayerRotation(Quaternion) turned the player to the rotation's yaw with the controller off (PlayerMovement.cs:683-689 on 0.4.6f13); 0.4.7f12 has SetRotation(Quaternion) in its place, beside the same LerpPlayerRotation",
					Emit = (ModuleDefinition module, TypeDefinition movement) => EmitForward1(module, movement, "SetPlayerRotation", "SetRotation")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.Product.ProductIconManager",
					OldName = "GenerateIcons",
					ParameterCount = 1,
					Because = "renamed: 0.4.6's GenerateIcons(productID) made one icon per packaging and returned the product's own sprite (ProductIconManager.cs:64-94 on 0.4.6f13); 0.4.7f12 calls it GenerateRuntimeIcons(productID), with the same return",
					Emit = (ModuleDefinition module, TypeDefinition icons) => EmitForward1(module, icons, "GenerateIcons", "GenerateRuntimeIcons")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.Player",
					OldName = "get_playerDataRetrieveReturned",
					ParameterCount = 0,
					Because = "renamed: 0.4.6's player raised playerDataRetrieveReturned once its saved data had been applied (Player.cs:447, :1476, :2746 on 0.4.6f13); 0.4.7 raises PlayerLoaded at the same point, the end of SetPlayerData_Client (Player.cs:448, :715-717, :2809 on 0.4.7f7)",
					Emit = (ModuleDefinition module, TypeDefinition player) => EmitGetterRename(module, player, "get_playerDataRetrieveReturned", "PlayerLoaded")
				},
				new Bridge
				{
					Assembly = "Assembly-CSharp",
					DeclaringType = "Il2CppScheduleOne.PlayerScripts.Player",
					OldName = "RequestPlayerData",
					ParameterCount = 1,
					ParameterTypes = new string[1] { "System.String" },
					Because = "0.4.6's RequestPlayerData(playerCode) asked the server for the player's saved data (Player.cs:694, :810 on 0.4.6f13); 0.4.7's RequestPlayerData_Server(playerCode, isHost) asks the same and is told whether the asker is the host, which the game reads from InstanceFinder.IsHost (Player.cs:687, :823 on 0.4.7f7)",
					Emit = EmitRequestPlayerData
				}
			};
		}

		internal static MethodDefinition Controller(TypeDefinition movement, out TypeDefinition controller)
		{
			MethodDefinition val = Shapes.Getter(movement, "SpeedController");
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				TypeReference returnType = ((MethodReference)val).ReturnType;
				obj = ((returnType != null) ? returnType.Resolve() : null);
			}
			controller = (TypeDefinition)obj;
			return val;
		}

		private static MethodDefinition EmitWalkSpeed(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0038: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = Shapes.Getter(movement, "DefaultWalkSpeed");
			if (val == null)
			{
				return null;
			}
			MethodDefinition val2 = new MethodDefinition("get_WalkSpeed", (MethodAttributes)2182, module.TypeSystem.Single);
			ILProcessor iLProcessor = val2.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(movement, val2);
		}

		private static MethodDefinition EmitSetWalkSpeed(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			TypeDefinition controller;
			MethodDefinition val = Controller(movement, out controller);
			MethodDefinition val2 = Shapes.Method(controller, "SetDefaultSpeed", 1);
			if (val == null || val2 == null)
			{
				return null;
			}
			MethodDefinition val3 = new MethodDefinition("set_WalkSpeed", (MethodAttributes)2182, module.TypeSystem.Void);
			((MethodReference)val3).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, module.TypeSystem.Single));
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			Instruction val4 = iLProcessor.Create(OpCodes.Pop);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Brfalse_S, val4);
			iLProcessor.Emit(OpCodes.Ldarg_1);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val4);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(movement, val3);
		}

		private static MethodDefinition EmitRunSpeed(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition controller;
			MethodDefinition val = Controller(movement, out controller);
			MethodDefinition val2 = Shapes.Getter(controller, "_maxSpeed");
			if (val == null || val2 == null)
			{
				return null;
			}
			MethodDefinition val3 = new MethodDefinition("get_RunSpeed", (MethodAttributes)2182, module.TypeSystem.Single);
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			Instruction val4 = iLProcessor.Create(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Brtrue_S, val4);
			iLProcessor.Emit(OpCodes.Pop);
			iLProcessor.Emit(OpCodes.Ldc_R4, 7f);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val4);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(movement, val3);
		}

		private static MethodDefinition EmitSetRunSpeed(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			TypeDefinition controller;
			MethodDefinition val = Controller(movement, out controller);
			MethodDefinition val2 = Shapes.Method(controller, "SetMaxSpeed", 1);
			if (val == null || val2 == null)
			{
				return null;
			}
			MethodDefinition val3 = new MethodDefinition("set_RunSpeed", (MethodAttributes)2182, module.TypeSystem.Void);
			((MethodReference)val3).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, module.TypeSystem.Single));
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			Instruction val4 = iLProcessor.Create(OpCodes.Pop);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Brfalse_S, val4);
			iLProcessor.Emit(OpCodes.Ldarg_1);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val4);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(movement, val3);
		}

		private static MethodDefinition EmitGetSpeedScale(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_01bd: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: 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_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: 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_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition controller;
			MethodDefinition val = Controller(movement, out controller);
			MethodDefinition val2 = Shapes.Getter(controller, "DefaultSpeed");
			MethodDefinition val3 = Shapes.Getter(controller, "_maxSpeed");
			MethodDefinition val4 = Shapes.Getter(controller, "MoveSpeed");
			if (val == null || val2 == null || val3 == null || val4 == null)
			{
				return null;
			}
			MethodDefinition val5 = new MethodDefinition("get_MovementSpeedScale", (MethodAttributes)2182, module.TypeSystem.Single);
			VariableDefinition val6 = new VariableDefinition(module.ImportReference((TypeReference)(object)controller));
			VariableDefinition val7 = new VariableDefinition(module.TypeSystem.Single);
			VariableDefinition val8 = new VariableDefinition(module.TypeSystem.Single);
			VariableDefinition val9 = new VariableDefinition(module.TypeSystem.Single);
			val5.Body.Variables.Add(val6);
			val5.Body.Variables.Add(val7);
			val5.Body.Variables.Add(val8);
			val5.Body.Variables.Add(val9);
			val5.Body.InitLocals = true;
			ILProcessor iLProcessor = val5.Body.GetILProcessor();
			Instruction val10 = iLProcessor.Create(OpCodes.Ldc_R4, 0f);
			Instruction val11 = iLProcessor.Create(OpCodes.Ldloc, val9);
			Instruction val12 = iLProcessor.Create(OpCodes.Ldloc, val9);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Stloc, val6);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Brfalse, val10);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Stloc, val7);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val3);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Sub);
			iLProcessor.Emit(OpCodes.Stloc, val8);
			iLProcessor.Emit(OpCodes.Ldloc, val8);
			iLProcessor.Emit(OpCodes.Ldc_R4, 0f);
			iLProcessor.Emit(OpCodes.Ble_Un, val10);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val4);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Sub);
			iLProcessor.Emit(OpCodes.Ldloc, val8);
			iLProcessor.Emit(OpCodes.Div);
			iLProcessor.Emit(OpCodes.Stloc, val9);
			iLProcessor.Emit(OpCodes.Ldloc, val9);
			iLProcessor.Emit(OpCodes.Ldc_R4, 0f);
			iLProcessor.Emit(OpCodes.Bge_Un, val11);
			iLProcessor.Emit(OpCodes.Br, val10);
			iLProcessor.Append(val11);
			iLProcessor.Emit(OpCodes.Ldc_R4, 1f);
			iLProcessor.Emit(OpCodes.Ble_Un, val12);
			iLProcessor.Emit(OpCodes.Ldc_R4, 1f);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val12);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val10);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(movement, val5);
		}

		private static MethodDefinition EmitSetSpeedScale(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: 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_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition controller;
			MethodDefinition val = Controller(movement, out controller);
			MethodDefinition val2 = Shapes.Getter(controller, "DefaultSpeed");
			MethodDefinition val3 = Shapes.Getter(controller, "_maxSpeed");
			MethodDefinition val4 = Shapes.Method(controller, "AddSpeedControl", 4);
			if (val == null || val2 == null || val3 == null || val4 == null)
			{
				return null;
			}
			MethodDefinition val5 = new MethodDefinition("set_MovementSpeedScale", (MethodAttributes)2182, module.TypeSystem.Void);
			((MethodReference)val5).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, module.TypeSystem.Single));
			VariableDefinition val6 = new VariableDefinition(module.ImportReference((TypeReference)(object)controller));
			VariableDefinition val7 = new VariableDefinition(module.TypeSystem.Single);
			VariableDefinition val8 = new VariableDefinition(module.TypeSystem.Single);
			val5.Body.Variables.Add(val6);
			val5.Body.Variables.Add(val7);
			val5.Body.Variables.Add(val8);
			val5.Body.InitLocals = true;
			ILProcessor iLProcessor = val5.Body.GetILProcessor();
			Instruction val9 = iLProcessor.Create(OpCodes.Ret);
			Instruction val10 = iLProcessor.Create(OpCodes.Ldloc, val7);
			Instruction val11 = iLProcessor.Create(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Stloc, val6);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Brfalse, val9);
			iLProcessor.Emit(OpCodes.Ldarg_1);
			iLProcessor.Emit(OpCodes.Stloc, val7);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Ldc_R4, 0f);
			iLProcessor.Emit(OpCodes.Bge_Un, val10);
			iLProcessor.Emit(OpCodes.Ldc_R4, 0f);
			iLProcessor.Emit(OpCodes.Stloc, val7);
			iLProcessor.Append(val10);
			iLProcessor.Emit(OpCodes.Ldc_R4, 1f);
			iLProcessor.Emit(OpCodes.Ble_Un, val11);
			iLProcessor.Emit(OpCodes.Ldc_R4, 1f);
			iLProcessor.Emit(OpCodes.Stloc, val7);
			iLProcessor.Append(val11);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Stloc, val8);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Ldstr, "default");
			iLProcessor.Emit(OpCodes.Ldloc, val8);
			iLProcessor.Emit(OpCodes.Ldloc, val6);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val3);
			iLProcessor.Emit(OpCodes.Ldloc, val8);
			iLProcessor.Emit(OpCodes.Sub);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Mul);
			iLProcessor.Emit(OpCodes.Add);
			iLProcessor.Emit(OpCodes.Ldc_I4_0);
			iLProcessor.Emit(OpCodes.Ldc_I4_1);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val4);
			iLProcessor.Append(val9);
			return AsProperty(movement, val5);
		}

		private static MethodDefinition EmitUpdateSpeed(ModuleDefinition module, TypeDefinition movement)
		{
			//IL_0042: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//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_0082: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			TypeDefinition controller;
			MethodDefinition val = Controller(movement, out controller);
			MethodDefinition val2 = Shapes.Method(controller, "SetSpeedMultiplier", 1);
			MethodDefinition val3 = Shapes.Getter(controller, "_speedMultiplier");
			if (val == null || val2 == null || val3 == null)
			{
				return null;
			}
			MethodDefinition val4 = new MethodDefinition("UpdateSpeed", (MethodAttributes)134, module.TypeSystem.Void);
			ILProcessor iLProcessor = val4.Body.GetILProcessor();
			Instruction val5 = iLProcessor.Create(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Brtrue_S, val5);
			iLProcessor.Emit(OpCodes.Pop);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val5);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val3);
			iLProcessor.Emit(val2.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ret);
			return val4;
		}

		private static MethodDefinition EmitConsumeProduct(ModuleDefinition module, TypeDefinition behaviour)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0093: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = Shapes.Method(behaviour, "ConsumeProduct_Server", 2);
			if (val == null || val.IsStatic)
			{
				return null;
			}
			MethodDefinition val2 = new MethodDefinition("ConsumeProduct", (MethodAttributes)134, module.TypeSystem.Void);
			Enumerator<ParameterDefinition> enumerator = ((MethodReference)val).Parameters.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					ParameterDefinition current = enumerator.Current;
					((MethodReference)val2).Parameters.Add(new ParameterDefinition(((ParameterReference)current).Name, (ParameterAttributes)0, module.ImportReference(((ParameterReference)current).ParameterType)));
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			ILProcessor iLProcessor = val2.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val2).Parameters[0]);
			iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val2).Parameters[1]);
			iLProcessor.Emit(val.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Ret);
			return val2;
		}

		private static MethodDefinition EmitSetContactName(ModuleDefinition module, TypeDefinition conversation)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = Shapes.Getter(conversation, "_sender");
			MethodDefinition val2 = Shapes.Method(conversation, "set__sender", 1);
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				TypeReference returnType = ((MethodReference)val).ReturnType;
				obj = ((returnType != null) ? returnType.Resolve() : null);
			}
			TypeDefinition val3 = (TypeDefinition)obj;
			MethodDefinition val4 = Shapes.Method(val3, "set__name", 1);
			if (val == null || val2 == null || val4 == null)
			{
				return null;
			}
			MethodDefinition val5 = new MethodDefinition("set_contactName", (MethodAttributes)2182, module.TypeSystem.Void);
			ParameterDefinition val6 = new ParameterDefinition("value", (ParameterAttributes)0, module.TypeSystem.String);
			((MethodReference)val5).Parameters.Add(val6);
			VariableDefinition val7 = new VariableDefinition(module.ImportReference(((MethodReference)val).ReturnType));
			val5.Body.Variables.Add(val7);
			val5.Body.InitLocals = true;
			ILProcessor iLProcessor = val5.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Stloc, val7);
			iLProcessor.Emit(((TypeReference)val3).IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Ldarg, val6);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val4);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(conversation, val5);
		}

		internal static MethodDefinition AvatarOf(TypeDefinition animation, out TypeDefinition avatar)
		{
			MethodDefinition val = Shapes.Getter(animation, "avatar");
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				TypeReference returnType = ((MethodReference)val).ReturnType;
				obj = ((returnType != null) ? returnType.Resolve() : null);
			}
			avatar = (TypeDefinition)obj;
			return val;
		}

		private static MethodDefinition EmitIsAvatarCulled(ModuleDefinition module, TypeDefinition animation)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition avatar;
			MethodDefinition val = AvatarOf(animation, out avatar);
			MethodDefinition val2 = Shapes.Getter(avatar, "IsCulled");
			if (val == null || val2 == null)
			{
				return null;
			}
			MethodDefinition val3 = new MethodDefinition("get_IsAvatarCulled", (MethodAttributes)2182, module.TypeSystem.Boolean);
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			Instruction val4 = iLProcessor.Create(OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Brtrue_S, val4);
			iLProcessor.Emit(OpCodes.Pop);
			iLProcessor.Emit(OpCodes.Ldc_I4_0);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val4);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(animation, val3);
		}

		private static MethodDefinition EmitSetVisibleToLocalPlayer(ModuleDefinition module, TypeDefinition player)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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)
			//IL_00d6: Expected O, but got Unknown
			MethodDefinition val = Shapes.Method(player, "set_avatarVisibleToLocalPlayer", 1);
			MethodDefinition val2 = Shapes.Method(player, "SetThirdPersonMeshesVisibility", 1);
			if (val == null || val2 == null || val.IsStatic || val2.IsStatic)
			{
				return null;
			}
			MethodDefinition val3 = new MethodDefinition("SetVisibleToLocalPlayer", (MethodAttributes)134, module.TypeSystem.Void);
			((MethodReference)val3).Parameters.Add(new ParameterDefinition("vis", (ParameterAttributes)0, module.TypeSystem.Boolean));
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Ldarg_1);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Ldarg_1);
			iLProcessor.Emit(val2.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Ret);
			return val3;
		}

		private static MethodDefinition EmitRequestPlayerData(ModuleDefinition module, TypeDefinition player)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			MethodDefinition val = Shapes.Method(player, "RequestPlayerData_Server", 2);
			TypeReference val2 = TypeIn(module, "Il2CppFishNet.Runtime", "Il2CppFishNet", "InstanceFinder");
			if (val == null || val.IsStatic || val2 == null)
			{
				return null;
			}
			MethodReference val3 = new MethodReference("get_IsHost", module.TypeSystem.Boolean, val2);
			MethodDefinition val4 = new MethodDefinition("RequestPlayerData", (MethodAttributes)134, module.TypeSystem.Void);
			((MethodReference)val4).Parameters.Add(new ParameterDefinition("playerCode", (ParameterAttributes)0, module.TypeSystem.String));
			ILProcessor iLProcessor = val4.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Ldarg_1);
			iLProcessor.Emit(OpCodes.Call, val3);
			iLProcessor.Emit(val.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, (MethodReference)(object)val);
			iLProcessor.Emit(OpCodes.Ret);
			return val4;
		}

		private static MethodDefinition EmitGenericDialogue(ModuleDefinition module, TypeDefinition controller)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			MethodDefinition val = Shapes.Getter(controller, "_genericConversation");
			if (val == null || val.IsStatic)
			{
				return null;
			}
			TypeDefinition val2 = ShadowTypes.Shadowing(module, ((MethodReference)val).ReturnType);
			if (val2 == null)
			{
				return null;
			}
			MethodDefinition val3 = new MethodDefinition("get_GenericDialogue", (MethodAttributes)2182, (TypeReference)(object)val2);
			ILProcessor iLProcessor = val3.Body.GetILProcessor();
			iLProcessor.Emit(OpCodes.Ldarg_0);
			iLProcessor.Emit(OpCodes.Call, (MethodReference)(object)val);
			if (!ShadowTypes.EmitRewrap(module, iLProcessor, val2, out var _))
			{
				return null;
			}
			return AsProperty(controller, val3);
		}

		private static MethodDefinition EmitEquippedGrabber(ModuleDefinition module, TypeDefinition grabber, string name, bool asFlag)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_010d: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			TypeDefinition type = module.GetType("Il2CppScheduleOne.PlayerScripts.PlayerInventory");
			TypeDefinition type2 = module.GetType("Il2CppScheduleOne.DevUtilities.PlayerSingleton`1");
			MethodDefinition val = Shapes.Method(type2, "get_Instance", 0);
			MethodDefinition val2 = Shapes.Getter(type, "isAnythingEquipped");
			MethodDefinition val3 = Shapes.Getter(type, "Equippable");
			MethodReference val4 = Shapes.GenericUp(module, grabber, "TryCast", (TypeReference)(object)grabber);
			if (val == null || !val.IsStatic || val2 == null || val3 == null || val4 == null)
			{
				return null;
			}
			GenericInstanceType val5 = new GenericInstanceType(module.ImportReference((TypeReference)(object)type2));
			val5.GenericArguments.Add(module.ImportReference((TypeReference)(object)type));
			MethodDefinition val6 = new MethodDefinition(name, (MethodAttributes)2198, (TypeReference)(asFlag ? ((object)module.TypeSystem.Boolean) : ((object)grabber)));
			val6.Body.InitLocals = true;
			VariableDefinition val7 = new VariableDefinition((TypeReference)(object)type);
			VariableDefinition val8 = new VariableDefinition(module.ImportReference(((MethodReference)val3).ReturnType));
			val6.Body.Variables.Add(val7);
			val6.Body.Variables.Add(val8);
			ILProcessor iLProcessor = val6.Body.GetILProcessor();
			Instruction val9 = iLProcessor.Create(asFlag ? OpCodes.Ldc_I4_0 : OpCodes.Ldnull);
			iLProcessor.Emit(OpCodes.Call, Shapes.Against(module, val, (TypeReference)(object)val5));
			iLProcessor.Emit(OpCodes.Stloc, val7);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Brfalse, val9);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Callvirt, (MethodReference)(object)val2);
			iLProcessor.Emit(OpCodes.Brfalse, val9);
			iLProcessor.Emit(OpCodes.Ldloc, val7);
			iLProcessor.Emit(OpCodes.Callvirt, (MethodReference)(object)val3);
			iLProcessor.Emit(OpCodes.Stloc, val8);
			iLProcessor.Emit(OpCodes.Ldloc, val8);
			iLProcessor.Emit(OpCodes.Brfalse, val9);
			iLProcessor.Emit(OpCodes.Ldloc, val8);
			iLProcessor.Emit(OpCodes.Callvirt, val4);
			if (asFlag)
			{
				iLProcessor.Emit(OpCodes.Ldnull);
				iLProcessor.Emit(OpCodes.Cgt_Un);
			}
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val9);
			iLProcessor.Emit(OpCodes.Ret);
			return AsProperty(grabber, val6);
		}

		private static MethodDefinition EmitSetPhysicsActive(ModuleDefinition module, TypeDefinition trash)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			MethodDefinition val = Shapes.Getter(trash, "_rigidbody");
			object type;
			if (val == null)
			{
				type = null;
			}
			else
			{
				TypeReference returnType = ((MethodReference)val).ReturnType;
				type = ((returnType != null) ? returnType.Resolve() : null);
			}
			MethodDefini