Decompiled source of Hikers Hunger Redux v3.1.0

HikersHunger.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using HarmonyLib;
using HikersHunger;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("HikersHunger")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.0.1.0")]
[assembly: AssemblyInformationalVersion("2.0.1")]
[assembly: AssemblyProduct("HikersHunger")]
[assembly: AssemblyTitle("HikersHunger")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("HikersHunger", "Hikers Hunger", "2.1.0")]
public class HikersHungerPlugin : BaseUnityPlugin, IInRoomCallbacks, IMatchmakingCallbacks, IOnEventCallback
{
	[Serializable]
	public struct HostCfg
	{
		public bool manualCannibalSelection;

		public int initialSelectionDelay;

		public int postSelectionDelay;

		public bool enableCustomEatTime;

		public float customEatTime;

		public bool constantCannibal;

		public float safeZoneDelay;

		public float safeZoneRange;

		public float cannibalRegenSpeed;

		public bool cannibalRegenEnabled;

		public bool campfireLitSafetyOnly;
	}

	[HarmonyPatch]
	public class HikersHungerPatches
	{
		[HarmonyPatch(typeof(Action_RestoreHunger), "RunAction")]
		[HarmonyPrefix]
		private static bool RestoreHungerPrefix(Action_RestoreHunger __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<Character>() != (Object)null)
			{
				int cannibalViewID = Instance.cannibalViewID;
				Character localCharacter = Character.localCharacter;
				int? obj;
				if (localCharacter == null)
				{
					obj = null;
				}
				else
				{
					PhotonView photonView = ((MonoBehaviourPun)localCharacter).photonView;
					obj = ((photonView != null) ? new int?(photonView.ViewID) : null);
				}
				if (cannibalViewID == obj)
				{
					return true;
				}
			}
			else
			{
				int cannibalViewID2 = Instance.cannibalViewID;
				Character localCharacter2 = Character.localCharacter;
				int? obj2;
				if (localCharacter2 == null)
				{
					obj2 = null;
				}
				else
				{
					PhotonView photonView2 = ((MonoBehaviourPun)localCharacter2).photonView;
					obj2 = ((photonView2 != null) ? new int?(photonView2.ViewID) : null);
				}
				if (cannibalViewID2 == obj2)
				{
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(GameUtils), "Awake")]
		[HarmonyPostfix]
		public static void GameUtilsAwakePostfix(GameUtils __instance)
		{
			((Component)__instance).gameObject.AddComponent<CannibalSyncer>();
			CannibalSyncer = ((Component)__instance).gameObject.GetComponent<CannibalSyncer>();
		}

		[HarmonyPatch(typeof(RunManager), "StartRun")]
		[HarmonyPostfix]
		private static void StartRunPostfix()
		{
			if (!((Object)(object)Singleton<MapHandler>.Instance == (Object)null))
			{
				Debug.Log((object)"[HikersHunger] Run started!");
				((MonoBehaviour)Instance).StartCoroutine(Instance.SelectRandomCannibalAfterDelay());
				((MonoBehaviour)CannibalSyncer).StartCoroutine(CannibalSyncer.SyncLoop());
			}
		}

