Decompiled source of HexesAndSanguineSteel v1.0.3

HexesAndSanguineSteel.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Gameplay.Systems;
using ProjectM.Gameplay.WarEvents;
using ProjectM.Network;
using ProjectM.Scripting;
using ProjectM.Shared;
using Stunlock.Core;
using Stunlock.Network;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;
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("HexesAndSanguineSteel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Server-side V Rising custom weapon, spell override, stat, weapon-type buff, and school on-hit mod.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("HexesAndSanguineSteel")]
[assembly: AssemblyTitle("HexesAndSanguineSteel")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HexesAndSanguineSteel
{
	[HarmonyPatch(typeof(WarEventRegistrySystem), "RegisterWarEventEntities")]
	internal static class Bootstrap
	{
		private static ManualLogSource? _log;

		private static bool _initialized;

		internal static void Initialize(Harmony harmony, ManualLogSource log)
		{
			_log = log;
			harmony.CreateClassProcessor(typeof(Bootstrap)).Patch();
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			if (_initialized)
			{
				return;
			}
			_initialized = true;
			try
			{
				CustomWeaponRegistry.ApplyAll();
				RuntimeOptimization.InfoOnce("bootstrap-prefab-mutations", "Hexes and Sanguine Steel bootstrap completed; runtime systems registered.");
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Custom weapon bootstrap failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}
	}
	internal static class CustomWeaponConfig
	{
		internal const int DefaultRuntimeCarrierBuff = -1721561549;

		internal const int DefaultRuntimeStatCarrierBuff = -1122472005;

		private const string DirectoryName = "HexesAndSanguineSteel";

		private const string LegacyDirectoryName = "CustomWeaponMod";

		private const string FileName = "weapons.json";

		private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
		{
			WriteIndented = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			AllowTrailingCommas = true,
			PropertyNameCaseInsensitive = true
		};

		private static WeaponConfigFile? _currentFile;

		private static IReadOnlyList<CustomWeaponDef> _currentDefinitions = Array.Empty<CustomWeaponDef>();

		private static IReadOnlyList<WeaponTypeBuffDef> _currentTypeBuffDefinitions = Array.Empty<WeaponTypeBuffDef>();

		private static IReadOnlyList<CustomWeaponCostDef> _globalUpgradeCost = Array.Empty<CustomWeaponCostDef>();

		internal static string ConfigDirectory => Path.Combine(Paths.ConfigPath, "HexesAndSanguineSteel");

		internal static string ConfigPath => Path.Combine(ConfigDirectory, "weapons.json");

		private static string LegacyConfigDirectory => Path.Combine(Paths.ConfigPath, "CustomWeaponMod");

		private static string LegacyConfigPath => Path.Combine(LegacyConfigDirectory, "weapons.json");

		internal static int CustomWeaponCarrierBuff => _currentFile?.DefaultCustomWeaponCarrierBuff ?? (-1721561549);

		internal static int CustomWeaponStatCarrierBuff => _currentFile?.DefaultCustomWeaponStatCarrierBuff ?? (-1122472005);

		internal static IReadOnlyList<WeaponTypeBuffDef> WeaponTypeBuffs => _currentTypeBuffDefinitions;

		internal static IReadOnlyList<CustomWeaponCostDef> GlobalUpgradeCost => _globalUpgradeCost;

		internal static bool DebugLogging => _currentFile?.DebugLogging ?? false;

		internal static double AdminRefreshCooldownSeconds => _currentFile?.AdminRefreshCooldownSeconds ?? 5.0;

		private static void CopyLegacyConfigIfNeeded()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			if (!File.Exists(ConfigPath) && File.Exists(LegacyConfigPath))
			{
				Directory.CreateDirectory(ConfigDirectory);
				File.Copy(LegacyConfigPath, ConfigPath, overwrite: false);
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(70, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Migrated legacy CustomWeaponMod config file to HexesAndSanguineSteel: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
				}
				logInstance.LogInfo(val);
			}
		}

		internal static IReadOnlyList<CustomWeaponDef> LoadOrCreate()
		{
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_066e: Expected O, but got Unknown
			Directory.CreateDirectory(ConfigDirectory);
			CopyLegacyConfigIfNeeded();
			bool flag = default(bool);
			if (!File.Exists(ConfigPath))
			{
				_currentFile = WeaponConfigFile.CreateDefault();
				_currentDefinitions = _currentFile.ToDefinitions();
				_currentTypeBuffDefinitions = _currentFile.ToWeaponTypeBuffDefinitions();
				_globalUpgradeCost = _currentFile.ToGlobalUpgradeCost();
				Save(_currentFile);
				ManualLogSource logInstance = Plugin.LogInstance;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(30, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Created custom weapon config: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
				}
				logInstance.LogInfo(val);
				return _currentDefinitions;
			}
			try
			{
				WeaponConfigFile weaponConfigFile = JsonSerializer.Deserialize<WeaponConfigFile>(File.ReadAllText(ConfigPath), JsonOptions);
				if (weaponConfigFile == null)
				{
					weaponConfigFile = WeaponConfigFile.CreateDefault();
					Save(weaponConfigFile);
				}
				WeaponConfigFile weaponConfigFile2 = weaponConfigFile;
				if (weaponConfigFile2.Weapons == null)
				{
					List<WeaponConfigEntry> list = (weaponConfigFile2.Weapons = new List<WeaponConfigEntry>());
				}
				weaponConfigFile2 = weaponConfigFile;
				if (weaponConfigFile2.WeaponTypeBuffs == null)
				{
					List<WeaponTypeBuffConfigEntry> list3 = (weaponConfigFile2.WeaponTypeBuffs = new List<WeaponTypeBuffConfigEntry>());
				}
				weaponConfigFile2 = weaponConfigFile;
				if (weaponConfigFile2.GlobalUpgradeCost == null)
				{
					List<WeaponUpgradeCostConfigEntry> list5 = (weaponConfigFile2.GlobalUpgradeCost = new List<WeaponUpgradeCostConfigEntry>());
				}
				bool flag2 = false;
				if (weaponConfigFile.ConfigVersion < 6)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 6;
					flag2 = true;
					if (weaponConfigFile.DefaultCustomWeaponCarrierBuff == 0)
					{
						weaponConfigFile.DefaultCustomWeaponCarrierBuff = -1721561549;
					}
					if (weaponConfigFile.DefaultCustomWeaponStatCarrierBuff == 0)
					{
						weaponConfigFile.DefaultCustomWeaponStatCarrierBuff = -1122472005;
					}
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v6. Custom weapon stats are now applied with runtime stat carrier buffs.");
				}
				if (weaponConfigFile.ConfigVersion < 7)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 7;
					weaponConfigFile2 = weaponConfigFile;
					if (weaponConfigFile2.WeaponTypeBuffs == null)
					{
						List<WeaponTypeBuffConfigEntry> list3 = (weaponConfigFile2.WeaponTypeBuffs = new List<WeaponTypeBuffConfigEntry>());
					}
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v7. Added WeaponTypeBuffs[] using the same runtime stat carrier.");
				}
				if (weaponConfigFile.ConfigVersion < 8)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 9;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v8. Custom weapons can now override R and C slots.");
				}
				if (weaponConfigFile.ConfigVersion < 10)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 10;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v10. Legacy PhysicalPower/SpellPower are ignored when Stats[] is non-empty; generated configs set them to 0 to avoid double-stat confusion.");
				}
				if (weaponConfigFile.ConfigVersion < 11)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 11;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v11. Added DebugLogging and AdminRefreshCooldownSeconds for lower-noise live operation.");
				}
				if (weaponConfigFile.ConfigVersion < 12)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 12;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v12. Added per-weapon UpgradeCost[] consumed by .csw upgrade.");
				}
				if (weaponConfigFile.ConfigVersion < 13)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 13;
					weaponConfigFile2 = weaponConfigFile;
					if (weaponConfigFile2.GlobalUpgradeCost == null)
					{
						List<WeaponUpgradeCostConfigEntry> list5 = (weaponConfigFile2.GlobalUpgradeCost = new List<WeaponUpgradeCostConfigEntry>());
					}
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v13. Added GlobalUpgradeCost[] used as the default cost for every .csw upgrade.");
				}
				if (weaponConfigFile.ConfigVersion < 14)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 14;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v14. Removed per-weapon UpgradeCost[]; .csw upgrade now uses GlobalUpgradeCost only.");
				}
				if (weaponConfigFile.ConfigVersion < 15)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 15;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v15. Added custom weapon OnHitEffects[] for spell-school/coating-style procs.");
				}
				if (weaponConfigFile.ConfigVersion < 16)
				{
					BackupPreMigrationConfig(weaponConfigFile.ConfigVersion);
					weaponConfigFile.ConfigVersion = 16;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded weapons.json to schema v16. Removed SecondaryBuff on-hit behavior; OnHitEffects now apply only the Bloodcraft class school debuffs.");
				}
				if (weaponConfigFile.DefaultCustomWeaponCarrierBuff == 0)
				{
					weaponConfigFile.DefaultCustomWeaponCarrierBuff = -1721561549;
					flag2 = true;
				}
				if (weaponConfigFile.DefaultCustomWeaponStatCarrierBuff == 0)
				{
					weaponConfigFile.DefaultCustomWeaponStatCarrierBuff = -1122472005;
					flag2 = true;
				}
				weaponConfigFile2 = weaponConfigFile;
				if (weaponConfigFile2.GlobalUpgradeCost == null)
				{
					List<WeaponUpgradeCostConfigEntry> list5 = (weaponConfigFile2.GlobalUpgradeCost = new List<WeaponUpgradeCostConfigEntry>());
				}
				foreach (WeaponConfigEntry weapon in weaponConfigFile.Weapons)
				{
					if (weapon.SpellSlot1 == 0 && weapon.R != 0)
					{
						weapon.SpellSlot1 = weapon.R;
						weapon.SpellSlot1Cooldown = weapon.RCooldown;
						weapon.R = 0;
						weapon.RCooldown = 0f;
						flag2 = true;
					}
					if (weapon.SpellSlot2 == 0 && weapon.C != 0)
					{
						weapon.SpellSlot2 = weapon.C;
						weapon.SpellSlot2Cooldown = weapon.CCooldown;
						weapon.C = 0;
						weapon.CCooldown = 0f;
						flag2 = true;
					}
					WeaponConfigEntry weaponConfigEntry = weapon;
					if (weaponConfigEntry.Stats == null)
					{
						List<WeaponStatConfigEntry> list10 = (weaponConfigEntry.Stats = new List<WeaponStatConfigEntry>());
					}
					weaponConfigEntry = weapon;
					if (weaponConfigEntry.OnHitEffects == null)
					{
						List<WeaponOnHitEffectConfigEntry> list12 = (weaponConfigEntry.OnHitEffects = new List<WeaponOnHitEffectConfigEntry>());
					}
					if (weapon.Stats.Count == 0)
					{
						if (weapon.PhysicalPower != 0f)
						{
							weapon.Stats.Add(new WeaponStatConfigEntry
							{
								StatType = "PhysicalPower",
								ModificationType = "AddToBase",
								AttributeCapType = "SoftCapped",
								Value = weapon.PhysicalPower
							});
						}
						if (weapon.SpellPower != 0f)
						{
							weapon.Stats.Add(new WeaponStatConfigEntry
							{
								StatType = "SpellPower",
								ModificationType = "AddToBase",
								AttributeCapType = "SoftCapped",
								Value = weapon.SpellPower
							});
						}
						if (weapon.Stats.Count > 0)
						{
							flag2 = true;
						}
					}
					if (weapon.Stats.Count > 0 && (weapon.PhysicalPower != 0f || weapon.SpellPower != 0f))
					{
						weapon.PhysicalPower = 0f;
						weapon.SpellPower = 0f;
						flag2 = true;
					}
				}
				if (flag2)
				{
					Save(weaponConfigFile);
				}
				_currentFile = weaponConfigFile;
				_currentDefinitions = weaponConfigFile.ToDefinitions();
				_currentTypeBuffDefinitions = weaponConfigFile.ToWeaponTypeBuffDefinitions();
				_globalUpgradeCost = weaponConfigFile.ToGlobalUpgradeCost();
				return _currentDefinitions;
			}
			catch (Exception ex)
			{
				string text = ConfigPath + ".broken";
				try
				{
					if (File.Exists(text))
					{
						File.Delete(text);
					}
					if (File.Exists(ConfigPath))
					{
						File.Move(ConfigPath, text);
					}
				}
				catch (Exception ex2)
				{
					ManualLogSource logInstance2 = Plugin.LogInstance;
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(33, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not back up broken config: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex2.Message);
					}
					logInstance2.LogWarning(val2);
				}
				_currentFile = WeaponConfigFile.CreateDefault();
				_currentDefinitions = _currentFile.ToDefinitions();
				_currentTypeBuffDefinitions = _currentFile.ToWeaponTypeBuffDefinitions();
				_globalUpgradeCost = _currentFile.ToGlobalUpgradeCost();
				Save(_currentFile);
				ManualLogSource logInstance3 = Plugin.LogInstance;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(92, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to read custom weapon config. Backed up broken file to '");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' and wrote defaults. Error: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				logInstance3.LogError(val3);
				return _currentDefinitions;
			}
		}

		private static void BackupPreMigrationConfig(int oldVersion)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			try
			{
				string text = ConfigPath + $".v{oldVersion}.backup";
				if (File.Exists(text))
				{
					File.Delete(text);
				}
				if (File.Exists(ConfigPath))
				{
					File.Copy(ConfigPath, text);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not create weapons.json migration backup: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				logInstance.LogWarning(val);
			}
		}

		private static void Save(WeaponConfigFile config)
		{
			Directory.CreateDirectory(ConfigDirectory);
			File.WriteAllText(ConfigPath, JsonSerializer.Serialize(config, JsonOptions));
		}
	}
	internal sealed class WeaponConfigFile
	{
		public int ConfigVersion { get; set; } = 16;

		public bool DebugLogging { get; set; }

		public double AdminRefreshCooldownSeconds { get; set; } = 5.0;

		public int DefaultCustomWeaponCarrierBuff { get; set; } = -1721561549;

		public int DefaultCustomWeaponStatCarrierBuff { get; set; } = -1122472005;

		public List<WeaponUpgradeCostConfigEntry> GlobalUpgradeCost { get; set; } = new List<WeaponUpgradeCostConfigEntry>();

		public List<WeaponConfigEntry> Weapons { get; set; } = new List<WeaponConfigEntry>();

		public List<WeaponTypeBuffConfigEntry> WeaponTypeBuffs { get; set; } = new List<WeaponTypeBuffConfigEntry>();

		public static WeaponConfigFile CreateDefault()
		{
			return new WeaponConfigFile
			{
				ConfigVersion = 16,
				DefaultCustomWeaponCarrierBuff = -1721561549,
				DefaultCustomWeaponStatCarrierBuff = -1122472005,
				GlobalUpgradeCost = new List<WeaponUpgradeCostConfigEntry>(),
				WeaponTypeBuffs = new List<WeaponTypeBuffConfigEntry>(1)
				{
					new WeaponTypeBuffConfigEntry
					{
						Enabled = false,
						WeaponType = "Mace",
						ApplyToCustomWeapons = true,
						Stats = new List<WeaponStatConfigEntry>(1)
						{
							new WeaponStatConfigEntry
							{
								StatType = "AttackSpeed",
								ModificationType = "AddToBase",
								AttributeCapType = "SoftCapped",
								Value = 0.1f
							}
						}
					}
				},
				Weapons = new List<WeaponConfigEntry>(1)
				{
					new WeaponConfigEntry
					{
						Enabled = true,
						Name = "Crimson Thorns",
						ItemWeapon = 1307774440,
						EquipBuff = 673013659,
						WeaponLevel = 100f,
						PhysicalPower = 0f,
						SpellPower = 0f,
						Stats = new List<WeaponStatConfigEntry>(3)
						{
							new WeaponStatConfigEntry
							{
								StatType = "PhysicalPower",
								ModificationType = "AddToBase",
								AttributeCapType = "SoftCapped",
								Value = 35f
							},
							new WeaponStatConfigEntry
							{
								StatType = "SpellPower",
								ModificationType = "AddToBase",
								AttributeCapType = "SoftCapped",
								Value = 10f
							},
							new WeaponStatConfigEntry
							{
								StatType = "PhysicalResistance",
								ModificationType = "AddToBase",
								AttributeCapType = "SoftCapped",
								Value = 6f
							}
						},
						OnHitEffects = new List<WeaponOnHitEffectConfigEntry>(),
						Attack = -208121356,
						AttackCooldown = 0f,
						Primary = 1826128809,
						PrimaryCooldown = 8f,
						Secondary = 1730729556,
						SecondaryCooldown = 10f,
						Dash = -1940289109,
						DashCooldown = 6f,
						Ultimate = -1730693034,
						UltimateCooldown = 60f,
						SpellSlot1 = 841757706,
						SpellSlot1Cooldown = 8f,
						SpellSlot2 = 1295370119,
						SpellSlot2Cooldown = 8f
					}
				}
			};
		}

		public IReadOnlyList<CustomWeaponDef> ToDefinitions()
		{
			List<CustomWeaponDef> list = new List<CustomWeaponDef>();
			foreach (WeaponConfigEntry weapon in Weapons)
			{
				if (weapon.Enabled)
				{
					list.Add(weapon.ToDefinition(DefaultCustomWeaponCarrierBuff, DefaultCustomWeaponStatCarrierBuff));
				}
			}
			return list;
		}

		public IReadOnlyList<CustomWeaponCostDef> ToGlobalUpgradeCost()
		{
			if (GlobalUpgradeCost == null)
			{
				List<WeaponUpgradeCostConfigEntry> list = (GlobalUpgradeCost = new List<WeaponUpgradeCostConfigEntry>());
			}
			return WeaponConfigEntry.BuildUpgradeCost("GlobalUpgradeCost", GlobalUpgradeCost);
		}

		public IReadOnlyList<WeaponTypeBuffDef> ToWeaponTypeBuffDefinitions()
		{
			List<WeaponTypeBuffDef> list = new List<WeaponTypeBuffDef>();
			foreach (WeaponTypeBuffConfigEntry weaponTypeBuff in WeaponTypeBuffs)
			{
				if (weaponTypeBuff.Enabled)
				{
					WeaponTypeBuffConfigEntry weaponTypeBuffConfigEntry = weaponTypeBuff;
					if (weaponTypeBuffConfigEntry.Stats == null)
					{
						List<WeaponStatConfigEntry> list2 = (weaponTypeBuffConfigEntry.Stats = new List<WeaponStatConfigEntry>());
					}
					list.Add(new WeaponTypeBuffDef(weaponTypeBuff.WeaponType, weaponTypeBuff.ApplyToCustomWeapons, StatConfigBuilder.BuildStats("WeaponTypeBuff:" + weaponTypeBuff.WeaponType, weaponTypeBuff.Stats)));
				}
			}
			return list;
		}
	}
	internal sealed class WeaponConfigEntry
	{
		public bool Enabled { get; set; } = true;

		public string Name { get; set; } = "Custom Weapon";

		public int ItemWeapon { get; set; }

		public int EquipBuff { get; set; }

		public int CarrierBuff { get; set; }

		public int StatCarrierBuff { get; set; }

		public float WeaponLevel { get; set; } = 100f;

		public float PhysicalPower { get; set; } = 35f;

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

		public List<WeaponStatConfigEntry> Stats { get; set; } = new List<WeaponStatConfigEntry>();

		public List<WeaponOnHitEffectConfigEntry> OnHitEffects { get; set; } = new List<WeaponOnHitEffectConfigEntry>();

		[JsonIgnore]
		public List<WeaponUpgradeCostConfigEntry> UpgradeCost { get; set; } = new List<WeaponUpgradeCostConfigEntry>();

		public int Attack { get; set; }

		public float AttackCooldown { get; set; }

		public int Primary { get; set; }

		public float PrimaryCooldown { get; set; }

		public int Secondary { get; set; }

		public float SecondaryCooldown { get; set; }

		public int Dash { get; set; }

		public float DashCooldown { get; set; }

		public int Ultimate { get; set; }

		public float UltimateCooldown { get; set; }

		[JsonPropertyName("Spell Slot 1")]
		public int SpellSlot1 { get; set; }

		[JsonPropertyName("Spell Slot 1 Cooldown")]
		public float SpellSlot1Cooldown { get; set; }

		[JsonPropertyName("Spell Slot 2")]
		public int SpellSlot2 { get; set; }

		[JsonPropertyName("Spell Slot 2 Cooldown")]
		public float SpellSlot2Cooldown { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
		public int R { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
		public float RCooldown { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
		public int C { get; set; }

		[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
		public float CCooldown { get; set; }

		public CustomWeaponDef ToDefinition(int defaultCarrierBuff, int defaultStatCarrierBuff)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			return new CustomWeaponDef(Name, Guid(ItemWeapon), Guid(EquipBuff), Guid((CarrierBuff != 0) ? CarrierBuff : defaultCarrierBuff), Guid((StatCarrierBuff != 0) ? StatCarrierBuff : defaultStatCarrierBuff), Array.Empty<CustomWeaponCostDef>(), new WeaponPowerDef(WeaponLevel, PhysicalPower, SpellPower), StatConfigBuilder.BuildStats(Name, Stats), BuildOnHitEffects(Name, OnHitEffects), Slot(Attack, AttackCooldown), Slot(Primary, PrimaryCooldown), Slot(Secondary, SecondaryCooldown), Slot(Dash, DashCooldown), Slot(Ultimate, UltimateCooldown), Slot(SpellSlot1, SpellSlot1Cooldown), Slot(SpellSlot2, SpellSlot2Cooldown));
		}

		private static IReadOnlyList<CustomWeaponStatDef> BuildStats(string weaponName, List<WeaponStatConfigEntry> stats)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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)
			List<CustomWeaponStatDef> list = new List<CustomWeaponStatDef>();
			foreach (WeaponStatConfigEntry stat in stats)
			{
				ModificationType result2;
				AttributeCapType result3;
				if (!Enum.TryParse<UnitStatType>(stat.StatType, ignoreCase: true, out UnitStatType result))
				{
					RuntimeOptimization.WarnOnce("stat-unknown:" + weaponName + ":" + stat.StatType, weaponName + ": unknown UnitStatType '" + stat.StatType + "'. Stat entry skipped.");
				}
				else if (!Enum.TryParse<ModificationType>(stat.ModificationType, ignoreCase: true, out result2))
				{
					RuntimeOptimization.WarnOnce("modtype-unknown:" + weaponName + ":" + stat.ModificationType, weaponName + ": unknown ModificationType '" + stat.ModificationType + "'. Stat entry skipped.");
				}
				else if (!Enum.TryParse<AttributeCapType>(stat.AttributeCapType, ignoreCase: true, out result3))
				{
					RuntimeOptimization.WarnOnce("captype-unknown:" + weaponName + ":" + stat.AttributeCapType, weaponName + ": unknown AttributeCapType '" + stat.AttributeCapType + "'. Stat entry skipped.");
				}
				else
				{
					list.Add(new CustomWeaponStatDef(result, result2, result3, stat.Value));
				}
			}
			return list;
		}

		private static IReadOnlyList<CustomWeaponOnHitEffectDef> BuildOnHitEffects(string weaponName, List<WeaponOnHitEffectConfigEntry> effects)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			List<CustomWeaponOnHitEffectDef> list = new List<CustomWeaponOnHitEffectDef>();
			if (effects == null)
			{
				effects = new List<WeaponOnHitEffectConfigEntry>();
			}
			foreach (WeaponOnHitEffectConfigEntry effect in effects)
			{
				if (effect.Enabled && !(effect.Chance <= 0f))
				{
					if (effect.TargetBuff == 0)
					{
						RuntimeOptimization.WarnOnce("onhit-target0:" + weaponName + ":" + effect.Name, weaponName + ": on-hit effect '" + effect.Name + "' has TargetBuff 0. Effect skipped.");
						continue;
					}
					list.Add(new CustomWeaponOnHitEffectDef(string.IsNullOrWhiteSpace(effect.Name) ? $"OnHit:{effect.TargetBuff}" : effect.Name, effect.School ?? string.Empty, Math.Clamp(effect.Chance, 0f, 1f), Guid(effect.TargetBuff), effect.AffectPlayers, effect.AffectNonPlayers));
				}
			}
			return list;
		}

		internal static IReadOnlyList<CustomWeaponCostDef> BuildUpgradeCost(string weaponName, List<WeaponUpgradeCostConfigEntry> costs)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			List<CustomWeaponCostDef> list = new List<CustomWeaponCostDef>();
			if (costs == null)
			{
				costs = new List<WeaponUpgradeCostConfigEntry>();
			}
			bool flag = default(bool);
			foreach (WeaponUpgradeCostConfigEntry cost in costs)
			{
				if (cost.Amount <= 0)
				{
					ManualLogSource logInstance = Plugin.LogInstance;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(63, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(weaponName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": upgrade cost '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(cost.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has non-positive Amount ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(cost.Amount);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Cost entry skipped.");
					}
					logInstance.LogWarning(val);
				}
				else if (cost.Item == 0)
				{
					ManualLogSource logInstance2 = Plugin.LogInstance;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(49, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(weaponName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": upgrade cost '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(cost.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has Item 0. Cost entry skipped.");
					}
					logInstance2.LogWarning(val);
				}
				else
				{
					list.Add(new CustomWeaponCostDef(string.IsNullOrWhiteSpace(cost.Name) ? cost.Item.ToString() : cost.Name, Guid(cost.Item), cost.Amount));
				}
			}
			return list;
		}

		private static PrefabGUID Guid(int hash)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return new PrefabGUID(hash);
		}

		private static AbilitySlotDef Slot(int guidHash, float cooldown)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return new AbilitySlotDef(Guid(guidHash), cooldown);
		}
	}
	internal sealed class WeaponOnHitEffectConfigEntry
	{
		public bool Enabled { get; set; } = true;

		public string Name { get; set; } = string.Empty;

		public string School { get; set; } = string.Empty;

		public float Chance { get; set; } = 0.15f;

		public int TargetBuff { get; set; }

		public bool AffectPlayers { get; set; }

		public bool AffectNonPlayers { get; set; } = true;
	}
	internal sealed class WeaponUpgradeCostConfigEntry
	{
		public string Name { get; set; } = string.Empty;

		public int Item { get; set; }

		public int Amount { get; set; }
	}
	internal sealed class WeaponTypeBuffConfigEntry
	{
		public bool Enabled { get; set; } = true;

		public string WeaponType { get; set; } = "Mace";

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

		public List<WeaponStatConfigEntry> Stats { get; set; } = new List<WeaponStatConfigEntry>();
	}
	internal static class StatConfigBuilder
	{
		private static readonly Dictionary<string, string> UnitStatAliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			["AS"] = "PrimaryAttackSpeed",
			["AttackSpeed"] = "PrimaryAttackSpeed",
			["PrimaryAttackSpeed"] = "PrimaryAttackSpeed",
			["AAS"] = "AbilityAttackSpeed",
			["AbilitySpeed"] = "AbilityAttackSpeed",
			["AbilityAttackSpeed"] = "AbilityAttackSpeed",
			["MS"] = "MovementSpeed",
			["MoveSpeed"] = "MovementSpeed",
			["MovementSpeed"] = "MovementSpeed"
		};

		private static readonly Dictionary<string, string> AttributeCapAliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			["UnCapped"] = "Uncapped",
			["Uncapped"] = "Uncapped",
			["NoCap"] = "Uncapped",
			["NoCaps"] = "Uncapped",
			["IgnoreCap"] = "Uncapped",
			["IgnoreCaps"] = "Uncapped",
			["None"] = "Uncapped"
		};

		internal static IReadOnlyList<CustomWeaponStatDef> BuildStats(string ownerName, List<WeaponStatConfigEntry> stats)
		{
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			List<CustomWeaponStatDef> list = new List<CustomWeaponStatDef>();
			foreach (WeaponStatConfigEntry stat in stats)
			{
				if (!TryParseUnitStatType(stat.StatType, out UnitStatType value, out string resolvedName))
				{
					RuntimeOptimization.WarnOnce("stat-unknown:" + ownerName + ":" + stat.StatType, ownerName + ": unknown UnitStatType '" + stat.StatType + "'. Stat entry skipped. Run .csw stattypes or use aliases like AttackSpeed/AS -> PrimaryAttackSpeed.");
					continue;
				}
				if (!Enum.TryParse<ModificationType>(stat.ModificationType, ignoreCase: true, out ModificationType result))
				{
					RuntimeOptimization.WarnOnce("modtype-unknown:" + ownerName + ":" + stat.ModificationType, ownerName + ": unknown ModificationType '" + stat.ModificationType + "'. Stat entry skipped.");
					continue;
				}
				if (!TryParseAttributeCapType(stat.AttributeCapType, out AttributeCapType value2, out string resolvedName2))
				{
					RuntimeOptimization.WarnOnce("captype-unknown:" + ownerName + ":" + stat.AttributeCapType, ownerName + ": unknown AttributeCapType '" + stat.AttributeCapType + "'. Stat entry skipped.");
					continue;
				}
				if (!string.Equals(stat.StatType, resolvedName, StringComparison.OrdinalIgnoreCase))
				{
					RuntimeOptimization.Debug($"{ownerName}: mapped UnitStatType alias '{stat.StatType}' -> '{resolvedName}'.");
				}
				if (!string.Equals(stat.AttributeCapType, resolvedName2, StringComparison.OrdinalIgnoreCase))
				{
					RuntimeOptimization.Debug($"{ownerName}: mapped AttributeCapType alias '{stat.AttributeCapType}' -> '{resolvedName2}'.");
				}
				list.Add(new CustomWeaponStatDef(value, result, value2, stat.Value));
			}
			return list;
		}

		private static bool TryParseUnitStatType(string rawName, out UnitStatType value, out string resolvedName)
		{
			resolvedName = rawName?.Trim() ?? string.Empty;
			if (Enum.TryParse<UnitStatType>(resolvedName, ignoreCase: true, out value))
			{
				return true;
			}
			if (UnitStatAliases.TryGetValue(resolvedName, out string value2) && Enum.TryParse<UnitStatType>(value2, ignoreCase: true, out value))
			{
				resolvedName = value2;
				return true;
			}
			value = (UnitStatType)0;
			return false;
		}

		private static bool TryParseAttributeCapType(string rawName, out AttributeCapType value, out string resolvedName)
		{
			resolvedName = rawName?.Trim() ?? string.Empty;
			if (Enum.TryParse<AttributeCapType>(resolvedName, ignoreCase: true, out value))
			{
				return true;
			}
			if (AttributeCapAliases.TryGetValue(resolvedName, out string value2) && Enum.TryParse<AttributeCapType>(value2, ignoreCase: true, out value))
			{
				resolvedName = value2;
				return true;
			}
			value = (AttributeCapType)0;
			return false;
		}
	}
	internal sealed class WeaponStatConfigEntry
	{
		public string StatType { get; set; } = "PhysicalPower";

		public string ModificationType { get; set; } = "AddToBase";

		public string AttributeCapType { get; set; } = "SoftCapped";

		public float Value { get; set; }
	}
	internal enum SpellSlotKind
	{
		Q,
		E,
		Dash,
		R,
		C,
		T
	}
	internal sealed class PlayerSpellOverrideFile
	{
		public int ConfigVersion { get; set; } = 8;

		public int DefaultCarrierBuff { get; set; } = 1644894901;

		public Dictionary<string, PlayerSpellOverrideEntry> Players { get; set; } = new Dictionary<string, PlayerSpellOverrideEntry>();
	}
	internal sealed class PlayerSpellOverrideEntry
	{
		public bool Enabled { get; set; } = true;

		public ulong PlatformId { get; set; }

		public string LastKnownName { get; set; } = string.Empty;

		public int CarrierBuff { get; set; }

		public Dictionary<string, PlayerSpellScopeEntry> WeaponScopes { get; set; } = new Dictionary<string, PlayerSpellScopeEntry>();

		public int Q { get; set; }

		public float QCooldown { get; set; }

		public int E { get; set; }

		public float ECooldown { get; set; }

		public int Dash { get; set; }

		public float DashCooldown { get; set; }

		public int R { get; set; }

		public float RCooldown { get; set; }

		public int C { get; set; }

		public float CCooldown { get; set; }

		public int T { get; set; }

		public float TCooldown { get; set; }
	}
	internal sealed class PlayerSpellScopeEntry
	{
		public int Q { get; set; }

		public float QCooldown { get; set; }

		public int E { get; set; }

		public float ECooldown { get; set; }

		public int Dash { get; set; }

		public float DashCooldown { get; set; }

		public int R { get; set; }

		public float RCooldown { get; set; }

		public int C { get; set; }

		public float CCooldown { get; set; }

		public int T { get; set; }

		public float TCooldown { get; set; }

		public bool HasAnySpell()
		{
			if (Q == 0 && E == 0 && Dash == 0 && R == 0 && C == 0)
			{
				return T != 0;
			}
			return true;
		}
	}
	internal static class PlayerSpellOverrideConfig
	{
		internal const int LegacyConflictingCarrierBuff = 673013659;

		internal const int SafeDefaultCarrierBuff = 1644894901;

		private const string DirectoryName = "HexesAndSanguineSteel";

		private const string LegacyDirectoryName = "CustomWeaponMod";

		private const string FileName = "player-spells.json";

		private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
		{
			WriteIndented = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			AllowTrailingCommas = true,
			PropertyNameCaseInsensitive = true
		};

		private static PlayerSpellOverrideFile? _cache;

		internal static string ConfigDirectory => Path.Combine(Paths.ConfigPath, "HexesAndSanguineSteel");

		internal static string ConfigPath => Path.Combine(ConfigDirectory, "player-spells.json");

		private static string LegacyConfigDirectory => Path.Combine(Paths.ConfigPath, "CustomWeaponMod");

		private static string LegacyConfigPath => Path.Combine(LegacyConfigDirectory, "player-spells.json");

		internal static PlayerSpellOverrideFile Current => _cache ?? LoadOrCreate();

		private static void CopyLegacyConfigIfNeeded()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			if (!File.Exists(ConfigPath) && File.Exists(LegacyConfigPath))
			{
				Directory.CreateDirectory(ConfigDirectory);
				File.Copy(LegacyConfigPath, ConfigPath, overwrite: false);
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(70, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Migrated legacy CustomWeaponMod config file to HexesAndSanguineSteel: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
				}
				logInstance.LogInfo(val);
			}
		}

		internal static PlayerSpellOverrideFile LoadOrCreate()
		{
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			Directory.CreateDirectory(ConfigDirectory);
			CopyLegacyConfigIfNeeded();
			bool flag = default(bool);
			if (!File.Exists(ConfigPath))
			{
				_cache = new PlayerSpellOverrideFile();
				Save(_cache);
				ManualLogSource logInstance = Plugin.LogInstance;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Created player spell override config: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ConfigPath);
				}
				logInstance.LogInfo(val);
				return _cache;
			}
			try
			{
				_cache = JsonSerializer.Deserialize<PlayerSpellOverrideFile>(File.ReadAllText(ConfigPath), JsonOptions) ?? new PlayerSpellOverrideFile();
				PlayerSpellOverrideFile cache = _cache;
				if (cache.Players == null)
				{
					Dictionary<string, PlayerSpellOverrideEntry> dictionary = (cache.Players = new Dictionary<string, PlayerSpellOverrideEntry>());
				}
				foreach (PlayerSpellOverrideEntry value in _cache.Players.Values)
				{
					if (value.WeaponScopes == null)
					{
						Dictionary<string, PlayerSpellScopeEntry> dictionary3 = (value.WeaponScopes = new Dictionary<string, PlayerSpellScopeEntry>());
					}
				}
				bool flag2 = false;
				if (_cache.ConfigVersion < 3)
				{
					BackupPreMigrationConfig();
					_cache.ConfigVersion = 3;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded player spell override config to weapon-scoped schema v3. Legacy flat Q/E/T fields were preserved but are no longer applied unless re-saved with commands.");
				}
				if (_cache.ConfigVersion < 4 || _cache.DefaultCarrierBuff == 673013659)
				{
					BackupPreMigrationConfig();
					if (_cache.DefaultCarrierBuff == 673013659)
					{
						_cache.DefaultCarrierBuff = 1644894901;
						flag2 = true;
						ManualLogSource logInstance2 = Plugin.LogInstance;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(124, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Migrated DefaultCarrierBuff away from ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(673013659);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" because it conflicts with the default custom spear equip buff. New default carrier: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(1644894901);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
						}
						logInstance2.LogWarning(val2);
					}
					foreach (PlayerSpellOverrideEntry value2 in _cache.Players.Values)
					{
						if (value2.CarrierBuff == 673013659)
						{
							value2.CarrierBuff = 0;
							flag2 = true;
						}
					}
					_cache.ConfigVersion = 4;
					flag2 = true;
				}
				if (_cache.ConfigVersion < 5)
				{
					BackupPreMigrationConfig();
					_cache.ConfigVersion = 5;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded player spell override config to schema v5. Dash, R, and C weapon-scoped spell slots are now supported.");
				}
				if (_cache.ConfigVersion < 6)
				{
					BackupPreMigrationConfig();
					_cache.ConfigVersion = 6;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded player spell override config to schema v6. SpellPool support was removed.");
				}
				if (_cache.ConfigVersion < 8)
				{
					BackupPreMigrationConfig();
					_cache.ConfigVersion = 8;
					flag2 = true;
					Plugin.LogInstance.LogInfo((object)"Upgraded player spell override config to schema v8. Experimental spell charge fields were removed.");
				}
				if (flag2)
				{
					Save(_cache);
				}
				return _cache;
			}
			catch (Exception ex)
			{
				string text = ConfigPath + ".broken";
				try
				{
					if (File.Exists(text))
					{
						File.Delete(text);
					}
					File.Move(ConfigPath, text);
				}
				catch (Exception ex2)
				{
					ManualLogSource logInstance3 = Plugin.LogInstance;
					BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not back up broken player spell config: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex2.Message);
					}
					logInstance3.LogWarning(val2);
				}
				_cache = new PlayerSpellOverrideFile();
				Save(_cache);
				ManualLogSource logInstance4 = Plugin.LogInstance;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to read player spell config. Wrote defaults. Error: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				logInstance4.LogError(val3);
				return _cache;
			}
		}

		private static void BackupPreMigrationConfig()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			try
			{
				string text = ConfigPath + ".backup";
				if (File.Exists(text))
				{
					File.Delete(text);
				}
				if (File.Exists(ConfigPath))
				{
					File.Copy(ConfigPath, text);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not create player spell config migration backup: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				logInstance.LogWarning(val);
			}
		}

		internal static void Save()
		{
			Save(Current);
		}

		private static void Save(PlayerSpellOverrideFile config)
		{
			Directory.CreateDirectory(ConfigDirectory);
			File.WriteAllText(ConfigPath, JsonSerializer.Serialize(config, JsonOptions));
		}
	}
	internal static class Core
	{
		private static World? _server;

		internal static World Server
		{
			get
			{
				World? server = _server;
				if (server != null && server.IsCreated)
				{
					return _server;
				}
				_server = WorldUtility.FindServerWorld(true);
				World? server2 = _server;
				if (server2 == null || !server2.IsCreated)
				{
					throw new InvalidOperationException("Server world is not ready.");
				}
				return _server;
			}
		}

		internal static EntityManager EntityManager => Server.EntityManager;

		internal static ServerGameManager ServerGameManager => Server.GetExistingSystemManaged<ServerScriptMapper>().GetServerGameManager();
	}
	internal readonly record struct AbilitySlotDef(PrefabGUID AbilityGroup, float CooldownSeconds = 0f);
	internal readonly record struct WeaponPowerDef(float WeaponLevel, float PhysicalPower, float SpellPower)
	{
		internal static WeaponPowerDef Default => new WeaponPowerDef(100f, 35f, 10f);
	}
	internal readonly record struct CustomWeaponStatDef(UnitStatType StatType, ModificationType ModificationType, AttributeCapType AttributeCapType, float Value, float Modifier = 1f)
	{
		[CompilerGenerated]
		public void Deconstruct(out UnitStatType StatType, out ModificationType ModificationType, out AttributeCapType AttributeCapType, out float Value, out float Modifier)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected I4, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			StatType = (UnitStatType)(int)this.StatType;
			ModificationType = (ModificationType)(int)this.ModificationType;
			AttributeCapType = (AttributeCapType)(int)this.AttributeCapType;
			Value = this.Value;
			Modifier = this.Modifier;
		}
	}
	internal readonly record struct WeaponTypeBuffDef(string WeaponType, bool ApplyToCustomWeapons, IReadOnlyList<CustomWeaponStatDef> Stats);
	internal readonly record struct CustomWeaponCostDef(string Name, PrefabGUID Item, int Amount);
	internal readonly record struct CustomWeaponOnHitEffectDef(string Name, string School, float Chance, PrefabGUID TargetBuff, bool AffectPlayers, bool AffectNonPlayers);
	internal readonly record struct CustomWeaponDef(string Name, PrefabGUID ItemWeapon, PrefabGUID EquipBuff, PrefabGUID CarrierBuff, PrefabGUID StatCarrierBuff, IReadOnlyList<CustomWeaponCostDef> UpgradeCost, WeaponPowerDef Power, IReadOnlyList<CustomWeaponStatDef> Stats, IReadOnlyList<CustomWeaponOnHitEffectDef> OnHitEffects, AbilitySlotDef Attack, AbilitySlotDef Primary, AbilitySlotDef Secondary, AbilitySlotDef Dash, AbilitySlotDef Ultimate, AbilitySlotDef SpellSlot1, AbilitySlotDef SpellSlot2);
	internal static class CustomWeaponRegistry
	{
		private static readonly Dictionary<int, CustomWeaponDef> _customWeaponsByItem = new Dictionary<int, CustomWeaponDef>();

		private static readonly Dictionary<int, string> _customWeaponNamesByItem = new Dictionary<int, string>();

		private static readonly Dictionary<string, CustomWeaponDef> _customWeaponsByName = new Dictionary<string, CustomWeaponDef>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<int> _reservedRuntimeCarrierBuffs = new HashSet<int>();

		private static readonly HashSet<int> _reservedRuntimeStatCarrierBuffs = new HashSet<int>();

		internal static IReadOnlyList<CustomWeaponDef> CurrentWeapons { get; private set; } = Array.Empty<CustomWeaponDef>();

		internal static IReadOnlyCollection<int> ReservedRuntimeCarrierBuffs => _reservedRuntimeCarrierBuffs;

		internal static IReadOnlyCollection<int> ReservedRuntimeStatCarrierBuffs => _reservedRuntimeStatCarrierBuffs;

		internal static bool IsCustomWeaponItem(int itemWeaponGuidHash)
		{
			return _customWeaponsByItem.ContainsKey(itemWeaponGuidHash);
		}

		internal static bool TryGetCustomWeapon(int itemWeaponGuidHash, out CustomWeaponDef weapon)
		{
			return _customWeaponsByItem.TryGetValue(itemWeaponGuidHash, out weapon);
		}

		internal static bool TryGetCustomWeaponByName(string name, out CustomWeaponDef weapon)
		{
			weapon = default(CustomWeaponDef);
			if (string.IsNullOrWhiteSpace(name))
			{
				return false;
			}
			return _customWeaponsByName.TryGetValue(name, out weapon);
		}

		internal static bool TryGetCustomWeaponForCharacter(Entity character, out CustomWeaponDef weapon, out string source)
		{
			//IL_0007: 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)
			source = string.Empty;
			if (CustomWeaponInstanceStore.TryGetHeldInstanceWeapon(character, out weapon, out CustomWeaponInstanceEntry instance))
			{
				source = $"instance:{instance.SequenceGuidHash}";
				return true;
			}
			if (ItemInstanceUtility.TryGetHeldWeaponPrefab(character, out var prefabGuid) && TryGetCustomWeapon(((PrefabGUID)(ref prefabGuid)).GuidHash, out weapon))
			{
				source = $"prefab:{((PrefabGUID)(ref prefabGuid)).GuidHash}";
				return true;
			}
			weapon = default(CustomWeaponDef);
			return false;
		}

		internal static bool IsCustomWeaponEquipBuff(int equipBuffGuidHash)
		{
			if (!_reservedRuntimeCarrierBuffs.Contains(equipBuffGuidHash))
			{
				return _reservedRuntimeStatCarrierBuffs.Contains(equipBuffGuidHash);
			}
			return true;
		}

		internal static string GetCustomWeaponUsingEquipBuff(int equipBuffGuidHash)
		{
			if (!_reservedRuntimeCarrierBuffs.Contains(equipBuffGuidHash))
			{
				if (_reservedRuntimeStatCarrierBuffs.Contains(equipBuffGuidHash))
				{
					return $"custom weapon runtime stat carrier {equipBuffGuidHash}";
				}
				return $"custom weapon using equip buff {equipBuffGuidHash}";
			}
			return $"custom weapon runtime ability carrier {equipBuffGuidHash}";
		}

		internal static string GetCustomWeaponName(int itemWeaponGuidHash)
		{
			if (!_customWeaponNamesByItem.TryGetValue(itemWeaponGuidHash, out string value))
			{
				return $"Custom weapon {itemWeaponGuidHash}";
			}
			return value;
		}

		internal static void ApplyAll()
		{
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Expected O, but got Unknown
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			RuntimePrefabCache.Clear();
			CustomWeaponStatCarrierService.Reset();
			IReadOnlyList<CustomWeaponDef> readOnlyList = (CurrentWeapons = CustomWeaponConfig.LoadOrCreate());
			_customWeaponsByItem.Clear();
			_customWeaponNamesByItem.Clear();
			_customWeaponsByName.Clear();
			_reservedRuntimeCarrierBuffs.Clear();
			_reservedRuntimeStatCarrierBuffs.Clear();
			Dictionary<int, int> dictionary = readOnlyList.GroupBy(delegate(CustomWeaponDef w)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				PrefabGUID itemWeapon = w.ItemWeapon;
				return ((PrefabGUID)(ref itemWeapon)).GuidHash;
			}).ToDictionary((IGrouping<int, CustomWeaponDef> g) => g.Key, (IGrouping<int, CustomWeaponDef> g) => g.Count());
			PrefabGUID val;
			foreach (CustomWeaponDef item in readOnlyList)
			{
				if (!_customWeaponsByName.TryAdd(item.Name, item))
				{
					RuntimeOptimization.WarnOnce("dup-name:" + item.Name, "Duplicate custom weapon name '" + item.Name + "'. .csw wepgive uses names, so only the first definition with this name can be targeted reliably.");
				}
				val = item.ItemWeapon;
				if (dictionary.TryGetValue(((PrefabGUID)(ref val)).GuidHash, out var value) && value == 1)
				{
					Dictionary<int, CustomWeaponDef> customWeaponsByItem = _customWeaponsByItem;
					val = item.ItemWeapon;
					customWeaponsByItem[((PrefabGUID)(ref val)).GuidHash] = item;
					Dictionary<int, string> customWeaponNamesByItem = _customWeaponNamesByItem;
					val = item.ItemWeapon;
					customWeaponNamesByItem[((PrefabGUID)(ref val)).GuidHash] = item.Name;
				}
				else
				{
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(9, 1);
					defaultInterpolatedStringHandler.AppendLiteral("dup-item:");
					val = item.ItemWeapon;
					defaultInterpolatedStringHandler.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					string key = defaultInterpolatedStringHandler.ToStringAndClear();
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(178, 1);
					defaultInterpolatedStringHandler2.AppendLiteral("ItemWeapon ");
					val = item.ItemWeapon;
					defaultInterpolatedStringHandler2.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					defaultInterpolatedStringHandler2.AppendLiteral(" is used by multiple custom weapon definitions. It will not be prefab-bound; give it with .csw wepgive so the generated item instance decides which definition applies.");
					RuntimeOptimization.WarnOnce(key, defaultInterpolatedStringHandler2.ToStringAndClear());
				}
				val = item.CarrierBuff;
				if (((PrefabGUID)(ref val)).HasValue())
				{
					HashSet<int> reservedRuntimeCarrierBuffs = _reservedRuntimeCarrierBuffs;
					val = item.CarrierBuff;
					reservedRuntimeCarrierBuffs.Add(((PrefabGUID)(ref val)).GuidHash);
				}
				val = item.StatCarrierBuff;
				if (((PrefabGUID)(ref val)).HasValue())
				{
					HashSet<int> reservedRuntimeStatCarrierBuffs = _reservedRuntimeStatCarrierBuffs;
					val = item.StatCarrierBuff;
					reservedRuntimeStatCarrierBuffs.Add(((PrefabGUID)(ref val)).GuidHash);
				}
			}
			if (CustomWeaponConfig.CustomWeaponCarrierBuff != 0)
			{
				_reservedRuntimeCarrierBuffs.Add(CustomWeaponConfig.CustomWeaponCarrierBuff);
			}
			if (CustomWeaponConfig.CustomWeaponStatCarrierBuff != 0)
			{
				_reservedRuntimeStatCarrierBuffs.Add(CustomWeaponConfig.CustomWeaponStatCarrierBuff);
			}
			CustomWeaponValidationService.ValidateCarriers();
			if (readOnlyList.Count == 0)
			{
				RuntimeOptimization.WarnOnce("no-enabled-weapons", "No enabled custom weapons found in " + CustomWeaponConfig.ConfigPath + ".");
				return;
			}
			RuntimeOptimization.InfoOnce("custom-weapon-apply-summary", $"Loaded {readOnlyList.Count} custom weapon definition(s), {CustomWeaponConfig.WeaponTypeBuffs.Count} weapon type buff(s), runtime carrier {CustomWeaponConfig.CustomWeaponCarrierBuff}, stat carrier {CustomWeaponConfig.CustomWeaponStatCarrierBuff}. Use .csw validate for details.");
			RuntimeOptimization.Debug($"WeaponTypeBuffs loaded: {CustomWeaponConfig.WeaponTypeBuffs.Count}. They share the runtime stat carrier {CustomWeaponConfig.CustomWeaponStatCarrierBuff} and are merged into one active player stat carrier.");
			bool flag = default(bool);
			foreach (CustomWeaponDef item2 in readOnlyList)
			{
				try
				{
					val = item2.ItemWeapon;
					if (dictionary.TryGetValue(((PrefabGUID)(ref val)).GuidHash, out var value2) && value2 == 1)
					{
						ApplyPrefabWeaponLevelOnly(item2);
					}
					else
					{
						DefaultInterpolatedStringHandler defaultInterpolatedStringHandler3 = new DefaultInterpolatedStringHandler(174, 2);
						defaultInterpolatedStringHandler3.AppendFormatted(item2.Name);
						defaultInterpolatedStringHandler3.AppendLiteral(": skipped prefab WeaponLevelSource mutation because ItemWeapon ");
						val = item2.ItemWeapon;
						defaultInterpolatedStringHandler3.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
						defaultInterpolatedStringHandler3.AppendLiteral(" is shared by multiple custom weapon definitions. Ability/stat behavior will be instance-bound by .csw wepgive.");
						RuntimeOptimization.Debug(defaultInterpolatedStringHandler3.ToStringAndClear());
					}
					ValidateRuntimeCarriers(item2);
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler4 = new DefaultInterpolatedStringHandler(83, 6);
					defaultInterpolatedStringHandler4.AppendLiteral("Registered runtime custom weapon: ");
					defaultInterpolatedStringHandler4.AppendFormatted(item2.Name);
					defaultInterpolatedStringHandler4.AppendLiteral(" item:");
					val = item2.ItemWeapon;
					defaultInterpolatedStringHandler4.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					defaultInterpolatedStringHandler4.AppendLiteral(" abilityCarrier:");
					val = item2.CarrierBuff;
					defaultInterpolatedStringHandler4.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					defaultInterpolatedStringHandler4.AppendLiteral(" statCarrier:");
					val = item2.StatCarrierBuff;
					defaultInterpolatedStringHandler4.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					defaultInterpolatedStringHandler4.AppendLiteral(" stats:");
					defaultInterpolatedStringHandler4.AppendFormatted(item2.Stats.Count);
					defaultInterpolatedStringHandler4.AppendLiteral(" onHit:");
					defaultInterpolatedStringHandler4.AppendFormatted(item2.OnHitEffects.Count);
					RuntimeOptimization.Debug(defaultInterpolatedStringHandler4.ToStringAndClear());
				}
				catch (Exception ex)
				{
					ManualLogSource logInstance = Plugin.LogInstance;
					BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed custom weapon '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(item2.Name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
					}
					logInstance.LogError(val2);
				}
			}
		}

		private static void ApplyPrefabWeaponLevelOnly(CustomWeaponDef weapon)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (!weapon.ItemWeapon.TryGetPrefabEntity(out var entity))
			{
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(13, 1);
				defaultInterpolatedStringHandler.AppendLiteral("missing-item:");
				PrefabGUID itemWeapon = weapon.ItemWeapon;
				defaultInterpolatedStringHandler.AppendFormatted(((PrefabGUID)(ref itemWeapon)).GuidHash);
				string key = defaultInterpolatedStringHandler.ToStringAndClear();
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(25, 2);
				defaultInterpolatedStringHandler2.AppendFormatted(weapon.Name);
				defaultInterpolatedStringHandler2.AppendLiteral(": item prefab not found: ");
				itemWeapon = weapon.ItemWeapon;
				defaultInterpolatedStringHandler2.AppendFormatted(((PrefabGUID)(ref itemWeapon)).GuidHash);
				RuntimeOptimization.WarnOnce(key, defaultInterpolatedStringHandler2.ToStringAndClear());
			}
			else
			{
				entity.With<WeaponLevelSource>((EntityExtensions.WithRefHandler<WeaponLevelSource>)delegate(ref WeaponLevelSource source)
				{
					source.Level = weapon.Power.WeaponLevel;
				});
			}
		}

		private static void ValidateRuntimeCarriers(CustomWeaponDef weapon)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			PrefabGUID val = weapon.CarrierBuff;
			if (((PrefabGUID)(ref val)).HasValue())
			{
				if (weapon.CarrierBuff.TryGetPrefabEntity(out var entity))
				{
					if (!entity.TryGetBuffer<ReplaceAbilityOnSlotBuff>(out DynamicBuffer<ReplaceAbilityOnSlotBuff> _))
					{
						DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(26, 1);
						defaultInterpolatedStringHandler.AppendLiteral("ability-carrier-no-buffer:");
						val = weapon.CarrierBuff;
						defaultInterpolatedStringHandler.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
						string key = defaultInterpolatedStringHandler.ToStringAndClear();
						DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(58, 2);
						defaultInterpolatedStringHandler2.AppendFormatted(weapon.Name);
						defaultInterpolatedStringHandler2.AppendLiteral(": ability carrier ");
						val = weapon.CarrierBuff;
						defaultInterpolatedStringHandler2.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
						defaultInterpolatedStringHandler2.AppendLiteral(" does not have ReplaceAbilityOnSlotBuff.");
						RuntimeOptimization.WarnOnce(key, defaultInterpolatedStringHandler2.ToStringAndClear());
					}
				}
				else
				{
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler3 = new DefaultInterpolatedStringHandler(24, 1);
					defaultInterpolatedStringHandler3.AppendLiteral("ability-carrier-missing:");
					val = weapon.CarrierBuff;
					defaultInterpolatedStringHandler3.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					string key2 = defaultInterpolatedStringHandler3.ToStringAndClear();
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler4 = new DefaultInterpolatedStringHandler(29, 2);
					defaultInterpolatedStringHandler4.AppendFormatted(weapon.Name);
					defaultInterpolatedStringHandler4.AppendLiteral(": ability carrier ");
					val = weapon.CarrierBuff;
					defaultInterpolatedStringHandler4.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					defaultInterpolatedStringHandler4.AppendLiteral(" not found.");
					RuntimeOptimization.WarnOnce(key2, defaultInterpolatedStringHandler4.ToStringAndClear());
				}
			}
			val = weapon.StatCarrierBuff;
			if (!((PrefabGUID)(ref val)).HasValue() || weapon.Stats.Count <= 0)
			{
				return;
			}
			if (weapon.StatCarrierBuff.TryGetPrefabEntity(out var entity2))
			{
				if (!entity2.TryGetBuffer<ModifyUnitStatBuff_DOTS>(out DynamicBuffer<ModifyUnitStatBuff_DOTS> _))
				{
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler5 = new DefaultInterpolatedStringHandler(23, 1);
					defaultInterpolatedStringHandler5.AppendLiteral("stat-carrier-no-buffer:");
					val = weapon.StatCarrierBuff;
					defaultInterpolatedStringHandler5.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					string key3 = defaultInterpolatedStringHandler5.ToStringAndClear();
					DefaultInterpolatedStringHandler defaultInterpolatedStringHandler6 = new DefaultInterpolatedStringHandler(54, 2);
					defaultInterpolatedStringHandler6.AppendFormatted(weapon.Name);
					defaultInterpolatedStringHandler6.AppendLiteral(": stat carrier ");
					val = weapon.StatCarrierBuff;
					defaultInterpolatedStringHandler6.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
					defaultInterpolatedStringHandler6.AppendLiteral(" does not have ModifyUnitStatBuff_DOTS.");
					RuntimeOptimization.WarnOnce(key3, defaultInterpolatedStringHandler6.ToStringAndClear());
				}
			}
			else
			{
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler7 = new DefaultInterpolatedStringHandler(21, 1);
				defaultInterpolatedStringHandler7.AppendLiteral("stat-carrier-missing:");
				val = weapon.StatCarrierBuff;
				defaultInterpolatedStringHandler7.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
				string key4 = defaultInterpolatedStringHandler7.ToStringAndClear();
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler8 = new DefaultInterpolatedStringHandler(26, 2);
				defaultInterpolatedStringHandler8.AppendFormatted(weapon.Name);
				defaultInterpolatedStringHandler8.AppendLiteral(": stat carrier ");
				val = weapon.StatCarrierBuff;
				defaultInterpolatedStringHandler8.AppendFormatted(((PrefabGUID)(ref val)).GuidHash);
				defaultInterpolatedStringHandler8.AppendLiteral(" not found.");
				RuntimeOptimization.WarnOnce(key4, defaultInterpolatedStringHandler8.ToStringAndClear());
			}
		}
	}
	[BepInPlugin("com.hexesandsanguinesteel.server", "Hexes and Sanguine Steel", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class Plugin : BasePlugin
	{
		internal const string PluginGuid = "com.hexesandsanguinesteel.server";

		internal const string PluginName = "Hexes and Sanguine Steel";

		internal static ManualLogSource LogInstance;

		internal static Harmony Harmony;

		public override void Load()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			LogInstance = ((BasePlugin)this).Log;
			if (Application.productName != "VRisingServer")
			{
				((BasePlugin)this).Log.LogWarning((object)"Hexes and Sanguine Steel is server-side only; skipping load on non-server process.");
				return;
			}
			Harmony = new Harmony("com.hexesandsanguinesteel.server");
			Bootstrap.Initialize(Harmony, ((BasePlugin)this).Log);
			Harmony.PatchAll();
			PlayerSpellOverrideService.Initialize();
			CustomWeaponInstanceStore.Initialize();
			CommandRegistry.RegisterAll();
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loaded ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Hexes and Sanguine Steel");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.1");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; waiting for server bootstrap.");
			}
			log.LogInfo(val);
		}

		public override bool Unload()
		{
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			CommandRegistry.UnregisterAssembly();
			return true;
		}
	}
	internal static class AbilityReplacementInjectionService
	{
		private static readonly int[] CustomWeaponManagedSlots = new int[7] { 0, 1, 2, 4, 5, 6, 7 };

		private static readonly int[] PlayerSpellManagedSlots = new int[6] { 1, 2, 4, 5, 6, 7 };

		internal static bool TryInjectForBuff(Entity buffEntity, out string message)
		{
			//IL_0007: 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_0019: 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_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_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_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_005c: 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_0072: 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)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			message = string.Empty;
			if (!buffEntity.ExistsSafe() || buffEntity.Has<DestroyTag>())
			{
				return false;
			}
			if (!buffEntity.TryGetBuffer<ReplaceAbilityOnSlotBuff>(out DynamicBuffer<ReplaceAbilityOnSlotBuff> buffer))
			{
				return false;
			}
			if (!buffEntity.TryRead<EntityOwner>(out EntityOwner value) || !value.Owner.ExistsSafe() || value.Owner.Has<DestroyTag>())
			{
				return false;
			}
			Entity owner = value.Owner;
			if (!owner.Has<PlayerCharacter>())
			{
				return false;
			}
			if (ShapeshiftUtility.IsFormReplacementBuff(buffEntity) || ShapeshiftUtility.IsActiveForm(owner))
			{
				CustomWeaponRuntimeOverrideService.RemoveAbilityCarriers(owner);
				if (PlayerLookup.TryFindOnlinePlayer(owner, out var result))
				{
					PlayerSpellOverrideService.RemoveRuntimeCarrierForForm(owner, result.PlatformId);
				}
				message = "Skipped ability injection while shapeshift/form is active. form:" + ShapeshiftUtility.DescribeActiveForm(owner);
				return false;
			}
			if (FeedInteractionUtility.IsFeedOrExtractionReplacementBuff(buffEntity) || FeedInteractionUtility.IsActiveFeedOrExtraction(owner))
			{
				CustomWeaponRuntimeOverrideService.RemoveAbilityCarriers(owner);
				if (PlayerLookup.TryFindOnlinePlayer(owner, out var result2))
				{
					PlayerSpellOverrideService.RemoveRuntimeCarrierForTemporaryAbilityState(owner, result2.PlatformId);
				}
				message = "Skipped ability injection while feed/V Blood extraction is active. feed:" + FeedInteractionUtility.DescribeActiveFeedOrExtraction(owner);
				return false;
			}
			if (CustomWeaponRegistry.TryGetCustomWeaponForCharacter(owner, out CustomWeaponDef weapon, out string source))
			{
				if (!IsExpectedCurrentWeaponReplacementBuff(buffEntity, owner, weapon, out string detail))
				{
					message = $"Skipped custom weapon injection into non-weapon replacement buff {detail} for '{weapon.Name}'.";
					return false;
				}
				InjectCustomWeapon(buffer, weapon);
				PlayerSpellOverrideService.ClearRuntimeSpellState(owner);
				CustomWeaponRuntimeOverrideService.QueueRuntimeRefresh($"ReplaceAbilityOnSlotSystem injection custom weapon {weapon.Name} ({source})");
				message = $"Injected custom weapon '{weapon.Name}' ({source}) into live ReplaceAbilityOnSlotBuff {detail}.";
				return true;
			}
			if (!PlayerLookup.TryFindOnlinePlayer(owner, out var result3))
			{
				return false;
			}
			if (!PlayerSpellOverrideConfig.Current.Players.TryGetValue(result3.PlatformId.ToString(), out PlayerSpellOverrideEntry value2) || !value2.Enabled)
			{
				return false;
			}
			PlayerSpellOverrideEntry playerSpellOverrideEntry = value2;
			if (playerSpellOverrideEntry.WeaponScopes == null)
			{
				Dictionary<string, PlayerSpellScopeEntry> dictionary = (playerSpellOverrideEntry.WeaponScopes = new Dictionary<string, PlayerSpellScopeEntry>());
			}
			WeaponScopeResult currentScope = WeaponScopeResolver.GetCurrentScope(owner);
			if (currentScope.IsCustomWeapon)
			{
				return false;
			}
			if (!value2.WeaponScopes.TryGetValue(currentScope.ScopeKey, out PlayerSpellScopeEntry value3) || !value3.HasAnySpell())
			{
				return false;
			}
			if (!IsExpectedCurrentWeaponReplacementBuff(buffEntity, owner, default(CustomWeaponDef), out string detail2))
			{
				message = $"Skipped spell override injection into non-weapon replacement buff {detail2} for {result3.Name}:{currentScope.ScopeKey}.";
				return false;
			}
			InjectPlayerSpellProfile(buffer, value3);
			PlayerSpellOverrideService.QueueCooldownRefresh("ReplaceAbilityOnSlotSystem injection spell override " + result3.Name + ":" + currentScope.ScopeKey);
			message = $"Injected spell override profile for {result3.Name} scope '{currentScope.ScopeKey}' into live ReplaceAbilityOnSlotBuff {detail2}.";
			return true;
		}

		private static bool IsExpectedCurrentWeaponReplacementBuff(Entity buffEntity, Entity character, CustomWeaponDef weapon, out string detail)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_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_0073: 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)
			detail = DescribeBuff(buffEntity);
			if (!buffEntity.TryRead<PrefabGUID>(out PrefabGUID value) || !((PrefabGUID)(ref value)).HasValue())
			{
				return false;
			}
			if (CustomWeaponRegistry.ReservedRuntimeCarrierBuffs.Contains(((PrefabGUID)(ref value)).GuidHash))
			{
				return true;
			}
			if (ItemInstanceUtility.TryGetHeldWeaponEquipBuff(character, out var buffGuid) && ((PrefabGUID)(ref buffGuid)).HasValue())
			{
				if (((PrefabGUID)(ref value)).GuidHash == ((PrefabGUID)(ref buffGuid)).GuidHash)
				{
					return true;
				}
				return false;
			}
			PrefabGUID equipBuff = weapon.EquipBuff;
			if (((PrefabGUID)(ref equipBuff)).HasValue())
			{
				_ = ((PrefabGUID)(ref value)).GuidHash;
				equipBuff = weapon.EquipBuff;
				_ = ((PrefabGUID)(ref equipBuff)).GuidHash;
				return true;
			}
			return true;
		}

		private static string DescribeBuff(Entity buffEntity)
		{
			//IL_0000: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			if (!buffEntity.ExistsSafe())
			{
				return "<destroyed>";
			}
			if (buffEntity.TryRead<PrefabGUID>(out PrefabGUID value) && ((PrefabGUID)(ref value)).HasValue())
			{
				return $"{((PrefabGUID)(ref value)).GuidHash} entity:{buffEntity.Index}:{buffEntity.Version}";
			}
			return $"entity:{buffEntity.Index}:{buffEntity.Version}";
		}

		private static void InjectCustomWeapon(DynamicBuffer<ReplaceAbilityOnSlotBuff> replacements, CustomWeaponDef weapon)
		{
			//IL_0000: 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_0016: 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)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			AddOrReplace(replacements, 0, weapon.Attack.AbilityGroup);
			AddOrReplace(replacements, 1, weapon.Primary.AbilityGroup);
			AddOrReplace(replacements, 2, weapon.Dash.AbilityGroup);
			AddOrReplace(replacements, 4, weapon.Secondary.AbilityGroup);
			AddOrReplace(replacements, 5, weapon.SpellSlot1.AbilityGroup);
			AddOrReplace(replacements, 6, weapon.SpellSlot2.AbilityGroup);
			AddOrReplace(replacements, 7, weapon.Ultimate.AbilityGroup);
		}

		private static void InjectPlayerSpellProfile(DynamicBuffer<ReplaceAbilityOnSlotBuff> replacements, PlayerSpellScopeEntry profile)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_001a: 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_002c: 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_003e: 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_0050: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			AddOrReplace(replacements, 1, new PrefabGUID(profile.Q));
			AddOrReplace(replacements, 2, new PrefabGUID(profile.Dash));
			AddOrReplace(replacements, 4, new PrefabGUID(profile.E));
			AddOrReplace(replacements, 5, new PrefabGUID(profile.R));
			AddOrReplace(replacements, 6, new PrefabGUID(profile.C));
			AddOrReplace(replacements, 7, new PrefabGUID(profile.T));
		}

		private static void AddOrReplace(DynamicBuffer<ReplaceAbilityOnSlotBuff> replacements, int slot, PrefabGUID abilityGroup)
		{
			//IL_000a: 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_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_0033: Unknown result type (might be due to invalid IL or missing references)
			if (((PrefabGUID)(ref abilityGroup)).HasValue())
			{
				RemoveSlot(replacements, slot);
				replacements.Add(new ReplaceAbilityOnSlotBuff
				{
					Slot = slot,
					NewGroupId = abilityGroup,
					CopyCooldown = false
				});
			}
		}

		private static void RemoveSlot(DynamicBuffer<ReplaceAbilityOnSlotBuff> replacements, int slot)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			for (int num = replacements.Length - 1; num >= 0; num--)
			{
				if (replacements[num].Slot == slot)
				{
					replacements.RemoveAt(num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(StatChangeSystem), "OnUpdate")]
	internal static class CustomWeaponOnHitService
	{
		private static readonly Random Rng = new Random();

		[HarmonyPostfix]
		private static void Postfix(StatChangeSystem __instance)
		{
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_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_0079: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			if (CustomWeaponRegistry.CurrentWeapons.Count == 0)
			{
				return;
			}
			NativeArray<Entity> val = default(NativeArray<Entity>);
			NativeArray<DamageTakenEvent> val2 = default(NativeArray<DamageTakenEvent>);
			try
			{
				EntityQuery damageTakenEventQuery = __instance._DamageTakenEventQuery;
				val = ((EntityQuery)(ref damageTakenEventQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2));
				damageTakenEventQuery = __instance._DamageTakenEventQuery;
				val2 = ((EntityQuery)(ref damageTakenEventQuery)).ToComponentDataArray<DamageTakenEvent>(AllocatorHandle.op_Implicit((Allocator)2));
				for (int i = 0; i < val2.Length; i++)
				{
					DamageTakenEvent val3 = val2[i];
					Entity entity = val3.Entity;
					if (!entity.ExistsSafe() || !entity.Has<Health>())
					{
						continue;
					}
					Entity val4 = ResolveOwner(val3.Source);
					if (!val4.ExistsSafe() || !val4.Has<PlayerCharacter>() || !CustomWeaponRegistry.TryGetCustomWeaponForCharacter(val4, out CustomWeaponDef weapon, out string _) || weapon.OnHitEffects.Count == 0)
					{
						continue;
					}
					bool flag = entity.Has<PlayerCharacter>();
					foreach (CustomWeaponOnHitEffectDef onHitEffect in weapon.OnHitEffects)
					{
						if ((!flag || onHitEffect.AffectPlayers) && (flag || onHitEffect.AffectNonPlayers) && !(onHitEffect.Chance <= 0f) && (!(onHitEffect.Chance < 1f) || !(Rng.NextDouble() > (double)onHitEffect.Chance)))
						{
							ApplyEffect(val4, entity, weapon, onHitEffect);
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logInstance = Plugin.LogInstance;
				bool flag2 = default(bool);
				BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(38, 1, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[CustomWeaponOnHitService] Exception: ");
					((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<Exception>(ex);
				}
				logInstance.LogWarning(val5);
			}
			finally
			{
				if (val2.IsCreated)
				{
					val2.Dispose();
				}
				if (val.IsCreated)
				{
					val.Dispose();
				}
			}
		}

		private static Entity ResolveOwner(Entity source)
		{
			//IL_0000: 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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0036: 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)
			//IL_0023: 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)
			if (!source.ExistsSafe())
			{
				return Entity.Null;
			}
			if (source.Has<PlayerCharacter>())
			{
				return source;
			}
			if (source.TryRead<EntityOwner>(out EntityOwner value) && value.Owner.ExistsSafe())
			{
				return value.Owner;
			}
			return source;
		}

		private static void ApplyEffect(Entity sourcePlayer, Entity target, CustomWeaponDef weapon, CustomWeaponOnHitEffectDef effect)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0013: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			PrefabGUID targetBuff = effect.TargetBuff;
			if (((PrefabGUID)(ref targetBuff)).HasValue() && target.TryApplyBuffWithOwner(sourcePlayer, effect.TargetBuff))
			{
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(40, 4);
				defaultInterpolatedStringHandler.AppendLiteral("OnHit '");
				defaultInterpolatedStringHandler.AppendFormatted(effect.Name);
				defaultInterpolatedStringHandler.AppendLiteral("' (");
				defaultInterpolatedStringHandler.AppendFormatted(effect.School);
				defaultInterpolatedStringHandler.AppendLiteral(") from ");
				defaultInterpolatedStringHandler.AppendFormatted(weapon.Name);
				defaultInterpolatedStringHandler.AppendLiteral(": applied school buff ");
				targetBuff = effect.TargetBuff;
				defaultInterpolatedStringHandler.AppendFormatted(((PrefabGUID)(ref targetBuff)).GuidHash);
				defaultInterpolatedStringHandler.AppendLiteral(".");
				RuntimeOptimization.Debug(defaultInterpolatedStringHandler.ToStringAndClear());
			}
		}
	}
	internal static class CustomWeaponRuntimeCooldownService
	{
		internal static int ApplyAllOnline()
		{
			//IL_0027: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			if (CustomWeaponRegistry.CurrentWeapons.Count == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (PlayerLookupResult onlinePlayer in PlayerLookup.GetOnlinePlayers())
			{
				if (WeaponScopeResolver.GetCurrentScope(onlinePlayer.CharacterEntity).IsCustomWeapon && CustomWeaponRegistry.TryGetCustomWeaponForCharacter(onlinePlayer.CharacterEntity, out CustomWeaponDef weapon, out string _))
				{
					num += ApplyWeaponCooldowns(onlinePlayer.CharacterEntity, weapon);
				}
			}
			return num;
		}

		private static int ApplyWeaponCooldowns(Entity character, CustomWeaponDef weapon)
		{
			//IL_0001: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			return 0 + ApplySlot(character, weapon.Name, "Attack", weapon.Attack) + ApplySlot(character, weapon.Name, "Primary/Q", weapon.Primary) + ApplySlot(character, weapon.Name, "Secondary/E", weapon.Secondary) + ApplySlot(character, weapon.Name, "Dash", weapon.Dash) + ApplySlot(character, weapon.Name, "Ultimate/T", weapon.Ultimate) + ApplySlot(character, weapon.Name, "Spell Slot 1", weapon.SpellSlot1) + ApplySlot(character, weapon.Name, "Spell Slot 2", weapon.SpellSlot2);
		}

		private static int ApplySlot(Entity character, string weaponName, string slotName, AbilitySlotDef ability)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			PrefabGUID abilityGroup = ability.AbilityGroup;
			if (!((PrefabGUID)(ref abilityGroup)).HasValue() || ability.CooldownSeconds <= 0f)
			{
				return 0;
			}
			return AbilityCooldownUtility.SetCooldownOnAttachedAbilityGroup(character, ability.AbilityGroup, ability.CooldownSeconds, $"CustomWeaponRuntimeCooldown[{weaponName}:{slotName}]");
		}
	}
	internal static class CustomWeaponRuntimeOverrideService
	{
		internal static void QueueRuntimeRefresh(string reason)
		{
			PlayerSpellOverrideService.QueueCooldownRefresh(reason);
		}

		internal static void ForceStatReconcile(Entity character, string reason)
		{
			//IL_0000: 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_000f: 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_0033: 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)
			if (character.ExistsSafe())
			{
				CustomWeaponStatCarrierService.ClearPendingForCharacter(character);
				RemoveStatCarriers(character);
				RuntimeStateCache.ClearRuntimeStatHash(character);
				RuntimeOptimization.Debug($"Forced stat reconcile for character {character.Index}:{character.Version}. Reason:{reason}");
			}
		}

		internal static int ApplyAllOnline()
		{
			int num = 0;
			foreach (PlayerLookupResult onlinePlayer in PlayerLookup.GetOnlinePlayers())
			{
				if (TryApplyForPlayer(onlinePlayer, out string _))
				{
					num++;
				}
			}
			return num;
		}

		internal static bool TryApplyForPlayer(PlayerLookupResult player, out string message)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return TryApplyForCharacter(player.CharacterEntity, out message);
		}

		internal static bool TryApplyForCharacter(Entity character, out string message)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0042: 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_0054: 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_0075: 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_0081: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			message = string.Empty;
			if (!character.ExistsSafe())
			{
				message = "Invalid character entity.";
				return false;
			}
			if (ShapeshiftUtility.IsActiveForm(character))
			{
				RemoveAllRuntimeCarriers(character);
				message = "Shapeshift/form active; custom weapon runtime override suppressed. form:" + ShapeshiftUtility.DescribeActiveForm(character);
				return false;
			}
			if (FeedInteractionUtility.IsActiveFeedOrExtraction(character))
			{
				RemoveAbilityCarriers(character);
				RuntimeStateCache.ClearCustomWeaponAbilityHash(character);
				message = "Feed/V Blood extraction active; custom weapon ability override suppressed. feed:" + FeedInteractionUtility.DescribeActiveFeedOrExtraction(character);
				return false;
			}
			WeaponScopeResult currentScope = WeaponScopeReso