using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HtF.Shared; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HtF.AmmoCounter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+76aa5112a8a5b0c9897d3f3557b28a045762e8aa")] [assembly: AssemblyProduct("HtF.AmmoCounter")] [assembly: AssemblyTitle("HtF.AmmoCounter")] [assembly: AssemblyVersion("1.0.0.0")] namespace HtF.Shared { public enum Language { Auto, Chinese, English } public static class Loc { private sealed class Entry { internal string NameZh; internal string NameEn; internal string DescZh; internal string DescEn; } private const string OwnerGuid = "htf.configmenu"; private const string OwnerSection = "介面"; private const string OwnerKey = "語言"; private static readonly Dictionary Entries = new Dictionary(StringComparer.Ordinal); public static Func LocalChoice; private static ConfigEntryBase _remote; private static string _remoteChoice; private static float _nextRemoteRead; public static bool IsEnglish { get; private set; } public static ConfigEntry Bind(ConfigFile file, string section, string key, T defaultValue, string nameEn, string descZh, string descEn = null, AcceptableValueBase range = null) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown Add(key, null, nameEn, descZh, descEn); return file.Bind(section, key, defaultValue, new ConfigDescription(CfgDesc(key), range, Array.Empty())); } public static void Section(string section, string nameEn) { Add(section, null, nameEn, null, null); } public static void EnumValue(object value, string nameZh, string nameEn) { if (value != null) { Add("enum." + value, nameZh, nameEn, null, null); } } public static void Add(string key, string nameZh, string nameEn, string descZh, string descEn) { if (!string.IsNullOrEmpty(key)) { Entries[key] = new Entry { NameZh = nameZh, NameEn = nameEn, DescZh = descZh, DescEn = descEn }; } } public static string Term(string key, bool english, bool wantDesc) { if (key == null || !Entries.TryGetValue(key, out var value)) { return null; } if (wantDesc) { if (!english) { return value.DescZh; } return value.DescEn; } if (!english) { return value.NameZh; } return value.NameEn; } public static string CfgDesc(string key) { if (key == null || !Entries.TryGetValue(key, out var value) || value.DescZh == null) { return ""; } if (value.DescEn != null) { return value.DescZh + "\n" + value.DescEn; } return value.DescZh; } public static void Resolve() { string text = ((LocalChoice != null) ? LocalChoice() : RemoteChoice()); if (text == "English") { IsEnglish = true; } else if (text == "Chinese") { IsEnglish = false; } else { IsEnglish = !GameSpeaksChinese(); } } private static string RemoteChoice() { if (Time.unscaledTime < _nextRemoteRead) { return _remoteChoice; } _nextRemoteRead = Time.unscaledTime + 0.5f; try { if (_remote == null) { if (!Chainloader.PluginInfos.TryGetValue("htf.configmenu", out var value)) { return _remoteChoice = null; } if (value == null || (Object)(object)value.Instance == (Object)null || value.Instance.Config == null) { return _remoteChoice = null; } ConfigEntryBase[] configEntries = value.Instance.Config.GetConfigEntries(); foreach (ConfigEntryBase val in configEntries) { if (val.Definition.Section == "介面" && val.Definition.Key == "語言") { _remote = val; break; } } if (_remote == null) { return _remoteChoice = null; } } _remoteChoice = _remote.BoxedValue?.ToString(); } catch (Exception) { _remoteChoice = null; } return _remoteChoice; } private static bool GameSpeaksChinese() { try { int curLanguage = LocalizationManager.CurLanguage; return curLanguage == 2 || curLanguage == 3; } catch (Exception) { return false; } } public static string P(string zh, string en) { if (!IsEnglish) { return zh; } return en; } } } namespace HtF.AmmoCounter { internal static class AmmoHud { private static GUIStyle _big; private static GUIStyle _small; private static Texture2D _white; private static Font _font; private static string _loadedFont; private static bool _stylesReady; private static FieldInfo _reloadingField; private static bool _reloadingFieldTried; private static readonly Color Normal = new Color(0.94f, 0.95f, 0.96f); private static readonly Color Low = new Color(1f, 0.71f, 0.24f); private static readonly Color Empty = new Color(0.93f, 0.31f, 0.29f); private static readonly Color Spent = new Color(1f, 1f, 1f, 0.22f); private static readonly Color Shadow = new Color(0f, 0f, 0f, 0.75f); internal static void Draw() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 if (Plugin.Enabled == null || !Plugin.Enabled.Value || (int)Event.current.type != 7) { return; } Weapon val; try { val = HeldWeapon(); if (!Object.op_Implicit((Object)(object)val) || (Plugin.HideWhenAds.Value && val.IsAds) || (Plugin.HideWhenPaused.Value && (PauseManager.IsPaused || ChatManager.IsTyping || PlayerUI.UIDisabled))) { return; } } catch (Exception) { return; } int num; int num2; bool reloading; string weaponName; try { num = Mathf.Max(0, val.Ammo); num2 = Mathf.Max(1, val.Attachments.AmmoPerMag); if (num > num2) { num2 = num; } reloading = Plugin.ShowReloading.Value && IsReloading(val); weaponName = (Plugin.ShowWeaponName.Value ? Name(val) : null); } catch (Exception) { return; } EnsureFont(); EnsureStyles(); Render(num, num2, reloading, weaponName); } private static Weapon HeldWeapon() { Player localPlayer = Player.LocalPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)localPlayer.Holding)) { return null; } Item heldItem = localPlayer.Holding.HeldItem; if (!Object.op_Implicit((Object)(object)heldItem)) { return null; } return heldItem.Weapon; } private static bool IsReloading(Weapon weapon) { if (!_reloadingFieldTried) { _reloadingFieldTried = true; _reloadingField = typeof(Weapon).GetField("_isReloading", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (_reloadingField == null) { Plugin.Log.LogWarning((object)"找不到 Weapon._isReloading,裝填提示不顯示。"); } } if (_reloadingField == null) { return false; } try { return (bool)_reloadingField.GetValue(weapon); } catch (Exception) { return false; } } private static string Name(Weapon weapon) { try { string name = ((Item)weapon).GetName(); if (!string.IsNullOrEmpty(name)) { return name; } } catch (Exception) { } string name2 = ((Object)weapon).name; if (string.IsNullOrEmpty(name2)) { return L.Unnamed; } int num = name2.IndexOf("(Clone)", StringComparison.Ordinal); return ((num >= 0) ? name2.Substring(0, num) : name2).Trim(); } private static void EnsureFont() { string text = Plugin.FontName.Value ?? ""; if (_loadedFont == text) { return; } _loadedFont = text; _font = null; _stylesReady = false; if (text.Length == 0) { return; } try { _font = Font.CreateDynamicFontFromOSFont(text, 24); } catch (Exception ex) { Plugin.Log.LogWarning((object)("載入字型 " + text + " 失敗:" + ex.Message)); } } private static void EnsureStyles() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_002f: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown if (!_stylesReady) { _stylesReady = true; if (!Object.op_Implicit((Object)(object)_white)) { _white = new Texture2D(1, 1, (TextureFormat)4, false); _white.SetPixel(0, 0, Color.white); ((Texture)_white).filterMode = (FilterMode)0; ((Object)_white).hideFlags = (HideFlags)61; _white.Apply(); } _big = new GUIStyle(GUI.skin.label) { fontSize = 26, fontStyle = (FontStyle)1, richText = false, wordWrap = false, alignment = (TextAnchor)4 }; if ((Object)(object)_font != (Object)null) { _big.font = _font; } _small = new GUIStyle(_big) { fontSize = 13, fontStyle = (FontStyle)0 }; } } private static Color ColorFor(int ammo, int mag) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (ammo <= 0) { if (!Plugin.BlinkWhenEmpty.Value) { return Empty; } float num = Mathf.PingPong(Time.unscaledTime * 2f, 1f); return Color.Lerp(Empty, new Color(Empty.r, Empty.g, Empty.b, 0.35f), num); } float value = Plugin.LowThreshold.Value; if (!(value > 0f) || !((float)ammo / (float)mag <= value)) { return Normal; } return Low; } private static void Render(int ammo, int mag, bool reloading, string weaponName) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) Style value = Plugin.DrawStyle.Value; bool flag = value != Style.圓點; bool num = value != Style.數字; string text = (Plugin.ShowMagSize.Value ? (ammo + " / " + mag) : ammo.ToString()); float num2 = 0f; float num3 = 0f; float num4 = 0f; if (weaponName != null) { num4 = _small.lineHeight; num2 = Mathf.Max(num2, _small.CalcSize(new GUIContent(weaponName)).x); num3 += num4 + 4f; } float num5 = 0f; if (flag) { num5 = _big.lineHeight; num2 = Mathf.Max(num2, _big.CalcSize(new GUIContent(text)).x); num3 += num5; } bool flag2 = num && mag <= 40; float num6 = (float)mag * 5f + (float)(mag - 1) * 3f; if (flag2) { if (flag) { num3 += 4f; } num2 = Mathf.Max(num2, num6); num3 += 14f; } else if (!flag) { flag = true; num5 = _big.lineHeight; num2 = Mathf.Max(num2, _big.CalcSize(new GUIContent(text)).x); num3 += num5; } float num7 = 0f; string text2 = (reloading ? L.Reloading : null); if (text2 != null) { num7 = _small.lineHeight; num2 = Mathf.Max(num2, _small.CalcSize(new GUIContent(text2)).x); num3 += 4f + num7; } float value2 = Plugin.Scale.Value; float num8 = (float)Screen.width / value2; float num9 = (float)Screen.height / value2; float num10; float num11; switch (Plugin.Anchor.Value) { case Corner.左上: num10 = Plugin.OffsetX.Value; num11 = Plugin.OffsetY.Value; break; case Corner.右上: num10 = num8 - num2 - (float)Plugin.OffsetX.Value; num11 = Plugin.OffsetY.Value; break; case Corner.左下: num10 = Plugin.OffsetX.Value; num11 = num9 - num3 - (float)Plugin.OffsetY.Value; break; case Corner.右下: num10 = num8 - num2 - (float)Plugin.OffsetX.Value; num11 = num9 - num3 - (float)Plugin.OffsetY.Value; break; default: num10 = num8 * 0.5f - num2 * 0.5f + (float)Plugin.OffsetX.Value; num11 = num9 * 0.5f + (float)Plugin.OffsetY.Value; break; } Color val = ColorFor(ammo, mag); Matrix4x4 matrix = GUI.matrix; Color color = GUI.color; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(value2, value2, 1f)); float num12 = num11; if (weaponName != null) { DrawText(new Rect(num10, num12, num2, num4), weaponName, _small, new Color(1f, 1f, 1f, 0.7f)); num12 += num4 + 4f; } if (flag) { DrawText(new Rect(num10, num12, num2, num5), text, _big, val); num12 += num5; if (flag2) { num12 += 4f; } } if (flag2) { float num13 = num10 + (num2 - num6) * 0.5f; Rect val2 = default(Rect); for (int i = 0; i < mag; i++) { ((Rect)(ref val2))..ctor(num13 + (float)i * 8f, num12, 5f, 14f); GUI.color = Shadow; GUI.DrawTexture(new Rect(((Rect)(ref val2)).x + 1f, ((Rect)(ref val2)).y + 1f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height), (Texture)(object)_white); GUI.color = ((i < ammo) ? val : Spent); GUI.DrawTexture(val2, (Texture)(object)_white); } num12 += 14f; } if (text2 != null) { num12 += 4f; DrawText(new Rect(num10, num12, num2, num7), text2, _small, new Color(1f, 1f, 1f, 0.8f)); } GUI.color = color; GUI.matrix = matrix; } private static void DrawText(Rect r, string text, GUIStyle style, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_005a: Unknown result type (might be due to invalid IL or missing references) GUI.color = Color.white; style.normal.textColor = Shadow; GUI.Label(new Rect(((Rect)(ref r)).x + 1f, ((Rect)(ref r)).y + 1f, ((Rect)(ref r)).width, ((Rect)(ref r)).height), text, style); style.normal.textColor = color; GUI.Label(r, text, style); } } internal static class L { internal static string Reloading => Loc.P("裝填中…", "Reloading…"); internal static string Unnamed => Loc.P("(無名)", "(unnamed)"); } internal enum Corner { 準心下方, 左上, 右上, 左下, 右下 } internal enum Style { 數字, 圓點, 數字與圓點 } [BepInPlugin("htf.ammocounter", "HtF Ammo Counter", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "htf.ammocounter"; internal static ManualLogSource Log; internal static ConfigEntry Enabled; internal static ConfigEntry ToggleKey; internal static ConfigEntry HideWhenPaused; internal static ConfigEntry HideWhenAds; internal static ConfigEntry Anchor; internal static ConfigEntry OffsetX; internal static ConfigEntry OffsetY; internal static ConfigEntry Scale; internal static ConfigEntry FontName; internal static ConfigEntry