Decompiled source of Valheim ZooFriends QoL V2 v2.7.5

patchers/SEManAddStatusEffectPatch.Patcher.dll

Decompiled 6 days ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Collections.Generic;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SEManAddStatusEffectPatch.Patcher;

public static class Patcher
{
	public static IEnumerable<string> TargetDLLs => new string[1] { "assembly_valheim.dll" };

	public static void Patch(AssemblyDefinition assembly)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0377: Unknown result type (might be due to invalid IL or missing references)
		//IL_037c: Unknown result type (might be due to invalid IL or missing references)
		//IL_041e: 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_088e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0893: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d6f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d76: Expected O, but got Unknown
		//IL_0d87: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d8e: Expected O, but got Unknown
		//IL_0da8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dad: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0332: Expected O, but got Unknown
		//IL_045b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0460: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Expected O, but got Unknown
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Expected O, but got Unknown
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Expected O, but got Unknown
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Expected O, but got Unknown
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Expected O, but got Unknown
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_070c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0711: Unknown result type (might be due to invalid IL or missing references)
		//IL_0645: Unknown result type (might be due to invalid IL or missing references)
		//IL_064a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e2b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e32: Expected O, but got Unknown
		//IL_0e57: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e5c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a91: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a96: Unknown result type (might be due to invalid IL or missing references)
		//IL_0994: Unknown result type (might be due to invalid IL or missing references)
		//IL_099b: Expected O, but got Unknown
		//IL_09c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_09d1: Expected O, but got Unknown
		//IL_09f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_057c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0583: Expected O, but got Unknown
		//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_06bd: Expected O, but got Unknown
		//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f5: Expected O, but got Unknown
		//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_0a07: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a34: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a41: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a4e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a5d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ec2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ec7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bb9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc0: Expected O, but got Unknown
		//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bdf: Expected O, but got Unknown
		//IL_0bf7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bfe: Expected O, but got Unknown
		//IL_0c16: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c1d: Expected O, but got Unknown
		//IL_0c35: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c3c: Expected O, but got Unknown
		//IL_0c88: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c95: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ca4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cb3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cc2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cd1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cde: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ced: Unknown result type (might be due to invalid IL or missing references)
		//IL_079e: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_07cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_080f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0827: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f52: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f68: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f7e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f96: Unknown result type (might be due to invalid IL or missing references)
		TypeDefinition type = assembly.MainModule.GetType("SEMan");
		Enumerator<MethodDefinition> enumerator;
		if (type != null)
		{
			TypeReference type2 = (TypeReference)(object)assembly.MainModule.GetType("StatusEffect");
			TypeReference boolean = assembly.MainModule.TypeSystem.Boolean;
			TypeReference @int = assembly.MainModule.TypeSystem.Int32;
			TypeReference single = assembly.MainModule.TypeSystem.Single;
			bool flag = false;
			MethodDefinition val = null;
			enumerator = type.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == "AddStatusEffect")
					{
						if (((MethodReference)current).Parameters.Count == 4 && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[0]).ParameterType).Name == "StatusEffect")
						{
							flag = true;
						}
						if (((MethodReference)current).Parameters.Count == 5 && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[0]).ParameterType).Name == "StatusEffect")
						{
							val = current;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (!flag && val != null)
			{
				MethodDefinition val2 = new MethodDefinition("AddStatusEffect", (MethodAttributes)134, type2);
				ParameterDefinition val3 = new ParameterDefinition("statusEffect", (ParameterAttributes)0, type2);
				ParameterDefinition val4 = new ParameterDefinition("resetTime", (ParameterAttributes)0, boolean);
				ParameterDefinition val5 = new ParameterDefinition("itemLevel", (ParameterAttributes)0, @int);
				ParameterDefinition val6 = new ParameterDefinition("skillLevel", (ParameterAttributes)0, single);
				((MethodReference)val2).Parameters.Add(val3);
				((MethodReference)val2).Parameters.Add(val4);
				((MethodReference)val2).Parameters.Add(val5);
				((MethodReference)val2).Parameters.Add(val6);
				ILProcessor iLProcessor = val2.Body.GetILProcessor();
				iLProcessor.Emit(OpCodes.Ldarg_0);
				iLProcessor.Emit(OpCodes.Ldarg, val3);
				iLProcessor.Emit(OpCodes.Ldarg, val4);
				iLProcessor.Emit(OpCodes.Ldarg, val5);
				iLProcessor.Emit(OpCodes.Ldarg, val6);
				iLProcessor.Emit(OpCodes.Ldc_I4_0);
				iLProcessor.Emit(OpCodes.Callvirt, (MethodReference)(object)val);
				iLProcessor.Emit(OpCodes.Ret);
				type.Methods.Add(val2);
				Console.WriteLine("[SEManPatch] Successfully injected 4-param AddStatusEffect bridge into SEMan!");
			}
		}
		TypeDefinition type3 = assembly.MainModule.GetType("Version");
		Enumerator<FieldDefinition> enumerator2;
		if (type3 != null)
		{
			bool flag2 = false;
			enumerator2 = type3.Fields.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					FieldDefinition current2 = enumerator2.Current;
					if (((MemberReference)current2).Name == "m_networkVersion")
					{
						flag2 = true;
						break;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
			if (!flag2)
			{
				TypeReference uInt = assembly.MainModule.TypeSystem.UInt32;
				FieldDefinition val7 = new FieldDefinition("m_networkVersion", (FieldAttributes)22, uInt);
				type3.Fields.Add(val7);
				Console.WriteLine("[SEManPatch] Successfully injected m_networkVersion field into Version class!");
			}
		}
		TypeDefinition type4 = assembly.MainModule.GetType("ZRoutedRpc");
		if (type4 != null)
		{
			enumerator2 = type4.Fields.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					FieldDefinition current2 = enumerator2.Current;
					if (((MemberReference)current2).Name == "Everybody")
					{
						if (current2.IsLiteral)
						{
							current2.Attributes = (FieldAttributes)22;
							Console.WriteLine("[SEManPatch] Successfully un-const'd ZRoutedRpc.Everybody to public static field!");
						}
						break;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}
		TypeDefinition type5 = assembly.MainModule.GetType("PlayerProfile");
		if (type5 != null)
		{
			TypeReference val8 = null;
			FieldDefinition val9 = null;
			Enumerator<TypeDefinition> enumerator3 = type5.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					TypeDefinition current3 = enumerator3.Current;
					if (!(((MemberReference)current3).Name == "PlayerStats"))
					{
						continue;
					}
					val8 = (TypeReference)(object)current3;
					enumerator2 = current3.Fields.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							FieldDefinition current2 = enumerator2.Current;
							if (((MemberReference)current2).Name == "m_knownCommands")
							{
								val9 = current2;
							}
						}
					}
					finally
					{
						((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
					break;
				}
			}
			finally
			{
				((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
			FieldDefinition val10 = null;
			MethodDefinition val11 = null;
			if (val8 != null)
			{
				bool flag3 = false;
				enumerator2 = type5.Fields.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						FieldDefinition current2 = enumerator2.Current;
						if (((MemberReference)current2).Name == "m_playerStats" && ((MemberReference)((FieldReference)current2).FieldType).FullName == ((MemberReference)val8).FullName)
						{
							flag3 = true;
							val10 = current2;
							break;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
				}
				if (!flag3)
				{
					val10 = new FieldDefinition("m_playerStats", (FieldAttributes)6, val8);
					type5.Fields.Add(val10);
					Console.WriteLine("[SEManPatch] Successfully injected scalar m_playerStats field into PlayerProfile!");
					TypeDefinition val12 = val8.Resolve();
					if (val12 != null)
					{
						enumerator = val12.Methods.GetEnumerator();
						try
						{
							while (enumerator.MoveNext())
							{
								MethodDefinition current = enumerator.Current;
								if (current.IsConstructor && !current.IsStatic && ((MethodReference)current).Parameters.Count == 0)
								{
									val11 = current;
									break;
								}
							}
						}
						finally
						{
							((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
						}
					}
				}
			}
			FieldDefinition val13 = null;
			MethodReference val14 = null;
			if (val9 != null)
			{
				bool flag4 = false;
				enumerator2 = type5.Fields.GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						FieldDefinition current2 = enumerator2.Current;
						if (((MemberReference)current2).Name == "m_knownCommands")
						{
							flag4 = true;
							val13 = current2;
							break;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
				}
				if (!flag4)
				{
					TypeReference fieldType = ((FieldReference)val9).FieldType;
					val13 = new FieldDefinition("m_knownCommands", (FieldAttributes)6, fieldType);
					type5.Fields.Add(val13);
					Console.WriteLine("[SEManPatch] Successfully injected m_knownCommands field into PlayerProfile!");
					MethodReference val15 = new MethodReference(".ctor", assembly.MainModule.TypeSystem.Void, fieldType);
					val15.HasThis = true;
					val14 = val15;
				}
			}
			enumerator = type5.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current4 = enumerator.Current;
					if (current4.IsConstructor && !current4.IsStatic && current4.HasBody && current4.Body.Instructions.Count > 0)
					{
						ILProcessor iLProcessor = current4.Body.GetILProcessor();
						Instruction val16 = current4.Body.Instructions[0];
						if (val10 != null && val11 != null)
						{
							iLProcessor.InsertBefore(val16, iLProcessor.Create(OpCodes.Ldarg_0));
							iLProcessor.InsertBefore(val16, iLProcessor.Create(OpCodes.Newobj, (MethodReference)(object)val11));
							iLProcessor.InsertBefore(val16, iLProcessor.Create(OpCodes.Stfld, (FieldReference)(object)val10));
						}
						if (val13 != null && val14 != null)
						{
							iLProcessor.InsertBefore(val16, iLProcessor.Create(OpCodes.Ldarg_0));
							iLProcessor.InsertBefore(val16, iLProcessor.Create(OpCodes.Newobj, val14));
							iLProcessor.InsertBefore(val16, iLProcessor.Create(OpCodes.Stfld, (FieldReference)(object)val13));
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}
		TypeDefinition type6 = assembly.MainModule.GetType("Inventory");
		if (type6 != null)
		{
			bool flag5 = false;
			MethodDefinition val17 = null;
			enumerator = type6.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == "AddItem")
					{
						if (((MethodReference)current).Parameters.Count == 8 && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[6]).ParameterType).Name == "Vector2i")
						{
							flag5 = true;
						}
						if (((MethodReference)current).Parameters.Count == 10 && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[6]).ParameterType).Name == "Vector2i")
						{
							val17 = current;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (!flag5 && val17 != null)
			{
				MethodDefinition val2 = new MethodDefinition("AddItem", (MethodAttributes)134, ((MethodReference)val17).ReturnType);
				for (int i = 0; i < 8; i++)
				{
					ParameterDefinition val18 = ((MethodReference)val17).Parameters[i];
					((MethodReference)val2).Parameters.Add(new ParameterDefinition(((ParameterReference)val18).Name, (ParameterAttributes)0, ((ParameterReference)val18).ParameterType));
				}
				ILProcessor iLProcessor = val2.Body.GetILProcessor();
				iLProcessor.Emit(OpCodes.Ldarg_0);
				for (int i = 0; i < 8; i++)
				{
					iLProcessor.Emit(OpCodes.Ldarg, ((MethodReference)val2).Parameters[i]);
				}
				iLProcessor.Emit(OpCodes.Ldc_I4_0);
				iLProcessor.Emit(OpCodes.Ldc_I4_0);
				iLProcessor.Emit(OpCodes.Callvirt, (MethodReference)(object)val17);
				iLProcessor.Emit(OpCodes.Ret);
				type6.Methods.Add(val2);
				Console.WriteLine("[SEManPatch] Successfully injected 8-param AddItem bridge into Inventory!");
			}
			bool flag6 = false;
			MethodDefinition val19 = null;
			enumerator = type6.Methods.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					MethodDefinition current = enumerator.Current;
					if (((MemberReference)current).Name == "AddItem")
					{
						if (((MethodReference)current).Parameters.Count == 4 && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[0]).ParameterType).Name == "ItemData")
						{
							flag6 = true;
						}
						if (((MethodReference)current).Parameters.Count == 5 && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[0]).ParameterType).Name == "ItemData" && ((MemberReference)((ParameterReference)((MethodReference)current).Parameters[4]).ParameterType).Name == "Boolean")
						{
							val19 = current;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (!flag6 && val19 != null)
			{
				MethodDefinition val2 = new MethodDefinition("AddItem", (MethodAttributes)134, ((MethodReference)val19).ReturnType);
				ParameterDefinition val20 = new ParameterDefinition("item", (ParameterAttributes)0, ((ParameterReference)((MethodReference)val19).Parameters[0]).ParameterType);
				ParameterDefinition val21 = new ParameterDefinition("amount", (ParameterAttributes)0, ((ParameterReference)((MethodReference)val19).Parameters[1]).ParameterType);
				ParameterDefinition val22 = new ParameterDefinition("x", (ParameterAttributes)0, ((ParameterReference)((MethodReference)val19).Parameters[2]).ParameterType);
				ParameterDefinition val23 = new ParameterDefinition("y", (ParameterAttributes)0, ((ParameterReference)((MethodReference)val19).Parameters[3]).ParameterType);
				((MethodReference)val2).Parameters.Add(val20);
				((MethodReference)val2).Parameters.Add(val21);
				((MethodReference)val2).Parameters.Add(val22);
				((MethodReference)val2).Parameters.Add(val23);
				ILProcessor iLProcessor = val2.Body.GetILProcessor();
				iLProcessor.Emit(OpCodes.Ldarg_0);
				iLProcessor.Emit(OpCodes.Ldarg, val20);
				iLProcessor.Emit(OpCodes.Ldarg, val21);
				iLProcessor.Emit(OpCodes.Ldarg, val22);
				iLProcessor.Emit(OpCodes.Ldarg, val23);
				iLProcessor.Emit(OpCodes.Ldc_I4_0);
				iLProcessor.Emit(OpCodes.Callvirt, (MethodReference)(object)val19);
				iLProcessor.Emit(OpCodes.Ret);
				type6.Methods.Add(val2);
				Console.WriteLine("[SEManPatch] Successfully injected 4-param AddItem bridge into Inventory!");
			}
		}
		TypeDefinition type7 = assembly.MainModule.GetType("PieceTable");
		if (type7 == null)
		{
			return;
		}
		TypeDefinition type8 = assembly.MainModule.GetType("Piece");
		if (type8 == null)
		{
			return;
		}
		TypeReference val24 = assembly.MainModule.ImportReference(typeof(List<>));
		GenericInstanceType val25 = new GenericInstanceType(val24);
		val25.GenericArguments.Add((TypeReference)(object)type8);
		GenericInstanceType val26 = new GenericInstanceType(val24);
		val26.GenericArguments.Add((TypeReference)(object)val25);
		bool flag7 = false;
		enumerator2 = type7.Fields.GetEnumerator();
		try
		{
			while (enumerator2.MoveNext())
			{
				FieldDefinition current2 = enumerator2.Current;
				if (((MemberReference)current2).Name == "m_availablePieces" && ((MemberReference)((FieldReference)current2).FieldType).FullName.Contains("List"))
				{
					flag7 = true;
					break;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
		}
		if (flag7)
		{
			return;
		}
		FieldDefinition val27 = new FieldDefinition("m_availablePieces", (FieldAttributes)6, (TypeReference)(object)val26);
		type7.Fields.Add(val27);
		Console.WriteLine("[SEManPatch] Successfully injected compatibility m_availablePieces field into PieceTable!");
		FieldDefinition val28 = null;
		enumerator2 = type7.Fields.GetEnumerator();
		try
		{
			while (enumerator2.MoveNext())
			{
				FieldDefinition current2 = enumerator2.Current;
				if (((MemberReference)current2).Name == "m_availablePiecesByCategory")
				{
					val28 = current2;
					break;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
		}
		if (val28 == null)
		{
			return;
		}
		enumerator = type7.Methods.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				MethodDefinition current4 = enumerator.Current;
				if (current4.IsConstructor && !current4.IsStatic && current4.HasBody && current4.Body.Instructions.Count > 0)
				{
					ILProcessor iLProcessor = current4.Body.GetILProcessor();
					Instruction val29 = current4.Body.Instructions[current4.Body.Instructions.Count - 1];
					iLProcessor.InsertBefore(val29, iLProcessor.Create(OpCodes.Ldarg_0));
					iLProcessor.InsertBefore(val29, iLProcessor.Create(OpCodes.Ldarg_0));
					iLProcessor.InsertBefore(val29, iLProcessor.Create(OpCodes.Ldfld, (FieldReference)(object)val28));
					iLProcessor.InsertBefore(val29, iLProcessor.Create(OpCodes.Stfld, (FieldReference)(object)val27));
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
	}
}

plugins/ZooFriendsQoLFixes.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ZooFriendsQoLFixes;

[BepInPlugin("com.zoofriends.qolfixes", "ZooFriends QoL Fixes", "1.0.5")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ZooFriendsFixesPlugin : BaseUnityPlugin
{
	private void Awake()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Plugin loaded, applying QoL, UI, Smelter stability, and Star Progression patches...");
		try
		{
			Harmony val = new Harmony("com.zoofriends.qolfixes");
			val.PatchAll(typeof(ZooFriendsFixesPlugin).Assembly);
			AttachCfcFinalizers(val);
			PatchEpicLootCoins(val);
			PatchStarLevelProgression(val);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Successfully applied all stability and progression patches!");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[ZooFriendsFixes] Error applying patches: " + ex));
		}
	}

	private void PatchStarLevelProgression(Harmony harmony)
	{
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Expected O, but got Unknown
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Expected O, but got Unknown
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Expected O, but got Unknown
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Expected O, but got Unknown
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Expected O, but got Unknown
		//IL_0316: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Expected O, but got Unknown
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Expected O, but got Unknown
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name == "StarLevelSystem"))
				{
					continue;
				}
				Type type = assembly.GetType("StarLevelSystem.modules.LevelSystem.LevelSelection");
				if (type != null)
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (methodInfo.Name == "DetermineLevel" && methodInfo.GetParameters().Length == 7)
						{
							harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "DetermineLevel_Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS DetermineLevel (7 params)");
						}
					}
					MethodInfo methodInfo2 = AccessTools.Method(type, "GetMaxCreatureLevel", (Type[])null, (Type[])null);
					if (methodInfo2 != null)
					{
						harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "GetMaxCreatureLevel_Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS GetMaxCreatureLevel");
					}
				}
				Type type2 = assembly.GetType("StarLevelSystem.modules.Modifiers.CreatureModifiers");
				if (type2 != null)
				{
					MethodInfo methodInfo3 = AccessTools.Method(type2, "SelectModifiersForCreature", (Type[])null, (Type[])null);
					if (methodInfo3 != null)
					{
						harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "SelectModifiersForCreature_Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS SelectModifiersForCreature");
					}
					MethodInfo methodInfo4 = AccessTools.Method(type2, "SetupModifiers", (Type[])null, (Type[])null);
					if (methodInfo4 != null)
					{
						harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "SetupModifiers_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS SetupModifiers");
					}
					MethodInfo methodInfo5 = AccessTools.Method(type2, "AddCreatureModifier", (Type[])null, (Type[])null);
					if (methodInfo5 != null)
					{
						harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "AddCreatureModifier_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS AddCreatureModifier");
					}
					MethodInfo methodInfo6 = AccessTools.Method(type2, "TryRollEvolutionModifier", (Type[])null, (Type[])null);
					if (methodInfo6 != null)
					{
						harmony.Patch((MethodBase)methodInfo6, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "TryRollEvolutionModifier_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS TryRollEvolutionModifier");
					}
					MethodInfo methodInfo7 = AccessTools.Method(type2, "RunOnceModifier", (Type[])null, (Type[])null);
					if (methodInfo7 != null)
					{
						harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "ModifierExecution_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS RunOnceModifier");
					}
					MethodInfo methodInfo8 = AccessTools.Method(type2, "StartupModifier", (Type[])null, (Type[])null);
					if (methodInfo8 != null)
					{
						harmony.Patch((MethodBase)methodInfo8, new HarmonyMethod(AccessTools.Method(typeof(ProgressionRules), "ModifierExecution_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched SLS StartupModifier");
					}
				}
				break;
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[ZooFriendsFixes] Error patching SLS progression: " + ex));
		}
	}

	private void PatchEpicLootCoins(Harmony harmony)
	{
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Expected O, but got Unknown
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name == "EpicLoot"))
				{
					continue;
				}
				Type type = assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper");
				if (type != null)
				{
					MethodInfo methodInfo = AccessTools.Method(type, "GetReAugmentCost", (Type[])null, (Type[])null);
					MethodInfo methodInfo2 = AccessTools.Method(typeof(ZooFriendsFixesPlugin), "ZeroReAugmentCostPrefix", (Type[])null, (Type[])null);
					if (methodInfo != null && methodInfo2 != null)
					{
						harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[ZooFriendsFixes] Patched EpicLoot GetReAugmentCost to 0 cost!");
					}
				}
				break;
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("[ZooFriendsFixes] Could not patch EpicLoot GetReAugmentCost: " + ex.Message));
		}
	}

	public static bool ZeroReAugmentCostPrefix(ref object __result)
	{
		__result = null;
		return false;
	}

	private void AttachCfcFinalizers(Harmony harmony)
	{
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Expected O, but got Unknown
		try
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name == "CraftFromContainers"))
				{
					continue;
				}
				string[] array = new string[5] { "CraftFromContainers.BepInExPlugin+Smelter_OnAddOre_Patch", "CraftFromContainers.BepInExPlugin+Smelter_OnAddFuel_Patch", "CraftFromContainers.BepInExPlugin+CookingStation_OnAddFuelSwitch_Patch", "CraftFromContainers.BepInExPlugin+CookingStation_FindCookableItem_Patch", "CraftFromContainers.BepInExPlugin+Fireplace_Interact_Patch" };
				MethodInfo methodInfo = AccessTools.Method(typeof(ZooFriendsFixesPlugin), "CfcSafetyFinalizer", (Type[])null, (Type[])null);
				string[] array2 = array;
				foreach (string text in array2)
				{
					Type type = assembly.GetType(text);
					if (type != null)
					{
						MethodInfo methodInfo2 = AccessTools.Method(type, "Prefix", (Type[])null, (Type[])null);
						if (methodInfo2 != null && methodInfo != null)
						{
							harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null);
							((BaseUnityPlugin)this).Logger.LogInfo((object)("[ZooFriendsFixes] Attached safety finalizer to " + text));
						}
					}
				}
				break;
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("[ZooFriendsFixes] Note on CFC finalizer attachment: " + ex.Message));
		}
	}

	public static Exception CfcSafetyFinalizer(Exception __exception)
	{
		if (__exception != null)
		{
			Debug.LogWarning((object)("[ZooFriendsFixes] Safely caught and suppressed exception in CraftFromContainers: " + __exception.Message));
		}
		return null;
	}
}
public static class ProgressionRules
{
	private static readonly string[] BossGlobalKeys = new string[7] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader" };

