Decompiled source of AccuracyTracker v1.2.2

BepInEx/plugins/Hikaria.AccuracyTracker/Hikaria.AccuracyTracker.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using Agents;
using BepInEx.Unity.IL2CPP.Utils;
using GameData;
using Gear;
using Hikaria.AccuracyTracker.Extensions;
using Hikaria.AccuracyTracker.Features;
using Hikaria.AccuracyTracker.Handlers;
using Hikaria.AccuracyTracker.Managers;
using Hikaria.Core;
using Hikaria.Core.Interfaces;
using Hikaria.Core.SNetworkExt;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Player;
using SNetwork;
using TMPro;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
using TheArchive.Core.Localization;
using TheArchive.Core.Models;
using TheArchive.Interfaces;
using TheArchive.Loader;
using TheArchive.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ModDefaultFeatureGroupName("Accuracy Tracker")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Hikaria.AccuracyTracker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5df8a29f6ac0deee8a7f75fe5c6bc03a06e9c7d7")]
[assembly: AssemblyProduct("Hikaria.AccuracyTracker")]
[assembly: AssemblyTitle("Hikaria.AccuracyTracker")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Hikaria.AccuracyTracker
{
	[ArchiveDependency(/*Could not decode attribute arguments.*/)]
	[ArchiveModule("Hikaria.AccuracyTracker", "AccuracyTracker", "1.2.2")]
	public class EntryPoint : IArchiveModule
	{
		public static EntryPoint Instance { get; private set; }

		public bool ApplyHarmonyPatches => false;

		public bool UsesLegacyPatches => false;

		public ArchiveLegacyPatcher Patcher { get; set; }

		public string ModuleGroup => "Accuracy Tracker";

		public Dictionary<Language, string> ModuleGroupLanguages => new Dictionary<Language, string>
		{
			{
				(Language)1,
				"命中率指示器"
			},
			{
				(Language)0,
				"Accuracy Tracker"
			}
		};

		public void Init()
		{
			Instance = this;
			Logs.LogMessage("OK");
		}

		public void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
		}

		public void OnLateUpdate()
		{
		}

		public void OnExit()
		{
		}
	}
	internal static class Logs
	{
		private static IArchiveLogger _logger;

		private static IArchiveLogger Logger => _logger ?? (_logger = LoaderWrapper.CreateLoggerInstance("Hikaria.AccuracyTracker", ConsoleColor.White));

		public static void LogDebug(object data)
		{
			Logger.Debug(data.ToString());
		}

		public static void LogError(object data)
		{
			Logger.Error(data.ToString());
		}

		public static void LogInfo(object data)
		{
			Logger.Info(data.ToString());
		}

		public static void LogMessage(object data)
		{
			Logger.Msg(ConsoleColor.White, data.ToString());
		}

		public static void LogWarning(object data)
		{
			Logger.Warning(data.ToString());
		}

		public static void LogNotice(object data)
		{
			Logger.Notice(data.ToString());
		}

		public static void LogSuccess(object data)
		{
			Logger.Success(data.ToString());
		}

		public static void LogException(Exception ex)
		{
			Logger.Exception(ex);
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Hikaria.AccuracyTracker";

		public const string NAME = "AccuracyTracker";

		public const string VERSION = "1.2.2";
	}
}
namespace Hikaria.AccuracyTracker.Managers
{
	public static class AccuracyManager
	{
		public struct pAccuracyData
		{
			public pPlayer Owner;

			public pAccuracySlotData StandardSlotData;

			public pAccuracySlotData SpecialSlotData;

			internal pAccuracyData(SNet_Player player, Dictionary<InventorySlot, AccuracyUpdater.AccuracyData.AccuracySlotData> slotDatas)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Owner = default(pPlayer);
				StandardSlotData = default(pAccuracySlotData);
				SpecialSlotData = default(pAccuracySlotData);
				((pPlayer)(ref Owner)).SetPlayer(player);
				if (slotDatas.TryGetValue((InventorySlot)1, out var value))
				{
					StandardSlotData = new pAccuracySlotData(value);
				}
				if (slotDatas.TryGetValue((InventorySlot)2, out var value2))
				{
					SpecialSlotData = new pAccuracySlotData(value2);
				}
			}
		}

		public struct pAccuracySlotData
		{
			public uint Hitted { get; private set; }

			public uint Shotted { get; private set; }

			public uint WeakspotHitted { get; private set; }

			public InventorySlot Slot { get; private set; }

			internal pAccuracySlotData(AccuracyUpdater.AccuracyData.AccuracySlotData data)
			{
				//IL_0017: 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)
				Hitted = 0u;
				Shotted = 0u;
				WeakspotHitted = 0u;
				Slot = (InventorySlot)0;
				Hitted = data.m_Hitted;
				Shotted = data.m_Shotted;
				WeakspotHitted = data.m_WeakspotHitted;
				Slot = data.m_Slot;
			}
		}

		private static Version MinimumVer = new Version("1.2.0", false);

		private static SNetExt_BroadcastAction<pAccuracyData> s_AccuracyDataBroadcastAction;

		public static bool IsMasterHasAcc { get; private set; }

		public static Dictionary<ulong, AccuracyUpdater.AccuracyData> AccuracyDataLookup { get; private set; } = new Dictionary<ulong, AccuracyUpdater.AccuracyData>();


		internal static void Setup()
		{
			CoreAPI.OnPlayerModsSynced += OnPlayerModsSynced;
			GameEventAPI.OnPlayerSlotChanged += OnPlayerSlotChanged;
			GameEventAPI.OnMasterChanged += OnMasterChanged;
			s_AccuracyDataBroadcastAction = SNetExt_BroadcastAction<pAccuracyData>.Create(typeof(pAccuracyData).FullName + "_v3", (Action<ulong, pAccuracyData>)ReceiveAccuracyData, (Func<SNet_Player, bool>)AccuracyDataListenerFilter, (SNet_ChannelType)4);
			((SNetExt_SyncedAction<pAccuracyData>)(object)s_AccuracyDataBroadcastAction).OnPlayerAddedToListeners += SyncToPlayer;
			((SNetExt_SyncedAction<pAccuracyData>)(object)s_AccuracyDataBroadcastAction).OnPlayerRemovedFromListeners += AccuracyUpdater.UnregisterPlayer;
		}

		internal static void DoClear()
		{
			foreach (AccuracyUpdater.AccuracyData value in AccuracyDataLookup.Values)
			{
				value.DoClear();
				value.NeedUpdate = true;
			}
		}

		private static void SyncToPlayer(SNet_Player player)
		{
			foreach (AccuracyUpdater.AccuracyData value in AccuracyDataLookup.Values)
			{
				if (value.Owner.IsLocal || SNet.IsMaster)
				{
					((SNetExt_SyncedAction<pAccuracyData>)(object)s_AccuracyDataBroadcastAction).SyncToPlayer(player, value.GetAccuracyData());
				}
			}
		}

		private static void OnPlayerSlotChanged(SNet_Player player, SNet_SlotType type, SNet_SlotHandleType handle, int index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			if ((int)handle == 0 || (int)handle == 1)
			{
				AccuracyUpdater.RegisterPlayer(player);
			}
		}

		private static bool AccuracyDataListenerFilter(SNet_Player player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return CoreAPI.IsPlayerInstalledMod(player, "Hikaria.AccuracyTracker", MinimumVer);
		}

		private static void OnPlayerModsSynced(SNet_Player player, IEnumerable<pModInfo> mods)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (player.IsMaster)
			{
				IsMasterHasAcc = CoreAPI.IsPlayerInstalledMod(player, "Hikaria.AccuracyTracker", MinimumVer);
			}
		}

		private static void ReceiveAccuracyData(ulong senderID, pAccuracyData data)
		{
			SNet_Player val = default(SNet_Player);
			if ((Object)(object)AccuracyUpdater.Instance != (Object)null && ((pPlayer)(ref data.Owner)).TryGetPlayer(ref val) && !val.IsLocal)
			{
				AccuracyUpdater.Instance.UpdateAccuracyData(data);
			}
		}

		internal static void SendAccuracyData(AccuracyUpdater.AccuracyData data)
		{
			s_AccuracyDataBroadcastAction.Do(data.GetAccuracyData());
		}

		private static void OnMasterChanged()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			IsMasterHasAcc = CoreAPI.IsPlayerInstalledMod(SNet.Master, "Hikaria.AccuracyTracker", MinimumVer);
		}

		public static bool IsAccuracyListener(ulong lookup)
		{
			return ((SNetExt_SyncedAction<pAccuracyData>)(object)s_AccuracyDataBroadcastAction).IsListener(lookup);
		}
	}
}
namespace Hikaria.AccuracyTracker.Handlers
{
	public class AccuracyUpdater : MonoBehaviour, IOnMasterChanged
	{
		public class AccuracyData
		{
			internal class AccuracySlotData
			{
				public uint m_Hitted;

