Decompiled source of PeakSafeOptimizer v1.0.0

plugins/PeakSafeOptimizer.dll

Decompiled 9 hours ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Peak.Afflictions;
using Peak.Network;
using PeakSafeOptimizer.Config;
using PeakSafeOptimizer.Diagnostics;
using PeakSafeOptimizer.Graphics;
using PeakSafeOptimizer.Infrastructure;
using PeakSafeOptimizer.Patches.Scale;
using Photon.Pun;
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityEngine.Playables;
using UnityEngine.SceneManagement;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PeakSafeOptimizer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2651244b36adcdccf970b931a35bed725d4c6566")]
[assembly: AssemblyProduct("PeakSafeOptimizer")]
[assembly: AssemblyTitle("PeakSafeOptimizer")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PeakSafeOptimizer
{
	internal sealed class CollisionCallbackReuse
	{
		private readonly ManualLogSource _log;

		private bool _applied;

		private bool _originalValue;

		private bool _hasOriginalValue;

		private bool _loggedBlocked;

		internal CollisionCallbackReuse(ManualLogSource log)
		{
			_log = log;
		}

		internal void Evaluate(PatchInstaller installer)
		{
			ConfigEntry<bool> collisionCallbackReuse = OptimizerConfig.CollisionCallbackReuse;
			bool flag = collisionCallbackReuse != null && collisionCallbackReuse.Value && installer != null && installer.IsInstalled(PatchId.SnowballContactSnapshot) && installer.IsInstalled(PatchId.SnowballContactConsume);
			if (flag == _applied)
			{
				if (!flag && !_loggedBlocked)
				{
					ConfigEntry<bool> collisionCallbackReuse2 = OptimizerConfig.CollisionCallbackReuse;
					if (collisionCallbackReuse2 != null && collisionCallbackReuse2.Value)
					{
						LogBlocked(installer);
					}
				}
				return;
			}
			_loggedBlocked = false;
			try
			{
				if (flag)
				{
					if (!_hasOriginalValue)
					{
						_originalValue = Physics.reuseCollisionCallbacks;
						_hasOriginalValue = true;
					}
					Physics.reuseCollisionCallbacks = true;
					_applied = true;
					ManualLogSource log = _log;
					if (log != null)
					{
						log.LogInfo((object)("PeakSafeOptimizer | Physics.reuseCollisionCallbacks = true " + $"(was {_originalValue}); the Snowball cross-frame collision reference is guarded."));
					}
				}
				else
				{
					Restore("guard unavailable");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogError((object)("Collision callback reuse toggle failed safely: " + ex.GetType().Name + ": " + ex.Message));
				}
			}
		}

		internal void Shutdown()
		{
			if (_applied)
			{
				Restore("shutdown");
			}
		}

		private void Restore(string reason)
		{
			_applied = false;
			if (!_hasOriginalValue)
			{
				return;
			}
			try
			{
				Physics.reuseCollisionCallbacks = _originalValue;
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogInfo((object)$"PeakSafeOptimizer | Physics.reuseCollisionCallbacks restored to {_originalValue} ({reason}).");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogError((object)("Collision callback reuse restore failed safely: " + ex.GetType().Name + ": " + ex.Message));
				}
			}
		}

		private void LogBlocked(PatchInstaller installer)
		{
			_loggedBlocked = true;
			bool flag = installer?.IsInstalled(PatchId.SnowballContactSnapshot) ?? false;
			bool flag2 = installer?.IsInstalled(PatchId.SnowballContactConsume) ?? false;
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogWarning((object)("PeakSafeOptimizer | CollisionCallbackReuse stays off: it needs both Snowball guards " + $"(SnowballContactSnapshot installed={flag}, SnowballContactConsume installed={flag2})."));
			}
		}
	}
	[BepInPlugin("com.peak.safeoptimizer", "PeakSafeOptimizer", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.peak.safeoptimizer";

		public const string PluginName = "PeakSafeOptimizer";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		private LifecycleRegistry _lifecycle;

		private OptimizerConfig _settings;

		private PatchInstaller _installer;

		private BoneWeightCap _boneWeightCap;

		private CollisionCallbackReuse _collisionReuse;

		private int _mainThreadId;

		private readonly ConcurrentQueue<PatchId> _pendingSettingChanges = new ConcurrentQueue<PatchId>();

		private void Awake()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			try
			{
				_mainThreadId = Thread.CurrentThread.ManagedThreadId;
				_settings = OptimizerConfig.Bind(((BaseUnityPlugin)this).Config);
				RateLimitedDiagnostics.Initialize(((BaseUnityPlugin)this).Logger, _settings.DetailedDiagnostics);
				_lifecycle = new LifecycleRegistry(((BaseUnityPlugin)this).Logger);
				_lifecycle.Register(RateLimitedDiagnostics.Reset);
				BuildFingerprint buildFingerprint = BuildFingerprint.Capture();
				((BaseUnityPlugin)this).Logger.LogInfo((object)buildFingerprint.ToDiagnosticString());
				_harmony = new Harmony("com.peak.safeoptimizer");
				_installer = new PatchInstaller(_harmony, buildFingerprint, ((BaseUnityPlugin)this).Logger);
				PatchCatalogSnapshot catalog = PatchCatalog.Discover(typeof(Plugin).Assembly, _settings, _lifecycle, ((BaseUnityPlugin)this).Logger);
				foreach (string item in _installer.Install(catalog).FormatReport())
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)item);
				}
				_boneWeightCap = new BoneWeightCap(((BaseUnityPlugin)this).Logger);
				_collisionReuse = new CollisionCallbackReuse(((BaseUnityPlugin)this).Logger);
				_collisionReuse.Evaluate(_installer);
				((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Plugin startup failed safely; no failure will escape Awake. {arg}");
				RollbackAfterFailedStartup();
			}
		}

		private void RollbackAfterFailedStartup()
		{
			try
			{
				((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Startup rollback: unsubscribe SettingChanged failed safely: " + ex.GetType().Name + ": " + ex.Message));
			}
			if (UninstallAll("Startup rollback"))
			{
				ShutdownGlobalLanes();
				DisposeLifecycle("Startup rollback");
				_lifecycle = null;
				_harmony = null;
				_installer = null;
				_settings = null;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"PeakSafeOptimizer | startup rolled back: all known patches were removed.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"PeakSafeOptimizer | startup rollback left one or more patches attached; their state was retained rather than reset underneath live Harmony methods.");
			}
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			try
			{
				if (((args != null) ? args.ChangedSetting : null) == null || _settings == null || !_settings.TryGetPatchIds(args.ChangedSetting, out var ids))
				{
					return;
				}
				bool flag = Thread.CurrentThread.ManagedThreadId != _mainThreadId;
				for (int i = 0; i < ids.Count; i++)
				{
					if (flag)
					{
						_pendingSettingChanges.Enqueue(ids[i]);
					}
					else
					{
						ApplySettingChange(ids[i]);
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("HotReload failed safely: " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private void Update()
		{
			PatchId result;
			while (_pendingSettingChanges.TryDequeue(out result))
			{
				ApplySettingChange(result);
			}
			_boneWeightCap?.Update(Time.unscaledDeltaTime);
			_collisionReuse?.Evaluate(_installer);
		}

		private void ApplySettingChange(PatchId id)
		{
			if (_settings == null || _installer == null)
			{
				return;
			}
			bool flag = _settings.IsEnabled(id);
			PatchStatus patchStatus = _installer.Toggle(id, flag);
			PatchStatusEntry patchStatusEntry = ((patchStatus.Entries.Count > 0) ? patchStatus.Entries[0] : null);
			if (patchStatusEntry != null)
			{
				switch (patchStatusEntry.Outcome)
				{
				case PatchOutcome.Applied:
					((BaseUnityPlugin)this).Logger.LogInfo((object)(flag ? $"HotReload: {id} enabled→installed" : $"HotReload: {id} disabled→uninstalled"));
					break;
				case PatchOutcome.Skipped:
					((BaseUnityPlugin)this).Logger.LogInfo((object)(flag ? $"HotReload: {id} enabled→{patchStatusEntry.Result}: {patchStatusEntry.Reason}" : $"HotReload: {id} disabled→{patchStatusEntry.Result}: {patchStatusEntry.Reason}"));
					break;
				case PatchOutcome.Failed:
					((BaseUnityPlugin)this).Logger.LogError((object)$"HotReload: {id} {patchStatusEntry.Result}: {patchStatusEntry.Reason}");
					break;
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Unsubscribe SettingChanged failed: {arg}");
			}
			ShutdownGlobalLanes();
			if (UninstallAll("Shutdown"))
			{
				DisposeLifecycle("Shutdown");
				_lifecycle = null;
				_harmony = null;
				_installer = null;
				_settings = null;
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"PeakSafeOptimizer shutdown left one or more patches attached; state was retained to keep those methods safe until process exit.");
			}
		}

		private bool UninstallAll(string phase)
		{
			if (_installer == null)
			{
				return true;
			}
			try
			{
				foreach (PatchStatusEntry entry in _installer.UninstallAll().Entries)
				{
					if (entry.Outcome == PatchOutcome.Failed)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)$"{phase}: {entry.Name} {entry.Result}: {entry.Reason}");
					}
				}
				return !_installer.HasInstalledPatches;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)(phase + ": verified uninstall failed safely: " + ex.GetType().Name + ": " + ex.Message));
				return false;
			}
		}

		private void ShutdownGlobalLanes()
		{
			try
			{
				_collisionReuse?.Shutdown();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Collision reuse shutdown failed safely: " + ex.GetType().Name + ": " + ex.Message));
			}
			_collisionReuse = null;
			try
			{
				_boneWeightCap?.Shutdown();
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Bone weight cap shutdown failed safely: " + ex2.GetType().Name + ": " + ex2.Message));
			}
			_boneWeightCap = null;
		}

		private void DisposeLifecycle(string phase)
		{
			try
			{
				_lifecycle?.Dispose();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)(phase + ": lifecycle dispose failed safely: " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}
}
namespace PeakSafeOptimizer.Patches.Stability
{
	internal sealed class EmoteWheelGuardModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.EmoteWheelGuard, () => new PatchDefinition(PatchId.EmoteWheelGuard, EmoteWheelGuardPatch.Initialize, EmoteWheelGuardPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(EmoteWheelGuardPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, EmoteWheelGuardPatch.Reset));
		}
	}
	internal static class EmoteWheelGuardPatch
	{
		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo field = typeof(Character).GetField("localCharacter", BindingFlags.Static | BindingFlags.Public);
			if (field == null || !field.IsStatic || field.FieldType != typeof(Character))
			{
				throw new InvalidOperationException("Character.localCharacter failed structural self-check");
			}
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterRefs), "stats", typeof(CharacterStats));
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return StabilityPatchValidation.RequireInstanceMethod(typeof(GUIManager), "UpdateEmoteWheel", typeof(void), Type.EmptyTypes, requirePublic: false);
		}

		internal static void Reset()
		{
		}

		internal static bool Prefix()
		{
			if (Object.op_Implicit((Object)(object)Character.localCharacter))
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter.data != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.stats != (Object)null)
				{
					return true;
				}
				RateLimitedDiagnostics.Hit("EmoteWheelGuard.localCharacter-members-unavailable");
				return false;
			}
			RateLimitedDiagnostics.Hit("EmoteWheelGuard.localCharacter-unavailable");
			return false;
		}
	}
	internal sealed class IKItemGuardModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.IKItemGuard, () => new PatchDefinition(PatchId.IKItemGuard, IKItemGuardPatch.Initialize, IKItemGuardPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(IKItemGuardPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, IKItemGuardPatch.Reset));
		}
	}
	internal static class IKItemGuardPatch
	{
		private static FieldRef<CharacterAnimations, Character> _character;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = StabilityPatchValidation.RequireInstanceField(typeof(CharacterAnimations), "character", typeof(Character));
			if (fieldInfo.IsPublic)
			{
				throw new InvalidOperationException("CharacterAnimations.character is no longer a private instance field");
			}
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterRefs), "IKHandTargetLeft", typeof(Transform));
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			StabilityPatchValidation.RequireInstanceProperty(typeof(CharacterData), "currentItem", typeof(Item));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterRefs), "IKHandTargetRight", typeof(Transform));
			_character = AccessTools.FieldRefAccess<CharacterAnimations, Character>(fieldInfo) ?? throw new InvalidOperationException("IKItemGuard accessor creation failed");
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return StabilityPatchValidation.RequireInstanceMethod(typeof(CharacterAnimations), "ConfigureIK", typeof(void), Type.EmptyTypes);
		}

		internal static void Reset()
		{
			_character = null;
		}

		internal static bool Prefix(CharacterAnimations __instance)
		{
			FieldRef<CharacterAnimations, Character> character = _character;
			if (character == null)
			{
				RateLimitedDiagnostics.Hit("IKItemGuard.accessors-unavailable");
				return true;
			}
			Character val = character.Invoke(__instance);
			if ((Object)(object)val == (Object)null || val.refs == null || (Object)(object)val.data == (Object)null)
			{
				return true;
			}
			if ((Object)(object)val.refs.IKHandTargetLeft == (Object)null)
			{
				return true;
			}
			Item currentItem = val.data.currentItem;
			if ((Object)(object)currentItem == (Object)null)
			{
				return true;
			}
			Transform val2 = ((Component)currentItem).transform.Find("Hand_R");
			Transform val3 = ((Component)currentItem).transform.Find("Hand_L");
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				RateLimitedDiagnostics.Hit("IKItemGuard.hand-node-missing");
				return false;
			}
			return true;
		}
	}
	internal static class ParachutePatch
	{
		private static FieldRef<CharacterData, Character> _character;

		private static FieldRef<CharacterBackpackHandler, Character> _handlerCharacter;

		internal static void Initialize()
		{
			FieldInfo fieldInfo = StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "character", typeof(Character));
			FieldInfo fieldInfo2 = StabilityPatchValidation.RequireInstanceField(typeof(CharacterBackpackHandler), "character", typeof(Character));
			ValidateCharacterStructure();
			ValidateCharacterDataStructure();
			ValidateInventoryStructure();
			ValidateBackpackStructure();
			FieldRef<CharacterData, Character> obj = AccessTools.FieldRefAccess<CharacterData, Character>(fieldInfo);
			FieldRef<CharacterBackpackHandler, Character> val = AccessTools.FieldRefAccess<CharacterBackpackHandler, Character>(fieldInfo2);
			if (obj == null || val == null)
			{
				throw new InvalidOperationException("Parachute FieldRef accessor creation failed");
			}
			_character = obj;
			_handlerCharacter = val;
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return StabilityPatchValidation.RequireInstanceMethod(typeof(CharacterData), "UpdateHasParachute", typeof(void), Type.EmptyTypes);
		}

		internal static void Reset()
		{
			_character = null;
			_handlerCharacter = null;
		}

		internal static bool Prefix(CharacterData __instance)
		{
			Character val = _character.Invoke(__instance);
			if ((Object)(object)val != (Object)null && val.isScoutmaster)
			{
				return false;
			}
			__instance.hasParachute = false;
			__instance.currentParachuteSlot = null;
			__instance.currentParachuteItem = null;
			if ((Object)(object)val == (Object)null)
			{
				RateLimitedDiagnostics.Hit("Parachute.character-null-or-destroyed");
				return false;
			}
			CharacterData data = val.data;
			if ((Object)(object)data == (Object)null)
			{
				RateLimitedDiagnostics.Hit("Parachute.characterData-null-or-destroyed");
				return false;
			}
			Item currentItem = data.currentItem;
			if ((Object)(object)currentItem != (Object)null)
			{
				GameObject gameObject = ((Component)currentItem).gameObject;
				if ((Object)(object)gameObject == (Object)null)
				{
					RateLimitedDiagnostics.Hit("Parachute.held-gameObject-null-or-destroyed");
				}
				else if (gameObject.CompareTag("Parachute"))
				{
					__instance.currentParachuteItem = currentItem;
					__instance.hasParachute = true;
					return false;
				}
			}
			Player player = val.player;
			if ((Object)(object)player == (Object)null)
			{
				RateLimitedDiagnostics.Hit("Parachute.player-null-or-destroyed");
				return false;
			}
			ItemSlot[] itemSlots = player.itemSlots;
			if (itemSlots == null)
			{
				RateLimitedDiagnostics.Hit("Parachute.itemSlots-null");
				return false;
			}
			ItemSlot[] array = itemSlots;
			foreach (ItemSlot val2 in array)
			{
				if (val2 == null)
				{
					RateLimitedDiagnostics.Hit("Parachute.slot-null");
				}
				else if (!val2.IsEmpty())
				{
					Item prefab = val2.prefab;
					if ((Object)(object)prefab == (Object)null)
					{
						RateLimitedDiagnostics.Hit("Parachute.nonempty-prefab-null-or-destroyed");
					}
					else if ((Object)(object)((Component)prefab).gameObject == (Object)null)
					{
						RateLimitedDiagnostics.Hit("Parachute.prefab-gameObject-null-or-destroyed");
					}
					else if (((Component)prefab).CompareTag("Parachute"))
					{
						__instance.currentParachuteSlot = val2;
						__instance.hasParachute = true;
						return false;
					}
				}
			}
			CharacterRefs refs = val.refs;
			if (refs == null)
			{
				RateLimitedDiagnostics.Hit("Parachute.characterRefs-null");
				return false;
			}
			CharacterBackpackHandler backpackHandler = refs.backpackHandler;
			if ((Object)(object)backpackHandler == (Object)null)
			{
				RateLimitedDiagnostics.Hit("Parachute.backpackHandler-null-or-destroyed");
				return false;
			}
			Character val3 = _handlerCharacter.Invoke(backpackHandler);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val3 != (Object)(object)val)
			{
				RateLimitedDiagnostics.Hit("Parachute.backpackHandler-owner-invalid");
				return false;
			}
			if (player.backpackSlot == null)
			{
				RateLimitedDiagnostics.Hit("Parachute.backpackSlot-null");
				return false;
			}
			BackpackOnBackVisuals activeBackpackVisuals = backpackHandler.activeBackpackVisuals;
			Item currentParachuteItem = default(Item);
			if ((Object)(object)activeBackpackVisuals != (Object)null && ((BackpackVisuals)activeBackpackVisuals).ContainsParachute(ref currentParachuteItem))
			{
				__instance.currentParachuteItem = currentParachuteItem;
				__instance.hasParachute = true;
			}
			return false;
		}

		private static void ValidateCharacterStructure()
		{
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "isScoutmaster", typeof(bool));
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			StabilityPatchValidation.RequireInstanceProperty(typeof(Character), "player", typeof(Player));
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
		}

		private static void ValidateCharacterDataStructure()
		{
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "hasParachute", typeof(bool));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "currentParachuteSlot", typeof(ItemSlot));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "currentParachuteItem", typeof(Item));
			StabilityPatchValidation.RequireInstanceProperty(typeof(CharacterData), "currentItem", typeof(Item));
		}

		private static void ValidateInventoryStructure()
		{
			StabilityPatchValidation.RequireInstanceField(typeof(Player), "itemSlots", typeof(ItemSlot[]));
			StabilityPatchValidation.RequireInstanceField(typeof(Player), "backpackSlot", typeof(BackpackSlot));
			StabilityPatchValidation.RequireInstanceMethod(typeof(ItemSlot), "IsEmpty", typeof(bool), Type.EmptyTypes);
			StabilityPatchValidation.RequireInstanceProperty(typeof(ItemSlot), "prefab", typeof(Item));
		}

		private static void ValidateBackpackStructure()
		{
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterRefs), "backpackHandler", typeof(CharacterBackpackHandler));
			StabilityPatchValidation.RequireInstanceProperty(typeof(CharacterBackpackHandler), "activeBackpackVisuals", typeof(BackpackOnBackVisuals));
			Type type = typeof(Item).MakeByRefType();
			ParameterInfo parameterInfo = StabilityPatchValidation.RequireInstanceMethod(typeof(BackpackVisuals), "ContainsParachute", typeof(bool), new Type[1] { type }).GetParameters()[0];
			if (!parameterInfo.IsOut || parameterInfo.IsIn)
			{
				throw new InvalidOperationException("BackpackVisuals.ContainsParachute parameter is no longer an out Item");
			}
		}
	}
	internal sealed class RopeSegmentGuardModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.RopeSegmentGuard, () => new PatchDefinition(PatchId.RopeSegmentGuard, RopeSegmentGuardPatch.Initialize, RopeSegmentGuardPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(RopeSegmentGuardPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, RopeSegmentGuardPatch.Reset));
		}
	}
	internal static class RopeSegmentGuardPatch
	{
		private static FieldRef<CharacterRopeHandling, Character> _character;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = StabilityPatchValidation.RequireInstanceField(typeof(CharacterRopeHandling), "character", typeof(Character));
			if (fieldInfo.IsPublic)
			{
				throw new InvalidOperationException("CharacterRopeHandling.character is no longer a private instance field");
			}
			StabilityPatchValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "heldRope", typeof(Rope));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "isRopeClimbing", typeof(bool));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "ropePercent", typeof(float));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "ropeClimbWorldNormal", typeof(Vector3));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "ropeClimbWorldUp", typeof(Vector3));
			StabilityPatchValidation.RequireInstanceField(typeof(CharacterData), "ropeClimbNormal", typeof(Vector3));
			StabilityPatchValidation.RequireInstanceField(typeof(Rope), "climbingAPI", typeof(RopeClimbingAPI));
			StabilityPatchValidation.RequireInstanceMethod(typeof(Rope), "GetRopeSegments", typeof(List<Transform>), Type.EmptyTypes);
			StabilityPatchValidation.RequireInstanceMethod(typeof(RopeClimbingAPI), "GetUp", typeof(Vector3), new Type[1] { typeof(float) });
			StabilityPatchValidation.RequireInstanceMethod(typeof(RopeClimbingAPI), "GetSegmentFromPercent", typeof(Transform), new Type[1] { typeof(float) });
			_character = AccessTools.FieldRefAccess<CharacterRopeHandling, Character>(fieldInfo) ?? throw new InvalidOperationException("RopeSegmentGuard accessor creation failed");
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return StabilityPatchValidation.RequireInstanceMethod(typeof(CharacterRopeHandling), "Climbing", typeof(void), Type.EmptyTypes, requirePublic: false);
		}

		internal static void Reset()
		{
			_character = null;
		}

		internal static bool Prefix(CharacterRopeHandling __instance)
		{
			FieldRef<CharacterRopeHandling, Character> character = _character;
			if (character == null)
			{
				RateLimitedDiagnostics.Hit("RopeSegmentGuard.accessors-unavailable");
				return true;
			}
			Character val = character.Invoke(__instance);
			CharacterData val2 = (((Object)(object)val != (Object)null) ? val.data : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				RateLimitedDiagnostics.Hit("RopeSegmentGuard.character-unavailable");
				return true;
			}
			Rope heldRope = val2.heldRope;
			if ((Object)(object)heldRope == (Object)null || (Object)(object)((MonoBehaviourPun)heldRope).photonView == (Object)null)
			{
				return true;
			}
			if ((Object)(object)heldRope.climbingAPI == (Object)null)
			{
				RateLimitedDiagnostics.Hit("RopeSegmentGuard.climbingAPI-null");
				return false;
			}
			List<Transform> ropeSegments = heldRope.GetRopeSegments();
			if (ropeSegments == null)
			{
				RateLimitedDiagnostics.Hit("RopeSegmentGuard.segments-null");
				return false;
			}
			if (ropeSegments.Count == 0)
			{
				RateLimitedDiagnostics.Hit("RopeSegmentGuard.segments-empty");
				return false;
			}
			return true;
		}
	}
	internal static class RunBasedValuesPatch
	{
		private static StructFieldRef<SerializableRunBasedValues, Dictionary<RUNBASEDVALUETYPE, int>> _ints;

		private static StructFieldRef<SerializableRunBasedValues, Dictionary<RUNBASEDVALUETYPE, float>> _floats;

		internal static void Initialize()
		{
			Type typeFromHandle = typeof(SerializableRunBasedValues);
			if (!typeFromHandle.IsValueType || typeFromHandle.IsEnum)
			{
				throw new InvalidOperationException("SerializableRunBasedValues is no longer a non-enum value type");
			}
			FieldInfo fieldInfo = StabilityPatchValidation.RequireInstanceField(typeFromHandle, "runBasedInts", typeof(Dictionary<RUNBASEDVALUETYPE, int>));
			FieldInfo fieldInfo2 = StabilityPatchValidation.RequireInstanceField(typeFromHandle, "runBasedFloats", typeof(Dictionary<RUNBASEDVALUETYPE, float>));
			if (fieldInfo.IsInitOnly || fieldInfo2.IsInitOnly)
			{
				throw new InvalidOperationException("RunBasedValues dictionary fields are unexpectedly readonly");
			}
			StructFieldRef<SerializableRunBasedValues, Dictionary<RUNBASEDVALUETYPE, int>> obj = AccessTools.StructFieldRefAccess<SerializableRunBasedValues, Dictionary<RUNBASEDVALUETYPE, int>>(fieldInfo);
			StructFieldRef<SerializableRunBasedValues, Dictionary<RUNBASEDVALUETYPE, float>> val = AccessTools.StructFieldRefAccess<SerializableRunBasedValues, Dictionary<RUNBASEDVALUETYPE, float>>(fieldInfo2);
			if (obj == null || val == null)
			{
				throw new InvalidOperationException("RunBasedValues StructFieldRef accessor creation failed");
			}
			_ints = obj;
			_floats = val;
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return StabilityPatchValidation.RequireInstanceMethod(typeof(SerializableRunBasedValues), "SerializeRunBasedValues", typeof(void), new Type[1] { typeof(BinarySerializer) });
		}

		internal static void Reset()
		{
			_ints = null;
			_floats = null;
		}

		internal static void Prefix(ref SerializableRunBasedValues __instance)
		{
			if (_ints.Invoke(ref __instance) == null)
			{
				_ints.Invoke(ref __instance) = new Dictionary<RUNBASEDVALUETYPE, int>();
				RateLimitedDiagnostics.Hit("RunBasedValues.runBasedInts-null");
			}
			if (_floats.Invoke(ref __instance) == null)
			{
				_floats.Invoke(ref __instance) = new Dictionary<RUNBASEDVALUETYPE, float>();
				RateLimitedDiagnostics.Hit("RunBasedValues.runBasedFloats-null");
			}
		}
	}
	internal sealed class StabilityPatchModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.RunBasedValues, () => new PatchDefinition(PatchId.RunBasedValues, RunBasedValuesPatch.Initialize, RunBasedValuesPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(RunBasedValuesPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: false, RunBasedValuesPatch.Reset));
			context.Register(PatchId.Parachute, () => new PatchDefinition(PatchId.Parachute, ParachutePatch.Initialize, ParachutePatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(ParachutePatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, ParachutePatch.Reset));
		}
	}
	internal static class StabilityPatchValidation
	{
		private const BindingFlags DeclaredInstance = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		internal static FieldInfo RequireInstanceField(Type declaringType, string name, Type fieldType)
		{
			FieldInfo field = declaringType.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				throw new MissingFieldException(declaringType.FullName, name);
			}
			if (field.DeclaringType != declaringType || field.IsStatic || field.FieldType != fieldType)
			{
				throw new InvalidOperationException("Unexpected field structure for " + declaringType.FullName + "." + name);
			}
			return field;
		}

		internal static PropertyInfo RequireInstanceProperty(Type declaringType, string name, Type propertyType, bool requirePublicGetter = true)
		{
			PropertyInfo property = declaringType.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo methodInfo = property?.GetGetMethod(nonPublic: true);
			if (property == null || property.DeclaringType != declaringType || property.PropertyType != propertyType || property.GetIndexParameters().Length != 0 || methodInfo == null || methodInfo.IsStatic || methodInfo.ContainsGenericParameters || (requirePublicGetter && !methodInfo.IsPublic))
			{
				throw new InvalidOperationException("Unexpected property structure for " + declaringType.FullName + "." + name);
			}
			return property;
		}

		internal static MethodInfo RequireInstanceMethod(Type declaringType, string name, Type returnType, Type[] parameterTypes, bool requirePublic = true)
		{
			MethodInfo method = declaringType.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, parameterTypes, null);
			if (method == null)
			{
				throw new MissingMethodException(declaringType.FullName, name);
			}
			if (method.DeclaringType != declaringType || method.IsStatic || method.ReturnType != returnType || method.ContainsGenericParameters || (requirePublic && !method.IsPublic))
			{
				throw new InvalidOperationException("Unexpected method structure for " + declaringType.FullName + "." + name);
			}
			ParameterInfo[] parameters = method.GetParameters();
			if (parameters.Length != parameterTypes.Length)
			{
				throw new InvalidOperationException("Unexpected parameter count for " + declaringType.FullName + "." + name);
			}
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].ParameterType != parameterTypes[i])
				{
					throw new InvalidOperationException($"Unexpected parameter {i} for {declaringType.FullName}.{name}");
				}
			}
			return method;
		}
	}
}
namespace PeakSafeOptimizer.Patches.Scale
{
	internal sealed class AnimatedMouthMaterialModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.AnimatedMouthMaterial, () => new PatchDefinition(PatchId.AnimatedMouthMaterial, AnimatedMouthMaterialPatch.Initialize, AnimatedMouthMaterialPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(AnimatedMouthMaterialPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, AnimatedMouthMaterialPatch.Reset));
		}
	}
	internal static class AnimatedMouthMaterialPatch
	{
		private sealed class State
		{
			internal int LastUseTalkSprites = -1;

			internal int LastAmplitudeIndex = -1;
		}

		private static Func<AnimatedMouth, Object> _getAudioSource;

		private static FieldRef<AnimatedMouth, float[]> _lastBuffer;

		private static FieldRef<AnimatedMouth, PushToTalkSetting> _pushToTalkSetting;

		private static FieldRef<AnimatedMouth, float> _volumePeak;

		private static Func<AnimatedMouth, float[], float> _micLevel;

		private static Func<PushToTalkSetting, PushToTalkType> _getPushToTalkValue;

		private static ConditionalWeakTable<AnimatedMouth, State> _state;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			Type? typeFromHandle = typeof(AnimatedMouth);
			FieldInfo field = ScaleValidation.RequireInstanceFieldByTypeName(typeFromHandle, "audioSource", "UnityEngine.AudioSource");
			ScaleValidation.RequireInstanceField(typeFromHandle, "isGhost", typeof(bool));
			ScaleValidation.RequireInstanceField(typeFromHandle, "character", typeof(Character));
			ScaleValidation.RequireInstanceField(typeFromHandle, "mouthRenderer", typeof(Renderer));
			ScaleValidation.RequireInstanceField(typeFromHandle, "mouthTextures", typeof(Texture2D[]));
			ScaleValidation.RequireInstanceField(typeFromHandle, "amplitudeIndex", typeof(int));
			ScaleValidation.RequireInstanceField(typeFromHandle, "isSpeaking", typeof(bool));
			ScaleValidation.RequireInstanceField(typeFromHandle, "volume", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "amplitudePeakLimiter", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "minAmplitudeThreshold", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "amplitudeHighestDecay", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "amplitudeSmoothing", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "talkThreshold", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "amplitudeMult", typeof(float));
			ScaleValidation.RequireInstanceField(typeFromHandle, "decibelToAmountCurve", typeof(AnimationCurve));
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeFromHandle, "m_lastSentLocalBuffer", typeof(float[]));
			FieldInfo fieldInfo2 = ScaleValidation.RequireInstanceField(typeFromHandle, "pushToTalkSetting", typeof(PushToTalkSetting));
			FieldInfo fieldInfo3 = ScaleValidation.RequireInstanceField(typeFromHandle, "volumePeak", typeof(float));
			ScaleValidation.RequireInstanceProperty(typeFromHandle, "NormalizedAmplitude", typeof(float));
			ScaleValidation.RequireInstanceProperty(typeFromHandle, "VoiceHandler", typeof(CharacterVoiceHandler));
			MethodInfo methodInfo = ScaleValidation.RequireInstanceMethod(typeFromHandle, "MicrophoneLevelMax", typeof(float), new Type[1] { typeof(float[]) }, requirePublic: false);
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceField(typeof(Character), "input", typeof(CharacterInput));
			ScaleValidation.RequireInstanceProperty(typeof(Character), "IsLocal", typeof(bool));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterData), "dead", typeof(bool));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "passedOut", typeof(bool));
			ScaleValidation.RequireInstanceField(typeof(CharacterInput), "pushToTalkPressed", typeof(bool));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterVoiceHandler), "LastReadSquaredMax", typeof(float));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterVoiceHandler), "LastAudioBuffer", typeof(float[]));
			PropertyInfo propertyInfo = ScaleValidation.RequireInheritedInstanceProperty(typeof(PushToTalkSetting), "Value", typeof(PushToTalkType));
			if (!Enum.IsDefined(typeof(PushToTalkType), (object)(PushToTalkType)1) || !Enum.IsDefined(typeof(PushToTalkType), (object)(PushToTalkType)2))
			{
				throw new InvalidOperationException("PushToTalkType values are no longer defined");
			}
			Func<AnimatedMouth, Object> func = ScaleEmit.CreateUnityObjectFieldGetter<AnimatedMouth>(field);
			FieldRef<AnimatedMouth, float[]> val = AccessTools.FieldRefAccess<AnimatedMouth, float[]>(fieldInfo);
			FieldRef<AnimatedMouth, PushToTalkSetting> val2 = AccessTools.FieldRefAccess<AnimatedMouth, PushToTalkSetting>(fieldInfo2);
			FieldRef<AnimatedMouth, float> val3 = AccessTools.FieldRefAccess<AnimatedMouth, float>(fieldInfo3);
			Func<AnimatedMouth, float[], float> func2 = (Func<AnimatedMouth, float[], float>)methodInfo.CreateDelegate(typeof(Func<AnimatedMouth, float[], float>));
			Func<PushToTalkSetting, PushToTalkType> func3 = EmitPushToTalkValueGetter(propertyInfo.GetGetMethod(nonPublic: true));
			if (func == null || val == null || val2 == null || val3 == null || func2 == null || func3 == null)
			{
				throw new InvalidOperationException("AnimatedMouthMaterial accessor creation failed");
			}
			_getAudioSource = func;
			_lastBuffer = val;
			_pushToTalkSetting = val2;
			_volumePeak = val3;
			_micLevel = func2;
			_getPushToTalkValue = func3;
			_state = new ConditionalWeakTable<AnimatedMouth, State>();
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(AnimatedMouth), "ProcessMicData", typeof(void), new Type[1] { typeof(float[]) }, requirePublic: false);
		}

		internal static void Reset()
		{
			_getAudioSource = null;
			_lastBuffer = null;
			_pushToTalkSetting = null;
			_volumePeak = null;
			_micLevel = null;
			_getPushToTalkValue = null;
			_state = null;
		}

		private static Func<PushToTalkSetting, PushToTalkType> EmitPushToTalkValueGetter(MethodInfo getter)
		{
			DynamicMethod dynamicMethod = new DynamicMethod("PSO_GetPushToTalkValue", typeof(PushToTalkType), new Type[1] { typeof(PushToTalkSetting) }, typeof(AnimatedMouthMaterialPatch).Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Castclass, getter.DeclaringType);
			iLGenerator.Emit(OpCodes.Callvirt, getter);
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<PushToTalkSetting, PushToTalkType>)dynamicMethod.CreateDelegate(typeof(Func<PushToTalkSetting, PushToTalkType>));
		}

		internal static bool Prefix(AnimatedMouth __instance, float[] buffer)
		{
			//IL_0132: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Invalid comparison between Unknown and I4
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Invalid comparison between Unknown and I4
			Func<AnimatedMouth, Object> getAudioSource = _getAudioSource;
			FieldRef<AnimatedMouth, float[]> lastBuffer = _lastBuffer;
			FieldRef<AnimatedMouth, PushToTalkSetting> pushToTalkSetting = _pushToTalkSetting;
			FieldRef<AnimatedMouth, float> volumePeak = _volumePeak;
			Func<AnimatedMouth, float[], float> micLevel = _micLevel;
			Func<PushToTalkSetting, PushToTalkType> getPushToTalkValue = _getPushToTalkValue;
			ConditionalWeakTable<AnimatedMouth, State> state = _state;
			if (getAudioSource == null || lastBuffer == null || pushToTalkSetting == null || volumePeak == null || micLevel == null || getPushToTalkValue == null || state == null)
			{
				RateLimitedDiagnostics.Hit("AnimatedMouthMaterial.accessors-unavailable");
				return true;
			}
			Renderer mouthRenderer = __instance.mouthRenderer;
			if ((Object)(object)mouthRenderer == (Object)null)
			{
				RateLimitedDiagnostics.Hit("AnimatedMouthMaterial.mouthRenderer-null");
				return true;
			}
			Texture2D[] mouthTextures = __instance.mouthTextures;
			if (mouthTextures == null || mouthTextures.Length == 0)
			{
				RateLimitedDiagnostics.Hit("AnimatedMouthMaterial.mouthTextures-empty");
				return true;
			}
			Character character = __instance.character;
			if ((Object)(object)character == (Object)null)
			{
				RateLimitedDiagnostics.Hit("AnimatedMouthMaterial.character-null");
				return true;
			}
			if (getAudioSource(__instance) == (Object)null)
			{
				return false;
			}
			if (!__instance.isGhost && (character.data.dead || character.data.passedOut))
			{
				return false;
			}
			bool isLocal = character.IsLocal;
			float num = ((!isLocal) ? __instance.VoiceHandler.LastReadSquaredMax : micLevel(__instance, buffer));
			if (!isLocal)
			{
				lastBuffer.Invoke(__instance) = __instance.VoiceHandler.LastAudioBuffer;
			}
			float num2 = AnimatedMouth.MicrophoneLevelMaxDecibels(num);
			PushToTalkSetting arg = pushToTalkSetting.Invoke(__instance);
			PushToTalkType val = getPushToTalkValue(arg);
			if (isLocal && (((int)val == 1 && !character.input.pushToTalkPressed) || ((int)val == 2 && character.input.pushToTalkPressed)))
			{
				num2 = -80f;
			}
			float num3 = __instance.decibelToAmountCurve.Evaluate(num2);
			if (num3 > __instance.amplitudePeakLimiter)
			{
				__instance.amplitudePeakLimiter = num3;
			}
			if (__instance.amplitudePeakLimiter > __instance.minAmplitudeThreshold)
			{
				__instance.amplitudePeakLimiter -= __instance.amplitudeHighestDecay * Time.deltaTime;
				__instance.amplitudePeakLimiter = Mathf.Max(__instance.amplitudePeakLimiter, __instance.minAmplitudeThreshold);
			}
			__instance.volume = num3 / __instance.amplitudePeakLimiter;
			float num4 = volumePeak.Invoke(__instance);
			num4 = ((!(__instance.volume > num4)) ? Mathf.Lerp(num4, 0f, Time.deltaTime * __instance.amplitudeSmoothing) : Mathf.Lerp(num4, __instance.volume, Time.deltaTime * __instance.amplitudeSmoothing));
			volumePeak.Invoke(__instance) = num4;
			int num5;
			bool isSpeaking;
			if (num4 > __instance.talkThreshold)
			{
				num5 = 1;
				isSpeaking = true;
			}
			else
			{
				isSpeaking = false;
				num5 = 0;
			}
			__instance.isSpeaking = isSpeaking;
			State value = state.GetValue(__instance, (AnimatedMouth _) => new State());
			Material material = mouthRenderer.material;
			if (value.LastUseTalkSprites != num5 || material.GetInt("_UseTalkSprites") != num5)
			{
				material.SetInt("_UseTalkSprites", num5);
				value.LastUseTalkSprites = num5;
			}
			int num6 = (__instance.amplitudeIndex = (int)(__instance.NormalizedAmplitude * (float)(mouthTextures.Length - 1)));
			Texture2D val2 = mouthTextures[num6];
			if (value.LastAmplitudeIndex != num6 || (Object)(object)material.GetTexture("_TalkSprite") != (Object)(object)val2)
			{
				material.SetTexture("_TalkSprite", (Texture)(object)val2);
				value.LastAmplitudeIndex = num6;
			}
			return false;
		}
	}
	internal sealed class AnimatorValuesHashModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.AnimatorValuesHash, () => new PatchDefinition(PatchId.AnimatorValuesHash, AnimatorValuesHashPatch.Initialize, AnimatorValuesHashPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(AnimatorValuesHashPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, AnimatorValuesHashPatch.Reset));
		}
	}
	internal static class AnimatorValuesHashPatch
	{
		private static Func<AnimatorValues, Object> _getAnimator;

		private static FieldRef<AnimatorValues, Character> _character;

		private static Func<string, int> _stringToHash;

		private static Func<Object, int, float> _getFloat;

		private static Action<Object, int, float> _setFloat;

		private static Action<Object, int, float, float, float> _setFloatDamped;

		private static Func<Object, int, bool> _getBool;

		private static Action<Object, int, bool> _setBool;

		private static int _inputXHash;

		private static int _inputYHash;

		private static int _isGroundedHash;

		private static int _sprintHash;

		private static int _velocityYHash;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			Type? typeFromHandle = typeof(AnimatorValues);
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceFieldByTypeName(typeFromHandle, "anim", "UnityEngine.Animator");
			FieldInfo fieldInfo2 = ScaleValidation.RequireInstanceField(typeFromHandle, "character", typeof(Character));
			ScaleValidation.RequireInstanceField(typeof(Character), "input", typeof(CharacterInput));
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
			ScaleValidation.RequireInstanceField(typeof(CharacterInput), "movementInput", typeof(Vector2));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "isGrounded", typeof(bool));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "isSprinting", typeof(bool));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "avarageVelocity", typeof(Vector3));
			ScaleValidation.RequireInstanceField(typeof(CharacterRefs), "movement", typeof(CharacterMovement));
			ScaleValidation.RequireInstanceField(typeof(CharacterMovement), "sprintAnimationDisabled", typeof(bool));
			Type fieldType = fieldInfo.FieldType;
			MethodInfo methodInfo = RequireMethod(fieldType, "StringToHash", typeof(int), true, typeof(string));
			MethodInfo methodInfo2 = RequireMethod(fieldType, "GetFloat", typeof(float), false, typeof(int));
			MethodInfo methodInfo3 = RequireMethod(fieldType, "SetFloat", typeof(void), false, typeof(int), typeof(float));
			MethodInfo methodInfo4 = RequireMethod(fieldType, "SetFloat", typeof(void), false, typeof(int), typeof(float), typeof(float), typeof(float));
			MethodInfo methodInfo5 = RequireMethod(fieldType, "GetBool", typeof(bool), false, typeof(int));
			MethodInfo methodInfo6 = RequireMethod(fieldType, "SetBool", typeof(void), false, typeof(int), typeof(bool));
			Func<AnimatorValues, Object> func = ScaleEmit.CreateUnityObjectFieldGetter<AnimatorValues>(fieldInfo);
			FieldRef<AnimatorValues, Character> val = AccessTools.FieldRefAccess<AnimatorValues, Character>(fieldInfo2);
			Func<string, int> func2 = (Func<string, int>)methodInfo.CreateDelegate(typeof(Func<string, int>));
			Func<Object, int, float> func3 = EmitGetFloat(fieldType, methodInfo2);
			Action<Object, int, float> action = EmitSetFloat(fieldType, methodInfo3);
			Action<Object, int, float, float, float> action2 = EmitSetFloatDamped(fieldType, methodInfo4);
			Func<Object, int, bool> func4 = EmitGetBool(fieldType, methodInfo5);
			Action<Object, int, bool> action3 = EmitSetBool(fieldType, methodInfo6);
			if (func == null || val == null || func2 == null || func3 == null || action == null || action2 == null || func4 == null || action3 == null)
			{
				throw new InvalidOperationException("AnimatorValuesHash accessor creation failed");
			}
			_getAnimator = func;
			_character = val;
			_stringToHash = func2;
			_getFloat = func3;
			_setFloat = action;
			_setFloatDamped = action2;
			_getBool = func4;
			_setBool = action3;
			_inputXHash = func2("Input X");
			_inputYHash = func2("Input Y");
			_isGroundedHash = func2("Is Grounded");
			_sprintHash = func2("Sprint");
			_velocityYHash = func2("Velocity Y");
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(AnimatorValues), "Update", typeof(void), Type.EmptyTypes, requirePublic: false);
		}

		internal static void Reset()
		{
			_getAnimator = null;
			_character = null;
			_stringToHash = null;
			_getFloat = null;
			_setFloat = null;
			_setFloatDamped = null;
			_getBool = null;
			_setBool = null;
			_inputXHash = 0;
			_inputYHash = 0;
			_isGroundedHash = 0;
			_sprintHash = 0;
			_velocityYHash = 0;
		}

		internal static bool Prefix(AnimatorValues __instance)
		{
			//IL_00c2: 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_00d0: 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)
			Func<AnimatorValues, Object> getAnimator = _getAnimator;
			FieldRef<AnimatorValues, Character> character = _character;
			Func<Object, int, float> getFloat = _getFloat;
			Action<Object, int, float> setFloat = _setFloat;
			Action<Object, int, float, float, float> setFloatDamped = _setFloatDamped;
			Func<Object, int, bool> getBool = _getBool;
			Action<Object, int, bool> setBool = _setBool;
			if (getAnimator == null || character == null || _stringToHash == null || getFloat == null || setFloat == null || setFloatDamped == null || getBool == null || setBool == null)
			{
				return true;
			}
			Object val = getAnimator(__instance);
			Character val2 = character.Invoke(__instance);
			if (val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val2.input == (Object)null || (Object)(object)val2.data == (Object)null || val2.refs == null || (Object)(object)val2.refs.movement == (Object)null)
			{
				return true;
			}
			CharacterData data = val2.data;
			Vector2 movementInput = val2.input.movementInput;
			SetFloatIfChanged(val, _inputXHash, movementInput.x, getFloat, setFloat);
			SetFloatIfChanged(val, _inputYHash, movementInput.y, getFloat, setFloat);
			SetBoolIfChanged(val, _isGroundedHash, data.isGrounded, getBool, setBool);
			if (val2.refs.movement.sprintAnimationDisabled)
			{
				SetFloatIfChanged(val, _sprintHash, 0f, getFloat, setFloat);
			}
			else
			{
				float num = (data.isSprinting ? 1f : 0f);
				if (getFloat(val, _sprintHash) != num)
				{
					setFloatDamped(val, _sprintHash, num, 0.125f, Time.deltaTime);
				}
			}
			SetFloatIfChanged(val, _velocityYHash, data.avarageVelocity.y, getFloat, setFloat);
			if (data.isGrounded)
			{
				val2.refs.movement.sprintAnimationDisabled = false;
			}
			return false;
		}

		private static void SetFloatIfChanged(Object animator, int hash, float target, Func<Object, int, float> getFloat, Action<Object, int, float> setFloat)
		{
			if (getFloat(animator, hash) != target)
			{
				setFloat(animator, hash, target);
			}
		}

		private static void SetBoolIfChanged(Object animator, int hash, bool target, Func<Object, int, bool> getBool, Action<Object, int, bool> setBool)
		{
			if (getBool(animator, hash) != target)
			{
				setBool(animator, hash, target);
			}
		}

		private static MethodInfo RequireMethod(Type owner, string name, Type returnType, bool isStatic, params Type[] parameterTypes)
		{
			BindingFlags bindingAttr = (BindingFlags)(0x10 | (isStatic ? 8 : 4));
			MethodInfo method = owner.GetMethod(name, bindingAttr, null, parameterTypes, null);
			if (method == null || method.DeclaringType != owner || method.IsStatic != isStatic || method.ReturnType != returnType || method.ContainsGenericParameters)
			{
				throw new MissingMethodException(owner.FullName, name);
			}
			return method;
		}

		private static Func<Object, int, float> EmitGetFloat(Type animatorType, MethodInfo methodInfo)
		{
			DynamicMethod dynamicMethod = NewAnimatorMethod("PSO_AnimatorGetFloat", typeof(float), typeof(int));
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			EmitAnimatorCallPrefix(iLGenerator, animatorType, 1);
			iLGenerator.Emit(OpCodes.Callvirt, methodInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<Object, int, float>)dynamicMethod.CreateDelegate(typeof(Func<Object, int, float>));
		}

		private static Action<Object, int, float> EmitSetFloat(Type animatorType, MethodInfo methodInfo)
		{
			DynamicMethod dynamicMethod = NewAnimatorMethod("PSO_AnimatorSetFloat", typeof(void), typeof(int), typeof(float));
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			EmitAnimatorCallPrefix(iLGenerator, animatorType, 2);
			iLGenerator.Emit(OpCodes.Callvirt, methodInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<Object, int, float>)dynamicMethod.CreateDelegate(typeof(Action<Object, int, float>));
		}

		private static Action<Object, int, float, float, float> EmitSetFloatDamped(Type animatorType, MethodInfo methodInfo)
		{
			DynamicMethod dynamicMethod = NewAnimatorMethod("PSO_AnimatorSetFloatDamped", typeof(void), typeof(int), typeof(float), typeof(float), typeof(float));
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			EmitAnimatorCallPrefix(iLGenerator, animatorType, 4);
			iLGenerator.Emit(OpCodes.Callvirt, methodInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<Object, int, float, float, float>)dynamicMethod.CreateDelegate(typeof(Action<Object, int, float, float, float>));
		}

		private static Func<Object, int, bool> EmitGetBool(Type animatorType, MethodInfo methodInfo)
		{
			DynamicMethod dynamicMethod = NewAnimatorMethod("PSO_AnimatorGetBool", typeof(bool), typeof(int));
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			EmitAnimatorCallPrefix(iLGenerator, animatorType, 1);
			iLGenerator.Emit(OpCodes.Callvirt, methodInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<Object, int, bool>)dynamicMethod.CreateDelegate(typeof(Func<Object, int, bool>));
		}

		private static Action<Object, int, bool> EmitSetBool(Type animatorType, MethodInfo methodInfo)
		{
			DynamicMethod dynamicMethod = NewAnimatorMethod("PSO_AnimatorSetBool", typeof(void), typeof(int), typeof(bool));
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			EmitAnimatorCallPrefix(iLGenerator, animatorType, 2);
			iLGenerator.Emit(OpCodes.Callvirt, methodInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<Object, int, bool>)dynamicMethod.CreateDelegate(typeof(Action<Object, int, bool>));
		}

		private static DynamicMethod NewAnimatorMethod(string name, Type returnType, params Type[] parametersAfterAnimator)
		{
			Type[] array = new Type[parametersAfterAnimator.Length + 1];
			array[0] = typeof(Object);
			Array.Copy(parametersAfterAnimator, 0, array, 1, parametersAfterAnimator.Length);
			return new DynamicMethod(name, returnType, array, typeof(AnimatorValuesHashPatch).Module, skipVisibility: true);
		}

		private static void EmitAnimatorCallPrefix(ILGenerator il, Type animatorType, int argumentCount)
		{
			il.Emit(OpCodes.Ldarg_0);
			il.Emit(OpCodes.Castclass, animatorType);
			for (int i = 1; i <= argumentCount; i++)
			{
				il.Emit(OpCodes.Ldarg, i);
			}
		}
	}
	internal sealed class BarAfflictionLayoutModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.BarAfflictionLayout, () => new PatchDefinition(PatchId.BarAfflictionLayout, BarAfflictionLayoutPatch.Initialize, BarAfflictionLayoutPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(BarAfflictionLayoutPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, BarAfflictionLayoutPatch.Reset));
		}
	}
	internal static class BarAfflictionLayoutPatch
	{
		private static Func<BarAffliction, Object> _getRtf;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo field = ScaleValidation.RequireInstanceFieldByTypeName(typeof(BarAffliction), "rtf", "UnityEngine.RectTransform");
			ScaleValidation.RequireInstanceProperty(typeof(BarAffliction), "width", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(BarAffliction), "size", typeof(float));
			_getRtf = ScaleEmit.CreateUnityObjectFieldGetter<BarAffliction>(field) ?? throw new InvalidOperationException("BarAfflictionLayout accessor creation failed");
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(BarAffliction), "UpdateAffliction", typeof(void), new Type[1] { typeof(StaminaBar) }, requirePublic: true);
		}

		internal static void Reset()
		{
			_getRtf = null;
		}

		internal static bool Prefix(BarAffliction __instance)
		{
			Func<BarAffliction, Object> getRtf = _getRtf;
			if (getRtf == null)
			{
				RateLimitedDiagnostics.Hit("BarAfflictionLayout.accessors-unavailable");
				return true;
			}
			if (getRtf(__instance) == (Object)null)
			{
				RateLimitedDiagnostics.Hit("BarAfflictionLayout.rtf-null");
				return true;
			}
			float width = __instance.width;
			if (Mathf.Lerp(width, __instance.size, Mathf.Min(Time.deltaTime * 10f, 0.1f)) == width)
			{
				return false;
			}
			return true;
		}
	}
	internal sealed class BodypartDragIdentityModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.BodypartDragIdentity, () => new PatchDefinition(PatchId.BodypartDragIdentity, BodypartDragIdentityPatch.Initialize, BodypartDragIdentityPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(BodypartDragIdentityPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, BodypartDragIdentityPatch.Reset));
		}
	}
	internal static class BodypartDragIdentityPatch
	{
		private const string RigidbodyTypeName = "UnityEngine.Rigidbody";

		private static FieldRef<Bodypart, Character> _character;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeof(Bodypart), "character", typeof(Character));
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterData), "currentRagdollControll", typeof(float));
			FieldInfo fieldInfo2 = ScaleValidation.RequireInstanceFieldByTypeName(typeof(Bodypart), "rig", "UnityEngine.Rigidbody");
			ScaleValidation.RequireInstancePropertyByTypeName(fieldInfo2.FieldType, "isKinematic", typeof(bool).FullName, requireSetter: true);
			ScaleValidation.RequireInstancePropertyByTypeName(fieldInfo2.FieldType, "linearVelocity", "UnityEngine.Vector3", requireSetter: true);
			ScaleValidation.RequireInstancePropertyByTypeName(fieldInfo2.FieldType, "angularVelocity", "UnityEngine.Vector3", requireSetter: true);
			_character = AccessTools.FieldRefAccess<Bodypart, Character>(fieldInfo) ?? throw new InvalidOperationException("BodypartDragIdentity FieldRef creation failed");
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(Bodypart), "Drag", typeof(void), new Type[2]
			{
				typeof(float),
				typeof(bool)
			}, requirePublic: false);
		}

		internal static void Reset()
		{
			_character = null;
		}

		internal static bool Prefix(Bodypart __instance, float drag, bool ignoreRagdoll)
		{
			FieldRef<Bodypart, Character> character = _character;
			if (character == null || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			float num = drag;
			if (!ignoreRagdoll)
			{
				Character val = character.Invoke(__instance);
				CharacterData val2 = (((Object)(object)val != (Object)null) ? val.data : null);
				if ((Object)(object)val2 == (Object)null)
				{
					return true;
				}
				num = Mathf.Lerp(1f, drag, val2.currentRagdollControll);
			}
			return num != 1f;
		}
	}
	internal sealed class BodypartMovementForceIdentityModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.BodypartMovementForceIdentity, () => new PatchDefinition(PatchId.BodypartMovementForceIdentity, BodypartMovementForceIdentityPatch.Initialize, BodypartMovementForceIdentityPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(BodypartMovementForceIdentityPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, BodypartMovementForceIdentityPatch.Reset));
		}
	}
	internal static class BodypartMovementForceIdentityPatch
	{
		private static FieldRef<Bodypart, Character> _character;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeof(Bodypart), "character", typeof(Character));
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "worldMovementInput_Lerp", typeof(Vector3));
			ScaleValidation.RequireInstanceMethod(typeof(Bodypart), "AddForce", typeof(void), new Type[2]
			{
				typeof(Vector3),
				typeof(ForceMode)
			}, requirePublic: true);
			ScaleValidation.RequireInstanceMethod(typeof(Bodypart), "ApplyForces", typeof(void), Type.EmptyTypes, requirePublic: false);
			ScaleValidation.RequireInstanceField(typeof(Bodypart), "forcesToAdd", typeof(Vector3));
			ScaleValidation.RequireInstanceFieldByTypeName(typeof(Bodypart), "rig", "UnityEngine.Rigidbody");
			_character = AccessTools.FieldRefAccess<Bodypart, Character>(fieldInfo) ?? throw new InvalidOperationException("BodypartMovementForceIdentity FieldRef creation failed");
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(Bodypart), "AddMovementForce", typeof(void), new Type[1] { typeof(float) }, requirePublic: false);
		}

		internal static void Reset()
		{
			_character = null;
		}

		internal static bool Prefix(Bodypart __instance, float movementForce, bool __runOriginal)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!__runOriginal)
			{
				return false;
			}
			FieldRef<Bodypart, Character> character = _character;
			if (character == null || (Object)(object)__instance == (Object)null)
			{
				return true;
			}
			Character val = character.Invoke(__instance);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			CharacterData data = val.data;
			if ((Object)(object)data == (Object)null)
			{
				return true;
			}
			Vector3 worldMovementInput_Lerp = data.worldMovementInput_Lerp;
			Vector3 val2 = movementForce * worldMovementInput_Lerp;
			if (val2.x == 0f && val2.y == 0f)
			{
				return val2.z != 0f;
			}
			return true;
		}
	}
	internal sealed class CampfireProtectionMergeModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.CampfireProtectionMerge, () => new PatchDefinition(PatchId.CampfireProtectionMerge, CampfireProtectionMergePatch.Initialize, CampfireProtectionMergePatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(CampfireProtectionMergePatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, CampfireProtectionMergePatch.Reset));
		}
	}
	internal static class CampfireProtectionMergePatch
	{
		private static FieldRef<Campfire, List<Character>> _charactersInRadius;

		private static FieldRef<Campfire, float> _timebuffLastApplied;

		private static FieldRef<Affliction_NoHunger> _campfireBuffGetter;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeof(Campfire), "_charactersInRadius", typeof(List<Character>));
			FieldInfo fieldInfo2 = ScaleValidation.RequireInstanceField(typeof(Campfire), "_timebuffLastApplied", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(Campfire), "moraleBoostRadius", typeof(float));
			FieldInfo field = typeof(Campfire).GetField("s_CampfireBuff", BindingFlags.Static | BindingFlags.NonPublic);
			if (field == null || !field.IsStatic || field.FieldType != typeof(Affliction_NoHunger))
			{
				throw new InvalidOperationException("Campfire.s_CampfireBuff failed structural self-check");
			}
			FieldRef<Affliction_NoHunger> val = AccessTools.StaticFieldRefAccess<Affliction_NoHunger>(field);
			if (val == null)
			{
				throw new InvalidOperationException("Campfire.s_CampfireBuff getter creation failed");
			}
			ScaleValidation.RequireStaticField(typeof(Character), "localCharacter", typeof(Character));
			ScaleValidation.RequireStaticProperty(typeof(PlayerHandler), "Exists", typeof(bool));
			ScaleValidation.RequireStaticMethod(typeof(PlayerHandler), "GetAllPlayerCharacters", typeof(List<Character>), Type.EmptyTypes, requirePublic: true);
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
			ScaleValidation.RequireInstanceField(typeof(CharacterRefs), "afflictions", typeof(CharacterAfflictions));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterData), "dead", typeof(bool));
			ScaleValidation.RequireInstanceProperty(typeof(Character), "Center", typeof(Vector3));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterAfflictions), "canGetHungry", typeof(bool));
			ScaleValidation.RequireInstanceMethod(typeof(CharacterAfflictions), "AddAffliction", typeof(void), new Type[2]
			{
				typeof(Affliction),
				typeof(bool)
			}, requirePublic: true);
			ScaleValidation.RequireStaticProperty(typeof(Singleton<OrbFogHandler>), "Instance", typeof(OrbFogHandler));
			ScaleValidation.RequireInstanceProperty(typeof(OrbFogHandler), "PlayersAreResting", typeof(bool));
			FieldRef<Campfire, List<Character>> obj = AccessTools.FieldRefAccess<Campfire, List<Character>>(fieldInfo);
			FieldRef<Campfire, float> val2 = AccessTools.FieldRefAccess<Campfire, float>(fieldInfo2);
			if (obj == null || val2 == null)
			{
				throw new InvalidOperationException("CampfireProtectionMerge accessor creation failed");
			}
			_charactersInRadius = obj;
			_timebuffLastApplied = val2;
			_campfireBuffGetter = val;
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(Campfire), "ApplyCampfireProtection", typeof(void), Type.EmptyTypes, requirePublic: false);
		}

		internal static void Reset()
		{
			_charactersInRadius = null;
			_timebuffLastApplied = null;
			_campfireBuffGetter = null;
		}

		internal static bool Prefix(Campfire __instance)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			FieldRef<Campfire, List<Character>> charactersInRadius = _charactersInRadius;
			FieldRef<Campfire, float> timebuffLastApplied = _timebuffLastApplied;
			FieldRef<Affliction_NoHunger> campfireBuffGetter = _campfireBuffGetter;
			Affliction val = null;
			if (campfireBuffGetter != null)
			{
				val = (Affliction)(object)campfireBuffGetter.Invoke();
			}
			if (charactersInRadius == null || timebuffLastApplied == null || val == null)
			{
				RateLimitedDiagnostics.Hit("CampfireProtectionMerge.accessors-unavailable");
				return true;
			}
			List<Character> list = charactersInRadius.Invoke(__instance);
			if (list == null)
			{
				RateLimitedDiagnostics.Hit("CampfireProtectionMerge.charactersInRadius-null");
				return true;
			}
			bool playersAreResting = true;
			list.Clear();
			if (PlayerHandler.Exists)
			{
				List<Character> allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters();
				if (allPlayerCharacters == null)
				{
					RateLimitedDiagnostics.Hit("CampfireProtectionMerge.roster-null");
					return true;
				}
				Vector3 position = ((Component)__instance).transform.position;
				float moraleBoostRadius = __instance.moraleBoostRadius;
				for (int i = 0; i < allPlayerCharacters.Count; i++)
				{
					Character val2 = allPlayerCharacters[i];
					if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.data == (Object)null) && !val2.data.dead)
					{
						if (!(Vector3.Distance(position, val2.Center) > moraleBoostRadius))
						{
							list.Add(val2);
						}
						else
						{
							playersAreResting = false;
						}
					}
				}
			}
			OrbFogHandler instance = Singleton<OrbFogHandler>.Instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				instance.PlayersAreResting = playersAreResting;
			}
			Character localCharacter = Character.localCharacter;
			bool flag = (Object)(object)localCharacter != (Object)null && list.Contains(localCharacter);
			if (!PlayerHandler.Exists || flag)
			{
				if ((Object)(object)localCharacter == (Object)null || localCharacter.refs == null)
				{
					RateLimitedDiagnostics.Hit("CampfireProtectionMerge.localCharacter-null");
					return false;
				}
				CharacterAfflictions afflictions = localCharacter.refs.afflictions;
				if ((Object)(object)afflictions == (Object)null)
				{
					RateLimitedDiagnostics.Hit("CampfireProtectionMerge.afflictions-null");
					return false;
				}
				if (afflictions.canGetHungry || Time.time - timebuffLastApplied.Invoke(__instance) > 2f)
				{
					afflictions.AddAffliction(val, false);
					timebuffLastApplied.Invoke(__instance) = Time.time;
				}
			}
			return false;
		}
	}
	internal sealed class CollisionCharacterLookupModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.CollisionCharacterLookup, () => new PatchDefinition(PatchId.CollisionCharacterLookup, CollisionCharacterLookupPatch.Initialize, CollisionCharacterLookupPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(CollisionCharacterLookupPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, CollisionCharacterLookupPatch.Reset));
		}
	}
	internal static class CollisionCharacterLookupPatch
	{
		private const string CollisionTypeName = "UnityEngine.Collision";

		private const string ColliderTypeName = "UnityEngine.Collider";

		private const string RigidbodyTypeName = "UnityEngine.Rigidbody";

		private const string CapsuleColliderTypeName = "UnityEngine.CapsuleCollider";

		private static FieldRef<CharacterMovement, Character> _character;

		private static Func<object, bool> _hasRigidbody;

		private static Func<object, Character> _tryGetCharacter;

		internal static void Initialize()
		{
			MethodInfo methodInfo = ResolveAndValidateTarget();
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeof(CharacterMovement), "character", typeof(Character));
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "sincePalJump", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "isCrouching", typeof(bool));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "sinceStandOnPlayer", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "lastStoodOnPlayer", typeof(Character));
			Type parameterType = methodInfo.GetParameters()[0].ParameterType;
			if (!string.Equals(parameterType.FullName, "UnityEngine.Collision", StringComparison.Ordinal))
			{
				throw new InvalidOperationException("CharacterMovement.StandOnPlayer collision type mismatch");
			}
			PropertyInfo propertyInfo = ScaleValidation.RequireInstancePropertyByTypeName(parameterType, "collider", "UnityEngine.Collider", requireSetter: false);
			PropertyInfo propertyInfo2 = ScaleValidation.RequireInstancePropertyByTypeName(parameterType, "rigidbody", "UnityEngine.Rigidbody", requireSetter: false);
			Type propertyType = propertyInfo.PropertyType;
			Type fieldType = typeof(Dictionary<, >).MakeGenericType(propertyType, typeof(Character));
			MethodInfo tryGetCharacter = ScaleValidation.RequireStaticMethod(typeof(CharacterRagdoll), "TryGetCharacterFromCollider", typeof(bool), new Type[2]
			{
				propertyType,
				typeof(Character).MakeByRefType()
			}, requirePublic: true);
			ScaleValidation.RequireStaticField(typeof(CharacterRagdoll), "COLLIDERS_TO_CHARACTERS", fieldType);
			ScaleValidation.RequireInstanceField(typeof(CharacterRagdoll), "partList", typeof(List<Bodypart>));
			ScaleValidation.RequireInstanceField(typeof(CharacterRagdoll), "character", typeof(Character));
			ScaleValidation.RequireInstanceMethod(typeof(CharacterRagdoll), "Start", typeof(void), Type.EmptyTypes, requirePublic: false);
			ScaleValidation.RequireInstanceMethod(typeof(CharacterRagdoll), "RegisterBodypartColliders", typeof(void), Type.EmptyTypes, requirePublic: false);
			ScaleValidation.RequireInstanceField(typeof(Bodypart), "colliders", typeof(List<RigCreatorCollider>));
			MethodInfo methodInfo2 = ScaleValidation.RequireInstanceMethodByTypeNames(typeof(RigCreatorCollider), "Col", "UnityEngine.CapsuleCollider", Array.Empty<string>());
			if (!propertyType.IsAssignableFrom(methodInfo2.ReturnType))
			{
				throw new InvalidOperationException("RigCreatorCollider.Col is not a Collider");
			}
			FieldRef<CharacterMovement, Character> obj = AccessTools.FieldRefAccess<CharacterMovement, Character>(fieldInfo);
			Func<object, bool> func = EmitHasRigidbody(parameterType, propertyInfo2.GetGetMethod(nonPublic: true));
			Func<object, Character> func2 = EmitCharacterLookup(parameterType, propertyInfo.GetGetMethod(nonPublic: true), tryGetCharacter);
			if (obj == null || func == null || func2 == null)
			{
				throw new InvalidOperationException("CollisionCharacterLookup accessor creation failed");
			}
			_character = obj;
			_hasRigidbody = func;
			_tryGetCharacter = func2;
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethodByTypeNames(typeof(CharacterMovement), "StandOnPlayer", typeof(bool).FullName, new string[1] { "UnityEngine.Collision" });
		}

		internal static void Reset()
		{
			_character = null;
			_hasRigidbody = null;
			_tryGetCharacter = null;
		}

		internal static bool Prefix(CharacterMovement __instance, object collision, ref bool __result)
		{
			FieldRef<CharacterMovement, Character> character = _character;
			Func<object, bool> hasRigidbody = _hasRigidbody;
			Func<object, Character> tryGetCharacter = _tryGetCharacter;
			if (character == null || hasRigidbody == null || tryGetCharacter == null)
			{
				return true;
			}
			Character val = character.Invoke(__instance);
			if ((Object)(object)val == (Object)null || (Object)(object)val.data == (Object)null || collision == null)
			{
				return true;
			}
			CharacterData data = val.data;
			if (data.sincePalJump < 0.5f || data.isCrouching)
			{
				__result = false;
				return false;
			}
			if (!hasRigidbody(collision))
			{
				__result = false;
				return false;
			}
			Character val2 = tryGetCharacter(collision);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.data == (Object)null)
			{
				return true;
			}
			if ((Object)(object)val2 == (Object)(object)val || !val2.data.isCrouching)
			{
				__result = false;
				return false;
			}
			data.sinceStandOnPlayer = 0f;
			data.lastStoodOnPlayer = val2;
			__result = true;
			return false;
		}

		private static Func<object, bool> EmitHasRigidbody(Type collisionType, MethodInfo rigidbodyGetter)
		{
			if (rigidbodyGetter == null || rigidbodyGetter.IsStatic)
			{
				throw new MissingMethodException("UnityEngine.Collision", "get_rigidbody");
			}
			DynamicMethod dynamicMethod = new DynamicMethod("PSO_CollisionHasRigidbody", typeof(bool), new Type[1] { typeof(object) }, typeof(CollisionCharacterLookupPatch).Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Castclass, collisionType);
			iLGenerator.Emit(OpCodes.Callvirt, rigidbodyGetter);
			iLGenerator.Emit(OpCodes.Ldnull);
			iLGenerator.Emit(OpCodes.Call, ResolveUnityObjectInequality());
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<object, bool>)dynamicMethod.CreateDelegate(typeof(Func<object, bool>));
		}

		private static Func<object, Character> EmitCharacterLookup(Type collisionType, MethodInfo colliderGetter, MethodInfo tryGetCharacter)
		{
			if (colliderGetter == null || colliderGetter.IsStatic)
			{
				throw new MissingMethodException("UnityEngine.Collision", "get_collider");
			}
			DynamicMethod dynamicMethod = new DynamicMethod("PSO_CollisionCharacterLookup", typeof(Character), new Type[1] { typeof(object) }, typeof(CollisionCharacterLookupPatch).Module, skipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			LocalBuilder local = iLGenerator.DeclareLocal(typeof(Character));
			Label label = iLGenerator.DefineLabel();
			Label label2 = iLGenerator.DefineLabel();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Castclass, collisionType);
			iLGenerator.Emit(OpCodes.Callvirt, colliderGetter);
			iLGenerator.Emit(OpCodes.Dup);
			iLGenerator.Emit(OpCodes.Ldnull);
			iLGenerator.Emit(OpCodes.Call, ResolveUnityObjectInequality());
			iLGenerator.Emit(OpCodes.Brfalse_S, label2);
			iLGenerator.Emit(OpCodes.Ldloca_S, local);
			iLGenerator.Emit(OpCodes.Call, tryGetCharacter);
			iLGenerator.Emit(OpCodes.Brtrue_S, label);
			iLGenerator.Emit(OpCodes.Ldnull);
			iLGenerator.Emit(OpCodes.Ret);
			iLGenerator.MarkLabel(label2);
			iLGenerator.Emit(OpCodes.Pop);
			iLGenerator.Emit(OpCodes.Ldnull);
			iLGenerator.Emit(OpCodes.Ret);
			iLGenerator.MarkLabel(label);
			iLGenerator.Emit(OpCodes.Ldloc, local);
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<object, Character>)dynamicMethod.CreateDelegate(typeof(Func<object, Character>));
		}

		private static MethodInfo ResolveUnityObjectInequality()
		{
			MethodInfo method = typeof(Object).GetMethod("op_Inequality", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
			{
				typeof(Object),
				typeof(Object)
			}, null);
			if (method == null || method.ReturnType != typeof(bool))
			{
				throw new MissingMethodException("UnityEngine.Object", "op_Inequality");
			}
			return method;
		}
	}
	internal sealed class CollisionContactsNoAllocModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.CollisionContactsNoAlloc, () => new PatchDefinition(PatchId.CollisionContactsNoAlloc, CollisionContactsNoAllocPatch.Initialize, CollisionContactsNoAllocPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(CollisionContactsNoAllocPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, CollisionContactsNoAllocPatch.Reset));
		}
	}
	internal static class CollisionContactsNoAllocPatch
	{
		private const string RocketRpcName = "RocketExplodeRPC";

		private static FieldRef<CharacterMovement, Character> _character;

		private static FieldRef<CharacterMovement, bool> _rocketActive;

		private static FieldRef<CharacterMovement, float> _currentRocketTime;

		private static Func<CharacterMovement, Collision, bool> _standOnPlayer;

		private static Func<CharacterMovement, Rigidbody, bool> _standableRig;

		private static Func<CharacterMovement, bool> _doGroundChecks;

		private static Func<CharacterMovement, float, bool> _acceptableAngle;

		private static Func<CollisionModifier, Character, bool> _canStand;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeof(CharacterMovement), "character", typeof(Character));
			FieldInfo fieldInfo2 = ScaleValidation.RequireInstanceField(typeof(CharacterMovement), "rocketActive", typeof(bool));
			FieldInfo fieldInfo3 = ScaleValidation.RequireInstanceField(typeof(CharacterMovement), "_currentRocketTime", typeof(float));
			MethodInfo methodInfo = ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "StandOnPlayer", typeof(bool), new Type[1] { typeof(Collision) }, requirePublic: false);
			MethodInfo methodInfo2 = ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "StandableRig", typeof(bool), new Type[1] { typeof(Rigidbody) }, requirePublic: false);
			MethodInfo methodInfo3 = ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "DoGroundChecks", typeof(bool), Type.EmptyTypes, requirePublic: false);
			MethodInfo methodInfo4 = ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "AcceptableAngle", typeof(bool), new Type[1] { typeof(float) }, requirePublic: false);
			MethodInfo methodInfo5 = ScaleValidation.RequireInstanceMethod(typeof(CollisionModifier), "CanStand", typeof(bool), new Type[1] { typeof(Character) }, requirePublic: false);
			ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "AddGroundSample", typeof(void), new Type[1] { typeof(PlayerGroundSample) }, requirePublic: true);
			ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "AddGroundSample_All", typeof(void), new Type[1] { typeof(PlayerGroundSample) }, requirePublic: true);
			ScaleValidation.RequireInstanceMethod(typeof(CollisionModifier), "Collide", typeof(void), new Type[4]
			{
				typeof(Character),
				typeof(ContactPoint),
				typeof(Collision),
				typeof(Bodypart)
			}, requirePublic: true);
			ScaleValidation.RequireInstanceField(typeof(CollisionModifier), "standable", typeof(bool));
			ScaleValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
			ScaleValidation.RequireInstanceField(typeof(CharacterRefs), "view", typeof(PhotonView));
			ScaleValidation.RequireInstanceProperty(typeof(Character), "IsLocal", typeof(bool));
			RequireRocketRpc();
			RequireGroundSampleShape();
			FieldRef<CharacterMovement, Character> obj = AccessTools.FieldRefAccess<CharacterMovement, Character>(fieldInfo);
			FieldRef<CharacterMovement, bool> val = AccessTools.FieldRefAccess<CharacterMovement, bool>(fieldInfo2);
			FieldRef<CharacterMovement, float> val2 = AccessTools.FieldRefAccess<CharacterMovement, float>(fieldInfo3);
			Func<CharacterMovement, Collision, bool> func = (Func<CharacterMovement, Collision, bool>)methodInfo.CreateDelegate(typeof(Func<CharacterMovement, Collision, bool>));
			Func<CharacterMovement, Rigidbody, bool> func2 = (Func<CharacterMovement, Rigidbody, bool>)methodInfo2.CreateDelegate(typeof(Func<CharacterMovement, Rigidbody, bool>));
			Func<CharacterMovement, bool> func3 = (Func<CharacterMovement, bool>)methodInfo3.CreateDelegate(typeof(Func<CharacterMovement, bool>));
			Func<CharacterMovement, float, bool> func4 = (Func<CharacterMovement, float, bool>)methodInfo4.CreateDelegate(typeof(Func<CharacterMovement, float, bool>));
			Func<CollisionModifier, Character, bool> func5 = (Func<CollisionModifier, Character, bool>)methodInfo5.CreateDelegate(typeof(Func<CollisionModifier, Character, bool>));
			if (obj == null || val == null || val2 == null || func == null || func2 == null || func3 == null || func4 == null || func5 == null)
			{
				throw new InvalidOperationException("CollisionContactsNoAlloc accessor creation failed");
			}
			_character = obj;
			_rocketActive = val;
			_currentRocketTime = val2;
			_standOnPlayer = func;
			_standableRig = func2;
			_doGroundChecks = func3;
			_acceptableAngle = func4;
			_canStand = func5;
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(CharacterMovement), "OnCollision", typeof(void), new Type[3]
			{
				typeof(Collision),
				typeof(bool),
				typeof(Bodypart)
			}, requirePublic: false);
		}

		internal static void Reset()
		{
			_character = null;
			_rocketActive = null;
			_currentRocketTime = null;
			_standOnPlayer = null;
			_standableRig = null;
			_doGroundChecks = null;
			_acceptableAngle = null;
			_canStand = null;
		}

		internal static bool Prefix(CharacterMovement __instance, Collision collision, bool collisionEnter, Bodypart bodypart)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			FieldRef<CharacterMovement, Character> character = _character;
			Func<CharacterMovement, Collision, bool> standOnPlayer = _standOnPlayer;
			Func<CharacterMovement, Rigidbody, bool> standableRig = _standableRig;
			Func<CharacterMovement, bool> doGroundChecks = _doGroundChecks;
			Func<CharacterMovement, float, bool> acceptableAngle = _acceptableAngle;
			Func<CollisionModifier, Character, bool> canStand = _canStand;
			if (character == null || standOnPlayer == null || standableRig == null || doGroundChecks == null || acceptableAngle == null || canStand == null || (Object)(object)__instance == (Object)null || collision == null)
			{
				return true;
			}
			Character val = character.Invoke(__instance);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			Collider collider = collision.collider;
			if ((Object)(object)collider == (Object)null)
			{
				return true;
			}
			if (collision.contactCount <= 0)
			{
				return true;
			}
			ContactPoint contact = collision.GetContact(0);
			CollisionModifier component = ((Component)collider).GetComponent<CollisionModifier>();
			if ((Object)(object)component != (Object)null)
			{
				component.Collide(val, contact, collision, bodypart);
				if (!component.standable || !canStand(component, val))
				{
					return false;
				}
			}
			bool flag = false;
			if (standOnPlayer(__instance, collision))
			{
				flag = true;
			}
			else if (!standableRig(__instance, collision.rigidbody))
			{
				return false;
			}
			if (_rocketActive.Invoke(__instance) && _currentRocketTime.Invoke(__instance) > 1f && val.IsLocal)
			{
				PhotonView val2 = val.refs?.view;
				if ((Object)(object)val2 == (Object)null)
				{
					RateLimitedDiagnostics.Hit("CollisionContactsNoAlloc.rocket-view-unavailable");
					return true;
				}
				val2.RPC("RocketExplodeRPC", (RpcTarget)0, Array.Empty<object>());
				_rocketActive.Invoke(__instance) = false;
			}
			float arg = Vector3.Angle(Vector3.up, ((ContactPoint)(ref contact)).normal);
			if (doGroundChecks(__instance))
			{
				if (acceptableAngle(__instance, arg) || flag)
				{
					__instance.AddGroundSample(new PlayerGroundSample(((ContactPoint)(ref contact)).point, ((ContactPoint)(ref contact)).normal));
				}
				__instance.AddGroundSample_All(new PlayerGroundSample(((ContactPoint)(ref contact)).point, ((ContactPoint)(ref contact)).normal));
			}
			return false;
		}

		private static void RequireRocketRpc()
		{
			MethodInfo method = typeof(CharacterMovement).GetMethod("RocketExplodeRPC", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method == null || method.ReturnType != typeof(void) || method.GetParameters().Length != 0)
			{
				throw new MissingMethodException(typeof(CharacterMovement).FullName, "RocketExplodeRPC");
			}
			if (((MemberInfo)method).GetCustomAttribute<PunRPC>() == null)
			{
				throw new InvalidOperationException("CharacterMovement.RocketExplodeRPC is no longer a PunRPC");
			}
		}

		private static void RequireGroundSampleShape()
		{
			Type typeFromHandle = typeof(PlayerGroundSample);
			if (!typeFromHandle.IsValueType)
			{
				throw new InvalidOperationException("PlayerGroundSample is no longer a struct");
			}
			if (typeFromHandle.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[2]
			{
				typeof(Vector3),
				typeof(Vector3)
			}, null) == null)
			{
				throw new MissingMethodException(typeFromHandle.FullName, ".ctor(Vector3, Vector3)");
			}
			ScaleValidation.RequireInstanceField(typeFromHandle, "point", typeof(Vector3));
			ScaleValidation.RequireInstanceField(typeFromHandle, "normal", typeof(Vector3));
			ScaleValidation.RequireInstanceField(typeFromHandle, "IsValid", typeof(bool));
		}
	}
	internal sealed class GenericOptimizerRangeModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.GenericOptimizerRange, () => new PatchDefinition(PatchId.GenericOptimizerRange, GenericOptimizerRangePatch.Initialize, GenericOptimizerRangePatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(GenericOptimizerRangePatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, GenericOptimizerRangePatch.Reset));
		}
	}
	internal static class GenericOptimizerRangePatch
	{
		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			ScaleValidation.RequireStaticField(typeof(Character), "AllCharacters", typeof(List<Character>));
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceProperty(typeof(CharacterData), "dead", typeof(bool));
			ScaleValidation.RequireInstanceProperty(typeof(Character), "Center", typeof(Vector3));
			ScaleValidation.RequireInstanceField(typeof(GenericOptimizer), "rangeToDisableScripts", typeof(float));
			ScaleValidation.RequireInstanceProperty(typeof(GenericOptimizer), "transform", typeof(Transform));
			ScaleValidation.RequireStaticMethod(typeof(Vector3), "Distance", typeof(float), new Type[2]
			{
				typeof(Vector3),
				typeof(Vector3)
			}, requirePublic: true);
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(GenericOptimizer), "AnyCharacterWithinRange", typeof(bool), new Type[1] { typeof(float) }, requirePublic: true);
		}

		internal static void Reset()
		{
		}

		internal static bool Prefix(GenericOptimizer __instance, float range, ref bool __result)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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)
			if (!(range >= 0f))
			{
				RateLimitedDiagnostics.Hit("GenericOptimizerRange.non-positive-range-fallback");
				return true;
			}
			List<Character> allCharacters = Character.AllCharacters;
			if (allCharacters == null)
			{
				RateLimitedDiagnostics.Hit("GenericOptimizerRange.allCharacters-null");
				return true;
			}
			Transform transform = ((Component)__instance).transform;
			if ((Object)(object)transform == (Object)null)
			{
				RateLimitedDiagnostics.Hit("GenericOptimizerRange.transform-null");
				return true;
			}
			Vector3 position = transform.position;
			bool flag = float.IsPositiveInfinity(range);
			float num = range * range;
			if (!flag && range > 0f && (!(num > 0f) || float.IsInfinity(num)))
			{
				return true;
			}
			for (int i = 0; i < allCharacters.Count; i++)
			{
				Character val = allCharacters[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				CharacterData data = val.data;
				if ((Object)(object)data == (Object)null || data.dead)
				{
					continue;
				}
				if (flag)
				{
					if (Vector3.Distance(val.Center, position) < range)
					{
						__result = true;
						return false;
					}
					continue;
				}
				Vector3 val2 = val.Center - position;
				if (((Vector3)(ref val2)).sqrMagnitude < num)
				{
					__result = true;
					return false;
				}
			}
			__result = false;
			return false;
		}
	}
	internal sealed class HeatEmissionScanModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.HeatEmissionScan, () => new PatchDefinition(PatchId.HeatEmissionScan, HeatEmissionScanPatch.Initialize, HeatEmissionScanPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(HeatEmissionScanPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, HeatEmissionScanPatch.Reset));
		}
	}
	internal static class HeatEmissionScanPatch
	{
		private static FieldRef<CharacterHeatEmission, Character> _character;

		private static FieldRef<CharacterHeatEmission, float> _counter;

		private static FieldRef<CharacterAfflictions, Character> _afflictionsCharacter;

		private static bool _ownerShortCircuitProven;

		internal static void Initialize()
		{
			ResolveAndValidateTarget();
			FieldInfo fieldInfo = ScaleValidation.RequireInstanceField(typeof(CharacterHeatEmission), "character", typeof(Character));
			FieldInfo fieldInfo2 = ScaleValidation.RequireInstanceField(typeof(CharacterHeatEmission), "counter", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(CharacterHeatEmission), "radius", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(CharacterHeatEmission), "heatAmount", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(CharacterHeatEmission), "rate", typeof(float));
			ScaleValidation.RequireInstanceField(typeof(Character), "refs", typeof(CharacterRefs));
			ScaleValidation.RequireInstanceField(typeof(Character), "data", typeof(CharacterData));
			ScaleValidation.RequireInstanceField(typeof(CharacterRefs), "hip", typeof(Bodypart));
			ScaleValidation.RequireInstanceField(typeof(CharacterRefs), "afflictions", typeof(CharacterAfflictions));
			ScaleValidation.RequireInstanceField(typeof(CharacterData), "sinceAddedCold", typeof(float));
			ScaleValidation.RequireStaticField(typeof(Character), "AllCharacters", typeof(List<Character>));
			ScaleValidation.RequireInstanceProperty(typeof(Character), "Center", typeof(Vector3));
			ScaleValidation.RequireInheritedInstanceProperty(typeof(Bodypart), "transform", typeof(Transform));
			ScaleValidation.RequireInstanceMethod(typeof(CharacterAfflictions), "SubtractStatus", typeof(void), new Type[4]
			{
				typeof(STATUSTYPE),
				typeof(float),
				typeof(bool),
				typeof(bool)
			}, requirePublic: true);
			FieldRef<CharacterHeatEmission, Character> val = AccessTools.FieldRefAccess<CharacterHeatEmission, Character>(fieldInfo);
			FieldRef<CharacterHeatEmission, float> val2 = AccessTools.FieldRefAccess<CharacterHeatEmission, float>(fieldInfo2);
			if (val == null || val2 == null)
			{
				throw new InvalidOperationException("HeatEmissionScan FieldRef creation failed");
			}
			_ownerShortCircuitProven = false;
			_afflictionsCharacter = null;
			try
			{
				FieldRef<CharacterAfflictions, Character> val3 = AccessTools.FieldRefAccess<CharacterAfflictions, Character>(ScaleValidation.RequireInstanceField(typeof(CharacterAfflictions), "character", typeof(Character)));
				if (val3 != null)
				{
					_afflictionsCharacter = val3;
					_ownerShortCircuitProven = true;
				}
			}
			catch (Exception)
			{
				_ownerShortCircuitProven = false;
				_afflictionsCharacter = null;
			}
			_character = val;
			_counter = val2;
		}

		internal static MethodInfo ResolveAndValidateTarget()
		{
			return ScaleValidation.RequireInstanceMethod(typeof(CharacterHeatEmission), "Update", typeof(void), Type.EmptyTypes, requirePublic: true);
		}

		internal static void Reset()
		{
			_character = null;
			_counter = null;
			_afflictionsCharacter = null;
			_ownerShortCircuitProven = false;
		}

		internal static bool Prefix(CharacterHeatEmission __instance)
		{
			//IL_00fe: 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_015d: 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_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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)
			FieldRef<CharacterHeatEmission, Character> character = _character;
			FieldRef<CharacterHeatEmission, float> counter = _counter;
			if (character == null || counter == null)
			{
				RateLimitedDiagnostics.Hit("HeatEmissionScan.accessors-unavailable");
				return true;
			}
			Character val = character.Invoke(__instance);
			if ((Object)(object)val == (Object)null)
			{
				RateLimitedDiagnostics.Hit("HeatEmissionScan.character-null");
				return true;
			}
			CharacterRefs refs = val.refs;
			Bodypart val2 = refs?.hip;
			CharacterData data = val.data;
			if (refs == null || (Object)(object)val2 == (Object)null || (Object)(object)data == (Object)null)
			{
				RateLimitedDiagnostics.Hit("HeatEmissionScan.owner-refs-incomplete");
				return true;
			}
			List<Character> allCharacters = Character.AllCharacters;
			if (allCharacters == null)
			{
				RateLimitedDiagnostics.Hit("HeatEmissionScan.allCharacters-null");
				return true;
			}
			Transform transform = ((Component)__instance).transform;
			Transform transform2 = val2.transform;
			if ((Object)(object)transform == (Object)null || (Object)(object)transform2 == (Object)null)
			{
				RateLimitedDiagnostics.Hit("HeatEmissionScan.transform-null");
				return true;
			}
			float radius = __instance.radius;
			float num = radius * radius;
			if (radius > 0f && (!(num > 0f) || float.IsInfinity(num)))
			{
				RateLimitedDiagnostics.Hit("HeatEmissionScan.radius-out-of-square-range");
				return true;
			}
			transform.position = transform2.position;
			if (data.sinceAddedCold < 3f)
			{
				return false;
			}
			float num2 = counter.Invoke(__instance) + Time.deltaTime;
			if (num2 < __instance.rate)
			{
				counter.Invoke(__instance) = num2;
				return false;
			}
			counter.Invoke(__instance) = 0f;
			if (!(radius > 0f))
			{
				return false;
			}
			Vector3 position = transform.position;
			float heatAmount = __instance.heatAmount;
			bool ownerShortCircuitProven = _ownerShortCircuitProven;
			FieldRef<CharacterAfflictions, Character> afflictionsCharacter = _afflictionsCharacter;
			for (int i = 0; i < allCharacters.Count; i++)
			{
				Character val3 = allCharacters[i];
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Vector3 val4 = position - val3.Center;
				if (((Vector3)(ref val4)).sqrMagnitude < num)
				{
					CharacterAfflictions val5 = val3.refs?.afflictions;
					if (!((Object)(object)val5 == (Object)null) && (!ownerShortCircuitProven || afflictionsCharacter == null || !((Object)(object)afflictionsCharacter.Invoke(val5) == (Object)(object)val3) || ((MonoBehaviourPun)val3).photonView.IsMine))
					{
						val5.SubtractStatus((STATUSTYPE)2, heatAmount, false, false);
					}
				}
			}
			return false;
		}
	}
	internal sealed class IsLookedAtScanModule : IPatchModule
	{
		public void Register(PatchModuleContext context)
		{
			context.Register(PatchId.IsLookedAtScan, () => new PatchDefinition(PatchId.IsLookedAtScan, IsLookedAtScanPatch.Initialize, IsLookedAtScanPatch.ResolveAndValidateTarget, () => new HarmonyMethod(typeof(IsLookedAtScanPatch), "Prefix", (Type[])null), null, null, null, requireCurrentMvid: true, IsLookedAtScanPatch.Reset));
		}
	}
	internal static class IsLookedAtScanPatch
	{
		private static FieldRef<IsLookedAt