Decompiled source of Serverside Simulations v1.1.9

Serverside_Simulations.dll

Decompiled a week ago
#define TRACE
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FeaturesLib;
using HarmonyLib;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using PatchingLib;
using PluginConfiguration;
using Requirements;
using UnityEngine;
using Valheim_Serverside;
using Valheim_Serverside.Features;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Valheim_Serverside")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Valheim_Serverside")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("118598c3-bcc2-4a92-a60e-f77be92f1305")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace PluginConfiguration
{
	public class Configuration
	{
		public static ConfigEntry<bool> modEnabled;

		public static ConfigEntry<bool> maxObjectsPerFrameEnabled;

		public static ConfigEntry<int> maxObjectsPerFrame;

		public static void Load(ConfigFile config)
		{
			modEnabled = config.Bind<bool>("General", "Enabled", true, "Enable or disable the mod");
			maxObjectsPerFrameEnabled = config.Bind<bool>("MaxObjectsPerFrame", "Enabled", true, "Enable or disable the feature");
			maxObjectsPerFrame = config.Bind<int>("MaxObjectsPerFrame", "MaxObjects", 100, "Maximum number of objects the server can create per frame.");
		}
	}
}
namespace FeaturesLib
{
	public interface IFeature
	{
		bool FeatureEnabled();
	}
	public class AvailableFeatures
	{
		public readonly List<IFeature> _features;

		public AvailableFeatures()
		{
			_features = new List<IFeature>();
		}

		public AvailableFeatures(List<IFeature> features)
		{
			_features = features;
		}

		public AvailableFeatures AddFeature(IFeature feature)
		{
			_features.Add(feature);
			return this;
		}

		public List<IFeature> EnabledFeatures()
		{
			return _features.Where((IFeature feature) => feature.FeatureEnabled()).ToList();
		}

		public Type[] GetAllNestedTypes()
		{
			return (from feature in EnabledFeatures()
				select feature.GetType().GetNestedTypes() into list
				from item in list
				select item).ToArray();
		}
	}
}
namespace Requirements
{
	public class PatchRequirement
	{
		public class DebugBuild : IPatchRequirement
		{
			public const string name = "DebugBuild";

			string IPatchRequirement.Name => "DebugBuild";

			Func<bool> IPatchRequirement.Checker => Utilities.IsDebugBuild;
		}
	}
}
namespace PatchingLib
{
	public interface IPatchRequirement
	{
		string Name { get; }

		Func<bool> Checker { get; }
	}
	public class PatchRequirements
	{
		private readonly Dictionary<string, Func<bool>> _requirements;

		public PatchRequirements()
		{
			_requirements = new Dictionary<string, Func<bool>>();
		}

		public PatchRequirements(Dictionary<string, Func<bool>> requirements)
		{
			_requirements = requirements;
		}

		public PatchRequirements AddRequirement(IPatchRequirement patchRequirement)
		{
			_requirements.Add(patchRequirement.Name, patchRequirement.Checker);
			return this;
		}

		public bool IsAllowed(string requirement_name)
		{
			_requirements.TryGetValue(requirement_name, out var value);
			return value?.Invoke() ?? false;
		}
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
	public class PatchRequiresAttribute : Attribute
	{
		public readonly string requirement_name;

		public PatchRequiresAttribute(string requirement_name)
		{
			this.requirement_name = requirement_name;
		}
	}
	public class HarmonyFeaturesPatcher
	{
		private readonly PatchRequirements _patchRequirements;

		public HarmonyFeaturesPatcher(PatchRequirements availableFeatures)
		{
			_patchRequirements = availableFeatures;
		}

