Decompiled source of RPGStatusEffects v1.0.2

plugins/RpgStatusEffects.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RpgStatusEffects")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RpgStatusEffects")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f0207a1b-c30c-4443-9d71-04c8e6c57b88")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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;
		}
	}
}
namespace RPGStatusEffects
{
	[BepInPlugin("com.Fire.rpgstatuseffects", "RPGStatusEffects", "1.0.1")]
	public class RPGStatusEffects : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static class ObjectDB_Awake_Path
		{
			public static void Postfix()
			{
				if (IsObjectDBValid())
				{
					AddItems(itemPrefabs);
					Instance.SetupStatusEffects();
					RecipeManager.SetupRecipe();
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		public static class Object_CopyOtherDB_Path
		{
			public static void Postfix()
			{
				if (!IsObjectDBValid())
				{
					if (Instance.configVerboseLogging.Value)
					{
						Debug.LogWarning((object)"RPGStatusEffects: ObjectDB not valid in CopyOtherDB, skipping item addition.");
					}
				}
				else
				{
					AddItems(itemPrefabs);
					Instance.SetupStatusEffects();
				}
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		public static class ZNetScene_Awake_Path
		{
			public static void Prefix(ZNetScene __instance)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					if (Instance.configVerboseLogging.Value)
					{
						Debug.LogWarning((object)"RPGStatusEffects: No ZNetScene found");
					}
				}
				else
				{
					AddPrefabsToZNetScene(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
		public static class TauntAIUpdatePatch
		{
			private static readonly MethodInfo setAlertedMethod = typeof(MonsterAI).GetMethod("SetAlerted", BindingFlags.Instance | BindingFlags.NonPublic);

			public static void Postfix(MonsterAI __instance, float dt)
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				Character component = ((Component)__instance).GetComponent<Character>();
				if ((Object)(object)component == (Object)null || component.IsPlayer())
				{
					return;
				}
				SEMan sEMan = component.GetSEMan();
				if (sEMan == null)
				{
					return;
				}
				int stableHashCode = StringExtensionMethods.GetStableHashCode("Taunted");
				TauntEffect tauntEffect = sEMan.GetStatusEffect(stableHashCode) as TauntEffect;
				if ((Object)(object)tauntEffect != (Object)null && (Object)(object)tauntEffect.Taunter != (Object)null && ((StatusEffect)tauntEffect).m_ttl > 0f)
				{
					typeof(MonsterAI).GetField("m_targetCreature", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, tauntEffect.Taunter);
					FieldInfo field = typeof(MonsterAI).GetField("m_fleeIfHurtWhenTargetCantBeReached", BindingFlags.Instance | BindingFlags.NonPublic);
					FieldInfo field2 = typeof(MonsterAI).GetField("m_fleeIfLowHealth", BindingFlags.Instance | BindingFlags.NonPublic);
					FieldInfo field3 = typeof(MonsterAI).GetField("m_enableHuntPlayer", BindingFlags.Instance | BindingFlags.NonPublic);
					if (!originalHuntStates.ContainsKey(component))
					{
						bool flag = field != null && (bool)field.GetValue(__instance);
						float num = ((field2 != null) ? ((float)field2.GetValue(__instance)) : 0f);
						bool flag2 = field3 != null && (bool)field3.GetValue(__instance);
						originalHuntStates[component] = (flag, num > 0f, flag2);
						if (Instance.configVerboseLogging.Value)
						{
							Debug.Log((object)string.Format("{0}: Stored original states for {1}: fleeIfHurt={2}, fleeIfLowHealth={3}, enableHuntPlayer={4}.", "RPGStatusEffects", ((Object)component).name, flag, num > 0f, flag2));
							if (field != null)
							{
								Debug.Log((object)("RPGStatusEffects: Set fleeIfHurtWhenTargetCantBeReached=false for " + ((Object)component).name + " during taunt."));
							}
							if (field2 != null)
							{
								Debug.Log((object)("RPGStatusEffects: Set fleeIfLowHealth=0 for " + ((Object)component).name + " during taunt."));
							}
							if (field3 != null)
							{
								Debug.Log((object)("RPGStatusEffects: Set enableHuntPlayer=true for " + ((Object)component).name + " during taunt."));
							}
							if (setAlertedMethod != null)
							{
								Debug.Log((object)("RPGStatusEffects: Called SetAlerted(true) for " + ((Object)component).name + " during taunt."));
							}
							Debug.Log((object)string.Format("{0}: Taunt locked enemy {1} to player (remaining: {2:F1}s).", "RPGStatusEffects", ((Object)component).name, ((StatusEffect)tauntEffect).m_ttl));
						}
						lastTauntLogTimes[component] = ((StatusEffect)tauntEffect).m_ttl;
					}
					if (field != null)
					{
						field.SetValue(__instance, false);
					}
					if (field2 != null)
					{
						field2.SetValue(__instance, 0f);
					}
					if (field3 != null)
					{
						field3.SetValue(__instance, true);
					}
					if (setAlertedMethod != null)
					{
						setAlertedMethod.Invoke(__instance, new object[1] { true });
					}
				}
				else
				{
					if (!lastTauntLogTimes.Remove(component))
					{
						return;
					}
					if (originalHuntStates.TryGetValue(component, out (bool, bool, bool) value))
					{
						FieldInfo field4 = typeof(MonsterAI).GetField("m_fleeIfHurtWhenTargetCantBeReached", BindingFlags.Instance | BindingFlags.NonPublic);
						FieldInfo field5 = typeof(MonsterAI).GetField("m_fleeIfLowHealth", BindingFlags.Instance | BindingFlags.NonPublic);
						FieldInfo field6 = typeof(MonsterAI).GetField("m_enableHuntPlayer", BindingFlags.Instance | BindingFlags.NonPublic);
						if (field4 != null)
						{
							field4.SetValue(__instance, value.Item1);
							if (Instance.configVerboseLogging.Value)
							{
								Debug.Log((object)string.Format("{0}: Restored fleeIfHurtWhenTargetCantBeReached={1} for {2}.", "RPGStatusEffects", value.Item1, ((Object)component).name));
							}
						}
						if (field5 != null)
						{
							field5.SetValue(__instance, value.Item2 ? 0.2f : 0f);
							if (Instance.configVerboseLogging.Value)
							{
								Debug.Log((object)string.Format("{0}: Restored fleeIfLowHealth={1} for {2}.", "RPGStatusEffects", value.Item2 ? 0.2f : 0f, ((Object)component).name));
							}
						}
						if (field6 != null)
						{
							field6.SetValue(__instance, value.Item3);
							if (Instance.configVerboseLogging.Value)
							{
								Debug.Log((object)string.Format("{0}: Restored enableHuntPlayer={1} for {2}.", "RPGStatusEffects", value.Item3, ((Object)component).name));
							}
						}
						originalHuntStates.Remove(component);
					}
					if (Instance.configVerboseLogging.Value)
					{
						Debug.Log((object)("RPGStatusEffects: Taunt ended on " + ((Object)component).name + "."));
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		public static class SetTauntOnDamagePatch
		{
			public static void Prefix(Character __instance, ref HitData hit)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				if (hit == null || ((ZDOID)(ref hit.m_attacker)).IsNone() || __instance.IsPlayer() || hit.m_statusEffectHash != StringExtensionMethods.GetStableHashCode("Taunted"))
				{
					return;
				}
				GameObject obj = ZNetScene.instance.FindInstance(hit.m_attacker);
				Character val = ((obj != null) ? obj.GetComponent<Character>() : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				SEMan sEMan = __instance.GetSEMan();
				if (sEMan == null)
				{
					return;
				}
				TauntEffect tauntEffect = sEMan.GetStatusEffect(StringExtensionMethods.GetStableHashCode("Taunted")) as TauntEffect;
				if ((Object)(object)tauntEffect == (Object)null)
				{
					tauntEffect = sEMan.AddStatusEffect(StringExtensionMethods.GetStableHashCode("Taunted"), true, 0, 0f) as TauntEffect;
				}
				if (!((Object)(object)tauntEffect != (Object)null))
				{
					return;
				}
				tauntEffect.Taunter = val;
				if (Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)("RPGStatusEffects: Applied taunt from player to " + ((Object)__instance).name + "."));
				}
				if (!val.IsPlayer())
				{
					return;
				}
				SEMan sEMan2 = val.GetSEMan();
				TauntingEffect tauntingEffect = StatusEffectManager.GetEffect("Taunting") as TauntingEffect;
				if ((Object)(object)tauntingEffect != (Object)null)
				{
					tauntingEffect.Duration = tauntEffect.Duration;
					sEMan2.AddStatusEffect((StatusEffect)(object)tauntingEffect, true, 0, 0f);
					if (Instance.configVerboseLogging.Value)
					{
						Debug.Log((object)string.Format("{0}: Applied Taunting effect to player {1} for {2}s.", "RPGStatusEffects", ((Object)val).name, tauntingEffect.Duration));
					}
				}
			}
		}

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

			private object <>2__current;

			public RPGStatusEffects <>4__this;

			private int <maxAttempts>5__2;

			private int <attempts>5__3;

			private float <approximateTimeSpent>5__4;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Expected O, but got Unknown
				int num = <>1__state;
				RPGStatusEffects rPGStatusEffects = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Scene activeScene = SceneManager.GetActiveScene();
					if (((Scene)(ref activeScene)).name == "start")
					{
						if (rPGStatusEffects.configVerboseLogging.Value)
						{
							Debug.Log((object)"RPGStatusEffects: Main menu detected, skipping initialization.");
						}
						return false;
					}
					<maxAttempts>5__2 = 100;
					<attempts>5__3 = 0;
					<approximateTimeSpent>5__4 = 0f;
					break;
				}
				case 1:
					<>1__state = -1;
					<approximateTimeSpent>5__4 += 0.1f;
					break;
				}
				if (!IsObjectDBValid() || (Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.m_prefabs == null || ZNetScene.instance.m_prefabs.Count == 0)
				{
					if (rPGStatusEffects.configVerboseLogging.Value)
					{
						Debug.Log((object)string.Format("{0}: Waiting for ObjectDB and ZNetScene (attempt {1}/{2})...", "RPGStatusEffects", <attempts>5__3 + 1, <maxAttempts>5__2));
					}
					<attempts>5__3++;
					if (<approximateTimeSpent>5__4 >= 10f)
					{
						Debug.LogError((object)string.Format("{0}: ObjectDB and ZNetScene failed to initialize after {1} attempts.", "RPGStatusEffects", <maxAttempts>5__2));
						return false;
					}
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				rPGStatusEffects.ValidateConfigs();
				rPGStatusEffects.SetupStatusEffects();
				RecipeManager.SetupRecipe();
				rPGStatusEffects.isInitialized = true;
				if (rPGStatusEffects.configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Status effects and recipe initialized.");
				}
				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 RPGStatusEffects Instance;

		private readonly Harmony harmony = new Harmony("com.Fire.rpgstatuseffects");

		public const string PluginGUID = "com.Fire.rpgstatuseffects";

		public const string PluginName = "RPGStatusEffects";

		public const string PluginVersion = "1.0.1";

		public ConfigSync configSync;

		public SyncedConfigEntry<bool> configVerboseLogging;

		public SyncedConfigEntry<float> configPurityDuration;

		public SyncedConfigEntry<float> configTauntDuration;

		public SyncedConfigEntry<string> configTauntHammerRecipe;

		private bool isInitialized;

		private bool isShuttingDown;

		public static AssetBundle assetBundle;

		public static readonly List<GameObject> itemPrefabs = new List<GameObject>();

		public static readonly FieldInfo knownRecipesField = typeof(Player).GetField("m_knownRecipes", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly Dictionary<Character, float> lastTauntLogTimes = new Dictionary<Character, float>();

		private static readonly Dictionary<Character, (bool fleeIfHurt, bool fleeIfLowHealth, bool enableHuntPlayer)> originalHuntStates = new Dictionary<Character, (bool, bool, bool)>();

		private void Awake()
		{
			Instance = this;
			configSync = new ConfigSync("com.Fire.rpgstatuseffects")
			{
				DisplayName = "RPGStatusEffects",
				CurrentVersion = "1.0.1",
				MinimumRequiredVersion = "1.0.1"
			};
			configSync.lockedConfigChanged += delegate
			{
				if (!isShuttingDown && isInitialized && IsObjectDBValid())
				{
					ValidateConfigs();
					SetupStatusEffects();
					RecipeManager.SetupRecipe();
					if (configVerboseLogging.Value)
					{
						Debug.Log((object)"RPGStatusEffects: Config sync triggered status effect and recipe update.");
					}
				}
			};
			configVerboseLogging = configSync.AddConfigEntry<bool>(((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", false, "Enable detailed debug logs."));
			configPurityDuration = configSync.AddConfigEntry<float>(((BaseUnityPlugin)this).Config.Bind<float>("StatusEffects", "PurityDuration", 10f, "Duration of the Purity status effect in seconds."));
			configTauntDuration = configSync.AddConfigEntry<float>(((BaseUnityPlugin)this).Config.Bind<float>("StatusEffects", "TauntDuration", 15f, "Duration of the Taunt effect in seconds."));
			configTauntHammerRecipe = configSync.AddConfigEntry<string>(((BaseUnityPlugin)this).Config.Bind<string>("Item_Recipe_TauntHammer", "Recipe", "Wood,10,5,LeatherScraps,5,2,SwordCheat,1,0", "Recipe for TauntHammer_vad (format: ItemName,Amount,AmountPerLevel,...)"));
			ValidateConfigs();
			loadAssets();
			harmony.PatchAll();
			RegisterConsoleCommands();
			((MonoBehaviour)this).StartCoroutine(InitializeStatusEffects());
			if (configVerboseLogging.Value)
			{
				Debug.Log((object)"RPGStatusEffects: Initialized version 1.0.1.");
			}
		}

		private void loadAssets()
		{
			try
			{
				assetBundle = GetAssetBundleFromResources("verdantsascent");
				if ((Object)(object)assetBundle == (Object)null)
				{
					Debug.LogError((object)"RPGStatusEffects: Failed to load asset bundle!");
					return;
				}
				if (configVerboseLogging.Value)
				{
					string[] allAssetNames = assetBundle.GetAllAssetNames();
					Debug.Log((object)("RPGStatusEffects: Available assets in bundle: " + string.Join(", ", allAssetNames)));
				}
				LoadItems("Assets/Custom/VAitems/");
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("RPGStatusEffects: Error loading assets: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private AssetBundle GetAssetBundleFromResources(string filename)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = executingAssembly.GetManifestResourceNames().SingleOrDefault((string str) => str.EndsWith(filename, StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				Debug.LogError((object)("RPGStatusEffects: No resource found ending with " + filename + "."));
				return null;
			}
			if (configVerboseLogging.Value)
			{
				Debug.Log((object)("RPGStatusEffects: Loading asset bundle from resource: " + text));
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				Debug.LogError((object)("RPGStatusEffects: Failed to open stream for resource " + text + "."));
				return null;
			}
			return AssetBundle.LoadFromStream(stream);
		}

		private void LoadItems(string mainPath)
		{
			string[] obj = new string[1] { "TauntHammer_vad" };
			itemPrefabs.Clear();
			string[] array = obj;
			foreach (string text in array)
			{
				string text2 = mainPath + "items/" + text + ".prefab";
				AssetBundle obj2 = assetBundle;
				GameObject val = ((obj2 != null) ? obj2.LoadAsset<GameObject>(text2) : null);
				if ((Object)(object)val == (Object)null)
				{
					if (configVerboseLogging.Value)
					{
						Debug.LogWarning((object)("RPGStatusEffects: Could not find prefab: " + text2));
					}
					continue;
				}
				ItemDrop component = val.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null)
				{
					if (configVerboseLogging.Value)
					{
						Debug.LogError((object)("RPGStatusEffects: " + text + " - ItemDrop component missing!"));
					}
					continue;
				}
				val.SetActive(true);
				itemPrefabs.Add(val);
				if (configVerboseLogging.Value)
				{
					Debug.Log((object)("RPGStatusEffects: Loaded prefab: " + text + ", m_dropPrefab: " + (((Object)(object)component.m_itemData.m_dropPrefab != (Object)null) ? ((Object)component.m_itemData.m_dropPrefab).name : "null")));
				}
			}
		}

		public static void AddItems(List<GameObject> items)
		{
			try
			{
				foreach (GameObject item in items)
				{
					if ((Object)(object)item == (Object)null)
					{
						if (Instance.configVerboseLogging.Value)
						{
							Debug.LogWarning((object)"RPGStatusEffects: Null item in list, skipping.");
						}
					}
					else if ((Object)(object)item.GetComponent<ItemDrop>() != (Object)null)
					{
						if ((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)item).name) == (Object)null)
						{
							ObjectDB.instance.m_items.Add(item);
							((Dictionary<int, GameObject>)typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(ObjectDB.instance))[((Object)item).name.GetHashCode()] = item;
							if (Instance.configVerboseLogging.Value)
							{
								Debug.Log((object)("RPGStatusEffects: Added " + ((Object)item).name + " to ObjectDB.m_items"));
							}
						}
						else if (Instance.configVerboseLogging.Value)
						{
							Debug.LogWarning((object)("RPGStatusEffects: " + ((Object)item).name + " already exists in ObjectDB, skipping."));
						}
					}
					else if (Instance.configVerboseLogging.Value)
					{
						Debug.LogError((object)("RPGStatusEffects: " + ((Object)item).name + " - ItemDrop not found on prefab"));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("RPGStatusEffects: Error adding items to ObjectDB: " + ex.Message));
			}
		}

		public static void AddPrefabsToZNetScene(ZNetScene zNetScene)
		{
			try
			{
				foreach (GameObject gm in itemPrefabs)
				{
					if ((Object)(object)gm == (Object)null)
					{
						if (Instance.configVerboseLogging.Value)
						{
							Debug.LogWarning((object)"RPGStatusEffects: Null prefab in itemPrefabs list, skipping.");
						}
					}
					else if ((Object)(object)zNetScene.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)gm).name) == (Object)null)
					{
						zNetScene.m_prefabs.Add(gm);
						if (Instance.configVerboseLogging.Value)
						{
							Debug.Log((object)("RPGStatusEffects: Added " + ((Object)gm).name + " to ZNetScene.m_prefabs"));
						}
					}
					else if (Instance.configVerboseLogging.Value)
					{
						Debug.LogWarning((object)("RPGStatusEffects: Object exists in ZNetScene, skipping: " + ((Object)gm).name));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("RPGStatusEffects: Error adding prefabs to ZNetScene: " + ex.Message));
			}
			zNetScene.m_prefabs.RemoveAll((GameObject x) => (Object)(object)x == (Object)null);
		}

		private void ValidateConfigs()
		{
			List<string> list = configTauntHammerRecipe.Value.Split(new char[1] { ',' }).ToList();
			if (list.Count % 3 != 0)
			{
				if (configVerboseLogging.Value)
				{
					Debug.LogWarning((object)"RPGStatusEffects: Invalid recipe config for TauntHammer_vad - resetting to default.");
				}
				configTauntHammerRecipe.Value = configTauntHammerRecipe.DefaultValue.ToString();
			}
			for (int i = 1; i < list.Count; i += 3)
			{
				if (!int.TryParse(list[i], out var result) || !int.TryParse(list[i + 1], out result))
				{
					if (configVerboseLogging.Value)
					{
						Debug.LogWarning((object)"RPGStatusEffects: Invalid amounts in recipe config for TauntHammer_vad - resetting to default.");
					}
					configTauntHammerRecipe.Value = configTauntHammerRecipe.DefaultValue.ToString();
					break;
				}
			}
		}

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

		public void SetupStatusEffects()
		{
			if (!IsObjectDBValid())
			{
				if (configVerboseLogging.Value)
				{
					Debug.LogWarning((object)"RPGStatusEffects: Skipping SetupStatusEffects - ObjectDB not valid.");
				}
			}
			else
			{
				StatusEffectManager.Initialize();
			}
		}

		private void RegisterConsoleCommands()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			new ConsoleCommand("va_status_reload", "Reload RPGStatusEffects configs", (ConsoleEvent)delegate
			{
				if (!isShuttingDown)
				{
					((BaseUnityPlugin)this).Config.Reload();
					RecipeManager.ClearCache();
					ValidateConfigs();
					if (IsObjectDBValid())
					{
						SetupStatusEffects();
						RecipeManager.SetupRecipe();
						if (configVerboseLogging.Value)
						{
							Debug.Log((object)"RPGStatusEffects: Configs reloaded and status effects/recipe updated.");
						}
					}
					else if (configVerboseLogging.Value)
					{
						Debug.LogWarning((object)"RPGStatusEffects: Cannot reload configs, ObjectDB not valid.");
					}
				}
			}, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private void OnDestroy()
		{
			isShuttingDown = true;
			harmony.UnpatchSelf();
			if ((Object)(object)assetBundle != (Object)null)
			{
				assetBundle.Unload(true);
				if (configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Unloaded asset bundle.");
				}
			}
			if (configVerboseLogging.Value)
			{
				Debug.Log((object)"RPGStatusEffects: Unloaded.");
			}
		}

		public static bool IsObjectDBValid()
		{
			return (Object)(object)ObjectDB.instance != (Object)null;
		}
	}
	public static class AdminSyncing
	{
		[HarmonyPatch(typeof(ZNet), "Awake")]
		private static class AdminStatusSyncPatch
		{
			[CompilerGenerated]
			private sealed class <>c__DisplayClass1_0
			{
				public SyncedList adminList;

				public Func<ZNetPeer, bool> <>9__0;

				internal bool <WatchAdminListChanges>b__0(ZNetPeer p)
				{
					return adminList.Contains(p.m_rpc.GetSocket().GetHostName());
				}
			}

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

				private object <>2__current;

				private <>c__DisplayClass1_0 <>8__1;

				private List<string> <currentList>5__2;

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

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

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

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

				private bool MoveNext()
				{
					//IL_0046: Unknown result type (might be due to invalid IL or missing references)
					//IL_0050: Expected O, but got Unknown
					//IL_0071: Unknown result type (might be due to invalid IL or missing references)
					//IL_007b: Expected O, but got Unknown
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -1;
						List<string> list = <>8__1.adminList.GetList();
						if (!list.SequenceEqual(<currentList>5__2))
						{
							<currentList>5__2 = new List<string>(list);
							List<ZNetPeer> peers = ZNet.instance.GetPeers();
							List<ZNetPeer> list2 = peers.Where((ZNetPeer p) => <>8__1.adminList.Contains(p.m_rpc.GetSocket().GetHostName())).ToList();
							SendAdmin(peers.Except(list2).ToList(), isAdmin: false);
							SendAdmin(list2, isAdmin: true);
						}
					}
					else
					{
						<>1__state = -1;
						<>8__1 = new <>c__DisplayClass1_0();
						<>8__1.adminList = (SyncedList)AccessTools.Field(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						<currentList>5__2 = new List<string>(<>8__1.adminList.GetList());
					}
					<>2__current = (object)new WaitForSeconds(30f);
					<>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();
				}
			}

			[HarmonyPostfix]
			[HarmonyPriority(700)]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				if (!((Object)(object)RPGStatusEffects.Instance == (Object)null))
				{
					if (isServer)
					{
						ZRoutedRpc.instance.Register<ZPackage>("RPGStatusEffects AdminStatusSync", (Action<long, ZPackage>)RPC_AdminStatusSync);
					}
					else if (!registeredOnClient)
					{
						ZRoutedRpc.instance.Register<ZPackage>("RPGStatusEffects AdminStatusSync", (Action<long, ZPackage>)RPC_AdminStatusSync);
						registeredOnClient = true;
					}
					if (isServer)
					{
						((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
					}
				}
			}

			[IteratorStateMachine(typeof(<WatchAdminListChanges>d__1))]
			private static IEnumerator WatchAdminListChanges()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <WatchAdminListChanges>d__1(0);
			}

			private static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				ZPackage val = new ZPackage();
				val.Write(isAdmin);
				((MonoBehaviour)ZNet.instance).StartCoroutine(SendZPackage(peers, val));
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass4_0
		{
			public ZPackage package;

			internal IEnumerator<bool> <SendZPackage>b__1(ZNetPeer p)
			{
				return TellPeerAdminStatus(p, package);
			}
		}

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

			private object <>2__current;

			public ZPackage package;

			public List<ZNetPeer> peers;

			private List<IEnumerator<bool>> <writers>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0050: 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;
					<>c__DisplayClass4_0 CS$<>8__locals0 = new <>c__DisplayClass4_0
					{
						package = package
					};
					if (!Object.op_Implicit((Object)(object)ZNet.instance))
					{
						return false;
					}
					byte[] array = CS$<>8__locals0.package.GetArray();
					if (array.Length > 10000)
					{
						ZPackage val = new ZPackage();
						val.Write(4);
						using MemoryStream memoryStream = new MemoryStream();
						using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.Optimal))
						{
							deflateStream.Write(array, 0, array.Length);
						}
						val.Write(memoryStream.ToArray());
						CS$<>8__locals0.package = val;
					}
					<writers>5__2 = (from p in peers
						where p.IsReady()
						select TellPeerAdminStatus(p, CS$<>8__locals0.package)).ToList();
					<writers>5__2.RemoveAll((IEnumerator<bool> w) => !w.MoveNext());
					break;
				}
				case 1:
					<>1__state = -1;
					<writers>5__2.RemoveAll((IEnumerator<bool> w) => !w.MoveNext());
					break;
				}
				if (<writers>5__2.Count > 0)
				{
					<>2__current = null;
					<>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 <TellPeerAdminStatus>d__5 : IEnumerator<bool>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private bool <>2__current;

			public ZPackage package;

			public ZNetPeer peer;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (ZRoutedRpc.instance != null)
					{
						ZPackage val = new ZPackage(package.GetArray());
						if (isServer)
						{
							peer.m_rpc.Invoke("RPGStatusEffects AdminStatusSync", new object[1] { val });
						}
						else
						{
							ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_server ? 0 : peer.m_uid, "RPGStatusEffects AdminStatusSync", new object[1] { val });
						}
					}
					<>2__current = false;
					<>1__state = 1;
					return true;
				case 1:
					<>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();
			}
		}

		private static bool isServer;

		internal static bool registeredOnClient;

		private static void RPC_AdminStatusSync(long sender, ZPackage package)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			bool lockExempt = false;
			try
			{
				lockExempt = package.ReadBool();
			}
			catch
			{
			}
			if (isServer)
			{
				ZNetPeer peer = ZNet.instance.GetPeer(sender);
				SyncedList val = (SyncedList)AccessTools.Field(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
				if (peer != null && val.Contains(peer.m_rpc.GetSocket().GetHostName()))
				{
					ZPackage val2 = new ZPackage();
					val2.Write(true);
					peer.m_rpc.Invoke("RPGStatusEffects AdminStatusSync", new object[1] { val2 });
				}
			}
			else
			{
				ConfigSync.lockExempt = lockExempt;
				RPGStatusEffects.Instance?.SetupStatusEffects();
				RecipeManager.SetupRecipe();
			}
		}

		[IteratorStateMachine(typeof(<SendZPackage>d__4))]
		internal static IEnumerator SendZPackage(List<ZNetPeer> peers, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SendZPackage>d__4(0)
			{
				peers = peers,
				package = package
			};
		}

		[IteratorStateMachine(typeof(<TellPeerAdminStatus>d__5))]
		private static IEnumerator<bool> TellPeerAdminStatus(ZNetPeer peer, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TellPeerAdminStatus>d__5(0)
			{
				peer = peer,
				package = package
			};
		}
	}
	public class ConfigSync
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass57_0
		{
			public long target;

			internal bool <SendZPackage>b__0(ZNetPeer p)
			{
				if (target != ZRoutedRpc.Everybody)
				{
					return p.m_uid == target;
				}
				return true;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass58_0
		{
			public ConfigSync <>4__this;

			public ZPackage package;

			internal IEnumerator <SendZPackage>b__1(ZNetPeer p)
			{
				return <>4__this.distributeConfigToPeers(p, package);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass59_0
		{
			public ZNetPeer peer;

			public ConfigSync <>4__this;
		}

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

			private object <>2__current;

			public long target;

			public ConfigSync <>4__this;

			public ZPackage package;

			private IEnumerator <enumerator>5__2;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				ConfigSync configSync = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>c__DisplayClass57_0 CS$<>8__locals0 = new <>c__DisplayClass57_0
					{
						target = target
					};
					if (!Object.op_Implicit((Object)(object)ZNet.instance))
					{
						return false;
					}
					List<ZNetPeer> peers = ((List<ZNetPeer>)AccessTools.Field(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance)).Where((ZNetPeer p) => CS$<>8__locals0.target == ZRoutedRpc.Everybody || p.m_uid == CS$<>8__locals0.target).ToList();
					<enumerator>5__2 = configSync.SendZPackage(peers, package);
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<enumerator>5__2.MoveNext())
				{
					<>2__current = <enumerator>5__2.Current;
					<>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 <SendZPackage>d__58 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ConfigSync <>4__this;

			public ZPackage package;

			public List<ZNetPeer> peers;

			private List<IEnumerator> <writers>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>c__DisplayClass58_0 CS$<>8__locals0 = new <>c__DisplayClass58_0
					{
						<>4__this = <>4__this,
						package = package
					};
					if (!Object.op_Implicit((Object)(object)ZNet.instance))
					{
						return false;
					}
					byte[] array = CS$<>8__locals0.package.GetArray();
					if (array.Length > 10000)
					{
						ZPackage val = new ZPackage();
						val.Write((byte)4);
						using MemoryStream memoryStream = new MemoryStream();
						using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.Optimal))
						{
							deflateStream.Write(array, 0, array.Length);
						}
						val.Write(memoryStream.ToArray());
						CS$<>8__locals0.package = val;
					}
					<writers>5__2 = (from p in peers
						where p.IsReady()
						select CS$<>8__locals0.<>4__this.distributeConfigToPeers(p, CS$<>8__locals0.package)).ToList();
					<writers>5__2.RemoveAll((IEnumerator w) => !w.MoveNext());
					break;
				}
				case 1:
					<>1__state = -1;
					<writers>5__2.RemoveAll((IEnumerator w) => !w.MoveNext());
					break;
				}
				if (<writers>5__2.Any())
				{
					<>2__current = null;
					<>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 <distributeConfigToPeers>d__59 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZNetPeer peer;

			public ConfigSync <>4__this;

			public ZPackage package;

			private <>c__DisplayClass59_0 <>8__1;

			private byte[] <data>5__2;

			private int <fragments>5__3;

			private long <packageId>5__4;

			private int <i>5__5;

			private IEnumerator<bool> <>7__wrap5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				switch (<>1__state)
				{
				case -3:
				case 1:
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
					break;
				case -4:
				case 3:
					try
					{
					}
					finally
					{
						<>m__Finally2();
					}
					break;
				}
				<>8__1 = null;
				<data>5__2 = null;
				<>7__wrap5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_013d: Expected O, but got Unknown
				try
				{
					ZPackage val;
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>8__1 = new <>c__DisplayClass59_0();
						<>8__1.peer = peer;
						<>8__1.<>4__this = <>4__this;
						<data>5__2 = package.GetArray();
						if (<data>5__2.Length > 250000)
						{
							<fragments>5__3 = (<data>5__2.Length + 249999) / 250000;
							<packageId>5__4 = ++packageCounter;
							<i>5__5 = 0;
							goto IL_01e3;
						}
						<>7__wrap5 = waitForQueue().GetEnumerator();
						<>1__state = -4;
						goto IL_0243;
					case 1:
						<>1__state = -3;
						goto IL_0103;
					case 2:
						<>1__state = -1;
						goto IL_01d1;
					case 3:
						{
							<>1__state = -4;
							goto IL_0243;
						}
						IL_0243:
						if (<>7__wrap5.MoveNext())
						{
							bool current = <>7__wrap5.Current;
							<>2__current = current;
							<>1__state = 3;
							return true;
						}
						<>m__Finally2();
						<>7__wrap5 = null;
						SendPackage(package);
						break;
						IL_01e3:
						if (<i>5__5 < <fragments>5__3)
						{
							<>7__wrap5 = waitForQueue().GetEnumerator();
							<>1__state = -3;
							goto IL_0103;
						}
						break;
						IL_01d1:
						<i>5__5++;
						goto IL_01e3;
						IL_0103:
						if (<>7__wrap5.MoveNext())
						{
							bool current2 = <>7__wrap5.Current;
							<>2__current = current2;
							<>1__state = 1;
							return true;
						}
						<>m__Finally1();
						<>7__wrap5 = null;
						if (!<>8__1.peer.m_socket.IsConnected())
						{
							break;
						}
						val = new ZPackage();
						val.Write((byte)2);
						val.Write(<packageId>5__4);
						val.Write(<i>5__5);
						val.Write(<fragments>5__3);
						val.Write(<data>5__2.Skip(250000 * <i>5__5).Take(250000).ToArray());
						SendPackage(val);
						if (<i>5__5 < <fragments>5__3 - 1)
						{
							<>2__current = true;
							<>1__state = 2;
							return true;
						}
						goto IL_01d1;
					}
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				void SendPackage(ZPackage pkg)
				{
					if (isServer)
					{
						((<>c__DisplayClass59_0)this).peer.m_rpc.Invoke(((<>c__DisplayClass59_0)this).<>4__this.Name + " ConfigSync", new object[1] { pkg });
					}
					else
					{
						ZRoutedRpc.instance.InvokeRoutedRPC(((<>c__DisplayClass59_0)this).peer.m_server ? 0 : ((<>c__DisplayClass59_0)this).peer.m_uid, ((<>c__DisplayClass59_0)this).<>4__this.Name + " ConfigSync", new object[1] { pkg });
					}
				}
				[IteratorStateMachine(typeof(<>c__DisplayClass59_0.<<distributeConfigToPeers>g__waitForQueue|0>d))]
				IEnumerable<bool> waitForQueue()
				{
					//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
					return new <>c__DisplayClass59_0.<<distributeConfigToPeers>g__waitForQueue|0>d(-2)
					{
						<>4__this = this
					};
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap5 != null)
				{
					<>7__wrap5.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -1;
				if (<>7__wrap5 != null)
				{
					<>7__wrap5.Dispose();
				}
			}

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

		public static bool ProcessingServerUpdate = false;

		public readonly string Name;

		public string DisplayName;

		public string CurrentVersion;

		public string MinimumRequiredVersion;

		public bool ModRequired;

		private bool? forceConfigLocking;

		private bool isSourceOfTruth = true;

		public static HashSet<ConfigSync> configSyncs = new HashSet<ConfigSync>();

		public HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();

		public HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();

		public static bool isServer;

		public static bool lockExempt = false;

		private OwnConfigEntryBase lockedConfig;

		private const byte PARTIAL_CONFIGS = 1;

		private const byte FRAGMENTED_CONFIG = 2;

		private const byte COMPRESSED_CONFIG = 4;

		private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();

		private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();

		private static long packageCounter = 0L;

		private bool initialSyncDone;

		public bool IsLocked
		{
			get
			{
				bool? flag = forceConfigLocking;
				bool num;
				if (!flag.HasValue)
				{
					OwnConfigEntryBase ownConfigEntryBase = lockedConfig;
					if (!(((ownConfigEntryBase != null) ? ownConfigEntryBase.BaseConfig.BoxedValue : null) is IConvertible convertible))
					{
						goto IL_0055;
					}
					num = convertible.ToInt32(CultureInfo.InvariantCulture) != 0;
				}
				else
				{
					num = flag.GetValueOrDefault();
				}
				if (num)
				{
					return !lockExempt;
				}
				goto IL_0055;
				IL_0055:
				return false;
			}
			set
			{
				forceConfigLocking = value;
			}
		}

		public bool IsAdmin
		{
			get
			{
				if (!lockExempt)
				{
					return isSourceOfTruth;
				}
				return true;
			}
		}

		public bool IsSourceOfTruth
		{
			get
			{
				return isSourceOfTruth;
			}
			internal set
			{
				if (value != isSourceOfTruth)
				{
					isSourceOfTruth = value;
					this.SourceOfTruthChanged?.Invoke(value);
				}
			}
		}

		public bool InitialSyncDone
		{
			get
			{
				return initialSyncDone;
			}
			internal set
			{
				initialSyncDone = value;
			}
		}

		public event Action<bool> SourceOfTruthChanged;

		public event Action lockedConfigChanged;

		public ConfigSync(string name)
		{
			Name = name;
			DisplayName = name;
			configSyncs.Add(this);
		}

		public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			SyncedConfigEntry<T> syncedEntry = (configData((ConfigEntryBase)(object)configEntry) as SyncedConfigEntry<T>) ?? new SyncedConfigEntry<T>(configEntry);
			object[] first = ((ConfigEntryBase)configEntry).Description.Tags?.ToArray() ?? new object[1]
			{
				new ConfigurationManagerAttributes()
			};
			first = first.Concat(new object[1] { syncedEntry }).ToArray();
			AccessTools.Field(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry).Description, first);
			configEntry.SettingChanged += delegate
			{
				if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig)
				{
					Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)(object)configEntry);
				}
			};
			allConfigs.Add(syncedEntry);
			return syncedEntry;
		}

		public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible
		{
			if (lockedConfig != null)
			{
				throw new Exception("Cannot initialize locking ConfigEntry twice");
			}
			lockedConfig = AddConfigEntry<T>(lockingConfig);
			lockingConfig.SettingChanged += delegate
			{
				this.lockedConfigChanged?.Invoke();
			};
			return (SyncedConfigEntry<T>)lockedConfig;
		}

		internal void AddCustomValue(CustomSyncedValueBase customValue)
		{
			if (allCustomValues.Any((CustomSyncedValueBase v) => v.Identifier == customValue.Identifier) || customValue.Identifier == "serverversion")
			{
				throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)");
			}
			allCustomValues.Add(customValue);
			allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority));
			customValue.ValueChanged += delegate
			{
				if (!ProcessingServerUpdate)
				{
					Broadcast(ZRoutedRpc.Everybody, customValue);
				}
			};
		}

		private void Broadcast(long target, ConfigEntryBase config)
		{
			if (!IsLocked || IsAdmin)
			{
				ZPackage package = ConfigsToPackage((IEnumerable<ConfigEntryBase>)(object)new ConfigEntryBase[1] { config });
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(SendZPackage(target, package));
				}
			}
		}

		private void Broadcast(long target, CustomSyncedValueBase customValue)
		{
			if (!IsLocked || IsAdmin)
			{
				ZPackage package = ConfigsToPackage(null, new CustomSyncedValueBase[1] { customValue });
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(SendZPackage(target, package));
				}
			}
		}

		internal void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package)
		{
			lockedConfigChanged += serverLockedSettingChanged;
			IsSourceOfTruth = false;
			if (HandleConfigSyncRPC(0L, package, clientUpdate: false))
			{
				InitialSyncDone = true;
			}
		}

		internal void RPC_FromOtherClientConfigSync(long sender, ZPackage package)
		{
			HandleConfigSyncRPC(sender, package, clientUpdate: true);
		}

		private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			try
			{
				if (isServer && IsLocked)
				{
					ZRpc currentRpc = SnatchCurrentlyHandlingRPC.currentRpc;
					object obj;
					if (currentRpc == null)
					{
						obj = null;
					}
					else
					{
						ISocket socket = currentRpc.GetSocket();
						obj = ((socket != null) ? socket.GetHostName() : null);
					}
					string text = (string)obj;
					SyncedList val = (SyncedList)AccessTools.Field(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					if (text != null && !val.Contains(text))
					{
						return false;
					}
				}
				cacheExpirations.RemoveAll((KeyValuePair<long, string> kv) => kv.Key < DateTimeOffset.Now.Ticks && configValueCache.Remove(kv.Value));
				byte b = package.ReadByte();
				if ((b & 2u) != 0)
				{
					long num = package.ReadLong();
					string text2 = sender.ToString() + num;
					if (!configValueCache.TryGetValue(text2, out var value))
					{
						value = new SortedDictionary<int, byte[]>();
						configValueCache[text2] = value;
						cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.Ticks + 600000000, text2));
					}
					int key = package.ReadInt();
					int num2 = package.ReadInt();
					value[key] = package.ReadByteArray();
					if (value.Count < num2)
					{
						return false;
					}
					configValueCache.Remove(text2);
					package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray());
					b = package.ReadByte();
				}
				ProcessingServerUpdate = true;
				if ((b & 4u) != 0)
				{
					using MemoryStream stream = new MemoryStream(package.ReadByteArray());
					using MemoryStream memoryStream = new MemoryStream();
					using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
					{
						deflateStream.CopyTo(memoryStream);
					}
					package = new ZPackage(memoryStream.ToArray());
					b = package.ReadByte();
				}
				if ((b & 1) == 0)
				{
					resetConfigsFromServer();
				}
				ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package);
				ConfigFile val2 = null;
				bool saveOnConfigSet = false;
				foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues)
				{
					if (!isServer && configValue.Key.LocalBaseValue == null)
					{
						configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue;
					}
					if (val2 == null)
					{
						val2 = configValue.Key.BaseConfig.ConfigFile;
						saveOnConfigSet = val2.SaveOnConfigSet;
						val2.SaveOnConfigSet = false;
					}
					configValue.Key.BaseConfig.BoxedValue = configValue.Value;
				}
				if (val2 != null)
				{
					val2.SaveOnConfigSet = saveOnConfigSet;
					val2.Save();
				}
				foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues)
				{
					if (!isServer && customValue.Key.LocalBaseValue == null)
					{
						customValue.Key.LocalBaseValue = customValue.Key.BoxedValue;
					}
					customValue.Key.BoxedValue = customValue.Value;
				}
				Debug.Log((object)string.Format("[RPGStatusEffects] Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "server", DisplayName ?? Name));
				if (!isServer)
				{
					serverLockedSettingChanged();
				}
				return true;
			}
			finally
			{
				ProcessingServerUpdate = false;
			}
		}

		private void serverLockedSettingChanged()
		{
			foreach (OwnConfigEntryBase allConfig in allConfigs)
			{
				configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig);
			}
		}

		internal static bool isWritableConfig(OwnConfigEntryBase config)
		{
			ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config));
			if (configSync == null || configSync.IsSourceOfTruth || !config.SynchronizedConfig || config.LocalBaseValue == null)
			{
				return true;
			}
			if (configSync.IsLocked && config == configSync.lockedConfig)
			{
				return lockExempt;
			}
			return true;
		}

		internal void resetConfigsFromServer()
		{
			ConfigFile val = null;
			bool saveOnConfigSet = false;
			foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase c) => c.LocalBaseValue != null))
			{
				if (val == null)
				{
					val = item.BaseConfig.ConfigFile;
					saveOnConfigSet = val.SaveOnConfigSet;
					val.SaveOnConfigSet = false;
				}
				item.BaseConfig.BoxedValue = item.LocalBaseValue;
				item.LocalBaseValue = null;
			}
			if (val != null)
			{
				val.SaveOnConfigSet = saveOnConfigSet;
				val.Save();
			}
			foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase c) => c.LocalBaseValue != null))
			{
				item2.BoxedValue = item2.LocalBaseValue;
				item2.LocalBaseValue = null;
			}
			lockedConfigChanged -= serverLockedSettingChanged;
			serverLockedSettingChanged();
		}

		private ParsedConfigs ReadConfigsFromPackage(ZPackage package)
		{
			ParsedConfigs parsedConfigs = new ParsedConfigs();
			Dictionary<string, OwnConfigEntryBase> dictionary = allConfigs.ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "*" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c);
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				string text = package.ReadString();
				string key = package.ReadString();
				string text2 = package.ReadString();
				Type type = Type.GetType(text2);
				if (text2 == "" || type != null)
				{
					object obj;
					try
					{
						obj = ((text2 == "") ? null : ReadValueWithTypeFromZPackage(package, type));
					}
					catch (InvalidDeserializationTypeException ex)
					{
						Debug.LogWarning((object)("[RPGStatusEffects] Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text2 + " for " + key + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected));
						continue;
					}
					OwnConfigEntryBase value;
					if (text == "Internal")
					{
						if (key == "lockexempt" && obj is bool flag)
						{
							lockExempt = flag;
							continue;
						}
						CustomSyncedValueBase customSyncedValueBase = allCustomValues.FirstOrDefault((CustomSyncedValueBase v) => v.Identifier == key);
						if (customSyncedValueBase != null)
						{
							if ((text2 == "" && (!customSyncedValueBase.Type.IsValueType || Nullable.GetUnderlyingType(customSyncedValueBase.Type) != null)) || GetZPackageTypeString(customSyncedValueBase.Type) == text2)
							{
								parsedConfigs.customValues[customSyncedValueBase] = obj;
								continue;
							}
							Debug.LogWarning((object)("[RPGStatusEffects] Got unexpected type " + text2 + " for internal value " + key + " for mod " + (DisplayName ?? Name) + ", expecting " + customSyncedValueBase.Type.AssemblyQualifiedName));
						}
					}
					else if (dictionary.TryGetValue(text + "*" + key, out value))
					{
						Type type2 = configType(value.BaseConfig);
						if ((text2 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text2)
						{
							parsedConfigs.configValues[value] = obj;
							continue;
						}
						Debug.LogWarning((object)("[RPGStatusEffects] Got unexpected type " + text2 + " for " + key + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName));
					}
					else
					{
						Debug.LogWarning((object)("[RPGStatusEffects] Received unknown config entry " + key + " in section " + text + " for mod " + (DisplayName ?? Name) + "."));
					}
					continue;
				}
				Debug.LogWarning((object)("[RPGStatusEffects] Got invalid type " + text2 + ", abort reading of received configs"));
				return new ParsedConfigs();
			}
			return parsedConfigs;
		}

		private static string GetZPackageTypeString(Type type)
		{
			return type.AssemblyQualifiedName;
		}

		private static void AddValueToZPackage(ZPackage package, object value)
		{
			Type type = value?.GetType();
			if (value is Enum)
			{
				value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(type), CultureInfo.InvariantCulture);
			}
			else
			{
				if (value is ICollection collection)
				{
					package.Write(collection.Count);
					{
						IEnumerator enumerator = collection.GetEnumerator();
						try
						{
							while (enumerator.MoveNext())
							{
								AddValueToZPackage(package, enumerator.Current);
							}
							return;
						}
						finally
						{
							IDisposable disposable = enumerator as IDisposable;
							if (disposable != null)
							{
								disposable.Dispose();
							}
						}
					}
				}
				if (type != null && type.IsValueType && !type.IsPrimitive)
				{
					FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					package.Write(fields.Length);
					FieldInfo[] array = fields;
					foreach (FieldInfo fieldInfo in array)
					{
						package.Write(GetZPackageTypeString(fieldInfo.FieldType));
						AddValueToZPackage(package, fieldInfo.GetValue(value));
					}
					return;
				}
			}
			ZRpc.Serialize(new object[1] { value }, ref package);
		}

		private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type)
		{
			if (type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum)
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				int num = package.ReadInt();
				if (num != fields.Length)
				{
					throw new InvalidDeserializationTypeException
					{
						received = $"(field count: {num})",
						expected = $"(field count: {fields.Length})"
					};
				}
				object uninitializedObject = FormatterServices.GetUninitializedObject(type);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					string text = package.ReadString();
					if (text != GetZPackageTypeString(fieldInfo.FieldType))
					{
						throw new InvalidDeserializationTypeException
						{
							received = text,
							expected = GetZPackageTypeString(fieldInfo.FieldType),
							field = fieldInfo.Name
						};
					}
					fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType));
				}
				return uninitializedObject;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				int num2 = package.ReadInt();
				Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments);
				IDictionary dictionary = (IDictionary)Activator.CreateInstance(type);
				FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
				FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic);
				for (int j = 0; j < num2; j++)
				{
					object obj = ReadValueWithTypeFromZPackage(package, type2);
					dictionary.Add(field.GetValue(obj), field2.GetValue(obj));
				}
				return dictionary;
			}
			if (type.IsGenericType)
			{
				Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]);
				if (type3.IsAssignableFrom(type))
				{
					int num3 = package.ReadInt();
					object obj2 = Activator.CreateInstance(type);
					MethodInfo method = type3.GetMethod("Add");
					for (int k = 0; k < num3; k++)
					{
						method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) });
					}
					return obj2;
				}
			}
			ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo));
			AccessTools.Field(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type);
			List<object> source = new List<object>();
			ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source);
			return source.First();
		}

		internal ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase> configs = null, IEnumerable<CustomSyncedValueBase> customValues = null, IEnumerable<PackageEntry> packageEntries = null, bool partial = true)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase c) => configData(c).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>();
			List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>();
			List<PackageEntry> list3 = packageEntries?.ToList() ?? new List<PackageEntry>();
			ZPackage val = new ZPackage();
			val.Write(partial ? ((byte)1) : ((byte)0));
			val.Write(list.Count + list2.Count + list3.Count);
			foreach (PackageEntry item in list3)
			{
				val.Write(item.section);
				val.Write(item.key);
				val.Write((item.value == null) ? "" : GetZPackageTypeString(item.type));
				AddValueToZPackage(val, item.value);
			}
			foreach (CustomSyncedValueBase item2 in list2)
			{
				val.Write("Internal");
				val.Write(item2.Identifier);
				val.Write(GetZPackageTypeString(item2.Type));
				AddValueToZPackage(val, item2.BoxedValue);
			}
			foreach (ConfigEntryBase item3 in list)
			{
				val.Write(item3.Definition.Section);
				val.Write(item3.Definition.Key);
				val.Write(GetZPackageTypeString(configType(item3)));
				AddValueToZPackage(val, item3.BoxedValue);
			}
			return val;
		}

		private static Type configType(ConfigEntryBase config)
		{
			return configType(config.SettingType);
		}

		private static Type configType(Type type)
		{
			if (!type.IsEnum)
			{
				return type;
			}
			return Enum.GetUnderlyingType(type);
		}

		[IteratorStateMachine(typeof(<SendZPackage>d__57))]
		internal IEnumerator SendZPackage(long target, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SendZPackage>d__57(0)
			{
				<>4__this = this,
				target = target,
				package = package
			};
		}

		[IteratorStateMachine(typeof(<SendZPackage>d__58))]
		internal IEnumerator SendZPackage(List<ZNetPeer> peers, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SendZPackage>d__58(0)
			{
				<>4__this = this,
				peers = peers,
				package = package
			};
		}

		[IteratorStateMachine(typeof(<distributeConfigToPeers>d__59))]
		private IEnumerator distributeConfigToPeers(ZNetPeer peer, ZPackage package)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <distributeConfigToPeers>d__59(0)
			{
				<>4__this = this,
				peer = peer,
				package = package
			};
		}

		internal static OwnConfigEntryBase configData(ConfigEntryBase config)
		{
			return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault();
		}

		private static T configAttribute<T>(ConfigEntryBase config) where T : class
		{
			object[] tags = config.Description.Tags;
			if (tags == null)
			{
				return null;
			}
			return tags.OfType<T>().FirstOrDefault();
		}
	}
	public abstract class OwnConfigEntryBase
	{
		public readonly ConfigEntryBase BaseConfig;

		public object LocalBaseValue;

		public bool SynchronizedConfig = true;

		protected OwnConfigEntryBase(ConfigEntryBase config)
		{
			BaseConfig = config;
		}
	}
	public class SyncedConfigEntry<T> : OwnConfigEntryBase
	{
		public T Value
		{
			get
			{
				if (BaseConfig is ConfigEntry<T> val)
				{
					return val.Value;
				}
				throw new InvalidOperationException("Cannot cast BaseConfig to ConfigEntry<" + typeof(T).Name + ">");
			}
			set
			{
				((ConfigEntry<T>)(object)BaseConfig).Value = value;
			}
		}

		public T DefaultValue
		{
			get
			{
				if (BaseConfig is ConfigEntry<T> val)
				{
					return (T)((ConfigEntryBase)val).BoxedValue;
				}
				throw new InvalidOperationException("Cannot cast BaseConfig to ConfigEntry<" + typeof(T).Name + ">");
			}
		}

		public SyncedConfigEntry(ConfigEntry<T> config)
			: base((ConfigEntryBase)(object)config)
		{
		}
	}
	public class CustomSyncedValueBase
	{
		public string Identifier { get; }

		public Type Type { get; }

		public object BoxedValue { get; set; }

		public object LocalBaseValue { get; set; }

		public int Priority { get; }

		public event Action ValueChanged;

		public CustomSyncedValueBase(string identifier, Type type, int priority = 0)
		{
			Identifier = identifier;
			Type = type;
			Priority = priority;
		}
	}
	public class ConfigurationManagerAttributes
	{
		public bool? ReadOnly;
	}
	public class ParsedConfigs
	{
		public readonly Dictionary<OwnConfigEntryBase, object> configValues = new Dictionary<OwnConfigEntryBase, object>();

		public readonly Dictionary<CustomSyncedValueBase, object> customValues = new Dictionary<CustomSyncedValueBase, object>();
	}
	public class PackageEntry
	{
		public string section;

		public string key;

		public Type type;

		public object value;
	}
	public class InvalidDeserializationTypeException : Exception
	{
		public string expected;

		public string received;

		public string field = "";
	}
	[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
	public class SnatchCurrentlyHandlingRPC
	{
		public static ZRpc currentRpc;

		[HarmonyPrefix]
		private static void Prefix(ZRpc __instance)
		{
			currentRpc = __instance;
		}
	}
	[HarmonyPatch(typeof(ZNet), "Awake")]
	public class RegisterRPCPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ZNet __instance)
		{
			ConfigSync.isServer = __instance.IsServer();
			foreach (ConfigSync configSync in ConfigSync.configSyncs)
			{
				ZRoutedRpc.instance.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<long, ZPackage>)configSync.RPC_FromOtherClientConfigSync);
				if (ConfigSync.isServer)
				{
					Debug.Log((object)("[RPGStatusEffects] Registered '" + configSync.Name + " ConfigSync' RPC"));
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public class RegisterClientRPCPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			if (__instance.IsServer())
			{
				return;
			}
			foreach (ConfigSync configSync in ConfigSync.configSyncs)
			{
				peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
			}
		}
	}
	[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
	public class PreventSavingServerInfo
	{
		[HarmonyPrefix]
		private static bool Prefix(ConfigEntryBase __instance, ref string __result)
		{
			OwnConfigEntryBase ownConfigEntryBase = ConfigSync.configData(__instance);
			if (ownConfigEntryBase == null || ConfigSync.isWritableConfig(ownConfigEntryBase))
			{
				return true;
			}
			__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
			return false;
		}
	}
	[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
	public class PreventConfigRereadChangingValues
	{
		[HarmonyPrefix]
		private static bool Prefix(ConfigEntryBase __instance, string value)
		{
			OwnConfigEntryBase ownConfigEntryBase = ConfigSync.configData(__instance);
			if (ownConfigEntryBase != null && ownConfigEntryBase.LocalBaseValue != null)
			{
				try
				{
					ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)($"[RPGStatusEffects] Config value of setting \"{__instance.Definition}\"" + " could not be parsed and will be ignored. Reason: " + ex.Message + "; Value: " + value));
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public class SendConfigsAfterLogin
	{
		public class BufferingSocket : ZPlayFabSocket, ISocket
		{
			public volatile bool finished;

			public volatile int versionMatchQueued;

			public readonly List<ZPackage> Package = new List<ZPackage>();

			public readonly ISocket Original;

			public BufferingSocket(ISocket original)
			{
				Original = original;
				object obj = AccessTools.Field(typeof(ZPlayFabSocket), "m_remotePlayerId")?.GetValue(original);
				if (obj != null)
				{
					AccessTools.Field(typeof(BufferingSocket), "m_remotePlayerId")?.SetValue(this, obj);
				}
			}

			public bool IsConnected()
			{
				return Original.IsConnected();
			}

			public ZPackage Recv()
			{
				return Original.Recv();
			}

			public int GetSendQueueSize()
			{
				return Original.GetSendQueueSize();
			}

			public int GetCurrentSendRate()
			{
				return Original.GetCurrentSendRate();
			}

			public bool IsHost()
			{
				return Original.IsHost();
			}

			public void Dispose()
			{
				Original.Dispose();
			}

			public bool GotNewData()
			{
				return Original.GotNewData();
			}

			public void Close()
			{
				Original.Close();
			}

			public string GetEndPointString()
			{
				return Original.GetEndPointString();
			}

			public void GetAndResetStats(out int totalSent, out int totalRecv)
			{
				Original.GetAndResetStats(ref totalSent, ref totalRecv);
			}

			public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
			{
				Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
			}

			public ISocket Accept()
			{
				return Original.Accept();
			}

			public int GetHostPort()
			{
				return Original.GetHostPort();
			}

			public bool Flush()
			{
				return Original.Flush();
			}

			public string GetHostName()
			{
				return Original.GetHostName();
			}

			public void VersionMatch()
			{
				if (finished)
				{
					Original.VersionMatch();
				}
				else
				{
					versionMatchQueued = Package.Count;
				}
			}

			public void Send(ZPackage pkg)
			{
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				int pos = pkg.GetPos();
				pkg.SetPos(0);
				int num = pkg.ReadInt();
				if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
				{
					ZPackage val = new ZPackage(pkg.GetArray());
					val.SetPos(pos);
					Package.Add(val);
				}
				else
				{
					pkg.SetPos(pos);
					Original.Send(pkg);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass1_0
		{
			public ZRpc rpc;

			public ZNet __instance;

			public Dictionary<Assembly, BufferingSocket> __state;

			public ZNetPeer peer;
		}

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(ref Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.IsServer())
			{
				return;
			}
			BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket());
			AccessTools.Field(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket);
			ZNetPeer val = (ZNetPeer)AccessTools.Method(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
			if (val != null && (int)ZNet.m_onlineBackend != 0)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(ZNetPeer), "m_socket");
				object? value = fieldInfo.GetValue(val);
				ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null);
				if (val2 != null)
				{
					AccessTools.Field(typeof(BufferingSocket), "m_remotePlayerId")?.SetValue(bufferingSocket, val2.m_remotePlayerId);
				}
				fieldInfo.SetValue(val, bufferingSocket);
			}
			if (__state == null)
			{
				__state = new Dictionary<Assembly, BufferingSocket>();
			}
			__state[Assembly.GetExecutingAssembly()] = bufferingSocket;
		}

		[HarmonyPostfix]
		private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			<>c__DisplayClass1_0 CS$<>8__locals0 = new <>c__DisplayClass1_0();
			CS$<>8__locals0.rpc = rpc;
			CS$<>8__locals0.__instance = __instance;
			CS$<>8__locals0.__state = __state;
			if (CS$<>8__locals0.__instance.IsServer())
			{
				CS$<>8__locals0.peer = (ZNetPeer)AccessTools.Method(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(CS$<>8__locals0.__instance, new object[1] { CS$<>8__locals0.rpc });
				if (CS$<>8__locals0.peer == null)
				{
					SendBufferedData();
				}
				else
				{
					((MonoBehaviour)CS$<>8__locals0.__instance).StartCoroutine(SendAsync());
				}
			}
			[IteratorStateMachine(typeof(<>c__DisplayClass1_0.<<Postfix>g__SendAsync|1>d))]
			IEnumerator SendAsync()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <>c__DisplayClass1_0.<<Postfix>g__SendAsync|1>d(0)
				{
					<>4__this = CS$<>8__locals0
				};
			}
			void SendBufferedData()
			{
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Expected O, but got Unknown
				if (CS$<>8__locals0.rpc.GetSocket() is BufferingSocket bufferingSocket)
				{
					AccessTools.Field(typeof(ZRpc), "m_socket").SetValue(CS$<>8__locals0.rpc, bufferingSocket.Original);
					ZNetPeer val = (ZNetPeer)AccessTools.Method(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(CS$<>8__locals0.__instance, new object[1] { CS$<>8__locals0.rpc });
					if (val != null)
					{
						AccessTools.Field(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
					}
				}
				BufferingSocket bufferingSocket2 = CS$<>8__locals0.__state[Assembly.GetExecutingAssembly()];
				bufferingSocket2.finished = true;
				for (int i = 0; i < bufferingSocket2.Package.Count; i++)
				{
					if (i == bufferingSocket2.versionMatchQueued)
					{
						bufferingSocket2.Original.VersionMatch();
					}
					bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
				}
				if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
				{
					bufferingSocket2.Original.VersionMatch();
				}
			}
		}
	}
	public static class RecipeManager
	{
		private static readonly Dictionary<string, Recipe> _existingRecipes = new Dictionary<string, Recipe>();

		private static readonly Dictionary<string, Requirement[]> itemRecipeCache = new Dictionary<string, Requirement[]>();

		public static void SetupRecipe()
		{
			if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			_existingRecipes.Clear();
			string itemName = "TauntHammer_vad";
			GameObject val = ((IEnumerable<GameObject>)RPGStatusEffects.itemPrefabs).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => (Object)(object)p != (Object)null && string.Equals(((Object)p).name, itemName, StringComparison.OrdinalIgnoreCase)));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			TauntEffect tauntEffect = StatusEffectManager.GetEffect("Taunted") as TauntEffect;
			if ((Object)(object)tauntEffect != (Object)null)
			{
				component.m_itemData.m_shared.m_attackStatusEffect = (StatusEffect)(object)tauntEffect;
				component.m_itemData.m_shared.m_attackStatusEffectChance = 1f;
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)string.Format("{0}: Assigned Taunt effect to TauntHammer_vad (effect: {1}, duration: {2}s).", "RPGStatusEffects", ((Object)tauntEffect).name, tauntEffect.Duration));
				}
			}
			GameObject prefab = ZNetScene.instance.GetPrefab("piece_workbench");
			CraftingStation val2 = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Requirement[] array = ParseRequirements(RPGStatusEffects.Instance.configTauntHammerRecipe.Value, itemName);
			if (array.Length == 0)
			{
				return;
			}
			Recipe recipe = ScriptableObject.CreateInstance<Recipe>();
			((Object)recipe).name = "Recipe_" + itemName;
			recipe.m_item = component;
			recipe.m_craftingStation = val2;
			recipe.m_minStationLevel = 1;
			recipe.m_amount = 1;
			recipe.m_resources = array;
			if (!ObjectDB.instance.m_recipes.Any((Recipe r) => ((Object)r).name == ((Object)recipe).name))
			{
				ObjectDB.instance.m_recipes.Add(recipe);
				_existingRecipes[itemName] = recipe;
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Added Recipe_TauntHammer_vad to ObjectDB.m_recipes");
				}
			}
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return;
			}
			HashSet<string> hashSet = (HashSet<string>)(RPGStatusEffects.knownRecipesField?.GetValue(Player.m_localPlayer));
			if (hashSet != null && !hashSet.Contains(((Object)recipe).name))
			{
				hashSet.Add(((Object)recipe).name);
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Added Recipe_TauntHammer_vad to player's known recipes.");
				}
			}
		}

		public static void ClearCache()
		{
			itemRecipeCache.Clear();
		}

		private static Requirement[] ParseRequirements(string configValue, string key)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			if (itemRecipeCache.TryGetValue(key, out var value))
			{
				return value;
			}
			List<Requirement> list = new List<Requirement>();
			string[] array = (from s in configValue.Split(new char[1] { ',' })
				select s.Trim()).ToArray();
			for (int i = 0; i < array.Length && i + 2 < array.Length; i += 3)
			{
				string text = array[i];
				if (!int.TryParse(array[i + 1], out var result))
				{
					result = 1;
				}
				if (!int.TryParse(array[i + 2], out var result2))
				{
					result2 = 0;
				}
				ZNetScene instance = ZNetScene.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject prefab = instance.GetPrefab(text);
					obj = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null);
				}
				if (obj == null)
				{
					ObjectDB instance2 = ObjectDB.instance;
					if (instance2 == null)
					{
						obj = null;
					}
					else
					{
						GameObject itemPrefab = instance2.GetItemPrefab(text);
						obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
					}
				}
				ItemDrop val = (ItemDrop)obj;
				if ((Object)(object)val == (Object)null)
				{
					if (RPGStatusEffects.Instance.configVerboseLogging.Value)
					{
						Debug.LogWarning((object)("RPGStatusEffects: Invalid material '" + text + "' in recipe for " + key + " - skipping."));
					}
				}
				else
				{
					list.Add(new Requirement
					{
						m_resItem = val,
						m_amount = result,
						m_amountPerLevel = result2,
						m_recover = true
					});
				}
			}
			Requirement[] array2 = list.ToArray();
			itemRecipeCache[key] = array2;
			if (array2.Length == 0 && RPGStatusEffects.Instance.configVerboseLogging.Value)
			{
				Debug.LogWarning((object)("RPGStatusEffects: No valid requirements parsed for " + key + " - recipe may fail."));
			}
			return array2;
		}
	}
	public static class StatusEffectManager
	{
		private static readonly Dictionary<string, StatusEffect> CustomEffects = new Dictionary<string, StatusEffect>();

		public static void Initialize()
		{
			if (!RPGStatusEffects.IsObjectDBValid())
			{
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.LogWarning((object)"RPGStatusEffects: Skipping StatusEffectManager init - ObjectDB not valid.");
				}
				return;
			}
			CustomEffects.Clear();
			ObjectDB instance = ObjectDB.instance;
			RegisterPurityEffect(instance);
			RegisterTauntEffect(instance);
			RegisterTauntingEffect(instance);
			if (RPGStatusEffects.Instance.configVerboseLogging.Value)
			{
				Debug.Log((object)string.Format("{0}: StatusEffectManager initialized {1} custom effects.", "RPGStatusEffects", CustomEffects.Count));
			}
		}

		private static void RegisterPurityEffect(ObjectDB objectDB)
		{
			StatusEffect val = ((IEnumerable<StatusEffect>)objectDB.m_StatusEffects).FirstOrDefault((Func<StatusEffect, bool>)((StatusEffect se) => ((Object)se).name == "Purify"));
			if ((Object)(object)val != (Object)null)
			{
				objectDB.m_StatusEffects.Remove(val);
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Removed existing Purify effect to update duration.");
				}
			}
			PurityEffect purityEffect = ScriptableObject.CreateInstance<PurityEffect>();
			((Object)purityEffect).name = "Purify";
			purityEffect.Icon = LoadOrCreateIcon();
			purityEffect.Duration = RPGStatusEffects.Instance.configPurityDuration.Value;
			objectDB.m_StatusEffects.Add((StatusEffect)(object)purityEffect);
			CustomEffects["Purify"] = (StatusEffect)(object)purityEffect;
			if (RPGStatusEffects.Instance.configVerboseLogging.Value)
			{
				Debug.Log((object)string.Format("{0}: Registered PurityEffect with duration {1}s, Icon: {2}.", "RPGStatusEffects", purityEffect.Duration, ((Object)(object)purityEffect.Icon != (Object)null) ? "Assigned" : "Null"));
			}
		}

		private static void RegisterTauntEffect(ObjectDB objectDB)
		{
			StatusEffect val = ((IEnumerable<StatusEffect>)objectDB.m_StatusEffects).FirstOrDefault((Func<StatusEffect, bool>)((StatusEffect se) => ((Object)se).name == "Taunted"));
			if ((Object)(object)val != (Object)null)
			{
				objectDB.m_StatusEffects.Remove(val);
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Removed existing Taunted effect to update duration.");
				}
			}
			TauntEffect tauntEffect = ScriptableObject.CreateInstance<TauntEffect>();
			((Object)tauntEffect).name = "Taunted";
			tauntEffect.Duration = RPGStatusEffects.Instance.configTauntDuration.Value;
			tauntEffect.Icon = null;
			objectDB.m_StatusEffects.Add((StatusEffect)(object)tauntEffect);
			CustomEffects["Taunted"] = (StatusEffect)(object)tauntEffect;
			if (RPGStatusEffects.Instance.configVerboseLogging.Value)
			{
				Debug.Log((object)string.Format("{0}: Registered TauntEffect with duration {1}s, Icon: {2}.", "RPGStatusEffects", tauntEffect.Duration, ((Object)(object)tauntEffect.Icon != (Object)null) ? "Assigned" : "Null"));
			}
		}

		private static void RegisterTauntingEffect(ObjectDB objectDB)
		{
			StatusEffect val = ((IEnumerable<StatusEffect>)objectDB.m_StatusEffects).FirstOrDefault((Func<StatusEffect, bool>)((StatusEffect se) => ((Object)se).name == "Taunting"));
			if ((Object)(object)val != (Object)null)
			{
				objectDB.m_StatusEffects.Remove(val);
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)"RPGStatusEffects: Removed existing Taunting effect to update duration.");
				}
			}
			TauntingEffect tauntingEffect = ScriptableObject.CreateInstance<TauntingEffect>();
			((Object)tauntingEffect).name = "Taunting";
			tauntingEffect.Duration = RPGStatusEffects.Instance.configTauntDuration.Value;
			tauntingEffect.Icon = LoadTauntingIcon();
			objectDB.m_StatusEffects.Add((StatusEffect)(object)tauntingEffect);
			CustomEffects["Taunting"] = (StatusEffect)(object)tauntingEffect;
			if (RPGStatusEffects.Instance.configVerboseLogging.Value)
			{
				Debug.Log((object)string.Format("{0}: Registered TauntingEffect with duration {1}s, Icon: {2}.", "RPGStatusEffects", tauntingEffect.Duration, ((Object)(object)tauntingEffect.Icon != (Object)null) ? "Assigned" : "Null"));
			}
		}

		private static Sprite LoadOrCreateIcon()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[5] { "assets/custom/vaitems/icons/purity_icon", "Assets/Custom/VAItems/Icons/purity_icon", "assets/custom/VAitems/icons/purity_icon", "Assets/Custom/VAItems/Icons/Purity_Icon", "assets/custom/vaitems/icons/purity_icon.png" };
			Sprite val = null;
			string[] array2 = array;
			foreach (string text in array2)
			{
				AssetBundle assetBundle = RPGStatusEffects.assetBundle;
				val = ((assetBundle != null) ? assetBundle.LoadAsset<Sprite>(text) : null);
				if ((Object)(object)val != (Object)null)
				{
					if (RPGStatusEffects.Instance.configVerboseLogging.Value)
					{
						Debug.Log((object)("RPGStatusEffects: Loaded purity_icon from asset bundle at " + text + "."));
					}
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.LogWarning((object)("RPGStatusEffects: Failed to load purity_icon from asset bundle. Attempted paths: " + string.Join(", ", array) + "."));
					if ((Object)(object)RPGStatusEffects.assetBundle != (Object)null)
					{
						Debug.Log((object)("RPGStatusEffects: Available assets in bundle: " + string.Join(", ", RPGStatusEffects.assetBundle.GetAllAssetNames()) + "."));
					}
					Debug.Log((object)"RPGStatusEffects: Falling back to cyan square for Purity icon.");
				}
				Texture2D val2 = new Texture2D(64, 64);
				Color[] array3 = (Color[])(object)new Color[4096];
				for (int j = 0; j < array3.Length; j++)
				{
					array3[j] = Color.cyan;
				}
				val2.SetPixels(array3);
				val2.Apply();
				val = Sprite.Create(val2, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
			}
			return val;
		}

		private static Sprite LoadTauntIcon()
		{
			return null;
		}

		private static Sprite LoadTauntingIcon()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			string[] array = new string[5] { "assets/custom/vaitems/icons/taunt_icon", "Assets/Custom/VAItems/Icons/taunt_icon", "assets/custom/VAitems/icons/taunt_icon", "Assets/Custom/VAItems/Icons/Taunt_Icon", "assets/custom/vaitems/icons/taunt_icon.png" };
			Sprite val = null;
			string[] array2 = array;
			foreach (string text in array2)
			{
				AssetBundle assetBundle = RPGStatusEffects.assetBundle;
				val = ((assetBundle != null) ? assetBundle.LoadAsset<Sprite>(text) : null);
				if ((Object)(object)val != (Object)null)
				{
					if (RPGStatusEffects.Instance.configVerboseLogging.Value)
					{
						Debug.Log((object)("RPGStatusEffects: Loaded taunt_icon from asset bundle at " + text + "."));
					}
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.LogWarning((object)("RPGStatusEffects: Failed to load taunt_icon from asset bundle. Attempted paths: " + string.Join(", ", array) + "."));
					if ((Object)(object)RPGStatusEffects.assetBundle != (Object)null)
					{
						Debug.Log((object)("RPGStatusEffects: Available assets in bundle: " + string.Join(", ", RPGStatusEffects.assetBundle.GetAllAssetNames()) + "."));
					}
					Debug.Log((object)"RPGStatusEffects: Falling back to yellow square for Taunting icon.");
				}
				Texture2D val2 = new Texture2D(64, 64);
				Color[] array3 = (Color[])(object)new Color[4096];
				for (int j = 0; j < array3.Length; j++)
				{
					array3[j] = Color.yellow;
				}
				val2.SetPixels(array3);
				val2.Apply();
				val = Sprite.Create(val2, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
			}
			return val;
		}

		public static StatusEffect GetEffect(string name)
		{
			CustomEffects.TryGetValue(name, out var value);
			return value;
		}
	}
	public class PurityEffect : StatusEffect
	{
		private static readonly HashSet<string> DebuffNames = new HashSet<string> { "Poison", "Burning", "Frost", "Wet", "Smoked", "Tared" };

		public Sprite Icon { get; set; }

		public float Duration { get; set; } = 10f;


		public override void Setup(Character character)
		{
			((StatusEffect)this).Setup(character);
			base.m_ttl = Duration;
			base.m_name = "Purify";
			base.m_icon = Icon;
			Character character2 = base.m_character;
			Player val = (Player)(object)((character2 is Player) ? character2 : null);
			if (val == null)
			{
				return;
			}
			foreach (StatusEffect item in new List<StatusEffect>(((Character)val).GetSEMan().GetStatusEffects()))
			{
				if ((Object)(object)item != (Object)(object)this && DebuffNames.Contains(((Object)item).name))
				{
					((Character)val).GetSEMan().RemoveStatusEffect(item, true);
				}
			}
			((Character)val).Message((MessageType)2, "All debuffs purified!", 0, (Sprite)null);
		}
	}
	public class TauntEffect : StatusEffect
	{
		public Character Taunter { get; set; }

		public float Duration { get; set; } = 15f;


		public Sprite Icon { get; set; }

		public override void Setup(Character character)
		{
			((StatusEffect)this).Setup(character);
			base.m_ttl = Duration;
			base.m_name = "Taunted";
			base.m_icon = Icon;
			if ((Object)(object)base.m_character != (Object)null)
			{
				base.m_character.Message((MessageType)1, "TAUNTED!", 0, (Sprite)null);
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)string.Format("{0}: Setup TauntEffect on {1}, Duration: {2}s, Icon: {3}.", "RPGStatusEffects", ((Object)base.m_character).name, base.m_ttl, ((Object)(object)base.m_icon != (Object)null) ? "Assigned" : "Null"));
				}
			}
		}

		public override void UpdateStatusEffect(float dt)
		{
			((StatusEffect)this).UpdateStatusEffect(dt);
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			if ((Object)(object)base.m_character != (Object)null)
			{
				base.m_character.Message((MessageType)1, "Taunt ended.", 0, (Sprite)null);
			}
		}
	}
	public class TauntingEffect : StatusEffect
	{
		public float Duration { get; set; } = 15f;


		public Sprite Icon { get; set; }

		public override void Setup(Character character)
		{
			((StatusEffect)this).Setup(character);
			base.m_ttl = Duration;
			base.m_name = "Taunting";
			base.m_icon = Icon;
			if ((Object)(object)base.m_character != (Object)null && base.m_character.IsPlayer())
			{
				base.m_character.Message((MessageType)1, "Taunting enemy!", 0, (Sprite)null);
				if (RPGStatusEffects.Instance.configVerboseLogging.Value)
				{
					Debug.Log((object)string.Format("{0}: Setup TauntingEffect on player {1}, Duration: {2}s, Icon: {3}.", "RPGStatusEffects", ((Object)base.m_character).name, base.m_ttl, ((Object)(object)base.m_icon != (Object)null) ? "Assigned" : "Null"));
				}
			}
		}

		public override void UpdateStatusEffect(float dt)
		{
			((StatusEffect)this).UpdateStatusEffect(dt);
		}

		public override void Stop()
		{
			((StatusEffect)this).Stop();
			if ((Object)(object)base.m_character != (Object)null && base.m_character.IsPlayer())
			{
				base.m_character.Message((MessageType)1, "Taunt expired.", 0, (Sprite)null);
			}
		}
	}
}