using System; using System.Collections; 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 UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Bonk")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Bonk")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("690f048f-8a99-4569-bab7-b3a02f45f8e3")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("nos6x.burglin.bonk", "Bonk", "1.0.0")] public sealed class BonkPlugin : BaseUnityPlugin { internal static AudioClip BonkClip; private const float BonkStartOffsetSeconds = 0.6f; private Harmony _harmony; private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _harmony = new Harmony("nos6x.burglin.bonk"); _harmony.PatchAll(); ((MonoBehaviour)this).StartCoroutine(LoadBonkClip()); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); _harmony = null; } } private IEnumerator LoadBonkClip() { Assembly assembly = Assembly.GetExecutingAssembly(); using Stream input = assembly.GetManifestResourceStream("Bonk.Bonk.mp3"); if (input == null) { yield break; } string path = Path.Combine(Path.GetTempPath(), "Bonk.mp3"); using (FileStream output = File.Create(path)) { byte[] buffer = new byte[81920]; while (true) { int num; int read = (num = input.Read(buffer, 0, buffer.Length)); if (num > 0) { output.Write(buffer, 0, read); continue; } break; } } string uri = "file:///" + path.Replace("\\", "/"); UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(uri, (AudioType)13); try { yield return request.SendWebRequest(); if ((int)request.result == 1) { BonkClip = DownloadHandlerAudioClip.GetContent(request); ((Object)BonkClip).name = "Bonk.mp3"; yield break; } } finally { ((IDisposable)request)?.Dispose(); } } internal static void PlayBonk(Vector3 position) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)BonkClip == (Object)null)) { GameObject val = new GameObject("BonkAudio"); val.transform.position = position; AudioSource val2 = val.AddComponent(); val2.clip = BonkClip; val2.volume = 1f; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 1f; val2.maxDistance = 35f; if (0.6f < BonkClip.length) { val2.time = 0.6f; } val2.Play(); Object.Destroy((Object)(object)val, Mathf.Max(0.05f, BonkClip.length - 0.6f + 0.1f)); } } } [HarmonyPatch] internal static class MetalBatHitEffectPatch { private static readonly FieldInfo FleshPlayerField = AccessTools.Field(typeof(MetalBat), "fleshPlayer"); private static readonly FieldInfo NormalPlayerField = AccessTools.Field(typeof(MetalBat), "normalPlayer"); private static readonly HashSet Patched = new HashSet(); private static MethodBase TargetMethod() { return AccessTools.Method(typeof(MetalBat), "HitEffectRpc", new Type[3] { typeof(bool), typeof(Vector3), typeof(Vector3) }, (Type[])null); } private static void Prefix(MetalBat __instance, bool __0, Vector3 __1, Vector3 __2) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !((Object)(object)BonkPlugin.BonkClip == (Object)null)) { PatchBat(__instance); BonkPlugin.PlayBonk(__1); } } private static void PatchBat(MetalBat bat) { int instanceID = ((Object)bat).GetInstanceID(); if (!Patched.Contains(instanceID)) { PatchObject(FleshPlayerField.GetValue(bat), 0, new HashSet(ReferenceEqualityComparer.Instance)); PatchObject(NormalPlayerField.GetValue(bat), 0, new HashSet(ReferenceEqualityComparer.Instance)); Patched.Add(instanceID); } } private static void PatchObject(object target, int depth, HashSet seen) { if (target == null || depth > 6) { return; } Type type = target.GetType(); if (IsSimple(type)) { return; } if (!type.IsValueType) { if (seen.Contains(target)) { return; } seen.Add(target); } if (target is IList list) { for (int i = 0; i < list.Count; i++) { PatchObject(list[i], depth + 1, seen); } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.IsStatic || fieldInfo.IsLiteral) { continue; } Type fieldType = fieldInfo.FieldType; try { if (typeof(AudioClip).IsAssignableFrom(fieldType)) { fieldInfo.SetValue(target, null); continue; } if (typeof(AudioClip[]).IsAssignableFrom(fieldType)) { fieldInfo.SetValue(target, new AudioClip[0]); continue; } object value = fieldInfo.GetValue(target); if (ShouldEnter(fieldType, value)) { PatchObject(value, depth + 1, seen); if (fieldType.IsValueType && !fieldInfo.IsInitOnly) { fieldInfo.SetValue(target, value); } } } catch { } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.GetIndexParameters().Length != 0) { continue; } Type propertyType = propertyInfo.PropertyType; try { if (typeof(AudioClip).IsAssignableFrom(propertyType) && propertyInfo.CanWrite) { propertyInfo.SetValue(target, null, null); } else if (typeof(AudioClip[]).IsAssignableFrom(propertyType) && propertyInfo.CanWrite) { propertyInfo.SetValue(target, new AudioClip[0], null); } else if (propertyInfo.CanRead) { object value2 = propertyInfo.GetValue(target, null); if (ShouldEnter(propertyType, value2)) { PatchObject(value2, depth + 1, seen); } } } catch { } } } private static bool ShouldEnter(Type type, object value) { if (value == null || IsSimple(type)) { return false; } if (typeof(AudioClip).IsAssignableFrom(type) || typeof(AudioClip[]).IsAssignableFrom(type)) { return true; } if (typeof(IList).IsAssignableFrom(type)) { return true; } string name = type.Name; string text = type.Namespace ?? string.Empty; return text.StartsWith("MoreMountains", StringComparison.Ordinal) || name.IndexOf("Feedback", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Audio", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Sound", StringComparison.OrdinalIgnoreCase) >= 0; } private static bool IsSimple(Type type) { return type.IsPrimitive || type.IsEnum || type == typeof(string) || type == typeof(decimal) || type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4) || type == typeof(Quaternion) || type == typeof(Color) || type == typeof(Rect); } } internal sealed class ReferenceEqualityComparer : IEqualityComparer { internal static readonly ReferenceEqualityComparer Instance = new ReferenceEqualityComparer(); public new bool Equals(object x, object y) { return x == y; } public int GetHashCode(object obj) { return (obj != null) ? RuntimeHelpers.GetHashCode(obj) : 0; } }