Decompiled source of Aetherial Endeavors Fixes v0.1.28

patchers/ValCoopCompatibility.Patcher.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using BepInEx;
using BepInEx.Logging;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;

[assembly: AssemblyTitle("Aetherial Endeavors Fixes")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyDescription("Verified startup repairs for the Aetherial Endeavors modpack.")]
[assembly: AssemblyFileVersion("0.1.26.0")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.1.26.0")]
namespace ValCoopCompatibility;

public static class AssemblyRepairs
{
	public static string[] ReferenceDirectories = new string[0];

	public static string[] ProfileReferenceDirectories = new string[0];

	public static byte[] Repair(byte[] source, string repairId)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Expected O, but got Unknown
		DefaultAssemblyResolver val = new DefaultAssemblyResolver();
		try
		{
			using MemoryStream memoryStream = new MemoryStream(source);
			foreach (string item in ReferenceDirectories.Concat(ProfileReferenceDirectories).Distinct())
			{
				((BaseAssemblyResolver)val).AddSearchDirectory(item);
			}
			ReaderParameters val2 = new ReaderParameters();
			val2.AssemblyResolver = (IAssemblyResolver)(object)val;
			AssemblyDefinition val3 = AssemblyDefinition.ReadAssembly((Stream)memoryStream, val2);
			try
			{
				switch (repairId)
				{
				case "customattributes-leech":
					RepairLeech(val3.MainModule);
					break;
				case "dragonknight-helper":
					if (!((IEnumerable<MethodDefinition>)FindType(val3.MainModule, "LastStand.LastStandEffect").Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "ValCoop_MakeStatusEffectPrefab"))
					{
						RepairDragonKnight(val3.MainModule);
					}
					if (((IEnumerable<Instruction>)((IEnumerable<MethodDefinition>)FindType(val3.MainModule, "LastStand.LastStandEffect").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "OnPacksLoaded").Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "LastStandEffect"))
					{
						ExtraRepairs.DragonIcon(val3.MainModule);
					}
					break;
				case "skiplogos-field":
					RepairSkipLogos(val3.MainModule);
					break;
				case "extended-event-log":
					ExtraRepairs.ExtendedEffects(val3.MainModule);
					break;
				case "npc-loot-iteration":
					ExtraRepairs.NpcLoot(val3.MainModule);
					break;
				case "sideloader-content":
					ExtraRepairs.SideLoader(val3.MainModule);
					break;
				case "vendavel-after-load":
					ExtraRepairs.VendavelAfterLoad(val3.MainModule);
					break;
				case "communicator-optional-overrides":
					ExtraRepairs.OptionalOverrides(val3.MainModule);
					break;
				case "enchantments-viewer-descriptions":
					Repairs015.Viewer(val3.MainModule);
					break;
				default:
					if (repairId.StartsWith("deferred-runic-"))
					{
						Repairs015.DeferredRunicVisuals(val3.MainModule);
						break;
					}
					switch (repairId)
					{
					case "crusader-effect-name":
						Repairs015.EffectName(val3.MainModule, "MakeOnConsecrationAllyPrefab");
						break;
					case "relic-effect-name":
						Repairs015.EffectName(val3.MainModule, "MakeCurseOfVulnrability");
						break;
					case "martial-owner":
						Repairs016.MartialOwner(val3.MainModule);
						break;
					case "banker-collision":
						if (!((IEnumerable<TypeDefinition>)val3.MainModule.Types).Any((TypeDefinition t) => ((MemberReference)t).FullName == "AetherialInjected.Bank016"))
						{
							Repairs016.Bank(val3.MainModule);
						}
						Repairs021.BankDialogue(val3.MainModule);
						break;
					case "flame-anor-tag":
						Repairs016.FlameTag(val3.MainModule);
						break;
					case "base-damage-preview":
						Repairs019.BaseDamage(val3.MainModule);
						break;
					case "champions-vigil-effect":
						Repairs020.ChampionsVigil(val3.MainModule);
						break;
					case "shinobi-cooldown-owner":
						Repairs022.ShinobiCooldownOwner(val3.MainModule);
						break;
					default:
						throw new InvalidOperationException("Unknown assembly repair: " + repairId);
					}
					break;
				}
				using MemoryStream memoryStream2 = new MemoryStream();
				WriterParameters val4 = new WriterParameters();
				val4.Timestamp = BitConverter.ToUInt32(source, BitConverter.ToInt32(source, 60) + 8);
				val3.Write((Stream)memoryStream2, val4);
				return memoryStream2.ToArray();
			}
			finally
			{
				((IDisposable)val3)?.Dispose();
			}
		}
		finally
		{
			((IDisposable)val)?.Dispose();
		}
	}

	private static TypeDefinition FindType(ModuleDefinition module, string name)
	{
		TypeDefinition[] array = (from t in AllTypes((IEnumerable<TypeDefinition>)module.Types)
			where ((MemberReference)t).FullName == name
			select t).ToArray();
		Require(array.Length == 1, "Expected one type: " + name);
		return array[0];
	}

	private static IEnumerable<TypeDefinition> AllTypes(IEnumerable<TypeDefinition> types)
	{
		foreach (TypeDefinition type in types)
		{
			yield return type;
			foreach (TypeDefinition item in AllTypes((IEnumerable<TypeDefinition>)type.NestedTypes))
			{
				yield return item;
			}
		}
	}

	public static void Require(bool condition, string message)
	{
		if (!condition)
		{
			throw new InvalidOperationException(message);
		}
	}

	public static void WidenBranches(MethodDefinition method)
	{
		//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)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: 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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected I4, but got Unknown
		//IL_007b: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Invalid comparison between Unknown and I4
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		Enumerator<Instruction> enumerator = method.Body.Instructions.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				Instruction current = enumerator.Current;
				OpCode opCode = current.OpCode;
				Code code = ((OpCode)(ref opCode)).Code;
				switch (code - 42)
				{
				case 0:
					current.OpCode = OpCodes.Br;
					continue;
				case 2:
					current.OpCode = OpCodes.Brtrue;
					continue;
				case 1:
					current.OpCode = OpCodes.Brfalse;
					continue;
				case 3:
					current.OpCode = OpCodes.Beq;
					continue;
				case 8:
					current.OpCode = OpCodes.Bne_Un;
					continue;
				case 4:
					current.OpCode = OpCodes.Bge;
					continue;
				case 9:
					current.OpCode = OpCodes.Bge_Un;
					continue;
				case 5:
					current.OpCode = OpCodes.Bgt;
					continue;
				case 10:
					current.OpCode = OpCodes.Bgt_Un;
					continue;
				case 6:
					current.OpCode = OpCodes.Ble;
					continue;
				case 11:
					current.OpCode = OpCodes.Ble_Un;
					continue;
				case 7:
					current.OpCode = OpCodes.Blt;
					continue;
				case 12:
					current.OpCode = OpCodes.Blt_Un;
					continue;
				}
				if ((int)code == 188)
				{
					current.OpCode = OpCodes.Leave;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private static void CopyBody(MethodDefinition from, MethodDefinition to)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		//IL_006e: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_00cf: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Expected O, but got Unknown
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Expected O, but got Unknown
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		Require(from.Body.ExceptionHandlers.Count == 0, "Unexpected exception handler in template.");
		MethodBody val = (to.Body = new MethodBody(to));
		val.InitLocals = from.Body.InitLocals;
		val.MaxStackSize = Math.Max(from.Body.MaxStackSize, 8);
		Dictionary<VariableDefinition, VariableDefinition> dictionary = new Dictionary<VariableDefinition, VariableDefinition>();
		Enumerator<VariableDefinition> enumerator = from.Body.Variables.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				VariableDefinition current = enumerator.Current;
				VariableDefinition val3 = new VariableDefinition(((VariableReference)current).VariableType);
				dictionary.Add(current, val3);
				val.Variables.Add(val3);
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		Dictionary<Instruction, Instruction> instructions = new Dictionary<Instruction, Instruction>();
		Enumerator<Instruction> enumerator2 = from.Body.Instructions.GetEnumerator();
		try
		{
			while (enumerator2.MoveNext())
			{
				Instruction current2 = enumerator2.Current;
				Instruction val4 = Instruction.Create(OpCodes.Nop);
				val4.OpCode = current2.OpCode;
				instructions.Add(current2, val4);
				val.Instructions.Add(val4);
			}
		}
		finally
		{
			((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
		}
		Enumerator<Instruction> enumerator3 = from.Body.Instructions.GetEnumerator();
		try
		{
			while (enumerator3.MoveNext())
			{
				Instruction current3 = enumerator3.Current;
				object obj = current3.Operand;
				if (obj is Instruction)
				{
					obj = instructions[(Instruction)obj];
				}
				else if (obj is Instruction[])
				{
					obj = ((Instruction[])obj).Select((Instruction i) => instructions[i]).ToArray();
				}
				else if (obj is VariableDefinition)
				{
					obj = dictionary[(VariableDefinition)obj];
				}
				else if (obj is ParameterDefinition)
				{
					obj = ((MethodReference)to).Parameters[((ParameterReference)(ParameterDefinition)obj).Index];
				}
				instructions[current3].Operand = obj;
			}
		}
		finally
		{
			((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
		}
		WidenBranches(to);
	}

	private static void RepairLeech(ModuleDefinition module)
	{
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Expected O, but got Unknown
		//IL_019c: 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_01b4: Expected O, but got Unknown
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Expected O, but got Unknown
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Expected O, but got Unknown
		//IL_0374: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0407: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_0425: Unknown result type (might be due to invalid IL or missing references)
		//IL_043c: Unknown result type (might be due to invalid IL or missing references)
		//IL_044b: Unknown result type (might be due to invalid IL or missing references)
		//IL_045c: Unknown result type (might be due to invalid IL or missing references)
		//IL_046b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0483: Unknown result type (might be due to invalid IL or missing references)
		//IL_0494: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_052e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0538: Expected O, but got Unknown
		//IL_054d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0559: Unknown result type (might be due to invalid IL or missing references)
		//IL_0565: Unknown result type (might be due to invalid IL or missing references)
		//IL_0571: Unknown result type (might be due to invalid IL or missing references)
		//IL_057f: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = FindType(module, "CustomAttributes.CustomAttributesBase");
		TypeDefinition val2 = FindType(module, "CustomAttributes.CustomAttributeComponent");
		TypeDefinition val3 = FindType(module, "CustomAttributes.CustomAttributeManager/Character_ReceiveHit");
		FieldDefinition val4 = ((IEnumerable<FieldDefinition>)val.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "OnCharacterCritEvent");
		FieldDefinition val5 = ((IEnumerable<FieldDefinition>)val.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "Instance");
		Require(!((IEnumerable<FieldDefinition>)val.Fields).Any((FieldDefinition f) => ((MemberReference)f).Name == "OnCharacterLeechEvent"), "Leech event already exists.");
		GenericInstanceType eventType = default(GenericInstanceType);
		ref GenericInstanceType reference = ref eventType;
		TypeReference fieldType = ((FieldReference)val4).FieldType;
		reference = (GenericInstanceType)(object)((fieldType is GenericInstanceType) ? fieldType : null);
		Require(eventType != null && eventType.GenericArguments.Count == 3 && ((MemberReference)eventType.GenericArguments[2]).FullName == "System.Single", "Unexpected event signature.");
		FieldDefinition val6 = new FieldDefinition("OnCharacterLeechEvent", (FieldAttributes)6, (TypeReference)(object)eventType);
		val.Fields.Add(val6);
		MethodDefinition doLeech = ((IEnumerable<MethodDefinition>)val2.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "DoLeech" && ((MethodReference)m).Parameters.Count == 1);
		Require(((MemberReference)((ParameterReference)((MethodReference)doLeech).Parameters[0]).ParameterType).FullName == "System.Single", "Unexpected DoLeech signature.");
		MethodDefinition val7 = new MethodDefinition("ValCoop_DoLeechWithTarget", doLeech.Attributes, ((MethodReference)doLeech).ReturnType);
		((MethodReference)val7).Parameters.Add(new ParameterDefinition("totalDamage", (ParameterAttributes)0, module.TypeSystem.Single));
		((MethodReference)val7).Parameters.Add(new ParameterDefinition("enemy", (ParameterAttributes)0, eventType.GenericArguments[1]));
		val2.Methods.Add(val7);
		CopyBody(doLeech, val7);
		Require(val7.Body.Variables.Count == 4 && ((MemberReference)((VariableReference)val7.Body.Variables[1]).VariableType).FullName == "System.Single", "Leech amount local changed.");
		MethodDefinition val8 = ((IEnumerable<MethodDefinition>)val2.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "get_parentPlayer");
		MethodDefinition val9 = ((IEnumerable<MethodDefinition>)val3.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Prefix");
		MethodReference[] array = (from m in ((IEnumerable<Instruction>)val9.Body.Instructions).Select(delegate(Instruction i)
			{
				object operand = i.Operand;
				return (MethodReference)((operand is MethodReference) ? operand : null);
			})
			where m != null && ((MemberReference)m).Name == "Invoke" && ((MemberReference)((MemberReference)m).DeclaringType).FullName == ((MemberReference)eventType).FullName
			select m).ToArray();
		Require(array.Length > 0, "Cannot reuse event Invoke signature.");
		Instruction[] array2 = ((IEnumerable<Instruction>)val7.Body.Instructions).Where(delegate(Instruction i)
		{
			object operand = i.Operand;
			MethodReference val16 = (MethodReference)((operand is MethodReference) ? operand : null);
			return val16 != null && ((MemberReference)((MemberReference)val16).DeclaringType).FullName == "CharacterStats" && (((MemberReference)val16).Name == "AffectStamina" || ((MemberReference)val16).Name == "RestaureMana");
		}).ToArray();
		Require(array2.Length == 2, "Expected two leech recovery branches.");
		ILProcessor iLProcessor = val7.Body.GetILProcessor();
		Instruction[] array3 = array2;
		foreach (Instruction val10 in array3)
		{
			Instruction val11 = Instruction.Create(OpCodes.Nop);
			Instruction val12 = Instruction.Create(OpCodes.Ldfld, (FieldReference)(object)val6);
			Instruction val13 = Instruction.Create(OpCodes.Ldarg_0);
			Instruction[] array4 = (Instruction[])(object)new Instruction[19]
			{
				Instruction.Create(OpCodes.Ldloc, val7.Body.Variables[1]),
				Instruction.Create(OpCodes.Ldc_R4, 0f),
				Instruction.Create(OpCodes.Ble_Un, val11),
				Instruction.Create(OpCodes.Ldsfld, (FieldReference)(object)val5),
				Instruction.Create(OpCodes.Dup),
				Instruction.Create(OpCodes.Brtrue, val12),
				Instruction.Create(OpCodes.Pop),
				Instruction.Create(OpCodes.Br, val11),
				val12,
				Instruction.Create(OpCodes.Dup),
				Instruction.Create(OpCodes.Brtrue, val13),
				Instruction.Create(OpCodes.Pop),
				Instruction.Create(OpCodes.Br, val11),
				val13,
				Instruction.Create(OpCodes.Call, (MethodReference)(object)val8),
				Instruction.Create(OpCodes.Ldarg_2),
				Instruction.Create(OpCodes.Ldloc, val7.Body.Variables[1]),
				Instruction.Create(OpCodes.Callvirt, array[0]),
				val11
			};
			Instruction val14 = val10;
			Instruction[] array5 = array4;
			foreach (Instruction val15 in array5)
			{
				iLProcessor.InsertAfter(val14, val15);
				val14 = val15;
			}
		}
		doLeech.Body = new MethodBody(doLeech);
		ILProcessor iLProcessor2 = doLeech.Body.GetILProcessor();
		iLProcessor2.Emit(OpCodes.Ldarg_0);
		iLProcessor2.Emit(OpCodes.Ldarg_1);
		iLProcessor2.Emit(OpCodes.Ldnull);
		iLProcessor2.Emit(OpCodes.Call, (MethodReference)(object)val7);
		iLProcessor2.Emit(OpCodes.Ret);
		Instruction[] array6 = ((IEnumerable<Instruction>)val9.Body.Instructions).Where(delegate(Instruction i)
		{
			object operand = i.Operand;
			MethodReference val16 = (MethodReference)((operand is MethodReference) ? operand : null);
			return val16 != null && ((MemberReference)val16).FullName == ((MemberReference)doLeech).FullName;
		}).ToArray();
		Require(array6.Length == 1 && ((MemberReference)((ParameterReference)((MethodReference)val9).Parameters[0]).ParameterType).FullName == "Character", "Expected one player-hit leech call.");
		val9.Body.GetILProcessor().InsertBefore(array6[0], Instruction.Create(OpCodes.Ldarg, ((MethodReference)val9).Parameters[0]));
		array6[0].Operand = val7;
		WidenBranches(val9);
	}

	private static void RepairDragonKnight(ModuleDefinition module)
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Expected O, but got Unknown
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Expected O, but got Unknown
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: 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_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = FindType(module, "LastStand.LastStandEffect");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "MakeLastStandDamagePrefab");
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "MakeStatusEffectPrefab");
		MethodReference val4 = (MethodReference)val3.Operand;
		Require(val4.Parameters.Count == 13 && ((MemberReference)val4.ReturnType).FullName == "StatusEffect", "Unexpected helper call.");
		MethodDefinition val5 = new MethodDefinition("ValCoop_MakeStatusEffectPrefab", (MethodAttributes)17, val4.ReturnType);
		Enumerator<ParameterDefinition> enumerator = val4.Parameters.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				ParameterDefinition current = enumerator.Current;
				((MethodReference)val5).Parameters.Add(new ParameterDefinition(((ParameterReference)current).Name, (ParameterAttributes)0, ((ParameterReference)current).ParameterType));
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		val.Methods.Add(val5);
		val5.Body.InitLocals = true;
		VariableDefinition val6 = new VariableDefinition(module.ImportReference(typeof(MethodInfo)));
		val5.Body.Variables.Add(val6);
		ILProcessor iLProcessor = val5.Body.GetILProcessor();
		Instruction val7 = Instruction.Create(OpCodes.Nop);
		Instruction val8 = Instruction.Create(OpCodes.Nop);
		EmitFindHelper(module, iLProcessor, val4, newSignature: true);
		iLProcessor.Emit(OpCodes.Stloc, val6);
		iLProcessor.Emit(OpCodes.Ldloc, val6);
		iLProcessor.Emit(OpCodes.Brfalse, val7);
		EmitInvokeHelper(module, iLProcessor, val5, val6, newSignature: true);
		iLProcessor.Append(val7);
		EmitFindHelper(module, iLProcessor, val4, newSignature: false);
		iLProcessor.Emit(OpCodes.Stloc, val6);
		iLProcessor.Emit(OpCodes.Ldloc, val6);
		iLProcessor.Emit(OpCodes.Brfalse, val8);
		EmitInvokeHelper(module, iLProcessor, val5, val6, newSignature: false);
		iLProcessor.Append(val8);
		iLProcessor.Emit(OpCodes.Ldstr, "ValCoop: TinyHelper exposes neither supported status-effect factory signature.");
		iLProcessor.Emit(OpCodes.Newobj, module.ImportReference((MethodBase)typeof(MissingMethodException).GetConstructor(new Type[1] { typeof(string) })));
		iLProcessor.Emit(OpCodes.Throw);
		val3.Operand = val5;
	}

	private static void EmitFindHelper(ModuleDefinition module, ILProcessor il, MethodReference original, bool newSignature)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: 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_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
		MethodReference val = module.ImportReference((MethodBase)typeof(Type).GetMethod("GetTypeFromHandle"));
		il.Emit(OpCodes.Ldtoken, ((MemberReference)original).DeclaringType);
		il.Emit(OpCodes.Call, val);
		il.Emit(OpCodes.Ldstr, "MakeStatusEffectPrefab");
		il.Emit(OpCodes.Ldc_I4, original.Parameters.Count + (newSignature ? 1 : 0));
		il.Emit(OpCodes.Newarr, module.ImportReference(typeof(Type)));
		for (int i = 0; i < original.Parameters.Count + (newSignature ? 1 : 0); i++)
		{
			il.Emit(OpCodes.Dup);
			il.Emit(OpCodes.Ldc_I4, i);
			il.Emit(OpCodes.Ldtoken, (i < original.Parameters.Count) ? ((ParameterReference)original.Parameters[i]).ParameterType : module.TypeSystem.String);
			il.Emit(OpCodes.Call, val);
			il.Emit(OpCodes.Stelem_Ref);
		}
		il.Emit(OpCodes.Callvirt, module.ImportReference((MethodBase)typeof(Type).GetMethod("GetMethod", new Type[2]
		{
			typeof(string),
			typeof(Type[])
		})));
	}

	private static void EmitInvokeHelper(ModuleDefinition module, ILProcessor il, MethodDefinition bridge, VariableDefinition info, bool newSignature)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		il.Emit(OpCodes.Ldloc, info);
		il.Emit(OpCodes.Ldnull);
		il.Emit(OpCodes.Ldc_I4, ((MethodReference)bridge).Parameters.Count + (newSignature ? 1 : 0));
		il.Emit(OpCodes.Newarr, module.TypeSystem.Object);
		for (int i = 0; i < ((MethodReference)bridge).Parameters.Count; i++)
		{
			ParameterDefinition val = ((MethodReference)bridge).Parameters[i];
			il.Emit(OpCodes.Dup);
			il.Emit(OpCodes.Ldc_I4, i);
			il.Emit(OpCodes.Ldarg, val);
			if (((ParameterReference)val).ParameterType.IsValueType)
			{
				il.Emit(OpCodes.Box, ((ParameterReference)val).ParameterType);
			}
			il.Emit(OpCodes.Stelem_Ref);
		}
		il.Emit(OpCodes.Callvirt, module.ImportReference((MethodBase)typeof(MethodBase).GetMethod("Invoke", new Type[2]
		{
			typeof(object),
			typeof(object[])
		})));
		il.Emit(OpCodes.Castclass, ((MethodReference)bridge).ReturnType);
		il.Emit(OpCodes.Ret);
	}

	private static void RepairSkipLogos(ModuleDefinition module)
	{
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: 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_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = FindType(module, "SkipLogos.SkipLogos");
		FieldDefinition field = ((IEnumerable<FieldDefinition>)val.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "fieldStartupVideoDone");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Awake");
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single(delegate(Instruction i)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			OpCode opCode = i.OpCode;
			return (int)((OpCode)(ref opCode)).Code == 37 && i.Previous.Operand is MethodReference && ((MemberReference)(MethodReference)i.Previous.Operand).Name == "GetField";
		});
		val3.OpCode = OpCodes.Stsfld;
		val3.Operand = field;
		MethodDefinition[] array = (from t in (IEnumerable<TypeDefinition>)val.NestedTypes
			where ((MemberReference)t).Name == "StartupVideo_Awake" || ((MemberReference)t).Name == "StartupVideo_Start"
			select ((IEnumerable<MethodDefinition>)t.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Patch")).ToArray();
		Require(array.Length == 2, "Expected two startup hooks.");
		MethodDefinition[] array2 = array;
		foreach (MethodDefinition val4 in array2)
		{
			Instruction val5 = ((IEnumerable<Instruction>)val4.Body.Instructions).Single(delegate(Instruction i)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Invalid comparison between Unknown and I4
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				OpCode opCode = i.OpCode;
				return (int)((OpCode)(ref opCode)).Code == 123 && ((MemberReference)(FieldReference)i.Operand).Name == ((MemberReference)field).Name;
			});
			ILProcessor iLProcessor = val4.Body.GetILProcessor();
			Instruction next = val5.Next;
			Instruction val6 = val5;
			Instruction[] array3 = (Instruction[])(object)new Instruction[4]
			{
				Instruction.Create(OpCodes.Dup),
				Instruction.Create(OpCodes.Brtrue, next),
				Instruction.Create(OpCodes.Pop),
				Instruction.Create(OpCodes.Ret)
			};
			foreach (Instruction val7 in array3)
			{
				iLProcessor.InsertAfter(val6, val7);
				val6 = val7;
			}
			WidenBranches(val4);
		}
	}
}
public static class ExtraRepairs
{
	private static void Require(bool ok, string message)
	{
		AssemblyRepairs.Require(ok, message);
	}

	public static void VendavelAfterLoad(ModuleDefinition module)
	{
		//IL_00b4: 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_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: 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)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		MethodDefinition val = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "QuestsOfAurai.Vendavel.VendavelQuest").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "AfterLoad");
		MethodReference val2 = module.GetMemberReferences().OfType<MethodReference>().First((MethodReference m) => ((MemberReference)((MemberReference)m).DeclaringType).FullName == "UnityEngine.Object" && ((MemberReference)m).Name == "op_Implicit");
		Instruction[] array = val.Body.Instructions.ToArray();
		Instruction[] array2 = array;
		foreach (Instruction val3 in array2)
		{
			object operand = val3.Operand;
			MethodReference val4 = (MethodReference)((operand is MethodReference) ? operand : null);
			bool flag = false;
			bool flag2 = false;
			if (val3.OpCode == OpCodes.Ldsfld && ((MemberReference)((MemberReference)(FieldReference)val3.Operand).DeclaringType).Name == "CharacterManager")
			{
				flag2 = true;
				flag = true;
			}
			if (val4 != null && (((MemberReference)val4).Name == "GetWorldHostCharacter" || ((MemberReference)val4).Name == "GetComponent"))
			{
				flag2 = true;
				flag = true;
			}
			if (val4 != null && (((MemberReference)val4).Name == "get_Inventory" || ((MemberReference)val4).Name == "get_QuestKnowledge"))
			{
				flag2 = true;
			}
			if (val3.OpCode == OpCodes.Isinst && ((MemberReference)(TypeReference)val3.Operand).Name == "Quest")
			{
				flag2 = true;
				flag = true;
			}
			if (!flag2)
			{
				continue;
			}
			Instruction next = val3.Next;
			ILProcessor iLProcessor = val.Body.GetILProcessor();
			Instruction val5 = val3;
			List<Instruction> list = new List<Instruction>();
			list.Add(Instruction.Create(OpCodes.Dup));
			List<Instruction> list2 = list;
			if (flag)
			{
				list2.Add(Instruction.Create(OpCodes.Call, val2));
			}
			list2.Add(Instruction.Create(OpCodes.Brtrue, next));
			list2.Add(Instruction.Create(OpCodes.Pop));
			list2.Add(Instruction.Create(OpCodes.Ret));
			foreach (Instruction item in list2)
			{
				iLProcessor.InsertAfter(val5, item);
				val5 = item;
			}
		}
		AssemblyRepairs.WidenBranches(val);
	}

	public static void OptionalOverrides(ModuleDefinition module)
	{
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "OutwardModsCommunicator.OMC");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)val.NestedTypes).Single((TypeDefinition t) => ((MemberReference)t).Name == "ResourcesPrefabManager_Load").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Postfix");
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "GetPlayerOverrideLocation");
		Instruction next = val3.Next.Next.Next;
		Require(next.Operand is MethodReference && ((MemberReference)(MethodReference)next.Operand).Name == "IsNullOrEmpty" && next.Next.OpCode == OpCodes.Brtrue_S, "Unexpected optional override check");
		next.Operand = module.ImportReference((MethodBase)typeof(File).GetMethod("Exists", new Type[1] { typeof(string) }));
		next.Next.OpCode = OpCodes.Brfalse;
		AssemblyRepairs.WidenBranches(val2);
	}

	public static void DragonIcon(ModuleDefinition module)
	{
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "LastStand.LastStandEffect");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "OnPacksLoaded");
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "LastStandEffect");
		val3.Operand = "SaintDE-DragonKnight";
	}

	public static void ExtendedEffects(ModuleDefinition module)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader_ExtendedEffects.Containers.Triggers.TriggeredEffect`1");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ActivateLocally");
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.OpCode == OpCodes.Ldstr && (string)i.Operand == "Event already registered");
		Require(val3.Previous.OpCode == OpCodes.Call && val3.Next.OpCode == OpCodes.Callvirt, "Unexpected duplicate-registration branch");
		Instruction[] array = (Instruction[])(object)new Instruction[3] { val3.Previous, val3, val3.Next };
		foreach (Instruction val4 in array)
		{
			val4.OpCode = OpCodes.Nop;
			val4.Operand = null;
		}
	}

	public static void NpcLoot(ModuleDefinition module)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: 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_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "JohBenjiNPCWeapons.JohBenjiNPCWeapons");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "SL_OnPacksLoaded");
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "get_Keys");
		TypeReference declaringType = ((MemberReference)(MethodReference)val3.Operand).DeclaringType;
		Require(declaringType is GenericInstanceType && ((MemberReference)declaringType).Name.StartsWith("Dictionary`"), "Unexpected loot dictionary type");
		Type typeFromHandle = typeof(Dictionary<, >);
		ConstructorInfo constructorInfo = typeFromHandle.GetConstructors().Single((ConstructorInfo c) => c.GetParameters().Length == 1 && c.GetParameters()[0].ParameterType.Name == "IDictionary`2");
		MethodReference val4 = module.ImportReference((MethodBase)constructorInfo);
		((MemberReference)val4).DeclaringType = declaringType;
		if (val3.Previous.OpCode != OpCodes.Newobj)
		{
			val2.Body.GetILProcessor().InsertBefore(val3, Instruction.Create(OpCodes.Newobj, val4));
		}
		AssemblyRepairs.WidenBranches(val2);
		string[] array = new string[2] { "BloodSpearPatch", "BloodSwordPatch" };
		foreach (string name in array)
		{
			Collection<TypeDefinition> types = module.Types;
			Func<TypeDefinition, bool> predicate = (TypeDefinition t) => ((MemberReference)t).Name == name;
			MethodDefinition val5 = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)types).Single(predicate).Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "PatchItem");
			Instruction val6 = ((IEnumerable<Instruction>)val5.Body.Instructions).Single((Instruction i) => i.Operand is GenericInstanceMethod && ((MemberReference)(GenericInstanceMethod)i.Operand).Name == "AddComponent" && ((MemberReference)((GenericInstanceMethod)i.Operand).GenericArguments[0]).Name == "ItemInteraction");
			VariableDefinition operand = ((IEnumerable<VariableDefinition>)val5.Body.Variables).Single((VariableDefinition v) => ((MemberReference)((VariableReference)v).VariableType).Name == "InteractionTake");
			Require(val6.Previous.OpCode == OpCodes.Ldloc_0, "Unexpected blood weapon interaction receiver");
			val6.Previous.OpCode = OpCodes.Ldloc;
			val6.Previous.Operand = operand;
			val6.OpCode = OpCodes.Nop;
			val6.Operand = null;
		}
		MethodDefinition val7 = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).Name == "DTAppend").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Apply");
		VariableDefinition val8 = ((IEnumerable<VariableDefinition>)val7.Body.Variables).Single((VariableDefinition v) => ((MemberReference)((VariableReference)v).VariableType).FullName == "Character");
		Instruction val9 = ((IEnumerable<Instruction>)val7.Body.Instructions).First((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "get_gameObject");
		Instruction val10 = ((IEnumerable<Instruction>)val7.Body.Instructions).Last((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "MoveNext");
		Instruction previous = val10.Previous;
		MethodReference val11 = module.GetMemberReferences().OfType<MethodReference>().First((MethodReference m) => ((MemberReference)((MemberReference)m).DeclaringType).FullName == "UnityEngine.Object" && ((MemberReference)m).Name == "op_Implicit");
		Instruction previous2 = val9.Previous;
		ILProcessor iLProcessor = val7.Body.GetILProcessor();
		iLProcessor.InsertBefore(previous2, Instruction.Create(OpCodes.Ldloc, val8));
		iLProcessor.InsertBefore(previous2, Instruction.Create(OpCodes.Call, val11));
		iLProcessor.InsertBefore(previous2, Instruction.Create(OpCodes.Brfalse, previous));
		AssemblyRepairs.WidenBranches(val7);
	}

	private static IEnumerable<TypeDefinition> Types(IEnumerable<TypeDefinition> types)
	{
		foreach (TypeDefinition t in types)
		{
			yield return t;
			foreach (TypeDefinition item in Types((IEnumerable<TypeDefinition>)t.NestedTypes))
			{
				yield return item;
			}
		}
	}

	private static TypeDefinition InjectSupport(ModuleDefinition target)
	{
		//IL_0127: 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_013e: Expected O, but got Unknown
		//IL_0165: 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_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Expected O, but got Unknown
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: 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_01f9: Expected O, but got Unknown
		//IL_0200: 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)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Expected O, but got Unknown
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Expected O, but got Unknown
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_037e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0385: Expected O, but got Unknown
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_0733: Unknown result type (might be due to invalid IL or missing references)
		//IL_0738: Unknown result type (might be due to invalid IL or missing references)
		//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0762: Unknown result type (might be due to invalid IL or missing references)
		//IL_0767: Unknown result type (might be due to invalid IL or missing references)
		//IL_0452: Unknown result type (might be due to invalid IL or missing references)
		//IL_0457: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0482: Unknown result type (might be due to invalid IL or missing references)
		//IL_048c: Expected O, but got Unknown
		//IL_0597: Unknown result type (might be due to invalid IL or missing references)
		//IL_059c: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e0: Expected O, but got Unknown
		//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05c6: Expected O, but got Unknown
		//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_07fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0515: Unknown result type (might be due to invalid IL or missing references)
		//IL_051f: Expected O, but got Unknown
		//IL_052f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0539: Expected O, but got Unknown
		//IL_0549: Unknown result type (might be due to invalid IL or missing references)
		//IL_0553: Expected O, but got Unknown
		//IL_084a: Unknown result type (might be due to invalid IL or missing references)
		//IL_084f: Unknown result type (might be due to invalid IL or missing references)
		//IL_08dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_08e6: Expected O, but got Unknown
		Dictionary<string, IMetadataScope> known = (from t in target.GetTypeReferences()
			group t by ((MemberReference)t).FullName).ToDictionary((IGrouping<string, TypeReference> g) => g.Key, (IGrouping<string, TypeReference> g) => g.First().Scope);
		foreach (TypeDefinition item in Types((IEnumerable<TypeDefinition>)target.Types))
		{
			known[((MemberReference)item).FullName] = (IMetadataScope)(object)target;
		}
		using Stream stream = typeof(ExtraRepairs).Assembly.GetManifestResourceStream("InjectionTemplate.dll");
		AssemblyDefinition val = AssemblyDefinition.ReadAssembly(stream);
		try
		{
			TypeDefinition val2 = ((IEnumerable<TypeDefinition>)val.MainModule.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "AetherialInjected.Support");
			TypeDefinition val3 = new TypeDefinition(((TypeReference)val2).Namespace, ((MemberReference)val2).Name, val2.Attributes, target.TypeSystem.Object);
			target.Types.Add(val3);
			known[((MemberReference)val3).FullName] = (IMetadataScope)(object)target;
			Enumerator<FieldDefinition> enumerator2 = val2.Fields.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					FieldDefinition current2 = enumerator2.Current;
					val3.Fields.Add(new FieldDefinition(((MemberReference)current2).Name, current2.Attributes, target.ImportReference(((FieldReference)current2).FieldType)));
				}
			}
			finally
			{
				((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<MethodDefinition> enumerator3 = val2.Methods.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					MethodDefinition current3 = enumerator3.Current;
					MethodDefinition val4 = new MethodDefinition(((MemberReference)current3).Name, current3.Attributes, target.ImportReference(((MethodReference)current3).ReturnType));
					Enumerator<ParameterDefinition> enumerator4 = ((MethodReference)current3).Parameters.GetEnumerator();
					try
					{
						while (enumerator4.MoveNext())
						{
							ParameterDefinition current4 = enumerator4.Current;
							((MethodReference)val4).Parameters.Add(new ParameterDefinition(((ParameterReference)current4).Name, current4.Attributes, target.ImportReference(((ParameterReference)current4).ParameterType)));
						}
					}
					finally
					{
						((IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose();
					}
					val3.Methods.Add(val4);
				}
			}
			finally
			{
				((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<MethodDefinition> enumerator5 = val2.Methods.GetEnumerator();
			try
			{
				while (enumerator5.MoveNext())
				{
					MethodDefinition oldMethod = enumerator5.Current;
					Collection<MethodDefinition> methods = val3.Methods;
					Func<MethodDefinition, bool> predicate = (MethodDefinition x) => ((MemberReference)x).Name == ((MemberReference)oldMethod).Name;
					MethodDefinition val5 = ((IEnumerable<MethodDefinition>)methods).Single(predicate);
					MethodBody val6 = new MethodBody(val5);
					val6.InitLocals = oldMethod.Body.InitLocals;
					val6.MaxStackSize = oldMethod.Body.MaxStackSize;
					val5.Body = val6;
					Dictionary<VariableDefinition, VariableDefinition> dictionary = new Dictionary<VariableDefinition, VariableDefinition>();
					Enumerator<VariableDefinition> enumerator6 = oldMethod.Body.Variables.GetEnumerator();
					try
					{
						while (enumerator6.MoveNext())
						{
							VariableDefinition current5 = enumerator6.Current;
							VariableDefinition val7 = (dictionary[current5] = new VariableDefinition(target.ImportReference(((VariableReference)current5).VariableType)));
							val5.Body.Variables.Add(val7);
						}
					}
					finally
					{
						((IDisposable)enumerator6/*cast due to .constrained prefix*/).Dispose();
					}
					Dictionary<Instruction, Instruction> ins = new Dictionary<Instruction, Instruction>();
					Enumerator<Instruction> enumerator7 = oldMethod.Body.Instructions.GetEnumerator();
					try
					{
						while (enumerator7.MoveNext())
						{
							Instruction current6 = enumerator7.Current;
							Instruction val9 = Instruction.Create(OpCodes.Nop);
							val9.OpCode = current6.OpCode;
							ins[current6] = val9;
							val5.Body.Instructions.Add(val9);
						}
					}
					finally
					{
						((IDisposable)enumerator7/*cast due to .constrained prefix*/).Dispose();
					}
					Enumerator<Instruction> enumerator8 = oldMethod.Body.Instructions.GetEnumerator();
					try
					{
						while (enumerator8.MoveNext())
						{
							Instruction current7 = enumerator8.Current;
							object obj = current7.Operand;
							if (obj is Instruction)
							{
								obj = ins[(Instruction)obj];
							}
							else if (obj is Instruction[])
							{
								obj = ((Instruction[])obj).Select((Instruction x) => ins[x]).ToArray();
							}
							else if (obj is VariableDefinition)
							{
								obj = dictionary[(VariableDefinition)obj];
							}
							else if (obj is ParameterDefinition)
							{
								obj = ((MethodReference)val5).Parameters[((ParameterReference)(ParameterDefinition)obj).Index];
							}
							else if (obj is MethodReference)
							{
								obj = target.ImportReference((MethodReference)obj);
							}
							else if (obj is FieldReference)
							{
								obj = target.ImportReference((FieldReference)obj);
							}
							else if (obj is TypeReference)
							{
								obj = target.ImportReference((TypeReference)obj);
							}
							ins[current7].Operand = obj;
						}
					}
					finally
					{
						((IDisposable)enumerator8/*cast due to .constrained prefix*/).Dispose();
					}
					Enumerator<ExceptionHandler> enumerator9 = oldMethod.Body.ExceptionHandlers.GetEnumerator();
					try
					{
						while (enumerator9.MoveNext())
						{
							ExceptionHandler current8 = enumerator9.Current;
							Collection<ExceptionHandler> exceptionHandlers = val5.Body.ExceptionHandlers;
							ExceptionHandler val10 = new ExceptionHandler(current8.HandlerType);
							val10.TryStart = ins[current8.TryStart];
							val10.TryEnd = ((current8.TryEnd == null) ? null : ins[current8.TryEnd]);
							val10.HandlerStart = ins[current8.HandlerStart];
							val10.HandlerEnd = ((current8.HandlerEnd == null) ? null : ins[current8.HandlerEnd]);
							val10.FilterStart = ((current8.FilterStart == null) ? null : ins[current8.FilterStart]);
							val10.CatchType = ((current8.CatchType == null) ? null : target.ImportReference(current8.CatchType));
							exceptionHandlers.Add(val10);
						}
					}
					finally
					{
						((IDisposable)enumerator9/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator5/*cast due to .constrained prefix*/).Dispose();
			}
			Action<TypeReference> map = null;
			map = delegate(TypeReference t)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				if (t != null && !(t is GenericParameter) && !(t is TypeDefinition))
				{
					GenericInstanceType val14 = (GenericInstanceType)(object)((t is GenericInstanceType) ? t : null);
					if (val14 != null)
					{
						Enumerator<TypeReference> enumerator16 = val14.GenericArguments.GetEnumerator();
						try
						{
							while (enumerator16.MoveNext())
							{
								TypeReference current15 = enumerator16.Current;
								map(current15);
							}
						}
						finally
						{
							((IDisposable)enumerator16/*cast due to .constrained prefix*/).Dispose();
						}
					}
					TypeSpecification val15 = (TypeSpecification)(object)((t is TypeSpecification) ? t : null);
					if (val15 != null)
					{
						map(val15.ElementType);
					}
					else
					{
						if (((MemberReference)t).DeclaringType != null)
						{
							map(((MemberReference)t).DeclaringType);
						}
						if (known.TryGetValue(((MemberReference)t).FullName, out var value))
						{
							t.Scope = value;
						}
						else
						{
							Require(t.Scope.Name != "InjectionTemplate", "Unknown injected type " + ((MemberReference)t).FullName);
						}
					}
				}
			};
			Enumerator<FieldDefinition> enumerator10 = val3.Fields.GetEnumerator();
			try
			{
				while (enumerator10.MoveNext())
				{
					FieldDefinition current9 = enumerator10.Current;
					map(((FieldReference)current9).FieldType);
				}
			}
			finally
			{
				((IDisposable)enumerator10/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<MethodDefinition> enumerator11 = val3.Methods.GetEnumerator();
			try
			{
				while (enumerator11.MoveNext())
				{
					MethodDefinition current10 = enumerator11.Current;
					map(((MethodReference)current10).ReturnType);
					Enumerator<ParameterDefinition> enumerator12 = ((MethodReference)current10).Parameters.GetEnumerator();
					try
					{
						while (enumerator12.MoveNext())
						{
							ParameterDefinition current11 = enumerator12.Current;
							map(((ParameterReference)current11).ParameterType);
						}
					}
					finally
					{
						((IDisposable)enumerator12/*cast due to .constrained prefix*/).Dispose();
					}
					Enumerator<VariableDefinition> enumerator13 = current10.Body.Variables.GetEnumerator();
					try
					{
						while (enumerator13.MoveNext())
						{
							VariableDefinition current12 = enumerator13.Current;
							map(((VariableReference)current12).VariableType);
						}
					}
					finally
					{
						((IDisposable)enumerator13/*cast due to .constrained prefix*/).Dispose();
					}
					Enumerator<Instruction> enumerator14 = current10.Body.Instructions.GetEnumerator();
					try
					{
						while (enumerator14.MoveNext())
						{
							Instruction current13 = enumerator14.Current;
							object operand = current13.Operand;
							MethodReference val11 = (MethodReference)((operand is MethodReference) ? operand : null);
							if (val11 != null)
							{
								map(((MemberReference)val11).DeclaringType);
								map(val11.ReturnType);
								Enumerator<ParameterDefinition> enumerator15 = val11.Parameters.GetEnumerator();
								try
								{
									while (enumerator15.MoveNext())
									{
										ParameterDefinition current14 = enumerator15.Current;
										map(((ParameterReference)current14).ParameterType);
									}
								}
								finally
								{
									((IDisposable)enumerator15/*cast due to .constrained prefix*/).Dispose();
								}
							}
							object operand2 = current13.Operand;
							FieldReference val12 = (FieldReference)((operand2 is FieldReference) ? operand2 : null);
							if (val12 != null)
							{
								map(((MemberReference)val12).DeclaringType);
								map(val12.FieldType);
							}
							if (current13.Operand is TypeReference)
							{
								map((TypeReference)current13.Operand);
							}
						}
					}
					finally
					{
						((IDisposable)enumerator14/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((IDisposable)enumerator11/*cast due to .constrained prefix*/).Dispose();
			}
			AssemblyNameReference[] array = ((IEnumerable<AssemblyNameReference>)target.AssemblyReferences).Where((AssemblyNameReference r) => r.Name == "InjectionTemplate").ToArray();
			foreach (AssemblyNameReference val13 in array)
			{
				target.AssemblyReferences.Remove(val13);
			}
			return val3;
		}
		finally
		{
			((IDisposable)val)?.Dispose();
		}
	}

	public static void SideLoader(ModuleDefinition module)
	{
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: 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_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0411: Unknown result type (might be due to invalid IL or missing references)
		if (((IEnumerable<TypeDefinition>)module.Types).Any((TypeDefinition t) => ((MemberReference)t).FullName == "AetherialInjected.Support"))
		{
			FullExceptions(module);
			RandomStatusSettings(module);
			Repairs014.SideLoader(module);
			Repairs015.SideLoader(module);
			Repairs016.SideLoader(module);
			Repairs017.SideLoader(module);
			Repairs019.SideLoader(module);
			Repairs021.SideLoader(module);
			return;
		}
		TypeDefinition val = InjectSupport(module);
		TypeDefinition val2 = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SLPacks.SLPackManager");
		MethodDefinition val3 = ((IEnumerable<MethodDefinition>)val2.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "LoadBaseSLPacks");
		Instruction val4 = ((IEnumerable<Instruction>)val3.Body.Instructions).First((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).FullName.Contains("System.IO.Directory::GetDirectories"));
		val4.Operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "PackDirectories");
		Instruction val5 = ((IEnumerable<Instruction>)val3.Body.Instructions).First((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name.Contains("g__AddSLPack"));
		Instruction previous = val5.Previous.Previous;
		Require(previous.Operand is MethodReference && ((MemberReference)(MethodReference)previous.Operand).Name == "GetFileName", "Unexpected pack folder argument");
		previous.Operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "PackFolderName");
		TypeDefinition val6 = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_CharacterTrainer");
		MethodDefinition val7 = ((IEnumerable<MethodDefinition>)val6.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ApplyToCharacter");
		Instruction val8 = ((IEnumerable<Instruction>)val7.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "ConnectNodes");
		FieldDefinition val9 = ((IEnumerable<FieldDefinition>)val6.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "SkillTree");
		ILProcessor iLProcessor = val7.Body.GetILProcessor();
		iLProcessor.InsertBefore(val8, Instruction.Create(OpCodes.Ldarg_0));
		iLProcessor.InsertBefore(val8, Instruction.Create(OpCodes.Ldfld, (FieldReference)(object)val9));
		val8.OpCode = OpCodes.Call;
		val8.Operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ConnectTrainer");
		AssemblyRepairs.WidenBranches(val7);
		TypeDefinition val10 = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SLPack");
		MethodDefinition val11 = ((IEnumerable<MethodDefinition>)val10.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "LoadAssetBundle");
		((IEnumerable<Instruction>)val11.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "LoadFromFile").Operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "LoadScrollBundle");
		TypeDefinition val12 = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_Item");
		MethodDefinition val13 = ((IEnumerable<MethodDefinition>)val12.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ApplyTexAndMats");
		Instruction val14 = ((IEnumerable<Instruction>)val13.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "get_Item" && ((MemberReference)((MemberReference)(MethodReference)i.Operand).DeclaringType).FullName == "System.Collections.Generic.Dictionary`2<System.String,System.Collections.Generic.List`1<UnityEngine.Texture2D>>");
		val14.OpCode = OpCodes.Call;
		val14.Operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "MaterialTextures");
		FullExceptions(module);
		RandomStatusSettings(module);
		Repairs014.SideLoader(module);
		Repairs015.SideLoader(module);
		Repairs016.SideLoader(module);
		Repairs017.SideLoader(module);
		Repairs019.SideLoader(module);
		Repairs021.SideLoader(module);
	}

	private static void RandomStatusSettings(ModuleDefinition module)
	{
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_AddStatusEffect");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ApplyToComponent");
		TypeDefinition random = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_AddStatusEffectRandom");
		if (!((IEnumerable<Instruction>)val2.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Isinst && i.Operand is TypeReference && ((MemberReference)(TypeReference)i.Operand).FullName == ((MemberReference)random).FullName))
		{
			FieldDefinition val3 = ((IEnumerable<FieldDefinition>)val.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "StatusEffect");
			Instruction previous = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.OpCode == OpCodes.Ldfld && ((MemberReference)(FieldReference)i.Operand).FullName.Contains("::NoDealer")).Previous.Previous;
			VariableDefinition val4 = ((IEnumerable<VariableDefinition>)val2.Body.Variables).Single((VariableDefinition v) => ((MemberReference)((VariableReference)v).VariableType).FullName == "AddStatusEffect");
			Instruction val5 = val2.Body.Instructions[0];
			ILProcessor iLProcessor = val2.Body.GetILProcessor();
			Instruction[] array = (Instruction[])(object)new Instruction[12]
			{
				Instruction.Create(OpCodes.Ldarg_0),
				Instruction.Create(OpCodes.Isinst, (TypeReference)(object)random),
				Instruction.Create(OpCodes.Brfalse, val5),
				Instruction.Create(OpCodes.Ldarg_0),
				Instruction.Create(OpCodes.Ldfld, (FieldReference)(object)val3),
				Instruction.Create(OpCodes.Call, module.ImportReference((MethodBase)typeof(string).GetMethod("IsNullOrEmpty"))),
				Instruction.Create(OpCodes.Brfalse, val5),
				Instruction.Create(OpCodes.Ldarg_1),
				Instruction.Create(OpCodes.Box, (TypeReference)(object)((MethodReference)val2).GenericParameters[0]),
				Instruction.Create(OpCodes.Isinst, ((VariableReference)val4).VariableType),
				Instruction.Create(OpCodes.Stloc, val4),
				Instruction.Create(OpCodes.Br, previous)
			};
			foreach (Instruction val6 in array)
			{
				iLProcessor.InsertBefore(val5, val6);
			}
			AssemblyRepairs.WidenBranches(val2);
		}
	}

	private static void FullExceptions(ModuleDefinition module)
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "LogInnerException");
		MethodDefinition val3 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "LogWarning" && ((MemberReference)((ParameterReference)((MethodReference)m).Parameters[0]).ParameterType).FullName == "System.String");
		val2.Body = new MethodBody(val2);
		ILProcessor iLProcessor = val2.Body.GetILProcessor();
		Instruction val4 = Instruction.Create(OpCodes.Ret);
		iLProcessor.Append(Instruction.Create(OpCodes.Ldarg_0));
		iLProcessor.Append(Instruction.Create(OpCodes.Brfalse, val4));
		iLProcessor.Append(Instruction.Create(OpCodes.Ldarg_0));
		iLProcessor.Append(Instruction.Create(OpCodes.Callvirt, module.ImportReference((MethodBase)typeof(Exception).GetMethod("ToString", Type.EmptyTypes))));
		iLProcessor.Append(Instruction.Create(OpCodes.Call, (MethodReference)(object)val3));
		iLProcessor.Append(val4);
	}
}
public static class Repairs014
{
	public static void SideLoader(ModuleDefinition module)
	{
		OptionalShadowRecipes(module);
		LateApplyContext(module);
	}

	private static void OptionalShadowRecipes(ModuleDefinition module)
	{
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Expected O, but got Unknown
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0318: Unknown result type (might be due to invalid IL or missing references)
		//IL_0329: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_035c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_037f: Unknown result type (might be due to invalid IL or missing references)
		//IL_038b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_Recipe");
		if (!((IEnumerable<MethodDefinition>)val.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "Aetherial_OptionalRecipeReady"))
		{
			MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Internal_ApplyRecipe");
			FieldDefinition val3 = ((IEnumerable<FieldDefinition>)val.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == "UID");
			MethodReference[] source = (from m in ((IEnumerable<Instruction>)val2.Body.Instructions).Select(delegate(Instruction i)
				{
					object operand = i.Operand;
					return (MethodReference)((operand is MethodReference) ? operand : null);
				})
				where m != null
				select m).ToArray();
			MethodReference val4 = source.First((MethodReference m) => ((MemberReference)((MemberReference)m).DeclaringType).FullName == "ResourcesPrefabManager" && ((MemberReference)m).Name == "get_Instance");
			MethodReference val5 = source.First((MethodReference m) => ((MemberReference)m).Name == "GetItemPrefab" && ((MemberReference)((ParameterReference)m.Parameters[0]).ParameterType).FullName == "System.Int32");
			MethodReference val6 = module.GetMemberReferences().OfType<MethodReference>().First((MethodReference m) => ((MemberReference)((MemberReference)m).DeclaringType).FullName == "UnityEngine.Object" && ((MemberReference)m).Name == "op_Implicit");
			MethodReference val7 = source.First((MethodReference m) => ((MemberReference)((MemberReference)m).DeclaringType).FullName == "SideLoader.SL" && ((MemberReference)m).Name == "Log");
			MethodDefinition val8 = new MethodDefinition("Aetherial_OptionalRecipeReady", (MethodAttributes)1, module.TypeSystem.Boolean);
			val.Methods.Add(val8);
			ILProcessor iLProcessor = val8.Body.GetILProcessor();
			Instruction val9 = Instruction.Create(OpCodes.Call, val4);
			Instruction val10 = Instruction.Create(OpCodes.Ldc_I4_1);
			Instruction val11 = Instruction.Create(OpCodes.Ldstr, "Aetherial Endeavors: optional Shadow conversion skipped because its required items are not installed.");
			string[] array = new string[2] { "!Shadow-daggerTOknife-custom Recipe", "!Shadow-knifeTOdagger-custom Recipe" };
			foreach (string text in array)
			{
				iLProcessor.Emit(OpCodes.Ldarg_0);
				iLProcessor.Emit(OpCodes.Ldfld, (FieldReference)(object)val3);
				iLProcessor.Emit(OpCodes.Ldstr, text);
				iLProcessor.Emit(OpCodes.Call, module.ImportReference((MethodBase)typeof(string).GetMethod("op_Equality", new Type[2]
				{
					typeof(string),
					typeof(string)
				})));
				iLProcessor.Emit(OpCodes.Brtrue, val9);
			}
			iLProcessor.Emit(OpCodes.Br, val10);
			iLProcessor.Append(val9);
			iLProcessor.Emit(OpCodes.Ldc_I4, -23076);
			iLProcessor.Emit(OpCodes.Callvirt, val5);
			iLProcessor.Emit(OpCodes.Call, val6);
			iLProcessor.Emit(OpCodes.Brfalse, val11);
			iLProcessor.Emit(OpCodes.Call, val4);
			iLProcessor.Emit(OpCodes.Ldc_I4, -23848);
			iLProcessor.Emit(OpCodes.Callvirt, val5);
			iLProcessor.Emit(OpCodes.Call, val6);
			iLProcessor.Emit(OpCodes.Brfalse, val11);
			iLProcessor.Append(val10);
			iLProcessor.Emit(OpCodes.Ret);
			iLProcessor.Append(val11);
			iLProcessor.Emit(OpCodes.Call, val7);
			iLProcessor.Emit(OpCodes.Ldc_I4_0);
			iLProcessor.Emit(OpCodes.Ret);
			Instruction val12 = val2.Body.Instructions[0];
			ILProcessor iLProcessor2 = val2.Body.GetILProcessor();
			Instruction[] array2 = (Instruction[])(object)new Instruction[4]
			{
				Instruction.Create(OpCodes.Ldarg_0),
				Instruction.Create(OpCodes.Call, (MethodReference)(object)val8),
				Instruction.Create(OpCodes.Brtrue, val12),
				Instruction.Create(OpCodes.Ret)
			};
			foreach (Instruction val13 in array2)
			{
				iLProcessor2.InsertBefore(val12, val13);
			}
			AssemblyRepairs.WidenBranches(val2);
		}
	}

	private static void LateApplyContext(ModuleDefinition module)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Expected O, but got Unknown
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Expected O, but got Unknown
		//IL_012b: 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_0158: 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_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_0343: Unknown result type (might be due to invalid IL or missing references)
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SLPacks.SLPackManager");
		if (((IEnumerable<MethodDefinition>)val.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "Aetherial_LateApplyContext"))
		{
			return;
		}
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "InvokeLateApplyListener");
		TypeDefinition val3 = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_StatusEffect");
		MethodDefinition val4 = new MethodDefinition("Aetherial_LateApplyContext", (MethodAttributes)17, module.TypeSystem.String);
		((MethodReference)val4).Parameters.Add(new ParameterDefinition("listener", (ParameterAttributes)0, ((ParameterReference)((MethodReference)val2).Parameters[0]).ParameterType));
		val4.Body.InitLocals = true;
		VariableDefinition val5 = new VariableDefinition((TypeReference)(object)val3);
		val4.Body.Variables.Add(val5);
		val.Methods.Add(val4);
		ILProcessor iLProcessor = val4.Body.GetILProcessor();
		Instruction val6 = Instruction.Create(OpCodes.Ldstr, "Exception invoking OnLateApply listener!");
		iLProcessor.Emit(OpCodes.Ldarg_0);
		iLProcessor.Emit(OpCodes.Brfalse, val6);
		iLProcessor.Emit(OpCodes.Ldarg_0);
		iLProcessor.Emit(OpCodes.Callvirt, module.ImportReference((MethodBase)typeof(Delegate).GetProperty("Target").GetGetMethod()));
		iLProcessor.Emit(OpCodes.Isinst, (TypeReference)(object)val3);
		iLProcessor.Emit(OpCodes.Stloc, val5);
		iLProcessor.Emit(OpCodes.Ldloc, val5);
		iLProcessor.Emit(OpCodes.Brfalse, val6);
		iLProcessor.Emit(OpCodes.Ldc_I4, 6);
		iLProcessor.Emit(OpCodes.Newarr, module.TypeSystem.String);
		string[] array = new string[6] { "Exception applying status '", null, "', source '", null, "', family: ", null };
		string[] fields = new string[6] { null, "StatusIdentifier", null, "TargetStatusIdentifier", null, "ReferenceFamilyUID" };
		int i;
		for (i = 0; i < array.Length; i++)
		{
			iLProcessor.Emit(OpCodes.Dup);
			iLProcessor.Emit(OpCodes.Ldc_I4, i);
			if (array[i] != null)
			{
				iLProcessor.Emit(OpCodes.Ldstr, array[i]);
			}
			else
			{
				iLProcessor.Emit(OpCodes.Ldloc, val5);
				iLProcessor.Emit(OpCodes.Ldfld, (FieldReference)(object)((IEnumerable<FieldDefinition>)val3.Fields).Single((FieldDefinition f) => ((MemberReference)f).Name == fields[i]));
			}
			iLProcessor.Emit(OpCodes.Stelem_Ref);
		}
		iLProcessor.Emit(OpCodes.Call, module.ImportReference((MethodBase)typeof(string).GetMethod("Concat", new Type[1] { typeof(string[]) })));
		iLProcessor.Emit(OpCodes.Ret);
		iLProcessor.Append(val6);
		iLProcessor.Emit(OpCodes.Ret);
		Instruction val7 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction val8) => val8.OpCode == OpCodes.Ldstr && (string)val8.Operand == "Exception invoking OnLateApply listener!");
		val7.OpCode = OpCodes.Ldarg_0;
		val7.Operand = null;
		val2.Body.GetILProcessor().InsertAfter(val7, Instruction.Create(OpCodes.Call, (MethodReference)(object)val4));
		AssemblyRepairs.WidenBranches(val2);
	}
}
public static class Repairs015
{
	private static void Require(bool value, string message)
	{
		AssemblyRepairs.Require(value, message);
	}

