using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using Steamworks; using Steamworks.Data; using TMPro; using UnityEngine; using UnityEngine.Localization.Components; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("HamiltonMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HamiltonMod")] [assembly: AssemblyTitle("HamiltonMod")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HamiltonMod { [BepInPlugin("codex.superbattlegolf.hamilton", "Hamilton", "0.1.17")] public sealed class HamiltonPlugin : BaseUnityPlugin { private enum ShotOutcome { Normal, Jam, Backfire } [HarmonyPatch(typeof(PlayerInventory), "DecrementUseFromSlotAt")] private static class KeepPistolLoadedPatch { private static bool Prefix(PlayerInventory __instance, int index) { return !IsReservedPistolSlot(__instance, index); } } [HarmonyPatch(typeof(PlayerInventory), "RemoveIfOutOfUses")] private static class PreventLoadedPistolRemovalPatch { private static bool Prefix(PlayerInventory __instance, int index) { return !IsReservedPistolSlot(__instance, index); } } [HarmonyPatch(typeof(PlayerInventorySettings), "get_MaxItems")] private static class MaxInventorySlotsPatch { private static void Postfix(ref int __result) { if (IsHamiltonEnabled()) { __result = Mathf.Max(__result, 4); } } } [HarmonyPatch(typeof(PlayerInventory), "OnStartServer")] private static class ServerStartReservedPistolPatch { private static void Postfix(PlayerInventory __instance) { if (IsHamiltonEnabled() && NetworkServer.active) { EnsureReservedPistol(__instance); } } } [HarmonyPatch(typeof(PlayerInventory), "OnStartClient")] private static class ClientStartReservedPistolPatch { private static void Postfix(PlayerInventory __instance) { } } [HarmonyPatch(typeof(PlayerInventory), "OnStartLocalPlayer")] private static class LocalPlayerStartReservedPistolPatch { private static void Postfix(PlayerInventory __instance) { if (IsHamiltonEnabled() && NetworkServer.active) { EnsureReservedPistol(__instance); } } } [HarmonyPatch(typeof(PlayerInventory), "ServerTryAddItem")] private static class ReservedSlotItemGrantPatch { private static bool Prefix(PlayerInventory __instance, ItemType itemToAdd, int remainingUses, ref bool __result) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if (!IsHamiltonEnabled() || !NetworkServer.active) { return true; } if ((int)itemToAdd == 2) { EnsureReservedPistol(__instance); __result = true; return false; } EnsureReservedPistol(__instance); return true; } } [HarmonyPatch(typeof(PlayerInventory), "DropItem")] private static class PreventDroppingReservedPistolPatch { private static bool Prefix(PlayerInventory __instance) { if (IsHamiltonEnabled()) { return __instance.EquippedItemIndex != 0; } return true; } } [HarmonyPatch(typeof(MatchSetupRules), "Initialize")] private static class MatchSetupRulesInitializePatch { private static void Postfix() { instance?.TryInstallHamiltonRulesToggle(); } } [HarmonyPatch(typeof(MatchSetupRules), "OnStartClient")] private static class MatchSetupRulesStartClientPatch { private static void Postfix() { instance?.TryInstallHamiltonRulesToggle(); } } [HarmonyPatch(typeof(ItemPool), "GetWeightedRandomItem")] private static class RemovePistolFromItemPoolsPatch { private static bool Prefix(ItemPool __instance, ref ItemType __result) { if (!IsHamiltonEnabled()) { return true; } return !TryGetWeightedRandomNonPistolItem(__instance, out __result); } } [HarmonyPatch] private static class DuelingPistolShotPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(PlayerInventory), "g__Shoot|164_0", (Type[])null, (Type[])null); } private static bool Prefix(PlayerInventory __instance) { if (!IsHamiltonEnabled() || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isLocalPlayer) { return true; } switch (RollShotOutcome()) { case ShotOutcome.Jam: QueueReloadJam(__instance); return true; case ShotOutcome.Backfire: Backfire(__instance); return false; default: return true; } } private static void Postfix(PlayerInventory __instance) { if (IsHamiltonEnabled() && (Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).isLocalPlayer) { ApplyReloadJam(__instance); } } } private const string PluginGuid = "codex.superbattlegolf.hamilton"; private const string PluginName = "Hamilton"; private const string PluginVersion = "0.1.17"; private const string LobbyEnabledStateKey = "codex_hamilton_enabled"; private const string LobbyEnabledVersionKey = "codex_hamilton_enabled_version"; private const string LobbyRequiredVersionKey = "codex_hamilton_required_version"; private const string LobbyMemberVersionKey = "codex_hamilton_member_version"; private const string ProGolfActiveStateKey = "codex_progolfplus_active"; private const float LobbyPollInterval = 1f; private const float LocalMemberVersionPublishInterval = 2f; private const float RulesUiRefreshInterval = 0.5f; private const int ReservedPistolSlotIndex = 0; private const int TotalInventorySlots = 4; private static HamiltonPlugin instance; private static FieldInfo inventorySlotsField; private static FieldInfo itemPoolSpawnChancesField; private static MethodInfo giveItemToLocalPlayerMethod; private static FieldInfo itemUseTimestampField; private static int syntheticItemUseIndex; private static bool hasLobbyEnabledState; private static bool lobbyEnabledState; private static string lastObservedLobbyEnabledVersion = string.Empty; private static float nextLobbyPollTime; private static float nextLocalMemberVersionPublishTime; private static bool allLobbyMembersCompatible = true; private static string incompatibleLobbyMembers = string.Empty; private static float nextCompatibilityWarningTime; private static bool lastEffectiveEnabled; private static bool proGolfPlusLobbyActive; private static readonly Dictionary spawnChanceItemFields = new Dictionary(); private static readonly Dictionary spawnChanceWeightFields = new Dictionary(); private static readonly HashSet pendingReloadJams = new HashSet(); private Harmony harmony; private ConfigEntry enabledConfig; private ConfigEntry grantCheckIntervalConfig; private ConfigEntry jamChanceConfig; private ConfigEntry jamReloadDelaySecondsConfig; private ConfigEntry backfireChanceConfig; private ConfigEntry autoSelectPistolConfig; private float nextGrantCheckTime; private float nextRulesUiCheckTime; private float nextRulesUiRefreshTime; private DropdownOption hamiltonRulesDropdown; private bool suppressHamiltonDropdownChanged; private void Awake() { //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown instance = this; enabledConfig = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", false, "Enable Hamilton when Custom rules are selected."); grantCheckIntervalConfig = ((BaseUnityPlugin)this).Config.Bind("General", "GrantCheckIntervalSeconds", 1f, "How often the mod checks whether the local player needs a pistol."); jamChanceConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "JamChance", 0.15f, "Chance from 0 to 1 that a pistol shot fires but reloads more slowly."); jamReloadDelaySecondsConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "JamReloadDelaySeconds", 1.5f, "Extra seconds added to the pistol reload when a jam happens."); backfireChanceConfig = ((BaseUnityPlugin)this).Config.Bind("Chaos", "BackfireChance", 0.1f, "Chance from 0 to 1 that a pistol shot hits the shooter instead."); autoSelectPistolConfig = ((BaseUnityPlugin)this).Config.Bind("General", "AutoSelectPistol", false, "Automatically select the permanent pistol slot when the mod grants one."); inventorySlotsField = AccessTools.Field(typeof(PlayerInventory), "slots"); itemUseTimestampField = AccessTools.Field(typeof(PlayerInventory), "k__BackingField"); itemPoolSpawnChancesField = AccessTools.Field(typeof(ItemPool), "spawnChances"); giveItemToLocalPlayerMethod = AccessTools.Method(typeof(PlayerInventory), "GiveItemToLocalPlayer", (Type[])null, (Type[])null); harmony = new Harmony("codex.superbattlegolf.hamilton"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Hamilton 0.1.17 loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } if (instance == this) { instance = null; } } private void Update() { PollSteamLobbyEnabledState(); TryInstallHamiltonRulesToggle(); RefreshHamiltonRulesToggleThrottled(); if (!IsHamiltonEnabled()) { if (lastEffectiveEnabled && NetworkServer.active) { RemoveHamiltonPistolsFromAllPlayers(); } lastEffectiveEnabled = false; return; } lastEffectiveEnabled = true; if (!(Time.unscaledTime < nextGrantCheckTime)) { nextGrantCheckTime = Time.unscaledTime + Mathf.Max(0.25f, grantCheckIntervalConfig.Value); TryEnsureLocalPlayerHasPistol(); } } private static bool IsHamiltonEnabled() { if (!IsHamiltonAllowedForCurrentPreset()) { return false; } if (IsProGolfMatchUnderway()) { return false; } if (NetworkServer.active && !allLobbyMembersCompatible) { return false; } if (hasLobbyEnabledState) { return lobbyEnabledState; } return instance?.enabledConfig.Value ?? false; } private static bool IsHamiltonAllowedForCurrentPreset() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 MatchSetupRules val = FindMatchSetupRules(); if ((Object)(object)val != (Object)null) { return (int)val.CurrentPreset == 2; } return false; } private static bool IsProGolfMatchUnderway() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 MatchSetupRules val = FindMatchSetupRules(); if ((Object)(object)val != (Object)null && (int)val.CurrentPreset == 1) { MatchState matchState = CourseManager.MatchState; if ((int)matchState >= 1) { return (int)matchState < 6; } return false; } return proGolfPlusLobbyActive; } private void RefreshHamiltonRulesToggleThrottled() { if (!(Time.unscaledTime < nextRulesUiRefreshTime)) { nextRulesUiRefreshTime = Time.unscaledTime + 0.5f; RefreshHamiltonRulesToggle(); } } private static int DropdownValueFromEnabled(bool enabled) { return (!enabled) ? 1 : 0; } private static bool EnabledFromDropdownValue(int value) { return value == 0; } private static void PollSteamLobbyEnabledState() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < nextLobbyPollTime) { return; } nextLobbyPollTime = Time.unscaledTime + 1f; Lobby lobby = default(Lobby); if (!BNetworkManager.TryGetSteamLobby(ref lobby)) { if (!NetworkServer.active && !NetworkClient.active) { hasLobbyEnabledState = false; lastObservedLobbyEnabledVersion = string.Empty; allLobbyMembersCompatible = true; incompatibleLobbyMembers = string.Empty; proGolfPlusLobbyActive = false; } return; } PublishLocalMemberVersion(lobby); proGolfPlusLobbyActive = string.Equals(((Lobby)(ref lobby)).GetData("codex_progolfplus_active"), "1", StringComparison.Ordinal); if (NetworkServer.active) { UpdateLobbyCompatibility(lobby); } string data = ((Lobby)(ref lobby)).GetData("codex_hamilton_enabled"); if (string.IsNullOrEmpty(data)) { if (NetworkServer.active) { PublishSteamLobbyEnabledState(instance?.enabledConfig.Value ?? false); } return; } string data2 = ((Lobby)(ref lobby)).GetData("codex_hamilton_enabled_version"); bool flag = data == "1"; bool num = !hasLobbyEnabledState || lobbyEnabledState != flag || data2 != lastObservedLobbyEnabledVersion; hasLobbyEnabledState = true; lobbyEnabledState = flag; lastObservedLobbyEnabledVersion = data2; if (num) { if (NetworkServer.active) { ApplyServerEnabledState(flag); } instance?.RefreshHamiltonRulesToggle(); } } private static void PublishLocalMemberVersion(Lobby lobby) { if (SteamClient.IsValid && !(Time.unscaledTime < nextLocalMemberVersionPublishTime)) { nextLocalMemberVersionPublishTime = Time.unscaledTime + 2f; ((Lobby)(ref lobby)).SetMemberData("codex_hamilton_member_version", "0.1.17"); } } private unsafe static void UpdateLobbyCompatibility(Lobby lobby) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } if (!string.Equals(((Lobby)(ref lobby)).GetData("codex_hamilton_required_version"), "0.1.17", StringComparison.Ordinal)) { ((Lobby)(ref lobby)).SetData("codex_hamilton_required_version", "0.1.17"); } List list = new List(); foreach (Friend member in ((Lobby)(ref lobby)).Members) { Friend current = member; string memberData = ((Lobby)(ref lobby)).GetMemberData(current, "codex_hamilton_member_version"); if (!string.Equals(memberData, "0.1.17", StringComparison.Ordinal)) { string? text; if (!string.IsNullOrEmpty(((Friend)(ref current)).Name)) { text = ((Friend)(ref current)).Name; } else { SteamId id = current.Id; text = ((object)(*(SteamId*)(&id))/*cast due to .constrained prefix*/).ToString(); } string text2 = text; list.Add(string.IsNullOrEmpty(memberData) ? (text2 + " (missing Hamilton 0.1.17)") : (text2 + " (Hamilton " + memberData + ", needs 0.1.17)")); } } allLobbyMembersCompatible = list.Count == 0; incompatibleLobbyMembers = string.Join(", ", list); if (allLobbyMembersCompatible) { return; } if (hasLobbyEnabledState && lobbyEnabledState) { PublishSteamLobbyEnabledState(enabled: false); } if (Time.unscaledTime >= nextCompatibilityWarningTime) { nextCompatibilityWarningTime = Time.unscaledTime + 10f; HamiltonPlugin hamiltonPlugin = instance; if (hamiltonPlugin != null) { ((BaseUnityPlugin)hamiltonPlugin).Logger.LogWarning((object)("Hamilton disabled until every lobby member is running Hamilton 0.1.17: " + incompatibleLobbyMembers)); } } } private static void PublishSteamLobbyEnabledState(bool enabled) { if (enabled && !IsHamiltonAllowedForCurrentPreset()) { enabled = false; } if (enabled && NetworkServer.active && !allLobbyMembersCompatible) { enabled = false; HamiltonPlugin hamiltonPlugin = instance; if (hamiltonPlugin != null) { ((BaseUnityPlugin)hamiltonPlugin).Logger.LogWarning((object)("Hamilton cannot be enabled yet. Waiting for: " + incompatibleLobbyMembers)); } } hasLobbyEnabledState = true; lobbyEnabledState = enabled; lastObservedLobbyEnabledVersion = Time.unscaledTime.ToString("R"); Lobby val = default(Lobby); if (BNetworkManager.TryGetSteamLobby(ref val)) { ((Lobby)(ref val)).SetData("codex_hamilton_enabled", enabled ? "1" : "0"); ((Lobby)(ref val)).SetData("codex_hamilton_enabled_version", lastObservedLobbyEnabledVersion); } ApplyServerEnabledState(enabled); instance?.RefreshHamiltonRulesToggle(); } private static ulong GetPlayerGuid(PlayerInfo player) { if (!((Object)(object)((player != null) ? player.PlayerId : null) != (Object)null)) { return 0uL; } return player.PlayerId.Guid; } private static void ApplyServerEnabledState(bool enabled) { if (!NetworkServer.active) { return; } PlayerInventory[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (PlayerInventory val in array) { if (!((Object)(object)val == (Object)null)) { if (enabled) { EnsureReservedPistol(val); } else { RemoveReservedPistol(val); } } } } private void TryInstallHamiltonRulesToggle() { if ((Object)(object)hamiltonRulesDropdown != (Object)null || Time.unscaledTime < nextRulesUiCheckTime) { return; } nextRulesUiCheckTime = Time.unscaledTime + 1f; MatchSetupRules val = FindMatchSetupRules(); if ((Object)(object)val == (Object)null) { return; } DropdownOption val2 = (((Object)(object)val.hitOtherPlayers != (Object)null) ? val.hitOtherPlayers : val.homingShots); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).transform == (Object)null) && !((Object)(object)((Component)val2).transform.parent == (Object)null)) { GameObject val3 = Object.Instantiate(((Component)val2).gameObject, ((Component)val2).transform.parent); ((Object)val3).name = "HamiltonRulesDropdown"; val3.transform.SetSiblingIndex(((Component)val2).transform.GetSiblingIndex() + 1); LocalizeStringEvent[] componentsInChildren = val3.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } hamiltonRulesDropdown = val3.GetComponent(); if ((Object)(object)hamiltonRulesDropdown == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not create Hamilton custom rules dropdown."); Object.Destroy((Object)(object)val3); return; } hamiltonRulesDropdown.SetOptions(new List { "On", "Off" }); hamiltonRulesDropdown.Initialize((Action)OnHamiltonRulesDropdownChanged, DropdownValueFromEnabled(IsHamiltonEnabled())); SetHamiltonRulesRowText(); RefreshHamiltonRulesToggle(); RebuildRulesLayout(((Component)val2).transform.parent); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Added Hamilton toggle to custom rules."); } } private static MatchSetupRules FindMatchSetupRules() { if (SingletonNetworkBehaviour.HasInstance) { return SingletonNetworkBehaviour.Instance; } if (SingletonBehaviour.HasInstance) { return SingletonBehaviour.Instance; } return Object.FindFirstObjectByType((FindObjectsInactive)1); } private static void RebuildRulesLayout(Transform parent) { RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { val = ((Component)parent).GetComponent(); } if ((Object)(object)val != (Object)null) { LayoutRebuilder.ForceRebuildLayoutImmediate(val); } } private void SetHamiltonRulesRowText() { if ((Object)(object)hamiltonRulesDropdown == (Object)null) { return; } TMP_Text captionText = hamiltonRulesDropdown.captionText; TMP_Text[] componentsInChildren = ((Component)hamiltonRulesDropdown).GetComponentsInChildren(true); foreach (TMP_Text val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)captionText) && !val.text.Equals("On", StringComparison.OrdinalIgnoreCase) && !val.text.Equals("Off", StringComparison.OrdinalIgnoreCase)) { val.text = GetHamiltonRulesLabel(); break; } } } private static string GetHamiltonRulesLabel() { if (NetworkServer.active && !allLobbyMembersCompatible) { return "Hamilton Needs Update"; } return "Hamilton"; } private void RefreshHamiltonRulesToggle() { if (!((Object)(object)hamiltonRulesDropdown == (Object)null)) { suppressHamiltonDropdownChanged = true; hamiltonRulesDropdown.valueWithoutNotify = DropdownValueFromEnabled(IsHamiltonEnabled()); suppressHamiltonDropdownChanged = false; hamiltonRulesDropdown.Interactable = NetworkServer.active && allLobbyMembersCompatible && IsHamiltonAllowedForCurrentPreset(); SetHamiltonRulesRowText(); } } private void OnHamiltonRulesDropdownChanged() { if (!suppressHamiltonDropdownChanged && !((Object)(object)hamiltonRulesDropdown == (Object)null)) { if (!NetworkServer.active) { RefreshHamiltonRulesToggle(); } else { PublishSteamLobbyEnabledState(EnabledFromDropdownValue(hamiltonRulesDropdown.value)); } } } private void TryEnsureLocalPlayerHasPistol() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } PlayerInventory localPlayerInventory = GameManager.LocalPlayerInventory; if ((Object)(object)localPlayerInventory == (Object)null || !((NetworkBehaviour)localPlayerInventory).isLocalPlayer) { return; } EnsureSlotCount(localPlayerInventory); int index; if (TryGetSlot(localPlayerInventory, 0, out var slot) && IsPistol(slot)) { if (autoSelectPistolConfig.Value && localPlayerInventory.EquippedItemIndex != 0 && localPlayerInventory.CanSelectItemAt(0)) { localPlayerInventory.TrySelectItemSlot(0); } } else if (TryFindPistolSlot(localPlayerInventory, out index) && index != 0) { MovePistolToReservedSlot(localPlayerInventory, index); } else { giveItemToLocalPlayerMethod?.Invoke(localPlayerInventory, new object[1] { (object)(ItemType)2 }); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Granted local player a dueling pistol."); } } private static bool TryFindPistolSlot(PlayerInventory inventory, out int index) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) index = -1; SyncList slots = GetSlots(inventory); if (slots == null) { return false; } for (int i = 0; i < slots.Count; i++) { if (IsPistol(slots[i])) { index = i; return true; } } return false; } private static bool TryGetSlot(PlayerInventory inventory, int index, out InventorySlot slot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) slot = InventorySlot.Empty; SyncList slots = GetSlots(inventory); if (slots == null || index < 0 || index >= slots.Count) { return false; } slot = slots[index]; return true; } private static bool IsPistol(InventorySlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) if ((int)slot.itemType == 2) { return slot.remainingUses > 0; } return false; } private static bool IsEmpty(InventorySlot slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if ((int)slot.itemType != 0) { return slot.remainingUses <= 0; } return true; } private static bool IsReservedPistolSlot(PlayerInventory inventory, int index) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (IsHamiltonEnabled() && index == 0 && TryGetSlot(inventory, index, out var slot)) { return IsPistol(slot); } return false; } private static SyncList GetSlots(PlayerInventory inventory) { return inventorySlotsField?.GetValue(inventory) as SyncList; } private static void EnsureSlotCount(PlayerInventory inventory) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) SyncList slots = GetSlots(inventory); if (slots != null) { while (slots.Count < 4) { slots.Add(InventorySlot.Empty); } } } private static void MovePistolToReservedSlot(PlayerInventory inventory, int existingPistolIndex) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) SyncList slots = GetSlots(inventory); if (slots != null && existingPistolIndex >= 0 && existingPistolIndex < slots.Count) { EnsureSlotCount(inventory); InventorySlot val = slots[0]; slots[0] = new InventorySlot((ItemType)2, 1); if (existingPistolIndex != 0) { slots[existingPistolIndex] = (IsEmpty(val) ? InventorySlot.Empty : val); } } } private static void EnsureReservedPistol(PlayerInventory inventory) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0048: Unknown result type (might be due to invalid IL or missing references) if (!IsHamiltonEnabled()) { return; } SyncList slots = GetSlots(inventory); if (slots == null) { return; } EnsureSlotCount(inventory); InventorySlot val = slots[0]; if (IsPistol(val)) { return; } if (TryFindPistolSlot(inventory, out var index) && index != 0) { MovePistolToReservedSlot(inventory, index); return; } if (!IsEmpty(val)) { MoveReservedItemToFirstNormalSlot(slots, val); } slots[0] = new InventorySlot((ItemType)2, 1); } private static void RemoveReservedPistol(PlayerInventory inventory) { //IL_0016: 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) SyncList slots = GetSlots(inventory); if (slots != null && 0 < slots.Count && IsPistol(slots[0])) { slots[0] = InventorySlot.Empty; } } private static void RemoveHamiltonPistolsFromAllPlayers() { PlayerInventory[] array = Object.FindObjectsByType((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { RemoveAllPistols(array[i]); } } private static void RemoveAllPistols(PlayerInventory inventory) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) SyncList slots = GetSlots(inventory); if (slots == null) { return; } for (int i = 0; i < slots.Count; i++) { if (IsPistol(slots[i])) { slots[i] = InventorySlot.Empty; } } } private static void MoveReservedItemToFirstNormalSlot(SyncList slots, InventorySlot reservedSlot) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) for (int i = 1; i < 4; i++) { if (IsEmpty(slots[i])) { slots[i] = reservedSlot; break; } } } private static bool TryGetWeightedRandomNonPistolItem(ItemPool pool, out ItemType item) { //IL_0055: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Invalid comparison between Unknown and I4 //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected I4, but got Unknown item = (ItemType)0; if (!(itemPoolSpawnChancesField?.GetValue(pool) is Array { Length: not 0 } array)) { return false; } float num = 0f; foreach (object item2 in array) { if (TryGetSpawnChanceFields(item2, out var itemField, out var weightField)) { ItemType val = (ItemType)itemField.GetValue(item2); float num2 = (float)weightField.GetValue(item2); if ((int)val != 2 && (int)val != 0 && num2 > 0f) { num += num2; } } } if (num <= 0f) { item = (ItemType)1; return true; } float num3 = Random.value * num; foreach (object item3 in array) { if (!TryGetSpawnChanceFields(item3, out var itemField2, out var weightField2)) { continue; } ItemType val2 = (ItemType)itemField2.GetValue(item3); float num4 = (float)weightField2.GetValue(item3); if ((int)val2 != 2 && (int)val2 != 0 && !(num4 <= 0f)) { num3 -= num4; if (num3 <= 0f) { item = (ItemType)(int)val2; return true; } } } item = (ItemType)1; return true; } private static bool TryGetSpawnChanceFields(object spawnChance, out FieldInfo itemField, out FieldInfo weightField) { itemField = null; weightField = null; if (spawnChance == null) { return false; } Type type = spawnChance.GetType(); if (!spawnChanceItemFields.TryGetValue(type, out itemField)) { itemField = AccessTools.Field(type, "item"); spawnChanceItemFields[type] = itemField; } if (!spawnChanceWeightFields.TryGetValue(type, out weightField)) { weightField = AccessTools.Field(type, "spawnChanceWeight"); spawnChanceWeightFields[type] = weightField; } if (itemField != null) { return weightField != null; } return false; } private static ShotOutcome RollShotOutcome() { float num = Mathf.Clamp01(instance?.backfireChanceConfig.Value ?? 0f); float num2 = Mathf.Clamp01(instance?.jamChanceConfig.Value ?? 0f); float value = Random.value; if (value < num) { return ShotOutcome.Backfire; } if (value < num + num2) { return ShotOutcome.Jam; } return ShotOutcome.Normal; } private static void Backfire(PlayerInventory inventory) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) PlayerInfo playerInfo = inventory.PlayerInfo; PlayerMovement val = ((playerInfo != null) ? playerInfo.Movement : null); Hittable val2 = ((playerInfo != null) ? playerInfo.AsHittable : null); if (!((Object)(object)playerInfo == (Object)null) && !((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { Vector3 val3 = -((Component)playerInfo).transform.forward + Vector3.up * 0.35f; Vector3 normalized = ((Vector3)(ref val3)).normalized; Vector3 val4 = ((Component)val2).transform.InverseTransformPoint(inventory.GetDuelingPistolBarrelEndPosition()); Vector3 val5 = normalized * 12f; ItemUseId val6 = CreateSyntheticItemUseId(playerInfo, (ItemType)2); bool flag = default(bool); val.TryKnockOut(playerInfo, (KnockoutType)4, false, val4, 0f, val5, false, val6, true, true, ref flag); HamiltonPlugin hamiltonPlugin = instance; if (hamiltonPlugin != null) { ((BaseUnityPlugin)hamiltonPlugin).Logger.LogInfo((object)"Dueling pistol backfired."); } } } private static ItemUseId CreateSyntheticItemUseId(PlayerInfo player, ItemType itemType) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) return new ItemUseId(((Object)(object)((player != null) ? player.PlayerId : null) != (Object)null) ? player.PlayerId.Guid : 0, ++syntheticItemUseIndex, itemType); } private static void QueueReloadJam(PlayerInventory inventory) { if ((Object)(object)inventory != (Object)null) { pendingReloadJams.Add(inventory); } } private static void ApplyReloadJam(PlayerInventory inventory) { if ((Object)(object)inventory == (Object)null || !pendingReloadJams.Remove(inventory)) { return; } float num = Mathf.Max(0f, instance?.jamReloadDelaySecondsConfig.Value ?? 0f); if (!(num <= 0f) && !(itemUseTimestampField == null)) { itemUseTimestampField.SetValue(inventory, Time.timeAsDouble + (double)num); HamiltonPlugin hamiltonPlugin = instance; if (hamiltonPlugin != null) { ((BaseUnityPlugin)hamiltonPlugin).Logger.LogInfo((object)$"Dueling pistol jammed; reload delayed by {num:0.##} seconds."); } } } } }