Bonk.dll

Decompiled 15 hours ago
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<AudioSource>();
			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<int> Patched = new HashSet<int>();

	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<object>(ReferenceEqualityComparer.Instance));
			PatchObject(NormalPlayerField.GetValue(bat), 0, new HashSet<object>(ReferenceEqualityComparer.Instance));
			Patched.Add(instanceID);
		}
	}

	private static void PatchObject(object target, int depth, HashSet<object> 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<object>
{
	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;
	}
}