	public static void SideLoader(ModuleDefinition module)
	{
		//IL_00e8: 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)
		if (!((IEnumerable<TypeDefinition>)module.Types).Any((TypeDefinition t) => ((MemberReference)t).FullName == "AetherialInjected.Chef015"))
		{
			MethodDefinition operand = ((IEnumerable<MethodDefinition>)TemplateInjector015.Inject(module, "AetherialInjected.Chef015").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Texture");
			MethodDefinition val = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_SkillTree").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "CreateSchool");
			Instruction val2 = ((IEnumerable<Instruction>)val.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "TryGetValue");
			val.Body.GetILProcessor().InsertBefore(val2, Instruction.Create(OpCodes.Ldarg_0));
			val2.OpCode = OpCodes.Call;
			val2.Operand = operand;
			AssemblyRepairs.WidenBranches(val);
			OptionalRunicImbues(module);
		}
	}

	private static void OptionalRunicImbues(ModuleDefinition module)
	{
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: 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_01b7: Expected O, but got Unknown
		//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_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Expected O, but got Unknown
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == "SideLoader.SL_RunicBlade");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "ApplyToComponent");
		ILProcessor iLProcessor = val2.Body.GetILProcessor();
		Instruction[] array = ((IEnumerable<Instruction>)val2.Body.Instructions).Where((Instruction i) => i.Operand is FieldReference && i.OpCode == OpCodes.Ldfld && ((MemberReference)(FieldReference)i.Operand).Name.Contains("ImbueID")).ToArray();
		Require(array.Length == 2, "Expected both runic imbue lookups");
		Instruction[] array2 = array;
		foreach (Instruction lookup in array2)
		{
			Instruction previous = lookup.Previous.Previous;
			Require(previous.OpCode == OpCodes.Call && ((MemberReference)(MethodReference)previous.Operand).Name == "get_Instance", "Unexpected runic lookup stack");
			Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).SkipWhile((Instruction i) => i != lookup).First((Instruction i) => i.OpCode == OpCodes.Stfld);
			object operand = val3.Next.Next.Operand;
			Instruction val4 = (Instruction)((operand is Instruction) ? operand : null);
			Require(val4 != null, "Missing runic continuation");
			Instruction[] array3 = (Instruction[])(object)new Instruction[8]
			{
				Instruction.Create(OpCodes.Ldarg_0),
				Instruction.Create(OpCodes.Ldfld, (FieldReference)lookup.Operand),
				Instruction.Create(OpCodes.Ldc_I4_M1),
				Instruction.Create(OpCodes.Bne_Un, previous),
				Instruction.Create(OpCodes.Ldloc_0),
				Instruction.Create(OpCodes.Ldnull),
				Instruction.Create(OpCodes.Stfld, (FieldReference)val3.Operand),
				Instruction.Create(OpCodes.Br, val4)
			};
			Enumerator<Instruction> enumerator = val2.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					if (current.Operand == previous)
					{
						current.Operand = array3[0];
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Instruction[] array4 = array3;
			foreach (Instruction val5 in array4)
			{
				iLProcessor.InsertBefore(previous, val5);
			}
		}
		AssemblyRepairs.WidenBranches(val2);
	}

	public static void Viewer(ModuleDefinition module)
	{
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: 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_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = TemplateInjector015.Inject(module, "AetherialInjected.Viewer015");
		MethodDefinition operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "StatusName");
		int num = 0;
		foreach (TypeDefinition item in ((IEnumerable<TypeDefinition>)module.Types).Where((TypeDefinition t) => ((MemberReference)t).Name == "ItemEnchantmentInformationHelper" || ((MemberReference)t).Name == "EnchantmentInformationHelper"))
		{
			MethodDefinition val2 = ((IEnumerable<MethodDefinition>)item.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "GetAddStatusEffectsDescription");
			Instruction[] array = ((IEnumerable<Instruction>)val2.Body.Instructions).Where((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "get_StatusName").ToArray();
			foreach (Instruction val3 in array)
			{
				Require(val3.Previous.OpCode == OpCodes.Ldfld && ((MemberReference)(FieldReference)val3.Previous.Operand).FullName == "StatusEffect AddStatusEffect::Status", "Unexpected status name access");
				val3.Previous.OpCode = OpCodes.Nop;
				val3.Previous.Operand = null;
				val3.OpCode = OpCodes.Call;
				val3.Operand = operand;
				num++;
			}
			AssemblyRepairs.WidenBranches(val2);
		}
		Require(num == 6, "Expected six enchantment status descriptions");
		MethodDefinition val4 = ((IEnumerable<MethodDefinition>)((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).Name == "ItemEnchantmentInformationHelper").Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "BuildDescriptions");
		Instruction val5 = ((IEnumerable<Instruction>)val4.Body.Instructions).Single((Instruction i) => i.Operand is MethodReference && ((MemberReference)(MethodReference)i.Operand).Name == "get_Message");
		val4.Body.GetILProcessor().InsertBefore(val5, Instruction.Create(OpCodes.Ldarg_1));
		val4.Body.GetILProcessor().InsertBefore(val5, Instruction.Create(OpCodes.Ldarg_0));
		val5.OpCode = OpCodes.Call;
		val5.Operand = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Error");
		AssemblyRepairs.WidenBranches(val4);
	}

	public static void DeferredRunicVisuals(ModuleDefinition module)
	{
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Expected O, but got Unknown
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((IEnumerable<MethodDefinition>)t.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "TryRefreshCapturedTextureState"));
		Require(((IEnumerable<MethodDefinition>)val.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "PreloadRunicBladeMaterialWhenReady"), "Expected existing deferred visual loader");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == "Awake");
		int num = 0;
		Instruction[] array = ((IEnumerable<Instruction>)val2.Body.Instructions).Where((Instruction i) => i.Operand is MethodReference && new string[2] { "TryRefreshCapturedTextureState", "TryRefreshRunicBladeSourceMaterial" }.Contains(((MemberReference)(MethodReference)i.Operand).Name)).ToArray();
		foreach (Instruction val3 in array)
		{
			MethodReference val4 = (MethodReference)val3.Operand;
			Instruction previous = val3.Previous;
			if (val4.Parameters.Count == 1)
			{
				Require(previous.OpCode == OpCodes.Ldc_I4_0, "Unexpected eager visual argument");
				previous.OpCode = OpCodes.Nop;
				previous.Operand = null;
				previous = previous.Previous;
			}
			Require(previous.OpCode == OpCodes.Ldarg_0, "Unexpected eager visual receiver");
			previous.OpCode = OpCodes.Nop;
			previous.Operand = null;
			val3.OpCode = OpCodes.Nop;
			val3.Operand = null;
			num++;
		}
		Require(num == 2, "Expected two eager visual probes");
	}

	public static void EffectName(ModuleDefinition module, string methodName)
	{
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		//IL_00ec: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition val = ((IEnumerable<TypeDefinition>)module.Types).Single((TypeDefinition t) => ((MemberReference)t).Name == "EffectInitializer");
		MethodDefinition val2 = ((IEnumerable<MethodDefinition>)val.Methods).Single((MethodDefinition m) => ((MemberReference)m).Name == methodName);
		Instruction val3 = ((IEnumerable<Instruction>)val2.Body.Instructions).Single((Instruction i) => i.OpCode == OpCodes.Newobj && ((MemberReference)((MemberReference)(MethodReference)i.Operand).DeclaringType).FullName == "SideLoader.SL_EffectTransform");
		Require(!((IEnumerable<Instruction>)val2.Body.Instructions).Any((Instruction i) => i.OpCode == OpCodes.Stfld && ((MemberReference)(FieldReference)i.Operand).Name == "TransformName"), "Effect name already supplied");
		FieldReference val4 = new FieldReference("TransformName", module.TypeSystem.String, ((MemberReference)(MethodReference)val3.Operand).DeclaringType);
		ILProcessor iLProcessor = val2.Body.GetILProcessor();
		Instruction val5 = Instruction.Create(OpCodes.Dup);
		Instruction val6 = Instruction.Create(OpCodes.Ldstr, "Normal");
		iLProcessor.InsertAfter(val3, val5);
		iLProcessor.InsertAfter(val5, val6);
		iLProcessor.InsertAfter(val6, Instruction.Create(OpCodes.Stfld, val4));
		AssemblyRepairs.WidenBranches(val2);
	}
}
public static class TemplateInjector015
{
	private static void Require(bool value, string message)
	{
		AssemblyRepairs.Require(value, message);
	}

