Decompiled source of DescriptiveWeaponStatShower v1.5.2

WeaponStatShower.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using GameData;
using Gear;
using HarmonyLib;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;
using WeaponStatShower.Patches;
using WeaponStatShower.Utils;
using WeaponStatShower.Utils.Language;
using WeaponStatShower.Utils.Language.Models;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("WeaponStatShower")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+85c316c320eef37590a4119a82a5ae81c084d884")]
[assembly: AssemblyProduct("WeaponStatShower")]
[assembly: AssemblyTitle("WeaponStatShower")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
namespace WeaponStatShower
{
	public static class BIEExtensions
	{
		public static ConfigEntry<T> GetConfigEntry<T>(this ConfigFile configFile, ConfigDefinition definition)
		{
			ConfigEntry<T> result = default(ConfigEntry<T>);
			if (!configFile.TryGetEntry<T>(definition, ref result))
			{
				throw new InvalidOperationException("Config entry has not been added yet.");
			}
			return result;
		}
	}
	[BepInPlugin("WeaponStatShower", "Weapon Stat Shower", "1.5.2")]
	[BepInProcess("GTFO.exe")]
	public class WeaponStatShowerPlugin : BasePlugin
	{
		internal const string ModName = "Weapon Stat Shower";

		internal const string GUID = "WeaponStatShower";

		private const string SectionMain = "Config";

		private static readonly ConfigDefinition ConfigDefinition = new ConfigDefinition("Config", "Version");

		private static readonly ConfigDefinition ConfigGameVersion = new ConfigDefinition("Config", "GameVersion");

		private static Harmony? HarmonyInstance;

		private static readonly Dictionary<Type, Patch> RegisteredPatches = new Dictionary<Type, Patch>();

		public static WeaponStatShowerPlugin Instance { get; private set; }

		public WeaponStatShowerPlugin()
		{
			((BasePlugin)this).Config.SaveOnConfigSet = false;
		}

		public override void Load()
		{
			Instance = this;
			((BasePlugin)this).Config.SaveOnConfigSet = true;
			LogInfo("STARTED");
			RegisterPatch<ShowStat>();
			((BasePlugin)this).Config.Save();
		}

		public static void RegisterPatch<T>() where T : Patch, new()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (HarmonyInstance == null)
			{
				HarmonyInstance = new Harmony("WeaponStatShower");
			}
			if (RegisteredPatches.TryGetValue(typeof(T), out Patch _))
			{
				LogDebug("Ignoring duplicate patch: " + typeof(T).Name);
				return;
			}
			T val = new T
			{
				Harmony = HarmonyInstance
			};
			val.Initialize();
			if (val.Enabled)
			{
				LogInfo("Applying patch: " + val.Name);
				val.Execute();
			}
			RegisteredPatches[typeof(T)] = val;
		}

		public static void LogDebug(object data)
		{
			((BasePlugin)Instance).Log.LogDebug(data);
		}

		public static void LogError(object data)
		{
			((BasePlugin)Instance).Log.LogError(data);
		}

		public static void LogFatal(object data)
		{
			((BasePlugin)Instance).Log.LogFatal(data);
		}

		public static void LogInfo(object data)
		{
			((BasePlugin)Instance).Log.LogInfo(data);
		}

		public static void LogMessage(object data)
		{
			((BasePlugin)Instance).Log.LogMessage(data);
		}

		public static void LogWarning(object data)
		{
			((BasePlugin)Instance).Log.LogWarning(data);
		}
	}
}
namespace WeaponStatShower.Utils
{
	internal static class ArchetypeUtil
	{
		internal static ArchetypeDataBlock? GetArchetypeDataBlock(GearIDRange idRange, uint categoryID, GearCategoryDataBlock gearCatBlock)
		{
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1);
			return (categoryID == 12) ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val));
		}

		internal static ArchetypeDataBlock? GetMappedArchetypeDataBlock(GearIDRange idRange, uint categoryID, GearCategoryDataBlock gearCatBlock)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected I4, but got Unknown
			//IL_005b: 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_0034: 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_0040: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			eWeaponFireMode val = (eWeaponFireMode)idRange.GetCompID((eGearComponent)1);
			bool flag = categoryID == 12;
			if (!flag)
			{
				val = (eWeaponFireMode)((val - 10) switch
				{
					0 => 0, 
					1 => 2, 
					2 => 1, 
					3 => 0, 
					_ => val, 
				});
			}
			return flag ? SentryGunInstance_Firing_Bullets.GetArchetypeDataForFireMode(val) : GameDataBlockBase<ArchetypeDataBlock>.GetBlock(GearBuilder.GetArchetypeID(gearCatBlock, val));
		}
	}
	internal class SleepersDatas
	{
		private readonly struct EnemyData
		{
			public readonly float Health;

			public readonly float HeadMultiplier;

			public readonly float BackMultiplier;

			public readonly bool IsArmored;

			public EnemyData(float health, float headMultiplier, float backMultiplier, bool isArmored)
			{
				Health = health;
				HeadMultiplier = headMultiplier;
				BackMultiplier = backMultiplier;
				IsArmored = isArmored;
			}
		}

		private readonly Dictionary<string, EnemyData> _enemyDatas = new Dictionary<string, EnemyData>();

		private readonly SleepersLanguageModel sleepersLanguageDatas;

		public SleepersDatas(string[] activatedSleepers, SleepersLanguageModel sleepersLanguageDatas)
		{
			this.sleepersLanguageDatas = sleepersLanguageDatas;
			foreach (string text in activatedSleepers)
			{
				string text2 = text.Trim();
				switch (text2)
				{
				case "DETAILS_ONLY":
				case "DESCRIPTION_ONLY":
				case "NONE":
					_enemyDatas.Clear();
					return;
				case "ALL":
					_enemyDatas.Clear();
					_enemyDatas.TryAdd(sleepersLanguageDatas.striker, new EnemyData(20f, 3f, 2f, isArmored: false));
					_enemyDatas.TryAdd(sleepersLanguageDatas.shooter, new EnemyData(30f, 5f, 2f, isArmored: false));
					_enemyDatas.TryAdd(sleepersLanguageDatas.scout, new EnemyData(42f, 3f, 2f, isArmored: false));
					_enemyDatas.TryAdd(sleepersLanguageDatas.bigStriker, new EnemyData(120f, 1.5f, 2f, isArmored: false));
					_enemyDatas.TryAdd(sleepersLanguageDatas.bigShooter, new EnemyData(150f, 2f, 2f, isArmored: false));
					_enemyDatas.TryAdd(sleepersLanguageDatas.charger, new EnemyData(30f, 1f, 2f, isArmored: true));
					_enemyDatas.TryAdd(sleepersLanguageDatas.chargerScout, new EnemyData(60f, 1f, 2f, isArmored: true));
					return;
				case "STRIKER":
					_enemyDatas.TryAdd(sleepersLanguageDatas.striker, new EnemyData(20f, 3f, 2f, isArmored: false));
					break;
				case "SHOOTER":
					_enemyDatas.TryAdd(sleepersLanguageDatas.shooter, new EnemyData(30f, 5f, 2f, isArmored: false));
					break;
				case "SCOUT":
					_enemyDatas.TryAdd(sleepersLanguageDatas.scout, new EnemyData(42f, 3f, 2f, isArmored: false));
					break;
				case "BIG_STRIKER":
					_enemyDatas.TryAdd(sleepersLanguageDatas.bigStriker, new EnemyData(120f, 1.5f, 2f, isArmored: false));
					break;
				case "BIG_SHOOTER":
					_enemyDatas.TryAdd(sleepersLanguageDatas.bigShooter, new EnemyData(150f, 2f, 2f, isArmored: false));
					break;
				case "CHARGER":
					_enemyDatas.TryAdd(sleepersLanguageDatas.charger, new EnemyData(30f, 1f, 2f, isArmored: true));
					break;
				case "CHARGER_SCOUT":
					_enemyDatas.TryAdd(sleepersLanguageDatas.chargerScout, new EnemyData(60f, 1f, 2f, isArmored: true));
					break;
				default:
					WeaponStatShowerPlugin.LogWarning("You inserted an incorrect value in the config: " + text2);
					break;
				}
			}
		}

		public string VerboseKill(ArchetypeDataBlock archetypeDB)
		{
			float damage = archetypeDB.Damage * (float)((archetypeDB.ShotgunBulletCount <= 0) ? 1 : archetypeDB.ShotgunBulletCount);
			float precisionDamageMulti = archetypeDB.PrecisionDamageMulti;
			return BuildKillString(precisionDamageMulti, (string _, EnemyData __) => damage);
		}

		internal string? VerboseKill(MeleeArchetypeDataBlock meleeArchetypeDB)
		{
			MeleeArchetypeDataBlock meleeArchetypeDB2 = meleeArchetypeDB;
			float baseDamage = meleeArchetypeDB2.ChargedAttackDamage * meleeArchetypeDB2.ChargedSleeperMulti;
			float chargedPrecisionMulti = meleeArchetypeDB2.ChargedPrecisionMulti;
			return BuildKillString(chargedPrecisionMulti, delegate(string enemyName, EnemyData _)
			{
				float num = baseDamage;
				if (enemyName.Contains("SCOUT") || enemyName.Contains("哨兵") || enemyName.Contains("黑触"))
				{
					num /= meleeArchetypeDB2.ChargedSleeperMulti;
				}
				return num;
			});
		}

		private string BuildKillString(float prcnMult, Func<string, EnemyData, float> getDamage)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			int num2 = 0;
			int num3 = _enemyDatas.Count - 1;
			foreach (KeyValuePair<string, EnemyData> enemyData2 in _enemyDatas)
			{
				enemyData2.Deconstruct(out var key, out var value);
				string text = key;
				EnemyData enemyData = value;
				float damage = getDamage(text, enemyData);
				List<string> list = new List<string>(4);
				if (canKillOnOccipit(damage, prcnMult, enemyData))
				{
					list.Add(sleepersLanguageDatas.occipit);
				}
				if (canKillOnHead(damage, prcnMult, enemyData))
				{
					list.Add(sleepersLanguageDatas.head);
				}
				if (canKillOnBack(damage, enemyData))
				{
					list.Add(sleepersLanguageDatas.back);
				}
				if (canKillOnChest(damage, enemyData))
				{
					list.Add(sleepersLanguageDatas.chest);
				}
				if (list.Count > 0)
				{
					if (num % 2 == 1)
					{
						stringBuilder.Append(" | ");
					}
					list.Reverse();
					stringBuilder.Append(text + ": [" + string.Join(",", list) + "]");
					if (num++ % 2 == 1 && num2 != num3)
					{
						stringBuilder.AppendLine();
					}
				}
				num2++;
			}
			if (num > 1 && stringBuilder.Length > 0)
			{
				if (stringBuilder[stringBuilder.Length - 1] != '\n')
				{
					stringBuilder.AppendLine();
				}
			}
			return stringBuilder.ToString();
		}

		private bool canKillOnChest(float damage, EnemyData data)
		{
			return damage >= data.Health;
		}

		private bool canKillOnBack(float damage, EnemyData data)
		{
			return damage * data.BackMultiplier >= data.Health;
		}

		private bool canKillOnHead(float damage, float prcnMultiplier, EnemyData data)
		{
			if (isArmored(data))
			{
				return damage * data.HeadMultiplier >= data.Health;
			}
			return damage * prcnMultiplier * data.HeadMultiplier >= data.Health;
		}

		private bool canKillOnOccipit(float damage, float prcnMultiplier, EnemyData data)
		{
			if (isArmored(data))
			{
				return damage * data.BackMultiplier * data.HeadMultiplier >= data.Health;
			}
			return damage * prcnMultiplier * data.BackMultiplier * data.HeadMultiplier >= data.Health;
		}

		private bool isArmored(EnemyData data)
		{
			return data.IsArmored;
		}
	}
	internal class WeaponDescriptionBuilder
	{
		private SleepersDatas _sleepersDatas;

		private PlayerDataBlock _playerDB;

		private GearIDRange _idRange;

		private uint _categoryID;

		private GearCategoryDataBlock _gearCategoryDB;

		private ItemDataBlock _itemDB;

		private LanguageDatas _languageDatas;

		private LanguageEnum _language;

		private LanguageEnum? _cachedLanguage;

		private LanguageDatas? _cachedLanguageDatas;

		private bool _showStats;

		private bool _showDescription;

		private readonly StringBuilder _strBuilder = new StringBuilder();

		private const string DIVIDER = " | ";

		private const string CLOSE_COLOR_TAG = "</color>";

		internal void Inizialize(GearIDRange idRange, PlayerDataBlock playerDB, LanguageEnum language, bool showStats, bool showDescription)
		{
			_idRange = idRange;
			_playerDB = playerDB;
			_language = language;
			_categoryID = idRange.GetCompID((eGearComponent)2);
			_gearCategoryDB = GameDataBlockBase<GearCategoryDataBlock>.GetBlock(_categoryID);
			_itemDB = GameDataBlockBase<ItemDataBlock>.GetBlock(_gearCategoryDB.BaseItem);
			_languageDatas = DeserializeLanguageJson(language);
			_showStats = showStats;
			_showDescription = showDescription;
		}

		public void UpdateSleepersDatas(string[] activatedSleepers, LanguageEnum language)
		{
			if (activatedSleepers[0].Trim().Length == 0)
			{
				WeaponStatShowerPlugin.LogWarning("Empty String in the config file, applying Default values");
				activatedSleepers = new string[1] { "ALL" };
			}
			_sleepersDatas = new SleepersDatas(activatedSleepers, DeserializeLanguageJson(language).sleepers);
		}

		private LanguageDatas DeserializeLanguageJson(LanguageEnum language)
		{
			if (_cachedLanguage == language && _cachedLanguageDatas != null)
			{
				return _cachedLanguageDatas;
			}
			LanguageDatasClass languageDatasClass = JsonSerializer.Deserialize<LanguageDatasClass>(LocalizedString.JsonString);
			_cachedLanguageDatas = (language.Equals(LanguageEnum.English) ? languageDatasClass.english : languageDatasClass.chinese);
			_cachedLanguage = language;
			return _cachedLanguageDatas;
		}

		public string DescriptionFormatter(string gearDescription)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if ((int)_itemDB.inventorySlot == 10)
			{
				MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(_gearCategoryDB));
				gearDescription = VerboseDescriptionFormatter(block);
				return gearDescription + GetFormatedWeaponStats(block, _itemDB);
			}
			var (val, isSentry) = GetRangedArchetype();
			if (val == null)
			{
				return (_showStats || _showDescription) ? string.Empty : gearDescription;
			}
			gearDescription = VerboseDescriptionFormatter(val, isSentry);
			return gearDescription + GetFormatedWeaponStats(val, isSentry);
		}

		internal string FireRateFormatter(string gearPublicName)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if ((int)_itemDB.inventorySlot == 10)
			{
				MeleeArchetypeDataBlock block = GameDataBlockBase<MeleeArchetypeDataBlock>.GetBlock(GearBuilder.GetMeleeArchetypeID(_gearCategoryDB));
				MeleeLanguageModel melee = _languageDatas.melee;
				return ((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)block).persistentID switch
				{
					1u => melee.hammer, 
					2u => melee.knife, 
					3u => melee.spear, 
					4u => melee.bat, 
					_ => gearPublicName, 
				};
			}
			ArchetypeDataBlock item = GetRangedArchetype().Item1;
			if (item == null)
			{
				return gearPublicName;
			}
			return VerbosePublicNameFireMode(item);
		}

		private (ArchetypeDataBlock?, bool) GetRangedArchetype()
		{
			bool item = _categoryID == 12;
			return (ArchetypeUtil.GetMappedArchetypeDataBlock(_idRange, _categoryID, _gearCategoryDB), item);
		}

		private string VerbosePublicNameFireMode(ArchetypeDataBlock archetypeDB)
		{
			//IL_000e: 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_0020: 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_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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected I4, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			FiremodeLanguageModel firemode = _languageDatas.firemode;
			eWeaponFireMode fireMode = archetypeDB.FireMode;
			_strBuilder.Clear();
			eWeaponFireMode val = fireMode;
			eWeaponFireMode val2 = val;
			switch ((int)val2)
			{
			case 2:
			case 11:
			{
				StringBuilder strBuilder = _strBuilder;
				StringBuilder stringBuilder6 = strBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
				handler.AppendFormatted(firemode.fullA);
				handler.AppendLiteral(" (<#12FF50>");
				handler.AppendFormatted(_languageDatas.rateOfFire);
				handler.AppendLiteral(" ");
				handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
				handler.AppendFormatted("</color>");
				handler.AppendLiteral(")");
				stringBuilder6.Append(ref handler);
				break;
			}
			case 0:
			case 10:
			{
				StringBuilder strBuilder = _strBuilder;
				StringBuilder stringBuilder5 = strBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
				handler.AppendFormatted(firemode.semiA);
				handler.AppendLiteral(" (<#12FF50>");
				handler.AppendFormatted(_languageDatas.rateOfFire);
				handler.AppendLiteral(" ");
				handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
				handler.AppendFormatted("</color>");
				handler.AppendLiteral(")");
				stringBuilder5.Append(ref handler);
				break;
			}
			case 1:
			case 12:
				if (archetypeDB.BurstShotCount != 1)
				{
					StringBuilder strBuilder = _strBuilder;
					StringBuilder stringBuilder3 = strBuilder;
					StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(23, 7, strBuilder);
					handler.AppendFormatted(firemode.burst);
					handler.AppendLiteral(" (<#704dfa>#");
					handler.AppendFormatted(archetypeDB.BurstShotCount);
					handler.AppendFormatted("</color>");
					handler.AppendFormatted(" | ");
					handler.AppendLiteral("<#12FF50>");
					handler.AppendFormatted(_languageDatas.rateOfFire);
					handler.AppendLiteral(" ");
					handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
					handler.AppendFormatted("</color>");
					handler.AppendLiteral(")");
					stringBuilder3.Append(ref handler);
				}
				else
				{
					StringBuilder strBuilder = _strBuilder;
					StringBuilder stringBuilder4 = strBuilder;
					StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
					handler.AppendFormatted(firemode.burst);
					handler.AppendLiteral(" (<#12FF50>");
					handler.AppendFormatted(_languageDatas.rateOfFire);
					handler.AppendLiteral(" ");
					handler.AppendFormatted(GetRateOfFire(archetypeDB, (eWeaponFireMode)0));
					handler.AppendFormatted("</color>");
					handler.AppendLiteral(")");
					stringBuilder4.Append(ref handler);
				}
				break;
			case 3:
			{
				StringBuilder strBuilder = _strBuilder;
				StringBuilder stringBuilder2 = strBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(28, 3, strBuilder);
				handler.AppendLiteral("S-Burst (<#12FF50>#");
				handler.AppendFormatted(archetypeDB.BurstShotCount);
				handler.AppendLiteral(" every ");
				handler.AppendFormatted(archetypeDB.SpecialSemiBurstCountTimeout);
				handler.AppendLiteral("'");
				handler.AppendFormatted("</color>");
				handler.AppendLiteral(")");
				stringBuilder2.Append(ref handler);
				break;
			}
			case 13:
			{
				StringBuilder strBuilder = _strBuilder;
				StringBuilder stringBuilder = strBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 4, strBuilder);
				handler.AppendFormatted(firemode.shotgunSentry);
				handler.AppendLiteral(" (<#12FF50>");
				handler.AppendFormatted(_languageDatas.rateOfFire);
				handler.AppendLiteral(" ");
				handler.AppendFormatted(GetRateOfFire(archetypeDB, fireMode));
				handler.AppendFormatted("</color>");
				handler.AppendLiteral(")");
				stringBuilder.Append(ref handler);
				break;
			}
			default:
				WeaponStatShowerPlugin.LogError("FireMode not found");
				break;
			}
			return _strBuilder.ToString();
		}

		private string VerboseDescriptionFormatter(ArchetypeDataBlock archetypeDB, bool isSentry)
		{
			SpreadLanguageModel spread = _languageDatas.spread;
			_strBuilder.Clear();
			switch (archetypeDB.ShotgunBulletSpread + archetypeDB.ShotgunConeSize)
			{
			case 1:
				_strBuilder.AppendLine(spread.chocked);
				break;
			case 4:
				_strBuilder.AppendLine(spread.small);
				break;
			case 5:
			case 7:
				_strBuilder.AppendLine(spread.medium);
				break;
			case 9:
				_strBuilder.AppendLine(spread.huge);
				break;
			default:
				WeaponStatShowerPlugin.LogError(LocalizedText.op_Implicit(archetypeDB.PublicName) + ": spread not considered{" + archetypeDB.ShotgunBulletSpread + "/" + archetypeDB.ShotgunConeSize + "}");
				break;
			case 0:
				break;
			}
			float specialChargetupTime = archetypeDB.SpecialChargetupTime;
			if (specialChargetupTime > 0f)
			{
				string value = (((double)specialChargetupTime > 0.4) ? _languageDatas.longChargeUp : _languageDatas.shortChargeUp);
				StringBuilder strBuilder = _strBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, strBuilder);
				handler.AppendFormatted(value);
				handler.AppendLiteral(" (");
				handler.AppendFormatted(FormatFloat(specialChargetupTime, 2));
				handler.AppendLiteral(")");
				strBuilder.AppendLine(ref handler);
			}
			return (_strBuilder.Length == 0) ? string.Empty : (_strBuilder.ToString() + "\n");
		}

		private string VerboseDescriptionFormatter(MeleeArchetypeDataBlock meleeArchetypeDB)
		{
			_strBuilder.Clear();
			if ((double)meleeArchetypeDB.CameraDamageRayLength < 1.76)
			{
				_strBuilder.AppendLine(_languageDatas.melee.shortRange);
			}
			else if ((double)meleeArchetypeDB.CameraDamageRayLength < 2.5)
			{
				_strBuilder.AppendLine(_languageDatas.melee.mediumRange);
			}
			else
			{
				_strBuilder.AppendLine(_languageDatas.melee.longRange);
			}
			_strBuilder.Append(meleeArchetypeDB.CanHitMultipleEnemies ? (_languageDatas.melee.canPierce + "\n") : string.Empty);
			return (_strBuilder.Length == 0) ? string.Empty : _strBuilder.ToString();
		}

		private string GetFormatedWeaponStats(ArchetypeDataBlock archetypeDB, bool isSentry = false)
		{
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			if (archetypeDB == null)
			{
				return string.Empty;
			}
			int count = 0;
			int dividerThreshold = ((_language != 0) ? 3 : 4);
			_strBuilder.Clear();
			if (_showStats)
			{
				string value = FormatFloat(archetypeDB.Damage, 2) + ((archetypeDB.ShotgunBulletCount > 0) ? $"(x{archetypeDB.ShotgunBulletCount})" : "");
				AppendStat(ref count, "<#9D2929>", _languageDatas.damage, value);
				AppendStatIf(ref count, Divider, !isSentry, "<color=orange>", _languageDatas.clip, archetypeDB.DefaultClipSize.ToString());
				Divider();
				AppendStat(ref count, "<#FFD306>", _languageDatas.maxAmmo, GetTotalAmmo(archetypeDB, _itemDB, isSentry).ToString());
				AppendStatIf(ref count, Divider, !isSentry, "<#C0FF00>", _languageDatas.reload, FormatFloat(archetypeDB.DefaultReloadTime, 2).ToString());
				AppendStatIf(ref count, Divider, archetypeDB.PrecisionDamageMulti != 1f, "<#18A4A9>", _languageDatas.precision, FormatFloat(archetypeDB.PrecisionDamageMulti, 2).ToString());
				Divider();
				AppendStat(ref count, "<#6764de>", _languageDatas.falloff, (int)archetypeDB.DamageFalloff.x + "m");
				AppendStatIf(ref count, Divider, archetypeDB.StaggerDamageMulti != 1f, "<color=green>", _languageDatas.stagger, FormatFloat(archetypeDB.StaggerDamageMulti, 2).ToString());
				AppendStatIf(ref count, Divider, archetypeDB.HipFireSpread != 0f && archetypeDB.ShotgunBulletCount == 0, "<#cc9347>", _languageDatas.hipSpread, FormatFloat(archetypeDB.HipFireSpread, 2).ToString());
				AppendStatIf(ref count, Divider, archetypeDB.AimSpread != 0f && archetypeDB.ShotgunBulletCount == 0, "<#e6583c>", _languageDatas.aimDSpread, FormatFloat(archetypeDB.AimSpread, 2).ToString());
				AppendStatIf(ref count, Divider, archetypeDB.PiercingBullets, "<#097345>", _languageDatas.pierceCount, archetypeDB.PiercingDamageCountLimit.ToString());
				_strBuilder.AppendLine();
			}
			_strBuilder.Append(_sleepersDatas.VerboseKill(archetypeDB));
			return _strBuilder.ToString();
			void Divider()
			{
				if (count >= dividerThreshold)
				{
					_strBuilder.AppendLine();
					count = 0;
				}
				else if (count > 0)
				{
					_strBuilder.Append(" | ");
				}
			}
		}

		private string GetFormatedWeaponStats(MeleeArchetypeDataBlock meleeArchetypeDB, ItemDataBlock itemDB)
		{
			if (meleeArchetypeDB == null)
			{
				return string.Empty;
			}
			int count = 0;
			MeleeLanguageModel melee = _languageDatas.melee;
			_strBuilder.Clear();
			if (_showStats)
			{
				_strBuilder.AppendLine();
				AppendStat(ref count, "<#9D2929>", _languageDatas.damage + "." + melee.light, meleeArchetypeDB.LightAttackDamage.ToString());
				Divider();
				AppendStat(ref count, "<color=orange>", _languageDatas.damage + "." + melee.heavy, meleeArchetypeDB.ChargedAttackDamage.ToString());
				AppendStatIf(ref count, Divider, !meleeArchetypeDB.AllowRunningWhenCharging, "<#FFD306>", melee.canRunWhileCharging);
				AppendStatIf(ref count, Divider, meleeArchetypeDB.LightStaggerMulti != 1f, "<#C0FF00>", _languageDatas.stagger + "." + melee.light, meleeArchetypeDB.LightStaggerMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedStaggerMulti != 1f, "<color=green>", _languageDatas.stagger + "." + melee.heavy, meleeArchetypeDB.ChargedStaggerMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.LightPrecisionMulti != 1f, "<#004E2C>", _languageDatas.precision + "." + melee.light, meleeArchetypeDB.LightPrecisionMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedPrecisionMulti != 1f, "<#55022B>", _languageDatas.precision + "." + melee.heavy, meleeArchetypeDB.ChargedPrecisionMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.LightSleeperMulti != 1f, "<#A918A7>", melee.sleepingEnemiesMultiplier + "." + melee.light, meleeArchetypeDB.LightSleeperMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedSleeperMulti != 1f, "<#025531>", melee.sleepingEnemiesMultiplier + "." + melee.heavy, meleeArchetypeDB.ChargedSleeperMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.LightEnvironmentMulti != 1f, "<#18A4A9>", melee.environmentMultiplier + "." + melee.light, meleeArchetypeDB.LightEnvironmentMulti.ToString());
				AppendStatIf(ref count, Divider, meleeArchetypeDB.ChargedEnvironmentMulti != 1f, "<#75A2AA>", melee.environmentMultiplier + "." + melee.heavy, meleeArchetypeDB.ChargedEnvironmentMulti.ToString());
				_strBuilder.AppendLine();
			}
			_strBuilder.Append(_sleepersDatas.VerboseKill(meleeArchetypeDB) ?? string.Empty);
			return _strBuilder.ToString();
			void Divider()
			{
				if (count >= 3)
				{
					_strBuilder.AppendLine();
					count = 0;
				}
				else if (count > 0)
				{
					_strBuilder.Append(" | ");
				}
			}
		}

		private void AppendStatIf(ref int count, Action divider, bool condition, string color, string label, string value = "")
		{
			if (condition)
			{
				divider();
				AppendStat(ref count, color, label, value);
			}
		}

		private void AppendStat(ref int count, string color, string label, string value = "")
		{
			_strBuilder.Append(color);
			_strBuilder.Append(label);
			if (!string.IsNullOrEmpty(value))
			{
				_strBuilder.Append(' ');
				_strBuilder.Append(value);
			}
			_strBuilder.Append("</color>");
			count++;
		}

		private static float FormatFloat(float value, int v)
		{
			return (float)Math.Round((decimal)value, v);
		}

		private int GetAmmoMax(ItemDataBlock itemDataBlock)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			AmmoType ammoTypeFromSlot = PlayerAmmoStorage.GetAmmoTypeFromSlot(itemDataBlock.inventorySlot);
			return (int)ammoTypeFromSlot switch
			{
				0 => _playerDB.AmmoStandardMaxCap, 
				1 => _playerDB.AmmoSpecialMaxCap, 
				2 => _playerDB.AmmoClassMaxCap, 
				5 => itemDataBlock.ConsumableAmmoMax, 
				_ => -1, 
			};
		}

		private int GetTotalAmmo(ArchetypeDataBlock archetypeDB, ItemDataBlock itemDB, bool isSentry = false)
		{
			int ammoMax = GetAmmoMax(itemDB);
			float num = archetypeDB.CostOfBullet;
			if (isSentry)
			{
				num *= itemDB.ClassAmmoCostFactor;
				if ((float)archetypeDB.ShotgunBulletCount > 0f)
				{
					num *= (float)archetypeDB.ShotgunBulletCount;
				}
			}
			int num2 = (int)((float)ammoMax / num);
			return isSentry ? num2 : (num2 + archetypeDB.DefaultClipSize);
		}

		private string GetRateOfFire(ArchetypeDataBlock archetypeDB, eWeaponFireMode fireMode)
		{
			//IL_0007: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			//IL_001f: 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_0034: Expected I4, but got Unknown
			float value = -1f;
			float num;
			switch ((int)fireMode)
			{
			default:
				switch (fireMode - 11)
				{
				case 0:
					break;
				case 2:
					goto IL_0045;
				case 1:
					goto IL_005b;
				default:
					goto end_IL_000c;
				}
				goto case 2;
			case 2:
				value = 1f / archetypeDB.ShotDelay;
				break;
			case 0:
				goto IL_0045;
			case 1:
				goto IL_005b;
				IL_005b:
				num = 1f / (archetypeDB.BurstDelay + archetypeDB.SpecialChargetupTime + archetypeDB.ShotDelay * (float)(archetypeDB.BurstShotCount - 1));
				value = num * (float)archetypeDB.BurstShotCount;
				break;
				IL_0045:
				value = 1f / (archetypeDB.ShotDelay + archetypeDB.SpecialChargetupTime);
				break;
				end_IL_000c:
				break;
			}
			return FormatFloat(value, 1).ToString();
		}
	}
}
namespace WeaponStatShower.Utils.Language
{
	public class LanguageDatas
	{
		public FiremodeLanguageModel firemode { get; set; } = new FiremodeLanguageModel();