				public uint m_Shotted;

				public uint m_WeakspotHitted;

				public InventorySlot m_Slot;

				public AccuracySlotData(InventorySlot slot)
				{
					//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)
					m_Slot = slot;
				}

				internal void Set(AccuracyManager.pAccuracySlotData data)
				{
					//IL_002a: Unknown result type (might be due to invalid IL or missing references)
					//IL_002f: Unknown result type (might be due to invalid IL or missing references)
					m_Hitted = data.Hitted;
					m_Shotted = data.Shotted;
					m_WeakspotHitted = data.WeakspotHitted;
					m_Slot = data.Slot;
				}

				public void DoClear()
				{
					m_Hitted = 0u;
					m_Shotted = 0u;
					m_WeakspotHitted = 0u;
				}
			}

			internal bool NeedUpdate = true;

			private Dictionary<InventorySlot, AccuracySlotData> AccuracySlotDataLookup = new Dictionary<InventorySlot, AccuracySlotData>();

			public SNet_Player Owner { get; private set; }

			public uint TotalHitted
			{
				get
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: 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)
					uint num = 0u;
					foreach (InventorySlot key in AccuracySlotDataLookup.Keys)
					{
						num += AccuracySlotDataLookup[key].m_Hitted;
					}
					return num;
				}
			}