		public void PatchAll(Type[] types, Harmony harmony_instance)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			foreach (Type type in types)
			{
				if (!type.GetCustomAttributes<PatchRequiresAttribute>().ToList().Any((PatchRequiresAttribute attribute) => !_patchRequirements.IsAllowed(attribute.requirement_name)))
				{
					ZLog.Log((object)("Patching: " + type.ToString()));
					new PatchClassProcessor(harmony_instance, type).Patch();
				}
				else
				{
					ZLog.Log((object)("Patch disabled: " + type.ToString()));
				}
			}
		}
	}
}
namespace Valheim_Serverside
{
	public class Utilities
	{
		public static bool IsDebugBuild()
		{
			return false;
		}
	}
	public class SequentialInstructions
	{
		private int num_found;

		public List<CodeInstruction> Sequential;

		public SequentialInstructions(List<CodeInstruction> instructions)
		{
			Sequential = instructions;
		}

		public bool Check(CodeInstruction instruction)
		{
			for (int i = 0; i < Sequential.Count(); i++)
			{
				CodeInstruction val = Sequential[i];
				bool flag = false;
				_ = val.opcode;
				if (val.operand != null && val.opcode == instruction.opcode && val.operand == instruction.operand)
				{
					flag = true;
				}
				else
				{
					_ = val.opcode;
					if (val.operand == null && val.opcode == instruction.opcode)
					{
						flag = true;
					}
					else if (val.operand != null)
					{
						_ = val.opcode;
					}
				}
				if (flag && i == num_found)
				{
					if (i == 0)
					{
						num_found = 1;
					}
					else
					{
						num_found = i + 1;
					}
					if (num_found == Sequential.Count())
					{
						return true;
					}
					return false;
				}
			}
			num_found = 0;
			return false;
		}
	}
	[Harmony]
	[BepInPlugin("MVP.Valheim_Serverside_Simulations", "Serverside Simulations", "1.1.9")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ServersidePlugin : BaseUnityPlugin
	{
		private static ServersidePlugin context;

		public static Configuration configuration;

		public static Harmony harmony;

		public const string ValheimPlusPluginId = "org.bepinex.plugins.valheim_plus";

		public static ManualLogSource logger;

		private void Awake()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			context = this;
			logger = ((BaseUnityPlugin)this).Logger;
			Configuration.Load(((BaseUnityPlugin)this).Config);
			if (!ModIsEnabled())
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Serverside Simulations is disabled. (configuration)");
				return;
			}
			if (!IsDedicated())
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Serverside Simulations is disabled. (not a dedicated server)");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Installing Serverside Simulations");
			harmony = new Harmony("MVP.Valheim_Serverside_Simulations");
			AvailableFeatures availableFeatures = new AvailableFeatures();
			availableFeatures.AddFeature(new Core());
			availableFeatures.AddFeature(new MaxObjectsPerFrame());
			availableFeatures.AddFeature(new Debugging());
			availableFeatures.AddFeature(new Compat_ValheimPlus());
			PatchRequirements patchRequirements = new PatchRequirements();
			patchRequirements.AddRequirement(new PatchRequirement.DebugBuild());
			new HarmonyFeaturesPatcher(patchRequirements).PatchAll(availableFeatures.GetAllNestedTypes(), harmony);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Serverside Simulations installed");
		}

		public bool ModIsEnabled()
		{
			return Configuration.modEnabled.Value;
		}

		public static bool IsDedicated()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new ZNet().IsDedicated();
		}
	}
}
namespace Valheim_Serverside.Features
{
	public class Compat_ValheimPlus : IFeature
	{
		public class ZNetScene_Awake_Patch
		{
			private static bool triedToPatchSmelter;

			public static void Postfix()
			{
				if (!triedToPatchSmelter)
				{
					TryPatchSmelter();
					triedToPatchSmelter = true;
				}
			}
		}

		public bool haveValheimPlus;