		[HarmonyPatch(typeof(Campfire), "Light_Rpc")]
		[HarmonyPostfix]
		private static void Light_RPCPostfix(Campfire __instance)
		{
			Instance.fireCount++;
			Debug.Log((object)$"[HikersHunger] Campfire lit! Total fires: {Instance.fireCount}");
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!allCharacter.isBot && !allCharacter.data.dead && (Object)(object)allCharacter.refs?.customization != (Object)null && allCharacter.IsLocal)
				{
					allCharacter.refs.customization.BecomeHuman();
				}
			}
			Debug.Log((object)"[HikersHunger] All players restored to human appearance");
			Instance.SelectNewCannibalAtCampfire();
		}

		[HarmonyPatch(typeof(CharacterInteractible), "GetInteractTime")]
		[HarmonyPostfix]
		private static void GetInteractTimePostfix(CharacterInteractible __instance, Character interactor, ref float __result)
		{
			if (Synced.enableCustomEatTime && Instance.cannibalViewID == ((MonoBehaviourPun)interactor).photonView.ViewID)
			{
				__result = ((((Component)__instance).gameObject.GetComponent<SafetyModule>().safeTime > Time.time || ((Component)interactor).gameObject.GetComponent<SafetyModule>().safeTime > Time.time) ? 999f : Synced.customEatTime);
			}
		}

		[HarmonyPatch(typeof(CharacterInteractible), "IsConstantlyInteractable")]
		[HarmonyPostfix]
		private static void IsConstantlyInteractablePostfix(CharacterInteractible __instance, Character interactor, ref bool __result)
		{
			if (__result && Instance.cannibalViewID == ((MonoBehaviourPun)interactor).photonView.ViewID)
			{
				__result = !(((Component)__instance).gameObject.GetComponent<SafetyModule>().safeTime > Time.time) && !(((Component)interactor).gameObject.GetComponent<SafetyModule>().safeTime > Time.time);
			}
		}

		[HarmonyPatch(typeof(CharacterInteractible), "GetEaten")]
		[HarmonyPrefix]
		private static bool GetEatenPrefix(CharacterInteractible __instance, Character eater)
		{
			if (Instance.cannibalViewID == eater.refs.view.ViewID)
			{
				if (((Component)__instance).gameObject.GetComponent<SafetyModule>().safeTime > Time.time)
				{
					Debug.Log((object)"[HikersHunger] BLOCKED: Cannibal attempted to eat safe player!");
					return false;
				}
				if (((Component)eater).gameObject.GetComponent<SafetyModule>().safeTime > Time.time)
				{
					Debug.Log((object)"[HikersHunger] BLOCKED: Safe Cannibal attempted to eat player!");
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(CharacterInteractible), "GetEaten")]
		[HarmonyPostfix]
		private static void GetEatenPostfix(CharacterInteractible __instance, Character eater)
		{
			if (Instance.cannibalViewID == ((MonoBehaviourPun)eater).photonView.ViewID)
			{
				eater.refs.afflictions.SetStatus((STATUSTYPE)5, 0f, true);
				if (Instance.eliminateCurseCoroutine != null)
				{
					((MonoBehaviour)Instance).StopCoroutine(Instance.eliminateCurseCoroutine);
					Instance.eliminateCurseCoroutine = null;
				}
				eater.refs.afflictions.currentStatuses[5] = 0.15f;
				Instance.eliminateCurseCoroutine = ((MonoBehaviour)Instance).StartCoroutine(Instance.EliminateCurseOverTime());
			}
		}

		[HarmonyPatch(typeof(Character), "Awake")]
		[HarmonyPostfix]
		private static void AwakePostFix(Character __instance)
		{
			if (!__instance.isBot && !__instance.IsGhost && !__instance.data.dead)
			{
				((Component)__instance).gameObject.AddComponent<SafetyModule>();
				((Component)__instance).gameObject.GetComponent<SafetyModule>().parentPlugin = Instance;
				if (__instance.IsLocal)
				{
					foundCampfires = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0);
				}
			}
		}
	}

	[CompilerGenerated]
	private sealed class <ActivateCannibalRegeneration>d__38 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public HikersHungerPlugin <>4__this;

		private WaitForSeconds <waitInstruction>5__1;

		private float <elapsed>5__2;

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

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

		[DebuggerHidden]
		public <ActivateCannibalRegeneration>d__38(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<waitInstruction>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			int num = <>1__state;
			if (num != 0)
			{
				if (num != 1)
				{
					return false;
				}
				<>1__state = -1;
				goto IL_007b;
			}
			<>1__state = -1;
			Debug.Log((object)"[HikersHunger] Regen Activated");
			<waitInstruction>5__1 = new WaitForSeconds(0.25f);
			goto IL_009e;
			IL_007b:
			if (<elapsed>5__2 < Synced.cannibalRegenSpeed)
			{
				<elapsed>5__2 += 0.25f;
				<>2__current = <waitInstruction>5__1;
				<>1__state = 1;
				return true;
			}
			<>4__this.DoRegenerationTick();
			goto IL_009e;
			IL_009e:
			if (Synced.cannibalRegenEnabled && <>4__this.IsLocalPlayerCannibal())
			{
				<elapsed>5__2 = 0f;
				goto IL_007b;
			}
			return false;
		}

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

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

	[CompilerGenerated]
	private sealed class <CannibalSafeZoneMonitoring>d__37 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public HikersHungerPlugin <>4__this;

		private WaitForSeconds <waitInstruction>5__1;

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

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

		[DebuggerHidden]
		public <CannibalSafeZoneMonitoring>d__37(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<waitInstruction>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<waitInstruction>5__1 = new WaitForSeconds(1f);
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (<>4__this.IsLocalPlayerCannibal())
			{
				if (((Component)Character.localCharacter).gameObject.GetComponent<SafetyModule>().safeTime > Time.time)
				{
					UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
				}
				else if (((Component)Character.localCharacter).gameObject.GetComponent<SafetyModule>().safeTime < Time.time)
				{
					UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = -1f;
				}
				<>2__current = <waitInstruction>5__1;
				<>1__state = 1;
				return true;
			}
			return false;
		}

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

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

	[CompilerGenerated]
	private sealed class <DelayCannibalPowers>d__74 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public int viewID;

		public HikersHungerPlugin <>4__this;

		private float <delay>5__1;

		private float <elapsed>5__2;

		private WaitForSeconds <cachedTime>5__3;

		private Exception <ex>5__4;

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

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

		[DebuggerHidden]
		public <DelayCannibalPowers>d__74(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<cachedTime>5__3 = null;
			<ex>5__4 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<delay>5__1 = Synced.postSelectionDelay;
				<elapsed>5__2 = 0f;
				<cachedTime>5__3 = new WaitForSeconds(0.5f);
				Debug.Log((object)$"[HikersHunger] Waiting {<delay>5__1} seconds before granting powers...");
				break;
			case 1:
				<>1__state = -1;
				<elapsed>5__2 += 0.5f;
				Debug.Log((object)$"[HikersHunger] Delay elapsed time: [{<elapsed>5__2}/{<delay>5__1}]");
				break;
			}
			if (<elapsed>5__2 < <delay>5__1)
			{
				<>2__current = <cachedTime>5__3;
				<>1__state = 1;
				return true;
			}
			try
			{
				<>4__this.manager.SetRoomProperty("cannibalViewId", (object)viewID);
				Debug.Log((object)"[HikersHunger] PostSelectionDelay finished! Cannibal ViewID room property set.");
			}
			catch (Exception ex)
			{
				<ex>5__4 = ex;
				Debug.Log((object)("[HikersHunger] Failed to set room property: " + <ex>5__4.Message));
			}
			return false;
		}

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

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

	[CompilerGenerated]
	private sealed class <EliminateCurseOverTime>d__40 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public HikersHungerPlugin <>4__this;

		private WaitForSeconds <waitTime>5__1;

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

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

		[DebuggerHidden]
		public <EliminateCurseOverTime>d__40(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<waitTime>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				Debug.Log((object)"[HikersHunger] Starting Curse Removal Coroutine.");
				<waitTime>5__1 = new WaitForSeconds(0.15f);
				<>2__current = (object)new WaitForSeconds(5f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				break;
			case 2:
				<>1__state = -1;
				Character.localCharacter.refs.afflictions.currentStatuses[5] -= 0.001f;
				if ((double)Character.localCharacter.refs.afflictions.currentStatuses[5] % 0.025 == 0.0)
				{
					Character.localCharacter.refs.afflictions.SetStatus((STATUSTYPE)5, Character.localCharacter.refs.afflictions.currentStatuses[5], true);
				}
				break;
			}
			if (Character.localCharacter.refs.afflictions.currentStatuses[5] > 0f)
			{
				<>2__current = <waitTime>5__1;
				<>1__state = 2;
				return true;
			}
			Character.localCharacter.refs.afflictions.SetStatus((STATUSTYPE)5, 0f, true);
			<>4__this.eliminateCurseCoroutine = null;
			((MonoBehaviour)<>4__this).StopCoroutine(<>4__this.eliminateCurseCoroutine);
			return false;
		}

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

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

	[CompilerGenerated]
	private sealed class <GenerateExtraStam>d__41 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float amount;

		public HikersHungerPlugin <>4__this;

		private WaitForSeconds <waitTime>5__1;

		private float <ticks>5__2;

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

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

		[DebuggerHidden]
		public <GenerateExtraStam>d__41(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<waitTime>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				Debug.Log((object)"[HikersHunger] Generating Extra Stamina Burst");
				<waitTime>5__1 = new WaitForSeconds(0.02f);
				<ticks>5__2 = 0f;
				break;
			case 1:
				<>1__state = -1;
				<ticks>5__2 += 1f;
				Character.localCharacter.AddExtraStamina(0.001f);
				break;
			}
			if (<ticks>5__2 < amount * 1000f)
			{
				<>2__current = <waitTime>5__1;
				<>1__state = 1;
				return true;
			}
			return false;
		}

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

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

	[CompilerGenerated]
	private sealed class <SelectRandomCannibalAfterDelay>d__75 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float overrideTime;

		public HikersHungerPlugin <>4__this;

		private float <delay>5__1;

		private float <elapsed>5__2;

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

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

		[DebuggerHidden]
		public <SelectRandomCannibalAfterDelay>d__75(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (overrideTime == 0f)
				{
					<delay>5__1 = Synced.initialSelectionDelay;
				}
				else
				{
					<delay>5__1 = overrideTime;
				}
				<elapsed>5__2 = 0f;
				Debug.Log((object)$"[HikersHunger] Waiting {<delay>5__1} seconds before selecting cannibal...");
				if (!PhotonNetwork.IsMasterClient)
				{
					return false;
				}
				<>4__this.randomPlayerList = <>4__this.GetValidCandidates(findDead: true);
				break;
			case 1:
				<>1__state = -1;
				<elapsed>5__2 += 1f;
				break;
			}
			if (<elapsed>5__2 < <delay>5__1)
			{
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			}
			if (Synced.manualCannibalSelection)
			{
				<>4__this.randomPlayerList = <>4__this.GetValidCandidates(findDead: true);
				<>4__this.showCannibalSelectionGUI = true;
			}
			else
			{
				<>4__this.SelectRandomCannibal();
			}
			return false;
		}

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

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

	public static HikersHungerPlugin Instance;

	public static CannibalSyncer CannibalSyncer;

	public int cannibalViewID = -1;

	private int fireCount = 0;

	private bool showCannibalSelectionGUI = false;

	private ConfigEntry<bool> manualCannibalSelection;

	private ConfigEntry<int> initialSelectionDelay;

	private ConfigEntry<int> postSelectionDelay;

	private ConfigEntry<bool> enableCustomEatTime;

	private ConfigEntry<float> customEatTime;

	private ConfigEntry<bool> constantCannibal;

	public ConfigEntry<float> safeZoneDelay;

	public ConfigEntry<float> safeZoneRange;

	public ConfigEntry<float> cannibalRegenSpeed;

	public ConfigEntry<float> hostSyncFrequency;

	public ConfigEntry<bool> cannibalRegenEnabled;

	public ConfigEntry<bool> campfireLitSafetyOnly;

	private List<Character> randomPlayerList;

	public static Campfire[] foundCampfires;

	public static HostCfg Synced;

	public PhotonScopedManager manager;

	private Harmony harmony;

	private Coroutine RegenerationCoroutine;

	private Coroutine CannibalSafeZoneCoroutine;

	private Coroutine eliminateCurseCoroutine;

	private void Awake()
	{
		Instance = this;
		InitializeConfiguration();
		InitializeHarmony();
		InitializePhotonManager();
		SceneManager.activeSceneChanged += OnSceneChanged;
		UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
		Debug.Log((object)"[HikersHunger] Plugin initialized successfully");
	}

	private void InitializeConfiguration()
	{
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Expected O, but got Unknown
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Expected O, but got Unknown
		manualCannibalSelection = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Manual Cannibal Selection", true, "When enabled, the host can manually select who becomes the cannibal using a GUI instead of random selection.");
		initialSelectionDelay = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Initial Selection Delay", 15, "The initial delay (in seconds) before the game starts attempting to select a cannibal.");
		postSelectionDelay = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Post Selection Delay", 60, "The delay (in seconds) after selecting a cannibal before actually giving them cannibal powers.");
		enableCustomEatTime = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Custom EatTime", true, "When enabled, allows hosts to customize how long it takes to eat players.");
		customEatTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Custom EatTime", 0.8f, "The time (in seconds) it takes to eat a player. Lower values = faster eating. 0.01 = almost instant.");
		constantCannibal = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Constant Cannibal", false, "When enabled, the first person chosen as cannibal remains cannibal for the entire game until a new run starts.");
		hostSyncFrequency = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Host Sync Frequency", 30f, new ConfigDescription("How often the host should send out a syncronization heartbeat to all clients. Lower this if you have persistent sync problems, raise it to help prevent network lag.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>()));
		safeZoneDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "SafeZone Delay", 15f, "The delay (in seconds) after leaving a safe zone before cannibal powers are restored.");
		safeZoneRange = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "SafeZone Range", 80f, "The safety range for campfires, in meters.");
		campfireLitSafetyOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "Campfires Only Safe While Lit", false, "Campfires will only provide safety to non-cannibals while they are actively lit.");
		cannibalRegenEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Cannibal", "Cannibal Regeneration", true, "Should cannibals regenerate all statuses?");
		cannibalRegenSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Cannibal", "Cannibal Regeneration Tickrate", 15f, new ConfigDescription("The tickrate, in seconds, for cannibal regeneration.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 60f), Array.Empty<object>()));
		Synced = BuildFromHostConfig();
		manualCannibalSelection.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		initialSelectionDelay.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		postSelectionDelay.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		enableCustomEatTime.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		customEatTime.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		constantCannibal.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		safeZoneDelay.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		safeZoneRange.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		cannibalRegenSpeed.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		cannibalRegenEnabled.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
		campfireLitSafetyOnly.SettingChanged += delegate
		{
			OnHostConfigChanged();
		};
	}

	private void InitializeHarmony()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		harmony = new Harmony("Hikers_Hunger");
		harmony.PatchAll();
		Debug.Log((object)"[HikersHunger] Harmony patches applied");
	}

	private void InitializePhotonManager()
	{
		manager = PhotonCustomPropsUtilsPlugin.GetManager("Hikers_Hunger");
		manager.RegisterRoomProperty<int>("cannibalViewId", (RoomEventType)2, (Action<int>)delegate(int value)
		{
			int num = cannibalViewID;
			cannibalViewID = value;
			if (num != cannibalViewID)
			{
				OnCannibalChanged();
			}
		});
	}

	private void OnCannibalChanged()
	{
		StripPowersFromAllPlayers();
		if (cannibalViewID != -1)
		{
			Character characterByViewID = GetCharacterByViewID(cannibalViewID);
			if ((Object)(object)characterByViewID != (Object)null)
			{
				Debug.Log((object)("[HikersHunger] " + (characterByViewID.refs.view.Owner.NickName ?? "Unknown") + " is now the cannibal"));
			}
			if (IsLocalPlayerCannibal())
			{
				GrantCannibalPowers();
			}
		}
	}

	private Character GetCharacterByViewID(int viewID)
	{
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (allCharacter != null && allCharacter.refs.view.ViewID == viewID)
			{
				return allCharacter;
			}
		}
		return null;
	}

	public bool IsLocalPlayerCannibal()
	{
		return cannibalViewID == Character.localCharacter.view.ViewID;
	}

	private void GrantCannibalPowers()
	{
		if (IsLocalPlayerCannibal())
		{
			Debug.Log((object)"[HikersHunger] Local player cannibal powers granted.");
			if (RegenerationCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(RegenerationCoroutine);
				RegenerationCoroutine = null;
			}
			if (CannibalSafeZoneCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(CannibalSafeZoneCoroutine);
				CannibalSafeZoneCoroutine = null;
			}
			RegenerationCoroutine = ((MonoBehaviour)this).StartCoroutine(ActivateCannibalRegeneration());
			CannibalSafeZoneCoroutine = ((MonoBehaviour)this).StartCoroutine(CannibalSafeZoneMonitoring());
		}
	}

	private void StripPowersFromAllPlayers()
	{
		Debug.Log((object)"[HikersHunger] Stripping cannibal powers from all players");
		if (RegenerationCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(RegenerationCoroutine);
			RegenerationCoroutine = null;
		}
		if (CannibalSafeZoneCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(CannibalSafeZoneCoroutine);
			CannibalSafeZoneCoroutine = null;
		}
		UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
		Debug.Log((object)"[HikersHunger] Local cannibal powers stripped");
	}

	public bool IsCharacterNearCampfire(Character c)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		bool result = false;
		Campfire[] array = foundCampfires;
		foreach (Campfire val in array)
		{
			if (Vector3.Distance(((Component)val).transform.position, c.Center) < Synced.safeZoneRange)
			{
				result = true;
				if (Synced.campfireLitSafetyOnly && !val.Lit)
				{
					result = false;
				}
				break;
			}
		}
		return result;
	}

	[IteratorStateMachine(typeof(<CannibalSafeZoneMonitoring>d__37))]
	private IEnumerator CannibalSafeZoneMonitoring()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <CannibalSafeZoneMonitoring>d__37(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<ActivateCannibalRegeneration>d__38))]
	private IEnumerator ActivateCannibalRegeneration()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ActivateCannibalRegeneration>d__38(0)
		{
			<>4__this = this
		};
	}

	private void DoRegenerationTick()
	{
		CharacterAfflictions afflictions = Character.localCharacter.refs.afflictions;
		Debug.Log((object)"[HikersHunger] Regen DoTick");
		((MonoBehaviour)this).StartCoroutine(GenerateExtraStam(0.1f));
		afflictions.SubtractStatus((STATUSTYPE)0, 0.025f, false, false);
		afflictions.SubtractStatus((STATUSTYPE)10, 0.025f, false, false);
		afflictions.SubtractStatus((STATUSTYPE)3, 0.025f, false, false);
		afflictions.SubtractStatus((STATUSTYPE)8, 0.025f, false, false);
		afflictions.SubtractStatus((STATUSTYPE)2, 0.025f, false, false);
		afflictions.SubtractStatus((STATUSTYPE)6, 0.025f, false, false);
		afflictions.SubtractStatus((STATUSTYPE)9, 0.025f, false, false);
	}

	[IteratorStateMachine(typeof(<EliminateCurseOverTime>d__40))]
	private IEnumerator EliminateCurseOverTime()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <EliminateCurseOverTime>d__40(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<GenerateExtraStam>d__41))]
	private IEnumerator GenerateExtraStam(float amount)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <GenerateExtraStam>d__41(0)
		{
			<>4__this = this,
			amount = amount
		};
	}

	private void OnEnable()
	{
		PhotonNetwork.AddCallbackTarget((object)this);
	}

	private void OnDisable()
	{
		PhotonNetwork.RemoveCallbackTarget((object)this);
	}

	private void OnDestroy()
	{
		PhotonNetwork.RemoveCallbackTarget((object)this);
	}

	private void OnSceneChanged(Scene oldScene, Scene newScene)
	{
		if (((Scene)(ref newScene)).name == "Airport")
		{
			ResetPluginState();
		}
		TryReadConfigFromRoom();
	}

	private void ResetPluginState()
	{
		Debug.Log((object)"[HikersHunger] Returned to Airport - resetting plugin state");
		cannibalViewID = -1;
		fireCount = 0;
		showCannibalSelectionGUI = false;
		UIPlayerNames.CANNIBAL_HUNGER_THRESHOLD = 2f;
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if ((Object)(object)allCharacter?.refs?.customization != (Object)null)
			{
				allCharacter.refs.customization.BecomeHuman();
			}
		}
	}

	public void OnJoinedRoom()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			Debug.Log((object)"[HikersHunger] Joined room as HOST");
			PublishConfig();
		}
		else
		{
			Debug.Log((object)"[HikersHunger] Joined room as CLIENT; reading config");
			TryReadConfigFromRoom();
		}
	}

	public void OnCreatedRoom()
	{
	}

	public void OnCreateRoomFailed(short returnCode, string message)
	{
	}

	public void OnFriendListUpdate(List<FriendInfo> friendList)
	{
	}

	public void OnJoinRandomFailed(short returnCode, string message)
	{
	}

	public void OnJoinRoomFailed(short returnCode, string message)
	{
	}

	public void OnLeftRoom()
	{
	}

	public void OnPlayerEnteredRoom(Player newPlayer)
	{
		if (PhotonNetwork.IsMasterClient)
		{
			PublishConfig();
		}
	}

	public void OnPlayerLeftRoom(Player otherPlayer)
	{
		if (cannibalViewID == -1 || otherPlayer == null)
		{
			return;
		}
		foreach (Character allCharacter in Character.AllCharacters)
		{
			object obj;
			if (allCharacter == null)
			{
				obj = null;
			}
			else
			{
				CharacterRefs refs = allCharacter.refs;
				if (refs == null)
				{
					obj = null;
				}
				else
				{
					PhotonView view = refs.view;
					obj = ((view != null) ? view.Owner : null);
				}
			}
			if (obj == otherPlayer && allCharacter.refs.view.ViewID == cannibalViewID)
			{
				Debug.Log((object)("[HikersHunger] The cannibal (" + otherPlayer.NickName + ") has left the game!"));
				StripPowersFromAllPlayers();
				Debug.Log((object)"[HikersHunger] Initiating new cannibal selection in form of host configuration.");
				Debug.Log((object)"[HikersHunger] Selection will begin after the configured selection delay.");
				((MonoBehaviour)this).StartCoroutine(SelectRandomCannibalAfterDelay());
				break;
			}
		}
	}

	public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
	{
		if (propertiesThatChanged != null && ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"HIKERS_HUNGER_CFG_V1") && propertiesThatChanged[(object)"HIKERS_HUNGER_CFG_V1"] is string s)
		{
			HostCfg synced = Synced;
			Synced = UnpackCfg(s);
			if (ConfigChanged(synced, Synced))
			{
				Debug.Log((object)"[HikersHunger] Config updated from room");
			}
		}
	}

	public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
	{
	}

	public void OnMasterClientSwitched(Player newMasterClient)
	{
		if (PhotonNetwork.IsMasterClient)
		{
			PublishConfig();
		}
	}

	public void OnEvent(EventData photonEvent)
	{
	}

	private HostCfg BuildFromHostConfig()
	{
		HostCfg result = default(HostCfg);
		result.manualCannibalSelection = manualCannibalSelection.Value;
		result.initialSelectionDelay = initialSelectionDelay.Value;
		result.postSelectionDelay = postSelectionDelay.Value;
		result.enableCustomEatTime = enableCustomEatTime.Value;
		result.customEatTime = customEatTime.Value;
		result.constantCannibal = constantCannibal.Value;
		result.safeZoneDelay = safeZoneDelay.Value;
		result.safeZoneRange = safeZoneRange.Value;
		result.cannibalRegenEnabled = cannibalRegenEnabled.Value;
		result.cannibalRegenSpeed = cannibalRegenSpeed.Value;
		result.campfireLitSafetyOnly = campfireLitSafetyOnly.Value;
		return result;
	}

	private static string PackCfg(HostCfg c)
	{
		CultureInfo invariantCulture = CultureInfo.InvariantCulture;
		return $"{c.manualCannibalSelection}|" + $"{c.initialSelectionDelay}|" + $"{c.postSelectionDelay}|" + $"{c.enableCustomEatTime}|" + $"{c.customEatTime}|" + $"{c.constantCannibal}|" + $"{c.safeZoneDelay}|" + $"{c.safeZoneRange}|" + $"{c.cannibalRegenEnabled}|" + $"{c.cannibalRegenSpeed}|" + $"{c.campfireLitSafetyOnly}";
	}

	private static HostCfg UnpackCfg(string s)
	{
		CultureInfo invariantCulture = CultureInfo.InvariantCulture;
		string[] array = (s ?? string.Empty).Split(new char[1] { '|' });
		HostCfg hostCfg = default(HostCfg);
		hostCfg.manualCannibalSelection = false;
		hostCfg.initialSelectionDelay = 20;
		hostCfg.postSelectionDelay = 120;
		hostCfg.enableCustomEatTime = false;
		hostCfg.customEatTime = 0.01f;
		hostCfg.constantCannibal = false;
		hostCfg.safeZoneDelay = 30f;
		hostCfg.safeZoneRange = 225f;
		hostCfg.cannibalRegenEnabled = true;
		hostCfg.cannibalRegenSpeed = 15f;
		hostCfg.campfireLitSafetyOnly = false;
		HostCfg result = hostCfg;
		if (array.Length >= 11)
		{
			bool.TryParse(array[0], out result.manualCannibalSelection);
			int.TryParse(array[1], NumberStyles.Integer, invariantCulture, out result.initialSelectionDelay);
			int.TryParse(array[2], NumberStyles.Integer, invariantCulture, out result.postSelectionDelay);
			bool.TryParse(array[3], out result.enableCustomEatTime);
			float.TryParse(array[4], NumberStyles.Float, invariantCulture, out result.customEatTime);
			bool.TryParse(array[5], out result.constantCannibal);
			float.TryParse(array[6], NumberStyles.Float, invariantCulture, out result.safeZoneDelay);
			float.TryParse(array[7], NumberStyles.Float, invariantCulture, out result.safeZoneRange);
			bool.TryParse(array[8], out result.cannibalRegenEnabled);
			float.TryParse(array[9], NumberStyles.Float, invariantCulture, out result.cannibalRegenSpeed);
			bool.TryParse(array[10], out result.campfireLitSafetyOnly);
		}
		return result;
	}

	private bool ConfigChanged(HostCfg old, HostCfg newCfg)
	{
		return old.manualCannibalSelection != newCfg.manualCannibalSelection || old.initialSelectionDelay != newCfg.initialSelectionDelay || old.postSelectionDelay != newCfg.postSelectionDelay || old.enableCustomEatTime != newCfg.enableCustomEatTime || old.customEatTime != newCfg.customEatTime || old.constantCannibal != newCfg.constantCannibal || old.safeZoneRange != newCfg.safeZoneRange || old.safeZoneDelay != newCfg.safeZoneDelay || old.cannibalRegenEnabled != newCfg.cannibalRegenEnabled || old.cannibalRegenSpeed != newCfg.cannibalRegenSpeed || old.campfireLitSafetyOnly != newCfg.campfireLitSafetyOnly;
	}

	private void TryReadConfigFromRoom()
	{
		Room currentRoom = PhotonNetwork.CurrentRoom;
		object value = null;
		if (currentRoom != null && (((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties)?.TryGetValue((object)"HIKERS_HUNGER_CFG_V1", out value)).GetValueOrDefault() && value is string s)
		{
			Synced = UnpackCfg(s);
		}
	}

	private void OnHostConfigChanged()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			PublishConfig();
		}
	}

	private void PublishConfig()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		Room currentRoom = PhotonNetwork.CurrentRoom;
		if (currentRoom != null)
		{
			Synced = BuildFromHostConfig();
			string text = PackCfg(Synced);
			Hashtable val = new Hashtable { [(object)"HIKERS_HUNGER_CFG_V1"] = text };
			currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			Debug.Log((object)"[HikersHunger] Host published config to room");
		}
	}

	private void OnGUI()
	{
		if (showCannibalSelectionGUI && PhotonNetwork.IsMasterClient)
		{
			DrawCannibalSelectionGUI();
		}
		if (IsLocalPlayerCannibal())
		{
			DrawActiveCannibalGUI();
		}
	}

	private void DrawCannibalSelectionGUI()
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Expected O, but got Unknown
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		List<Character> list = randomPlayerList;
		float num = 400f;
		float num2 = 30f;
		float num3 = 5f;
		float num4 = (float)list.Count * (num2 + num3) + 130f;
		float num5 = ((float)Screen.width - num) / 2f;
		float num6 = ((float)Screen.height - num4) / 2f;
		HandleMenuInput();
		GUI.color = new Color(0f, 0f, 0f, 0.8f);
		GUI.Box(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), "");
		GUI.color = Color.white;
		GUI.Box(new Rect(num5, num6, num, num4), "Select Cannibal");
		GUI.Label(new Rect(num5 + 10f, num6 + 20f, num - 20f, 30f), "Choose who will become the cannibal:", new GUIStyle(GUI.skin.label)
		{
			fontSize = 16,
			alignment = (TextAnchor)4
		});
		float num7 = num6 + 60f;
		foreach (Character item in list)
		{
			if (num7 + num2 > num6 + num4 - (num2 + num3 * 2f))
			{
				break;
			}
			Player owner = item.refs.view.Owner;
			string text = (((owner != null) ? owner.NickName : null) ?? "Unknown Player") + (item.data.dead ? " (dead)" : "");
			if (GUI.Button(new Rect(num5 + 20f, num7, num - 40f, num2), text))
			{
				if (cannibalViewID != -1)
				{
					StripPowersFromAllPlayers();
				}
				SelectCannibal(item, isInitialSelection: true);
				CloseGUI();
			}
			num7 += num2 + num3;
		}
		if (GUI.Button(new Rect(num5 + 20f, num6 + num4 - (num2 + num3 * 2f), num - 40f, num2), "Cancel (Random Selection)"))
		{
			CloseGUI();
			SelectRandomCannibal();
		}
	}

	private void DrawActiveCannibalGUI()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		float num = 240f;
		float num2 = 30f;
		float num3 = ((float)Screen.width - num) / 2f;
		float num4 = (float)Screen.height - num2 - 20f;
		GUI.color = new Color(0f, 0f, 0f, 0.5f);
		GUI.Box(new Rect(num3, num4, num, num2), "");
		GUI.color = Color.white;
		GUI.Label(new Rect(num3 + 10f, num4, num - 20f, 30f), "You are the Cannibal", new GUIStyle(GUI.skin.label)
		{
			fontSize = 16,
			alignment = (TextAnchor)4
		});
	}

	private void HandleMenuInput()
	{
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
	}

	private void CloseGUI()
	{
		showCannibalSelectionGUI = false;
		Cursor.lockState = (CursorLockMode)1;
		Cursor.visible = false;
	}

	private List<Character> GetValidCandidates(bool findDead = false)
	{
		List<Character> list = new List<Character>();
		foreach (Character allCharacter in Character.AllCharacters)
		{
			if (allCharacter.refs.view.Owner != null && !allCharacter.isBot && (findDead || !allCharacter.data.dead))
			{
				list.Add(allCharacter);
			}
		}
		int count = list.Count;
		for (int i = 0; i < count - 1; i++)
		{
			int num;
			for (num = i; num == i; num = Random.Range(i, count))
			{
			}
			Character value = list[i];
			list[i] = list[num];
			list[num] = value;
		}
		return list;
	}

	private void SelectCannibal(Character character, bool isInitialSelection = false)
	{
		if (!((Object)(object)character.refs.view == (Object)null))
		{
			int viewID = character.refs.view.ViewID;
			Player owner = character.refs.view.Owner;
			Debug.Log((object)("[HikersHunger] Cannibal selected: " + (((owner != null) ? owner.NickName : null) ?? "Unknown") + "."));
			((MonoBehaviour)this).StartCoroutine(DelayCannibalPowers(viewID));
		}
	}

	[IteratorStateMachine(typeof(<DelayCannibalPowers>d__74))]
	private IEnumerator DelayCannibalPowers(int viewID)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DelayCannibalPowers>d__74(0)
		{
			<>4__this = this,
			viewID = viewID
		};
	}

	[IteratorStateMachine(typeof(<SelectRandomCannibalAfterDelay>d__75))]
	private IEnumerator SelectRandomCannibalAfterDelay(float overrideTime = 0f)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SelectRandomCannibalAfterDelay>d__75(0)
		{
			<>4__this = this,
			overrideTime = overrideTime
		};
	}

	private void SelectRandomCannibal()
	{
		if (PhotonNetwork.IsMasterClient)
		{
			List<Character> validCandidates = GetValidCandidates();
			if (validCandidates.Count > 0)
			{
				int index = Random.Range(0, validCandidates.Count);
				SelectCannibal(validCandidates[index], isInitialSelection: true);
			}
		}
	}

	private void SelectNewCannibalAtCampfire()
	{
		if (Synced.constantCannibal)
		{
			Debug.Log((object)"[HikersHunger] Constant cannibal mode - keeping current cannibal");
			return;
		}
		if (cannibalViewID != -1)
		{
			Debug.Log((object)"[HikersHunger] Stripping powers from current cannibal before selecting new one");
			manager.SetRoomProperty("cannibalViewId", (object)(-1));
			StripPowersFromAllPlayers();
		}
		if (PhotonNetwork.IsMasterClient)
		{
			if (Synced.manualCannibalSelection)
			{
				((MonoBehaviour)this).StartCoroutine(SelectRandomCannibalAfterDelay(1f));
			}
			else
			{
				SelectRandomCannibal();
			}
		}
	}
}
namespace HikersHunger
{
	public class CannibalSyncer : MonoBehaviourPunCallbacks
	{
		[CompilerGenerated]
		private sealed class <SyncLoop>d__4 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public CannibalSyncer <>4__this;

