Decompiled source of AutomaticPvPSwitch v1.1.0

AutomaticPvPSwitch.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using AutomaticPvPSwitch.Hooks;
using AutomaticPvPSwitch.Models;
using AutomaticPvPSwitch.Services;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HookDOTS.API;
using HookDOTS.API.Attributes;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Network;
using Stunlock.Core;
using Unity.Collections;
using Unity.Entities;
using VampireCommandFramework;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Thiaz")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Automatically switches player ability builds when entering PvP combat.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+987d784b37d3acf5846585e8e91165652afb95e3")]
[assembly: AssemblyProduct("AutomaticPvPSwitch")]
[assembly: AssemblyTitle("AutomaticPvPSwitch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 AutomaticPvPSwitch
{
	[BepInPlugin("AutomaticPvPSwitch", "AutomaticPvPSwitch", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		internal static ManualLogSource Logger;

		private HookDOTS _hookDOTS;

		public override void Load()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			BuildStorage.Init(Paths.ConfigPath);
			CommandRegistry.RegisterAll(Assembly.GetExecutingAssembly());
			_hookDOTS = new HookDOTS("AutomaticPvPSwitch", ((BasePlugin)this).Log);
			_hookDOTS.RegisterAnnotatedHooks();
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutomaticPvPSwitch ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.1.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			log.LogInfo(val);
		}

		public override bool Unload()
		{
			((BasePlugin)this).Log.LogInfo((object)"AutomaticPvPSwitch unloaded.");
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "AutomaticPvPSwitch";

		public const string PLUGIN_NAME = "AutomaticPvPSwitch";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace AutomaticPvPSwitch.Services
{
	public static class AbilityHelper
	{
		private const int BAR_TRAVEL = 2;

		private const int BAR_SPELL1 = 5;

		private const int BAR_SPELL2 = 6;

		private const int BAR_ULTIMATE = 7;

		private static readonly string[] SpellSchoolPrefixes = new string[6] { "AB_Blood_", "AB_Unholy_", "AB_Chaos_", "AB_Illusion_", "AB_Frost_", "AB_Storm_" };

		public static PlayerBuild ReadCurrentBuild(EntityManager em, Entity charEntity)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			PlayerBuild playerBuild = new PlayerBuild();
			if (!((EntityManager)(ref em)).HasBuffer<AbilityGroupSlotBuffer>(charEntity))
			{
				return playerBuild;
			}
			DynamicBuffer<AbilityGroupSlotBuffer> buffer = ((EntityManager)(ref em)).GetBuffer<AbilityGroupSlotBuffer>(charEntity, false);
			int num = 0;
			for (int i = 0; i < buffer.Length; i++)
			{
				AbilityGroupSlotBuffer val = buffer[i];
				if (!val.ShowOnBar)
				{
					continue;
				}
				if (num == 2 || num == 5 || num == 6 || num == 7)
				{
					int num2 = ReadSlotAbilityPrefab(em, val);
					switch (num)
					{
					case 2:
						playerBuild.Travel = num2;
						break;
					case 5:
						playerBuild.Spell1 = num2;
						break;
					case 6:
						playerBuild.Spell2 = num2;
						break;
					case 7:
						playerBuild.Ultimate = num2;
						break;
					}
				}
				num++;
				if (num > 7)
				{
					break;
				}
			}
			return playerBuild;
		}

		public static bool ApplyBuild(EntityManager em, Entity charEntity, PlayerBuild build, ulong platformId)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			if (build == null || build.IsEmpty)
			{
				return false;
			}
			World val = FindServerWorld();
			if (val == null)
			{
				return false;
			}
			DebugEventsSystem existingSystemManaged = val.GetExistingSystemManaged<DebugEventsSystem>();
			if (existingSystemManaged == null)
			{
				Plugin.Logger.LogWarning((object)"[AbilityHelper] Could not get DebugEventsSystem");
				return false;
			}
			BuffSpawnerSystemData bssd = BuffSpawnerSystemData.Create((ComponentSystemBase)(object)existingSystemManaged);
			PrefabCollectionSystem existingSystemManaged2 = val.GetExistingSystemManaged<PrefabCollectionSystem>();
			if (existingSystemManaged2 == null)
			{
				Plugin.Logger.LogWarning((object)"[AbilityHelper] Could not get PrefabCollectionSystem");
				return false;
			}
			PrefabLookupMap prefabLookupMap = existingSystemManaged2._PrefabLookupMap;
			int num = 0;
			PlayerBuild playerBuild = ReadCurrentBuild(em, charEntity);
			if (build.Spell1 != 0 && build.Spell1 != playerBuild.Spell1 && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Spell1, primarySlot: true, "Spell1"))
			{
				num++;
			}
			if (build.Spell2 != 0 && build.Spell2 != playerBuild.Spell2 && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Spell2, primarySlot: false, "Spell2"))
			{
				num++;
			}
			if (build.Ultimate != 0 && build.Ultimate != playerBuild.Ultimate && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Ultimate, primarySlot: true, "Ultimate"))
			{
				num++;
			}
			if (build.Travel != 0 && build.Travel != playerBuild.Travel && ApplyAbility(em, bssd, prefabLookupMap, charEntity, build.Travel, primarySlot: true, "Travel"))
			{
				num++;
			}
			return num > 0;
		}

		private static bool ApplyAbility(EntityManager em, BuffSpawnerSystemData bssd, PrefabLookupMap prefabMap, Entity charEntity, int abilityGuid, bool primarySlot, string label)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Invalid comparison between Unknown and I4
			//IL_0111: 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)
			PrefabGUID val = default(PrefabGUID);
			((PrefabGUID)(ref val))..ctor(abilityGuid);
			NativeParallelHashMap<PrefabGUID, ConvertedAssetData> assetDataLookup = prefabMap.AssetDataLookup;
			bool flag = default(bool);
			if (!assetDataLookup.ContainsKey(val))
			{
				ManualLogSource logger = Plugin.Logger;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(63, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[AbilityHelper] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": PrefabGUID ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(abilityGuid);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" not found in game data, skipping.");
				}
				logger.LogWarning(val2);
				return false;
			}
			if (!IsAbilityUnlocked(em, charEntity, val, prefabMap))
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[AbilityHelper] ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ResolveNameFromMap(prefabMap, abilityGuid));
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" not unlocked, skipping.");
				}
				logger2.LogInfo(val3);
				return false;
			}
			try
			{
				ApplyVBloodAbilityResult val4 = VBloodAbilityUtilities.TryApplyVBloodAbility(em, bssd, prefabMap, charEntity, val, (VBloodAbilityApplyType)0, primarySlot);
				ManualLogSource logger3 = Plugin.Logger;
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(26, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[AbilityHelper] ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ResolveNameFromMap(prefabMap, abilityGuid));
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" result=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<ApplyVBloodAbilityResult>(val4);
				}
				logger3.LogInfo(val3);
				return (int)val4 == 0;
			}
			catch (Exception ex)
			{
				ManualLogSource logger4 = Plugin.Logger;
				bool flag2 = default(bool);
				BepInExErrorLogInterpolatedStringHandler val5 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[AbilityHelper] ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(label);
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" failed: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(ex.Message);
				}
				logger4.LogError(val5);
				return false;
			}
		}

		private static bool IsAbilityUnlocked(EntityManager em, Entity charEntity, PrefabGUID ability, PrefabLookupMap prefabMap)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!IsSpellSchoolAbility(prefabMap, ability))
				{
					return true;
				}
				Entity val = charEntity;
				if (!((EntityManager)(ref em)).HasComponent<ProgressionMapper>(charEntity))
				{
					if (!((EntityManager)(ref em)).HasComponent<PlayerCharacter>(charEntity))
					{
						return true;
					}
					val = ((EntityManager)(ref em)).GetComponentData<PlayerCharacter>(charEntity).UserEntity;
					if (val == Entity.Null || !((EntityManager)(ref em)).HasComponent<ProgressionMapper>(val))
					{
						return true;
					}
				}
				Entity entity = ((EntityManager)(ref em)).GetComponentData<ProgressionMapper>(val).ProgressionEntity._Entity;
				if (entity == Entity.Null || !((EntityManager)(ref em)).Exists(entity))
				{
					return true;
				}
				if (!((EntityManager)(ref em)).HasBuffer<UnlockedSpellBookAbility>(entity))
				{
					return true;
				}
				DynamicBuffer<UnlockedSpellBookAbility> buffer = ((EntityManager)(ref em)).GetBuffer<UnlockedSpellBookAbility>(entity, false);
				for (int i = 0; i < buffer.Length; i++)
				{
					if (buffer[i].Ability._Value == ability._Value)
					{
						return true;
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[AbilityHelper] IsAbilityUnlocked check failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				logger.LogWarning(val2);
				return true;
			}
		}

		private static bool IsSpellSchoolAbility(PrefabLookupMap prefabMap, PrefabGUID ability)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			try
			{
				NativeParallelHashMap<PrefabGUID, ConvertedAssetData> assetDataLookup = prefabMap.AssetDataLookup;
				ConvertedAssetData val = default(ConvertedAssetData);
				if (!assetDataLookup.TryGetValue(ability, ref val))
				{
					return false;
				}
				string text = ((object)(FixedString128Bytes)(ref val.AssetName)).ToString();
				string[] spellSchoolPrefixes = SpellSchoolPrefixes;
				foreach (string value in spellSchoolPrefixes)
				{
					if (text.StartsWith(value, StringComparison.Ordinal))
					{
						return true;
					}
				}
				if (text.IndexOf("VeilOf", StringComparison.Ordinal) >= 0)
				{
					return true;
				}
				if (text.StartsWith("AB_", StringComparison.Ordinal) && !text.StartsWith("AB_Vampire_", StringComparison.Ordinal) && !text.StartsWith("AB_Interact_", StringComparison.Ordinal))
				{
					ManualLogSource logger = Plugin.Logger;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(90, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[AbilityHelper] Unknown spell school prefix for: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" - may need to add to SpellSchoolPrefixes");
					}
					logger.LogWarning(val2);
				}
			}
			catch
			{
			}
			return false;
		}

		private static string ResolveNameFromMap(PrefabLookupMap prefabMap, int guidHash)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				NativeParallelHashMap<PrefabGUID, ConvertedAssetData> assetDataLookup = prefabMap.AssetDataLookup;
				ConvertedAssetData val = default(ConvertedAssetData);
				if (assetDataLookup.TryGetValue(new PrefabGUID(guidHash), ref val))
				{
					string text = ((object)(FixedString128Bytes)(ref val.AssetName)).ToString();
					if (!string.IsNullOrEmpty(text))
					{
						return CleanAbilityName(text);
					}
				}
			}
			catch
			{
			}
			return $"#{guidHash}";
		}

		private static int ReadSlotAbilityPrefab(EntityManager em, AbilityGroupSlotBuffer slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Entity entity = slot.GroupSlotEntity._Entity;
			if (entity == Entity.Null)
			{
				return 0;
			}
			if (!((EntityManager)(ref em)).HasComponent<AbilityGroupSlot>(entity))
			{
				return 0;
			}
			AbilityGroupSlot componentData = ((EntityManager)(ref em)).GetComponentData<AbilityGroupSlot>(entity);
			Entity entity2 = componentData.StateEntity._Entity;
			if (entity2 != Entity.Null && ((EntityManager)(ref em)).HasComponent<PrefabGUID>(entity2))
			{
				return ((EntityManager)(ref em)).GetComponentData<PrefabGUID>(entity2)._Value;
			}
			return componentData.GroupGuid._Value._Value;
		}

		private static World FindServerWorld()
		{
			Enumerator<World> enumerator = World.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current != null && current.Name == "Server")
				{
					return current;
				}
			}
			return null;
		}

		public static string ResolveName(int guidHash)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (guidHash == 0)
			{
				return "(empty)";
			}
			try
			{
				Enumerator<World> enumerator = World.All.GetEnumerator();
				ConvertedAssetData val3 = default(ConvertedAssetData);
				while (enumerator.MoveNext())
				{
					World current = enumerator.Current;
					if (current == null || current.Name != "Server")
					{
						continue;
					}
					Type val = Il2CppType.Of<PrefabCollectionSystem>();
					ComponentSystemBase existingSystemManaged = current.GetExistingSystemManaged(val);
					if (existingSystemManaged == null)
					{
						continue;
					}
					PrefabCollectionSystem val2 = ((Il2CppObjectBase)existingSystemManaged).TryCast<PrefabCollectionSystem>();
					if (val2 == null)
					{
						continue;
					}
					NativeParallelHashMap<PrefabGUID, ConvertedAssetData> assetDataLookup = val2._PrefabLookupMap.AssetDataLookup;
					if (assetDataLookup.TryGetValue(new PrefabGUID(guidHash), ref val3))
					{
						string text = ((object)(FixedString128Bytes)(ref val3.AssetName)).ToString();
						if (!string.IsNullOrEmpty(text))
						{
							return CleanAbilityName(text);
						}
					}
				}
			}
			catch
			{
			}
			return $"#{guidHash}";
		}

		private static string CleanAbilityName(string raw)
		{
			if (raw.StartsWith("AB_Vampire_", StringComparison.Ordinal))
			{
				raw = raw.Substring("AB_Vampire_".Length);
			}
			else if (raw.StartsWith("AB_", StringComparison.Ordinal))
			{
				raw = raw.Substring("AB_".Length);
			}
			int num = raw.IndexOf("_AbilityGroup", StringComparison.OrdinalIgnoreCase);
			if (num > 0)
			{
				raw = raw.Substring(0, num);
			}
			return raw.Replace('_', ' ');
		}
	}
	public static class BuildCommands
	{
		private static readonly Dictionary<ulong, DateTime> _lastSwitchTime = new Dictionary<ulong, DateTime>();

		private const int SWITCH_COOLDOWN_SECONDS = 10;

		[Command("pvp", null, null, "Switch to PvP build. Use '.pvp save' to save current abilities as PvP build.", null, false)]
		public static void PvpCommand(ChatCommandContext ctx, string action = null)
		{
			HandleBuildCommand(ctx, "pvp", action);
		}

		[Command("pvpswitch", null, null, "Admin: globally enable/disable automatic PvP build switching.", null, true)]
		public static void PvpSwitchCommand(ChatCommandContext ctx, string action = null, string playerName = null)
		{
			if (action != null && action.Equals("enable", StringComparison.OrdinalIgnoreCase))
			{
				BuildStorage.SetGlobalEnabled(enabled: true);
				ctx.Reply("AutomaticPvPSwitch: <color=#00FF00>enabled</color>");
				Plugin.Logger.LogInfo((object)"[PvPSwitch] Globally enabled by admin.");
			}
			else if (action != null && action.Equals("disable", StringComparison.OrdinalIgnoreCase))
			{
				BuildStorage.SetGlobalEnabled(enabled: false);
				ctx.Reply("AutomaticPvPSwitch: <color=#FF0000>disabled</color>");
				Plugin.Logger.LogInfo((object)"[PvPSwitch] Globally disabled by admin.");
			}
			else if (action != null && action.Equals("reset", StringComparison.OrdinalIgnoreCase))
			{
				BuildStorage.ResetAllBuilds();
				ctx.Reply("AutomaticPvPSwitch: all builds <color=#FF0000>reset</color>.");
			}
			else if (action != null && action.Equals("resetplayer", StringComparison.OrdinalIgnoreCase))
			{
				ResetPlayer(ctx, playerName);
			}
			else
			{
				string text = (BuildStorage.GlobalEnabled ? "<color=#00FF00>enabled</color>" : "<color=#FF0000>disabled</color>");
				ctx.Reply("AutomaticPvPSwitch: " + text + ". Use '.pvpswitch enable/disable/reset/resetplayer'.");
			}
		}

		[Command("pve", null, null, "Switch to PvE build. Use '.pve save' to save current abilities as PvE build.", null, false)]
		public static void PveCommand(ChatCommandContext ctx, string action = null)
		{
			HandleBuildCommand(ctx, "pve", action);
		}

		private static void HandleBuildCommand(ChatCommandContext ctx, string mode, string action)
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				World val = FindServerWorld();
				if (val == null)
				{
					ctx.Reply("Error: Server world not found.");
					return;
				}
				EntityManager entityManager = val.EntityManager;
				Entity senderUserEntity = ctx.Event.SenderUserEntity;
				User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(senderUserEntity);
				ulong platformId = componentData.PlatformId;
				Entity entity = componentData.LocalCharacter._Entity;
				if (entity == Entity.Null)
				{
					ctx.Reply("Error: Character entity not found.");
				}
				else if (action != null && action.Equals("save", StringComparison.OrdinalIgnoreCase))
				{
					SaveBuild(ctx, entityManager, entity, platformId, mode);
				}
				else if (action != null && action.Equals("enable", StringComparison.OrdinalIgnoreCase))
				{
					BuildStorage.SetAutoEnabled(platformId, enabled: true);
					ctx.Reply("Auto-switch: <color=#00FF00>enabled</color>");
				}
				else if (action != null && action.Equals("disable", StringComparison.OrdinalIgnoreCase))
				{
					BuildStorage.SetAutoEnabled(platformId, enabled: false);
					ctx.Reply("Auto-switch: <color=#FF0000>disabled</color>");
				}
				else
				{
					LoadBuild(ctx, entityManager, entity, platformId, mode);
				}
			}
			catch (Exception ex)
			{
				ctx.Reply("Error: " + ex.Message);
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(18, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[BuildCommands] ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(mode);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
				}
				logger.LogError(val2);
			}
		}

		private static void SaveBuild(ChatCommandContext ctx, EntityManager em, Entity charEntity, ulong platformId, string mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayerBuild playerBuild = AbilityHelper.ReadCurrentBuild(em, charEntity);
			if (playerBuild.IsEmpty)
			{
				ctx.Reply("No abilities found on your bar. Make sure you have spells equipped.");
				return;
			}
			BuildStorage.SaveBuild(platformId, mode, playerBuild);
			ctx.Reply(mode.ToUpperInvariant() + " build saved.");
		}

		private static void LoadBuild(ChatCommandContext ctx, EntityManager em, Entity charEntity, ulong platformId, string mode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (PvPBuffDetector.HasPvPBuff(em, charEntity))
			{
				ctx.Reply("Can't switch build while PvP debuff is active.");
				return;
			}
			if (_lastSwitchTime.TryGetValue(platformId, out var value))
			{
				double totalSeconds = (DateTime.UtcNow - value).TotalSeconds;
				if (totalSeconds < 10.0)
				{
					int value2 = (int)Math.Ceiling(10.0 - totalSeconds);
					ctx.Reply($"Cooldown: {value2}s remaining.");
					return;
				}
			}
			PlayerBuild build = BuildStorage.GetBuild(platformId, mode);
			if (build == null || build.IsEmpty)
			{
				ctx.Reply($"No {mode.ToUpperInvariant()} build saved. Use '.{mode} save' first.");
			}
			else if (AbilityHelper.ApplyBuild(em, charEntity, build, platformId))
			{
				_lastSwitchTime[platformId] = DateTime.UtcNow;
				ctx.Reply("Switched to " + mode.ToUpperInvariant() + " build.");
			}
			else
			{
				ctx.Reply("Already using " + mode.ToUpperInvariant() + " build (no changes needed).");
			}
		}

		private static void ResetPlayer(ChatCommandContext ctx, string playerName)
		{
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			if (string.IsNullOrEmpty(playerName))
			{
				ctx.Reply("Usage: .pvpswitch resetplayer <playerName>");
				return;
			}
			bool flag = default(bool);
			try
			{
				World val = FindServerWorld();
				if (val == null)
				{
					ctx.Reply("Error: Server world not found.");
					return;
				}
				EntityManager entityManager = val.EntityManager;
				ComponentType val2 = default(ComponentType);
				((ComponentType)(ref val2))..ctor(Il2CppType.Of<User>(), (AccessMode)1);
				EntityQueryBuilder val3 = new EntityQueryBuilder(AllocatorHandle.op_Implicit((Allocator)2));
				EntityQueryBuilder val4 = ((EntityQueryBuilder)(ref val3)).AddAll(val2);
				EntityQuery val5 = ((EntityManager)(ref entityManager)).CreateEntityQuery(ref val4);
				((EntityQueryBuilder)(ref val4)).Dispose();
				NativeArray<Entity> val6 = ((EntityQuery)(ref val5)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				try
				{
					for (int i = 0; i < val6.Length; i++)
					{
						User componentData = ((EntityManager)(ref entityManager)).GetComponentData<User>(val6[i]);
						if (((object)(FixedString64Bytes)(ref componentData.CharacterName)).ToString().Equals(playerName, StringComparison.OrdinalIgnoreCase))
						{
							ulong platformId = componentData.PlatformId;
							Entity entity = componentData.LocalCharacter._Entity;
							BuildStorage.RemovePlayer(platformId);
							_lastSwitchTime.Remove(platformId);
							int num = 0;
							if (entity != Entity.Null && componentData.IsConnected)
							{
								num = RemoveVBloodAbilities(entityManager, entity);
							}
							ctx.Reply((num > 0) ? $"Player '{playerName}': builds cleared, {num} abilities removed." : ("Player '" + playerName + "': builds cleared."));
							ManualLogSource logger = Plugin.Logger;
							BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("[PvPSwitch] Admin reset player '");
								((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(playerName);
								((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("' (pid=");
								((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<ulong>(platformId);
								((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(").");
							}
							logger.LogInfo(val7);
							return;
						}
					}
				}
				finally
				{
					val6.Dispose();
				}
				ctx.Reply("Player '" + playerName + "' not found.");
			}
			catch (Exception ex)
			{
				ctx.Reply("Error: " + ex.Message);
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val8 = new BepInExErrorLogInterpolatedStringHandler(25, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val8).AppendLiteral("[PvPSwitch] resetplayer: ");
					((BepInExLogInterpolatedStringHandler)val8).AppendFormatted<Exception>(ex);
				}
				logger2.LogError(val8);
			}
		}

		private static int RemoveVBloodAbilities(EntityManager em, Entity charEntity)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (!((EntityManager)(ref em)).HasBuffer<VBloodAbilityBuffEntry>(charEntity))
			{
				return 0;
			}
			DynamicBuffer<VBloodAbilityBuffEntry> buffer = ((EntityManager)(ref em)).GetBuffer<VBloodAbilityBuffEntry>(charEntity, false);
			List<PrefabGUID> list = new List<PrefabGUID>(buffer.Length);
			for (int i = 0; i < buffer.Length; i++)
			{
				PrefabGUID activeAbility = buffer[i].ActiveAbility;
				if (activeAbility._Value != 0)
				{
					list.Add(activeAbility);
				}
			}
			bool flag = default(bool);
			foreach (PrefabGUID item in list)
			{
				try
				{
					VBloodAbilityUtilities.TryRemoveVBloodAbility(em, charEntity, item);
				}
				catch (Exception ex)
				{
					ManualLogSource logger = Plugin.Logger;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(52, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildCommands] TryRemoveVBloodAbility failed for ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(item._Value);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					logger.LogWarning(val);
				}
			}
			return list.Count;
		}

		private static World FindServerWorld()
		{
			Enumerator<World> enumerator = World.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current != null && current.Name == "Server")
				{
					return current;
				}
			}
			return null;
		}
	}
	public static class BuildStorage
	{
		private static readonly Dictionary<ulong, PlayerData> _builds = new Dictionary<ulong, PlayerData>();

		private static string _filePath;

		private static string _globalFilePath;

		public static bool GlobalEnabled { get; private set; } = true;


		public static int PvpBuildCount { get; private set; }

		public static void Init(string configDir)
		{
			string text = Path.Combine(configDir, "AutomaticPvPSwitch");
			Directory.CreateDirectory(text);
			_filePath = Path.Combine(text, "builds.json");
			_globalFilePath = Path.Combine(text, "global_enabled");
			LoadGlobalState();
			Load();
		}

		public static bool HasBuild(ulong platformId, string mode)
		{
			if (!_builds.TryGetValue(platformId, out var value))
			{
				return false;
			}
			PlayerBuild playerBuild = ((mode == "pvp") ? value.Pvp : value.Pve);
			if (playerBuild != null)
			{
				return !playerBuild.IsEmpty;
			}
			return false;
		}

		public static PlayerBuild GetBuild(ulong platformId, string mode)
		{
			if (!_builds.TryGetValue(platformId, out var value))
			{
				return null;
			}
			if (!(mode == "pvp"))
			{
				return value.Pve;
			}
			return value.Pvp;
		}

		public static void RemovePlayer(ulong platformId)
		{
			if (_builds.TryGetValue(platformId, out var value))
			{
				if (value.Pvp != null && !value.Pvp.IsEmpty)
				{
					PvpBuildCount--;
				}
				_builds.Remove(platformId);
				Save();
			}
		}

		public static void ResetAllBuilds()
		{
			_builds.Clear();
			PvpBuildCount = 0;
			Save();
			Plugin.Logger.LogInfo((object)"[BuildStorage] All builds reset.");
		}

		public static void SetGlobalEnabled(bool enabled)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			GlobalEnabled = enabled;
			try
			{
				File.WriteAllText(_globalFilePath, enabled ? "1" : "0");
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildStorage] Global state save failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				logger.LogError(val);
			}
		}

		private static void LoadGlobalState()
		{
			if (!File.Exists(_globalFilePath))
			{
				return;
			}
			try
			{
				GlobalEnabled = File.ReadAllText(_globalFilePath).Trim() != "0";
			}
			catch
			{
			}
		}

		public static bool IsAutoEnabled(ulong platformId)
		{
			if (!_builds.TryGetValue(platformId, out var value))
			{
				return true;
			}
			return value.AutoEnabled;
		}

		public static void SetAutoEnabled(ulong platformId, bool enabled)
		{
			if (!_builds.TryGetValue(platformId, out var value))
			{
				value = new PlayerData();
				_builds[platformId] = value;
			}
			value.AutoEnabled = enabled;
			Save();
		}

		public static void SaveBuild(ulong platformId, string mode, PlayerBuild build)
		{
			if (!_builds.TryGetValue(platformId, out var value))
			{
				value = new PlayerData();
				_builds[platformId] = value;
			}
			if (mode == "pvp")
			{
				bool flag = value.Pvp != null && !value.Pvp.IsEmpty;
				bool flag2 = build != null && !build.IsEmpty;
				value.Pvp = build;
				if (!flag && flag2)
				{
					PvpBuildCount++;
				}
				else if (flag && !flag2)
				{
					PvpBuildCount--;
				}
			}
			else
			{
				value.Pve = build;
			}
			Save();
		}

		private static void Load()
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			if (!File.Exists(_filePath))
			{
				return;
			}
			bool flag = default(bool);
			try
			{
				foreach (KeyValuePair<string, PlayerData> item in SimpleJson.Deserialize(File.ReadAllText(_filePath)))
				{
					if (ulong.TryParse(item.Key, out var result))
					{
						_builds[result] = item.Value;
					}
				}
				PvpBuildCount = 0;
				foreach (PlayerData value in _builds.Values)
				{
					if (value.Pvp != null && !value.Pvp.IsEmpty)
					{
						PvpBuildCount++;
					}
				}
				ManualLogSource logger = Plugin.Logger;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildStorage] Loaded ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_builds.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" players, ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(PvpBuildCount);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" PvP builds.");
				}
				logger.LogInfo(val);
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[BuildStorage] Load failed: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
				}
				logger2.LogError(val2);
			}
		}

		private static void Save()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			try
			{
				string contents = SimpleJson.Serialize(_builds);
				string text = _filePath + ".tmp";
				File.WriteAllText(text, contents);
				File.Move(text, _filePath, overwrite: true);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[BuildStorage] Save failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				logger.LogError(val);
			}
		}
	}
	internal static class SimpleJson
	{
		public static string Serialize(Dictionary<ulong, PlayerData> data)
		{
			StringBuilder stringBuilder = new StringBuilder(256);
			stringBuilder.Append('{');
			bool flag = true;
			foreach (KeyValuePair<ulong, PlayerData> datum in data)
			{
				if (!flag)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append('"').Append(datum.Key).Append("\":{");
				bool flag2 = true;
				if (datum.Value.Pvp != null)
				{
					stringBuilder.Append("\"pvp\":");
					SerializeBuild(stringBuilder, datum.Value.Pvp);
					flag2 = false;
				}
				if (datum.Value.Pve != null)
				{
					if (!flag2)
					{
						stringBuilder.Append(',');
					}
					stringBuilder.Append("\"pve\":");
					SerializeBuild(stringBuilder, datum.Value.Pve);
					flag2 = false;
				}
				if (!datum.Value.AutoEnabled)
				{
					if (!flag2)
					{
						stringBuilder.Append(',');
					}
					stringBuilder.Append("\"auto\":false");
				}
				stringBuilder.Append('}');
				flag = false;
			}
			stringBuilder.Append('}');
			return stringBuilder.ToString();
		}

		private static void SerializeBuild(StringBuilder sb, PlayerBuild b)
		{
			sb.Append('{');
			sb.Append("\"s1\":").Append(b.Spell1);
			sb.Append(",\"s2\":").Append(b.Spell2);
			sb.Append(",\"ult\":").Append(b.Ultimate);
			sb.Append(",\"tr\":").Append(b.Travel);
			sb.Append('}');
		}

		public static Dictionary<string, PlayerData> Deserialize(string json)
		{
			Dictionary<string, PlayerData> dictionary = new Dictionary<string, PlayerData>();
			int idx = 0;
			SkipWhitespace(json, ref idx);
			if (idx >= json.Length || json[idx] != '{')
			{
				return dictionary;
			}
			idx++;
			while (idx < json.Length)
			{
				SkipWhitespace(json, ref idx);
				if (idx >= json.Length || json[idx] == '}')
				{
					break;
				}
				if (json[idx] == ',')
				{
					idx++;
					continue;
				}
				string key = ReadString(json, ref idx);
				SkipWhitespace(json, ref idx);
				if (idx < json.Length && json[idx] == ':')
				{
					idx++;
				}
				PlayerData value = ReadPlayerData(json, ref idx);
				dictionary[key] = value;
			}
			return dictionary;
		}

		private static PlayerData ReadPlayerData(string json, ref int idx)
		{
			PlayerData playerData = new PlayerData();
			SkipWhitespace(json, ref idx);
			if (idx >= json.Length || json[idx] != '{')
			{
				return playerData;
			}
			idx++;
			while (idx < json.Length)
			{
				SkipWhitespace(json, ref idx);
				if (idx >= json.Length || json[idx] == '}')
				{
					idx++;
					break;
				}
				if (json[idx] == ',')
				{
					idx++;
					continue;
				}
				string text = ReadString(json, ref idx);
				SkipWhitespace(json, ref idx);
				if (idx < json.Length && json[idx] == ':')
				{
					idx++;
				}
				if (text == "auto")
				{
					bool autoEnabled = ReadBool(json, ref idx);
					playerData.AutoEnabled = autoEnabled;
					continue;
				}
				PlayerBuild playerBuild = ReadBuild(json, ref idx);
				if (text == "pvp")
				{
					playerData.Pvp = playerBuild;
				}
				else if (text == "pve")
				{
					playerData.Pve = playerBuild;
				}
			}
			return playerData;
		}

		private static PlayerBuild ReadBuild(string json, ref int idx)
		{
			PlayerBuild playerBuild = new PlayerBuild();
			SkipWhitespace(json, ref idx);
			if (idx >= json.Length || json[idx] != '{')
			{
				return playerBuild;
			}
			idx++;
			while (idx < json.Length)
			{
				SkipWhitespace(json, ref idx);
				if (idx >= json.Length || json[idx] == '}')
				{
					idx++;
					break;
				}
				if (json[idx] == ',')
				{
					idx++;
					continue;
				}
				string text = ReadString(json, ref idx);
				SkipWhitespace(json, ref idx);
				if (idx < json.Length && json[idx] == ':')
				{
					idx++;
				}
				int num = ReadInt(json, ref idx);
				switch (text)
				{
				case "s1":
					playerBuild.Spell1 = num;
					break;
				case "s2":
					playerBuild.Spell2 = num;
					break;
				case "ult":
					playerBuild.Ultimate = num;
					break;
				case "tr":
					playerBuild.Travel = num;
					break;
				}
			}
			return playerBuild;
		}

		private static string ReadString(string json, ref int idx)
		{
			SkipWhitespace(json, ref idx);
			if (idx >= json.Length || json[idx] != '"')
			{
				return "";
			}
			idx++;
			int num = idx;
			while (idx < json.Length && json[idx] != '"')
			{
				if (json[idx] == '\\')
				{
					idx++;
				}
				idx++;
			}
			int num2 = num;
			string result = json.Substring(num2, idx - num2);
			if (idx < json.Length)
			{
				idx++;
			}
			return result;
		}

		private static bool ReadBool(string json, ref int idx)
		{
			SkipWhitespace(json, ref idx);
			if (idx + 4 <= json.Length && json.Substring(idx, 4) == "true")
			{
				idx += 4;
				return true;
			}
			if (idx + 5 <= json.Length && json.Substring(idx, 5) == "false")
			{
				idx += 5;
				return false;
			}
			return true;
		}

		private static int ReadInt(string json, ref int idx)
		{
			SkipWhitespace(json, ref idx);
			int num = idx;
			if (idx < json.Length && json[idx] == '-')
			{
				idx++;
			}
			while (idx < json.Length && char.IsDigit(json[idx]))
			{
				idx++;
			}
			if (num == idx)
			{
				return 0;
			}
			int num2 = num;
			if (!int.TryParse(json.Substring(num2, idx - num2), out var result))
			{
				return 0;
			}
			return result;
		}

		private static void SkipWhitespace(string json, ref int idx)
		{
			while (idx < json.Length && char.IsWhiteSpace(json[idx]))
			{
				idx++;
			}
		}
	}
}
namespace AutomaticPvPSwitch.Models
{
	public class PlayerBuild
	{
		public int Spell1 { get; set; }