		public MeleeLanguageModel melee { get; set; } = new MeleeLanguageModel();


		public SpreadLanguageModel spread { get; set; } = new SpreadLanguageModel();


		public SleepersLanguageModel sleepers { get; set; } = new SleepersLanguageModel();


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


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


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


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


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


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


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


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


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


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


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


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


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


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

	}
	internal class LanguageDatasClass
	{
		public LanguageDatas english { get; set; } = new LanguageDatas();


		public LanguageDatas chinese { get; set; } = new LanguageDatas();

	}
	internal enum LanguageEnum
	{
		English,
		Chinese
	}
	internal class LocalizedString
	{
		public static readonly string JsonString = "{\r\n\t\t\t\"english\": {\r\n\t\t\t\t\"firemode\": {\r\n\t\t\t\t\t\"fullA\": \"Full-A\",\r\n\t\t\t\t\t\"semiA\": \"Semi-A\",\r\n\t\t\t\t\t\"burst\": \"Burst\",\r\n\t\t\t\t\t\"shotgunSentry\": \"Shotgun-S\"\r\n\t\t\t\t},\r\n\t\t\t\t\"melee\": {\r\n\t\t\t\t\t\"light\": \"Lgt\",\r\n\t\t\t\t\t\"heavy\": \"Hvy\",\r\n\t\t\t\t\t\"canRunWhileCharging\": \"Can't run\",\r\n\t\t\t\t\t\"sleepingEnemiesMultiplier\": \"Slp\",\r\n\t\t\t\t\t\"environmentMultiplier\": \"Env\",\r\n\t\t\t\t\t\"canPierce\": \"Piercing\",\r\n\t\t\t\t\t\"shortRange\": \"Short Range\",\r\n\t\t\t\t\t\"mediumRange\": \"Medium Range\",\r\n\t\t\t\t\t\"longRange\": \"Long Range\",\r\n\t\t\t\t\t\"hammer\": \"Hammer - Balanced\",\r\n\t\t\t\t\t\"knife\": \"Knife - Fast\",\r\n\t\t\t\t\t\"bat\": \"Bat - Fast\",\r\n\t\t\t\t\t\"spear\": \"Spear - Slow\"\r\n\t\t\t\t},\r\n\t\t\t\t\"spread\": {\r\n\t\t\t\t\t\"chocked\": \"Chocked Spread\",\r\n\t\t\t\t\t\"small\": \"Small Spread\",\r\n\t\t\t\t\t\"medium\": \"Medium Spread\",\r\n\t\t\t\t\t\"large\": \"Large Spread\",\r\n\t\t\t\t\t\"huge\": \"Huge Spread\"\r\n\t\t\t\t},\r\n\t\t\t\t\"sleepers\": {\r\n\t\t\t\t\t\"striker\": \"STRK\",\r\n\t\t\t\t\t\"shooter\": \"SHTR\",\r\n\t\t\t\t\t\"scout\": \"SCOUT\",\r\n\t\t\t\t\t\"bigStriker\": \"B-STRK\",\r\n\t\t\t\t\t\"bigShooter\": \"B-SHTR\",\r\n\t\t\t\t\t\"charger\": \"CHRG\",\r\n\t\t\t\t\t\"chargerScout\": \"C-SCOUT\",\r\n\t\t\t\t\t\"occipit\": \"o\",\r\n\t\t\t\t\t\"head\": \"h\",\r\n\t\t\t\t\t\"back\": \"b\",\r\n\t\t\t\t\t\"chest\": \"c\"\r\n\t\t\t\t},\r\n\t\t\t\t\"damage\": \"Dmg\",\r\n\t\t\t\t\"clip\": \"Clp\",\r\n\t\t\t\t\"maxAmmo\": \"Max\",\r\n\t\t\t\t\"falloff\": \"Dist\",\r\n\t\t\t\t\"reload\": \"Rld\",\r\n\t\t\t\t\"stagger\": \"Stgr\",\r\n\t\t\t\t\"precision\": \"Prcn\",\r\n\t\t\t\t\"pierceCount\": \"Pierc\",\r\n\t\t\t\t\"rateOfFire\": \"RoF\",\r\n\t\t\t\t\"aimDSpread\": \"ADS\",\r\n\t\t\t\t\"hipSpread\": \"HIP\",\r\n\t\t\t\t\"deployable\": \"Deployable\",\r\n\t\t\t\t\"longChargeUp\": \"Long Charge-up\",\r\n\t\t\t\t\"shortChargeUp\": \"short Charge-up\"\r\n\t\t\t},\r\n\r\n\t\t\t\"chinese\": {\r\n\t\t\t\t\"firemode\": {\r\n\t\t\t\t\t\"fullA\": \"全自动\",\r\n\t\t\t\t\t\"semiA\": \"半自动\",\r\n\t\t\t\t\t\"burst\": \"连发\",\r\n\t\t\t\t\t\"shotgunSentry\": \"半自动霰弹射击\"\r\n\t\t\t\t},\r\n\t\t\t\t\"melee\": {\r\n\t\t\t\t\t\"light\": \"轻击\",\r\n\t\t\t\t\t\"heavy\": \"重击\",\r\n\t\t\t\t\t\"canRunWhileCharging\": \"不能冲刺\",\r\n\t\t\t\t\t\"sleepingEnemiesMultiplier\": \"沉睡倍率\",\r\n\t\t\t\t\t\"environmentMultiplier\": \"环境倍率\",\r\n\t\t\t\t\t\"canPierce\": \"穿刺\",\r\n\t\t\t\t\t\"shortRange\": \"短距离\",\r\n\t\t\t\t\t\"mediumRange\": \"中距离\",\r\n\t\t\t\t\t\"longRange\": \"长距离\",\r\n\t\t\t\t\t\"hammer\": \"大锤 - 均衡\",\r\n\t\t\t\t\t\"knife\": \"刀 - 快速\",\r\n\t\t\t\t\t\"bat\": \"棍棒 - 快速\",\r\n\t\t\t\t\t\"spear\": \"矛 - 慢速\"\r\n\t\t\t\t},\r\n\t\t\t\t\"spread\": {\r\n\t\t\t\t\t\"chocked\": \"收束扩散\",\r\n\t\t\t\t\t\"small\": \"扩散小\",\r\n\t\t\t\t\t\"medium\": \"中度扩散\",\r\n\t\t\t\t\t\"large\": \"扩散大\",\r\n\t\t\t\t\t\"huge\": \"超大扩散\"\r\n\t\t\t\t},\r\n\t\t\t\t\"sleepers\": {\r\n\t\t\t\t\t\"striker\": \"前锋\",\r\n\t\t\t\t\t\"shooter\": \"射手\",\r\n\t\t\t\t\t\"scout\": \"哨兵\",\r\n\t\t\t\t\t\"bigStriker\": \"大壮\",\r\n\t\t\t\t\t\"bigShooter\": \"大姐\",\r\n\t\t\t\t\t\"charger\": \"黑刺\",\r\n\t\t\t\t\t\"chargerScout\": \"黑触\",\r\n\t\t\t\t\t\"occipit\": \"后脑\",\r\n\t\t\t\t\t\"head\": \"头\",\r\n\t\t\t\t\t\"back\": \"背\",\r\n\t\t\t\t\t\"chest\": \"胸\"\r\n\t\t\t\t},\r\n\r\n\t\t\t\t\"damage\": \"伤害\",\r\n\t\t\t\t\"clip\": \"弹容量\",\r\n\t\t\t\t\"maxAmmo\": \"总弹量\",\r\n\t\t\t\t\"falloff\": \"衰减距离\",\r\n\t\t\t\t\"reload\": \"换弹时间\",\r\n\t\t\t\t\"stagger\": \"硬直倍率\",\r\n\t\t\t\t\"precision\": \"精准倍率\",\r\n\t\t\t\t\"pierceCount\": \"穿透\",\r\n\t\t\t\t\"rateOfFire\": \"射速\",\r\n\t\t\t\t\"aimDSpread\": \"倍镜\",\r\n\t\t\t\t\"hipSpread\": \"后坐力\",\r\n\t\t\t\t\"deployable\": \"可部署\",\r\n\t\t\t\t\"longChargeUp\": \"长蓄力\",\r\n\t\t\t\t\"shortChargeUp\": \"短蓄力\"\r\n\t\t\t}\r\n\t\t}";
	}
}
namespace WeaponStatShower.Utils.Language.Models
{
	public class FiremodeLanguageModel
	{
		public string fullA { get; set; } = string.Empty;


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


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


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

	}
	public class MeleeLanguageModel
	{
		public string light { get; set; } = string.Empty;


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


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


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


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


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


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


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


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


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


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


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


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

	}
	public class SleepersLanguageModel
	{
		public string striker { get; set; } = string.Empty;


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


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


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


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


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


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


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


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


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


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

	}
	public class SpreadLanguageModel
	{
		public string chocked { get; set; } = string.Empty;


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


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


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


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

	}
}
namespace WeaponStatShower.Patches
{
	public abstract class Patch
	{
		protected internal Harmony? Harmony { get; set; }