			private float <elapsed>5__1;

			private float <delay>5__2;

			private WaitForSeconds <waitTime>5__3;

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

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

			[DebuggerHidden]
			public <SyncLoop>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_0097;
				}
				<>1__state = -1;
				if (!PhotonNetwork.IsMasterClient)
				{
					return false;
				}
				<waitTime>5__3 = new WaitForSeconds(0.5f);
				goto IL_0140;
				IL_0097:
				if (<elapsed>5__1 < <delay>5__2)
				{
					<elapsed>5__1 += 0.5f;
					<>2__current = <waitTime>5__3;
					<>1__state = 1;
					return true;
				}
				Debug.Log((object)"[HikersHunger] Room Variables Sync'd!");
				Debug.Log((object)$"[HikersHunger] Cannibal ID: {HikersHungerPlugin.Instance.cannibalViewID}   |   Localplayer ID: {Character.localCharacter.refs.view.ViewID}");
				HikersHungerPlugin.Instance.manager.SetRoomProperty("cannibalViewId", (object)HikersHungerPlugin.Instance.cannibalViewID);
				<>4__this.photonView.RPC("RPC_SyncCannibal", (RpcTarget)0, new object[1] { HikersHungerPlugin.Instance.cannibalViewID });
				goto IL_0140;
				IL_0140:
				<elapsed>5__1 = 0f;
				<delay>5__2 = HikersHungerPlugin.Instance.hostSyncFrequency.Value;
				goto IL_0097;
			}

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

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

		public static CannibalSyncer instance;

		internal PhotonView photonView;

		private void Awake()
		{
			instance = this;
			photonView = ((Component)this).GetComponent<PhotonView>();
			Debug.Log((object)"[HikersHunger] Added CannibalSyncer component to GameUtils.");
		}

		[PunRPC]
		private void RPC_SyncCannibal(int cannibal)
		{
			HikersHungerPlugin.Instance.cannibalViewID = cannibal;
		}

		[IteratorStateMachine(typeof(<SyncLoop>d__4))]
		public IEnumerator SyncLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SyncLoop>d__4(0)
			{
				<>4__this = this
			};
		}
	}
	public class SafetyModule : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <SafeZoneMonitoringLoop>d__8 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SafetyModule <>4__this;

			private WaitForSeconds <waitCache>5__1;

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

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

			[DebuggerHidden]
			public <SafeZoneMonitoringLoop>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<waitCache>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<waitCache>5__1 = new WaitForSeconds(1f);
					break;
				case 1:
					<>1__state = -1;
					<>4__this.CheckSafeZoneStatus();
					break;
				}
				<>2__current = <waitCache>5__1;
				<>1__state = 1;
				return true;
			}

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

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

		public static SafetyModule instance;

		public PhotonView photonView;

		public float safeTime = 0f;

		private Coroutine safeZoneCheckCoroutine;

		public HikersHungerPlugin parentPlugin;

		public Character character;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			instance = this;
			photonView = ((Component)this).GetComponent<PhotonView>();
			character = ((Component)this).GetComponent<Character>();
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "Airport")
			{
				StartSafeZoneMonitoring();
				Debug.Log((object)("[HikersHunger][SafetyModule] Added SafetyModule component to " + photonView.Owner.NickName));
			}
		}

		private void StartSafeZoneMonitoring()
		{
			if (safeZoneCheckCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(safeZoneCheckCoroutine);
				safeZoneCheckCoroutine = null;
			}
			safeZoneCheckCoroutine = ((MonoBehaviour)this).StartCoroutine(SafeZoneMonitoringLoop());
		}

		[IteratorStateMachine(typeof(<SafeZoneMonitoringLoop>d__8))]
		private IEnumerator SafeZoneMonitoringLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SafeZoneMonitoringLoop>d__8(0)
			{
				<>4__this = this
			};
		}

		private void CheckSafeZoneStatus()
		{
			try
			{
				if (parentPlugin.IsCharacterNearCampfire(character))
				{
					safeTime = Time.time + HikersHungerPlugin.Synced.safeZoneDelay;
				}
			}
			catch (Exception)
			{
			}
		}

		private void OnDestroy()
		{
			if (safeZoneCheckCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(safeZoneCheckCoroutine);
				safeZoneCheckCoroutine = null;
			}
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HikersHunger";

		public const string PLUGIN_NAME = "HikersHunger";

		public const string PLUGIN_VERSION = "2.0.1";
	}
}