	private static IEnumerable<TypeDefinition> Types(IEnumerable<TypeDefinition> ts)
	{
		foreach (TypeDefinition t in ts)
		{
			yield return t;
			foreach (TypeDefinition item in Types((IEnumerable<TypeDefinition>)t.NestedTypes))
			{
				yield return item;
			}
		}
	}

	public static TypeDefinition Inject(ModuleDefinition target, string typeName)
	{
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Expected O, but got Unknown
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: 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_01db: Expected O, but got Unknown
		//IL_01fa: 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_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Expected O, but got Unknown
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Expected O, but got Unknown
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Expected O, but got Unknown
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0726: Unknown result type (might be due to invalid IL or missing references)
		//IL_072b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bd: Expected O, but got Unknown
		//IL_0411: Unknown result type (might be due to invalid IL or missing references)
		//IL_0416: Unknown result type (might be due to invalid IL or missing references)
		//IL_076b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0770: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0433: Unknown result type (might be due to invalid IL or missing references)
		//IL_079a: Unknown result type (might be due to invalid IL or missing references)
		//IL_079f: Unknown result type (might be due to invalid IL or missing references)
		//IL_048a: Unknown result type (might be due to invalid IL or missing references)
		//IL_048f: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Expected O, but got Unknown
		//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_050e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0518: Expected O, but got Unknown
		//IL_052e: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fe: Expected O, but got Unknown
		//IL_082e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0833: Unknown result type (might be due to invalid IL or missing references)
		//IL_054d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0557: Expected O, but got Unknown
		//IL_0567: Unknown result type (might be due to invalid IL or missing references)
		//IL_0571: Expected O, but got Unknown
		//IL_0581: Unknown result type (might be due to invalid IL or missing references)
		//IL_058b: Expected O, but got Unknown
		//IL_0882: Unknown result type (might be due to invalid IL or missing references)
		//IL_0887: Unknown result type (might be due to invalid IL or missing references)
		//IL_0914: Unknown result type (might be due to invalid IL or missing references)
		//IL_091e: Expected O, but got Unknown
		Dictionary<string, IMetadataScope> known = (from t in target.GetTypeReferences()
			group t by ((MemberReference)t).FullName).ToDictionary((IGrouping<string, TypeReference> g) => g.Key, (IGrouping<string, TypeReference> g) => g.First().Scope);
		foreach (TypeDefinition item in Types((IEnumerable<TypeDefinition>)target.Types))
		{
			known[((MemberReference)item).FullName] = (IMetadataScope)(object)target;
		}
		if (known.ContainsKey("AddStatusEffect"))
		{
			known["AddStatusEffectRandom"] = known["AddStatusEffect"];
		}
		using Stream stream = typeof(TemplateInjector015).Assembly.GetManifestResourceStream("Template015.dll");
		AssemblyDefinition val = AssemblyDefinition.ReadAssembly(stream);
		try
		{
			TypeDefinition val2 = ((IEnumerable<TypeDefinition>)val.MainModule.Types).Single((TypeDefinition t) => ((MemberReference)t).FullName == typeName);
			TypeDefinition val3 = new TypeDefinition(((TypeReference)val2).Namespace, ((MemberReference)val2).Name, val2.Attributes, target.TypeSystem.Object);
			target.Types.Add(val3);
			known[((MemberReference)val3).FullName] = (IMetadataScope)(object)target;
			Enumerator<FieldDefinition> enumerator2 = val2.Fields.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					FieldDefinition current2 = enumerator2.Current;
					val3.Fields.Add(new FieldDefinition(((MemberReference)current2).Name, current2.Att

plugins/AetherialEndeavorsFixes/AetherialEndeavorsFixes.Runtime.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using NodeCanvas.BehaviourTrees;
using NodeCanvas.Framework;
using Photon;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("Aetherial Endeavors Fixes Runtime")]
[assembly: AssemblyFileVersion("0.1.28.0")]
[assembly: AssemblyVersion("0.1.28.0")]
namespace AetherialEndeavorsFixes;

[BepInPlugin("Outwardz.AetherialEndeavorsFixes.Runtime", "Aetherial Endeavors Fixes Runtime", "0.1.28")]
public sealed class RuntimePlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Character), "SpellCast", new Type[] { })]
	private static class CastingContext
	{
		private static string scene;

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