		public virtual string Name { get; }

		public virtual bool Enabled => true;

		public virtual void Initialize()
		{
		}

		public abstract void Execute();

		public void PatchConstructor<TClass>(PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class
		{
			PatchConstructor<TClass>(null, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchConstructor<TClass>(Type[]? parameters, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null) where TClass : class
		{
			ConstructorInfo methodBase = AccessTools.Constructor(typeof(TClass), parameters, false);
			PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchMethod<TClass>(methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			MethodInfo methodBase = AccessTools.Method(typeof(TClass), methodName, parameters, generics);
			PatchMethod<TClass>(methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod<TClass>(MethodBase methodBase, PatchType patchType, string prefixMethodName = null, string postfixMethodName = null) where TClass : class
		{
			PatchMethod(typeof(TClass), methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(Type classType, string methodName, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
		{
			PatchMethod(classType, methodName, null, patchType, generics, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(Type classType, string methodName, Type[] parameters, PatchType patchType, Type[] generics = null, string prefixMethodName = null, string postfixMethodName = null)
		{
			MethodInfo methodBase = AccessTools.Method(classType, methodName, parameters, generics);
			PatchMethod(classType, methodBase, patchType, prefixMethodName, postfixMethodName);
		}

		public void PatchMethod(Type classType, MethodBase methodBase, PatchType patchType, string? prefixMethodName = null, string? postfixMethodName = null)
		{
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_0175: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			string text = classType.Name.Replace("`", "__");
			string value = methodBase.ToString();
			string text2 = (methodBase.IsConstructor ? "ctor" : methodBase.Name);
			MethodInfo methodInfo = null;
			MethodInfo methodInfo2 = null;
			if ((patchType & PatchType.Prefix) != 0)
			{
				try
				{
					methodInfo2 = AccessTools.Method(GetType(), prefixMethodName ?? (text + "__" + text2 + "__Prefix"), (Type[])null, (Type[])null);
				}
				catch (Exception value2)
				{
					WeaponStatShowerPlugin.LogFatal($"Failed to obtain the prefix patch method for {value}): {value2}");
				}
			}
			if ((patchType & PatchType.Postfix) != 0)
			{
				try
				{
					methodInfo = AccessTools.Method(GetType(), postfixMethodName ?? (text + "__" + text2 + "__Postfix"), (Type[])null, (Type[])null);
				}
				catch (Exception value3)
				{
					WeaponStatShowerPlugin.LogFatal($"Failed to obtain the postfix patch method for {value}): {value3}");
				}
			}
			try
			{
				if (methodInfo2 != null && methodInfo != null)
				{
					Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else if (methodInfo2 != null)
				{
					Harmony.Patch(methodBase, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else if (methodInfo != null)
				{
					Harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception value4)
			{
				WeaponStatShowerPlugin.LogError($"Failed to patch method {value}: {value4}");
			}
		}
	}
	[Flags]
	public enum PatchType : byte
	{
		Prefix = 1,
		Postfix = 2,
		Both = 3
	}
	internal class ShowStat : Patch
	{
		private static readonly ConfigDefinition ConfigEnabled = new ConfigDefinition("ShowStat", "Enabled");

		private static readonly ConfigDefinition Language = new ConfigDefinition("ShowStat", "Language");

		private static readonly ConfigDefinition ConfigSleepers = new ConfigDefinition("ShowStat", "SleepersShown");

		private static readonly ConfigDefinition ShowStats = new ConfigDefinition("ShowStat", "ShowStats");

		private static readonly ConfigDefinition ShowDescription = new ConfigDefinition("ShowStat", "ShowDescription");

		private static WeaponDescriptionBuilder? DescriptionBuilder;

		private static LanguageEnum PrevLanguageEnum = LanguageEnum.English;

		private static string PrevShownSleepers = "PLACEHOLDER";

		private const string PatchName = "ShowStat";

		private const PatchType patchType = PatchType.Postfix;

		public override string Name { get; } = "ShowStat";


		public static Patch Instance { get; private set; }

		public override void Initialize()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			Instance = this;
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<bool>(ConfigEnabled, true, new ConfigDescription("Show the stats of a weapon.", (AcceptableValueBase)null, Array.Empty<object>()));
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<LanguageEnum>(Language, LanguageEnum.English, new ConfigDescription("Select the mod language.", (AcceptableValueBase)null, Array.Empty<object>()));
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<string>(ConfigSleepers, "NONE", new ConfigDescription("Select which Sleepers are shown, seperated by a comma.\nAcceptable values: ALL, NONE, STRIKER, SHOOTER, SCOUT, BIG_STRIKER, BIG_SHOOTER, CHARGER, CHARGER_SCOUT", (AcceptableValueBase)null, Array.Empty<object>()));
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<bool>(ShowStats, true, new ConfigDescription("Show auto-generated weapon stats.", (AcceptableValueBase)null, Array.Empty<object>()));
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Bind<bool>(ShowDescription, true, new ConfigDescription("Show gear descriptions alongside stats and enemy killpoints (if enabled).", (AcceptableValueBase)null, Array.Empty<object>()));
			DescriptionBuilder = new WeaponDescriptionBuilder();
		}

		public override void Execute()
		{
			PatchMethod<CM_InventorySlotItem>("LoadData", PatchType.Postfix);
		}

		public static void CM_InventorySlotItem__LoadData__Postfix(CM_InventorySlotItem __instance, GearIDRange idRange, bool clickable, bool detailedInfo)
		{
			if ((Object)(object)__instance == (Object)null || !detailedInfo)
			{
				return;
			}
			if (DescriptionBuilder == null)
			{
				WeaponStatShowerPlugin.LogError("Something went wrong with the DescriptionBuilder");
				return;
			}
			((BasePlugin)WeaponStatShowerPlugin.Instance).Config.Reload();
			ConfigFile config = ((BasePlugin)WeaponStatShowerPlugin.Instance).Config;
			string text = config.GetConfigEntry<string>(ConfigSleepers).Value.Trim().ToUpper();
			LanguageEnum value = config.GetConfigEntry<LanguageEnum>(Language).Value;
			bool value2 = config.GetConfigEntry<bool>(ShowStats).Value;
			bool value3 = config.GetConfigEntry<bool>(ShowDescription).Value;
			if (!PrevShownSleepers.Equals(text) || !value.Equals(PrevLanguageEnum))
			{
				DescriptionBuilder.UpdateSleepersDatas(text.Split(','), value);
				PrevShownSleepers = text;
				PrevLanguageEnum = value;
			}
			DescriptionBuilder.Inizialize(idRange, GameDataBlockBase<PlayerDataBlock>.GetBlock(1u), value, value2, value3);
			if (value3)
			{
				string text2 = DescriptionBuilder.DescriptionFormatter(__instance.GearDescription);
				if (!Utility.IsNullOrWhiteSpace(text2))
				{
					text2 += "\n";
				}
				__instance.GearDescription = text2 + __instance.GearDescription;
			}
			__instance.GearPublicName = DescriptionBuilder.FireRateFormatter(__instance.GearPublicName);
		}
	}
}