Decompiled source of GunGame v1.2.4
plugins/GunGameMod.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
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.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FishNet; using FishNet.Connection; using FishNet.Managing; using FishNet.Managing.Scened; using FishNet.Object; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("GunGameMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+87e1819de472829ee4359e1459224afd33ef4312")] [assembly: AssemblyProduct("GunGameMod")] [assembly: AssemblyTitle("GunGameMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 GunGameMod { public static class GunGamePatches { private static Harmony _harmony; private static Dictionary<int, int> _killsPerPlayer = new Dictionary<int, int>(); private static HashSet<int> _waitingForSetStartTime = new HashSet<int>(); private static HashSet<string> _pendingPlaceableReplace = new HashSet<string>(); private static Dictionary<int, GameObject> _playerRagdolls = new Dictionary<int, GameObject>(); private static bool _winSequenceInProgress = false; private static HashSet<int> _respawnInProgress = new HashSet<int>(); private static Dictionary<int, int> _respawnRequestSeq = new Dictionary<int, int>(); private static HashSet<int> _playersAwaitingRespawn = new HashSet<int>(); private static Dictionary<int, float> _nextRespawnRecoveryTime = new Dictionary<int, float>(); private static float _nextRespawnWatchdogTime; private static Dictionary<int, float> _lastKillAwardTime = new Dictionary<int, float>(); private static Dictionary<int, int> _lastKillAwardCount = new Dictionary<int, int>(); private static Dictionary<string, float> _suppressThrowableOpenUntil = new Dictionary<string, float>(); private static HashSet<int> _minigunDropQueued = new HashSet<int>(); private const float MultiKillAwardSuppressSeconds = 0.35f; private const float ThrowableOpenSuppressSeconds = 0.35f; private const int MaxRespawnAttempts = 3; private const float RespawnValidationSeconds = 2f; private const float RespawnRetryDelaySeconds = 0.25f; private const float RespawnWatchdogIntervalSeconds = 0.5f; private const float RespawnRecoveryDelaySeconds = 1f; private static MethodInfo _miCmdRespawnLogic; private static MethodInfo _miRoundWon; private static FieldInfo _fiSpawnedObject; private static MethodInfo _miRpcLogic_DropObjectServer; private static MethodInfo _miRpcLogic_DropObjectObserver; private static MethodInfo _miMatchLogsSendToAll; private static FieldInfo _fiRightIdlePosition; private static FieldInfo _fiRigBuilder; private static Type _particleSystemType; public static void Apply() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown if (_harmony != null) { return; } _harmony = new Harmony("com.modder.gungame.patches"); CacheReflectionMethods(); try { PatchPrefix(typeof(GameManager), "WaitForDraw", "GameManager_WaitForDraw_Prefix"); PatchPrefix(typeof(GameManager), "RpcLogic___PlayerDied_3316948804", "GameManager_RpcLogic_PlayerDied_Prefix"); PatchPrefix(typeof(RoundManager), "CmdEndRound", "RoundManager_CmdEndRound_Prefix"); PatchPrefix(typeof(GameManager), "SetStartTime", "GameManager_SetStartTime_Prefix"); PatchPrefix(typeof(PlayerManager), "RpcLogic___SetPlayerMove_1140765316", "PlayerManager_RpcLogic_SetPlayerMove_Prefix"); PatchPrefix(typeof(KillCam), "Update", "KillCam_Update_Prefix"); PatchPrefix(typeof(ItemBehaviour), "Start", "ItemBehaviour_Start_Prefix"); PatchPostfixReflected(typeof(PlayerPickup), "RpcLogic___SetObjectInHandObserver_46969756", "PlayerPickup_SetObjectInHandObserver_Postfix"); PatchPrefix(typeof(ItemBehaviour), "StickOnGround", "ItemBehaviour_StickOnGround_Prefix"); PatchPrefix(typeof(Spawner), "Update", "Spawner_Update_Prefix"); PatchPrefix(typeof(PlayerPickup), "RightHandFix", "PlayerPickup_RightHandFix_Prefix"); PatchPrefix(typeof(PlayerPickup), "LeftHandFix", "PlayerPickup_LeftHandFix_Prefix"); PatchPrefix(typeof(PlayerPickup), "HandsReconstruct", "PlayerPickup_HandsReconstruct_Prefix"); PatchPrefix(typeof(PlayerPickup), "RightHandDrop", "PlayerPickup_RightHandDrop_Prefix"); PatchPrefix(typeof(PlayerPickup), "RightHandPickup", "PlayerPickup_RightHandPickup_Prefix"); PatchPrefix(typeof(PlayerPickup), "SwitchWeapons", "PlayerPickup_SwitchWeapons_Prefix"); PatchPrefix(typeof(PlayerPickup), "LeftHandPickup", "PlayerPickup_LeftHandPickup_Prefix"); if (_miRpcLogic_DropObjectServer != null) { _harmony.Patch((MethodBase)_miRpcLogic_DropObjectServer, new HarmonyMethod(typeof(GunGamePatches).GetMethod("PlayerPickup_RpcLogic_DropObjectServer_Prefix", BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (_miRpcLogic_DropObjectObserver != null) { _harmony.Patch((MethodBase)_miRpcLogic_DropObjectObserver, new HarmonyMethod(typeof(GunGamePatches).GetMethod("PlayerPickup_RpcLogic_DropObjectObserver_Prefix", BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } PatchPrefix(typeof(PauseManager), "StartRoundDelay", "PauseManager_StartRoundDelay_Prefix"); PatchPrefix(typeof(ProximityMine), "KillShockWave", "ProximityMine_KillShockWave_Prefix"); PatchPrefix(typeof(Claymore), "KillShockWave", "Claymore_KillShockWave_Prefix"); PatchPostfix(typeof(Minigun), "Update", "Minigun_Update_Postfix"); PatchPrefix(typeof(DualLauncher), "SetBool", "DualLauncher_SetBool_Prefix"); PatchPostfix(typeof(WeaponHandSpawner), "RpcLogic___SpawnObject_2587446063", "WeaponHandSpawner_SpawnObject_Postfix"); PatchPrefix(typeof(MatchLogs), "RpcLogic___RpcSendChatLine_3615296227", "MatchLogs_RpcSendChatLine_Prefix"); PatchPostfix(typeof(PlayerManager), "SpawnPlayer", "PlayerManager_SpawnPlayer_Postfix", new Type[2] { typeof(int), typeof(int) }); PatchPostfix(typeof(PlayerHealth), "RpcLogic___ExplodeForAll_576886416", "PlayerHealth_ExplodeForAll_Postfix"); PatchPostfixReflected(typeof(PlayerValues), "sync___set_value_playerClient", "PlayerValues_SetPlayerClient_Postfix"); PatchPrefix(typeof(DamageZone), "OnEnable", "DamageZone_OnEnable_Prefix"); PatchPrefix(typeof(FirstPersonController), "OnTriggerStay", "FirstPersonController_OnTriggerStay_Prefix"); } catch { } } private static void CacheReflectionMethods() { _miCmdRespawnLogic = typeof(PlayerManager).GetMethod("RpcLogic___CmdRespawn_2166136261", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (_miCmdRespawnLogic == null) { ManualLogSource log = GunGamePlugin.Log; if (log != null) { log.LogError((object)"[GunGame Respawn] native PlayerManager respawn method was not found"); } } _miRoundWon = typeof(GameManager).GetMethod("RoundWon", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _fiSpawnedObject = typeof(PlayerManager).GetField("SpawnedObject", BindingFlags.Instance | BindingFlags.NonPublic); _miRpcLogic_DropObjectServer = typeof(PlayerPickup).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.Contains("RpcLogic___DropObjectServer")); _miRpcLogic_DropObjectObserver = typeof(PlayerPickup).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.Contains("RpcLogic___DropObjectObserver")); _miMatchLogsSendToAll = typeof(MatchLogs).GetMethod("RpcSendChatLineToAllObservers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _fiRightIdlePosition = typeof(PlayerPickup).GetField("RightIdlePosition", BindingFlags.Instance | BindingFlags.NonPublic); _fiRigBuilder = typeof(PlayerPickup).GetField("RigBuilder", BindingFlags.Instance | BindingFlags.NonPublic); } private static void PatchPrefix(Type type, string methodName, string patchName, Type[] paramTypes = null) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown MethodInfo methodInfo = ((paramTypes == null) ? type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null)); if (!(methodInfo == null)) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(GunGamePatches).GetMethod(patchName, BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void PatchPostfix(Type type, string methodName, string patchName, Type[] paramTypes = null) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown MethodInfo methodInfo = ((paramTypes == null) ? type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null)); if (!(methodInfo == null)) { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(GunGamePatches).GetMethod(patchName, BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void PatchPostfixReflected(Type type, string methodName, string patchName) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { _harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(GunGamePatches).GetMethod(patchName, BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } public static void ResetState() { _killsPerPlayer.Clear(); _waitingForSetStartTime.Clear(); _pendingPlaceableReplace.Clear(); _playerRagdolls.Clear(); _winSequenceInProgress = false; _respawnInProgress.Clear(); _respawnRequestSeq.Clear(); _playersAwaitingRespawn.Clear(); _nextRespawnRecoveryTime.Clear(); _nextRespawnWatchdogTime = 0f; _lastKillAwardTime.Clear(); _lastKillAwardCount.Clear(); _suppressThrowableOpenUntil.Clear(); _minigunDropQueued.Clear(); } public static int GetCurrentWeaponIndex(int playerId) { int progressStage = GetProgressStage(playerId); int orderedWeaponCount = GunGamePlugin.GetOrderedWeaponCount(); if (orderedWeaponCount <= 0) { return 0; } return (progressStage - 1) % orderedWeaponCount; } private static int GetProgressStage(int playerId) { if (!_killsPerPlayer.TryGetValue(playerId, out var value) || value <= 0) { return 1; } return value; } private static int GetCompletedKillCount(int playerId) { return GetProgressStage(playerId) - 1; } public static bool GameManager_WaitForDraw_Prefix(ref IEnumerator __result) { if (!GunGamePlugin.MatchOver) { __result = EmptyCoroutine(); return false; } return true; } public static bool KillCam_Update_Prefix() { return !GunGamePlugin.Enabled.Value; } private static IEnumerator EmptyCoroutine() { yield break; } public static bool GameManager_RpcLogic_PlayerDied_Prefix(int playerId) { if (!GunGamePlugin.Enabled.Value) { return true; } if (GunGamePlugin.MatchOver) { return false; } try { if ((Object)(object)InstanceFinder.NetworkManager != (Object)null && InstanceFinder.NetworkManager.IsServer) { PlayerPickup val = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)val != (Object)null) { GunGameWeaponManager.DespawnHeldWeapon(val); } ClearPlacedExplosivesForPlayer(playerId); GunGameWeaponManager.QueueWeaponUpgrade(playerId, GetCurrentWeaponIndex(playerId)); } if (GameManager.Instance?.alivePlayers != null && !GameManager.Instance.alivePlayers.Contains(playerId)) { GameManager.Instance.alivePlayers.Add(playerId); } if ((Object)(object)InstanceFinder.NetworkManager == (Object)null || !InstanceFinder.NetworkManager.IsServer) { return true; } int num = FindKillerId(playerId); if (num >= 0 && num != playerId) { float unscaledTime = Time.unscaledTime; int progressStage = GetProgressStage(num); int completedKillCount = GetCompletedKillCount(num); int num2 = progressStage + 1; if (progressStage > 1 && _lastKillAwardTime.TryGetValue(num, out var value) && unscaledTime - value <= 0.35f && _lastKillAwardCount.TryGetValue(num, out var value2) && value2 == progressStage) { string playerName = GetPlayerName(num); string playerName2 = GetPlayerName(playerId); int orderedWeaponCount = GunGamePlugin.GetOrderedWeaponCount(); GameObject orderedWeaponPrefab = GunGamePlugin.GetOrderedWeaponPrefab((orderedWeaponCount > 0) ? ((completedKillCount - 1 + orderedWeaponCount) % orderedWeaponCount) : 0); string text = ((orderedWeaponPrefab != null) ? ((Object)orderedWeaponPrefab).name : null) ?? "Unknown"; BroadcastChat($"<b><color=yellow>[Gun Game]</color></b> <b>{playerName}</b> <color=red>killed</color> <b>{playerName2}</b> with <b><color=white>{text}</color></b> <color=#00FFFF>[{completedKillCount}/{GunGamePlugin.KillsToWin.Value}]</color>"); } else { _lastKillAwardTime[num] = unscaledTime; _lastKillAwardCount[num] = num2; _killsPerPlayer[num] = num2; int num3 = num2 - 1; int orderedWeaponCount2 = GunGamePlugin.GetOrderedWeaponCount(); int weaponIndex = ((orderedWeaponCount2 > 0) ? ((num2 - 1) % orderedWeaponCount2) : 0); GameObject orderedWeaponPrefab2 = GunGamePlugin.GetOrderedWeaponPrefab((orderedWeaponCount2 > 0) ? ((num2 - 2 + orderedWeaponCount2) % orderedWeaponCount2) : 0); string text2 = ((orderedWeaponPrefab2 != null) ? ((Object)orderedWeaponPrefab2).name : null) ?? "Unknown"; string playerName3 = GetPlayerName(num); string playerName4 = GetPlayerName(playerId); BroadcastChat((num3 >= GunGamePlugin.KillsToWin.Value) ? ("<b><color=yellow>[Gun Game]</color></b> <b>" + playerName3 + "</b> <color=red>killed</color> <b>" + playerName4 + "</b> with <b><color=white>" + text2 + "</color></b> — <b><color=yellow>WINS THE ROUND!</color></b>") : $"<b><color=yellow>[Gun Game]</color></b> <b>{playerName3}</b> <color=red>killed</color> <b>{playerName4}</b> with <b><color=white>{text2}</color></b> <color=#00FFFF>[{num3}/{GunGamePlugin.KillsToWin.Value}]</color>"); GunGameWeaponManager.GiveWeaponToPlayer(num, weaponIndex); ((MonoBehaviour)GameManager.Instance).StartCoroutine(DelayedKillWeaponGive(num, weaponIndex)); switch (text2) { case "ProximityMine": case "APMine": case "Claymore": ClearPlacedExplosivesForPlayer(num); break; } if (num3 >= GunGamePlugin.KillsToWin.Value && !_winSequenceInProgress) { _winSequenceInProgress = true; GunGamePlugin.MatchOver = true; ((MonoBehaviour)GameManager.Instance).StartCoroutine(WinSequenceCoroutine(num)); return false; } } } else { string playerName5 = GetPlayerName(playerId); BroadcastChat("<b><color=yellow>[Gun Game]</color></b> <b>" + playerName5 + "</b> <color=#888888>killed themselves</color>"); } ScheduleRespawn(playerId); } catch { try { ScheduleRespawn(playerId); } catch { } } return false; } public static void PlayerManager_SpawnPlayer_Postfix(PlayerManager __instance) { if (!GunGamePlugin.Enabled.Value || (Object)(object)__instance == (Object)null) { return; } ClientInstance component = ((Component)__instance).GetComponent<ClientInstance>(); if ((Object)(object)component == (Object)null) { return; } int playerId = component.PlayerId; if (playerId < 0) { return; } if ((Object)(object)InstanceFinder.NetworkManager != (Object)null && InstanceFinder.NetworkManager.IsServer) { int num; if (!_respawnInProgress.Contains(playerId)) { num = (GunGameWeaponManager.HasPendingWeapon(playerId) ? 1 : 0); if (num == 0) { if (_killsPerPlayer.ContainsKey(playerId)) { _killsPerPlayer.Remove(playerId); } GunGameWeaponManager.ClearPendingForPlayer(playerId); } } else { num = 1; } if (GameManager.Instance?.alivePlayers != null && !GameManager.Instance.alivePlayers.Contains(playerId)) { GameManager.Instance.alivePlayers.Add(playerId); } _waitingForSetStartTime.Add(playerId); if (num == 0 && GunGamePlugin.GetOrderedWeaponCount() > 0) { GunGameWeaponManager.GiveWeaponToPlayer(playerId, 0); GameManager instance = GameManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(DelayedInitialSpawnFallback(playerId)); } } } if (((NetworkBehaviour)__instance).IsOwner) { if ((Object)(object)PauseManager.Instance != (Object)null) { PauseManager.Instance.startRound = false; } GameManager instance2 = GameManager.Instance; if (instance2 != null) { ((MonoBehaviour)instance2).StartCoroutine(KeepPlayerMovable(__instance, 4f)); } } } public static void GameManager_SetStartTime_Prefix(ref float serverTimeTillStart) { if (GunGamePlugin.Enabled.Value && !GunGamePlugin.MatchOver) { serverTimeTillStart = 0f; } } public static bool PlayerManager_RpcLogic_SetPlayerMove_Prefix(PlayerManager __instance, bool state) { if (!GunGamePlugin.Enabled.Value || GunGamePlugin.MatchOver) { return true; } ClientInstance component = ((Component)__instance).GetComponent<ClientInstance>(); if ((Object)(object)component == (Object)null) { return true; } int playerId = component.PlayerId; if (playerId < 0) { return true; } if (!state && _waitingForSetStartTime.Contains(playerId)) { _waitingForSetStartTime.Remove(playerId); try { if ((Object)(object)__instance.player != (Object)null) { __instance.player.sync___set_value_canMove(true, true); __instance.player.startOfRound = false; } if ((Object)(object)PauseManager.Instance != (Object)null) { PauseManager.Instance.startRound = false; PauseManager.Instance.pause = false; PauseManager.Instance.otherPauseBools = false; } } catch { } return false; } return true; } public static bool ItemBehaviour_Start_Prefix(ItemBehaviour __instance) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } __instance.dispenserStart = true; Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.isKinematic = true; component.useGravity = false; component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; } return true; } public static void PlayerPickup_SetObjectInHandObserver_Postfix(PlayerPickup __instance, GameObject obj) { if (!((Object)(object)obj == (Object)null)) { ItemBehaviour component = obj.GetComponent<ItemBehaviour>(); if ((Object)(object)component != (Object)null) { component.dispenserStart = false; } } } public static bool ItemBehaviour_StickOnGround_Prefix(ItemBehaviour __instance) { if ((Object)(object)__instance.cam == (Object)null) { return false; } return true; } public static bool Spawner_Update_Prefix() { return !GunGamePlugin.Enabled.Value; } public static bool PlayerPickup_RightHandFix_Prefix(PlayerPickup __instance) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!GunGamePlugin.Enabled.Value) { return true; } if (__instance.sync___get_value_hasObjectInHand() && (Object)(object)__instance.sync___get_value_objInHand() == (Object)null) { __instance.sync___set_value_hasObjectInHand(false, true); return false; } GameObject val = __instance.sync___get_value_objInHand(); if ((Object)(object)val == (Object)null) { return true; } if (val.layer == 7 || val.layer == 9) { MethodInfo setObjectInHandObserverLogic = GunGameWeaponManager.SetObjectInHandObserverLogic; if (setObjectInHandObserverLogic != null) { try { setObjectInHandObserverLogic.Invoke(__instance, new object[5] { val, val.transform.position, val.transform.rotation, ((Component)__instance).gameObject, true }); } catch { } } return false; } return true; } public static bool PlayerPickup_LeftHandFix_Prefix(PlayerPickup __instance) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!GunGamePlugin.Enabled.Value) { return true; } if (__instance.sync___get_value_hasObjectInLeftHand() && (Object)(object)__instance.sync___get_value_objInLeftHand() == (Object)null) { __instance.sync___set_value_hasObjectInLeftHand(false, true); return false; } GameObject val = __instance.sync___get_value_objInLeftHand(); if ((Object)(object)val == (Object)null) { return true; } if (val.layer == 7 || val.layer == 9) { MethodInfo setObjectInHandObserverLogic = GunGameWeaponManager.SetObjectInHandObserverLogic; if (setObjectInHandObserverLogic != null) { try { setObjectInHandObserverLogic.Invoke(__instance, new object[5] { val, val.transform.position, val.transform.rotation, ((Component)__instance).gameObject, false }); } catch { } } return false; } return true; } public static bool PlayerPickup_RightHandDrop_Prefix(PlayerPickup __instance) { if (!GunGamePlugin.Enabled.Value) { return true; } GameObject val = __instance.sync___get_value_objInHand(); if (__instance.sync___get_value_hasObjectInHand() && ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent<ItemBehaviour>() == (Object)null)) { __instance.sync___set_value_hasObjectInHand(false, true); __instance.sync___set_value_objInHand((GameObject)null, true); return false; } PlayerHealth componentInParent = ((Component)__instance).GetComponentInParent<PlayerHealth>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.sync___get_value_isKilled()) { return false; } return true; } public static bool PlayerPickup_HandsReconstruct_Prefix(PlayerPickup __instance) { if (!GunGamePlugin.Enabled.Value || (Object)(object)__instance == (Object)null) { return true; } try { GameObject val = __instance.sync___get_value_objInLeftHand(); GameObject val2 = __instance.sync___get_value_objInHand(); if ((Object)(object)val == (Object)null || (Object)(object)val2 != (Object)null) { return true; } object? obj = _fiRightIdlePosition?.GetValue(__instance); Transform rightIKTarget = (Transform)((obj is Transform) ? obj : null); ItemBehaviour component = val.GetComponent<ItemBehaviour>(); __instance.SetRightIKTarget(rightIKTarget); __instance.SetLeftIKTarget(((Object)(object)component != (Object)null) ? component.gripLeft : null); object obj2 = _fiRigBuilder?.GetValue(__instance); obj2?.GetType().GetMethod("Build", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj2, null); return false; } catch { return true; } } public static bool PlayerPickup_RightHandPickup_Prefix() { return !GunGamePlugin.Enabled.Value; } public static bool PlayerPickup_SwitchWeapons_Prefix() { return !GunGamePlugin.Enabled.Value; } public static bool PlayerPickup_LeftHandPickup_Prefix() { return !GunGamePlugin.Enabled.Value; } public static bool PlayerPickup_RpcLogic_DropObjectServer_Prefix(PlayerPickup __instance, GameObject obj, bool rightHand) { if (!GunGamePlugin.Enabled.Value) { return true; } if (!InstanceFinder.NetworkManager.IsServer) { return true; } string droppedName = (((Object)(object)obj != (Object)null) ? ((Object)obj).name.Replace("(Clone)", "").Trim() : ""); bool flag = IsPlaceableDrop(droppedName); bool flag2 = IsThrowableDrop(droppedName); try { int pickupPlayerId = GetPickupPlayerId(__instance); int weaponIndex = ((pickupPlayerId >= 0) ? GetCurrentWeaponIndex(pickupPlayerId) : 0); bool rightHand2; bool flag3 = TryGetHeldObjectHand(__instance, obj, out rightHand2); if (IsUnsafeDropObject(obj) || IsDeathOrRespawnDrop(__instance, pickupPlayerId)) { if (flag3) { ClearHeldHand(__instance, rightHand2); } return false; } if ((flag || flag2) && (Object)(object)obj != (Object)null) { obj.transform.SetParent((Transform)null); } if (!flag3) { return false; } if (pickupPlayerId >= 0 && GunGameWeaponManager.IsDropProtected(pickupPlayerId) && IsProtectedHeldDrop(__instance, obj, rightHand2)) { return false; } object obj2 = ((object)GameManager.Instance) ?? ((object)GunGamePlugin.Instance); if (obj2 != null) { ((MonoBehaviour)obj2).StartCoroutine(DeferredDropCleanup(__instance, obj, flag, flag2, pickupPlayerId, weaponIndex, rightHand2)); } } catch { } return false; } public static bool PlayerPickup_RpcLogic_DropObjectObserver_Prefix(PlayerPickup __instance, GameObject obj, bool rightHand) { if (!GunGamePlugin.Enabled.Value) { return true; } try { int pickupPlayerId = GetPickupPlayerId(__instance); if (IsUnsafeDropObject(obj) || IsDeathOrRespawnDrop(__instance, pickupPlayerId)) { return false; } } catch { return false; } return true; } private static int GetPickupPlayerId(PlayerPickup pickup) { try { int? obj; if (pickup == null) { obj = null; } else { PlayerValues playerValues = pickup.playerValues; obj = ((playerValues == null) ? ((int?)null) : playerValues.sync___get_value_playerClient()?.PlayerId); } return obj ?? (-1); } catch { return -1; } } private static bool IsUnsafeDropObject(GameObject obj) { if ((Object)(object)obj == (Object)null) { return true; } try { return (Object)(object)obj.GetComponent<ItemBehaviour>() == (Object)null || (Object)(object)obj.GetComponent<Weapon>() == (Object)null; } catch { return true; } } private static bool IsDeathOrRespawnDrop(PlayerPickup pickup, int playerId) { if (playerId >= 0 && (_playersAwaitingRespawn.Contains(playerId) || _respawnInProgress.Contains(playerId))) { return true; } try { if ((Object)(object)pickup == (Object)null || !((Component)pickup).gameObject.activeInHierarchy) { return true; } PlayerHealth componentInParent = ((Component)pickup).GetComponentInParent<PlayerHealth>(); if ((Object)(object)componentInParent == (Object)null) { return false; } return componentInParent.sync___get_value_health() <= 0f || componentInParent.sync___get_value_isKilled(); } catch { return true; } } private static void ClearHeldHand(PlayerPickup pickup, bool rightHand) { if ((Object)(object)pickup == (Object)null) { return; } try { if (rightHand) { pickup.sync___set_value_hasObjectInHand(false, true); pickup.sync___set_value_objInHand((GameObject)null, true); } else { pickup.sync___set_value_hasObjectInLeftHand(false, true); pickup.sync___set_value_objInLeftHand((GameObject)null, true); } } catch { } } private static bool TryGetHeldObjectHand(PlayerPickup pickup, GameObject obj, out bool rightHand) { rightHand = true; if ((Object)(object)pickup == (Object)null || (Object)(object)obj == (Object)null) { return false; } if ((Object)(object)pickup.sync___get_value_objInHand() == (Object)(object)obj) { return true; } if (pickup.sync___get_value_hasObjectInLeftHand() && (Object)(object)pickup.sync___get_value_objInLeftHand() == (Object)(object)obj) { rightHand = false; return true; } return false; } private static bool IsPlaceableDrop(string droppedName) { switch (droppedName) { default: return droppedName == "tptrap"; case "Claymore": case "ProximityMine": case "APMine": case "Teleport Mine": case "TPTrap": return true; } } private static bool IsThrowableDrop(string droppedName) { switch (droppedName) { default: return droppedName == "repulsiongrenade"; case "HandGrenade": case "GlandGrenade": case "Repulsion Grenade": case "RepulsionGrenade": case "RepulsorGrenadeMerged": case "KBGrenade": return true; } } private static bool IsProtectedHeldDrop(PlayerPickup pickup, GameObject obj, bool rightHand) { if ((Object)(object)pickup == (Object)null || (Object)(object)obj == (Object)null) { return false; } if ((Object)(object)(rightHand ? pickup.sync___get_value_objInHand() : (pickup.sync___get_value_hasObjectInLeftHand() ? pickup.sync___get_value_objInLeftHand() : null)) != (Object)(object)obj) { return false; } Weapon component = obj.GetComponent<Weapon>(); if ((Object)(object)component == (Object)null) { return false; } try { return component.sync___get_value_currentAmmo() > 0; } catch { return false; } } private static IEnumerator DeferredDropCleanup(PlayerPickup pickup, GameObject obj, bool isPlaceable, bool isThrowable, int playerId, int weaponIndex, bool rightHand) { yield return null; try { if (rightHand) { pickup.sync___set_value_hasObjectInHand(false, true); pickup.sync___set_value_objInHand((GameObject)null, true); } else { pickup.sync___set_value_hasObjectInLeftHand(false, true); pickup.sync___set_value_objInLeftHand((GameObject)null, true); } } catch { } if (!isPlaceable && !isThrowable && (Object)(object)obj != (Object)null) { NetworkObject component = obj.GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { try { InstanceFinder.ServerManager.Despawn(component, (DespawnType?)null); } catch { } } else { try { Object.Destroy((Object)(object)obj); } catch { } } } yield return (object)new WaitForSeconds(0.1f); if (playerId < 0 || GunGamePlugin.MatchOver) { yield break; } if (isPlaceable) { string handReplaceKey = GetHandReplaceKey(playerId, rightHand); if (!_pendingPlaceableReplace.Contains(handReplaceKey)) { _pendingPlaceableReplace.Add(handReplaceKey); object obj5 = ((object)GameManager.Instance) ?? ((object)GunGamePlugin.Instance); if (obj5 != null) { ((MonoBehaviour)obj5).StartCoroutine(EnsurePlaceableReplaced(playerId, rightHand)); } } } else { GunGameWeaponManager.ReplaceWeaponInHand(playerId, weaponIndex, rightHand); } } private static IEnumerator DelayedKillWeaponGive(int killerId, int weaponIndex) { yield return (object)new WaitForSeconds(3f); if (GunGamePlugin.MatchOver) { yield break; } try { PlayerPickup val = GunGamePlugin.FindPickupForPlayerId(killerId); if ((Object)(object)val != (Object)null && !val.sync___get_value_hasObjectInHand()) { GunGameWeaponManager.GiveWeaponToPlayer(killerId, weaponIndex); } } catch { } } private static IEnumerator DelayedInitialSpawnFallback(int playerId) { yield return (object)new WaitForSeconds(7f); if (GunGamePlugin.MatchOver) { yield break; } try { if (!GunGameWeaponManager.IsGivingWeapon(playerId)) { PlayerPickup val = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)val != (Object)null && !val.sync___get_value_hasObjectInHand()) { GunGameWeaponManager.GiveWeaponToPlayer(playerId, GetCurrentWeaponIndex(playerId)); } } } catch { } } private static IEnumerator DelayedRespawnWeaponFallback(int playerId) { yield return (object)new WaitForSeconds(3f); if (GunGamePlugin.MatchOver) { yield break; } try { if (!GunGameWeaponManager.IsGivingWeapon(playerId)) { PlayerPickup val = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)val != (Object)null && !val.sync___get_value_hasObjectInHand()) { GunGameWeaponManager.GiveWeaponToPlayer(playerId, GetCurrentWeaponIndex(playerId)); } } } catch { } } private static IEnumerator EnsurePlaceableReplaced(int playerId, bool rightHand) { bool gave = false; try { for (int attempt = 0; attempt < 12; attempt++) { yield return (object)new WaitForSeconds(0.5f); if (GunGamePlugin.MatchOver) { yield break; } if (GunGameWeaponManager.IsGivingWeaponInHand(playerId, rightHand)) { continue; } PlayerPickup val = GunGamePlugin.FindPickupForPlayerId(playerId); if (!((Object)(object)val == (Object)null)) { if (IsHandEmpty(val, rightHand)) { int currentWeaponIndex = GetCurrentWeaponIndex(playerId); GunGameWeaponManager.ReplaceWeaponInHand(playerId, currentWeaponIndex, rightHand); } yield break; } } if (!gave && !GunGamePlugin.MatchOver) { PlayerPickup val2 = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)val2 != (Object)null && IsHandEmpty(val2, rightHand)) { GunGameWeaponManager.ReplaceWeaponInHand(playerId, GetCurrentWeaponIndex(playerId), rightHand); } } } finally { _pendingPlaceableReplace.Remove(GetHandReplaceKey(playerId, rightHand)); } } private static string GetHandReplaceKey(int playerId, bool rightHand) { return playerId + (rightHand ? ":R" : ":L"); } private static bool IsHandEmpty(PlayerPickup pickup, bool rightHand) { if ((Object)(object)pickup == (Object)null) { return false; } if (!rightHand) { return !pickup.sync___get_value_hasObjectInLeftHand(); } return !pickup.sync___get_value_hasObjectInHand(); } public static bool RoundManager_CmdEndRound_Prefix(int winningTeamId) { if (!GunGamePlugin.MatchOver) { return false; } return true; } private static IEnumerator WinSequenceCoroutine(int winnerPlayerId) { yield return (object)new WaitForSeconds(1.5f); bool endRoundCalled = false; try { int playerTeam = GetPlayerTeam(winnerPlayerId); BroadcastChat("<b><color=yellow>[Gun Game]</color></b> <b><color=white>" + GetPlayerName(winnerPlayerId) + "</color></b> wins the round!"); if ((Object)(object)ScoreManager.Instance != (Object)null) { ScoreManager.Instance.AddRoundScore(playerTeam, 1); } if (_miRoundWon != null) { _miRoundWon.Invoke(GameManager.Instance, new object[1] { playerTeam }); } if ((Object)(object)RoundManager.Instance != (Object)null) { RoundManager.Instance.CmdEndRound(playerTeam); endRoundCalled = true; } } catch { } yield return (object)new WaitForSeconds(4f); if (endRoundCalled) { try { if ((Object)(object)SceneMotor.Instance != (Object)null) { SceneMotor.Instance.ChangeNetworkScene(); } } catch { } } GunGamePlugin.MatchOver = false; ResetState(); } private static Type GetParticleSystemType() { if (_particleSystemType != null) { return _particleSystemType; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType("UnityEngine.ParticleSystem"); if (type != null) { _particleSystemType = type; break; } } return _particleSystemType; } private static void CleanupBloodAndHats() { try { Type particleSystemType = GetParticleSystemType(); if (particleSystemType != null) { Object[] array = Object.FindObjectsOfType(particleSystemType, true); foreach (Object val in array) { try { Component val2 = (Component)(object)((val is Component) ? val : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.transform.parent == (Object)null) { Object.Destroy((Object)(object)val2.gameObject); } } catch { } } } HatPosition[] array2 = Object.FindObjectsOfType<HatPosition>(true); foreach (HatPosition val3 in array2) { try { if ((Object)(object)((Component)val3).transform.parent == (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } } catch { } } } catch { } } internal static void CleanupWorldEffects() { try { foreach (KeyValuePair<int, GameObject> playerRagdoll in _playerRagdolls) { try { if ((Object)(object)playerRagdoll.Value != (Object)null) { Object.Destroy((Object)(object)playerRagdoll.Value); } } catch { } } _playerRagdolls.Clear(); RagdollDress[] array = Object.FindObjectsOfType<RagdollDress>(true); foreach (RagdollDress val in array) { try { Object.Destroy((Object)(object)((Component)val).gameObject); } catch { } } } catch { } CleanupBloodAndHats(); } private static void ScheduleRespawn(int deadPlayerId) { if (deadPlayerId >= 0 && !GunGamePlugin.MatchOver && !((Object)(object)GameManager.Instance == (Object)null) && !((Object)(object)InstanceFinder.NetworkManager == (Object)null) && InstanceFinder.NetworkManager.IsServer) { if (!_respawnRequestSeq.ContainsKey(deadPlayerId)) { _respawnRequestSeq[deadPlayerId] = 0; } _playersAwaitingRespawn.Add(deadPlayerId); int num = ++_respawnRequestSeq[deadPlayerId]; float num2 = Mathf.Max(0.25f, GunGamePlugin.RespawnDelay.Value); _nextRespawnRecoveryTime[deadPlayerId] = Time.time + num2 + 6.75f + 1f; LogRespawn(deadPlayerId, 0, $"queued sequence={num} delay={num2:0.00}s"); ((MonoBehaviour)GameManager.Instance).StartCoroutine(SinglePlayerRespawnCoroutine(deadPlayerId, num, num2)); } } public static void ServerRespawnWatchdogUpdate() { if (!GunGamePlugin.Enabled.Value || GunGamePlugin.MatchOver || (Object)(object)InstanceFinder.NetworkManager == (Object)null || !InstanceFinder.NetworkManager.IsServer || Time.time < _nextRespawnWatchdogTime) { return; } _nextRespawnWatchdogTime = Time.time + 0.5f; int[] array = _playersAwaitingRespawn.ToArray(); foreach (int num in array) { if (!_respawnInProgress.Contains(num)) { PlayerManager pm = FindPlayerManagerForId(num); float value; if (IsPlayerRespawnValid(num, pm, out var _)) { CompleteRespawn(num, pm, "watchdog found valid player"); } else if (!_nextRespawnRecoveryTime.TryGetValue(num, out value) || !(Time.time < value)) { LogRespawn(num, 0, "watchdog restarting failed respawn"); ScheduleRespawn(num); } } } } private static IEnumerator SinglePlayerRespawnCoroutine(int deadPlayerId, int seq, float delay) { yield return (object)new WaitForSeconds(delay); if (GunGamePlugin.MatchOver || (Object)(object)GameManager.Instance == (Object)null || (Object)(object)InstanceFinder.NetworkManager == (Object)null || !InstanceFinder.NetworkManager.IsServer || !_respawnRequestSeq.TryGetValue(deadPlayerId, out var value) || value != seq) { yield break; } float gateTimeout = Time.time + 1.5f; while (_respawnInProgress.Contains(deadPlayerId) && Time.time < gateTimeout) { yield return null; } if (_respawnInProgress.Contains(deadPlayerId)) { yield break; } _respawnInProgress.Add(deadPlayerId); bool spawned = false; PlayerManager spawnedManager = null; try { for (int attempt = 1; attempt <= 3; attempt++) { if (GunGamePlugin.MatchOver) { break; } PlayerManager val = FindPlayerManagerForId(deadPlayerId); if ((Object)(object)val == (Object)null) { LogRespawn(deadPlayerId, attempt, "missing PlayerManager"); yield return (object)new WaitForSeconds(0.25f); continue; } CleanupRespawnArtifacts(deadPlayerId); if (!TryInvokeRespawn(val, deadPlayerId, attempt)) { yield return (object)new WaitForSeconds(0.25f); continue; } string failureReason = "spawn did not become valid"; float validationDeadline = Time.time + 2f; while (Time.time < validationDeadline && !GunGamePlugin.MatchOver) { if (_respawnRequestSeq.TryGetValue(deadPlayerId, out value) && value == seq) { val = FindPlayerManagerForId(deadPlayerId); if (IsPlayerRespawnValid(deadPlayerId, val, out failureReason)) { spawned = true; spawnedManager = val; break; } yield return null; continue; } yield break; } if (spawned) { LogRespawn(deadPlayerId, attempt, "native respawn verified"); break; } LogRespawn(deadPlayerId, attempt, "verify failed: " + failureReason); yield return (object)new WaitForSeconds(0.25f); } } finally { _respawnInProgress.Remove(deadPlayerId); } if (spawned) { CompleteRespawn(deadPlayerId, spawnedManager, "respawn finalized"); yield break; } LogRespawn(deadPlayerId, 3, "respawn failed after all attempts"); _nextRespawnRecoveryTime[deadPlayerId] = Time.time + 1f; } private static void CompleteRespawn(int playerId, PlayerManager pm, string source) { if (_playersAwaitingRespawn.Remove(playerId)) { _nextRespawnRecoveryTime.Remove(playerId); ForcePlayerReady(pm); if (GunGameWeaponManager.HasPendingWeapon(playerId)) { GunGameWeaponManager.ApplyPendingWeaponOnSpawn(playerId); } else { GunGameWeaponManager.GiveWeaponToPlayer(playerId, GetCurrentWeaponIndex(playerId)); } GameManager instance = GameManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(DelayedRespawnWeaponFallback(playerId)); } LogRespawn(playerId, 0, source); } } private static bool TryInvokeRespawn(PlayerManager pm, int playerId, int attempt) { if (_miCmdRespawnLogic == null || (Object)(object)pm == (Object)null) { return false; } try { _miCmdRespawnLogic.Invoke(pm, null); LogRespawn(playerId, attempt, "native respawn invoked"); return true; } catch (Exception ex) { Exception ex2 = ((ex is TargetInvocationException && ex.InnerException != null) ? ex.InnerException : ex); LogRespawn(playerId, attempt, "native respawn failed: " + ex2.GetType().Name + " - " + ex2.Message); return false; } } private static bool IsPlayerRespawnValid(int playerId, PlayerManager pm, out string reason) { reason = ""; if ((Object)(object)pm == (Object)null) { reason = "missing PlayerManager"; return false; } if ((Object)(object)pm.player == (Object)null) { reason = "missing player controller"; return false; } GameObject gameObject = ((Component)pm.player).gameObject; if ((Object)(object)gameObject == (Object)null || !gameObject.activeInHierarchy) { reason = "inactive player object"; return false; } PlayerValues component = gameObject.GetComponent<PlayerValues>(); if ((((component == null) ? ((int?)null) : component.sync___get_value_playerClient()?.PlayerId) ?? (-1)) != playerId) { reason = "player id mismatch"; return false; } PlayerHealth component2 = gameObject.GetComponent<PlayerHealth>(); if ((Object)(object)component2 == (Object)null) { reason = "missing PlayerHealth"; return false; } if (component2.sync___get_value_health() <= 0f || component2.sync___get_value_isKilled()) { reason = "still dead"; return false; } if ((Object)(object)gameObject.GetComponentInChildren<PlayerPickup>(true) == (Object)null) { reason = "missing PlayerPickup"; return false; } NetworkObject component3 = gameObject.GetComponent<NetworkObject>(); if ((Object)(object)component3 == (Object)null || !component3.IsSpawned) { reason = "player NetworkObject is not spawned"; return false; } CharacterController component4 = gameObject.GetComponent<CharacterController>(); if ((Object)(object)component4 == (Object)null || !((Collider)component4).enabled) { reason = "character controller is not ready"; return false; } return true; } private static void ForcePlayerReady(PlayerManager pm) { if ((Object)(object)pm == (Object)null) { return; } try { pm.SetPlayerMove(true); if ((Object)(object)pm.player != (Object)null) { pm.player.sync___set_value_canMove(true, true); pm.player.startOfRound = false; } if ((Object)(object)PauseManager.Instance != (Object)null) { PauseManager.Instance.startRound = false; } } catch (Exception ex) { ManualLogSource log = GunGamePlugin.Log; if (log != null) { log.LogWarning((object)("[GunGame Respawn] could not finalize player movement: " + ex.GetType().Name)); } } GameManager instance = GameManager.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(KeepPlayerMovable(pm, 4f)); } } private static void CleanupRespawnArtifacts(int playerId) { try { if (_playerRagdolls.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } _playerRagdolls.Remove(playerId); CleanupBloodAndHats(); } catch { } } private static void LogRespawn(int playerId, int attempt, string message) { try { ManualLogSource log = GunGamePlugin.Log; if (log != null) { log.LogInfo((object)$"[GunGame Respawn] player={playerId} attempt={attempt}: {message}"); } } catch { } } private static IEnumerator KeepPlayerMovable(PlayerManager pm, float duration) { float end = Time.time + duration; while (Time.time < end) { try { if ((Object)(object)pm != (Object)null) { pm.SetPlayerMove(true); if ((Object)(object)pm.player != (Object)null) { pm.player.sync___set_value_canMove(true, true); pm.player.startOfRound = false; } if ((Object)(object)PauseManager.Instance != (Object)null) { PauseManager.Instance.startRound = false; } } } catch { } yield return null; } } private static int FindKillerId(int deadPlayerId) { PlayerHealth val = FindPlayerHealth(deadPlayerId); if ((Object)(object)val == (Object)null) { return -1; } Transform killer = val.killer; if ((Object)(object)killer == (Object)null) { return -1; } ClientInstance componentInParent = ((Component)killer).GetComponentInParent<ClientInstance>(true); if ((Object)(object)componentInParent != (Object)null) { return componentInParent.PlayerId; } PlayerValues obj = ((Component)killer).GetComponentInParent<PlayerValues>(true) ?? ((Component)killer).GetComponentInChildren<PlayerValues>(true); int? num = ((obj == null) ? ((int?)null) : obj.sync___get_value_playerClient()?.PlayerId); if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); if (valueOrDefault >= 0) { return valueOrDefault; } } GameObject val2 = null; ProximityMine val3 = ((Component)killer).GetComponentInParent<ProximityMine>(true) ?? ((Component)killer).GetComponentInChildren<ProximityMine>(true); if ((Object)(object)val3 != (Object)null) { val2 = val3.sync___get_value__rootObject(); } else { Claymore val4 = ((Component)killer).GetComponentInParent<Claymore>(true) ?? ((Component)killer).GetComponentInChildren<Claymore>(true); if ((Object)(object)val4 != (Object)null) { val2 = val4.sync___get_value__rootObject(); } } if ((Object)(object)val2 != (Object)null) { int ownerIdFromRootObject = GetOwnerIdFromRootObject(val2); if (ownerIdFromRootObject >= 0) { return ownerIdFromRootObject; } } return -1; } public static bool DamageZone_OnEnable_Prefix(DamageZone __instance) { if (!GunGamePlugin.Enabled.Value) { return true; } try { Collider[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } if ((Object)(object)__instance.toDestroy != (Object)null) { Object.Destroy((Object)(object)__instance.toDestroy); } Object.Destroy((Object)(object)((Component)__instance).gameObject); } catch { } return false; } public static bool FirstPersonController_OnTriggerStay_Prefix(Collider col) { if (GunGamePlugin.Enabled.Value && ((Component)col).CompareTag("DamageZone")) { return false; } return true; } public static void PlayerHealth_ExplodeForAll_Postfix(PlayerHealth __instance) { //IL_0074: 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) if (!GunGamePlugin.Enabled.Value) { return; } try { PlayerValues playerValues = __instance.playerValues; int num = ((playerValues == null) ? ((int?)null) : playerValues.sync___get_value_playerClient()?.PlayerId) ?? (-1); if (num < 0) { return; } RagdollDress val = null; float num2 = float.MaxValue; RagdollDress[] array = Object.FindObjectsOfType<RagdollDress>(true); foreach (RagdollDress val2 in array) { float num3 = Vector3.Distance(((Component)val2).transform.position, ((Component)__instance).transform.position); if (num3 < num2) { num2 = num3; val = val2; } } if ((Object)(object)val != (Object)null) { _playerRagdolls[num] = ((Component)val).gameObject; } } catch { } } public static void PlayerValues_SetPlayerClient_Postfix(ClientInstance __0) { if (!GunGamePlugin.Enabled.Value || (Object)(object)__0 == (Object)null) { return; } try { int playerId = __0.PlayerId; if (playerId >= 0) { if (_playerRagdolls.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); _playerRagdolls.Remove(playerId); } CleanupBloodAndHats(); } } catch { } } private static PlayerHealth FindPlayerHealth(int deadPlayerId) { PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>(true); foreach (PlayerHealth val in array) { if (val != null) { PlayerValues playerValues = val.playerValues; if (((playerValues == null) ? ((int?)null) : playerValues.sync___get_value_playerClient()?.PlayerId) == deadPlayerId) { return val; } } } return null; } private static PlayerManager FindPlayerManagerForId(int playerId) { if (ClientInstance.playerInstances.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null) { return ((Component)value).GetComponent<PlayerManager>(); } return null; } public static bool PauseManager_StartRoundDelay_Prefix(PauseManager __instance) { if (!GunGamePlugin.Enabled.Value) { return true; } try { __instance.InvokeRoundStarted(); __instance.onStartRoundScreen = true; MonoBehaviour val = (MonoBehaviour)(((object)GunGamePlugin.Instance) ?? ((object)GameManager.Instance)); if ((Object)(object)val != (Object)null) { val.StartCoroutine(ClearOnStartRoundScreen(__instance)); } } catch { } return false; } private static IEnumerator ClearOnStartRoundScreen(PauseManager pm) { yield return (object)new WaitForSeconds(0.8f); if ((Object)(object)pm != (Object)null) { pm.onStartRoundScreen = false; } } public static bool ProximityMine_KillShockWave_Prefix(ProximityMine __instance) { GameObject val = __instance.sync___get_value__rootObject(); if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)val.GetComponent<FirstPersonController>() == (Object)null) { return false; } return true; } public static bool Claymore_KillShockWave_Prefix(Claymore __instance) { GameObject val = __instance.sync___get_value__rootObject(); if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)val.GetComponent<FirstPersonController>() == (Object)null) { return false; } return true; } public static void Minigun_Update_Postfix(Minigun __instance) { if (!GunGamePlugin.Enabled.Value || (Object)(object)__instance == (Object)null) { return; } try { if ((Object)(object)__instance == (Object)null || ((Weapon)__instance).sync___get_value_currentAmmo() > 0) { if ((Object)(object)__instance != (Object)null) { _minigunDropQueued.Remove(((Object)__instance).GetInstanceID()); } return; } object obj = ((Weapon)__instance).behaviour?.playerPickup; if (obj == null) { GameObject rootObject = ((Weapon)__instance).rootObject; obj = ((rootObject != null) ? rootObject.GetComponent<PlayerPickup>() : null); } PlayerPickup val = (PlayerPickup)obj; if ((Object)(object)val == (Object)null || !TryGetHeldObjectHand(val, ((Component)__instance).gameObject, out var rightHand)) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (_minigunDropQueued.Add(instanceID)) { if (rightHand) { val.RightHandDrop(); } else { val.LeftHandDrop(); } } } catch { } } public static bool DualLauncher_SetBool_Prefix(DualLauncher __instance, bool value) { if (!GunGamePlugin.Enabled.Value || (Object)(object)__instance == (Object)null || !value) { return true; } try { object obj = ((Weapon)(__instance?)).behaviour?.playerPickup; if (obj == null) { if (__instance == null) { obj = null; } else { GameObject rootObject = ((Weapon)__instance).rootObject; obj = ((rootObject != null) ? rootObject.GetComponent<PlayerPickup>() : null); } } PlayerPickup val = (PlayerPickup)obj; if ((Object)(object)__instance == (Object)null || (Object)(object)val == (Object)null) { return true; } if (!TryGetHeldObjectHand(val, ((Component)__instance).gameObject, out var rightHand)) { return true; } PlayerValues playerValues = val.playerValues; int num = ((playerValues == null) ? ((int?)null) : playerValues.sync___get_value_playerClient()?.PlayerId) ?? (-1); if (num < 0) { return true; } string handReplaceKey = GetHandReplaceKey(num, rightHand); if (_suppressThrowableOpenUntil.TryGetValue(handReplaceKey, out var value2) && Time.unscaledTime <= value2) { return false; } } catch { } return true; } public static void WeaponHandSpawner_SpawnObject_Postfix(WeaponHandSpawner __instance) { if (!GunGamePlugin.Enabled.Value || (Object)(object)__instance == (Object)null) { return; } try { object obj = ((Weapon)(__instance?)).behaviour?.playerPickup; if (obj == null) { if (__instance == null) { obj = null; } else { GameObject rootObject = ((Weapon)__instance).rootObject; obj = ((rootObject != null) ? rootObject.GetComponent<PlayerPickup>() : null); } } PlayerPickup val = (PlayerPickup)obj; if (!((Object)(object)__instance == (Object)null) && !((Object)(object)val == (Object)null) && TryGetHeldObjectHand(val, ((Component)__instance).gameObject, out var rightHand) && IsThrowableHeldWeapon((!rightHand) ? val.sync___get_value_objInHand() : (val.sync___get_value_hasObjectInLeftHand() ? val.sync___get_value_objInLeftHand() : null))) { PlayerValues playerValues = val.playerValues; int num = ((playerValues == null) ? ((int?)null) : playerValues.sync___get_value_playerClient()?.PlayerId) ?? (-1); if (num >= 0) { _suppressThrowableOpenUntil[GetHandReplaceKey(num, !rightHand)] = Time.unscaledTime + 0.35f; } } } catch { } } private static bool IsThrowableHeldWeapon(GameObject obj) { if ((Object)(object)obj == (Object)null) { return false; } if (!IsThrowableDrop(((Object)obj).name?.Replace("(Clone)", "").Trim() ?? "")) { return (Object)(object)obj.GetComponent<DualLauncher>() != (Object)null; } return true; } public static bool MatchLogs_RpcSendChatLine_Prefix() { return !GunGamePlugin.Enabled.Value; } private static int GetOwnerIdFromRootObject(GameObject root) { if ((Object)(object)root == (Object)null) { return -1; } ClientInstance val = root.GetComponentInParent<ClientInstance>(true) ?? root.GetComponentInChildren<ClientInstance>(true); if ((Object)(object)val != (Object)null) { return val.PlayerId; } PlayerValues obj = root.GetComponentInParent<PlayerValues>(true) ?? root.GetComponentInChildren<PlayerValues>(true); int num = ((obj == null) ? ((int?)null) : obj.sync___get_value_playerClient()?.PlayerId) ?? (-1); if (num >= 0) { return num; } foreach (KeyValuePair<int, ClientInstance> playerInstance in ClientInstance.playerInstances) { try { ClientInstance value = playerInstance.Value; PlayerManager val2 = ((value != null) ? ((Component)value).GetComponent<PlayerManager>() : null); if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)val2.player != (Object)null && ((Object)(object)((Component)val2.player).gameObject == (Object)(object)root || root.transform.IsChildOf(((Component)val2.player).transform))) { return playerInstance.Key; } object? obj2 = _fiSpawnedObject?.GetValue(val2); GameObject val3 = (GameObject)((obj2 is GameObject) ? obj2 : null); if ((Object)(object)val3 != (Object)null && ((Object)(object)val3 == (Object)(object)root || root.transform.IsChildOf(val3.transform))) { return playerInstance.Key; } } } catch { } } return -1; } private static void ClearPlacedExplosivesForPlayer(int playerId) { try { ProximityMine[] array = Object.FindObjectsOfType<ProximityMine>(true); foreach (ProximityMine val in array) { try { if (GetOwnerIdFromRootObject(val.sync___get_value__rootObject()) == playerId) { NetworkObject component = ((Component)val).GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { InstanceFinder.ServerManager.Despawn(component, (DespawnType?)null); } else { Object.Destroy((Object)(object)((Component)val).gameObject); } } } catch { } } Claymore[] array2 = Object.FindObjectsOfType<Claymore>(true); foreach (Claymore val2 in array2) { try { if (GetOwnerIdFromRootObject(val2.sync___get_value__rootObject()) == playerId) { NetworkObject component2 = ((Component)val2).GetComponent<NetworkObject>(); if ((Object)(object)component2 != (Object)null && component2.IsSpawned) { InstanceFinder.ServerManager.Despawn(component2, (DespawnType?)null); } else { Object.Destroy((Object)(object)((Component)val2).gameObject); } } } catch { } } } catch { } } internal static void BroadcastChat(string text) { if ((Object)(object)MatchLogs.Instance == (Object)null || (Object)(object)InstanceFinder.NetworkManager == (Object)null || !InstanceFinder.NetworkManager.IsServer) { return; } try { _miMatchLogsSendToAll?.Invoke(MatchLogs.Instance, new object[1] { text }); } catch { } } private static string GetPlayerName(int playerId) { try { if (ClientInstance.playerInstances.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null) { return value.PlayerNameTag; } } catch { } return $"Player {playerId}"; } private static int GetPlayerTeam(int playerId) { if ((Object)(object)ScoreManager.Instance != (Object)null) { try { return ScoreManager.Instance.GetTeamId(playerId); } catch { } } return playerId; } } public static class GunGameWeaponManager { private static Dictionary<int, int> _pendingWeaponIndex = new Dictionary<int, int>(); private static MethodInfo _miSetObjectInHandRpcLogic; private static MethodInfo _miSetObjectInHandObserver; private static MethodInfo _miSetObjectInHandObserverLogic; private static bool _initialSpawnDelayDone = false; private static Dictionary<int, int> _giveSequence = new Dictionary<int, int>(); private static HashSet<int> _givingInProgress = new HashSet<int>(); private static HashSet<string> _handGivingInProgress = new HashSet<string>(); private static Dictionary<int, float> _dropProtectionUntil = new Dictionary<int, float>(); internal static MethodInfo SetObjectInHandObserverLogic { get { CacheMethods(); return _miSetObjectInHandObserverLogic; } } public static void QueueWeaponUpgrade(int playerId, int weaponIndex) { _pendingWeaponIndex[playerId] = weaponIndex; } public static int GetAndClearPendingWeapon(int playerId) { if (_pendingWeaponIndex.TryGetValue(playerId, out var value)) { _pendingWeaponIndex.Remove(playerId); return value; } return -1; } public static bool HasPendingWeapon(int playerId) { return _pendingWeaponIndex.ContainsKey(playerId); } public static void ClearPendingForPlayer(int playerId) { _pendingWeaponIndex.Remove(playerId); _giveSequence.Remove(playerId); _dropProtectionUntil.Remove(playerId); } public static void ClearAllPending() { _pendingWeaponIndex.Clear(); _giveSequence.Clear(); _givingInProgress.Clear(); _handGivingInProgress.Clear(); _dropProtectionUntil.Clear(); _initialSpawnDelayDone = false; } private static void CacheMethods() { if (!(_miSetObjectInHandRpcLogic != null)) { _miSetObjectInHandRpcLogic = typeof(PlayerPickup).GetMethod("RpcLogic___SetObjectInHandServer_46969756", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _miSetObjectInHandObserver = typeof(PlayerPickup).GetMethod("SetObjectInHandObserver", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _miSetObjectInHandObserverLogic = typeof(PlayerPickup).GetMethod("RpcLogic___SetObjectInHandObserver_46969756", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } } public static bool IsGivingWeapon(int playerId) { if (!_givingInProgress.Contains(playerId)) { return IsReplacingAnyHand(playerId); } return true; } public static bool IsGivingWeaponInHand(int playerId, bool rightHand) { if (!_givingInProgress.Contains(playerId)) { return _handGivingInProgress.Contains(GetHandGiveKey(playerId, rightHand)); } return true; } private static bool IsReplacingAnyHand(int playerId) { string value = playerId + ":"; foreach (string item in _handGivingInProgress) { if (item.StartsWith(value, StringComparison.Ordinal)) { return true; } } return false; } private static string GetHandGiveKey(int playerId, bool rightHand) { return playerId + (rightHand ? ":R" : ":L"); } public static int GetGiveSequence(int playerId) { if (!_giveSequence.TryGetValue(playerId, out var value)) { return 0; } return value; } public static void GiveWeaponToPlayer(int playerId, int weaponIndex) { if (!((Object)(object)InstanceFinder.NetworkManager == (Object)null) && InstanceFinder.NetworkManager.IsServer && !GunGamePlugin.MatchOver) { if (!_giveSequence.ContainsKey(playerId)) { _giveSequence[playerId] = 0; } int seq = ++_giveSequence[playerId]; MonoBehaviour val = (MonoBehaviour)(((object)GameManager.Instance) ?? ((object)GunGamePlugin.Instance)); if ((Object)(object)val != (Object)null) { val.StartCoroutine(GiveWeaponCoroutine(playerId, weaponIndex, seq)); } } } public static void ReplaceWeaponInHand(int playerId, int weaponIndex, bool rightHand) { if (!((Object)(object)InstanceFinder.NetworkManager == (Object)null) && InstanceFinder.NetworkManager.IsServer && !GunGamePlugin.MatchOver) { MonoBehaviour val = (MonoBehaviour)(((object)GameManager.Instance) ?? ((object)GunGamePlugin.Instance)); if ((Object)(object)val != (Object)null) { val.StartCoroutine(ReplaceWeaponInHandCoroutine(playerId, weaponIndex, rightHand)); } } } private static IEnumerator GiveWeaponCoroutine(int playerId, int weaponIndex, int seq) { NetworkManager nm = InstanceFinder.NetworkManager; if ((Object)(object)nm == (Object)null || !nm.IsServer) { yield break; } _givingInProgress.Add(playerId); bool flag = false; try { if ((Object)(object)GunGamePlugin.GetOrderedWeaponPrefab(weaponIndex) == (Object)null) { flag = true; } } finally { if (flag) { _givingInProgress.Remove(playerId); } } if (flag) { yield break; } float num = (_initialSpawnDelayDone ? 0f : 2f); _initialSpawnDelayDone = true; yield return (object)new WaitForSeconds(num); if (GunGamePlugin.MatchOver) { _givingInProgress.Remove(playerId); yield break; } if (_giveSequence.TryGetValue(playerId, out var value) && value != seq) { _givingInProgress.Remove(playerId); yield break; } PlayerPickup pickup = null; for (int attempt = 0; attempt < 8; attempt++) { pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup != (Object)null) { break; } yield return (object)new WaitForSeconds(0.5f); } if ((Object)(object)pickup == (Object)null) { _givingInProgress.Remove(playerId); yield break; } while (HasUnplacedTeleportMine(pickup)) { if (GunGamePlugin.MatchOver) { _givingInProgress.Remove(playerId); yield break; } if (_giveSequence.TryGetValue(playerId, out var value2) && value2 != seq) { _givingInProgress.Remove(playerId); yield break; } yield return (object)new WaitForSeconds(0.25f); pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup == (Object)null) { _givingInProgress.Remove(playerId); yield break; } } GameObject heldRight = pickup.sync___get_value_objInHand(); GameObject heldLeft = (pickup.sync___get_value_hasObjectInLeftHand() ? pickup.sync___get_value_objInLeftHand() : null); pickup.sync___set_value_hasObjectInHand(false, true); pickup.sync___set_value_hasObjectInLeftHand(false, true); pickup.sync___set_value_objInHand((GameObject)null, true); pickup.sync___set_value_objInLeftHand((GameObject)null, true); yield return (object)new WaitForSeconds(0.3f); if (_giveSequence.TryGetValue(playerId, out var value3) && value3 != seq) { _givingInProgress.Remove(playerId); yield break; } GameObject[] array = (GameObject[])(object)new GameObject[2] { heldRight, heldLeft }; foreach (GameObject val in array) { if ((Object)(object)val == (Object)null) { continue; } NetworkObject componentInParent = val.GetComponentInParent<NetworkObject>(); if ((Object)(object)componentInParent != (Object)null) { try { InstanceFinder.ServerManager.Despawn(componentInParent, (DespawnType?)null); } catch { } } else { try { Object.Destroy((Object)(object)val); } catch { } } } try { pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup != (Object)null) { ItemBehaviour[] componentsInChildren = ((Component)((Component)pickup).transform.root).GetComponentsInChildren<ItemBehaviour>(true); foreach (ItemBehaviour val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } NetworkObject component = ((Component)val2).GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { try { InstanceFinder.ServerManager.Despawn(component, (DespawnType?)null); } catch { } } else { try { Object.Destroy((Object)(object)((Component)val2).gameObject); } catch { } } } } } catch { } yield return (object)new WaitForSeconds(0.15f); pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup == (Object)null) { _givingInProgress.Remove(playerId); yield break; } GameObject playerGO = null; try { if (ClientInstance.playerInstances.TryGetValue(playerId, out var value4)) { PlayerManager val3 = ((value4 != null) ? ((Component)value4).GetComponent<PlayerManager>() : null); object obj6; if (val3 == null) { obj6 = null; } else { FirstPersonController player = val3.player; obj6 = ((player != null) ? ((Component)player).gameObject : null); } playerGO = (GameObject)obj6; } } catch { } if ((Object)(object)playerGO == (Object)null) { playerGO = ((Component)((Component)pickup).transform.root).gameObject; } GameObject orderedWeaponPrefab = GunGamePlugin.GetOrderedWeaponPrefab(weaponIndex); GameObject secondPrefab = GunGamePlugin.GetSecondWeaponPrefab(weaponIndex); GameObject rightWeapon = null; GameObject leftWeapon = null; ItemBehaviour rightIb = null; ItemBehaviour leftIb = null; try { rightWeapon = SpawnWeaponPrefab(nm, orderedWeaponPrefab, playerGO, out rightIb); if ((Object)(object)secondPrefab != (Object)null) { leftWeapon = SpawnWeaponPrefab(nm, secondPrefab, playerGO, out leftIb); } } catch (Exception) { DespawnOrDestroy(rightWeapon); DespawnOrDestroy(leftWeapon); _givingInProgress.Remove(playerId); yield break; } yield return (object)new WaitForSeconds(0.1f); if ((Object)(object)rightWeapon == (Object)null || ((Object)(object)secondPrefab != (Object)null && (Object)(object)leftWeapon == (Object)null) || (Object)(object)pickup == (Object)null) { DespawnOrDestroy(rightWeapon); DespawnOrDestroy(leftWeapon); _givingInProgress.Remove(playerId); yield break; } CacheMethods(); AssignWeaponToHand(pickup, rightWeapon, rightIb, playerGO, rightHand: true); if ((Object)(object)secondPrefab != (Object)null) { AssignWeaponToHand(pickup, leftWeapon, leftIb, playerGO, rightHand: false); } ProtectRecentGrant(playerId); _givingInProgress.Remove(playerId); } private static IEnumerator ReplaceWeaponInHandCoroutine(int playerId, int weaponIndex, bool rightHand) { NetworkManager nm = InstanceFinder.NetworkManager; if ((Object)(object)nm == (Object)null || !nm.IsServer) { yield break; } GameObject prefab = (rightHand ? GunGamePlugin.GetOrderedWeaponPrefab(weaponIndex) : GunGamePlugin.GetSecondWeaponPrefab(weaponIndex)); if ((Object)(object)prefab == (Object)null) { yield break; } string handKey = GetHandGiveKey(playerId, rightHand); if (!_handGivingInProgress.Add(handKey)) { yield break; } try { PlayerPickup pickup = null; for (int attempt = 0; attempt < 8; attempt++) { pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup != (Object)null) { break; } yield return (object)new WaitForSeconds(0.5f); } if ((Object)(object)pickup == (Object)null) { yield break; } while (HasUnplacedTeleportMineInHand(pickup, rightHand)) { if (GunGamePlugin.MatchOver) { yield break; } yield return (object)new WaitForSeconds(0.25f); pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup == (Object)null) { yield break; } } GameObject weapon = (rightHand ? pickup.sync___get_value_objInHand() : (pickup.sync___get_value_hasObjectInLeftHand() ? pickup.sync___get_value_objInLeftHand() : null)); if (rightHand) { pickup.sync___set_value_hasObjectInHand(false, true); pickup.sync___set_value_objInHand((GameObject)null, true); } else { pickup.sync___set_value_hasObjectInLeftHand(false, true); pickup.sync___set_value_objInLeftHand((GameObject)null, true); } DespawnOrDestroy(weapon); yield return (object)new WaitForSeconds(0.1f); pickup = GunGamePlugin.FindPickupForPlayerId(playerId); if ((Object)(object)pickup == (Object)null) { yield break; } GameObject playerGO = null; try { if (ClientInstance.playerInstances.TryGetValue(playerId, out var value)) { PlayerManager val = ((value != null) ? ((Component)value).GetComponent<PlayerManager>() : null); object obj; if (val == null) { obj = null; } else { FirstPersonController player = val.player; obj = ((player != null) ? ((Component)player).gameObject : null); } playerGO = (GameObject)obj; } } catch { } if ((Object)(object)playerGO == (Object)null) { playerGO = ((Component)((Component)pickup).transform.root).gameObject; } GameObject weapon2 = null; ItemBehaviour ib = null; try { weapon2 = SpawnWeaponPrefab(nm, prefab, playerGO, out ib); } catch { DespawnOrDestroy(weapon2); yield break; } yield return (object)new WaitForSeconds(0.1f); if (!((Object)(object)weapon2 == (Object)null)) { CacheMethods(); AssignWeaponToHand(pickup, weapon2, ib, playerGO, rightHand); ProtectRecentGrant(playerId); } } finally { _handGivingInProgress.Remove(handKey); } } private static GameObject SpawnWeaponPrefab(NetworkManager nm, GameObject prefab, GameObject playerGO, out ItemBehaviour ib) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(prefab, playerGO.transform.position, playerGO.transform.rotation); ib = val.GetComponent<ItemBehaviour>(); if ((Object)(object)ib != (Object)null) { ib.dispenserStart = true; } Rigidbody component = val.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.isKinematic = true; component.useGravity = false; } nm.ServerManager.Spawn(val, (NetworkConnection)null); Weapon component2 = val.GetComponent<Weapon>(); if ((Object)(object)component2 != (Object)null && IsTeleportMinePrefab(val)) { SetWeaponAmmo(component2, 2); } return val; } private static void AssignWeaponToHand(PlayerPickup pickup, GameObject weapon, ItemBehaviour ib, GameObject playerGO, bool rightHand) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pickup == (Object)null || (Object)(object)weapon == (Object)null) { return; } try { _miSetObjectInHandRpcLogic?.Invoke(pickup, new object[5] { weapon, weapon.transform.position, weapon.transform.rotation, playerGO, rightHand }); } catch { } if ((Object)(object)ib != (Object)null) { ib.dispenserStart = false; } try { if (rightHand) { pickup.sync___set_value_hasObjectInHand(true, true); pickup.sync___set_value_objInHand(weapon, true); } else { pickup.sync___set_value_hasObjectInLeftHand(true, true); pickup.sync___set_value_objInLeftHand(weapon, true); } } catch { } try { _miSetObjectInHandObserver?.Invoke(pickup, new object[5] { weapon, weapon.transform.position, weapon.transform.rotation, playerGO, rightHand }); } catch { } try { _miSetObjectInHandObserverLogic?.Invoke(pickup, new object[5] { weapon, weapon.transform.position, weapon.transform.rotation, playerGO, rightHand }); } catch { } } private static void ProtectRecentGrant(int playerId) { _dropProtectionUntil[playerId] = Time.time + 2f; } internal static bool IsDropProtected(int playerId) { if (!_dropProtectionUntil.TryGetValue(playerId, out var value)) { return false; } if (Time.time <= value) { return true; } _dropProtectionUntil.Remove(playerId); return false; } private static bool IsTeleportMinePrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } string a = ((Object)prefab).name?.Replace("(Clone)", "").Trim(); if (!string.Equals(a, "Teleport Mine", StringComparison.Ordinal) && !string.Equals(a, "TPTrap", StringComparison.Ordinal)) { return string.Equals(a, "tptrap", StringComparison.Ordinal); } return true; } private static bool HasUnplacedTeleportMine(PlayerPickup pickup) { if ((Object)(object)pickup == (Object)null) { return false; } if (!HasUnplacedTeleportMine(pickup.sync___get_value_objInHand())) { return HasUnplacedTeleportMine(pickup.sync___get_value_hasObjectInLeftHand() ? pickup.sync___get_value_objInLeftHand() : null); } return true; } private static bool HasUnplacedTeleportMineInHand(PlayerPickup pickup, bool rightHand) { if ((Object)(object)pickup == (Object)null) { return false; } return HasUnplacedTeleportMine(rightHand ? pickup.sync___get_value_objInHand() : (pickup.sync___get_value_hasObjectInLeftHand() ? pickup.sync___get_value_objInLeftHand() : null)); } private static bool HasUnplacedTeleportMine(GameObject weapon) { if ((Object)(object)weapon == (Object)null || !IsTeleportMinePrefab(weapon)) { return false; } Weapon component = weapon.GetComponent<Weapon>(); if ((Object)(object)component != (Object)null) { return component.sync___get_value_currentAmmo() > 0; } return false; } private static void SetWeaponAmmo(Weapon weapon, int ammo) { try { weapon.currentAmmo = ammo; } catch { } try { weapon.sync___set_value_currentAmmo(ammo, true); } catch { } } private static void DespawnOrDestroy(GameObject weapon) { if ((Object)(object)weapon == (Object)null) { return; } NetworkObject component = weapon.GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { try { InstanceFinder.ServerManager.Despawn(component, (DespawnType?)null); return; } catch { return; } } try { Object.Destroy((Object)(object)weapon); } catch { } } internal static void DespawnHeldWeapon(PlayerPickup pickup) { if ((Object)(object)pickup == (Object)null) { return; } GameObject val = pickup.sync___get_value_objInHand(); GameObject val2 = (pickup.sync___get_value_hasObjectInLeftHand() ? pickup.sync___get_value_objInLeftHand() : null); pickup.sync___set_value_hasObjectInHand(false, true); pickup.sync___set_value_hasObjectInLeftHand(false, true); pickup.sync___set_value_objInHand((GameObject)null, true); pickup.sync___set_value_objInLeftHand((GameObject)null, true); GameObject[] array = (GameObject[])(object)new GameObject[2] { val, val2 }; foreach (GameObject val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } NetworkObject componentInParent = val3.GetComponentInParent<NetworkObject>(); if ((Object)(object)componentInParent != (Object)null) { try { InstanceFinder.ServerManager.Despawn(componentInParent, (DespawnType?)null); } catch { } } else { try { Object.Destroy((Object)(object)val3); } catch { } } } try { ItemBehaviour[] componentsInChildren = ((Component)((Component)pickup).transform.root).GetComponentsInChildren<ItemBehaviour>(true); foreach (ItemBehaviour val4 in componentsInChildren) { if ((Object)(object)val4 == (Object)null) { continue; } NetworkObject component = ((Component)val4).GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { try { InstanceFinder.ServerManager.Despawn(component, (DespawnType?)null); } catch { } } else { try { Object.Destroy((Object)(object)((Component)val4).gameObject); } catch { } } } } catch { } } public static void ApplyPendingWeaponOnSpawn(int playerId) { if (!((Object)(object)InstanceFinder.NetworkManager == (Object)null) && InstanceFinder.NetworkManager.IsServer) { int andClearPendingWeapon = GetAndClearPendingWeapon(playerId); if (andClearPendingWeapon >= 0) { GiveWeaponToPlayer(playerId, andClearPendingWeapon); } } } } [BepInPlugin("com.modder.gungame", "Gun Game", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class GunGamePlugin : BaseUnityPlugin { public const string PluginGUID = "com.modder.gungame"; public const string PluginName = "Gun Game"; public const string PluginVersion = "1.0.0"; public const uint ModId = 774411u; private const string KokiWeaponsPluginGUID = "com.koki.weapons"; private const string CmrPluginGUID = "straftatcmr.rebalance"; internal static ManualLogSource Log; private static GunGamePlugin _instance; public static ConfigEntry<bool> Enabled; public static ConfigEntry<int> KillsToWin; public static ConfigEntry<float> RespawnDelay; public static ConfigEntry<bool> KillSelfNow; public static ConfigEntry<KeyboardShortcut> KillSelfShortcut; public static ConfigEntry<string>[] WeaponSlots; public static ConfigEntry<string>[] SecondWeaponSlots; public static bool MatchOver = false; private bool _fishNetHooked; private const int WeaponSlotCount = 100; private const string NoSecondWeapon = "None"; private const string DualPlaceableWarning = "Certain dual weilded combinations may have unpredictible results."; private const float ModMenuDropdownWidth = 332f; private const float ModMenuDropdownWidthTolerance = 1f; private float _nextDropdownResizeTime; private static Dictionary<string, string[]> WeaponConfigValueToNames = new Dictionary<string, string[]>(StringComparer.Ordinal); private static Dictionary<string, GameObject> ResourceWeaponPrefabs = new Dictionary<string, GameObject>(StringComparer.Ordinal); private static HashSet<string> MissingResourceWeaponNames = new HashSet<string>(StringComparer.Ordinal); private static GameObject[] CachedResourceWeapons = (GameObject[])(object)new GameObject[0]; private static bool ResourceWeaponsLoaded = false; private static readonly string[] DefaultWeaponNames = new string[71] { "Gun", "Glock", "Revolver", "Silenzzio", "Webley", "Keso", "Bender", "BeamLoad", "Mac10", "SMG", "Bukanee", "Dispenser", "Yangtse", "Hill_H15", "Crisis", "DF_Torrent", "GlaiveGun", "Tromblonj", "SawedOff", "Shotgun", "Havoc", "AAA12", "Kusma", "AR15", "AK-K", "QCW05", "FG42", "HK_G11", "HK_Caws", "SmithCarbine", "Gust", "Warden", "Kanye", "Elephant", "M2000", "Bayshore", "HandCanon", "Minigun", "Nugget", "Mortini", "DualLauncher", "RocketLauncher", "Prophet", "Phoenix", "Gamma", "GammaGen2", "BlankState", "Bublee", "DF_Blister", "DF_Cyst", "HandGrenade", "GlandGrenade", "ProximityMine", "APMine", "Claymore", "StunMine", "StunGrenade", "FlashLight", "HandGrenadeTwo", "RepulsiveGun", "BaseballBat", "Stylus", "Nizeh", "JahvalMahmaerd", "BigFattyBro", "CurvedKnife", "Couperet", "Katana", "Flamberge", "DF_GodSword", "Impetus" }; private static readonly string[][] VanillaWeaponNameGroups = new string[5][] { new string[2] { "StunMine", "stunMine" }, new string[2] { "StunGrenade", "stunGrenade" }, new string[2] { "FlashLight", "flashLight" }, new string[2] { "RepulsiveGun", "repulsiveGun" }, new string[2] { "HandGrenadeTwo", "handGrenadeTwo" } }; private static readonly string[][] KokiWeaponNameGroups = new string[2][] { new string[3] { "Teleport Mine", "TPTrap", "tptrap" }, new string[5] { "Repulsion Grenade", "RepulsionGrenade", "RepulsorGrenadeMerged", "KBGrenade", "repulsiongrenade" } }; private static readonly string[][] CmrWeaponNameGroups = new string[1][] { new string[2] { "Katana", "kuz-yakich" } }; public static GunGamePlugin Instance => _instance; private void Awake() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; _instance = this; LogDetectedCompatibility(); Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable Gun Game mode."); KillsToWin = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Kills To Win", DefaultWeaponNames.Length, new ConfigDescription("Kills before round ends.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); RespawnDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Respawn Delay", 3f, "Seconds before a dead player respawns."); KillSelfNow = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Kill Self Now", false, "Turn this on to kill your local player once for respawn testing. It resets itself to off."); KillSelfShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "Kill Self Shortcut", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Hotkey that kills your local player for respawn testing."); BindWeaponSlots(); GunGamePatches.Apply(); SceneManager.sceneLoaded += OnSceneLoaded; } private void OnEnable() { _instance = this; } private void OnDisable() { if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; if (_fishNetHooked && (Object)(object)InstanceFinder.SceneManager != (Object)null) { InstanceFinder.SceneManager.OnLoadEnd -= OnFishNetSceneLoaded; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ResetGunGameState(); } private void OnFishNetSceneLoaded(SceneLoadEndEventArgs args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Scene[] loadedScenes = args.LoadedScenes; for (int i = 0; i < loadedScenes.Length; i++) { _ = ref loadedScenes[i]; ResetGunGameState(); } } private void ResetGunGameState() { FullReset(); } internal static void FullReset() { MatchOver = false; GunGameWeaponManager.ClearAllPending(); GunGamePatches.ResetState(); GunGamePatches.CleanupWorldEffects(); try { if ((Object)(object)PauseManager.Instance != (Object)null) { PauseManager.Instance.startRound = false; PauseManager.Instance.onStartRoundScreen = false; } } catch { } } private void Update() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) SceneManager sceneManager = InstanceFinder.SceneManager; if (!_fishNetHooked && (Object)(object)sceneManager != (Object)null) { sceneManager.OnLoadEnd += OnFishNetSceneLoaded; _fishNetHooked = true; } else if (_fishNetHooked && (Object)(object)sceneManager == (Object)null) { _fishNetHooked = false; FullReset(); } WidenModMenuDropdowns(); if (Enabled.Value && KillSelfNow.Value) { KillSelfNow.Value = false; KillLocalPlayerForTesting(); } if (Enabled.Value) { KeyboardShortcut value = KillSelfShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { KillLocalPlayerForTesting(); } } if (!Enabled.Value || (Object)(object)GameManager.Instance == (Object)null || MatchOver || (Object)(object)InstanceFinder.NetworkManager == (Object)null || !InstanceFinder.NetworkManager.IsServer) { return; } GunGamePatches.ServerRespawnWatchdogUpdate(); foreach (KeyValuePair<int, ClientInstance> playerInstance in ClientInstance.playerInstances) { if (!GameManager.Instance.alivePlayers.Contains(playerInstance.Key)) { GameManager.Instance.alivePlayers.Add(playerInstance.Key); } } } private static void KillLocalPlayerForTesting() { try { int num = (((Object)(object)ClientInstance.Instance != (Object)null) ? ClientInstance.Instance.PlayerId : (-1)); if (num < 0) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"Kill Self requested, but no local ClientInstance player id was found."); } return; } PlayerHealth val = FindPlayerHealthById(num); if ((Object)(object)val == (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)$"Kill Self requested, but no PlayerHealth was found for player {num}."); } } else if (!val.sync___get_value_isKilled()) { if ((Object)(object)InstanceFinder.NetworkManager != (Object)null && InstanceFinder.NetworkManager.IsServer) { val.RpcLogic___RemoveHealth_431000436(9999f); } else { val.RemoveHealth(9999f); } } } catch (Exception ex) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)("Kill Self failed: " + ex.GetType().Name)); } } } private static PlayerHealth FindPlayerHealthById(int playerId) { try { PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>(true); foreach (PlayerHealth val in array) { if (!((Object)(object)val == (Object)null)) { PlayerValues playerValues = val.playerValues; if ((((playerValues == null) ? ((int?)null) : playerValues.sync___get_value_playerClient()?.PlayerId) ?? (-1)) == playerId) { return val; } } } } catch { } return null; } public static int GetOrderedWeaponCount() { _instance?.EnsureWeaponSlotsBound(); if (WeaponSlots != null && WeaponSlots.Length != 0) { return WeaponSlots.Length; } RefreshResourceWeapons(); return ResourceWeaponPrefabs.Count; } public static GameObject GetOrderedWeaponPrefab(int index) { _instance?.EnsureWeaponSlotsBound(); if (WeaponSlots != null && index >= 0 && index < WeaponSlots.Length) { if (TryResolveConfiguredWeaponPrefab(WeaponSlots[index]?.Value?.Trim(), out var prefab)) { return prefab; } return null; } GameObject[] array = LoadResourceWeapons(); if (array != null && index >= 0 && index < array.Length) { return array[index]; } return null; } public static GameObject GetSecondWeaponPrefab(int index) { _instance?.EnsureWeaponSlotsBound(); if (SecondWeaponSlots == null || index < 0 || index >= SecondWeaponSlots.Length) { return null; } string text = SecondWeaponSlots[index]?.Value?.Trim(); if (string.IsNullOrWhiteSpace(text) || string.Equals(text, "None", StringComparison.Ordinal)) { return null; } if (TryResolveConfiguredWeaponPrefab(text, out var prefab)) { return prefab; } return null; } private void EnsureWeaponSlotsBound() { if (WeaponSlots == null || SecondWeaponSlots == null) { BindWeaponSlots(); } } private void BindWeaponSlots() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown WeaponSlots = new ConfigEntry<string>[100]; SecondWeaponSlots = new ConfigEntry<string>[100]; string[] availableWeaponConfigValues = GetAvailableWeaponConfigValues(); AcceptableValueList<string> val = new AcceptableValueList<string>(availableWeaponConfigValues); AcceptableValueList<string> val2 = new AcceptableValueList<string>(BuildSecondWeaponConfigValues(availableWeaponConfigValues)); for (int i = 0; i < WeaponSlots.Length; i++) { WeaponSlots[i] = ((BaseUnityPlugin)this).Config.Bind<string>("Weapon Progression", $"Weapon {i + 1}", DefaultWeaponNames[i % DefaultWeaponNames.Length], new ConfigDescription(string.Format("Weapon given at progression slot {0}. {1}", i + 1, "Certain dual weilded combinations may have unpredictible results."), (AcceptableValueBase)(object)val, Array.Empty<object>())); SecondWeaponSlots[i] = ((BaseUnityPlugin)this).Config.Bind<string>("Weapon Progression", $"Weapon {i + 1} Off Hand", "None", new ConfigDescription(string.Format("Optional left-hand weapon given at progression slot {0}. {1}", i + 1, "Certain dual weilded combinations may have unpredictible results."), (AcceptableValueBase)(object)val2, Array.Empty<object>())); } } private static string[] BuildSecondWeaponConfigValues(string[] weaponValues) { List<string> list = new List<string> { "None" }; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal) { "None" }; foreach (string text in weaponValues) { if (!string.IsNullOrWhiteSpace(text) && hashSet.Add(text)) { list.Add(text); } } return list.ToArray(); } private static string[] GetAvailableWeaponConfigValues() { List<string> list = new List<string>(); HashSet<string> seen = new HashSet<string>(StringComparer.Ordinal); for (int i = 0; i < DefaultWeaponNames.Length; i++) { AddWeaponName(DefaultWeaponNames[i], list, seen); } try { GameObject[] array = LoadResourceWeapons(); foreach (GameObject val in array) { if ((Object)(object)val != (Object)null) { AddWeaponName(((Object)val).name, list, seen); } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Could not discover resource weapons for config dropdowns: " + ex.GetType().Name)); } } list.Sort(StringComparer.OrdinalIgnoreCase); return BuildWeaponConfigValues(list); } private static void AddWeaponName(string weaponName, List<string> names, HashSet<string> seen) { if (!string.IsNullOrWhiteSpace(weaponName)) { weaponName = weaponName.Replace("(Clone)", "").Trim(); if (seen.Add(weaponName)) { names.Add(weaponName); } } } private static string[] BuildWeaponConfigValues(List<string> weaponNames) { List<string> list = new List<string>(); HashSet<string> usedValues = new HashSet<string>(StringComparer.Ordinal); Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>(StringComparer.Ordinal); foreach (string weaponName in weaponNames) { string current; string[] weaponNameCandidates = GetWeaponNameCandidates(current = weaponName); current = MakeUniqueConfigValue(current, usedValues); list.Add(current); dictionary[current] = weaponNameCandidates; string[] array = weaponNameCandidates; foreach (string key in array) { if (!dictionary.ContainsKey(key)) { dictionary[key] = weaponNameCandidates; } } } WeaponConfigValueToNames = dictionary; return list.ToArray(); } private static string MakeUniqueConfigValue(string configValue, HashSet<string> usedValues) { if (usedValues.Add(configValue)) { return configValue; } int num = 2; string text2; while (true) { string text = $" #{num}"; text2 = configValue + text; if (usedValues.Add(text2)) { break; } num++; } return text2; } private static string[] GetWeaponNameCandidates(string weaponName) { foreach (string[] activeWeaponNameGroup in GetActiveWeaponNameGroups()) { string[] array = activeWeaponNameGroup; for (int i = 0; i < array.Length; i++) { if (string.Equals(array[i], weaponName, StringComparison.Ordinal)) { return activeWeaponNameGroup; } } } return new string[1] { weaponName }; } private static IEnumerable<string[]> GetActiveWeaponNameGroups() { string[][] vanillaWeaponNameGroups = VanillaWeaponNameGroups; for (int i = 0; i < vanillaWeaponNameGroups.Length; i++) { yield return vanillaWeaponNameGroups[i]; } if (IsKokiWeaponsLoaded()) { vanillaWeaponNameGroups = KokiWeaponNameGroups; for (int i = 0; i < vanillaWeaponNameGroups.Length; i++) { yield return vanillaWeaponNameGroups[i]; } } if (IsCmrLoaded()) { vanillaWeaponNameGroups = CmrWeaponNameGroups; for (int i = 0; i < vanillaWeaponNameGroups.Length; i++) { yield return vanillaWeaponNameGroups[i]; } } } private static bool IsKokiWeaponsLoaded() { return IsPluginLoaded("com.koki.weapons"); } private static bool IsCmrLoaded() { return IsPluginLoaded("straftatcmr.rebalance"); } private static bool IsPluginLoaded(string pluginGuid) { try { return Chainloader.PluginInfos != null && Chainloader.PluginInfos.ContainsKey(pluginGuid); } catch { return false; } } private static void LogDetectedCompatibility() { bool flag = IsKokiWeaponsLoaded(); bool flag2 = IsCmrLoa