		private static void Prefix(Character __instance, GameObject ___m_castingEventReceiver, Skill ___m_lastUsedSkill)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)___m_castingEventReceiver) || !Object.op_Implicit((Object)(object)__instance) || log == null)
			{
				return;
			}
			try
			{
				string activeSceneName = SceneManagerHelper.ActiveSceneName;
				if (activeSceneName != scene)
				{
					scene = activeSceneName;
					seen.Clear();
				}
				string text = (Object.op_Implicit((Object)(object)___m_lastUsedSkill) ? (((Item)___m_lastUsedSkill).ItemID + " / " + ((Object)___m_lastUsedSkill).name) : "none");
				string item = ((Object)__instance).GetInstanceID() + " / " + text;
				if (seen.Count < 24 && seen.Add(item))
				{
					log.LogInfo((object)string.Concat("Casting diagnostic: scene=", activeSceneName, ", actor=", ((Object)__instance).name, ", last skill=", text, ", position=", ((Component)__instance).transform.position, ". Animation has no casting receiver; no cast was changed or replayed."));
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("Casting diagnostic failed: " + ex));
			}
		}
	}

	[HarmonyPatch(typeof(ResourcesPrefabManager), "GetStatusEffectPrefab", new Type[] { typeof(string) })]
	private static class StatusLookupContext
	{
		private static readonly HashSet<string> seen = new HashSet<string>();

		private static void Postfix(string __0, StatusEffect __result)
		{
			if (Object.op_Implicit((Object)(object)__result) || log == null || (__0 != "Infuse Blood" && __0 != "Infuse Light" && __0 != "alchemicalExpansion-lifeRegeneration" && __0 != "alchemicalExpansion-manaRegeneration" && __0 != "alchemicalExpansion-unstableFlameEffect" && __0 != "alchemicalExpansion-SpeedUp25" && __0 != "CallElements"))
			{
				return;
			}
			try
			{
				if (seen.Add(__0))
				{
					log.LogInfo((object)("Status lookup diagnostic: " + __0 + " was not registered when requested. Caller: " + new StackTrace(1, fNeedFileInfo: false)));
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("Status lookup diagnostic failed: " + ex));
			}
		}
	}

	[HarmonyPatch(typeof(CharacterStats), "UpdateEquipmentStats")]
	private static class EquipmentRefresh
	{
		private static void Postfix(CharacterStats __instance, Character ___m_character, Stat ___m_detectability, Stat ___m_visualDetectability)
		{
			if (!enabledRepair)
			{
				return;
			}
			try
			{
				ThiefEquipment.Refresh(__instance, ___m_character, ___m_detectability, ___m_visualDetectability);
			}
			catch (Exception ex)
			{
				log.LogError((object)("Thief equipment update failed: " + ex));
			}
		}
	}

	private static bool enabledRepair;

	private static ManualLogSource log;

	private void OnApplicationQuit()
	{
		AudioTransitionDiagnostics.Quitting = true;
	}

	private void Start()
	{
		SynchronizedNpcThreadFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
	}

	private void Awake()
	{
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		log = ((BaseUnityPlugin)this).Logger;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Running fixes runtime " + typeof(RuntimePlugin).Assembly.GetName().Version));
		((Component)this).gameObject.AddComponent<NavigationDiagnostics>().Log = ((BaseUnityPlugin)this).Logger;
		try
		{
			enabledRepair = HasSupportedThief(Paths.PluginPath);
			DonorSceneFixes.Initialize(Paths.PluginPath, Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
			new Harmony("Outwardz.AetherialEndeavorsFixes.Runtime").PatchAll(typeof(RuntimePlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)(enabledRepair ? "Thief equipment fix ready." : "Thief equipment fix inactive: supported repaired definition not found."));
		}
		catch (Exception ex)
		{
			enabledRepair = false;
			((BaseUnityPlugin)this).Logger.LogError((object)("Runtime patches could not start: " + ex));
		}
		LanternLifetimeFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		TrainerIdentityFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		MendicantsCompatibility.Install(Paths.PluginPath, Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		RunicBarrierCompatibility.Install(Paths.PluginPath, Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		AudioTransitionDiagnostics.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		GatheringNotificationFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		BasicInteractionLifetimeFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		QuickSlotLoadFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		JoinSynchronizationFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		SceneExitFix.Install(Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		TrainerPrerequisiteFix.Install(Paths.PluginPath, ((BaseUnityPlugin)this).Logger);
		BladefallBoonFix.Install(Paths.PluginPath, Paths.ManagedPath, ((BaseUnityPlugin)this).Logger);
		((Component)this).gameObject.AddComponent<StartupOptimizer>().Initialize(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config);
	}

	private static bool HasSupportedThief(string directory)
	{
		string[] files = Directory.GetFiles(directory, "-30442_ Thief.xml");
		foreach (string path in files)
		{
			if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != FileAttributes.None)
			{
				continue;
			}
			using FileStream inputStream = File.OpenRead(path);
			using SHA256 sHA = SHA256.Create();
			if (BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant() == "42652e4c9a5f3acaea53852bda2e519de7647caeae1620192a3bc82a43c4c4a8")
			{
				return true;
			}
		}
		string[] directories = Directory.GetDirectories(directory);
		foreach (string text in directories)
		{
			if (!text.EndsWith(".disabled", StringComparison.OrdinalIgnoreCase) && !text.EndsWith(".old", StringComparison.OrdinalIgnoreCase) && (File.GetAttributes(text) & FileAttributes.ReparsePoint) == 0 && HasSupportedThief(text))
			{
				return true;
			}
		}
		return false;
	}
}
internal static class BladefallBoonFix
{
	private const string DefinitionHash = "dca07df90bef5f618b452cd960716628d494044b58014994d9dde70363dc8e54";

	private const string ClassfixesRageHash = "b9bb44d3a5b860bfea75b419c6d4788379ff245efd93be831a567c613adb3e54";

	private static bool classfixesRage;

	private static string Hash(string path)
	{
		using FileStream inputStream = File.OpenRead(path);
		using SHA256 sHA = SHA256.Create();
		return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
	}

	private static IEnumerable<string> Definitions(string directory)
	{
		return Candidates(directory, "-1008_Bladefall.xml");
	}

	private static IEnumerable<string> Candidates(string directory, string fileName)
	{
		string[] files;
		string[] children;
		try
		{
			if ((File.GetAttributes(directory) & FileAttributes.ReparsePoint) != FileAttributes.None)
			{
				yield break;
			}
			files = Directory.GetFiles(directory, fileName);
			children = Directory.GetDirectories(directory);
		}
		catch (DirectoryNotFoundException)
		{
			yield break;
		}
		catch (FileNotFoundException)
		{
			yield break;
		}
		try
		{
			string[] array = files;
			foreach (string file in array)
			{
				FileAttributes attributes;
				try
				{
					attributes = File.GetAttributes(file);
				}
				catch (FileNotFoundException)
				{
					continue;
				}
				catch (DirectoryNotFoundException)
				{
					continue;
				}
				if ((attributes & FileAttributes.ReparsePoint) == 0)
				{
					yield return file;
				}
			}
		}
		finally
		{
		}
		try
		{
			string[] array2 = children;
			foreach (string child in array2)
			{
				if (child.EndsWith(".disabled", StringComparison.OrdinalIgnoreCase) || child.EndsWith(".old", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				foreach (string item in Candidates(child, fileName))
				{
					yield return item;
				}
			}
		}
		finally
		{
		}
	}

	internal static void Install(string plugins, string managed, ManualLogSource logger)
	{
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Expected O, but got Unknown
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			string[] array = Definitions(plugins).ToArray();
			if (array.Length != 0)
			{
				if (array.Length != 1 || Hash(array[0]) != "dca07df90bef5f618b452cd960716628d494044b58014994d9dde70363dc8e54" || !DonorSceneFixes.SupportedGame(managed))
				{
					throw new InvalidOperationException("Bladefall definition or game build differs from the verified build.");
				}
				string[] array2 = Candidates(plugins, "Rage Amp.xml").ToArray();
				classfixesRage = array2.Length == 1 && Hash(array2[0]) == "b9bb44d3a5b860bfea75b419c6d4788379ff245efd93be831a567c613adb3e54";
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "SideLoader");
				string text = ((assembly == null) ? "" : Hash(assembly.Location));
				if (text != "5da977a019f2158e9217a0e86c4be05a039ea0cd1a1ba6a78a759aa2931d9052" && text != "d56a937169c353096818b9a73c8c2aecce65eb2c4eb291dd79d4b717494c14ec")
				{
					throw new InvalidOperationException("Unsupported SideLoader build.");
				}
				val = new Harmony("Outwardz.AetherialEndeavorsFixes.BladefallBoon");
				val.Patch((MethodBase)AccessTools.Method(typeof(HasStatusEffectEffectCondition), "CheckIsValid", new Type[1] { typeof(Character) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(BladefallBoonFix), "AfterStatusCheck", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				logger.LogInfo((object)("Bladefall boon compatibility ready: native amplified Rage supported; verified Classfixes Rage Amp=" + classfixesRage + "."));
			}
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				val.UnpatchSelf();
			}
			logger.LogWarning((object)("Bladefall boon compatibility inactive; original requirements retained. " + ex));
		}
	}

	private static void AfterStatusCheck(HasStatusEffectEffectCondition __instance, Character __0, ref bool __result)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		if (__result || !Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)__0) || __instance.Inverse || ((EffectCondition)__instance).Invert || __instance.CheckOwner || ((Object)__instance).name != "AdditionalActivationConditions" || __instance.DiseaseAge != 0f)
		{
			return;
		}
		StatusEffectSelector statusEffect = __instance.StatusEffect;
		if (statusEffect == null || (int)statusEffect.Type != 0 || !Object.op_Implicit((Object)(object)statusEffect.StatusEffect) || statusEffect.StatusEffect.IdentifierName != "Rage")
		{
			return;
		}
		Skill val = UnityEngineExtensions.FirstOrDefault<Skill>((IList<Skill>)((Component)__instance).GetComponentsInParent<Skill>(true));
		if (Object.op_Implicit((Object)(object)val) && ((Item)val).ItemID == -1008)
		{
			StatusEffect amplifiedStatus = statusEffect.StatusEffect.AmplifiedStatus;
			if (Object.op_Implicit((Object)(object)amplifiedStatus) && Object.op_Implicit((Object)(object)__0.StatusEffectMngr))
			{
				__result = __0.StatusEffectMngr.HasStatusOfAge(amplifiedStatus, __instance.DiseaseAge);
			}
			if (!__result && classfixesRage && Object.op_Implicit((Object)(object)__0.StatusEffectMngr))
			{
				__result = __0.StatusEffectMngr.HasStatusOfAge("Rage Amp", __instance.DiseaseAge);
			}
		}
	}
}
internal static class TrainerPrerequisiteFix
{
	private static bool ice;

	private static bool fire;

	private static bool crusader;

	private static bool martial;

	private static ManualLogSource log;

	private static string Hash(string path)
	{
		using FileStream inputStream = File.OpenRead(path);
		using SHA256 sHA = SHA256.Create();
		return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
	}

	private static bool FileMatches(string plugins, string name, string hash)
	{
		return Directory.GetFiles(plugins, name, SearchOption.AllDirectories).Any((string p) => Hash(p) == hash);
	}

	private static bool AssemblyMatches(string name, string hash)
	{
		Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly x) => x.GetName().Name == name);
		if (assembly != null)
		{
			return Hash(assembly.Location) == hash;
		}
		return false;
	}

	internal static void Install(string plugins, ManualLogSource logger)
	{
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Expected O, but got Unknown
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "SideLoader");
			if (assembly == null)
			{
				return;
			}
			string text = Hash(assembly.Location);
			if (text != "5da977a019f2158e9217a0e86c4be05a039ea0cd1a1ba6a78a759aa2931d9052" && text != "d56a937169c353096818b9a73c8c2aecce65eb2c4eb291dd79d4b717494c14ec")
			{
				return;
			}
			ice = FileMatches(plugins, "Mark.xml", "46ff99565271c5d644cab3dcf1b5b7e6a9d04dbc994e79f6175b72ed1ab60adc");
			fire = FileMatches(plugins, "Ralph.xml", "d269f533fcefcd91c4c4418ac7c2ffd83c64bd71b18a2e048f1dc24dfd730ed3");
			crusader = AssemblyMatches("Crusader", "dc4f1dedbc77f5dbb6a72c855e5af5510e2c68516d2d58c1cebaece9c20243cb");
			martial = AssemblyMatches("MartialArtist", "b015adfd33eff9416ee7eebcf1aed88c070d88b6bf62fa6b3286051a140a2521");
			if (ice || fire || crusader || martial)
			{
				log = logger;
				MethodInfo method = assembly.GetType("SideLoader.SL_SkillTree", throwOnError: true).GetMethod("ApplyRows", new Type[1] { typeof(int) });
				if (method == null)
				{
					throw new InvalidOperationException("Skill-tree API differs from the verified build.");
				}
				val = new Harmony("Outwardz.AetherialEndeavorsFixes.TrainerPrerequisites");
				val.Patch((MethodBase)method, new HarmonyMethod(typeof(TrainerPrerequisiteFix), "BeforeRows", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				logger.LogInfo((object)("Trainer prerequisite corrections ready: Ice Mage=" + ice + ", Fire Mage=" + fire + ", Crusader=" + crusader + ", Martial Artist=" + martial + ". Other definitions are unchanged."));
			}
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				val.UnpatchSelf();
			}
			logger.LogWarning((object)("Trainer prerequisite corrections inactive; original definitions retained. " + ex));
		}
	}

	private static object Read(object value, string name)
	{
		if (value == null)
		{
			return null;
		}
		FieldInfo field = value.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public);
		if (!(field == null))
		{
			return field.GetValue(value);
		}
		return null;
	}

	private static int Id(object slot)
	{
		object obj = Read(slot, "SkillID");
		if (!(obj is int))
		{
			return 0;
		}
		return (int)obj;
	}

	private static object Find(object tree, int rowIndex, int column)
	{
		if (!(Read(tree, "SkillRows") is IEnumerable enumerable))
		{
			return null;
		}
		foreach (object item in enumerable)
		{
			if (!object.Equals(Read(item, "RowIndex"), rowIndex) || !(Read(item, "Slots") is IEnumerable enumerable2))
			{
				continue;
			}
			foreach (object item2 in enumerable2)
			{
				if (object.Equals(Read(item2, "ColumnIndex"), column))
				{
					return item2;
				}
			}
		}
		return null;
	}

	private static int Change(object slot, int id, Vector2 before, Vector2 after)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		if (slot == null || (id != 0 && Id(slot) != id))
		{
			return 0;
		}
		FieldInfo field = slot.GetType().GetField("RequiredSkillSlot", BindingFlags.Instance | BindingFlags.Public);
		if (!(field == null) && !(field.FieldType != typeof(Vector2)))
		{
			Vector2 val = (Vector2)field.GetValue(slot);
			if (((Vector2)(ref val)).Equals(before))
			{
				field.SetValue(slot, after);
				return 1;
			}
		}
		return 0;
	}

	internal static int Correct(object tree, string kind)
	{
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		switch (kind)
		{
		case "ice":
		case "fire":
		{
			bool flag = kind == "ice";
			object obj = Find(tree, 2, 2);
			if (Id(obj) != (flag ? (-56004) : (-56005)) || !object.Equals(Read(obj, "Breakthrough"), true))
			{
				return 0;
			}
			if (flag && Find(tree, 1, 2) == null)
			{
				num += Change(obj, -56004, new Vector2(1f, 2f), Vector2.zero);
			}
			num += Change(Find(tree, 3, 3), flag ? (-56006) : (-56021), new Vector2(2f, 0f), new Vector2(2f, 2f));
			num += Change(Find(tree, 3, 1), flag ? (-56007) : (-56020), new Vector2(2f, 0f), new Vector2(2f, 2f));
			break;
		}
		case "crusader":
			if (Find(tree, 1, 2) == null)
			{
				num += Change(Find(tree, 2, 1), 2502026, new Vector2(1f, 2f), Vector2.zero);
				break;
			}
			goto default;
		default:
			if (kind == "martial" && Find(tree, 3, 2) == null)
			{
				object obj2 = Find(tree, 2, 2);
				object slot = Read(obj2, "Choice1");
				object slot2 = Read(obj2, "Choice2");
				if (Id(slot) != 2502033 || Id(slot2) != 2502032)
				{
					return 0;
				}
				num += Change(obj2, 0, new Vector2(3f, 2f), Vector2.zero);
				num += Change(slot, 2502033, new Vector2(3f, 2f), Vector2.zero);
				num += Change(slot2, 2502032, new Vector2(3f, 2f), Vector2.zero);
			}
			break;
		}
		return num;
	}

	private static void BeforeRows(object __instance)
	{
		try
		{
			string text = Read(__instance, "Name") as string;
			string text2 = Read(__instance, "UID") as string;
			string text3 = ((ice && text == "MageIce" && text2 == "com.marcus.imtree") ? "ice" : ((fire && text == "FireMage" && text2 == "com.marcus.firetree") ? "fire" : ((crusader && text == "Crusader" && text2 == "Crusader") ? "crusader" : ((martial && text == "Martial Artist" && text2 == "Martial Artist") ? "martial" : null))));
			if (text3 != null)
			{
				int num = Correct(__instance, text3);
				if (num > 0 && log != null)
				{
					log.LogInfo((object)("Corrected " + num + " invalid prerequisite coordinate(s) in " + text + "; skills, costs and breakthrough flags are unchanged."));
				}
			}
		}
		catch (Exception ex)
		{
			if (log != null)
			{
				log.LogWarning((object)("Trainer prerequisite check could not finish; original tree construction continues. " + ex));
			}
		}
	}
}
internal static class SceneExitFix
{
	internal sealed class ReturnRoutine : IEnumerator, IDisposable
	{
		private readonly IEnumerator original;