		public int Spell2 { get; set; }

		public int Ultimate { get; set; }

		public int Travel { get; set; }

		public bool IsEmpty
		{
			get
			{
				if (Spell1 == 0 && Spell2 == 0 && Ultimate == 0)
				{
					return Travel == 0;
				}
				return false;
			}
		}
	}
	public class PlayerData
	{
		public PlayerBuild Pvp { get; set; }

		public PlayerBuild Pve { get; set; }

		public bool AutoEnabled { get; set; } = true;

	}
}
namespace AutomaticPvPSwitch.Hooks
{
	public static class PvPBuffDetector
	{
		private const int PVP_COMBAT_BUFF = 697095869;

		private static World _serverWorld;

		private static BuffSystem_Spawn_Server _system;

		private static bool _logged;

		[EcsSystemUpdatePrefix(typeof(BuffSystem_Spawn_Server), true)]
		public static void Prefix()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			if (!BuildStorage.GlobalEnabled || BuildStorage.PvpBuildCount == 0)
			{
				return;
			}
			BuffSystem_Spawn_Server system = GetSystem();
			if (system == null)
			{
				return;
			}
			if (!_logged)
			{
				Plugin.Logger.LogInfo((object)"[PvPBuffDetector] HookDOTS prefix active on BuffSystem_Spawn_Server.");
				_logged = true;
			}
			EntityQuery _query_401358634_;
			bool flag = default(bool);
			try
			{
				_query_401358634_ = system.__query_401358634_0;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(58, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PvPBuffDetector] Spawn query unavailable (game update?): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				logger.LogError(val);
				return;
			}
			if (((EntityQuery)(ref _query_401358634_)).IsEmpty)
			{
				return;
			}
			EntityManager entityManager = _serverWorld.EntityManager;
			NativeArray<Entity> val2 = default(NativeArray<Entity>);
			try
			{
				val2 = ((EntityQuery)(ref _query_401358634_)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				for (int i = 0; i < val2.Length; i++)
				{
					Entity val3 = val2[i];
					if (((EntityManager)(ref entityManager)).HasComponent<PrefabGUID>(val3) && ((EntityManager)(ref entityManager)).GetComponentData<PrefabGUID>(val3)._Value == 697095869 && ((EntityManager)(ref entityManager)).HasComponent<EntityOwner>(val3))
					{
						Entity owner = ((EntityManager)(ref entityManager)).GetComponentData<EntityOwner>(val3).Owner;
						TrySwitchToPvP(entityManager, owner);
					}
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PvPBuffDetector] ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2);
				}
				logger2.LogError(val);
			}
			finally
			{
				if (val2.IsCreated)
				{
					val2.Dispose();
				}
			}
		}

		private static void TrySwitchToPvP(EntityManager em, Entity charEntity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if (charEntity == Entity.Null || !((EntityManager)(ref em)).Exists(charEntity) || !((EntityManager)(ref em)).HasComponent<PlayerCharacter>(charEntity))
			{
				return;
			}
			Entity userEntity = ((EntityManager)(ref em)).GetComponentData<PlayerCharacter>(charEntity).UserEntity;
			if (userEntity == Entity.Null || !((EntityManager)(ref em)).Exists(userEntity))
			{
				return;
			}
			User componentData = ((EntityManager)(ref em)).GetComponentData<User>(userEntity);
			if (!componentData.IsConnected)
			{
				return;
			}
			ulong platformId = componentData.PlatformId;
			if (!BuildStorage.IsAutoEnabled(platformId))
			{
				return;
			}
			PlayerBuild build = BuildStorage.GetBuild(platformId, "pvp");
			if (build != null && !build.IsEmpty && AbilityHelper.ApplyBuild(em, charEntity, build, platformId))
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[PvPBuffDetector] Auto-switched ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<FixedString64Bytes>(componentData.CharacterName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" to PvP build.");
				}
				logger.LogInfo(val);
			}
		}

		public static bool HasPvPBuff(EntityManager em, Entity charEntity)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!((EntityManager)(ref em)).HasBuffer<BuffBuffer>(charEntity))
			{
				return false;
			}
			DynamicBuffer<BuffBuffer> buffer = ((EntityManager)(ref em)).GetBuffer<BuffBuffer>(charEntity, false);
			for (int i = 0; i < buffer.Length; i++)
			{
				if (buffer[i].PrefabGuid._Value == 697095869)
				{
					return true;
				}
			}
			return false;
		}

		private static BuffSystem_Spawn_Server GetSystem()
		{
			if (_serverWorld != null && _serverWorld.IsCreated && _system != null)
			{
				return _system;
			}
			_serverWorld = null;
			_system = null;
			Enumerator<World> enumerator = World.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current != null && current.IsCreated && current.Name == "Server")
				{
					_serverWorld = current;
					break;
				}
			}
			if (_serverWorld == null)
			{
				return null;
			}
			_system = _serverWorld.GetExistingSystemManaged<BuffSystem_Spawn_Server>();
			return _system;
		}
	}
}