	public static int GetMaxAllowedLevel()
	{
		if ((Object)(object)ZoneSystem.instance == (Object)null)
		{
			return 3;
		}
		int num = 0;
		for (int i = 0; i < BossGlobalKeys.Length; i++)
		{
			if (ZoneSystem.instance.GetGlobalKey(BossGlobalKeys[i]))
			{
				num++;
			}
		}
		int num2 = Math.Min(10, 2 + num * 2);
		return num2 + 1;
	}

	public static bool IsBossDefeated(Character character)
	{
		if ((Object)(object)character == (Object)null)
		{
			return true;
		}
		if ((Object)(object)ZoneSystem.instance == (Object)null)
		{
			return true;
		}
		if (!string.IsNullOrEmpty(character.m_defeatSetGlobalKey))
		{
			return ZoneSystem.instance.GetGlobalKey(character.m_defeatSetGlobalKey);
		}
		string text = ((Object)((Component)character).gameObject).name.Replace("(Clone)", "").Trim().ToLowerInvariant();
		if (text.Contains("eikthyr"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_eikthyr");
		}
		if (text.Contains("gdking") || text.Contains("elder"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_gdking");
		}
		if (text.Contains("bonemass"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_bonemass");
		}
		if (text.Contains("dragon") || text.Contains("moder"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_dragon");
		}
		if (text.Contains("goblinking") || text.Contains("yagluth"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_goblinking");
		}
		if (text.Contains("queen") || text.Contains("seekerqueen"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_queen");
		}
		if (text.Contains("fader"))
		{
			return ZoneSystem.instance.GetGlobalKey("defeated_fader");
		}
		return true;
	}

	public static void DetermineLevel_Postfix(Character character, ref int __result)
	{
		if ((Object)(object)character == (Object)null || character.IsPlayer() || character.IsTamed())
		{
			return;
		}
		if (character.IsBoss() && !IsBossDefeated(character))
		{
			__result = 1;
			return;
		}
		int maxAllowedLevel = GetMaxAllowedLevel();
		if (__result > maxAllowedLevel)
		{
			__result = maxAllowedLevel;
		}
	}

	public static void GetMaxCreatureLevel_Postfix(Character character, ref int __result)
	{
		if ((Object)(object)character == (Object)null || character.IsPlayer() || character.IsTamed())
		{
			return;
		}
		if (character.IsBoss() && !IsBossDefeated(character))
		{
			__result = 1;
			return;
		}
		int maxAllowedLevel = GetMaxAllowedLevel();
		if (__result > maxAllowedLevel)
		{
			__result = maxAllowedLevel;
		}
	}

	public static void SelectModifiersForCreature_Postfix(Character character, ref object __result)
	{
		if (!((Object)(object)character == (Object)null) && !character.IsPlayer() && !character.IsTamed() && character.IsBoss() && !IsBossDefeated(character) && __result is IDictionary dictionary)
		{
			dictionary.Clear();
		}
	}

	public static void SetupModifiers_Prefix(Character character, object selectedMods)
	{
		if (!((Object)(object)character == (Object)null) && !character.IsPlayer() && !character.IsTamed() && character.IsBoss() && !IsBossDefeated(character) && selectedMods is IDictionary dictionary)
		{
			dictionary.Clear();
		}
	}

	public static bool AddCreatureModifier_Prefix(Character character, ref bool __result)
	{
		if ((Object)(object)character == (Object)null)
		{
			return true;
		}
		if (character.IsPlayer() || character.IsTamed())
		{
			return true;
		}
		if (character.IsBoss() && !IsBossDefeated(character))
		{
			__result = false;
			return false;
		}
		return true;
	}

	public static bool TryRollEvolutionModifier_Prefix(Character character, ref bool __result)
	{
		if ((Object)(object)character == (Object)null)
		{
			return true;
		}
		if (character.IsPlayer() || character.IsTamed())
		{
			return true;
		}
		if (character.IsBoss() && !IsBossDefeated(character))
		{
			__result = false;
			return false;
		}
		return true;
	}

	public static bool ModifierExecution_Prefix(Character character)
	{
		if ((Object)(object)character == (Object)null)
		{
			return true;
		}
		if (character.IsPlayer() || character.IsTamed())
		{
			return true;
		}
		if (character.IsBoss() && !IsBossDefeated(character))
		{
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Character), "SetLevel")]
public static class Patch_Character_SetLevel
{
	public static void Prefix(Character __instance, ref int level)
	{
		try
		{
			if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || __instance.IsTamed())
			{
				return;
			}
			if (__instance.IsBoss() && !ProgressionRules.IsBossDefeated(__instance))
			{
				level = 1;
				return;
			}
			int maxAllowedLevel = ProgressionRules.GetMaxAllowedLevel();
			if (level > maxAllowedLevel)
			{
				level = maxAllowedLevel;
			}
		}
		catch (Exception)
		{
		}
	}
}
[HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")]
public static class Patch_Player_UpdateKnownRecipesList
{
	public static void Prefix(Player __instance)
	{
		try
		{
			if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_recipes != null)
			{
				ObjectDB.instance.m_recipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r.m_item == (Object)null || r.m_item.m_itemData == null || r.m_item.m_itemData.m_shared == null);
			}
			if (!((Object)(object)__instance != (Object)null))
			{
				return;
			}
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			if (inventory == null)
			{
				return;
			}
			List<PieceTable> list = new List<PieceTable>();
			inventory.GetAllPieceTables(list);
			for (int num = 0; num < list.Count; num++)
			{
				PieceTable val = list[num];
				if ((Object)(object)val != (Object)null && val.m_pieces != null)
				{
					val.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || (Object)(object)p.GetComponent<Piece>() == (Object)null);
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error in UpdateKnownRecipesList prefix: " + ex));
		}
	}
}
[HarmonyPatch(typeof(PieceTable), "UpdateAvailable", new Type[]
{
	typeof(HashSet<string>),
	typeof(Player),
	typeof(bool),
	typeof(bool)
})]
public static class Patch_PieceTable_UpdateAvailable
{
	public static void Prefix(PieceTable __instance)
	{
		try
		{
			if ((Object)(object)__instance != (Object)null && __instance.m_pieces != null)
			{
				__instance.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || (Object)(object)p.GetComponent<Piece>() == (Object)null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error in PieceTable.UpdateAvailable prefix: " + ex));
		}
	}
}
[HarmonyPatch(typeof(Inventory), "GetAllPieceTables")]
public static class Patch_Inventory_GetAllPieceTables
{
	public static void Postfix(List<PieceTable> tables)
	{
		try
		{
			if (tables == null)
			{
				return;
			}
			for (int i = 0; i < tables.Count; i++)
			{
				PieceTable val = tables[i];
				if ((Object)(object)val != (Object)null && val.m_pieces != null)
				{
					val.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || (Object)(object)p.GetComponent<Piece>() == (Object)null);
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error in GetAllPieceTables postfix: " + ex));
		}
	}
}
[HarmonyPatch(typeof(ObjectDB), "Awake")]
public static class Patch_ObjectDB_Awake
{
	public static void Postfix(ObjectDB __instance)
	{
		CleanObjectDB(__instance);
	}

	public static void CleanObjectDB(ObjectDB db)
	{
		try
		{
			if ((Object)(object)db != (Object)null && db.m_recipes != null)
			{
				db.m_recipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r.m_item == (Object)null || r.m_item.m_itemData == null || r.m_item.m_itemData.m_shared == null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error in CleanObjectDB: " + ex));
		}
	}
}
[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
public static class Patch_ObjectDB_CopyOtherDB
{
	public static void Postfix(ObjectDB __instance)
	{
		Patch_ObjectDB_Awake.CleanObjectDB(__instance);
	}
}
[HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList", new Type[] { typeof(List<Recipe>) })]
public static class Patch_InventoryGui_UpdateRecipeList
{
	public static void Prefix(ref List<Recipe> recipes)
	{
		try
		{
			if (recipes != null)
			{
				recipes.RemoveAll((Recipe r) => (Object)(object)r == (Object)null || (Object)(object)r.m_item == (Object)null || r.m_item.m_itemData == null || r.m_item.m_itemData.m_shared == null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error filtering recipes for UI: " + ex));
		}
	}
}
[HarmonyPatch(typeof(Smelter), "Awake")]
public static class Patch_Smelter_Awake
{
	public static void Postfix(Smelter __instance)
	{
		SmelterHelper.CleanSmelter(__instance);
	}
}
[HarmonyPatch(typeof(Smelter), "OnAddOre")]
public static class Patch_Smelter_OnAddOre
{
	[HarmonyPriority(800)]
	public static void Prefix(Smelter __instance, Humanoid user)
	{
		SmelterHelper.CleanSmelter(__instance);
		SmelterHelper.PopulateDropPrefabs(user);
	}
}
[HarmonyPatch(typeof(Smelter), "OnHoverAddOre")]
public static class Patch_Smelter_OnHoverAddOre
{
	[HarmonyPriority(800)]
	public static void Prefix(Smelter __instance)
	{
		SmelterHelper.CleanSmelter(__instance);
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			SmelterHelper.PopulateDropPrefabs((Humanoid)(object)Player.m_localPlayer);
		}
	}
}
[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
public static class Patch_Smelter_OnAddFuel
{
	[HarmonyPriority(800)]
	public static void Prefix(Smelter __instance, Humanoid user)
	{
		SmelterHelper.CleanSmelter(__instance);
		SmelterHelper.PopulateDropPrefabs(user);
	}
}
[HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")]
public static class Patch_Smelter_OnHoverAddFuel
{
	[HarmonyPriority(800)]
	public static void Prefix(Smelter __instance)
	{
		SmelterHelper.CleanSmelter(__instance);
		if ((Object)(object)Player.m_localPlayer != (Object)null)
		{
			SmelterHelper.PopulateDropPrefabs((Humanoid)(object)Player.m_localPlayer);
		}
	}
}
[HarmonyPatch(typeof(CookingStation), "Awake")]
public static class Patch_CookingStation_Awake
{
	public static void Postfix(CookingStation __instance)
	{
		SmelterHelper.CleanCookingStation(__instance);
	}
}
[HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")]
public static class Patch_CookingStation_OnAddFuelSwitch
{
	[HarmonyPriority(800)]
	public static void Prefix(CookingStation __instance, Humanoid user)
	{
		SmelterHelper.CleanCookingStation(__instance);
		SmelterHelper.PopulateDropPrefabs(user);
	}
}
[HarmonyPatch(typeof(CookingStation), "FindCookableItem")]
public static class Patch_CookingStation_FindCookableItem
{
	[HarmonyPriority(800)]
	public static void Prefix(CookingStation __instance, Inventory inventory)
	{
		SmelterHelper.CleanCookingStation(__instance);
		SmelterHelper.FixInventoryPrefabs(inventory);
	}
}
[HarmonyPatch(typeof(Fireplace), "Interact")]
public static class Patch_Fireplace_Interact
{
	[HarmonyPriority(800)]
	public static void Prefix(Fireplace __instance, Humanoid user)
	{
		SmelterHelper.PopulateDropPrefabs(user);
	}
}
[HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage) })]
public static class Patch_Inventory_Load_Prefabs1
{
	public static void Postfix(Inventory __instance)
	{
		SmelterHelper.FixInventoryPrefabs(__instance);
	}
}
[HarmonyPatch(typeof(Inventory), "Load", new Type[]
{
	typeof(ZPackage),
	typeof(bool)
})]
public static class Patch_Inventory_Load_Prefabs2
{
	public static void Postfix(Inventory __instance)
	{
		SmelterHelper.FixInventoryPrefabs(__instance);
	}
}
public static class SmelterHelper
{
	public static void CleanSmelter(Smelter s)
	{
		try
		{
			if ((Object)(object)s != (Object)null && s.m_conversion != null)
			{
				s.m_conversion.RemoveAll((ItemConversion c) => c == null || (Object)(object)c.m_from == (Object)null || c.m_from.m_itemData == null || c.m_from.m_itemData.m_shared == null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error cleaning Smelter conversions: " + ex));
		}
	}

	public static void CleanCookingStation(CookingStation c)
	{
		try
		{
			if ((Object)(object)c != (Object)null && c.m_conversion != null)
			{
				c.m_conversion.RemoveAll((ItemConversion conv) => conv == null || (Object)(object)conv.m_from == (Object)null || conv.m_from.m_itemData == null || conv.m_from.m_itemData.m_shared == null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error cleaning CookingStation conversions: " + ex));
		}
	}

	public static void PopulateDropPrefabs(Humanoid user)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)ObjectDB.instance == (Object)null || !((Object)(object)user != (Object)null))
			{
				return;
			}
			FixInventoryPrefabs(user.GetInventory());
			Vector3 position = ((Component)user).transform.position;
			Collider[] array = Physics.OverlapSphere(position, 25f);
			for (int i = 0; i < array.Length; i++)
			{
				Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					FixInventoryPrefabs(componentInParent.GetInventory());
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[ZooFriendsFixes] Error in PopulateDropPrefabs: " + ex));
		}
	}

	public static void FixInventoryPrefabs(Inventory inv)
	{
		if (inv == null || (Object)(object)ObjectDB.instance == (Object)null)
		{
			return;
		}
		List<ItemData> allItems = inv.GetAllItems();
		if (allItems == null)
		{
			return;
		}
		for (int i = 0; i < allItems.Count; i++)
		{
			ItemData val = allItems[i];
			if (val == null || !((Object)(object)val.m_dropPrefab == (Object)null) || val.m_shared == null)
			{
				continue;
			}
			GameObject val2 = ObjectDB.instance.GetItemPrefab(val.m_shared);
			if ((Object)(object)val2 == (Object)null && ObjectDB.instance.m_items != null && !string.IsNullOrEmpty(val.m_shared.m_name))
			{
				for (int j = 0; j < ObjectDB.instance.m_items.Count; j++)
				{
					GameObject val3 = ObjectDB.instance.m_items[j];
					if ((Object)(object)val3 != (Object)null)
					{
						ItemDrop component = val3.GetComponent<ItemDrop>();
						if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_name == val.m_shared.m_name)
						{
							val2 = val3;
							break;
						}
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val.m_dropPrefab = val2;
			}
		}
	}
}
[HarmonyPatch(typeof(Tameable), "Awake")]
public static class Patch_Tameable_Awake
{
	public static void Postfix(Tameable __instance)
	{
		if ((Object)(object)__instance != (Object)null && __instance.m_tamingTime > 600f)
		{
			__instance.m_tamingTime = 600f;
		}
	}
}
[HarmonyPatch(typeof(Procreation), "Awake")]
public static class Patch_Procreation_Awake
{
	public static void Postfix(Procreation __instance)
	{
		if ((Object)(object)__instance != (Object)null)
		{
			__instance.m_pregnancyDuration = 120f;
			__instance.m_maxCreatures = 10;
			if (__instance.m_totalCheckRange < 20f)
			{
				__instance.m_totalCheckRange = 20f;
			}
		}
	}
}
[HarmonyPatch(typeof(SpawnSystem), "Spawn")]
public static class Patch_SpawnSystem_Spawn
{
	public static bool Prefix(SpawnData critter, Vector3 spawnPoint, bool eventSpawner)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (eventSpawner)
			{
				return true;
			}
			float num = 2025f;
			int num2 = 0;
			List<Character> allCharacters = Character.GetAllCharacters();
			if (allCharacters != null)
			{
				for (int i = 0; i < allCharacters.Count; i++)
				{
					Character val = allCharacters[i];
					if ((Object)(object)val != (Object)null && !val.IsPlayer() && !val.IsTamed() && !val.IsDead() && Vector3.SqrMagnitude(((Component)val).transform.position - spawnPoint) <= num)
					{
						num2++;
						if (num2 >= 10)
						{
							return false;
						}
					}
				}
			}
		}
		catch (Exception)
		{
		}
		return true;
	}
}
[HarmonyPatch(typeof(MonsterAI), "Awake")]
public static class Patch_MonsterAI_Awake
{
	public static void Postfix(MonsterAI __instance)
	{
		if ((Object)(object)__instance != (Object)null && __instance.m_fallAsleepDistance < 35f)
		{
			__instance.m_fallAsleepDistance = 35f;
		}
	}
}