		private bool entered;

		private bool finished;

		private bool disposed;

		private int epoch;

		public object Current => original.Current;

		internal ReturnRoutine(IEnumerator original)
		{
			this.original = original;
		}

		public bool MoveNext()
		{
			if (finished)
			{
				return false;
			}
			if (!entered)
			{
				entered = true;
				epoch = returnEpoch;
				returnDepth++;
			}
			try
			{
				if (original.MoveNext())
				{
					return true;
				}
				Finish();
				return false;
			}
			catch
			{
				Finish();
				throw;
			}
		}

		public void Reset()
		{
			throw new NotSupportedException();
		}

		private void Finish()
		{
			if (!finished)
			{
				finished = true;
				if (entered && epoch == returnEpoch)
				{
					returnDepth--;
				}
			}
		}

		public void Dispose()
		{
			if (disposed)
			{
				return;
			}
			disposed = true;
			try
			{
				if (original is IDisposable disposable)
				{
					disposable.Dispose();
				}
			}
			finally
			{
				Finish();
			}
		}
	}

	private static ManualLogSource log;

	private static int returnDepth;

	private static int returnEpoch;

	internal static bool ReturningToMenu => returnDepth > 0;

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Expected O, but got Unknown
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Expected O, but got Unknown
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			if (DonorSceneFixes.SupportedGame(managed))
			{
				log = logger;
				MethodInfo method = typeof(NetworkLevelLoader).GetMethod("FinalizeRestart", BindingFlags.Instance | BindingFlags.NonPublic);
				MethodInfo method2 = typeof(CharacterManager).GetMethod("ClearAllCharacters", Type.EmptyTypes);
				MethodInfo method3 = typeof(NetworkLevelLoader).GetMethod("BaseLoadLevel", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[3]
				{
					typeof(int),
					typeof(float),
					typeof(bool)
				}, null);
				if (method == null || method.ReturnType != typeof(IEnumerator) || method2 == null || method3 == null)
				{
					throw new InvalidOperationException("Scene exit API differs from the verified game build.");
				}
				val = new Harmony("Outwardz.AetherialEndeavorsFixes.SceneExit");
				val.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(SceneExitFix), "TrackReturn", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)method2, new HarmonyMethod(typeof(SceneExitFix), "BeforeClearCharacters", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)method3, new HarmonyMethod(typeof(SceneExitFix), "NewWorldLoad", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				logger.LogInfo((object)"Scene exit guards ready: stop departing NPC behavior before character destruction; track the complete return-to-menu audio transition.");
			}
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				val.UnpatchSelf();
			}
			logger.LogWarning((object)("Scene exit guards inactive; original cleanup retained. " + ex));
		}
	}

	private static void TrackReturn(ref IEnumerator __result)
	{
		if (__result != null)
		{
			__result = new ReturnRoutine(__result);
		}
	}

	private static void NewWorldLoad()
	{
		returnEpoch++;
		returnDepth = 0;
	}

	private static void BeforeClearCharacters()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		if (!ReturningToMenu)
		{
			return;
		}
		Scene activeScene = SceneManager.GetActiveScene();
		if (!((Scene)(ref activeScene)).IsValid() || !((Scene)(ref activeScene)).isLoaded || ((Scene)(ref activeScene)).name == "DontDestroyOnLoad")
		{
			return;
		}
		int num = 0;
		BehaviourTreeOwner[] array = Object.FindObjectsOfType<BehaviourTreeOwner>();
		foreach (BehaviourTreeOwner val in array)
		{
			if (!Object.op_Implicit((Object)(object)val) || ((Component)val).gameObject.scene != activeScene || (!((GraphOwner)val).isRunning && !((GraphOwner)val).isPaused))
			{
				continue;
			}
			try
			{
				((GraphOwner)val).StopBehaviour(true);
				num++;
			}
			catch (Exception ex)
			{
				if (log != null)
				{
					log.LogWarning((object)("NPC behavior cleanup failed for " + ((Object)val).name + "; original destruction continues. " + ex));
				}
			}
		}
		if (log != null && num > 0)
		{
			log.LogInfo((object)("Stopped " + num + " departing NPC behavior tree(s) before character cleanup in " + ((Scene)(ref activeScene)).name + "."));
		}
	}
}
public sealed class StartupOptimizer : MonoBehaviour
{
	private ManualLogSource Logger;

	private ConfigEntry<bool> enabledSetting;

	private Type serializerType;

	private EventInfo beforeLoad;

	private Action callback;

	private bool attempted;

	private static StartupOptimizer active;

	private Harmony harmony;

	private Func<Type[]> currentTypes;

	private Type[] warmedTypes;

	private Dictionary<Type, XmlSerializer> warmedCache;

	private Dictionary<Type, XmlSerializer> ownedReaders;

	public void Initialize(ManualLogSource logger, ConfigFile config)
	{
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Expected O, but got Unknown
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Expected O, but got Unknown
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Expected O, but got Unknown
		Logger = logger;
		enabledSetting = config.Bind<bool>("Startup", "Enabled", true, "Reduce SideLoader startup overhead with shared XML readers and efficient initial debug-console text. Disable and restart to use original startup behavior.");
		if (!enabledSetting.Value)
		{
			return;
		}
		try
		{
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "SideLoader");
			if (assembly == null)
			{
				return;
			}
			string text;
			using (FileStream inputStream = File.OpenRead(assembly.Location))
			{
				using SHA256 sHA = SHA256.Create();
				text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
			}
			if (text != "5da977a019f2158e9217a0e86c4be05a039ea0cd1a1ba6a78a759aa2931d9052" && text != "d56a937169c353096818b9a73c8c2aecce65eb2c4eb291dd79d4b717494c14ec")
			{
				Logger.LogWarning((object)"Startup optimization inactive: unrecognized SideLoader build. Original loading is retained.");
				return;
			}
			serializerType = assembly.GetType("SideLoader.Serializer", throwOnError: true);
			currentTypes = (Func<Type[]>)Delegate.CreateDelegate(typeof(Func<Type[]>), serializerType.GetProperty("SLTypes", BindingFlags.Static | BindingFlags.Public).GetGetMethod());
			beforeLoad = assembly.GetType("SideLoader.SL", throwOnError: true).GetEvent("BeforePacksLoaded", BindingFlags.Static | BindingFlags.Public);
			if (beforeLoad == null || beforeLoad.EventHandlerType != typeof(Action))
			{
				throw new InvalidOperationException("Unexpected SideLoader startup event.");
			}
			active = this;
			harmony = new Harmony("Outwardz.AetherialEndeavorsFixes.Startup");
			harmony.Patch((MethodBase)serializerType.GetMethod("GetXmlSerializer", BindingFlags.Static | BindingFlags.Public), new HarmonyMethod(typeof(StartupOptimizer), "CheckRegisteredTypes", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Type type = assembly.GetType("SideLoader.UI.Modules.DebugConsole", throwOnError: true);
			ConstructorInfo constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(GameObject) }, null);
			if (constructor == null || constructor.GetMethodBody().ExceptionHandlingClauses.Count != 0)
			{
				throw new InvalidOperationException("Unexpected SideLoader console constructor.");
			}
			harmony.Patch((MethodBase)constructor, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(StartupOptimizer), "ConsoleConstructor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			callback = Warmup;
			Logger.LogInfo((object)"Shared XML reader optimization ready; waits for all plugin types before pack loading.");
		}
		catch (Exception ex)
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogWarning((object)("Startup optimization inactive; original loading retained. " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private static IEnumerable<CodeInstruction> ConsoleConstructor(IEnumerable<CodeInstruction> input)
	{
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Expected O, but got Unknown
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Expected O, but got Unknown
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Expected O, but got Unknown
		List<CodeInstruction> list = input.ToList();
		int num = list.FindIndex((CodeInstruction i) => i.operand is MethodInfo && ((MethodInfo)i.operand).Name == "ConstructUI");
		int num2 = num + 2;
		int num3 = list.FindIndex((CodeInstruction i) => i.operand is MethodInfo && ((MethodInfo)i.operand).Name == "set_text" && ((MethodInfo)i.operand).DeclaringType == typeof(InputField));
		FieldInfo fieldInfo = list.Select((CodeInstruction i) => i.operand as FieldInfo).FirstOrDefault((FieldInfo f) => f != null && f.Name == "s_preInitMessages" && f.FieldType == typeof(List<string>));
		if (num < 0 || num2 < 0 || num3 < 4 || fieldInfo == null || list[num2].opcode != OpCodes.Ldstr || (string)list[num2].operand != "" || list[num2 + 1].opcode != OpCodes.Stloc_0 || list[num3 - 3].opcode != OpCodes.Ldarg_0 || list[num3 - 2].opcode != OpCodes.Ldfld || list[num3 - 1].opcode != OpCodes.Ldloc_0)
		{
			throw new InvalidOperationException("Console startup loop differs from the verified build.");
		}
		CodeInstruction val = new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo);
		val.labels.AddRange(list[num2].labels);
		list.RemoveRange(num2, num3 - 3 - num2);
		list.InsertRange(num2, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
		{
			val,
			new CodeInstruction(OpCodes.Call, (object)typeof(ConsoleStartupText).GetMethod("Build")),
			new CodeInstruction(OpCodes.Stloc_0, (object)null)
		});
		return list;
	}

	public static void ReportConsoleBuild(int history, int shown)
	{
		if ((Object)(object)active != (Object)null)
		{
			active.Logger.LogInfo((object)("Console startup view built from " + history + " messages; displays " + shown + " characters while retaining full message history and disk logs."));
		}
	}

	private void Start()
	{
		if (beforeLoad != null && callback != null)
		{
			beforeLoad.AddEventHandler(null, callback);
		}
	}

	private static void CheckRegisteredTypes()
	{
		if ((Object)(object)active == (Object)null || active.warmedTypes == null)
		{
			return;
		}
		try
		{
			if (!object.ReferenceEquals(active.currentTypes(), active.warmedTypes))
			{
				active.ReleasePreparedReaders();
			}
		}
		catch (Exception ex)
		{
			active.ReleasePreparedReaders();
			active.Logger.LogWarning((object)("Reader cache validation reverted to original loading: " + ex.Message));
		}
	}

	private void ReleasePreparedReaders()
	{
		warmedTypes = null;
		if (warmedCache != null && ownedReaders != null)
		{
			foreach (KeyValuePair<Type, XmlSerializer> ownedReader in ownedReaders)
			{
				if (warmedCache.TryGetValue(ownedReader.Key, out var value) && object.ReferenceEquals(value, ownedReader.Value))
				{
					warmedCache.Remove(ownedReader.Key);
				}
			}
		}
		ownedReaders = null;
		warmedCache = null;
		Logger.LogInfo((object)"Additional XML types registered; released prepared readers so original loading includes the new types.");
	}

	private void Warmup()
	{
		if (attempted || !enabledSetting.Value)
		{
			return;
		}
		attempted = true;
		Stopwatch stopwatch = Stopwatch.StartNew();
		Dictionary<Type, XmlSerializer> dictionary = null;
		List<Type> list = new List<Type>();
		try
		{
			PropertyInfo property = serializerType.GetProperty("SLTypes", BindingFlags.Static | BindingFlags.Public);
			FieldInfo field = serializerType.GetField("xmlCache", BindingFlags.Static | BindingFlags.NonPublic);
			if (property == null || field == null || field.FieldType != typeof(Dictionary<Type, XmlSerializer>))
			{
				throw new InvalidOperationException("Unexpected SideLoader XML cache layout.");
			}
			Type[] source = (Type[])property.GetValue(null, null);
			Type[] array = source.ToArray();
			dictionary = (Dictionary<Type, XmlSerializer>)field.GetValue(null);
			if (dictionary == null)
			{
				throw new InvalidOperationException("XML cache was not initialized.");
			}
			Dictionary<Type, XmlSerializer> prepared = SharedXmlReaders.Build(array);
			Type[] second = (Type[])property.GetValue(null, null);
			if (!array.SequenceEqual(second))
			{
				throw new InvalidOperationException("Registered XML types changed during reader preparation.");
			}
			foreach (KeyValuePair<Type, XmlSerializer> item in prepared)
			{
				if (!dictionary.ContainsKey(item.Key))
				{
					dictionary.Add(item.Key, item.Value);
					list.Add(item.Key);
				}
			}
			ownedReaders = list.ToDictionary((Type t) => t, (Type t) => prepared[t]);
			warmedCache = dictionary;
			warmedTypes = source;
			Logger.LogInfo((object)("Prepared " + list.Count + " shared XML readers in " + stopwatch.Elapsed.TotalSeconds.ToString("F3") + "s; retained existing readers and all " + array.Length + " registered content types."));
		}
		catch (Exception ex)
		{
			if (dictionary != null)
			{
				foreach (Type item2 in list)
				{
					dictionary.Remove(item2);
				}
			}
			ownedReaders = null;
			warmedCache = null;
			warmedTypes = null;
			Logger.LogWarning((object)("Shared XML preparation skipped; original loading retained. " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private void OnDestroy()
	{
		if (beforeLoad != null && callback != null)
		{
			beforeLoad.RemoveEventHandler(null, callback);
		}
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if ((Object)(object)active == (Object)(object)this)
		{
			active = null;
		}
	}
}
public static class SharedXmlReaders
{
	public static Dictionary<Type, XmlSerializer> Build(Type[] types)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		if (types == null || types.Length == 0)
		{
			throw new ArgumentException("No registered SideLoader types.");
		}
		types = types.Distinct().ToArray();
		XmlReflectionImporter val = new XmlReflectionImporter();
		Type[] array = types;
		foreach (Type type in array)
		{
			val.IncludeType(type);
		}
		XmlMapping[] array2 = (XmlMapping[])(object)new XmlMapping[types.Length];
		for (int j = 0; j < types.Length; j++)
		{
			array2[j] = (XmlMapping)(object)val.ImportTypeMapping(types[j]);
		}
		XmlSerializer[] array3 = XmlSerializer.FromMappings(array2);
		if (array3 == null || array3.Length != types.Length)
		{
			throw new InvalidOperationException("Incomplete shared serializer batch.");
		}
		Dictionary<Type, XmlSerializer> dictionary = new Dictionary<Type, XmlSerializer>();
		for (int k = 0; k < types.Length; k++)
		{
			if (array3[k] == null)
			{
				throw new InvalidOperationException("Missing shared serializer.");
			}
			dictionary.Add(types[k], array3[k]);
		}
		return dictionary;
	}
}
public static class ConsoleStartupText
{
	public static string Build(List<string> messages)
	{
		StringBuilder stringBuilder = new StringBuilder(10000);
		int num = messages.Count - 1;
		while (num >= 0 && stringBuilder.Length < 10000)
		{
			if (stringBuilder.Length > 0)
			{
				stringBuilder.Append("\r\n", 0, Math.Min(2, 10000 - stringBuilder.Length));
			}
			string text = messages[num];
			if (!string.IsNullOrEmpty(text))
			{
				stringBuilder.Append(text, 0, Math.Min(text.Length, 10000 - stringBuilder.Length));
			}
			num--;
		}
		StartupOptimizer.ReportConsoleBuild(messages.Count, stringBuilder.Length);
		return stringBuilder.ToString();
	}
}
internal static class QuickSlotLoadFix
{
	private static FieldInfo slots;

	private static ManualLogSource log;

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

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Expected O, but got Unknown
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				logger.LogWarning((object)"Quick-slot loading fix inactive: unsupported game build.");
				return;
			}
			slots = typeof(CharacterQuickSlotManager).GetField("m_quickSlots", BindingFlags.Instance | BindingFlags.NonPublic);
			Type nestedType = typeof(Character).GetNestedType("<ApplyQuickSlotsCoroutine>d__595", BindingFlags.NonPublic);
			MethodInfo methodInfo = ((nestedType == null) ? null : nestedType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic));
			if (slots == null || slots.FieldType != typeof(QuickSlot[]) || methodInfo == null || methodInfo.ReturnType != typeof(bool))
			{
				throw new InvalidOperationException("Quick-slot save-loading layout differs from the tested build.");
			}
			log = logger;
			val = new Harmony("Outwardz.AetherialEndeavorsFixes.QuickSlotLoad");
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(QuickSlotLoadFix).GetMethod("Transpile", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Quick-slot loading fix ready: unavailable saved slots are skipped; valid slots and saved data are retained.");
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				val.UnpatchSelf();
			}
			logger.LogWarning((object)("Quick-slot loading fix could not start; original loader retained. " + ex));
		}
	}

	private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		MethodInfo get = typeof(CharacterQuickSlotManager).GetMethod("GetQuickSlot", new Type[1] { typeof(int) });
		CodeInstruction[] array = list.Where((CodeInstruction i) => i.opcode == OpCodes.Callvirt && object.Equals(i.operand, get)).ToArray();
		if (get == null || array.Length != 1)
		{
			throw new InvalidOperationException("Quick-slot load call differs from the tested build.");
		}
		array[0].opcode = OpCodes.Call;
		array[0].operand = typeof(QuickSlotLoadFix).GetMethod("AvailableSlot", BindingFlags.Static | BindingFlags.NonPublic);
		return list;
	}