			public uint TotalWeakspotHitted
			{
				get
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: 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)
					uint num = 0u;
					foreach (InventorySlot key in AccuracySlotDataLookup.Keys)
					{
						num += AccuracySlotDataLookup[key].m_WeakspotHitted;
					}
					return num;
				}
			}

			public uint TotalShotted
			{
				get
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_001c: 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)
					uint num = 0u;
					foreach (InventorySlot key in AccuracySlotDataLookup.Keys)
					{
						num += AccuracySlotDataLookup[key].m_Shotted;
					}
					return num;
				}
			}

			internal AccuracyData(SNet_Player player)
			{
				Owner = player;
				AccuracySlotDataLookup[(InventorySlot)1] = new AccuracySlotData((InventorySlot)1);
				AccuracySlotDataLookup[(InventorySlot)2] = new AccuracySlotData((InventorySlot)2);
			}

			internal void Set(AccuracyManager.pAccuracyData data)
			{
				SNet_Player owner = default(SNet_Player);
				if (((pPlayer)(ref data.Owner)).TryGetPlayer(ref owner))
				{
					Owner = owner;
				}
				AccuracySlotDataLookup[(InventorySlot)1].Set(data.StandardSlotData);
				AccuracySlotDataLookup[(InventorySlot)2].Set(data.SpecialSlotData);
			}

			internal void AddShotted(InventorySlot slot, uint count)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				if (AccuracySlotDataLookup.TryGetValue(slot, out var value))
				{
					value.m_Shotted += count;
				}
			}

			internal void AddHitted(InventorySlot slot, uint count)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				if (AccuracySlotDataLookup.TryGetValue(slot, out var value))
				{
					value.m_Hitted += count;
				}
			}

			internal void AddWeakspotHitted(InventorySlot slot, uint count)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				if (AccuracySlotDataLookup.TryGetValue(slot, out var value))
				{
					value.m_WeakspotHitted += count;
				}
			}

			internal void DoClear()
			{
				foreach (AccuracySlotData value in AccuracySlotDataLookup.Values)
				{
					value.DoClear();
				}
			}

			public string GetAccuracyText()
			{
				//IL_0039: 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_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_033c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_0213: Unknown result type (might be due to invalid IL or missing references)
				//IL_0239: Unknown result type (might be due to invalid IL or missing references)
				//IL_025f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0285: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_041f: Unknown result type (might be due to invalid IL or missing references)
				//IL_047f: Unknown result type (might be due to invalid IL or missing references)
				//IL_04df: Unknown result type (might be due to invalid IL or missing references)
				if (!Owner.HasCharacterSlot)
				{
					string result = string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatInGame, "-", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.ShottedColor) + ">0</color>");
					if (!Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.EnableColorInGame)
					{
						return string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatInGame, "*-", "-%", "-%", 0, 0, 0);
					}
					return result;
				}
				string text = ((AccuracyManager.IsAccuracyListener(Owner.Lookup) || (AccuracyManager.IsMasterHasAcc && Owner.IsBot) || Owner.IsLocal) ? "" : "*");
				string text2 = (UseGenericName ? CharacterNamesLookup[Owner.CharacterIndex].Name : Owner.NickName.RemoveHtmlTags());
				if (TotalShotted == 0)
				{
					string result2 = text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatInGame, text2, "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.ShottedColor) + ">0</color>");
					if (!Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.EnableColorInGame)
					{
						return text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatInGame, text2, "-%", "-%", 0, 0, 0);
					}
					return result2;
				}
				string result3 = text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatInGame, text2, $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedRatioColor)}>{100 * TotalHitted / TotalShotted}%</color>", (TotalHitted == 0) ? "-" : $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedRatioColor)}>{100 * TotalWeakspotHitted / TotalHitted}%</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedColor)}>{TotalWeakspotHitted}</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedColor)}>{TotalHitted}</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.ShottedColor)}>{TotalShotted}</color>");
				if (!Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.EnableColorInGame)
				{
					return text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatInGame, text2, $"{100 * TotalHitted / TotalShotted}%", (TotalHitted == 0) ? "-" : $"{100 * TotalWeakspotHitted / TotalHitted}%", $"{TotalWeakspotHitted}", $"{TotalHitted}", $"{TotalShotted}");
				}
				return result3;
			}

			public string GetAccuracyText(InventorySlot slot)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: 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_00d9: 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_02a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_031a: Unknown result type (might be due to invalid IL or missing references)
				//IL_038b: Unknown result type (might be due to invalid IL or missing references)
				//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_044b: Unknown result type (might be due to invalid IL or missing references)
				if (!Owner.HasCharacterSlot || !AccuracySlotDataLookup.TryGetValue(slot, out var value))
				{
					return string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatOnEndScreen, "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.ShottedColor) + ">0</color>");
				}
				string text = ((AccuracyManager.IsAccuracyListener(Owner.Lookup) || (AccuracyManager.IsMasterHasAcc && Owner.IsBot) || Owner.IsLocal) ? "" : "*");
				if (value.m_Shotted == 0)
				{
					string result = text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatOnEndScreen, "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedRatioColor) + ">-%</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedColor) + ">0</color>", "<" + SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.ShottedColor) + ">0</color>");
					if (!Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.EnableColorOnEndScreen)
					{
						return text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatOnEndScreen, "-%", "-%", 0, 0, 0);
					}
					return result;
				}
				string result2 = text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatOnEndScreen, $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedRatioColor)}>{100 * value.m_Hitted / value.m_Shotted}%</color>", (value.m_Hitted == 0) ? "-" : $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedRatioColor)}>{100 * value.m_WeakspotHitted / value.m_Hitted}%</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.WeakspotHittedColor)}>{value.m_WeakspotHitted}</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.HittedColor)}>{value.m_Hitted}</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.ShottedColor)}>{value.m_Shotted}</color>");
				if (!Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.FontColors.EnableColorOnEndScreen)
				{
					return text + string.Format(Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.DisplayFormatOnEndScreen, $"{100 * value.m_Hitted / value.m_Shotted}%", (value.m_Hitted == 0) ? "-" : $"{100 * value.m_WeakspotHitted / value.m_Hitted}%", value.m_WeakspotHitted, value.m_Hitted, value.m_Shotted);
				}
				return result2;
			}

			public AccuracyManager.pAccuracyData GetAccuracyData()
			{
				return new AccuracyManager.pAccuracyData(Owner, AccuracySlotDataLookup);
			}
		}

		private static int _offsetX = 0;

		private static int _offsetY = 0;

		private static bool _enable = true;

		private static bool _showOthersAcc = true;

		private static bool _showBotsAcc = false;

		private static string _showFormat = "{0}: {1}/{2}({4}/{5})";

		private static string _pageExpeditionSuccessShowFormat = "{0}/{1}({2}/{3}/{4})";

		private static bool _useGenericName = true;

		private static bool _isSetup;

		private static Dictionary<int, TextMeshPro> AccuracyTextMeshes = new Dictionary<int, TextMeshPro>();

		private static Dictionary<int, bool> AccuracyTextMeshesVisible = new Dictionary<int, bool>();

		private static Dictionary<ulong, int> AccuracyRegisteredCharacterIndex = new Dictionary<ulong, int>();

		internal static Dictionary<ulong, uint> ShotsBuffer = new Dictionary<ulong, uint>();

		public static AccuracyUpdater Instance { get; private set; }

		public static int OffsetX
		{
			get
			{
				return _offsetX;
			}
			set
			{
				_offsetX = value;
				if (IsSetup)
				{
					UpdateVisible();
				}
			}
		}

		public static int OffsetY
		{
			get
			{
				return _offsetY;
			}
			set
			{
				_offsetY = value;
				if (IsSetup)
				{
					UpdateVisible();
				}
			}
		}

		public static bool Enabled
		{
			get
			{
				return _enable;
			}
			internal set
			{
				if (IsSetup)
				{
					MarkAllAccuracyDataNeedUpdate();
				}
				_enable = value;
			}
		}

		public static bool ShowOtherPlayersAcc
		{
			get
			{
				return _showOthersAcc;
			}
			internal set
			{
				if (IsSetup)
				{
					MarkAllAccuracyDataNeedUpdate();
				}
				_showOthersAcc = value;
			}
		}

		public static bool ShowBotsAcc
		{
			get
			{
				return _showBotsAcc;
			}
			internal set
			{
				if (IsSetup)
				{
					MarkAllAccuracyDataNeedUpdate();
				}
				_showBotsAcc = value;
			}
		}

		public static string ShowFormat
		{
			get
			{
				return _showFormat;
			}
			set
			{
				if (IsSetup)
				{
					MarkAllAccuracyDataNeedUpdate();
				}
				_showFormat = value;
			}
		}

		public static string PageExpeditionSuccessShowFormat
		{
			get
			{
				return _pageExpeditionSuccessShowFormat;
			}
			set
			{
				if (IsSetup)
				{
					MarkAllAccuracyDataNeedUpdate();
				}
				_pageExpeditionSuccessShowFormat = value;
			}
		}

		public static bool UseGenericName
		{
			get
			{
				return _useGenericName;
			}
			set
			{
				if (IsSetup)
				{
					MarkAllAccuracyDataNeedUpdate();
				}
				_useGenericName = value;
			}
		}

		public static Dictionary<int, Hikaria.AccuracyTracker.Features.AccuracyTracker.PlayerNameEntry> CharacterNamesLookup { get; set; } = new Dictionary<int, Hikaria.AccuracyTracker.Features.AccuracyTracker.PlayerNameEntry>
		{
			{
				0,
				new Hikaria.AccuracyTracker.Features.AccuracyTracker.PlayerNameEntry("Wood", "RED")
			},
			{
				1,
				new Hikaria.AccuracyTracker.Features.AccuracyTracker.PlayerNameEntry("Dauda", "GRE")
			},
			{
				2,
				new Hikaria.AccuracyTracker.Features.AccuracyTracker.PlayerNameEntry("Hackett", "BLU")
			},
			{
				3,
				new Hikaria.AccuracyTracker.Features.AccuracyTracker.PlayerNameEntry("Bishop", "PUR")
			}
		};


		public static bool IsSetup
		{
			get
			{
				return _isSetup;
			}
			private set
			{
				_isSetup = value;
			}
		}

		private void Awake()
		{
			Instance = this;
			Setup();
			GameEventAPI.RegisterSelf<AccuracyUpdater>(this);
			MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, UpdateAccuracyDataCoroutine());
		}

		private void OnDestroy()
		{
			GameEventAPI.UnregisterSelf<AccuracyUpdater>(this);
		}

		private void Setup()
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			if (IsSetup)
			{
				return;
			}
			AccuracyTextMeshesVisible[0] = false;
			AccuracyTextMeshesVisible[1] = false;
			AccuracyTextMeshesVisible[2] = false;
			AccuracyTextMeshesVisible[3] = false;
			PUI_Inventory inventory = GuiManager.Current.m_playerLayer.Inventory;
			foreach (RectTransform componentsInChild in ((Component)inventory.m_iconDisplay).GetComponentsInChildren<RectTransform>(true))
			{
				if (!(((Object)componentsInChild).name == "Background Fade"))
				{
					continue;
				}
				TextMeshPro slim_archetypeName = inventory.m_inventorySlots[(InventorySlot)10].m_slim_archetypeName;
				for (int i = 0; i < 4; i++)
				{
					GameObject val = Object.Instantiate<GameObject>(((Component)componentsInChild).gameObject, ((Transform)componentsInChild).parent);
					RectTransform component = val.GetComponent<RectTransform>();
					val.gameObject.SetActive(true);
					foreach (Transform componentsInChild2 in val.GetComponentsInChildren<Transform>(true))
					{
						if (((Object)componentsInChild2).name == "TimerShowObject")
						{
							((Component)componentsInChild2).gameObject.active = false;
						}
					}
					val.transform.localPosition = new Vector3(-70f + (float)OffsetX, (float)(-62 + OffsetY + -35 * i), 0f);
					AccuracyTextMeshes[i] = Object.Instantiate<TextMeshPro>(slim_archetypeName);
					GameObject val2 = new GameObject($"AccuracyTracker{i}")
					{
						layer = 5,
						hideFlags = (HideFlags)61
					};
					val2.transform.SetParent(((Component)component).transform, false);
					TextMeshPro obj = AccuracyTextMeshes[i];
					((TMP_Text)obj).m_width = ((TMP_Text)obj).m_width * 2f;
					AccuracyTextMeshes[i].transform.SetParent(val2.transform, false);
					((Component)AccuracyTextMeshes[i]).GetComponent<RectTransform>().anchoredPosition = new Vector2(-5f, 9f);
					((TMP_Text)AccuracyTextMeshes[i]).SetText("-: -%/-%(0/0)", true);
					((TMP_Text)AccuracyTextMeshes[i]).ForceMeshUpdate(false, false);
				}
				break;
			}
			MarkAllAccuracyDataNeedUpdate();
			IsSetup = true;
		}

		public void OnMasterChanged()
		{
			CheckAndSetVisible();
		}

		internal static void CheckAndSetVisible()
		{
			if (!SNet.IsMaster)
			{
				foreach (ulong item in AccuracyManager.AccuracyDataLookup.Keys.ToList())
				{
					if (!AccuracyManager.IsAccuracyListener(item) && AccuracyRegisteredCharacterIndex.TryGetValue(item, out var value))
					{
						SetVisible(value, visible: false, update: false);
					}
				}
			}
			else
			{
				foreach (KeyValuePair<ulong, int> item2 in AccuracyRegisteredCharacterIndex)
				{
					SetVisible(item2.Value, visible: true, update: false);
				}
			}
			UpdateVisible();
		}

		internal static void RegisterPlayer(SNet_Player player)
		{
			if (player.CharacterSlot != null)
			{
				AccuracyRegisteredCharacterIndex[player.Lookup] = player.CharacterSlot.index;
				AccuracyManager.AccuracyDataLookup[player.Lookup] = new AccuracyData(player);
				AccuracyManager.AccuracyDataLookup[player.Lookup].NeedUpdate = true;
			}
		}

		internal static void UnregisterPlayer(SNet_Player player)
		{
			if (player.IsLocal)
			{
				UnregisterAllPlayers();
			}
			else
			{
				UnregisterPlayer(player.Lookup);
			}
		}

		private IEnumerator UpdateAccuracyDataCoroutine()
		{
			WaitForSecondsRealtime yielder = new WaitForSecondsRealtime(3f);
			while (true)
			{
				foreach (AccuracyData value2 in AccuracyManager.AccuracyDataLookup.Values)
				{
					SNet_Player owner = value2.Owner;
					if (!value2.NeedUpdate || !AccuracyRegisteredCharacterIndex.TryGetValue(owner.Lookup, out var value))
					{
						continue;
					}
					UpdateAccuracyTextMesh(value, value2.GetAccuracyText());
					value2.NeedUpdate = false;
					if ((SNet.IsMaster && (owner.IsBot || !AccuracyManager.IsAccuracyListener(owner.Lookup))) || owner.IsLocal)
					{
						AccuracyManager.SendAccuracyData(value2);
					}
					if (NeedShowAccuracy(owner))
					{
						if (!AccuracyTextMeshesVisible[value])
						{
							SetVisible(value, visible: true);
						}
					}
					else if (AccuracyTextMeshesVisible[value])
					{
						SetVisible(value, visible: false);
					}
				}
				yield return yielder;
			}
		}

		internal void UpdateAccuracyData(AccuracyManager.pAccuracyData data)
		{
			SNet_Player val = default(SNet_Player);
			if (((pPlayer)(ref data.Owner)).TryGetPlayer(ref val) && AccuracyManager.AccuracyDataLookup.TryGetValue(val.Lookup, out var value))
			{
				value.Set(data);
				value.NeedUpdate = true;
			}
		}

		private void UpdateAccuracyTextMesh(int index, string text)
		{
			if (AccuracyTextMeshes.TryGetValue(index, out var value))
			{
				((TMP_Text)value).SetText(text, true);
				((TMP_Text)value).ForceMeshUpdate(false, false);
			}
		}

		internal static void MarkAllAccuracyDataNeedUpdate()
		{
			foreach (AccuracyData value in AccuracyManager.AccuracyDataLookup.Values)
			{
				value.NeedUpdate = true;
			}
		}

		internal static void MarkAccuracyDataNeedUpdate(ulong lookup)
		{
			AccuracyManager.AccuracyDataLookup[lookup].NeedUpdate = true;
		}

		internal static void SetVisible(int index, bool visible, bool update = true)
		{
			AccuracyTextMeshesVisible[index] = Enabled && visible;
			if (update)
			{
				UpdateVisible();
			}
		}

		private static void UpdateVisible()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 4; i++)
			{
				if (!AccuracyTextMeshesVisible.ContainsKey(i))
				{
					continue;
				}
				int num = 0;
				for (int j = 0; j < 4; j++)
				{
					if (j <= i && !AccuracyTextMeshesVisible[j])
					{
						num++;
					}
				}
				if (AccuracyTextMeshesVisible[i])
				{
					((Component)AccuracyTextMeshes[i].transform.parent.parent).gameObject.SetActive(true);
					((Component)AccuracyTextMeshes[i].transform.parent.parent).transform.localPosition = new Vector3(-70f + (float)OffsetX, -62f + (float)OffsetY + -35f * (float)(i - num), 0f);
				}
				else
				{
					((Component)AccuracyTextMeshes[i].transform.parent.parent).gameObject.SetActive(false);
				}
			}
		}

		internal static void UnregisterAllPlayers()
		{
			foreach (ulong key in AccuracyRegisteredCharacterIndex.Keys)
			{
				UnregisterPlayer(key);
			}
			UpdateVisible();
		}

		internal static void UnregisterPlayer(ulong lookup)
		{
			if (AccuracyRegisteredCharacterIndex.TryGetValue(lookup, out var value))
			{
				SetVisible(value, visible: false);
			}
			AccuracyManager.AccuracyDataLookup.Remove(lookup);
			AccuracyRegisteredCharacterIndex.Remove(lookup);
			ShotsBuffer.Remove(lookup);
		}

		internal static void AddHitted(ulong lookup, InventorySlot slot, uint count)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (AccuracyManager.AccuracyDataLookup.TryGetValue(lookup, out var value))
			{
				value.AddHitted(slot, count);
			}
		}

		internal static void AddShotted(ulong lookup, InventorySlot slot, uint count)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (AccuracyManager.AccuracyDataLookup.TryGetValue(lookup, out var value))
			{
				value.AddShotted(slot, count);
			}
		}

		internal static void AddWeakspotHitted(ulong lookup, InventorySlot slot, uint count)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (AccuracyManager.AccuracyDataLookup.TryGetValue(lookup, out var value))
			{
				value.AddWeakspotHitted(slot, count);
			}
		}

		public static bool TryGetPlayerAccuracyData(SNet_Player player, out AccuracyData data)
		{
			return AccuracyManager.AccuracyDataLookup.TryGetValue(player.Lookup, out data);
		}

		private static bool NeedShowAccuracy(SNet_Player player)
		{
			if (!Hikaria.AccuracyTracker.Features.AccuracyTracker.Settings.Enabled || (!player.IsLocal && !ShowOtherPlayersAcc) || (player.IsBot && !ShowBotsAcc))
			{
				return false;
			}
			if (!AccuracyManager.IsAccuracyListener(player.Lookup) && !player.IsLocal && (!player.IsBot || !AccuracyManager.IsMasterHasAcc))
			{
				return AccuracyManager.IsMasterHasAcc;
			}
			return true;
		}
	}
}
namespace Hikaria.AccuracyTracker.Features
{
	[EnableFeatureByDefault]
	[DisallowInGameToggle]
	public class AccuracyTracker : Feature
	{
		public class AccuracyTrackerSettings
		{
			[FSDisplayName("启用")]
			public bool Enabled
			{
				get
				{
					return AccuracyUpdater.Enabled;
				}
				set
				{
					AccuracyUpdater.Enabled = value;
				}
			}

