using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using PluginConfig.API; using PluginConfig.API.Fields; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("KnucklBlasterParry")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("KnucklBlasterParry")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0047c3d5-622e-4056-975b-9789adcc5271")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("KnuckleblasterParry", "Knuckleblaster Parry", "1.0.1")] public class Plugin : BaseUnityPlugin { public static Plugin Instance; private Harmony harmony; public static BoolField EnableParry; private static FieldInfo ccField; private static FieldInfo camObjField; private static FieldInfo ppzField; private static FieldInfo boostedProjectileField; private static FieldInfo hitCoinField; private static FieldInfo enemyIdentifierField; private static FieldInfo currentPunchField; private static FieldInfo animatorField; private static MethodInfo tryParryProjectileMethod; private static MethodInfo parryProjectileMethod; private static MethodInfo delayedPunchflectionMethod; private void Awake() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown Instance = this; harmony = new Harmony("knuckleblasterparry"); PluginConfigurator val = PluginConfigurator.Create("Knuckleblaster Parry", "KnuckleblasterParryDfcfg"); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string iconWithURL = "file:///" + Path.Combine(directoryName, "icon.png").Replace("\\", "/"); val.SetIconWithURL(iconWithURL); EnableParry = new BoolField(val.rootPanel, "Enable Parry", "Enable_parry", true); CacheMembers(); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Knuckleblaster Parry loaded"); } private void CacheMembers() { ccField = AccessTools.Field(typeof(Punch), "cc"); camObjField = AccessTools.Field(typeof(Punch), "camObj"); ppzField = AccessTools.Field(typeof(Punch), "ppz"); boostedProjectileField = AccessTools.Field(typeof(Punch), "alreadyBoostedProjectile"); hitCoinField = AccessTools.Field(typeof(Punch), "alreadyHitCoin"); enemyIdentifierField = AccessTools.Field(typeof(Enemy), "eid"); currentPunchField = AccessTools.Field(typeof(FistControl), "currentPunch"); animatorField = AccessTools.Field(typeof(Punch), "anim"); tryParryProjectileMethod = AccessTools.Method(typeof(Punch), "TryParryProjectile", (Type[])null, (Type[])null); parryProjectileMethod = AccessTools.Method(typeof(Punch), "ParryProjectile", (Type[])null, (Type[])null); delayedPunchflectionMethod = AccessTools.Method(typeof(Coin), "DelayedPunchflection", (Type[])null, (Type[])null); } public static CameraController GetCameraController(Punch punch) { object? value = ccField.GetValue(punch); return (CameraController)((value is CameraController) ? value : null); } public static GameObject GetCameraObject(Punch punch) { object? value = camObjField.GetValue(punch); return (GameObject)((value is GameObject) ? value : null); } public static bool TryParry(Punch punch, Transform target, bool firstFrame) { if (IsChainsawTarget(target)) { return false; } if (IsParriedProjectileTarget(target)) { return false; } return (bool)tryParryProjectileMethod.Invoke(punch, new object[2] { target, firstFrame }); } public static void ParryProjectile(Punch punch, Projectile projectile) { parryProjectileMethod.Invoke(punch, new object[1] { projectile }); } public static void PunchflectCoin(Coin coin) { delayedPunchflectionMethod.Invoke(coin, null); } public static void RestoreAnimation(Punch punch) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (!((Object)(object)punch == (Object)null) && (int)punch.type == 1) { object? value = animatorField.GetValue(punch); Animator val = (Animator)((value is Animator) ? value : null); if (!((Object)(object)val == (Object)null)) { val.ResetTrigger("Hook"); val.SetTrigger("Punch"); } } } public static ProjectileParryZone GetParryZone(Punch punch) { object? value = ppzField.GetValue(punch); ProjectileParryZone val = (ProjectileParryZone)((value is ProjectileParryZone) ? value : null); if ((Object)(object)val != (Object)null) { return val; } val = ((Component)((Component)punch).transform.parent).GetComponentInChildren(); ppzField.SetValue(punch, val); return val; } public static bool CanBoostProjectile(Punch punch, bool firstFrame) { return !(bool)boostedProjectileField.GetValue(punch) && firstFrame; } public static bool AlreadyHitCoin(Punch punch) { return (bool)hitCoinField.GetValue(punch); } public static void SetCoinHit(Punch punch) { hitCoinField.SetValue(punch, true); } public static EnemyIdentifier GetEnemyIdentifier(Enemy enemy) { object? value = enemyIdentifierField.GetValue(enemy); return (EnemyIdentifier)((value is EnemyIdentifier) ? value : null); } public static Punch GetCurrentPunch() { FistControl instance = MonoSingleton.Instance; if ((Object)(object)instance == (Object)null) { return null; } object? value = currentPunchField.GetValue(instance); return (Punch)((value is Punch) ? value : null); } public static bool IsChainsawTarget(Transform target) { if ((Object)(object)target == (Object)null) { return false; } Chainsaw val = default(Chainsaw); if (((Component)target).TryGetComponent(ref val)) { return true; } ParryHelper val2 = default(ParryHelper); if (((Component)target).TryGetComponent(ref val2) && (Object)(object)val2.target != (Object)null && ((Component)val2.target).TryGetComponent(ref val)) { return true; } return false; } public static bool IsParriedProjectileTarget(Transform target) { if ((Object)(object)target == (Object)null) { return false; } Projectile val = default(Projectile); if (((Component)target).TryGetComponent(ref val) && val.parried) { return true; } ParryHelper val2 = default(ParryHelper); Projectile val3 = default(Projectile); if (((Component)target).TryGetComponent(ref val2) && (Object)(object)val2.target != (Object)null && ((Component)val2.target).TryGetComponent(ref val3) && val3.parried) { return true; } return false; } } [HarmonyPatch(typeof(LeaderboardController))] public static class LeaderboardBlocker { [HarmonyPatch("SubmitLevelScore")] [HarmonyPrefix] private static bool BlockLevelScores() { MonoSingleton.Instance.SendHudMessage("Leaderboards disabled - Knuckleblaster Parry.", "", "", 0, false, false, true); return false; } [HarmonyPatch("SubmitCyberGrindScore")] [HarmonyPrefix] private static bool BlockCyberGrindScores() { MonoSingleton.Instance.SendHudMessage("Leaderboards disabled = Knuckleblaster Parry.", "", "", 0, false, false, true); return false; } } [HarmonyPatch(typeof(Punch), "ActiveFrame")] public class HeavyParryPatch { private const int ParryMask = 16384; private const float ParryRange = 4f; private static void Prefix(Punch __instance, bool firstFrame) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 if ((Object)(object)__instance == (Object)null || !Plugin.EnableParry.value || (int)__instance.type != 1 || __instance.parriedSomething) { return; } CameraController cameraController = Plugin.GetCameraController(__instance); GameObject cameraObject = Plugin.GetCameraObject(__instance); if (!((Object)(object)cameraController == (Object)null) && !((Object)(object)cameraObject == (Object)null)) { HashSet checkedTargets = new HashSet(); if (!TryParryOverlaps(__instance, cameraController, checkedTargets, firstFrame) && !TryParryRaycast(__instance, cameraController, cameraObject, checkedTargets, firstFrame) && !TryParryZoneProjectile(__instance, checkedTargets, firstFrame)) { TryPunchflectCoin(__instance, cameraController, cameraObject); } } } private static bool TryParryOverlaps(Punch punch, CameraController cc, HashSet checkedTargets, bool firstFrame) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(cc.GetDefaultPos(), 0.01f, 16384, (QueryTriggerInteraction)2); foreach (Collider val in array) { Transform val2 = (((Object)(object)val.attachedRigidbody != (Object)null) ? ((Component)val.attachedRigidbody).transform : ((Component)val).transform); checkedTargets.Add(val2); checkedTargets.Add(((Component)val).transform); if (Plugin.TryParry(punch, val2, firstFrame)) { return true; } } return false; } private static bool TryParryRaycast(Punch punch, CameraController cc, GameObject camObj, HashSet checkedTargets, bool firstFrame) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); bool flag = Physics.Raycast(cc.GetDefaultPos(), camObj.transform.forward, ref val, 4f, 16384); if (!flag) { flag = Physics.BoxCast(cc.GetDefaultPos(), Vector3.one * 0.3f, camObj.transform.forward, ref val, camObj.transform.rotation, 4f, 16384); } if (!flag) { return false; } if (checkedTargets.Contains(((RaycastHit)(ref val)).transform)) { return false; } checkedTargets.Add(((RaycastHit)(ref val)).transform); return Plugin.TryParry(punch, ((RaycastHit)(ref val)).transform, firstFrame); } private static bool TryParryZoneProjectile(Punch punch, HashSet checkedTargets, bool firstFrame) { ProjectileParryZone parryZone = Plugin.GetParryZone(punch); if ((Object)(object)parryZone == (Object)null) { return false; } Projectile val = parryZone.CheckParryZone(); if ((Object)(object)val == (Object)null) { return false; } if (checkedTargets.Contains(((Component)val).transform)) { return false; } if (val.parried || val.unparryable) { return false; } if (!Plugin.CanBoostProjectile(punch, firstFrame) && val.playerBullet) { return false; } Plugin.ParryProjectile(punch, val); punch.parriedSomething = true; punch.hitSomething = true; return true; } private static void TryPunchflectCoin(Punch punch, CameraController cc, GameObject camObj) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //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) if (Plugin.AlreadyHitCoin(punch)) { return; } RaycastHit[] array = Physics.SphereCastAll(new Ray(cc.GetDefaultPos(), camObj.transform.forward), 0.35f, 4f, -1, (QueryTriggerInteraction)2); Coin val = null; float num = float.PositiveInfinity; for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; Coin val3 = (((Object)(object)((RaycastHit)(ref val2)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent() : null); if (!((Object)(object)val3 == (Object)null) && !(((RaycastHit)(ref val2)).distance >= num)) { val = val3; num = ((RaycastHit)(ref val2)).distance; } } if (!((Object)(object)val == (Object)null)) { Plugin.PunchflectCoin(val); Plugin.SetCoinHit(punch); punch.hitSomething = true; } } } [HarmonyPatch(typeof(Enemy), "HandleParrying")] public class EnemyParryPatch { private static void Prefix(Enemy __instance, ref string __state) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 if (!Plugin.EnableParry.value) { return; } __state = null; EnemyIdentifier enemyIdentifier = Plugin.GetEnemyIdentifier(__instance); if (!((Object)(object)enemyIdentifier == (Object)null) && !(enemyIdentifier.hitter != "heavypunch")) { Punch currentPunch = Plugin.GetCurrentPunch(); if (!((Object)(object)currentPunch == (Object)null) && (int)currentPunch.type == 1 && currentPunch.activeFrames > 0) { __state = enemyIdentifier.hitter; enemyIdentifier.hitter = "punch"; } } } private static void Postfix(Enemy __instance, string __state) { RestoreHitter(__instance, __state); } private static void Finalizer(Enemy __instance, string __state) { RestoreHitter(__instance, __state); } private static void RestoreHitter(Enemy enemy, string oldHitter) { if (oldHitter != null) { EnemyIdentifier enemyIdentifier = Plugin.GetEnemyIdentifier(enemy); if ((Object)(object)enemyIdentifier != (Object)null) { enemyIdentifier.hitter = oldHitter; } } } } [HarmonyPatch(typeof(Punch), "Parry")] public class HeavyParryAnimationPatch { private static void Postfix(Punch __instance) { Plugin.RestoreAnimation(__instance); } } [HarmonyPatch(typeof(Punch), "ParryProjectile")] public class ProjectileParryAnimationPatch { private static void Postfix(Punch __instance) { Plugin.RestoreAnimation(__instance); } } [HarmonyPatch(typeof(Punch), "TryParryProjectile")] public class TryParryAnimationPatch { private static void Postfix(Punch __instance, bool __result) { if (__result) { Plugin.RestoreAnimation(__instance); } } }