Decompiled source of FearMe v0.2.0

plugins/FearMe.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using SimpleJson;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("FearMe")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FearMe")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
namespace FearMe
{
	internal static class ItemData
	{
		public enum BiomeItemLevel
		{
			None,
			Starter,
			Meadows,
			BlackForest,
			Swamp,
			Mountain,
			Plains,
			Mistlands,
			Ashlands
		}

		private static IDictionary<string, int> _itemLevels;

		public static IDictionary<string, int> ItemLevels
		{
			get
			{
				if (_itemLevels == null)
				{
					return _itemLevels = GetDefaults();
				}
				return _itemLevels;
			}
			set
			{
				_itemLevels = value;
			}
		}

		private static IDictionary<string, int> GetDefaults()
		{
			return new Dictionary<string, int>
			{
				{ "$item_helmet_midsummercrown", 1 },
				{ "$item_helmet_yule", 1 },
				{ "$item_helmet_dverger", 1 },
				{ "$item_helmet_odin", 1 },
				{ "$item_helmet_leather", 2 },
				{ "$item_helmet_trollleather", 3 },
				{ "$item_helmet_bronze", 3 },
				{ "$item_helmet_iron", 4 },
				{ "$item_helmet_root", 4 },
				{ "$item_helmet_fenris", 5 },
				{ "$item_helmet_drake", 5 },
				{ "$item_helmet_padded", 6 },
				{ "$item_helmet_mage", 7 },
				{ "$item_helmet_carapace", 7 },
				{ "$item_helmet_mage_ashlands", 8 },
				{ "$item_helmet_flametal", 8 },
				{ "$item_helmet_medium_ashlands", 8 },
				{ "$item_chest_rags", 1 },
				{ "$item_chest_leather", 2 },
				{ "$item_chest_trollleather", 3 },
				{ "$item_chest_bronze", 3 },
				{ "$item_chest_root", 4 },
				{ "$item_chest_iron", 4 },
				{ "$item_chest_fenris", 5 },
				{ "$item_chest_wolf", 5 },
				{ "$item_chest_pcuirass", 6 },
				{ "$item_chest_carapace", 7 },
				{ "$item_chest_mage", 7 },
				{ "$item_chest_flametal", 8 },
				{ "$item_chest_mage_ashlands", 8 },
				{ "$item_chest_medium_ashlands", 8 },
				{ "$item_cape_odin", 1 },
				{ "$item_cape_deerhide", 2 },
				{ "$item_cape_trollhide", 3 },
				{ "$item_cape_wolf", 5 },
				{ "$item_cape_lox", 6 },
				{ "$item_cape_linen", 6 },
				{ "$item_cape_feather", 7 },
				{ "$item_cape_ash", 8 },
				{ "$item_cape_asksvin", 8 },
				{ "$item_legs_rags", 1 },
				{ "$item_legs_leather", 2 },
				{ "$item_legs_bronze", 3 },
				{ "$item_legs_trollleather", 3 },
				{ "$item_legs_iron", 4 },
				{ "$item_legs_root", 4 },
				{ "$item_legs_fenris", 5 },
				{ "$item_legs_wolf", 5 },
				{ "$item_legs_pgreaves", 6 },
				{ "$item_legs_carapace", 7 },
				{ "$item_legs_mage", 7 },
				{ "$item_legs_flametal", 8 },
				{ "$item_legs_mage_ashlands", 8 },
				{ "$item_legs_medium_ashlands", 8 }
			};
		}
	}
	[BepInPlugin("tulivu.valheimmods.fearme", "FearMe", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	internal class Main : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "tulivu.valheimmods.fearme";

		public const string PLUGIN_NAME = "FearMe";

		public const string PLUGIN_VERSION = "0.2.0";

		private static bool _loaded;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<string> _itemLevels;

		private static ConfigEntry<string> _monstersBravery;

		private const string GENERAL_SECTION = "General";

		private const string DATA_SECTION = "Data";

		public static bool Enabled
		{
			get
			{
				if (_loaded && _enabled != null)
				{
					return _enabled.Value;
				}
				return false;
			}
		}

		private void Awake()
		{
			try
			{
				Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "tulivu.valheimmods.fearme");
				LoadConfig();
				RegisterRPCs();
				_loaded = true;
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during Main.Awake:");
			}
		}

		private void OnDestroy()
		{
			try
			{
				_loaded = false;
				UnloadConfig();
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during Main.OnDestroy:");
			}
		}

		private void LoadConfig()
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			_enabled = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "General", "Enabled", true, "Enable this mod", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			_enabled.SettingChanged += Enabled_SettingChanged;
			ConfigFile config = ((BaseUnityPlugin)this).Config;
			Action<ConfigEntryBase> action = SimpleDictionaryDrawer;
			_monstersBravery = ConfigFileExtensions.BindConfig<string>(config, "Data", "MonsterBravery", (string)null, "Bravery levels, correlated to the biomes the monsters are in, with some tweaks for flavor.\r\n\t2 - Meadows\r\n\t3 - Black Forest\r\n\t4 - Swamp\r\n\t5 - Mountain\r\n\t6 - Plains\r\n\t7 - Mistlands\r\n\t8 - Ashlands", true, (int?)null, (AcceptableValueBase)null, action, (ConfigurationManagerAttributes)null);
			_monstersBravery.SettingChanged += MonstersBravery_SettingChanged;
			MonstersBravery_SettingChanged(_monstersBravery.Value, first: true);
			ConfigFile config2 = ((BaseUnityPlugin)this).Config;
			action = SimpleDictionaryDrawer;
			_itemLevels = ConfigFileExtensions.BindConfig<string>(config2, "Data", "ItemLevels", (string)null, "Armor levels, based on the biomes they come from.\r\n\t0 - Naked\r\n\t1 - Starter (Rags)\r\n\t2 - Meadows (Leather)\r\n\t3 - BlackForest (Bronze/Troll)\r\n\t4 - Swamp (Iron/Root)\r\n\t5 - Mountain (Wolf/Fenris)\r\n\t6 - Plains (Padded)\r\n\t7 - Mistlands (Carapace/Mage)\r\n\t8 - Ashlands (Flametal/Ashlands Mage)", true, (int?)null, (AcceptableValueBase)null, action, (ConfigurationManagerAttributes)null);
			_itemLevels.SettingChanged += ItemLevels_SettingChanged;
			ItemLevels_SettingChanged(_itemLevels.Value, first: true);
			new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L);
		}

		private static void SimpleDictionaryDrawer(ConfigEntryBase entry)
		{
			try
			{
				GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label("Use -1 to ignore", Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				IDictionary<string, int> dictionary = SimpleJson.DeserializeObject<IDictionary<string, int>>((string)entry.BoxedValue);
				Dictionary<string, int> dictionary2 = new Dictionary<string, int>(dictionary);
				foreach (KeyValuePair<string, int> item in dictionary)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(item.Key, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
					if (int.TryParse(GUILayout.TextField(item.Value.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(50f),
						GUILayout.MaxWidth(50f)
					}), out var result) && result != item.Value)
					{
						dictionary2[item.Key] = result;
						entry.BoxedValue = SimpleJson.SerializeObject((object)dictionary2);
					}
					GUILayout.EndHorizontal();
				}
				GUI.changed = false;
				GUILayout.EndVertical();
				GUILayout.FlexibleSpace();
			}
			catch (Exception e)
			{
				Utils.LogException(e, $"Exception during {new Action<ConfigEntryBase>(SimpleDictionaryDrawer)}");
			}
		}

		private void Enabled_SettingChanged(object sender, EventArgs e)
		{
			PlayerExtensions.ClearPlayerItemLevels();
		}

		private void ItemLevels_SettingChanged(object sender, EventArgs e)
		{
			EventArgs obj = ((e is SettingChangedEventArgs) ? e : null);
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				ConfigEntryBase changedSetting = ((SettingChangedEventArgs)obj).ChangedSetting;
				obj2 = ((changedSetting != null) ? changedSetting.BoxedValue : null);
			}
			string itemLevelsJson = obj2 as string;
			ItemLevels_SettingChanged(itemLevelsJson);
		}

		private void ItemLevels_SettingChanged(string itemLevelsJson, bool first = false)
		{
			try
			{
				IDictionary<string, int> dictionary = null;
				if (!string.IsNullOrWhiteSpace(itemLevelsJson))
				{
					dictionary = SimpleJson.DeserializeObject<IDictionary<string, int>>(itemLevelsJson);
				}
				if (dictionary == null || !dictionary.Any())
				{
					ItemData.ItemLevels = null;
					_itemLevels.Value = SimpleJson.SerializeObject((object)ItemData.ItemLevels);
				}
				else
				{
					ItemData.ItemLevels = dictionary;
				}
			}
			catch (Exception)
			{
				if (first)
				{
					ItemData.ItemLevels = null;
					_itemLevels.Value = SimpleJson.SerializeObject((object)ItemData.ItemLevels);
				}
			}
		}

		private void MonstersBravery_SettingChanged(object sender, EventArgs e)
		{
			EventArgs obj = ((e is SettingChangedEventArgs) ? e : null);
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				ConfigEntryBase changedSetting = ((SettingChangedEventArgs)obj).ChangedSetting;
				obj2 = ((changedSetting != null) ? changedSetting.BoxedValue : null);
			}
			string monstersBraveryJson = obj2 as string;
			MonstersBravery_SettingChanged(monstersBraveryJson);
		}

		private void MonstersBravery_SettingChanged(string monstersBraveryJson, bool first = false)
		{
			try
			{
				IDictionary<string, int> dictionary = null;
				if (!string.IsNullOrWhiteSpace(monstersBraveryJson))
				{
					dictionary = SimpleJson.DeserializeObject<IDictionary<string, int>>(monstersBraveryJson);
				}
				if (dictionary == null || !dictionary.Any())
				{
					MonsterData.MonsterBravery = null;
					_monstersBravery.Value = SimpleJson.SerializeObject((object)MonsterData.MonsterBravery);
				}
				else
				{
					MonsterData.MonsterBravery = dictionary;
				}
			}
			catch (Exception)
			{
				if (first)
				{
					MonsterData.MonsterBravery = null;
					_monstersBravery.Value = SimpleJson.SerializeObject((object)MonsterData.MonsterBravery);
				}
			}
		}

		private void UnloadConfig()
		{
			if (_enabled != null)
			{
				_enabled.SettingChanged -= Enabled_SettingChanged;
				_enabled = null;
			}
			if (_itemLevels != null)
			{
				_itemLevels.SettingChanged -= ItemLevels_SettingChanged;
				_itemLevels = null;
			}
			if (_monstersBravery != null)
			{
				_monstersBravery.SettingChanged -= MonstersBravery_SettingChanged;
				_monstersBravery = null;
			}
		}

		private void RegisterRPCs()
		{
			PlayerExtensions.RegisterRPCs();
		}
	}
	internal static class MonsterData
	{
		private static IDictionary<string, int> _monsterBravery;

		public static IDictionary<string, int> MonsterBravery
		{
			get
			{
				if (_monsterBravery == null)
				{
					return _monsterBravery = GetDefaults();
				}
				return _monsterBravery;
			}
			set
			{
				_monsterBravery = value;
			}
		}

		private static IDictionary<string, int> GetDefaults()
		{
			return new Dictionary<string, int>
			{
				{ "$enemy_neck", 2 },
				{ "$enemy_boar", 2 },
				{ "$enemy_greyling", 2 },
				{ "$enemy_ghost", 5 },
				{ "$enemy_greydwarf", 3 },
				{ "$enemy_greydwarfbrute", 4 },
				{ "$enemy_greydwarfshaman", 4 },
				{ "$enemy_skeletonpoison", 4 },
				{ "$enemy_troll", 6 },
				{ "$enemy_abomination", 6 },
				{ "$enemy_blob", 4 },
				{ "$enemy_blobelite", 5 },
				{ "$enemy_draugr", 4 },
				{ "$enemy_draugrelite", 5 },
				{ "$enemy_leech", 4 },
				{ "$enemy_skeleton", 4 },
				{ "$enemy_surtling", 4 },
				{ "$enemy_wraith", 5 },
				{ "$enemy_bat", 5 },
				{ "$enemy_dragon", 5 },
				{ "$enemy_drake", 5 },
				{ "$enemy_fenring", 6 },
				{ "$enemy_fenringcultist", 6 },
				{ "$enemy_stonegolem", 7 },
				{ "$enemy_ulv", 5 },
				{ "$enemy_wolf", 6 },
				{ "$enemy_blobtar", 6 },
				{ "$enemy_deathsquito", 7 },
				{ "$enemy_goblin", 6 },
				{ "$enemy_goblinbrute", 8 },
				{ "$enemy_goblinshaman", 6 },
				{ "$enemy_lox", 9 },
				{ "$enemy_babyseeker", 6 },
				{ "$enemy_gjall", 9 },
				{ "$enemy_seeker", 7 },
				{ "$enemy_seekerbrute", 8 },
				{ "$enemy_tick", 7 },
				{ "$enemy_asksvin", 8 },
				{ "$enemy_bloblava", 8 },
				{ "$enemy_charred", 8 },
				{ "$enemy_charred_archer", 8 },
				{ "$enemy_charred_grunt", 8 },
				{ "$enemy_charred_mage", 8 },
				{ "$enemy_charred_melee", 8 },
				{ "$enemy_charred_melee_Dyrnwyn", 8 },
				{ "$enemy_charred_melee_Fader", 8 },
				{ "$enemy_charred_twitcher", 8 },
				{ "$enemy_charred_twitcher_summoned", 8 },
				{ "$enemy_fallenvalkyrie", 9 },
				{ "$enemy_morgen", 8 },
				{ "$enemy_volture", 8 }
			};
		}
	}
	public enum FearLevel
	{
		NotAfraid,
		Cautious,
		Afraid
	}
	public static class MonsterExtensions
	{
		public static FearLevel GetFearLevel(this BaseAI ai, Character targetCreature, bool checkAlerted)
		{
			try
			{
				if (!Main.Enabled)
				{
					return FearLevel.NotAfraid;
				}
				if (!((Object)(object)targetCreature == (Object)null))
				{
					Player val = (Player)(object)((targetCreature is Player) ? targetCreature : null);
					if (val != null)
					{
						if (!((Object)(object)ai == (Object)null))
						{
							MonsterAI val2 = (MonsterAI)(object)((ai is MonsterAI) ? ai : null);
							if (val2 != null)
							{
								if (checkAlerted && !ai.IsAlerted())
								{
									return FearLevel.NotAfraid;
								}
								if (val2.IsEventCreature())
								{
									return FearLevel.NotAfraid;
								}
								if ((Object)(object)ai.m_character == (Object)null || ai.m_character.m_name == null)
								{
									return FearLevel.NotAfraid;
								}
								Character character = ai.m_character;
								if (character.IsTamed() || character.IsBoss())
								{
									return FearLevel.NotAfraid;
								}
								int monsterBravery = character.GetMonsterBravery();
								if (monsterBravery <= 0)
								{
									return FearLevel.NotAfraid;
								}
								int playerItemLevel = val.GetPlayerItemLevel();
								if (playerItemLevel <= 0)
								{
									return FearLevel.NotAfraid;
								}
								return (playerItemLevel > monsterBravery) ? ((playerItemLevel < monsterBravery + 2) ? FearLevel.Cautious : FearLevel.Afraid) : FearLevel.NotAfraid;
							}
						}
						return FearLevel.NotAfraid;
					}
				}
				return FearLevel.NotAfraid;
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during GetFearLevel:");
				return FearLevel.NotAfraid;
			}
		}

		private static int GetMonsterBravery(this Character character)
		{
			try
			{
				int value;
				return MonsterData.MonsterBravery.TryGetValue(character.m_name, out value) ? (value + (character.GetLevel() - 1)) : (-1);
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during GetMonsterBravery:");
				return -1;
			}
		}
	}
	public static class PlayerExtensions
	{
		[CompilerGenerated]
		private sealed class <OnClientReceive_AllPlayersItemLevelsRPC>d__15 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZPackage package;

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

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

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

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

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				try
				{
					if (package != null && package.Size() > 0)
					{
						int num = package.ReadInt();
						for (int i = 0; i < num; i++)
						{
							long playerId = package.ReadLong();
							int playerItemLevel = package.ReadInt();
							SetPlayerItemLevel(playerId, playerItemLevel);
						}
					}
				}
				catch (Exception e)
				{
					Utils.LogException(e, "Exception during OnClientReceive_PlayerItemLevelRPC:");
				}
				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 <OnClientReceive_PlayerItemLevelRPC>d__12 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				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 <OnServerReceive_AllPlayersItemLevelsRPC>d__14 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				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 <OnServerReceive_PlayerItemLevelRPC>d__11 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZPackage package;

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

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

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

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

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				try
				{
					if (package != null && package.Size() > 0)
					{
						long playerId = package.ReadLong();
						int playerItemLevel = package.ReadInt();
						SetPlayerItemLevel(playerId, playerItemLevel);
						hasPlayerItemLevelsChanges = true;
					}
				}
				catch (Exception e)
				{
					Utils.LogException(e, "Exception during OnServerReceive_PlayerItemLevelRPC:");
				}
				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();
			}
		}

		private static IDictionary<long, int> _playersItemLevels = new Dictionary<long, int>();

		private static CustomRPC _playerItemLevelRPC;

		private static CustomRPC _allPlayersItemLevelsRPC;

		private static bool hasPlayerItemLevelsChanges = false;

		private static int playerItemLevelsBroadcastsSkipped = 0;

		public static void ClearPlayerItemLevels()
		{
			_playersItemLevels.Clear();
		}

		public static int GetPlayerItemLevel(this Player player)
		{
			try
			{
				if (!Main.Enabled)
				{
					return 0;
				}
				int value = 0;
				long playerID = player.GetPlayerID();
				if (playerID != 0L && !_playersItemLevels.TryGetValue(playerID, out value))
				{
					value = UpdatePlayerItemLevel(playerID, player);
				}
				return value;
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during GetPlayerItemLevel:");
				return 0;
			}
		}

		private static void SetPlayerItemLevel(long playerId, int playerItemLevel)
		{
			_playersItemLevels[playerId] = playerItemLevel;
		}

		public static void UpdatePlayerItemLevel(this Player player)
		{
			try
			{
				if (Main.Enabled)
				{
					UpdatePlayerItemLevel(player.GetPlayerID(), player);
				}
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during UpdatePlayerItemLevel:");
			}
		}

		private static int UpdatePlayerItemLevel(long playerId, Player player)
		{
			int num = 0;
			if (playerId != 0L)
			{
				(int itemLevelSum, int qualitySum, int numItems) tuple = player.SumEquipment();
				int item = tuple.itemLevelSum;
				int item2 = tuple.qualitySum;
				int item3 = tuple.numItems;
				num = CalculateItemLevel(item, item2, item3);
				if (!_playersItemLevels.TryGetValue(playerId, out var value) || value != num)
				{
					SetPlayerItemLevel(playerId, num);
					SendPlayerItemLevel(playerId, num);
				}
			}
			return num;
		}

		private static (int itemLevelSum, int qualitySum, int numItems) SumEquipment(this Player player)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int value;
			if (((Humanoid)player).m_helmetItem != null)
			{
				if (ItemData.ItemLevels.TryGetValue(((Humanoid)player).m_helmetItem.m_shared.m_name, out value) && value >= 0)
				{
					num += value;
					num2 += ((Humanoid)player).m_helmetItem.m_quality;
					num3++;
				}
			}
			else
			{
				num3++;
			}
			if (((Humanoid)player).m_chestItem != null)
			{
				if (ItemData.ItemLevels.TryGetValue(((Humanoid)player).m_chestItem.m_shared.m_name, out value) && value >= 0)
				{
					num += value;
					num2 += ((Humanoid)player).m_chestItem.m_quality;
					num3++;
				}
			}
			else
			{
				num3++;
			}
			if (((Humanoid)player).m_legItem != null)
			{
				if (ItemData.ItemLevels.TryGetValue(((Humanoid)player).m_legItem.m_shared.m_name, out value) && value >= 0)
				{
					num += value;
					num2 += ((Humanoid)player).m_legItem.m_quality;
					num3++;
				}
			}
			else
			{
				num3++;
			}
			return (num, num2, num3);
		}

		private static int CalculateItemLevel(int itemLevelSum, int qualitySum, int numItems)
		{
			int result = -1;
			if (numItems > 0)
			{
				result = (3 * itemLevelSum + qualitySum - (numItems - 1)) / (3 * numItems);
			}
			return result;
		}

		public static void RegisterRPCs()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0027: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0053: Expected O, but got Unknown
			_playerItemLevelRPC = NetworkManager.Instance.AddRPC("RPC_PlayerItemLevel", new CoroutineHandler(OnServerReceive_PlayerItemLevelRPC), new CoroutineHandler(OnClientReceive_PlayerItemLevelRPC));
			_allPlayersItemLevelsRPC = NetworkManager.Instance.AddRPC("RPC_AllPlayersItemLevels", new CoroutineHandler(OnServerReceive_AllPlayersItemLevelsRPC), new CoroutineHandler(OnClientReceive_AllPlayersItemLevelsRPC));
		}

		[IteratorStateMachine(typeof(<OnServerReceive_PlayerItemLevelRPC>d__11))]
		private static IEnumerator OnServerReceive_PlayerItemLevelRPC(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnServerReceive_PlayerItemLevelRPC>d__11(0)
			{
				package = package
			};
		}

		[IteratorStateMachine(typeof(<OnClientReceive_PlayerItemLevelRPC>d__12))]
		private static IEnumerator OnClientReceive_PlayerItemLevelRPC(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnClientReceive_PlayerItemLevelRPC>d__12(0);
		}

		private static void SendPlayerItemLevel(long playerId, int playerItemLevel)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (!((Object)(object)ZNet.instance == (Object)null))
			{
				ZPackage val = new ZPackage();
				val.Write(playerId);
				val.Write(playerItemLevel);
				_playerItemLevelRPC.SendPackage(ZRoutedRpc.Everybody, val);
			}
		}

		[IteratorStateMachine(typeof(<OnServerReceive_AllPlayersItemLevelsRPC>d__14))]
		private static IEnumerator OnServerReceive_AllPlayersItemLevelsRPC(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnServerReceive_AllPlayersItemLevelsRPC>d__14(0);
		}

		[IteratorStateMachine(typeof(<OnClientReceive_AllPlayersItemLevelsRPC>d__15))]
		private static IEnumerator OnClientReceive_AllPlayersItemLevelsRPC(long sender, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnClientReceive_AllPlayersItemLevelsRPC>d__15(0)
			{
				package = package
			};
		}

		public static void BroadcastPlayerItemLevels()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			try
			{
				if (!Main.Enabled || !_playersItemLevels.Any() || (Object)(object)ZNet.instance == (Object)null)
				{
					return;
				}
				if (!hasPlayerItemLevelsChanges && playerItemLevelsBroadcastsSkipped < 10)
				{
					playerItemLevelsBroadcastsSkipped++;
					return;
				}
				ZPackage val = new ZPackage();
				val.Write(_playersItemLevels.Count);
				foreach (KeyValuePair<long, int> playersItemLevel in _playersItemLevels)
				{
					val.Write(playersItemLevel.Key);
					val.Write(playersItemLevel.Value);
				}
				_allPlayersItemLevelsRPC.SendPackage(ZRoutedRpc.Everybody, val);
				hasPlayerItemLevelsChanges = false;
				playerItemLevelsBroadcastsSkipped = 0;
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during BroadcastPlayerItemLevels:");
			}
		}
	}
	public static class Utils
	{
		public static void LogException(Exception e, string note = null)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (!string.IsNullOrWhiteSpace(note))
			{
				stringBuilder.AppendLine(note);
			}
			for (Exception ex = e; ex != null; ex = ex.InnerException)
			{
				if (!string.IsNullOrWhiteSpace(note))
				{
					stringBuilder.Append("\t");
				}
				stringBuilder.AppendLine(ex.Message ?? string.Empty);
			}
			Logger.LogError((object)stringBuilder.ToString());
		}
	}
}
namespace FearMe.Patches
{
	[HarmonyPatch(typeof(ZNet), "SendPlayerList")]
	public static class ZNet_SendPlayerList_Patch
	{
		public static void Postfix(ZNet __instance)
		{
			try
			{
				if (Main.Enabled)
				{
					PlayerExtensions.BroadcastPlayerItemLevels();
				}
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during ZNet_SendPlayerList_Patch: ");
			}
		}
	}
}
namespace FearMe.Patches.Equip
{
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	public static class Humanoid_EquipItem_Patch
	{
		public static void Postfix(bool __result, Humanoid __instance)
		{
			try
			{
				if (Main.Enabled && __result)
				{
					((Player)(object)((__instance is Player) ? __instance : null))?.UpdatePlayerItemLevel();
				}
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during Humanoid_EquipItem_Patch:");
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
	public static class Humanoid_UnequipItem_Patch
	{
		public static void Postfix(Humanoid __instance)
		{
			try
			{
				if (Main.Enabled)
				{
					((Player)(object)((__instance is Player) ? __instance : null))?.UpdatePlayerItemLevel();
				}
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during Humanoid_UnequipItem_Patch:");
			}
		}
	}
}
namespace FearMe.Patches.AI
{
	[HarmonyPatch(typeof(BaseAI), "FindEnemy")]
	public static class BaseAI_FindEnemy_Patch
	{
		public static void Postfix(ref Character __result, BaseAI __instance)
		{
			try
			{
				if (Main.Enabled && (Object)(object)((__instance is MonsterAI) ? __instance : null) != (Object)null && __instance.GetFearLevel(__result, checkAlerted: false) == FearLevel.Cautious)
				{
					__result = null;
				}
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during BaseAI_FindEnemy_Patch: ");
			}
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class MonsterAI_UpdateAI_Patch
	{
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, generator).MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch(new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(MonsterAI), "m_fleeIfHurtWhenTargetCantBeReached")), (string)null)
			}).ThrowIfInvalid("Could not find location of m_fleeIfHurtWhenTargetCantBeReached in MonsterAI.UpdateAI to patch");
			List<Label> labels = val.Labels;
			val.Labels = new List<Label>();
			Label label = default(Label);
			val.CreateLabel(ref label);
			val.Insert((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
			}).AddLabels((IEnumerable<Label>)labels).Advance(1)
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_1, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(MonsterAI_UpdateAI_Patch), "RunAway", (Type[])null, (Type[])null))
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brfalse, (object)label)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldc_I4_1, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ret, (object)null)
				});
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(BaseAI), "SetAlerted", (Type[])null, (Type[])null), (string)null)
			}).Advance(3).ThrowIfInvalid("Could not find location of SetAlerted in MonsterAI.UpdateAI to patch");
			Label label2 = default(Label);
			val.CreateLabel(ref label2);
			val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_1, (object)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(MonsterAI_UpdateAI_Patch), "RunAway", (Type[])null, (Type[])null))
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Brfalse, (object)label2)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldc_I4_1, (object)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ret, (object)null)
				});
			return val.Instructions();
		}

		private static bool RunAway(this MonsterAI ai, float dt)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!Main.Enabled)
				{
					return false;
				}
				bool result = false;
				Character targetCreature = ((BaseAI)ai).GetTargetCreature();
				if (((BaseAI)(object)ai).GetFearLevel(targetCreature, checkAlerted: true) == FearLevel.Afraid)
				{
					result = true;
					((BaseAI)ai).Flee(dt, ((Component)targetCreature).transform.position);
					ai.m_updateTargetTimer = 5f;
				}
				return result;
			}
			catch (Exception e)
			{
				Utils.LogException(e, "Exception during MonsterAI_UpdateAI_Patch: ");
				return false;
			}
		}
	}
}