			[FSDisplayName("在结算界面显示")]
			public bool DisplayOnEndScreen { get; set; } = true;


			[FSDisplayName("显示其他玩家的命中率")]
			public bool ShowOtherPlayersAcc
			{
				get
				{
					return AccuracyUpdater.ShowOtherPlayersAcc;
				}
				set
				{
					AccuracyUpdater.ShowOtherPlayersAcc = value;
				}
			}

			[FSDisplayName("显示机器人玩家的命中率")]
			public bool ShowBotsAcc
			{
				get
				{
					return AccuracyUpdater.ShowBotsAcc;
				}
				set
				{
					AccuracyUpdater.ShowBotsAcc = value;
				}
			}

			[FSDisplayName("显示格式")]
			[FSDescription("{0}: 玩家名称, {1}: 命中率, {2}: 弱点命中率, {3}: 弱点命中次数, {4}: 命中次数, {5}: 弹丸击发次数")]
			public string DisplayFormatInGame
			{
				get
				{
					return AccuracyUpdater.ShowFormat;
				}
				set
				{
					AccuracyUpdater.ShowFormat = value;
				}
			}

			[FSDisplayName("结算界面显示格式")]
			[FSDescription("{0}: 命中率, {1}: 弱点命中率, {2}: 弱点命中次数, {3}: 命中次数, {4}: 弹丸击发次数")]
			public string DisplayFormatOnEndScreen
			{
				get
				{
					return AccuracyUpdater.PageExpeditionSuccessShowFormat;
				}
				set
				{
					AccuracyUpdater.PageExpeditionSuccessShowFormat = value;
				}
			}