	private static QuickSlot AvailableSlot(CharacterQuickSlotManager manager, int index)
	{
		if (!Object.op_Implicit((Object)(object)manager))
		{
			return null;
		}
		QuickSlot[] array = slots.GetValue(manager) as QuickSlot[];
		if (array != null && index >= 0 && index < array.Length)
		{
			return manager.GetQuickSlot(index);
		}
		string item = index + "/" + ((array == null) ? "uninitialized" : array.Length.ToString());
		if (log != null && reported.Count < 16 && reported.Add(item))
		{
			log.LogWarning((object)("Skipped unavailable saved quick-slot index " + index + " (current count " + ((array == null) ? "uninitialized" : array.Length.ToString()) + "). Other assignments continue; the saved record was not edited."));
		}
		return null;
	}
}
internal static class JoinSynchronizationFix
{
	private static ManualLogSource log;

	private static int attempt;

	private static float started;

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				logger.LogWarning((object)"Join synchronization guard inactive: unsupported game build.");
				return;
			}
			Type nestedType = typeof(NetworkLevelLoader).GetNestedType("<ConnectionCoroutine>d__87", BindingFlags.NonPublic);
			MethodInfo methodInfo = ((nestedType == null) ? null : nestedType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic));
			MethodInfo method = typeof(NetworkInstantiateManager).GetMethod("RequestInstantiationData", Type.EmptyTypes);
			MethodInfo method2 = typeof(NetworkInstantiateManager).GetMethod("SendInstantiationData", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method3 = typeof(NetworkInstantiateManager).GetMethod("SendNewPlayerHasConnected", BindingFlags.Instance | BindingFlags.NonPublic);
			if (methodInfo == null || methodInfo.ReturnType != typeof(bool) || method == null || method2 == null || method3 == null)
			{
				throw new InvalidOperationException("Join synchronization methods differ from the tested build.");
			}
			log = logger;
			val = new Harmony("Outwardz.AetherialEndeavorsFixes.JoinSynchronization");
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, Hook("Transpile"), (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)method, Hook("Request"), (HarmonyMethod)null, (HarmonyMethod)null, Hook("RequestFinished"), (HarmonyMethod)null);
			val.Patch((MethodBase)method3, Hook("HostRequest"), (HarmonyMethod)null, (HarmonyMethod)null, Hook("HostFinished"), (HarmonyMethod)null);
			val.Patch((MethodBase)method2, Hook("Receiving"), (HarmonyMethod)null, (HarmonyMethod)null, Hook("Received"), (HarmonyMethod)null);
			logger.LogInfo((object)"Join synchronization guard ready: the native 30-second data timeout uses real time; request/host/reply failures remain visible.");
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				val.UnpatchSelf();
			}
			logger.LogWarning((object)("Join synchronization guard could not start; original protocol retained. " + ex));
		}
	}

	private static HarmonyMethod Hook(string name)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		return new HarmonyMethod(typeof(JoinSynchronizationFix).GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic));
	}

	private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		MethodInfo getMethod = typeof(Time).GetProperty("time").GetGetMethod();
		MethodInfo getMethod2 = typeof(Time).GetProperty("realtimeSinceStartup").GetGetMethod();
		List<int> list2 = new List<int>();
		for (int i = 0; i < list.Count; i++)
		{
			if (CodeInstructionExtensions.Calls(list[i], getMethod))
			{
				FieldInfo fieldInfo = ((i + 1 < list.Count) ? (list[i + 1].operand as FieldInfo) : null);
				FieldInfo fieldInfo2 = ((i + 2 < list.Count) ? (list[i + 2].operand as FieldInfo) : null);
				if ((fieldInfo != null && fieldInfo.Name == "<requestTime>5__4" && list[i + 1].opcode == OpCodes.Stfld) || (fieldInfo2 != null && fieldInfo2.Name == "<requestTime>5__4" && list[i + 2].opcode == OpCodes.Ldfld && i + 4 < list.Count && list[i + 3].opcode == OpCodes.Sub && list[i + 4].opcode == OpCodes.Ldc_R4 && object.Equals(list[i + 4].operand, 30f)))
				{
					list2.Add(i);
				}
			}
		}
		if (getMethod2 == null || list2.Count != 2)
		{
			throw new InvalidOperationException("Native join timeout clock sites differ from the tested build.");
		}
		foreach (int item in list2)
		{
			list[item].operand = getMethod2;
		}
		return list;
	}

	private static string Context()
	{
		PhotonPlayer player = PhotonNetwork.player;
		PhotonPlayer masterClient = PhotonNetwork.masterClient;
		NetworkLevelLoader instance = NetworkLevelLoader.Instance;
		NetworkInstantiateManager instance2 = NetworkInstantiateManager.Instance;
		return "role=" + (PhotonNetwork.isMasterClient ? "host" : "guest") + ", inRoom=" + PhotonNetwork.inRoom + ", local=" + ((player == null) ? (-1) : player.ID) + ", master=" + ((masterClient == null) ? (-1) : masterClient.ID) + ", players=" + PhotonNetwork.playerList.Length + ", view=" + ((Object.op_Implicit((Object)(object)instance2) && Object.op_Implicit((Object)(object)((MonoBehaviour)instance2).photonView)) ? ((MonoBehaviour)instance2).photonView.viewID : (-1)) + ", scene=" + SceneManagerHelper.ActiveSceneName + ", loading=" + (Object.op_Implicit((Object)(object)instance) && instance.IsGameplayLoading) + ", timeScale=" + Time.timeScale;
	}

	private static void Report(string text, Exception error)
	{
		try
		{
			if (log != null)
			{
				if (error == null)
				{
					log.LogInfo((object)(text + "; " + Context()));
					return;
				}
				log.LogError((object)(text + "; " + Context() + "; " + error));
			}
		}
		catch
		{
		}
	}

	private static void Request()
	{
		attempt++;
		started = Time.realtimeSinceStartup;
		Report("World sync request " + attempt, null);
	}

	private static Exception RequestFinished(Exception __exception)
	{
		if (__exception != null)
		{
			Report("World sync request threw", __exception);
		}
		return __exception;
	}

	private static void HostRequest(PhotonMessageInfo __1)
	{
		Report("World sync host received request from " + ((__1.sender == null) ? (-1) : __1.sender.ID), null);
	}

	private static Exception HostFinished(Exception __exception)
	{
		Report((__exception == null) ? "World sync host request handler completed" : "World sync host request handler failed", __exception);
		return __exception;
	}

	private static void Receiving(string __0, string __2, string __3, string __4)
	{
		Report("World sync reply received for scene=" + __0 + ", payload characters=" + Length(__2) + "/" + Length(__3) + "/" + Length(__4), null);
	}

	private static int Length(string value)
	{
		return value?.Length ?? 0;
	}

	private static Exception Received(NetworkInstantiateManager __instance, Exception __exception)
	{
		Report((__exception == null) ? ("World sync reply handler completed; dataReceived=" + (Object.op_Implicit((Object)(object)__instance) && __instance.InstantiationDataReceived) + ", elapsed=" + (Time.realtimeSinceStartup - started).ToString("F2") + " real seconds") : "World sync reply application failed", __exception);
		return __exception;
	}
}
internal static class RuntimeKnown
{
	public const string ThiefHash = "42652e4c9a5f3acaea53852bda2e519de7647caeae1620192a3bc82a43c4c4a8";
}
internal static class RunicBarrierCompatibility
{
	private const int Shim = 8100220;

	private static Type skillType;

	private static FieldInfo target;

	private static FieldInfo newId;

	private static FieldInfo owner;

	private static FieldInfo effects;

	private static MethodInfo getSerializer;

	private static MethodInfo applyGroup;

	private static object none;

	private static Func<bool> packsLoaded;

	private static string definition;

	private static ManualLogSource log;

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

	private static string Hash(string path)
	{
		using FileStream inputStream = File.OpenRead(path);
		using SHA256 sHA = SHA256.Create();
		return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
	}

	private static IEnumerable<string> Definitions(string directory)
	{
		if ((File.GetAttributes(directory) & FileAttributes.ReparsePoint) != FileAttributes.None)
		{
			yield break;
		}
		try
		{
			string[] files = Directory.GetFiles(directory, "8100220*.xml");
			foreach (string file in files)
			{
				if ((File.GetAttributes(file) & FileAttributes.ReparsePoint) == 0)
				{
					yield return file;
				}
			}
		}
		finally
		{
		}
		try
		{
			string[] directories = Directory.GetDirectories(directory);
			foreach (string child in directories)
			{
				if (child.EndsWith(".disabled", StringComparison.OrdinalIgnoreCase) || child.EndsWith(".old", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				foreach (string item in Definitions(child))
				{
					yield return item;
				}
			}
		}
		finally
		{
		}
	}

	internal static void Install(string plugins, string managed, ManualLogSource logger)
	{
		//IL_043f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Expected O, but got Unknown
		//IL_045f: Unknown result type (might be due to invalid IL or missing references)
		//IL_046c: Expected O, but got Unknown
		//IL_052b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0539: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "RunicBarrier");
			if (assembly == null)
			{
				logger.LogInfo((object)"Runic Barrier compatibility inactive: Runic Barrier is not installed.");
				return;
			}
			if (!RunicBarrierKnown.SupportedPlugin(Hash(assembly.Location)) || !DonorSceneFixes.SupportedGame(managed))
			{
				throw new InvalidOperationException("Unsupported Runic Barrier or game build.");
			}
			string[] array = new string[RunicBarrierKnown.DefinitionHashes.Length];
			foreach (string item in Definitions(plugins))
			{
				int num = Array.IndexOf(RunicBarrierKnown.DefinitionHashes, Hash(item));
				if (num >= 0)
				{
					if (array[num] != null)
					{
						throw new InvalidOperationException("Duplicate supported Shim definition.");
					}
					array[num] = File.ReadAllText(item);
				}
			}
			if (array.Any((string x) => x == null))
			{
				throw new InvalidOperationException("The supported Runic Barrier, Classfixes Part 2 and Supportive Rune Sage definitions are not all present.");
			}
			Assembly assembly2 = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "SideLoader");
			if (assembly2 == null || Hash(assembly2.Location) != "5da977a019f2158e9217a0e86c4be05a039ea0cd1a1ba6a78a759aa2931d9052")
			{
				throw new InvalidOperationException("Unsupported SideLoader build.");
			}
			skillType = assembly2.GetType("SideLoader.SL_AttackSkill", throwOnError: true);
			Type type = assembly2.GetType("SideLoader.SL_Item", throwOnError: true);
			Type type2 = assembly2.GetType("SideLoader.SL_EffectTransform", throwOnError: true);
			Type type3 = assembly2.GetType("SideLoader.EditBehaviours", throwOnError: true);
			target = type.GetField("Target_ItemID");
			newId = type.GetField("New_ItemID");
			owner = type.GetField("SLPackName");
			effects = type.GetField("EffectTransforms");
			getSerializer = assembly2.GetType("SideLoader.Serializer", throwOnError: true).GetMethod("GetXmlSerializer", new Type[1] { typeof(Type) });
			applyGroup = type2.GetMethod("ApplyToTransform", new Type[2]
			{
				typeof(Transform),
				type3
			});
			MethodInfo method = type.GetMethod("OnLateApply", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(object[]) }, null);
			if (target == null || target.FieldType != typeof(int) || newId == null || newId.FieldType != typeof(int) || owner == null || owner.FieldType != typeof(string) || effects == null || effects.FieldType != type2.MakeArrayType() || getSerializer == null || applyGroup == null || applyGroup.ReturnType != typeof(Transform) || method == null || method.ReturnType != typeof(void))
			{
				throw new InvalidOperationException("SideLoader rune effect API differs from the tested build.");
			}
			none = Enum.Parse(type3, "NONE");
			if (Convert.ToInt32(none) != 0)
			{
				throw new InvalidOperationException("Unexpected SideLoader append behavior.");
			}
			PropertyInfo property = assembly2.GetType("SideLoader.SL", throwOnError: true).GetProperty("PacksLoaded", BindingFlags.Static | BindingFlags.Public);
			if (property == null || property.PropertyType != typeof(bool) || property.GetGetMethod() == null)
			{
				throw new InvalidOperationException("SideLoader pack readiness API differs from the tested build.");
			}
			packsLoaded = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), property.GetGetMethod());
			definition = array[0];
			log = logger;
			ValidateDefinition(definition);
			val = new Harmony("Outwardz.AetherialEndeavorsFixes.RunicBarrier");
			val.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(RunicBarrierCompatibility).GetMethod("AfterTemplate", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			string[] array2 = new string[2] { "RunicBarrier.VFXTrim", "RunicBarrier.VFXMap" };
			foreach (string text in array2)
			{
				Type type4 = assembly.GetType(text, throwOnError: false);
				if (!(type4 == null) || !(text == "RunicBarrier.VFXMap"))
				{
					MethodInfo methodInfo = ((type4 == null) ? null : type4.GetMethod("TryOnce", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
					if (methodInfo == null || methodInfo.ReturnType != typeof(void) || methodInfo.GetParameters().Length != 0)
					{
						throw new InvalidOperationException("Runic Barrier visual setup differs from the tested build.");
					}
					val.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(RunicBarrierCompatibility).GetMethod("VisualsReady", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			logger.LogInfo((object)"Runic Barrier compatibility ready: refresh the ward after supported Shim templates; other rune effects and costs are retained.");
			logger.LogInfo((object)"Runic Barrier visual setup waits for SideLoader packs; startup does not look up unregistered ward statuses.");
		}
		catch (Exception ex)
		{
			definition = null;
			packsLoaded = null;
			if (val != null)
			{
				try
				{
					val.UnpatchSelf();
				}
				catch (Exception ex2)
				{
					logger.LogWarning((object)("Runic Barrier hook cleanup failed: " + ex2));
				}
			}
			logger.LogWarning((object)("Runic Barrier compatibility could not start; original mod behavior retained. " + ex));
		}
	}

	private static bool VisualsReady()
	{
		if (packsLoaded != null)
		{
			return packsLoaded();
		}
		return false;
	}

	private static object ReadGroup()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		XmlSerializer val = (XmlSerializer)getSerializer.Invoke(null, new object[1] { skillType });
		StringReader stringReader = new StringReader(definition);
		XmlReaderSettings val2 = new XmlReaderSettings();
		val2.DtdProcessing = (DtdProcessing)0;
		val2.XmlResolver = null;
		XmlReader val3 = XmlReader.Create((TextReader)stringReader, val2);
		object obj;
		try
		{
			obj = val.Deserialize(val3);
		}
		finally
		{
			((IDisposable)val3)?.Dispose();
		}
		Array array = ((obj == null) ? null : (effects.GetValue(obj) as Array));
		if (obj == null || obj.GetType() != skillType || (int)target.GetValue(obj) != 8100220 || (int)newId.GetValue(obj) != 8100220 || array == null || array.Length != 1)
		{
			throw new InvalidOperationException("Unexpected Runic Barrier donor template.");
		}
		object value = array.GetValue(0);
		if (value == null || (string)value.GetType().GetField("TransformName").GetValue(value) != "RunicBarrier")
		{
			throw new InvalidOperationException("Unexpected Runic Barrier effect group.");
		}
		return value;
	}

	private static Transform[] OwnedGroups(Transform parent)
	{
		List<Transform> list = new List<Transform>();
		for (int i = 0; i < parent.childCount; i++)
		{
			Transform child = parent.GetChild(i);
			if (Object.op_Implicit((Object)(object)child) && ((Object)child).name == "RunicBarrier")
			{
				list.Add(child);
			}
		}
		return list.ToArray();
	}

	private static void AfterTemplate(object __instance, object[] __0)
	{
		if (definition == null || __instance == null || __instance.GetType() != skillType || __0 == null || __0.Length == 0)
		{
			return;
		}
		try
		{
			if ((int)target.GetValue(__instance) != 8100220 || (int)newId.GetValue(__instance) != 8100220)
			{
				return;
			}
			string text = (string)owner.GetValue(__instance);
			if (!UnityEngineExtensions.Contains<string>(RunicBarrierKnown.Owners, text))
			{
				return;
			}
			object obj = __0[0];
			Item val = (Item)((obj is Item) ? obj : null);
			if (!Object.op_Implicit((Object)(object)val) || val.ItemID != 8100220)
			{
				return;
			}
			object group = ReadGroup();
			Transform parent = ((Component)val).transform;
			RunicBarrierEffects.Refresh(() => OwnedGroups(parent), delegate
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Expected O, but got Unknown
				Transform val2 = (Transform)applyGroup.Invoke(group, new object[2] { parent, none });
				if (!Object.op_Implicit((Object)(object)val2))
				{
					throw new InvalidOperationException("Runic Barrier effect group creation failed.");
				}
				return val2;
			}, delegate(Transform old)
			{
				Object.DestroyImmediate((Object)(object)((Component)old).gameObject);
			});
			if (reported.Add(text))
			{
				log.LogInfo((object)("Runic Barrier effect group retained after Shim from " + text + "; base and amplified raise/dismiss actions preserved."));
				if (reported.Count == RunicBarrierKnown.Owners.Length)
				{
					log.LogInfo((object)"All three supported Shim templates now retain one Runic Barrier group.");
				}
			}
		}
		catch (Exception ex)
		{
			log.LogError((object)("Runic Barrier effect refresh failed; existing effect groups retained where possible. " + ex));
		}
	}

	internal static void ValidateDefinition(string xml)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		XmlDocument val = new XmlDocument();
		val.XmlResolver = null;
		XmlDocument val2 = val;
		StringReader stringReader = new StringReader(xml);
		XmlReaderSettings val3 = new XmlReaderSettings();
		val3.DtdProcessing = (DtdProcessing)0;
		val3.XmlResolver = null;
		XmlReader val4 = XmlReader.Create((TextReader)stringReader, val3);
		try
		{
			val2.Load(val4);
		}
		finally
		{
			((IDisposable)val4)?.Dispose();
		}
		XmlElement documentElement = val2.DocumentElement;
		if (documentElement == null || ((XmlNode)documentElement).Name != "SL_AttackSkill" || ((XmlNode)documentElement).NamespaceURI.Length != 0)
		{
			throw new InvalidOperationException("Unexpected Runic Barrier donor template.");
		}
		string[] array = new string[2] { "Target_ItemID", "New_ItemID" };
		foreach (string text in array)
		{
			XmlNodeList val5 = ((XmlNode)documentElement).SelectNodes(text);
			if (val5.Count != 1 || !int.TryParse(val5[0].InnerText, out var result) || result != 8100220)
			{
				throw new InvalidOperationException("Unexpected Runic Barrier donor item ID.");
			}
		}
		XmlNodeList val6 = ((XmlNode)documentElement).SelectNodes("EffectTransforms/SL_EffectTransform");
		if (((XmlNode)documentElement).SelectNodes("EffectTransforms").Count != 1 || val6.Count != 1 || val6[0].SelectNodes("TransformName").Count != 1 || val6[0].SelectSingleNode("TransformName").InnerText != "RunicBarrier")
		{
			throw new InvalidOperationException("Unexpected Runic Barrier effect group.");
		}
	}
}
internal static class RunicBarrierEffects
{
	internal static T Refresh<T>(Func<T[]> ownedGroups, Func<T> create, Action<T> remove) where T : class
	{
		T[] previous = ownedGroups();
		T fresh;
		try
		{
			fresh = create();
			if (fresh == null || !ownedGroups().Any((T x) => object.ReferenceEquals(x, fresh)))
			{
				throw new InvalidOperationException("Runic Barrier effect group was not created under the rune.");
			}
		}
		catch
		{
			foreach (T item in from x in ownedGroups()
				where !previous.Any((T p) => object.ReferenceEquals(p, x))
				select x)
			{
				remove(item);
			}
			throw;
		}
		T[] array = previous;
		foreach (T val in array)
		{
			if (!object.ReferenceEquals(val, fresh))
			{
				remove(val);
			}
		}
		return fresh;
	}
}
internal static class RunicBarrierKnown
{
	internal const string PluginHash = "8d317208739d060ec62ec45250853289e8a2334faeb79206a927c7514e0f8f59";