		public Compat_ValheimPlus()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			haveValheimPlus = Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.valheim_plus");
			if (haveValheimPlus)
			{
				TryPatchInventoryAssistant();
				ServersidePlugin.harmony.Patch((MethodBase)AccessTools.Method(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(ZNetScene_Awake_Patch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public bool FeatureEnabled()
		{
			return haveValheimPlus;
		}

		private void TryPatchInventoryAssistant()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			Type type = Type.GetType("ValheimPlus.InventoryAssistant, ValheimPlus");
			if (type != null)
			{
				ServersidePlugin.logger.LogInfo((object)"Patching ValheimPlus.InventoryAssistant.GetNearbyChests");
				ServersidePlugin.harmony.Patch((MethodBase)AccessTools.Method(type, "GetNearbyChests", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Compat_ValheimPlus), "Transpile_InventoryAssistant_GetNearbyChests", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				ServersidePlugin.logger.LogError((object)"Couldn't find ValheimPlus.InventoryAssistant");
			}
		}

		private static void TryPatchSmelter()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			Type type = Type.GetType("ValheimPlus.GameClasses.Smelter_UpdateSmelter_Patch, ValheimPlus");
			if (type != null)
			{
				ServersidePlugin.logger.LogInfo((object)"Patching ValheimPlus.GameClasses.Smelter_UpdateSmelter_Patch.Prefix");
				ServersidePlugin.harmony.Patch((MethodBase)AccessTools.Method(type, "Prefix", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Compat_ValheimPlus), "Transpile_Smelter_FixedUpdate_Patch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				ServersidePlugin.logger.LogError((object)"Couldn't find ValheimPlus.GameClasses.Smelter_UpdateSmelter_Patch");
			}
		}

		private static IEnumerable<CodeInstruction> Transpile_InventoryAssistant_GetNearbyChests(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Player), "m_localPlayer"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Player), "GetPlayerID", (Type[])null, (Type[])null), (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null), (string)null)
			}).RemoveInstructions(4).Insert((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldc_I4_1, (object)null)
			})
				.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_2, (object)null, (string)null)
				})
				.SetInstruction(new CodeInstruction(OpCodes.Ldc_I4_0, (object)null))
				.InstructionEnumeration();
		}

		private static IEnumerable<CodeInstruction> Transpile_Smelter_FixedUpdate_Patch(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Object), "op_Implicit", (Type[])null, (Type[])null), (string)null),
				new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null)
			}).SetOpcodeAndAdvance(OpCodes.Brtrue).InstructionEnumeration();
		}
	}
	public class Core : IFeature
	{
		[HarmonyPatch(typeof(ZNetScene), "CreateDestroyObjects")]
		public class CreateDestroyObjects_Patch
		{
			private static bool Prefix(ZNetScene __instance)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				List<ZDO> list = new List<ZDO>();
				List<ZDO> list2 = new List<ZDO>();
				foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers())
				{
					Vector2i zone = ZoneSystem.GetZone(connectedPeer.GetRefPos());
					ZDOMan.instance.FindSectorObjects(zone, ZoneSystem.instance.m_activeArea, ZoneSystem.instance.m_activeDistantArea, list, list2);
				}
				list2 = list2.Distinct().ToList();
				list = list.Distinct().ToList();
				Traverse.Create((object)__instance).Method("CreateObjects", new object[2] { list, list2 }).GetValue();
				Traverse.Create((object)__instance).Method("RemoveObjects", new object[2] { list, list2 }).GetValue();
				return false;
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "IsActiveAreaLoaded")]
		public static class ZoneSystem_IsActiveAreaLoaded_Patch
		{
			private static bool Prefix(ZoneSystem __instance, ref bool __result, Dictionary<Vector2i, dynamic> ___m_zones)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: 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_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				foreach (ZNetPeer peer in ZNet.instance.GetPeers())
				{
					Vector2i zone = ZoneSystem.GetZone(peer.GetRefPos());
					for (int i = zone.y - __instance.m_activeArea; i <= zone.y + __instance.m_activeArea; i++)
					{
						for (int j = zone.x - __instance.m_activeArea; j <= zone.x + __instance.m_activeArea; j++)
						{
							if (!___m_zones.ContainsKey(new Vector2i(j, i)))
							{
								__result = false;
								return false;
							}
						}
					}
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Update")]
		public static class ZoneSystem_Update_Patch
		{
			private static bool Prefix(ZoneSystem __instance, ref float ___m_updateTimer)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				if ((int)ZNet.GetConnectionStatus() != 2)
				{
					return false;
				}
				___m_updateTimer += Time.deltaTime;
				if (___m_updateTimer > 0.1f)
				{
					___m_updateTimer = 0f;
					Traverse.Create((object)__instance).Method("UpdateTTL", new object[1] { 0.1f }).GetValue();
					if (ZNet.instance.IsServer())
					{
						foreach (ZNetPeer peer in ZNet.instance.GetPeers())
						{
							Traverse.Create((object)__instance).Method("CreateLocalZones", new object[1] { peer.GetRefPos() }).GetValue();
						}
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(ZDOMan), "ReleaseNearbyZDOS")]
		public static class ZDOMan_ReleaseNearbyZDOS_Patch
		{
			private static bool Prefix(ZDOMan __instance, ref Vector3 refPosition, ref long uid)
			{
				//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_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				Vector2i zone = ZoneSystem.GetZone(refPosition);
				List<ZDO> value = Traverse.Create((object)__instance).Field("m_tempNearObjects").GetValue<List<ZDO>>();
				value.Clear();
				__instance.FindSectorObjects(zone, ZoneSystem.instance.m_activeArea, 0, value, (List<ZDO>)null);
				foreach (ZDO item in value)
				{
					if (!item.Persistent)
					{
						continue;
					}
					bool flag = false;
					foreach (ZNetPeer peer in ZNet.instance.GetPeers())
					{
						if (ZNetScene.InActiveArea(item.GetSector(), ZoneSystem.GetZone(peer.GetRefPos())))
						{
							flag = true;
							break;
						}
					}
					long owner = item.GetOwner();
					if (owner == uid || owner == ZNet.GetUID())
					{
						if (!flag)
						{
							item.SetOwner(0L);
						}
					}
					else if ((owner == 0L || !new Traverse((object)__instance).Method("IsInPeerActiveArea", new object[2]
					{
						item.GetSector(),
						item.GetOwner()
					}).GetValue<bool>()) && flag)
					{
						item.SetOwner(ZNet.GetUID());
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(RandEventSystem), "FixedUpdate")]
		public static class RandEventSystem_FixedUpdate_Patch
		{
			[CompilerGenerated]
			private sealed class <Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private CodeInstruction <>2__current;

				private int <>l__initialThreadId;

				private IEnumerable<CodeInstruction> _instructions;

				public IEnumerable<CodeInstruction> <>3___instructions;

				private List<CodeInstruction> <new_instructions>5__2;

				private SequentialInstructions <localPlayerCheck>5__3;

				private int <i>5__4;

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

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

				[DebuggerHidden]
				public <Transpiler>d__1(int <>1__state)
				{
					this.<>1__state = <>1__state;
					<>l__initialThreadId = Environment.CurrentManagedThreadId;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<new_instructions>5__2 = null;
					<localPlayerCheck>5__3 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_0097: Unknown result type (might be due to invalid IL or missing references)
					//IL_009d: Expected O, but got Unknown
					//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ab: Expected O, but got Unknown
					//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b9: Expected O, but got Unknown
					//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c7: Expected O, but got Unknown
					//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d5: Expected O, but got Unknown
					//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
					//IL_00e3: Expected O, but got Unknown
					//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f1: Expected O, but got Unknown
					//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
					//IL_01c2: Expected O, but got Unknown
					//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
					//IL_01d0: Expected O, but got Unknown
					//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
					//IL_01de: Expected O, but got Unknown
					//IL_0225: Unknown result type (might be due to invalid IL or missing references)
					//IL_022f: Expected O, but got Unknown
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						MethodInfo methodInfo = AccessTools.Method(typeof(RandEventSystem), "IsAnyPlayerInEventArea", (Type[])null, (Type[])null);
						FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_localPlayer");
						MethodInfo methodInfo2 = AccessTools.Method(typeof(Object), "op_Implicit", (Type[])null, (Type[])null);
						bool flag = false;
						CodeInstruction val = null;
						List<CodeInstruction> list = _instructions.ToList();
						<new_instructions>5__2 = _instructions.ToList();
						SequentialInstructions sequentialInstructions = new SequentialInstructions(new List<CodeInstruction>((IEnumerable<CodeInstruction>)(object)new CodeInstruction[7]
						{
							new CodeInstruction(OpCodes.Ldarg_0, (object)null),
							new CodeInstruction(OpCodes.Ldarg_0, (object)null),
							new CodeInstruction(OpCodes.Ldfld, (object)null),
							new CodeInstruction(OpCodes.Ldsfld, (object)null),
							new CodeInstruction(OpCodes.Callvirt, (object)null),
							new CodeInstruction(OpCodes.Callvirt, (object)null),
							new CodeInstruction(OpCodes.Call, (object)null)
						}));
						for (int i = 0; i < list.Count; i++)
						{
							CodeInstruction val2 = list[i];
							if (CodeInstructionExtensions.OperandIs(val2, (MemberInfo)methodInfo))
							{
								flag = true;
							}
							else if (flag && CodeInstructionExtensions.IsStloc(val2, (LocalBuilder)null))
							{
								val = val2.Clone();
								val.opcode = StlocToLdloc[val2.opcode];
								flag = false;
							}
							else if (val != null && sequentialInstructions.Check(val2))
							{
								int count = sequentialInstructions.Sequential.Count;
								int index = i - (count - 1);
								<new_instructions>5__2.RemoveRange(index, count);
								<new_instructions>5__2.Insert(index, val);
								break;
							}
						}
						<localPlayerCheck>5__3 = new SequentialInstructions(new List<CodeInstruction>((IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
						{
							new CodeInstruction(OpCodes.Ldsfld, (object)fieldInfo),
							new CodeInstruction(OpCodes.Call, (object)methodInfo2),
							new CodeInstruction(OpCodes.Brfalse, (object)null)
						}));
						<i>5__4 = 0;
						break;
					}
					case 1:
						<>1__state = -1;
						goto IL_0259;
					case 2:
						{
							<>1__state = -1;
							goto IL_0259;
						}
						IL_0259:
						<i>5__4++;
						break;
					}
					if (<i>5__4 < <new_instructions>5__2.Count)
					{
						CodeInstruction val3 = <new_instructions>5__2[<i>5__4];
						if (<localPlayerCheck>5__3.Check(val3))
						{
							<>2__current = new CodeInstruction(OpCodes.Brtrue, val3.operand);
							<>1__state = 1;
							return true;
						}
						<>2__current = val3;
						<>1__state = 2;
						return true;
					}
					return false;
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}

				[DebuggerHidden]
				IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
				{
					<Transpiler>d__1 <Transpiler>d__;
					if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
					{
						<>1__state = 0;
						<Transpiler>d__ = this;
					}
					else
					{
						<Transpiler>d__ = new <Transpiler>d__1(0);
					}
					<Transpiler>d__._instructions = <>3___instructions;
					return <Transpiler>d__;
				}

				[DebuggerHidden]
				IEnumerator IEnumerable.GetEnumerator()
				{
					return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
				}
			}

			private static Dictionary<OpCode, OpCode> StlocToLdloc = new Dictionary<OpCode, OpCode>
			{
				{
					OpCodes.Stloc_0,
					OpCodes.Ldloc_0
				},
				{
					OpCodes.Stloc_1,
					OpCodes.Ldloc_1
				},
				{
					OpCodes.Stloc_2,
					OpCodes.Ldloc_2
				},
				{
					OpCodes.Stloc_3,
					OpCodes.Ldloc_3
				},
				{
					OpCodes.Stloc_S,
					OpCodes.Ldloc_S
				},
				{
					OpCodes.Stloc,
					OpCodes.Ldloc
				}
			};

			[IteratorStateMachine(typeof(<Transpiler>d__1))]
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> _instructions)
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <Transpiler>d__1(-2)
				{
					<>3___instructions = _instructions
				};
			}
		}

		[HarmonyPatch(typeof(SpawnSystem), "UpdateSpawning")]
		public static class SpawnSystem_UpdateSpawning_Patch
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> _instructions)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Expected O, but got Unknown
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Expected O, but got Unknown
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Expected O, but got Unknown
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Expected O, but got Unknown
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Expected O, but got Unknown
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Expected O, but got Unknown
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Expected O, but got Unknown
				return new CodeMatcher(_instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[4]
				{
					new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Player), "m_localPlayer"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Object), "op_Equality", (Type[])null, (Type[])null), (string)null),
					new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null)
				}).SetOpcodeAndAdvance(OpCodes.Brtrue).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(RandEventSystem), "GetCurrentSpawners", (Type[])null, (Type[])null), (string)null)
				})
					.RemoveInstruction()
					.Insert((CodeInstruction[])(object)new CodeInstruction[2]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Core), "GetCurrentSpawners", (Type[])null, (Type[])null))
					})
					.InstructionEnumeration();
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "OutsideActiveArea", new Type[] { typeof(Vector3) })]
		public static class ZNetScene_OutsideActiveArea_Patch
		{
			private static bool Prefix(ref bool __result, ZNetScene __instance, Vector3 point)
			{
				//IL_001d: 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)
				__result = true;
				foreach (ZNetPeer peer in ZNet.instance.GetPeers())
				{
					if (!ZNetScene.OutsideActiveArea(point, peer.GetRefPos()))
					{
						__result = false;
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(ZRoutedRpc), "RouteRPC")]
		public static class ZRoutedRpc_RouteRPC_Patch
		{
			private static void Prefix(RoutedRPCData rpcData)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				if (rpcData.m_methodHash == StringExtensionMethods.GetStableHashCode("RequestRespons"))
				{
					bool flag = rpcData.m_parameters.ReadBool();
					ZDO zDO = ZDOMan.instance.GetZDO(rpcData.m_targetZDO);
					if (zDO != null && flag)
					{
						ServersidePlugin.logger.LogDebug((object)$"RequestRespons: Setting ship's owner to {rpcData.m_targetPeerID}");
						zDO.SetOwner(rpcData.m_targetPeerID);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UpdateAttack")]
		public static class Humanoid_UpdateAttack_Patch
		{
			private static void Prefix(ref Humanoid __instance)
			{
				if (__instance.m_currentAttack != null && (Object)(object)__instance.m_currentAttack.m_character == (Object)null)
				{
					__instance.m_currentAttack = null;
				}
			}
		}

		[HarmonyPatch(typeof(WearNTear), "UpdateSupport")]
		public static class WearNTear_UpdateSupport_Patch
		{
			private static void Prefix(ref WearNTear __instance)
			{
				if (__instance.m_colliders != null && __instance.m_bounds == null)
				{
					__instance.SetupColliders();
				}
			}
		}

		[HarmonyPatch(typeof(Ship), "UpdateOwner")]
		public static class Ship_UpdateOwner_Patch
		{
			private static bool Prefix(ref Ship __instance)
			{
				ZDO zDO = __instance.m_nview.GetZDO();
				if (zDO.GetInt("InUse", 0) == 0)
				{
					if (!__instance.m_shipControlls.HaveValidUser())
					{
						__instance.m_lastWaterImpactTime = Time.time;
						zDO.SetOwner(ZNet.GetUID());
						return false;
					}
					long user = __instance.m_shipControlls.GetUser();
					if (user != 0L)
					{
						long owner = ((Character)Player.GetPlayer(user)).GetOwner();
						ServersidePlugin.logger.LogDebug((object)$"UpdateOwner: Setting ship's owner to {owner}");
						zDO.SetOwner(owner);
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(AudioMan), "Update")]
		public static class AudioMan_Update_Patch
		{
			private static bool Prefix()
			{
				return false;
			}
		}

		[HarmonyPatch(typeof(ShieldDomeImageEffect), "GetDomeColor")]
		public static class ShieldDomeImageEffect_GetDomeColor_Patch
		{
			private static bool Prefix(ref Color __result)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				__result = new Color(1f, 1f, 1f);
				return false;
			}
		}

		public bool FeatureEnabled()
		{
			return true;
		}

		public static bool IsServer()
		{
			if (Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return ZNet.instance.IsServer();
			}
			return false;
		}

		public static void PrintLog(string text)
		{
			Trace.WriteLine(text);
		}

		public static void PrintLog(object[] obj)
		{
			Trace.WriteLine(string.Concat(obj));
		}

		public static List<SpawnData> GetCurrentSpawners(RandEventSystem instance, SpawnSystem spawnSystem)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (Traverse.Create((object)instance).Field("m_activeEvent").GetValue<RandomEvent>() == null)
			{
				return null;
			}
			ZNetView value = Traverse.Create((object)spawnSystem).Field("m_nview").GetValue<ZNetView>();
			RandomEvent value2 = Traverse.Create((object)instance).Field("m_randomEvent").GetValue<RandomEvent>();
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (ZNetScene.InActiveArea(value.GetZDO().GetSector(), ((Component)allPlayer).transform.position) && Traverse.Create((object)instance).Method("IsInsideRandomEventArea", new Type[2]
				{
					typeof(RandomEvent),
					typeof(Vector3)
				}, new object[2]
				{
					value2,
					((Component)allPlayer).transform.position
				}).GetValue<bool>())
				{
					return instance.GetCurrentSpawners();
				}
			}
			return null;
		}
	}
	public class MaxObjectsPerFrame : IFeature
	{
		[HarmonyPatch(typeof(ZNetScene), "CreateObjects")]
		public class CreateObjects_Patch
		{
			public static void ILManipulator(ILContext il)
			{
				//IL_0001: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
				new ILCursor(il).GotoNext((MoveType)0, new Func<Instruction, bool>[5]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 0),
					(Instruction i) => ILPatternMatchingExt.MatchLdarg(i, 1),
					(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 0),
					(Instruction i) => ILPatternMatchingExt.MatchLdloca(i, 1),
					(Instruction i) => ILPatternMatchingExt.MatchCall<ZNetScene>(i, "CreateObjectsSorted")
				}).Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(MaxObjectsPerFrame), "GetMaxCreatedPerFrame", (Type[])null, (Type[])null)).Emit(OpCodes.Stloc_0);
			}
		}

		public bool FeatureEnabled()
		{
			return Configuration.maxObjectsPerFrameEnabled.Value;
		}

		public static int GetMaxCreatedPerFrame()
		{
			return Configuration.maxObjectsPerFrame.Value;
		}
	}
	[Harmony]
	internal class Debugging : IFeature
	{
		[PatchRequires("DebugBuild")]
		[HarmonyPatch(typeof(Chat), "RPC_ChatMessage")]
		public static class Chat_RPC_ChatMessage_Patch
		{
			private static void Prefix(ref long sender, ref string text)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				ZNetPeer peer = ZNet.instance.GetPeer(sender);
				if (peer != null)
				{
					if (text == "startevent")
					{
						RandEventSystem.instance.SetRandomEventByName("army_theelder", peer.GetRefPos());
					}
					else if (text == "stopevent")
					{
						RandEventSystem.instance.ResetRandomEvent();
					}
					else if (text.StartsWith("maxobjects"))
					{
						Configuration.maxObjectsPerFrame.Value = Convert.ToInt32(text.Split(new char[1] { ' ' }).GetValue(1));
					}
				}
			}
		}

		public bool FeatureEnabled()
		{
			return Utilities.IsDebugBuild();
		}
	}
}