			[FSHeader("玩家显示名称设置", true)]
			[FSDisplayName("使用通用玩家名称")]
			[FSDescription("若禁用则使用玩家名称")]
			public bool UseGenericName
			{
				get
				{
					return AccuracyUpdater.UseGenericName;
				}
				set
				{
					AccuracyUpdater.UseGenericName = value;
				}
			}

			[FSInline]
			[FSDisplayName("显示位置设置")]
			public PositionSettings Position { get; set; } = new PositionSettings();


			[FSInline]
			[FSDisplayName("显示颜色设置")]
			public ColorSettings FontColors { get; set; } = new ColorSettings();

		}

		public class PlayerNameEntry
		{
			private string _name;

			[FSSeparator]
			[FSDisplayName("人物")]
			[FSReadOnly(true)]
			public string Character { get; set; }

			[FSDisplayName("名称")]
			public string Name
			{
				get
				{
					return _name;
				}
				set
				{
					if (AccuracyUpdater.IsSetup)
					{
						AccuracyUpdater.MarkAllAccuracyDataNeedUpdate();
					}
					_name = value;
				}
			}

			public PlayerNameEntry(string character, string name)
			{
				Character = character;
				Name = name;
			}
		}

		public class PositionSettings
		{
			[FSHeader("显示位置设置", true)]
			[FSDisplayName("横向偏移量")]
			[FSDescription("单位: 像素")]
			public int OffsetX
			{
				get
				{
					return AccuracyUpdater.OffsetX;
				}
				set
				{
					AccuracyUpdater.OffsetX = value;
				}
			}