	internal const string Plugin101Hash = "84f23d9dd3aabcf95e37b8a8ae8466686c7fcc07d70bc5f961142c663423c618";

	internal static readonly string[] DefinitionHashes = new string[3] { "4e57d616f4c4eda9601e9f1d488a3f28af4d7be8f8c6135ed8be127a69a5bff5", "6b14d62efed23f723b54a70a1381efbd964a86ecf351fef0fb5892dffd5a8fef", "6e0e8e3c78277085b054edb8058c5d4118f9d6a9d969c05474df1551e5b1e179" };

	internal static readonly string[] Owners = new string[3] { "Wrango-Runic_Barrier", "classfixesmos", "GarstigeHobbitse-Supportive_Rune_Sage_EN" };

	internal static bool SupportedPlugin(string hash)
	{
		if (!(hash == "8d317208739d060ec62ec45250853289e8a2334faeb79206a927c7514e0f8f59"))
		{
			return hash == "84f23d9dd3aabcf95e37b8a8ae8466686c7fcc07d70bc5f961142c663423c618";
		}
		return true;
	}
}
internal static class AudioTransitionDiagnostics
{
	internal const string MissingManager = "[Audio] The manager in Global.AudioManager is being destroyed and no other living one exists. Sound will fail until a scene brings one.";

	internal static bool Quitting;

	internal static bool ExpectedTeardown(bool quitting, bool loaderExists, bool inLoading)
	{
		if (!quitting)
		{
			if (loaderExists)
			{
				return inLoading;
			}
			return false;
		}
		return true;
	}

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Expected O, but got Unknown
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		Harmony val = null;
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				return;
			}
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetType("Champions_of_Elatt.NPCs.AudioManagerGuard/OnDestroyPatch".Replace('/', '+')) != null);
			if (assembly == null)
			{
				return;
			}
			string text;
			using (FileStream inputStream = File.OpenRead(assembly.Location))
			{
				using SHA256 sHA = SHA256.Create();
				text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
			}
			if (text != "2a50e742d0eee9aeec686ac768b3ca1ea2828376477d7e9dd83e84739a03d895" && text != "f65129f3a639a3f439d4e7c17b90a91b8a61553e1d0dafa4896c5d89b3584dd8")
			{
				throw new InvalidOperationException("Unsupported Champions audio diagnostic build.");
			}
			Type type = assembly.GetType("Champions_of_Elatt.NPCs.AudioManagerGuard+OnDestroyPatch", throwOnError: true);
			MethodInfo method = type.GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[1] { typeof(GlobalAudioManager) }, null);
			if (method == null || method.ReturnType != typeof(void))
			{
				throw new InvalidOperationException("Audio teardown diagnostic API differs from the tested build.");
			}
			val = new Harmony("Outwardz.AetherialEndeavorsFixes.AudioTransitionDiagnostics");
			val.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(AudioTransitionDiagnostics).GetMethod("Transpile", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Audio teardown diagnostics ready: loading and application exit are informational; unexpected manager loss remains an error.");
		}
		catch (Exception ex)
		{
			if (val != null)
			{
				try
				{
					val.UnpatchSelf();
				}
				catch (Exception ex2)
				{
					logger.LogWarning((object)("Audio diagnostic hook cleanup failed: " + ex2));
				}
			}
			logger.LogWarning((object)("Audio teardown diagnostic correction could not start; original diagnostics retained. " + ex));
		}
	}

	private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		MethodInfo method = typeof(ManualLogSource).GetMethod("LogError", new Type[1] { typeof(object) });
		MethodInfo method2 = typeof(AudioTransitionDiagnostics).GetMethod("Report", BindingFlags.Static | BindingFlags.NonPublic);
		int num = 0;
		for (int i = 1; i < list.Count; i++)
		{
			if (!(list[i - 1].opcode != OpCodes.Ldstr) && !((string)list[i - 1].operand != "[Audio] The manager in Global.AudioManager is being destroyed and no other living one exists. Sound will fail until a scene brings one.") && CodeInstructionExtensions.Calls(list[i], method))
			{
				list[i].opcode = OpCodes.Call;
				list[i].operand = method2;
				num++;
			}
		}
		if (num != 1)
		{
			throw new InvalidOperationException("Expected exactly one supported missing-manager diagnostic.");
		}
		return list;
	}

	private static void Report(ManualLogSource logger, object message)
	{
		bool flag = Quitting;
		try
		{
			NetworkLevelLoader instance = NetworkLevelLoader.Instance;
			flag = ExpectedTeardown(Quitting || SceneExitFix.ReturningToMenu, Object.op_Implicit((Object)(object)instance), Object.op_Implicit((Object)(object)instance) && instance.InLoading);
		}
		catch
		{
		}
		if (flag)
		{
			logger.LogInfo((object)"[Audio] Audio manager released during loading or application exit; the next scene supplies its own manager.");
		}
		else
		{
			logger.LogError(message);
		}
	}
}
internal sealed class NpcContinuationDispatcher
{
	private readonly TaskScheduler scheduler;

	private readonly int threadId;

	private readonly Func<Func<bool>> captureLifetime;

	private readonly Action<Exception> report;

	internal NpcContinuationDispatcher(TaskScheduler scheduler, Func<Func<bool>> captureLifetime, Action<Exception> report)
	{
		if (scheduler == null || captureLifetime == null)
		{
			throw new ArgumentNullException();
		}
		this.scheduler = scheduler;
		this.captureLifetime = captureLifetime;
		this.report = report;
		threadId = Thread.CurrentThread.ManagedThreadId;
	}

	private void RequireMainThread()
	{
		if (Thread.CurrentThread.ManagedThreadId != threadId)
		{
			throw new InvalidOperationException("NPC continuation must be scheduled and executed on the Unity main thread.");
		}
	}

	internal Task<object> Continue(Task task, Func<Task, object> callback)
	{
		RequireMainThread();
		if (task == null || callback == null)
		{
			throw new ArgumentNullException();
		}
		Func<bool> alive = captureLifetime();
		return task.ContinueWith(delegate(Task antecedent)
		{
			RequireMainThread();
			if (!alive())
			{
				return (object)null;
			}
			try
			{
				return callback(antecedent);
			}
			catch (Exception obj)
			{
				if (report != null)
				{
					report(obj);
				}
				throw;
			}
		}, CancellationToken.None, TaskContinuationOptions.None, scheduler);
	}

	internal Task Continue(Task task, Action<Task> callback)
	{
		if (callback == null)
		{
			throw new ArgumentNullException();
		}
		return Continue(task, delegate(Task antecedent)
		{
			callback(antecedent);
			return (object)null;
		});
	}
}
internal static class SynchronizedNpcThreadFix
{
	internal const string HashA = "dd291a4a9b278e62d0a14cb3580398dff1ded9801da71ab8cdf5658cd8ca5a76";

	internal const string HashB = "278f61aad54301b4e471f2f78b9f3c7354baf489863941092b599199aca4bbd3";

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

	private static NpcContinuationDispatcher dispatcher;

	private static Harmony harmony;

	internal static void Install(string managed, ManualLogSource log)
	{
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Expected O, but got Unknown
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Expected O, but got Unknown
		if (dispatcher != null)
		{
			return;
		}
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				throw new InvalidOperationException("Unsupported game build.");
			}
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "SynchronizedWorldObjects");
			if (assembly == null)
			{
				log.LogInfo((object)"Synchronized NPC thread fix inactive: NPC helper is not loaded.");
				return;
			}
			string text;
			using (FileStream inputStream = File.OpenRead(assembly.Location))
			{
				using SHA256 sHA = SHA256.Create();
				text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
			}
			if (text != "dd291a4a9b278e62d0a14cb3580398dff1ded9801da71ab8cdf5658cd8ca5a76" && text != "278f61aad54301b4e471f2f78b9f3c7354baf489863941092b599199aca4bbd3")
			{
				throw new InvalidOperationException("Unsupported NPC helper file: " + text);
			}
			SynchronizationContext current = SynchronizationContext.Current;
			if (current == null || current.GetType().FullName != "UnityEngine.UnitySynchronizationContext")
			{
				throw new InvalidOperationException("Unity main-thread synchronization context is unavailable.");
			}
			Type type = assembly.GetType("SynchronizedWorldObjects.SynchronizedNPC", throwOnError: true);
			MethodInfo[] array = new MethodInfo[3]
			{
				type.GetMethod("SetupClientSide", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, new Type[5]
				{
					typeof(int),
					typeof(string),
					typeof(int),
					typeof(int),
					typeof(string)
				}, null),
				type.GetMethod("SetupServerSide", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null),
				type.GetMethod("AITick", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null)
			};
			if (array.Any((MethodInfo m) => m == null) || array[0].ReturnType != typeof(object) || array[1].ReturnType != typeof(object) || array[2].ReturnType != typeof(void))
			{
				throw new InvalidOperationException("NPC continuation methods differ from the tested helper.");
			}
			dispatcher = new NpcContinuationDispatcher(TaskScheduler.FromCurrentSynchronizationContext(), CaptureSceneLifetime, delegate(Exception ex2)
			{
				log.LogError((object)("Synchronized NPC callback failed on the main thread: " + ex2));
			});
			harmony = new Harmony("Outwardz.AetherialEndeavorsFixes.NpcMainThread");
			HarmonyMethod val = new HarmonyMethod(typeof(SynchronizedNpcThreadFix).GetMethod("Transpile", BindingFlags.Static | BindingFlags.NonPublic));
			MethodInfo[] array2 = array;
			foreach (MethodInfo methodInfo in array2)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			SceneManager.sceneUnloaded += SceneUnloaded;
			log.LogInfo((object)"Synchronized NPC main-thread fix ready: client retries, server setup and animation ticks; callbacks expire when their scene unloads.");
		}
		catch (Exception ex)
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			dispatcher = null;
			log.LogWarning((object)("Synchronized NPC thread fix could not start; other fixes remain active. " + ex));
		}
	}

	private static int Generation(int handle)
	{
		if (!generations.TryGetValue(handle, out var value))
		{
			return 0;
		}
		return value;
	}

	private static void SceneUnloaded(Scene scene)
	{
		generations[((Scene)(ref scene)).handle] = Generation(((Scene)(ref scene)).handle) + 1;
	}

	private static Func<bool> CaptureSceneLifetime()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		Scene scene = SceneManager.GetActiveScene();
		int handle = ((Scene)(ref scene)).handle;
		int generation = Generation(handle);
		bool valid = ((Scene)(ref scene)).IsValid() && ((Scene)(ref scene)).isLoaded;
		return () => valid && Generation(handle) == generation && ((Scene)(ref scene)).isLoaded;
	}

	private static Task<object> ContinueSetup(Task task, Func<Task, object> callback)
	{
		return dispatcher.Continue(task, callback);
	}

	private static Task ContinueAnimation(Task task, Action<Task> callback)
	{
		return dispatcher.Continue(task, callback);
	}

	internal static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		CodeInstruction[] array = list.Where((CodeInstruction i) => i.opcode == OpCodes.Callvirt && i.operand is MethodInfo && ((MethodInfo)i.operand).DeclaringType == typeof(Task) && ((MethodInfo)i.operand).Name == "ContinueWith").ToArray();
		CodeInstruction[] array2 = list.Where((CodeInstruction i) => i.opcode == OpCodes.Call && object.Equals(i.operand, typeof(Console).GetMethod("Read", Type.EmptyTypes))).ToArray();
		if (array.Length != 1 || array2.Length != 1)
		{
			throw new InvalidOperationException("Expected one NPC continuation and one unused console read.");
		}
		MethodInfo methodInfo = (MethodInfo)array[0].operand;
		MethodInfo method;
		if (methodInfo.IsGenericMethod && methodInfo.GetGenericArguments().SequenceEqual(new Type[1] { typeof(object) }) && (from p in methodInfo.GetParameters()
			select p.ParameterType).SequenceEqual(new Type[1] { typeof(Func<Task, object>) }))
		{
			method = typeof(SynchronizedNpcThreadFix).GetMethod("ContinueSetup", BindingFlags.Static | BindingFlags.NonPublic);
		}
		else
		{
			if (methodInfo.IsGenericMethod || !(from p in methodInfo.GetParameters()
				select p.ParameterType).SequenceEqual(new Type[1] { typeof(Action<Task>) }))
			{
				throw new InvalidOperationException("Unsupported NPC continuation signature.");
			}
			method = typeof(SynchronizedNpcThreadFix).GetMethod("ContinueAnimation", BindingFlags.Static | BindingFlags.NonPublic);
		}
		int num = list.IndexOf(array2[0]);
		if (num + 1 >= list.Count || list[num + 1].opcode != OpCodes.Pop)
		{
			throw new InvalidOperationException("Console read result unexpectedly used.");
		}
		array[0].opcode = OpCodes.Call;
		array[0].operand = method;
		list[num].opcode = OpCodes.Nop;
		list[num].operand = null;
		list[num + 1].opcode = OpCodes.Nop;
		list[num + 1].operand = null;
		return list;
	}
}
public static class ThiefEquipment
{
	private sealed class State
	{
		public Stat DetectStat;

		public Stat VisualStat;

		public StatStack Detect;

		public StatStack Visual;
	}

	public const int EnchantmentId = -30442;

	private static readonly ConditionalWeakTable<CharacterStats, State> states = new ConditionalWeakTable<CharacterStats, State>();

	public static void Refresh(CharacterStats stats, Character character, Stat detect, Stat visual)
	{
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Expected O, but got Unknown
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		if ((Object)(object)stats == (Object)null)
		{
			return;
		}
		bool flag = false;
		if ((Object)(object)character != (Object)null && (Object)(object)character.Inventory != (Object)null && (Object)(object)character.Inventory.Equipment != (Object)null)
		{
			Item equippedItem = character.Inventory.Equipment.GetEquippedItem((EquipmentSlotIDs)7);
			Equipment val = (Equipment)(object)((equippedItem is Equipment) ? equippedItem : null);
			flag = (Object)(object)val != (Object)null && val.ActiveEnchantmentIDs != null && val.ActiveEnchantmentIDs.Contains(-30442);
		}
		if (states.TryGetValue(stats, out var value))
		{
			if (flag && detect == value.DetectStat && visual == value.VisualStat)
			{
				return;
			}
			Stop(value);
			states.Remove(stats);
			value = null;
		}
		if (!flag || detect == null || visual == null)
		{
			return;
		}
		State state = new State();
		state.DetectStat = detect;
		state.VisualStat = visual;
		value = state;
		try
		{
			value.Detect = detect.AddStack(new StatStack("AetherialFixes.Thief.Detect", -1f, -12f, (Tag[])null), false);
			value.Visual = visual.AddStack(new StatStack("AetherialFixes.Thief.Visual", -1f, -12f, (Tag[])null), false);
			if (value.Detect == null || value.Visual == null)
			{
				throw new InvalidOperationException("Could not attach Thief stat bonuses.");
			}
			detect.Update();
			visual.Update();
			states.Add(stats, value);
		}
		catch
		{
			Stop(value);
			throw;
		}
	}

