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.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils;
using GTFO.API;
using GameData;
using Gear;
using Hikaria.AccuracyShower.Extensions;
using Hikaria.AccuracyShower.Features;
using Hikaria.AccuracyShower.Handlers;
using Hikaria.AccuracyShower.Managers;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Player;
using SNetwork;
using TMPro;
using TheArchive;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
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: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Hikaria.AccuracyShower")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Hikaria.AccuracyShower")]
[assembly: AssemblyTitle("Hikaria.AccuracyShower")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Hikaria.AccuracyShower
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("Hikaria.AccuracyShower", "AccuracyShower", "1.0.1")]
public class EntryPoint : BasePlugin, IArchiveModule
{
public static EntryPoint Instance { get; private set; }
public bool ApplyHarmonyPatches => false;
public bool UsesLegacyPatches => false;
public ArchiveLegacyPatcher Patcher { get; set; }
public override void Load()
{
Instance = this;
ArchiveMod.RegisterArchiveModule(typeof(EntryPoint));
Logs.LogMessage("OK");
}
public void Init()
{
}
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.AccuracyShower", 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.AccuracyShower";
public const string NAME = "AccuracyShower";
public const string VERSION = "1.0.1";
}
}
namespace Hikaria.AccuracyShower.Managers
{
public static class AccuracyManager
{
[StructLayout(LayoutKind.Sequential, Size = 1)]
private struct pBroadcastListenAccuracyData
{
}
public struct pAccuracyData
{
public pPlayer m_player;
public uint m_Hitted;
public uint m_Shotted;
public uint m_WeakspotHitted;
public pAccuracyData(SNet_Player player, uint hitted, uint shotted, uint weakspotHitted)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
m_player = default(pPlayer);
((pPlayer)(ref m_player)).SetPlayer(player);
m_Hitted = hitted;
m_Shotted = shotted;
m_WeakspotHitted = weakspotHitted;
}
}
public static bool IsMasterHasAcc => AccuracyDataListeners.Any((KeyValuePair<ulong, SNet_Player> p) => p.Key == SNet.Master.Lookup);
private static Dictionary<ulong, SNet_Player> AccuracyDataListeners { get; set; } = new Dictionary<ulong, SNet_Player>();
private static Dictionary<ulong, SNet_Player> LobbyPlayers { get; set; } = new Dictionary<ulong, SNet_Player>();
internal static void Setup()
{
NetworkAPI.RegisterEvent<pAccuracyData>(typeof(pAccuracyData).FullName, (Action<ulong, pAccuracyData>)ReceiveAccuracyData);
NetworkAPI.RegisterEvent<pBroadcastListenAccuracyData>(typeof(pBroadcastListenAccuracyData).FullName, (Action<ulong, pBroadcastListenAccuracyData>)ReceiveBroadcastListenAccuracyData);
}
private static void ReceiveBroadcastListenAccuracyData(ulong senderID, pBroadcastListenAccuracyData data)
{
SNet_Player val = default(SNet_Player);
if (SNet.Core.TryGetPlayer(senderID, ref val, true))
{
AccuracyDataListeners.TryAdd(val.Lookup, val);
AccuracyUpdater.MarkAllAccuracyDataNeedUpdate();
}
}
private static void ReceiveAccuracyData(ulong senderID, pAccuracyData data)
{
SNet_Player val = default(SNet_Player);
if ((Object)(object)AccuracyUpdater.Instance != (Object)null && ((pPlayer)(ref data.m_player)).TryGetPlayer(ref val) && !val.IsLocal)
{
AccuracyUpdater.Instance.UpdateAccuracyData(data);
}
}
internal static void SendAccuracyData(AccuracyUpdater.AccuracyData data)
{
NetworkAPI.InvokeEvent<pAccuracyData>(typeof(pAccuracyData).FullName, data.GetAccuracyData(), AccuracyDataListeners.Values.ToList(), (SNet_ChannelType)4);
}
internal static void BroadcastAccuracyDataListener()
{
NetworkAPI.InvokeEvent<pBroadcastListenAccuracyData>(typeof(pBroadcastListenAccuracyData).FullName, default(pBroadcastListenAccuracyData), (SNet_ChannelType)4);
}
internal static void OnSessionMemberChanged(SNet_Player player, Hikaria.AccuracyShower.Features.AccuracyShower.SessionMemberEvent playerEvent)
{
switch (playerEvent)
{
case Hikaria.AccuracyShower.Features.AccuracyShower.SessionMemberEvent.JoinSessionHub:
LobbyPlayers.TryAdd(player.Lookup, player);
if (player.IsLocal)
{
AccuracyDataListeners.TryAdd(player.Lookup, player);
}
AccuracyUpdater.RegisterPlayer(player);
break;
case Hikaria.AccuracyShower.Features.AccuracyShower.SessionMemberEvent.LeftSessionHub:
LobbyPlayers.Remove(player.Lookup);
if (player.IsLocal)
{
AccuracyDataListeners.Clear();
AccuracyUpdater.UnregisterAllPlayers();
}
else
{
AccuracyDataListeners.Remove(player.Lookup);
AccuracyUpdater.UnregisterPlayer(player.Lookup);
}
break;
}
}
public static bool IsAccuracyListener(ulong lookup)
{
return AccuracyDataListeners.ContainsKey(lookup);
}
public static bool IsLobbyPlayer(ulong lookup)
{
return LobbyPlayers.ContainsKey(lookup);
}
}
}
namespace Hikaria.AccuracyShower.Handlers
{
public class AccuracyUpdater : MonoBehaviour
{
public class AccuracyData
{
internal SNet_Player m_Owner;
internal uint m_Hitted;
internal uint m_Shotted;
internal uint m_WeakspotHitted;
internal AccuracyData(SNet_Player player)
{
m_Owner = player;
m_Hitted = 0u;
m_Shotted = 0u;
m_WeakspotHitted = 0u;
}
internal void Set(AccuracyManager.pAccuracyData data)
{
SNet_Player owner = default(SNet_Player);
((pPlayer)(ref data.m_player)).TryGetPlayer(ref owner);
m_Owner = owner;
m_Hitted = data.m_Hitted;
m_Shotted = data.m_Shotted;
m_WeakspotHitted = data.m_WeakspotHitted;
}
internal void AddShotted(uint count)
{
m_Shotted += count;
}
internal void AddHitted(uint count)
{
m_Hitted += count;
}
internal void AddWeakspotHitted(uint count)
{
m_WeakspotHitted += count;
}
public SNet_Player GetOwner()
{
return m_Owner;
}
public uint GetHitted()
{
return m_Hitted;
}
public uint GetWeakspotHitted()
{
return m_WeakspotHitted;
}
public uint GetShotted()
{
return m_Shotted;
}
public string GetAccuracyText()
{
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_029d: Unknown result type (might be due to invalid IL or missing references)
//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
if (!m_Owner.HasCharacterSlot)
{
return string.Format(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.ShowFormat, "-", "-", "-", 0, 0, 0);
}
string text = ((AccuracyManager.IsAccuracyListener(m_Owner.Lookup) || (AccuracyManager.IsMasterHasAcc && m_Owner.IsBot) || m_Owner.IsLocal) ? "" : "*");
string text2 = (UseGenericName ? Hikaria.AccuracyShower.Features.AccuracyShower.Settings.CharacterNames[m_Owner.CharacterIndex].Name : m_Owner.NickName.RemoveHtmlTags());
if (m_Shotted == 0)
{
return text + string.Format(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.ShowFormat, text2, "-%", "-%", 0, 0, 0);
}
return text + string.Format(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.ShowFormat, text2, $"<{SColorExtensions.ToHexString(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.FontColors.HittedRatioColor)}>{100 * m_Hitted / m_Shotted}%</color>", (m_Hitted == 0) ? "-" : $"<{SColorExtensions.ToHexString(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.FontColors.WeakspotHittedRatioColor)}>{100 * m_WeakspotHitted / m_Hitted}%</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.FontColors.WeakspotHittedColor)}>{m_WeakspotHitted}>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.FontColors.HittedColor)}>{m_Hitted}</color>", $"<{SColorExtensions.ToHexString(Hikaria.AccuracyShower.Features.AccuracyShower.Settings.FontColors.ShottedColor)}>{m_Shotted}</color>");
}
public AccuracyManager.pAccuracyData GetAccuracyData()
{
return new AccuracyManager.pAccuracyData(m_Owner, m_Hitted, m_Shotted, m_WeakspotHitted);
}
}
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 bool _useGenericName = true;
private static bool _isSetup;
private static Dictionary<ulong, Coroutine> RegisterPlayerCoroutines = new Dictionary<ulong, Coroutine>();
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 bool UseGenericName
{
get
{
return _useGenericName;
}
set
{
if (IsSetup)
{
MarkAllAccuracyDataNeedUpdate();
}
_useGenericName = value;
}
}
public static Dictionary<int, Hikaria.AccuracyShower.Features.AccuracyShower.PlayerNameEntry> CharacterNamesLookup { get; set; } = new Dictionary<int, Hikaria.AccuracyShower.Features.AccuracyShower.PlayerNameEntry>
{
{
0,
new Hikaria.AccuracyShower.Features.AccuracyShower.PlayerNameEntry("Wood", "RED")
},
{
1,
new Hikaria.AccuracyShower.Features.AccuracyShower.PlayerNameEntry("Dauda", "GRE")
},
{
2,
new Hikaria.AccuracyShower.Features.AccuracyShower.PlayerNameEntry("Hackett", "BLU")
},
{
3,
new Hikaria.AccuracyShower.Features.AccuracyShower.PlayerNameEntry("Bishop", "PUR")
}
};
public static bool IsSetup
{
get
{
return _isSetup;
}
private set
{
_isSetup = value;
}
}
private static Dictionary<int, TextMeshPro> AccuracyTextMeshes { get; set; } = new Dictionary<int, TextMeshPro>();
private static Dictionary<ulong, AccuracyData> AccuracyDataLookup { get; set; } = new Dictionary<ulong, AccuracyData>();
private static Dictionary<ulong, bool> AccuracyDataNeedUpdate { get; set; } = new Dictionary<ulong, bool>();
private static Dictionary<int, bool> AccuracyTextMeshesVisible { get; set; } = new Dictionary<int, bool>();
private static Dictionary<ulong, int> AccuracyRegisteredCharacterIndex { get; set; } = new Dictionary<ulong, int>();
private void Awake()
{
Instance = this;
Setup();
MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, UpdateAccuracyDataCoroutine());
}
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($"AccuracyShower{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;
}
internal static void CheckAndSetVisible()
{
if (!SNet.IsMaster)
{
foreach (ulong item in 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 (RegisterPlayerCoroutines.ContainsKey(player.Lookup))
{
((MonoBehaviour)Instance).StopCoroutine(RegisterPlayerCoroutines[player.Lookup]);
}
MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)Instance, RegisterPlayerCoroutine(player));
}
private static IEnumerator RegisterPlayerCoroutine(SNet_Player player)
{
WaitForSecondsRealtime yielder = new WaitForSecondsRealtime(1f);
while (!player.HasCharacterSlot || player.CharacterIndex == -1)
{
yield return yielder;
}
AccuracyRegisteredCharacterIndex[player.Lookup] = player.CharacterIndex;
AccuracyDataLookup[player.Lookup] = new AccuracyData(player);
AccuracyDataNeedUpdate[player.Lookup] = true;
}
private IEnumerator UpdateAccuracyDataCoroutine()
{
WaitForSecondsRealtime yielder = new WaitForSecondsRealtime(3f);
while (true)
{
foreach (AccuracyData item in AccuracyDataLookup.Values.ToList())
{
SNet_Player owner = item.m_Owner;
if (!AccuracyDataNeedUpdate[owner.Lookup] || !AccuracyRegisteredCharacterIndex.TryGetValue(owner.Lookup, out var value))
{
continue;
}
UpdateAccuracyData(value, item.GetAccuracyText());
AccuracyDataNeedUpdate[owner.Lookup] = false;
if ((SNet.IsMaster && (owner.IsBot || !AccuracyManager.IsAccuracyListener(owner.Lookup))) || owner.IsLocal)
{
AccuracyManager.SendAccuracyData(item);
}
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.m_player)).TryGetPlayer(ref val))
{
AccuracyDataLookup[val.Lookup].Set(data);
AccuracyDataNeedUpdate[val.Lookup] = true;
}
}
private void UpdateAccuracyData(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 (ulong item in AccuracyDataNeedUpdate.Keys.ToList())
{
AccuracyDataNeedUpdate[item] = true;
}
}
internal static void MarkAccuracyDataNeedUpdate(ulong lookup)
{
AccuracyDataNeedUpdate[lookup] = true;
}
internal static void DoClear()
{
foreach (ulong item in AccuracyDataLookup.Keys.ToList())
{
AccuracyData accuracyData = AccuracyDataLookup[item];
accuracyData.m_Hitted = 0u;
accuracyData.m_Shotted = 0u;
accuracyData.m_WeakspotHitted = 0u;
AccuracyDataNeedUpdate[item] = true;
}
}
internal static void SetVisible(int index, bool visible, bool update = true)
{
AccuracyTextMeshesVisible[index] = Enabled && visible;
if (update)
{
UpdateVisible();
}
}
private static void UpdateVisible()
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: 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).transform.localPosition = new Vector3(-70f + (float)OffsetX, -62f + (float)OffsetY + -35f * (float)(i - num), 0f);
}
else
{
((Component)AccuracyTextMeshes[i].transform.parent.parent).transform.localPosition = new Vector3(-70f, 1000f, 0f);
}
}
}
internal static void UnregisterAllPlayers()
{
foreach (ulong key in AccuracyRegisteredCharacterIndex.Keys)
{
UnregisterPlayer(key);
}
UpdateVisible();
}
internal static void UnregisterPlayer(ulong lookup)
{
if (AccuracyRegisteredCharacterIndex.ContainsKey(lookup))
{
SetVisible(AccuracyRegisteredCharacterIndex[lookup], visible: false);
}
AccuracyDataLookup.Remove(lookup);
AccuracyDataNeedUpdate.Remove(lookup);
AccuracyRegisteredCharacterIndex.Remove(lookup);
}
internal static void AddHitted(ulong lookup, uint count)
{
if (AccuracyDataLookup.ContainsKey(lookup))
{
AccuracyDataLookup[lookup].AddHitted(count);
}
}
internal static void AddShotted(ulong lookup, uint count)
{
if (AccuracyDataLookup.ContainsKey(lookup))
{
AccuracyDataLookup[lookup].AddShotted(count);
}
}
internal static void AddWeakspotHitted(ulong lookup, uint count)
{
if (AccuracyDataLookup.ContainsKey(lookup))
{
AccuracyDataLookup[lookup].AddWeakspotHitted(count);
}
}
public static bool TryGetPlayerAccuracyData(SNet_Player player, out AccuracyData data)
{
return AccuracyDataLookup.TryGetValue(player.Lookup, out data);
}
private static bool NeedShowAccuracy(SNet_Player player)
{
if (!Hikaria.AccuracyShower.Features.AccuracyShower.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.AccuracyShower.Features
{
[EnableFeatureByDefault]
[DisallowInGameToggle]
public class AccuracyShower : Feature
{
public class AccuracyShowerSettings
{
[FSDisplayName("启用")]
public bool Enabled
{
get
{
return AccuracyUpdater.Enabled;
}
set
{
AccuracyUpdater.Enabled = value;
}
}
[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 ShowFormat
{
get
{
return AccuracyUpdater.ShowFormat;
}
set
{
AccuracyUpdater.ShowFormat = value;
}
}
[FSDisplayName("使用通用玩家名称")]
[FSDescription("若此项为 False, 则使用玩家名称")]
public bool UseGenericName
{
get
{
return AccuracyUpdater.UseGenericName;
}
set
{
AccuracyUpdater.UseGenericName = value;
}
}
[FSDisplayName("通用玩家名称设置")]
[FSReadOnly(true)]
public List<PlayerNameEntry> CharacterNames
{
get
{
return AccuracyUpdater.CharacterNamesLookup.Values.ToList();
}
set
{
}
}
[FSDisplayName("显示位置设置")]
public PositionSettings Position { get; set; } = new PositionSettings();
[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
{
[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
{
[FSDisplayName("命中率颜色")]
public SColor WeakspotHittedRatioColor { get; set; } = new SColor(0.7206f, 0.7206f, 0.7206f, (float?)0.3137f);
[FSDisplayName("弱点命中率颜色")]
public SColor HittedRatioColor { 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 HittedColor { 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("AccuracyShower");
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 SNet_GlobalManager__Setup__Patch
{
private static void Postfix()
{
SNet_Events.OnMasterChanged += Action.op_Implicit((Action)OnMasterChanged);
SNet_Events.OnPlayerEvent += Action<SNet_Player, SNet_PlayerEvent, SNet_PlayerEventReason>.op_Implicit((Action<SNet_Player, SNet_PlayerEvent, SNet_PlayerEventReason>)OnPlayerEvent);
}
}
public enum SessionMemberEvent
{
JoinSessionHub,
LeftSessionHub
}
[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 PlayerSync__SyncInventoryStatus__Patch
{
private static void Prefix(PlayerSync __instance)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Invalid comparison between Unknown and I4
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Invalid comparison between Unknown and I4
SNet_Player owner = __instance.m_agent.Owner;
if (!owner.IsLocal && SNet.IsMaster && !owner.IsBot && !AccuracyManager.IsAccuracyListener(owner.Lookup))
{
InventorySlot wieldedSlot = __instance.GetWieldedSlot();
if ((int)wieldedSlot == 1 || (int)wieldedSlot == 2)
{
LastWieldValidSlot[owner.Lookup] = wieldedSlot;
}
}
}
}
[ArchivePatch(/*Could not decode attribute arguments.*/)]
private class PlayerInventorySynced__GetSync__Patch
{
private static void Prefix(PlayerInventorySynced __instance)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Invalid comparison between Unknown and I4
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Invalid comparison between Unknown and I4
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Invalid comparison between Unknown and I4
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)((PlayerInventoryBase)__instance).Owner == (Object)null)
{
return;
}
SNet_Player owner = ((PlayerInventoryBase)__instance).Owner.Owner;
if (!SNet.IsMaster || owner.IsBot || owner.IsLocal || AccuracyManager.IsAccuracyListener(owner.Lookup))
{
return;
}
InventorySlot wieldedSlot = ((PlayerInventoryBase)__instance).Owner.Inventory.WieldedSlot;
if ((int)wieldedSlot == 3)
{
return;
}
uint num = (uint)((PlayerInventoryBase)__instance).Owner.Sync.FireCountSync;
InventorySlot value;
if ((Object)(object)((PlayerInventoryBase)__instance).WieldedItem != (Object)null && ((int)wieldedSlot == 1 || (int)wieldedSlot == 2))
{
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;
}
}
}
else if (LastWieldValidSlot.TryGetValue(owner.Lookup, out value))
{
PlayerBackpack val3 = default(PlayerBackpack);
BackpackItem val4 = default(BackpackItem);
if (!PlayerBackpackManager.TryGetBackpack(owner, ref val3) || !val3.TryGetBackpackItem(value, ref val4))
{
return;
}
BulletWeaponSynced val5 = ((Il2CppObjectBase)val4.Instance).TryCast<BulletWeaponSynced>();
if ((Object)(object)val5 != (Object)null)
{
ShotgunSynced val6 = ((Il2CppObjectBase)val5).TryCast<ShotgunSynced>();
if ((Object)(object)val6 != (Object)null && ((ItemEquippable)val6).ArchetypeData != null)
{
num *= (uint)((ItemEquippable)val6).ArchetypeData.ShotgunBulletCount;
}
}
else
{
Logs.LogError("Not BulletWeapon but fire bullets?");
}
}
AccuracyUpdater.AddShotted(owner.Lookup, num);
AccuracyUpdater.MarkAccuracyDataNeedUpdate(owner.Lookup);
}
}
[ArchivePatch(/*Could not decode attribute arguments.*/)]
private class Dam_EnemyDamageBase__ReceiveBulletDamage__Patch
{
private static void Postfix(Dam_EnemyDamageBase __instance, pBulletDamageData data)
{
//IL_0054: 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_0065: Invalid comparison between Unknown and I4
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;
if (!AccuracyManager.IsAccuracyListener(owner.Lookup) && !owner.IsLocal && !owner.IsBot)
{
if ((int)((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)__instance.DamageLimbs)[(int)data.limbID].m_type == 1)
{
AccuracyUpdater.AddWeakspotHitted(owner.Lookup, 1u);
}
AccuracyUpdater.AddHitted(owner.Lookup, 1u);
AccuracyUpdater.MarkAccuracyDataNeedUpdate(owner.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 = 1;
HitCount = 0u;
BulletHitCalledCount = 0;
BulletsCountPerFire = 1;
ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
if (archetypeData != null)
{
IsPiercingBullet = archetypeData.PiercingBullets;
BulletPiercingLimit = (archetypeData.PiercingBullets ? archetypeData.PiercingDamageCountLimit : 0);
}
}
}
private static void Postfix(BulletWeapon __instance)
{
if (((Item)__instance).Owner.Owner.IsBot && SNet.IsMaster)
{
CanCalc = false;
IsInWeaponFire = false;
SNet_Player owner = ((Item)__instance).Owner.Owner;
AccuracyUpdater.AddShotted(owner.Lookup, (uint)BulletsCountPerFire);
AccuracyUpdater.AddHitted(owner.Lookup, HitCount);
AccuracyUpdater.MarkAccuracyDataNeedUpdate(owner.Lookup);
}
}
}
[ArchivePatch(/*Could not decode attribute arguments.*/)]
private class ShotgunSynced__Fire__Patch
{
private static void Prefix(Shotgun __instance)
{
if (((Item)__instance).Owner.Owner.IsBot && SNet.IsMaster)
{
CanCalc = true;
IsInWeaponFire = true;
IsPiercingBullet = false;
BulletPiercingLimit = 1;
HitCount = 0u;
BulletHitCalledCount = 0;
BulletsCountPerFire = 1;
ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
if (archetypeData != null)
{
IsPiercingBullet = archetypeData.PiercingBullets;
BulletPiercingLimit = (archetypeData.PiercingBullets ? archetypeData.PiercingDamageCountLimit : 0);
BulletsCountPerFire = archetypeData.ShotgunBulletCount;
}
}
}
private static void Postfix(BulletWeapon __instance)
{
if (((Item)__instance).Owner.Owner.IsBot && SNet.IsMaster)
{
CanCalc = false;
IsInWeaponFire = false;
SNet_Player owner = ((Item)__instance).Owner.Owner;
AccuracyUpdater.AddShotted(owner.Lookup, (uint)BulletsCountPerFire);
AccuracyUpdater.AddHitted(owner.Lookup, HitCount);
AccuracyUpdater.MarkAccuracyDataNeedUpdate(owner.Lookup);
}
}
}
[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 = 1;
HitCount = 0u;
BulletHitCalledCount = 0;
BulletsCountPerFire = 1;
ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
if (archetypeData != null)
{
IsPiercingBullet = archetypeData.PiercingBullets;
BulletPiercingLimit = (archetypeData.PiercingBullets ? archetypeData.PiercingDamageCountLimit : 0);
}
}
}
private static void Postfix(BulletWeapon __instance)
{
if (IsWeaponOwner(__instance))
{
CanCalc = false;
IsInWeaponFire = false;
SNet_Player owner = ((Item)__instance).Owner.Owner;
AccuracyUpdater.AddShotted(owner.Lookup, (uint)BulletsCountPerFire);
AccuracyUpdater.AddHitted(owner.Lookup, HitCount);
AccuracyUpdater.MarkAccuracyDataNeedUpdate(owner.Lookup);
}
}
}
[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 = 1;
HitCount = 0u;
BulletHitCalledCount = 0;
BulletsCountPerFire = 1;
ArchetypeDataBlock archetypeData = ((ItemEquippable)__instance).ArchetypeData;
if (archetypeData != null)
{
IsPiercingBullet = archetypeData.PiercingBullets;
BulletPiercingLimit = (archetypeData.PiercingBullets ? archetypeData.PiercingDamageCountLimit : 0);
BulletsCountPerFire = archetypeData.ShotgunBulletCount;
}
}
}
private static void Postfix(Shotgun __instance)
{
if (IsWeaponOwner((BulletWeapon)(object)__instance))
{
CanCalc = false;
IsInWeaponFire = false;
SNet_Player owner = ((Item)__instance).Owner.Owner;
AccuracyUpdater.AddShotted(owner.Lookup, (uint)BulletsCountPerFire);
AccuracyUpdater.AddHitted(owner.Lookup, HitCount);
AccuracyUpdater.MarkAccuracyDataNeedUpdate(owner.Lookup);
}
}
}
[ArchivePatch(/*Could not decode attribute arguments.*/)]
private class Dam_EnemyDamageLimb__BulletDamage__Patch
{
private static void Postfix(Dam_EnemyDamageLimb __instance, Agent sourceAgent)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Invalid comparison between Unknown and I4
if (CanCalc && !((Object)(object)sourceAgent == (Object)null))
{
PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
if ((Object)(object)val != (Object)null && (int)__instance.m_type == 1)
{
AccuracyUpdater.AddWeakspotHitted(val.Owner.Lookup, 1u);
}
}
}
}
[ArchivePatch(/*Could not decode attribute arguments.*/)]
private class BulletWeapon__BulletHit__Patch
{
private static bool CanCalcHitted;
private static void Postfix(bool __result)
{
if (!IsInWeaponFire || IsSentryGunFire || !CanCalc || BulletHitCalledCount >= BulletsCountPerFire)
{
return;
}
if (IsPiercingBullet)
{
if (BulletHitCalledCount % BulletPiercingLimit == 0)
{
CanCalcHitted = true;
}
}
else
{
CanCalcHitted = true;
}
BulletHitCalledCount++;
if (__result && CanCalcHitted)
{
HitCount++;
CanCalcHitted = false;
}
}
}
private static uint HitCount;
private static int BulletPiercingLimit;
private static int BulletsCountPerFire;
private static int BulletHitCalledCount;
private static bool IsPiercingBullet;
private static bool IsInWeaponFire;
private static bool CanCalc;
public override string Name => "AccuracyShower";
public override string Group => Group.op_Implicit(FeatureGroups.Hud);
[FeatureConfig]
public static AccuracyShowerSettings Settings { get; set; }
public static bool IsSetup { get; private set; }
public static bool IsSentryGunFire { get; private set; }
private static Dictionary<ulong, InventorySlot> LastWieldValidSlot { get; set; } = new Dictionary<ulong, InventorySlot>();
public override void OnGameStateChanged(int state)
{
if (state == 5)
{
AccuracyUpdater.DoClear();
}
}
public override void Init()
{
ClassInjector.RegisterTypeInIl2Cpp<AccuracyUpdater>(false);
AccuracyManager.Setup();
}
private static void OnPlayerEvent(SNet_Player player, SNet_PlayerEvent playerEvent, SNet_PlayerEventReason reason)
{
//IL_0005: 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_000a: Invalid comparison between Unknown and I4
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
AccuracyManager.BroadcastAccuracyDataListener();
if ((int)playerEvent != 0)
{
if ((int)playerEvent == 5)
{
AccuracyManager.OnSessionMemberChanged(player, SessionMemberEvent.JoinSessionHub);
return;
}
if ((int)playerEvent != 6)
{
return;
}
}
AccuracyManager.OnSessionMemberChanged(player, SessionMemberEvent.LeftSessionHub);
}
private static void OnMasterChanged()
{
AccuracyUpdater.CheckAndSetVisible();
}
private static bool IsWeaponOwner(BulletWeapon weapon)
{
if ((Object)(object)weapon == (Object)null || (Object)(object)((Item)weapon).Owner == (Object)null || (Object)(object)((Item)weapon).Owner.Owner == (Object)null)
{
return false;
}
return ((Item)weapon).Owner.Owner.IsLocal;
}
}
}
namespace Hikaria.AccuracyShower.Extensions
{
internal static class StringExts
{
public static string RemoveHtmlTags(this string htmlString)
{
string pattern = "<.*?>";
return Regex.Replace(htmlString, pattern, string.Empty);
}
}
}