			[FSDisplayName("纵向偏移量")]
			[FSDescription("单位: 像素")]
			public int OffsetY
			{
				get
				{
					return AccuracyUpdater.OffsetY;
				}
				set
				{
					AccuracyUpdater.OffsetY = value;
				}
			}
		}

		public class ColorSettings
		{
			[FSHeader("显示颜色设置", true)]
			[FSDisplayName("在游戏内使用颜色")]
			public bool EnableColorInGame { get; set; } = true;


			[FSDisplayName("在结算界面使用颜色")]
			public bool EnableColorOnEndScreen { get; set; }

			[FSDisplayName("命中率颜色")]
			public SColor HittedRatioColor { get; set; } = new SColor(0.7206f, 0.7206f, 0.7206f, (float?)0.3137f);


			[FSDisplayName("命中次数颜色")]
			public SColor HittedColor { get; set; } = new SColor(0.7206f, 0.7206f, 0.7206f, (float?)0.3137f);


			[FSDisplayName("弱点命中率颜色")]
			public SColor WeakspotHittedRatioColor { get; set; } = new SColor(0.7206f, 0.7206f, 0.7206f, (float?)0.3137f);


			[FSDisplayName("弱点命中次数颜色")]
			public SColor WeakspotHittedColor { get; set; } = new SColor(0.7206f, 0.7206f, 0.7206f, (float?)0.3137f);