	private static void Stop(State state)
	{
		if (state.Detect != null)
		{
			state.Detect.Stop();
		}
		if (state.Visual != null)
		{
			state.Visual.Stop();
		}
		if (state.DetectStat != null)
		{
			state.DetectStat.Update();
		}
		if (state.VisualStat != null)
		{
			state.VisualStat.Update();
		}
	}
}
public sealed class NavigationDiagnostics : MonoBehaviour
{
	public ManualLogSource Log;

	private bool pending;

	private bool earlyPending;

	private string origin;

	private float due;

	private int warnings;

	private void OnEnable()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		Application.logMessageReceived += new LogCallback(OnMessage);
	}

	private void OnDisable()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		Application.logMessageReceived -= new LogCallback(OnMessage);
		pending = false;
		earlyPending = false;
		warnings = 0;
		origin = null;
	}

	private void OnMessage(string message, string trace, LogType type)
	{
		if (message != null && message.StartsWith("Failed to create agent because it is not close enough to the NavMesh", StringComparison.Ordinal))
		{
			warnings++;
			if (!pending)
			{
				pending = true;
				earlyPending = true;
				due = Time.realtimeSinceStartup + 10f;
				origin = (string.IsNullOrEmpty(trace) ? "No stack trace supplied by Unity." : trace.Substring(0, Math.Min(trace.Length, 2400)));
			}
		}
	}

	private void Update()
	{
		if (earlyPending)
		{
			earlyPending = false;
			if (Log != null)
			{
				Log.LogInfo((object)("Navigation warning origin: " + origin));
				Report(warnings, early: true);
			}
			origin = null;
		}
		if (pending && !(Time.realtimeSinceStartup < due))
		{
			pending = false;
			int count = warnings;
			warnings = 0;
			if (Log != null)
			{
				Report(count, early: false);
			}
		}
	}

	private void Report(int count, bool early)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: 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)
		try
		{
			int num = 0;
			NavMeshAgent[] array = Object.FindObjectsOfType<NavMeshAgent>();
			foreach (NavMeshAgent val in array)
			{
				if (!Object.op_Implicit((Object)(object)val) || !((Behaviour)val).enabled || !((Component)val).gameObject.activeInHierarchy || val.isOnNavMesh)
				{
					continue;
				}
				num++;
				if (num <= 12)
				{
					Vector3 position = ((Component)val).transform.position;
					string text = ((Object)val).name;
					Transform parent = ((Component)val).transform.parent;
					while ((Object)(object)parent != (Object)null)
					{
						text = ((Object)parent).name + "/" + text;
						parent = parent.parent;
					}
					ManualLogSource log = Log;
					string[] array2 = new string[11]
					{
						early ? "Early navigation candidate: " : "Navigation check: ",
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null,
						null
					};
					Scene scene = ((Component)val).gameObject.scene;
					array2[1] = ((Scene)(ref scene)).name;
					array2[2] = " / ";
					array2[3] = text;
					array2[4] = " at ";
					array2[5] = position.x.ToString("F2", CultureInfo.InvariantCulture);
					array2[6] = ", ";
					array2[7] = position.y.ToString("F2", CultureInfo.InvariantCulture);
					array2[8] = ", ";
					array2[9] = position.z.ToString("F2", CultureInfo.InvariantCulture);
					array2[10] = (early ? " is off the NavMesh on the next update. This may be temporary; its connection to the warning is not established." : " is still off the NavMesh.");
					log.LogWarning((object)string.Concat(array2));
				}
			}
			Log.LogInfo((object)((early ? "Early navigation check after " : "Navigation check after ") + count + " placement warnings: " + num + " active agents still off the NavMesh. No agents were changed."));
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Navigation diagnostic could not finish: " + ex));
		}
	}
}
internal static class DonorSceneFixes
{
	[HarmonyPatch(typeof(SEScreenSpaceShadows), "OnPreRender")]
	private static class ShadowPatch
	{
		private static bool Prefix(SEScreenSpaceShadows __instance, Light ___sun, bool ___sunInitialized)
		{
			return Shadow(__instance, ___sun, ___sunInitialized);
		}
	}

	[HarmonyPatch(typeof(AmbienceSound), "OnSoundLoaded")]
	private static class AudioPatch
	{
		private static bool Prefix(AmbienceSound __instance)
		{
			return Audio(__instance);
		}
	}

	internal static bool Enabled;

	internal static ManualLogSource Log;

	private static bool reportedAudio;

	internal static void Initialize(string plugins, string managed, ManualLogSource log)
	{
		Log = log;
		Enabled = false;
		try
		{
			if (!SupportedGame(managed))
			{
				log.LogWarning((object)"Scene lifetime guards inactive: game assembly differs from the tested Outward Definitive Edition build.");
				return;
			}
			Enabled = FindSupported(plugins);
			log.LogInfo((object)(Enabled ? "Champions donor-scene lifetime guards ready (verified game and Champions build)." : "Champions donor-scene guards inactive: no supported Champions 1.0.5 or 1.1.0 DLL was found."));
		}
		catch (Exception ex)
		{
			log.LogWarning((object)("Scene lifetime guard validation failed; other runtime fixes will still start. " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	internal static bool SupportedGame(string managed)
	{
		string path = Path.Combine(managed, "Assembly-CSharp.dll");
		if (!File.Exists(path))
		{
			return false;
		}
		using FileStream inputStream = File.OpenRead(path);
		using SHA256 sHA = SHA256.Create();
		return BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant() == "01acb2e4bf1026868f021233bbd923f50a4d971e24582412879cca955f7adfa7";
	}

	private static bool MatchesChampion(string hash)
	{
		if (!(hash == "4b5af7dc5458cab64738a096d4fbff5f652830aa2a8f577c2b795567e03b0f32") && !(hash == "f65129f3a639a3f439d4e7c17b90a91b8a61553e1d0dafa4896c5d89b3584dd8"))
		{
			return hash == "2a50e742d0eee9aeec686ac768b3ca1ea2828376477d7e9dd83e84739a03d895";
		}
		return true;
	}

	private static bool FindSupported(string directory)
	{
		string[] files = Directory.GetFiles(directory, "Outward_Champions_of_Elatt.dll");
		foreach (string path in files)
		{
			if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != FileAttributes.None)
			{
				continue;
			}
			using FileStream inputStream = File.OpenRead(path);
			using SHA256 sHA = SHA256.Create();
			string text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
			if (MatchesChampion(text))
			{
				return true;
			}
			if (Log != null)
			{
				Log.LogWarning((object)("Champions DLL not recognized by scene lifetime guards; SHA256=" + text + ". No version check was bypassed."));
			}
		}
		string[] directories = Directory.GetDirectories(directory);
		foreach (string text2 in directories)
		{
			if (!text2.EndsWith(".disabled", StringComparison.OrdinalIgnoreCase) && !text2.EndsWith(".old", StringComparison.OrdinalIgnoreCase) && (File.GetAttributes(text2) & FileAttributes.ReparsePoint) == 0 && FindSupported(text2))
			{
				return true;
			}
		}
		return false;
	}

	internal static bool Shadow(SEScreenSpaceShadows effect, Light sun, bool initialized)
	{
		if (!Enabled || !Object.op_Implicit((Object)(object)effect) || !initialized || Object.op_Implicit((Object)(object)sun))
		{
			return true;
		}
		((Behaviour)effect).enabled = false;
		if (Log != null)
		{
			Log.LogInfo((object)"Aetherial Endeavors: disabled an orphaned shadow effect before rendering. Its light had been destroyed.");
		}
		return false;
	}

	internal static bool Audio(AmbienceSound ambience)
	{
		if (!Enabled || Object.op_Implicit((Object)(object)ambience))
		{
			return true;
		}
		if (!reportedAudio && Log != null)
		{
			reportedAudio = true;
			Log.LogInfo((object)"Aetherial Endeavors: discarded a late ambience callback for a destroyed scene object.");
		}
		return false;
	}
}
internal static class LanternLifetimeFix
{
	private static FieldInfo ownerField;

	private static ManualLogSource log;

	private static bool reported;

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				logger.LogWarning((object)"Lantern lifetime fix inactive: game assembly differs from the tested build.");
				return;
			}
			Type nestedType = typeof(ItemLanternVisual).GetNestedType("<DelayedLight>d__18", BindingFlags.NonPublic);
			MethodInfo methodInfo = ((nestedType == null) ? null : nestedType.GetMethod("MoveNext", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic));
			FieldInfo fieldInfo = ((nestedType == null) ? null : nestedType.GetField("<>4__this", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
			if (methodInfo == null || methodInfo.ReturnType != typeof(bool) || methodInfo.GetParameters().Length != 0 || fieldInfo == null || fieldInfo.FieldType != typeof(ItemLanternVisual))
			{
				throw new InvalidOperationException("The expected lantern coroutine was not found.");
			}
			ownerField = fieldInfo;
			log = logger;
			new Harmony("Outwardz.AetherialEndeavorsFixes.LanternLifetime").Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(LanternLifetimeFix).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Lantern lifetime fix ready.");
		}
		catch (Exception ex)
		{
			logger.LogWarning((object)("Lantern lifetime fix could not start; other fixes remain active. " + ex));
		}
	}

	private static bool Prefix(object __instance, ref bool __result)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		ItemLanternVisual val = (ItemLanternVisual)ownerField.GetValue(__instance);
		if (Object.op_Implicit((Object)(object)val))
		{
			return true;
		}
		__result = false;
		if (!reported && log != null)
		{
			reported = true;
			log.LogInfo((object)"Stopped a delayed lantern effect after its scene object was destroyed.");
		}
		return false;
	}
}
internal static class BasicInteractionLifetimeFix
{
	private static ManualLogSource log;

	private static bool reported;

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_0089: 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_00b3: Expected O, but got Unknown
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				logger.LogWarning((object)"Basic interaction lifetime fix inactive: unsupported game build.");
				return;
			}
			MethodInfo method = typeof(InteractionActivator).GetMethod("OnActivateBasicInteraction", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
			{
				typeof(Character),
				typeof(int)
			}, null);
			if (method == null || method.ReturnType != typeof(void))
			{
				throw new InvalidOperationException("Basic interaction entry differs from the tested build.");
			}
			log = logger;
			new Harmony("Outwardz.AetherialEndeavorsFixes.BasicInteractionLifetime").Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BasicInteractionLifetimeFix).GetMethod("Transpile", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Co-op basic interaction lifetime fix ready.");
		}
		catch (Exception ex)
		{
			logger.LogWarning((object)("Basic interaction lifetime fix could not start; other fixes remain active. " + ex));
		}
	}

	private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		MethodInfo simple = typeof(IInteraction).GetMethod("Activate", new Type[1] { typeof(Character) });
		MethodInfo toggle = typeof(IInteraction).GetMethod("Activate", new Type[2]
		{
			typeof(Character),
			typeof(int)
		});
		CodeInstruction[] array = list.Where((CodeInstruction i) => i.opcode == OpCodes.Callvirt && object.Equals(i.operand, simple)).ToArray();
		CodeInstruction[] array2 = list.Where((CodeInstruction i) => i.opcode == OpCodes.Callvirt && object.Equals(i.operand, toggle)).ToArray();
		if (simple == null || toggle == null || array.Length != 1 || array2.Length != 1)
		{
			throw new InvalidOperationException("Basic interaction calls differ from the tested build.");
		}
		array[0].opcode = OpCodes.Call;
		array[0].operand = typeof(BasicInteractionLifetimeFix).GetMethod("ActivateIfPresent", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[2]
		{
			typeof(IInteraction),
			typeof(Character)
		}, null);
		array2[0].opcode = OpCodes.Call;
		array2[0].operand = typeof(BasicInteractionLifetimeFix).GetMethod("ActivateIfPresent", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[3]
		{
			typeof(IInteraction),
			typeof(Character),
			typeof(int)
		}, null);
		return list;
	}

	private static bool IsPresent(IInteraction interaction)
	{
		Object val = (Object)(object)((interaction is Object) ? interaction : null);
		if (!object.ReferenceEquals(interaction, null) && (object.ReferenceEquals(val, null) || Object.op_Implicit(val)))
		{
			return true;
		}
		if (!reported && log != null)
		{
			reported = true;
			log.LogWarning((object)"Rejected a basic interaction request with no available action. No action was replayed; matching co-op mod profiles are still required.");
		}
		return false;
	}

	private static void ActivateIfPresent(IInteraction interaction, Character character)
	{
		if (IsPresent(interaction))
		{
			interaction.Activate(character);
		}
	}

	private static void ActivateIfPresent(IInteraction interaction, Character character, int toggleState)
	{
		if (IsPresent(interaction))
		{
			interaction.Activate(character, toggleState);
		}
	}
}
internal static class GatheringNotificationFix
{
	private static ManualLogSource log;

	private static bool reported;

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_007c: 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_00a6: Expected O, but got Unknown
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				logger.LogWarning((object)"Gathering notification fix inactive: unsupported game build.");
				return;
			}
			MethodInfo method = typeof(GatherableInteraction).GetMethod("Activate", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(Character) }, null);
			if (method == null || method.ReturnType != typeof(void))
			{
				throw new InvalidOperationException("Gathering entry differs from the tested build.");
			}
			log = logger;
			new Harmony("Outwardz.AetherialEndeavorsFixes.GatheringNotification").Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(GatheringNotificationFix).GetMethod("Transpile", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Co-op gathering notification fix ready.");
		}
		catch (Exception ex)
		{
			logger.LogWarning((object)("Gathering notification fix could not start; other fixes remain active. " + ex));
		}
	}

	private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		List<CodeInstruction> list = instructions.ToList();
		MethodInfo notification = typeof(CharacterUI).GetMethod("ShowInfoNotification", new Type[1] { typeof(string) });
		CodeInstruction[] array = list.Where((CodeInstruction i) => i.opcode == OpCodes.Callvirt && object.Equals(i.operand, notification)).ToArray();
		if (notification == null || notification.ReturnType != typeof(void) || array.Length != 1)
		{
			throw new InvalidOperationException("Gathering notification call differs from the tested build.");
		}
		array[0].opcode = OpCodes.Call;
		array[0].operand = typeof(GatheringNotificationFix).GetMethod("NotifyIfPresent", BindingFlags.Static | BindingFlags.NonPublic);
		return list;
	}

	private static void NotifyIfPresent(CharacterUI ui, string message)
	{
		if (Object.op_Implicit((Object)(object)ui))
		{
			ui.ShowInfoNotification(message);
		}
		else if (!reported && log != null)
		{
			reported = true;
			log.LogInfo((object)"Skipped a gathering notification without a local character UI; required-item checks were preserved.");
		}
	}
}
internal static class TrainerIdentityFix
{
	private const string SupportedSideLoader = "5da977a019f2158e9217a0e86c4be05a039ea0cd1a1ba6a78a759aa2931d9052";

	private const string ActivatorId = "oxpWPvh4NEO20S_f-DxovQ";

	private const string TriggerId = "UrimpMbJyEy52m_H6q4g_w";

	private static readonly FieldInfo activatorRegistered = typeof(EventActivator).GetField("m_uidRegistered", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo triggerRegistered = typeof(InteractionTriggerBase).GetField("m_uidRegistered", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo activatorUid = typeof(EventActivator).GetField("m_uid", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo triggerUid = typeof(InteractionTriggerBase).GetField("m_UID", BindingFlags.Instance | BindingFlags.NonPublic);

	private static ManualLogSource log;

	private static bool reported;

	internal static void Install(string managed, ManualLogSource logger)
	{
		//IL_0207: 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_0232: Expected O, but got Unknown
		log = logger;
		try
		{
			if (!DonorSceneFixes.SupportedGame(managed))
			{
				logger.LogWarning((object)"Trainer identity fix inactive: unsupported game build.");
				return;
			}
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault((Assembly a) => a.GetName().Name == "SideLoader");
			if (assembly == null || !File.Exists(assembly.Location))
			{
				logger.LogWarning((object)"Trainer identity fix inactive: SideLoader is not loaded.");
				return;
			}
			string text;
			using (FileStream inputStream = File.OpenRead(assembly.Location))
			{
				using SHA256 sHA = SHA256.Create();
				text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", "").ToLowerInvariant();
			}
			if (text != "5da977a019f2158e9217a0e86c4be05a039ea0cd1a1ba6a78a759aa2931d9052")
			{
				logger.LogWarning((object)"Trainer identity fix inactive: unsupported SideLoader file.");
				return;
			}
			if (activatorRegistered == null || triggerRegistered == null || activatorRegistered.FieldType != typeof(bool) || triggerRegistered.FieldType != typeof(bool))
			{
				throw new InvalidOperationException("Registration fields differ from the tested build.");
			}
			if (activatorUid == null || triggerUid == null || activatorUid.FieldType != typeof(UID) || triggerUid.FieldType != typeof(UID) || activatorUid.IsInitOnly || triggerUid.IsInitOnly)
			{
				throw new InvalidOperationException("Interaction ID fields differ from the tested build.");
			}
			Type type = assembly.GetType("SideLoader.SL_CharacterTrainer", throwOnError: true);
			MethodInfo method = type.GetMethod("ApplyToCharacter", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public, null, new Type[2]
			{
				typeof(Character),
				typeof(bool)
			}, null);
			if (method == null)
			{
				throw new InvalidOperationException("Trainer setup method not found.");
			}
			new Harmony("Outwardz.AetherialEndeavorsFixes.TrainerIdentity").Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(TrainerIdentityFix).GetMethod("Transpile", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null);
			logger.LogInfo((object)"Trainer interaction identity fix ready.");
		}
		catch (Exception ex)
		{
			logger.LogWarning((object)("Trainer identity fix could not start; other fixes remain active. " + ex));
		}
	}

	private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
	{
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Expected O, but got Unknown
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Expected O, but got Unknown
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Expected O, but got Unknown
		List<CodeInstruction> list = instructions.ToList();
		if (list.Count((CodeInstruction i) => i.opcode == OpCodes.Ldstr && object.Equals(i.operand, "editor/templates/TrainerTemplate")) != 1)
		{
			throw new InvalidOperationException("Trainer clone sequence is not unique.");
		}
		int num = list.FindIndex((CodeInstruction i) => i.opcode == OpCodes.Ldstr && object.Equals(i.operand, "editor/templates/TrainerTemplate"));
		if (num < 0 || list.Count <= num + 3)
		{
			throw new InvalidOperationException("Trainer clone sequence missing.");
		}
		MethodInfo methodInfo = list[num + 1].operand as MethodInfo;
		MethodInfo methodInfo2 = list[num + 2].operand as MethodInfo;
		if (list[num + 1].opcode != OpCodes.Call || methodInfo == null || methodInfo.DeclaringType != typeof(Resources) || methodInfo.Name != "Load" || !methodInfo.IsGenericMethod || methodInfo.GetGenericArguments().Length != 1 || methodInfo.GetGenericArguments()[0] != typeof(GameObject) || list[num + 2].opcode != OpCodes.Call || methodInfo2 == null || methodInfo2.DeclaringType != typeof(Object) || methodInfo2.Name != "Instantiate" || !methodInfo2.IsGenericMethod || methodInfo2.GetGenericArguments().Length != 1 || methodInfo2.GetGenericArguments()[0] != typeof(GameObject) || list[num + 3].opcode != OpCodes.Stloc_0)
		{
			throw new InvalidOperationException("Trainer clone sequence differs from the tested build.");
		}
		list.InsertRange(num + 4, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
		{
			new CodeInstruction(OpCodes.Ldloc_0, (object)null),
			new CodeInstruction(OpCodes.Ldarg_1, (object)null),
			new CodeInstruction(OpCodes.Call, (object)typeof(TrainerIdentityFix).GetMethod("Assign", BindingFlags.Static | BindingFlags.NonPublic))
		});
		return list;
	}

	private static void Assign(GameObject clone, Character character)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (mi