			[FSDisplayName("弹丸击发次数颜色")]
			public SColor ShottedColor { get; set; } = new SColor(0.7206f, 0.7206f, 0.7206f, (float?)0.3137f);

		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		public class CM_PageRundown_New__Setup__Postfix
		{
			private static void Postfix()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Expected O, but got Unknown
				if (!IsSetup)
				{
					GameObject val = new GameObject("AccurayTracker");
					Object.DontDestroyOnLoad((Object)(object)val);
					if ((Object)(object)val.GetComponent<AccuracyUpdater>() == (Object)null)
					{
						val.AddComponent<AccuracyUpdater>();
					}
					IsSetup = true;
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class CM_PageExpeditionSuccess__TryGetArchetypeName__Patch
		{
			private static void Postfix(PlayerBackpack backpack, InventorySlot slot, ref string name)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				if (((int)slot == 1 || (int)slot == 2) && Settings.DisplayOnEndScreen && AccuracyUpdater.TryGetPlayerAccuracyData(backpack.Owner, out var data))
				{
					name = name + " | " + data.GetAccuracyText(slot);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__FireBullet__Patch
		{
			private static void Prefix()
			{
				IsSentryGunFire = true;
			}

			private static void Postfix()
			{
				IsSentryGunFire = false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__UpdateFireShotgunSemi__Patch
		{
			private static void Prefix()
			{
				IsSentryGunFire = true;
			}

			private static void Postfix()
			{
				IsSentryGunFire = false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PlayerInventorySynced__GetSync__Patch
		{
			private static void Prefix(PlayerInventorySynced __instance)
			{
				//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_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Invalid comparison between Unknown and I4
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Invalid comparison between Unknown and I4
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Invalid comparison between Unknown and I4
				if ((Object)(object)((PlayerInventoryBase)__instance).Owner == (Object)null)
				{
					return;
				}
				SNet_Player owner = ((PlayerInventoryBase)__instance).Owner.Owner;
				if (!SNet.IsMaster || owner.IsBot || owner.IsLocal)
				{
					return;
				}
				ulong lookup = owner.Lookup;
				if (AccuracyManager.IsAccuracyListener(lookup))
				{
					return;
				}
				InventorySlot wieldedSlot = ((PlayerInventoryBase)__instance).Owner.Inventory.WieldedSlot;
				if ((int)wieldedSlot == 3)
				{
					return;
				}
				uint num = (uint)((PlayerInventoryBase)__instance).Owner.Sync.FireCountSync;
				if (AccuracyUpdater.ShotsBuffer.TryGetValue(lookup, out var value))
				{
					num += value;
					AccuracyUpdater.ShotsBuffer[lookup] = 0u;
				}
				if ((Object)(object)((PlayerInventoryBase)__instance).WieldedItem != (Object)null)
				{
					if ((int)wieldedSlot != 1 && (int)wieldedSlot != 2)
					{
						AccuracyUpdater.ShotsBuffer[lookup] = num;
						return;
					}
					BulletWeaponSynced val = ((Il2CppObjectBase)((PlayerInventoryBase)__instance).WieldedItem).TryCast<BulletWeaponSynced>();
					if ((Object)(object)val != (Object)null)
					{
						ShotgunSynced val2 = ((Il2CppObjectBase)val).TryCast<ShotgunSynced>();
						if ((Object)(object)val2 != (Object)null && ((ItemEquippable)val2).ArchetypeData != null)
						{
							num *= (uint)((ItemEquippable)val2).ArchetypeData.ShotgunBulletCount;
						}
					}
				}
				AccuracyUpdater.AddShotted(lookup, wieldedSlot, num);
				AccuracyUpdater.MarkAccuracyDataNeedUpdate(lookup);
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_EnemyDamageBase__ReceiveBulletDamage__Patch
		{
			private static void Postfix(Dam_EnemyDamageBase __instance, pBulletDamageData data)
			{
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Invalid comparison between Unknown and I4
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Invalid comparison between Unknown and I4
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Invalid comparison between Unknown and I4
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				Agent val = default(Agent);
				if (IsSentryGunFire || !((pAgent)(ref data.source)).TryGet(ref val))
				{
					return;
				}
				PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				SNet_Player owner = val2.Owner;
				ulong lookup = owner.Lookup;
				if (AccuracyManager.IsAccuracyListener(lookup) || owner.IsLocal || owner.IsBot)
				{
					return;
				}
				InventorySlot wieldedSlot = val2.Inventory.WieldedSlot;
				if ((int)wieldedSlot != 1 && (int)wieldedSlot != 2)
				{
					Logs.LogError("Not wielding BulletWeapon but ReceiveBulletDamage?");
					return;
				}
				if (data.limbID >= 0 && (int)((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)__instance.DamageLimbs)[(int)data.limbID].m_type == 1)
				{
					AccuracyUpdater.AddWeakspotHitted(lookup, wieldedSlot, 1u);
				}
				AccuracyUpdater.AddHitted(lookup, wieldedSlot, 1u);
				AccuracyUpdater.MarkAccuracyDataNeedUpdate(lookup);
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeaponSynced__Fire__Patch
		{
			private static void Prefix(BulletWeaponSynced __instance)
			{
				if (((Item)__instance).Owner.Owner.IsBot && SNet.IsMaster)
				{
					CanCalc = true;
					IsInWeaponFire = true;
					IsPiercingBullet = false;
					BulletPiercingLimit = 0u;
					BulletsPerFire = 1u;
					ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
					if (archetypeData != null)
					{
						IsPiercingBullet = archetypeData.PiercingBullets;
						BulletPiercingLimit = (archetypeData.PiercingBullets ? ((uint)(archetypeData.PiercingDamageCountLimit - 1)) : 0u);
					}
				}
			}

			private static void Postfix(BulletWeaponSynced __instance)
			{
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				if (!((Item)__instance).Owner.Owner.IsBot || !SNet.IsMaster)
				{
					return;
				}
				CanCalc = false;
				IsInWeaponFire = false;
				ulong lookup = ((Item)__instance).Owner.Owner.Lookup;
				uint num = 0u;
				uint num2 = 0u;
				foreach (BulletHitData value in BulletHitDataLookup.Values)
				{
					if (value.IsHit)
					{
						num++;
					}
					if (value.IsWeakspotHit)
					{
						num2++;
					}
				}
				AccuracyUpdater.AddShotted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, BulletsPerFire);
				AccuracyUpdater.AddHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num);
				AccuracyUpdater.AddWeakspotHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num2);
				AccuracyUpdater.MarkAccuracyDataNeedUpdate(lookup);
				CurrentBulletIndex = 0u;
				BulletHitDataLookup.Clear();
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class ShotgunSynced__Fire__Patch
		{
			private static void Prefix(ShotgunSynced __instance)
			{
				if (((Item)__instance).Owner.Owner.IsBot && SNet.IsMaster)
				{
					CanCalc = true;
					IsInWeaponFire = true;
					IsPiercingBullet = false;
					BulletPiercingLimit = 0u;
					BulletsPerFire = 1u;
					ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
					if (archetypeData != null)
					{
						IsPiercingBullet = archetypeData.PiercingBullets;
						BulletPiercingLimit = (archetypeData.PiercingBullets ? ((uint)(archetypeData.PiercingDamageCountLimit - 1)) : 0u);
						BulletsPerFire = (uint)archetypeData.ShotgunBulletCount;
					}
				}
			}

			private static void Postfix(ShotgunSynced __instance)
			{
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				if (!((Item)__instance).Owner.Owner.IsBot || !SNet.IsMaster)
				{
					return;
				}
				CanCalc = false;
				IsInWeaponFire = false;
				ulong lookup = ((Item)__instance).Owner.Owner.Lookup;
				uint num = 0u;
				uint num2 = 0u;
				foreach (BulletHitData value in BulletHitDataLookup.Values)
				{
					if (value.IsHit)
					{
						num++;
					}
					if (value.IsWeakspotHit)
					{
						num2++;
					}
				}
				AccuracyUpdater.AddShotted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, BulletsPerFire);
				AccuracyUpdater.AddHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num);
				AccuracyUpdater.AddWeakspotHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num2);
				AccuracyUpdater.MarkAccuracyDataNeedUpdate(lookup);
				CurrentBulletIndex = 0u;
				BulletHitDataLookup.Clear();
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__Fire__Patch
		{
			private static void Prefix(BulletWeapon __instance)
			{
				if (IsWeaponOwner(__instance))
				{
					CanCalc = true;
					IsInWeaponFire = true;
					IsPiercingBullet = false;
					BulletPiercingLimit = 0u;
					BulletsPerFire = 1u;
					ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
					if (archetypeData != null)
					{
						IsPiercingBullet = archetypeData.PiercingBullets;
						BulletPiercingLimit = (archetypeData.PiercingBullets ? ((uint)(archetypeData.PiercingDamageCountLimit - 1)) : 0u);
					}
				}
			}

			private static void Postfix(BulletWeapon __instance)
			{
				//IL_007a: 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)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				if (!IsWeaponOwner(__instance))
				{
					return;
				}
				CanCalc = false;
				IsInWeaponFire = false;
				ulong lookup = ((Item)__instance).Owner.Owner.Lookup;
				uint num = 0u;
				uint num2 = 0u;
				foreach (BulletHitData value in BulletHitDataLookup.Values)
				{
					if (value.IsHit)
					{
						num++;
					}
					if (value.IsWeakspotHit)
					{
						num2++;
					}
				}
				AccuracyUpdater.AddShotted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, BulletsPerFire);
				AccuracyUpdater.AddHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num);
				AccuracyUpdater.AddWeakspotHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num2);
				AccuracyUpdater.MarkAccuracyDataNeedUpdate(lookup);
				CurrentBulletIndex = 0u;
				BulletHitDataLookup.Clear();
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Shotgun__Fire__Patch
		{
			private static void Prefix(Shotgun __instance)
			{
				if (IsWeaponOwner((BulletWeapon)(object)__instance))
				{
					CanCalc = true;
					IsInWeaponFire = true;
					IsPiercingBullet = false;
					BulletPiercingLimit = 0u;
					BulletsPerFire = 1u;
					ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
					if (archetypeData != null)
					{
						IsPiercingBullet = archetypeData.PiercingBullets;
						BulletPiercingLimit = (archetypeData.PiercingBullets ? ((uint)(archetypeData.PiercingDamageCountLimit - 1)) : 0u);
						BulletsPerFire = (uint)archetypeData.ShotgunBulletCount;
					}
					IsShotgunFireShots = true;
				}
			}

			private static void Postfix(Shotgun __instance)
			{
				//IL_007a: 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)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				if (!IsWeaponOwner((BulletWeapon)(object)__instance))
				{
					return;
				}
				CanCalc = false;
				IsInWeaponFire = false;
				ulong lookup = ((Item)__instance).Owner.Owner.Lookup;
				uint num = 0u;
				uint num2 = 0u;
				foreach (BulletHitData value in BulletHitDataLookup.Values)
				{
					if (value.IsHit)
					{
						num++;
					}
					if (value.IsWeakspotHit)
					{
						num2++;
					}
				}
				AccuracyUpdater.AddShotted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, BulletsPerFire);
				AccuracyUpdater.AddHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num);
				AccuracyUpdater.AddWeakspotHitted(lookup, ((Item)__instance).ItemDataBlock.inventorySlot, num2);
				AccuracyUpdater.MarkAccuracyDataNeedUpdate(lookup);
				IsShotgunFireShots = false;
				CurrentBulletIndex = 0u;
				BulletHitDataLookup.Clear();
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_EnemyDamageLimb__BulletDamage__Patch
		{
			private static void Postfix(Dam_EnemyDamageLimb __instance, Agent sourceAgent)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Invalid comparison between Unknown and I4
				if (IsInWeaponFire && !IsSentryGunFire && CanCalc && !((Object)(object)sourceAgent == (Object)null) && CurrentBulletHitData != null)
				{
					PlayerAgent obj = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
					if (obj != null && ((Agent)obj).IsLocallyOwned && (int)__instance.m_type == 1 && !CurrentBulletHitData.IsWeakspotHit)
					{
						CurrentBulletHitData.IsWeakspotHit = true;
					}
				}
			}
		}

		private class BulletHitData
		{
			public uint Index;

			public uint BulletHitCount;

			public bool IsHit;

			public bool IsWeakspotHit;

			public bool IsDead;
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Weapon__CastWeaponRay__Patch
		{
			public static Type[] ParameterTypes()
			{
				return new Type[4]
				{
					typeof(Transform),
					typeof(WeaponHitData).MakeByRefType(),
					typeof(Vector3),
					typeof(int)
				};
			}

			private static void Postfix(ref WeaponHitData weaponRayData, bool __result)
			{
				if (IsInWeaponFire && !IsSentryGunFire && CanCalc)
				{
					if (!BulletHitDataLookup.TryGetValue(CurrentBulletIndex, out CurrentBulletHitData))
					{
						CurrentBulletHitData = new BulletHitData
						{
							Index = CurrentBulletIndex,
							BulletHitCount = 0u,
							IsHit = false,
							IsWeakspotHit = false,
							IsDead = !IsPiercingBullet
						};
						BulletHitDataLookup.Add(CurrentBulletIndex, CurrentBulletHitData);
					}
					if (!__result)
					{
						CurrentBulletHitData.IsDead = true;
						CurrentBulletIndex++;
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__BulletHit__Patch
		{
			private static void Postfix(bool __result)
			{
				//IL_0075: 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_008c: Unknown result type (might be due to invalid IL or missing references)
				if (!IsInWeaponFire || IsSentryGunFire || !CanCalc || CurrentBulletHitData == null)
				{
					return;
				}
				if (__result)
				{
					if (!CurrentBulletHitData.IsHit)
					{
						CurrentBulletHitData.IsHit = true;
					}
					if (IsPiercingBullet)
					{
						CurrentBulletHitData.BulletHitCount++;
					}
				}
				if (!IsPiercingBullet)
				{
					CurrentBulletHitData.IsDead = true;
					CurrentBulletIndex++;
					return;
				}
				RaycastHit rayHit = Weapon.s_weaponRayData.rayHit;
				if (!CustomExtensions.IsInLayerMask(((Component)((RaycastHit)(ref rayHit)).collider).gameObject, LayerMask.op_Implicit(LayerManager.MASK_BULLETWEAPON_PIERCING_PASS)) || CurrentBulletHitData.BulletHitCount >= BulletPiercingLimit + 1)
				{
					CurrentBulletHitData.IsDead = true;
					CurrentBulletIndex++;
				}
			}
		}

		private static uint BulletPiercingLimit;

		private static uint BulletsPerFire;

		private static bool IsPiercingBullet;

		private static bool IsInWeaponFire;

		private static bool CanCalc;

		private static bool IsShotgunFireShots;

		private static uint CurrentBulletIndex = 0u;

		private static BulletHitData CurrentBulletHitData;

		private static Dictionary<uint, BulletHitData> BulletHitDataLookup = new Dictionary<uint, BulletHitData>();

		public override string Name => "命中率指示器";

		public override bool InlineSettingsIntoParentMenu => true;

		[FeatureConfig]
		public static AccuracyTrackerSettings Settings { get; set; }

		public static bool IsSetup { get; private set; }

		public static bool IsSentryGunFire { get; private set; }

		public override void OnGameStateChanged(int state)
		{
			if (state == 5 || state == 11)
			{
				AccuracyManager.DoClear();
			}
		}

		public override void Init()
		{
			ClassInjector.RegisterTypeInIl2Cpp<AccuracyUpdater>(false);
			AccuracyManager.Setup();
		}

		private static bool IsWeaponOwner(BulletWeapon weapon)
		{
			bool? obj;
			if (weapon == null)
			{
				obj = null;
			}
			else
			{
				PlayerAgent owner = ((Item)weapon).Owner;
				obj = ((owner != null) ? new bool?(((Agent)owner).IsLocallyOwned) : null);
			}
			bool? flag = obj;
			return flag.GetValueOrDefault();
		}
	}
}
namespace Hikaria.AccuracyTracker.Extensions
{
	internal static class StringExts
	{
		public static string RemoveHtmlTags(this string htmlString)
		{
			string pattern = "<.*?>";
			return Regex.Replace(htmlString, pattern, string.Empty);
		}
	}
}