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;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("UKSoundTool")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UKSoundTool")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ae817c5f-a4a9-458f-a608-9f621ebc9e08")]
[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")]
namespace UniversalAudioReplacer;
public static class AudioHooks
{
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
public class AudioSource_SetClip_Patch
{
[HarmonyPrefix]
public static void Prefix(ref AudioClip value)
{
if (AudioReplacerPlugin.TryGetReplacement(value, out var replacementClip))
{
value = replacementClip;
}
}
}
[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { })]
public class AudioSource_Play_Patch
{
[HarmonyPrefix]
public static void Prefix(AudioSource __instance)
{
if ((Object)(object)__instance != (Object)null && AudioReplacerPlugin.TryGetReplacement(__instance.clip, out var replacementClip) && (Object)(object)__instance.clip != (Object)(object)replacementClip)
{
__instance.clip = replacementClip;
}
}
}
[HarmonyPatch(typeof(AudioSource), "Play", new Type[] { typeof(ulong) })]
public class AudioSource_PlayDelay_Patch
{
[HarmonyPrefix]
public static void Prefix(AudioSource __instance)
{
if ((Object)(object)__instance != (Object)null && AudioReplacerPlugin.TryGetReplacement(__instance.clip, out var replacementClip) && (Object)(object)__instance.clip != (Object)(object)replacementClip)
{
__instance.clip = replacementClip;
}
}
}
[HarmonyPatch(typeof(AudioSource), "PlayDelayed")]
public class AudioSource_PlayDelayed_Patch
{
[HarmonyPrefix]
public static void Prefix(AudioSource __instance)
{
if ((Object)(object)__instance != (Object)null && AudioReplacerPlugin.TryGetReplacement(__instance.clip, out var replacementClip) && (Object)(object)__instance.clip != (Object)(object)replacementClip)
{
__instance.clip = replacementClip;
}
}
}
[HarmonyPatch(typeof(AudioSource), "PlayScheduled")]
public class AudioSource_PlayScheduled_Patch
{
[HarmonyPrefix]
public static void Prefix(AudioSource __instance)
{
if ((Object)(object)__instance != (Object)null && AudioReplacerPlugin.TryGetReplacement(__instance.clip, out var replacementClip) && (Object)(object)__instance.clip != (Object)(object)replacementClip)
{
__instance.clip = replacementClip;
}
}
}
[HarmonyPatch(typeof(AudioSource), "PlayOneShot", new Type[]
{
typeof(AudioClip),
typeof(float)
})]
public class AudioSource_PlayOneShot_Patch
{
[HarmonyPrefix]
public static void Prefix(ref AudioClip clip)
{
if (AudioReplacerPlugin.TryGetReplacement(clip, out var replacementClip))
{
clip = replacementClip;
}
}
}
[HarmonyPatch(typeof(AudioSource), "PlayClipAtPoint", new Type[]
{
typeof(AudioClip),
typeof(Vector3),
typeof(float)
})]
public class AudioSource_PlayClipAtPoint_Patch
{
[HarmonyPrefix]
public static void Prefix(ref AudioClip clip)
{
if (AudioReplacerPlugin.TryGetReplacement(clip, out var replacementClip))
{
clip = replacementClip;
}
}
}
}
[BepInPlugin("com.thehalfbunny.universalaudioreplacer", "Universal Audio Replacer", "3.3.0")]
public class AudioReplacerPlugin : BaseUnityPlugin
{
[CompilerGenerated]
private sealed class <LoadAudioFiles>d__6 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AudioReplacerPlugin <>4__this;
private string[] <audioFolders>5__1;
private string[] <supportedExtensions>5__2;
private string <defaultFolder>5__3;
private string[] <>s__4;
private int <>s__5;
private string <folder>5__6;
private string[] <>s__7;
private int <>s__8;
private string <ext>5__9;
private string[] <>s__10;
private int <>s__11;
private string <file>5__12;
private string <name>5__13;
private AudioType <audioType>5__14;
private string <safeUri>5__15;
private long <fileSize>5__16;
private bool <shouldStream>5__17;
private UnityWebRequest <uwr>5__18;
private AudioClip <clip>5__19;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadAudioFiles>d__6(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<audioFolders>5__1 = null;
<supportedExtensions>5__2 = null;
<defaultFolder>5__3 = null;
<>s__4 = null;
<folder>5__6 = null;
<>s__7 = null;
<ext>5__9 = null;
<>s__10 = null;
<file>5__12 = null;
<name>5__13 = null;
<safeUri>5__15 = null;
<uwr>5__18 = null;
<clip>5__19 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
//IL_0228: Invalid comparison between Unknown and I4
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
if ((int)<uwr>5__18.result == 1)
{
<clip>5__19 = DownloadHandlerAudioClip.GetContent(<uwr>5__18);
((Object)<clip>5__19).name = <name>5__13;
((Object)<clip>5__19).hideFlags = (HideFlags)32;
if (<shouldStream>5__17)
{
activeStreams.Add(<uwr>5__18);
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Streaming large audio file: " + <name>5__13));
}
else
{
<clip>5__19.LoadAudioData();
<uwr>5__18.Dispose();
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Loaded small SFX into RAM: " + <name>5__13));
}
loadedCustomClips[<name>5__13] = <clip>5__19;
<clip>5__19 = null;
}
else
{
((BaseUnityPlugin)<>4__this).Logger.LogError((object)("Failed to load " + <name>5__13 + ". Error: " + <uwr>5__18.error));
<uwr>5__18.Dispose();
}
<name>5__13 = null;
<safeUri>5__15 = null;
<uwr>5__18 = null;
<file>5__12 = null;
<>s__11++;
goto IL_0369;
}
<>1__state = -1;
<audioFolders>5__1 = Directory.GetDirectories(Paths.PluginPath, "AudioMod", SearchOption.AllDirectories);
if (<audioFolders>5__1.Length == 0)
{
<defaultFolder>5__3 = Path.Combine(Paths.PluginPath, "AudioMod");
Directory.CreateDirectory(<defaultFolder>5__3);
<audioFolders>5__1 = new string[1] { <defaultFolder>5__3 };
<defaultFolder>5__3 = null;
}
<supportedExtensions>5__2 = new string[2] { "*.wav", "*.ogg" };
<>s__4 = <audioFolders>5__1;
<>s__5 = 0;
goto IL_03c9;
IL_0399:
if (<>s__8 < <>s__7.Length)
{
<ext>5__9 = <>s__7[<>s__8];
<>s__10 = Directory.GetFiles(<folder>5__6, <ext>5__9, SearchOption.AllDirectories);
<>s__11 = 0;
goto IL_0369;
}
<>s__7 = null;
<folder>5__6 = null;
<>s__5++;
goto IL_03c9;
IL_03c9:
if (<>s__5 < <>s__4.Length)
{
<folder>5__6 = <>s__4[<>s__5];
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Scanning for audio in: " + <folder>5__6));
<>s__7 = <supportedExtensions>5__2;
<>s__8 = 0;
goto IL_0399;
}
<>s__4 = null;
return false;
IL_0369:
if (<>s__11 < <>s__10.Length)
{
<file>5__12 = <>s__10[<>s__11];
<name>5__13 = Path.GetFileNameWithoutExtension(<file>5__12);
<audioType>5__14 = (AudioType)((<ext>5__9 == "*.wav") ? 20 : 14);
<safeUri>5__15 = new Uri(<file>5__12).AbsoluteUri;
<fileSize>5__16 = new FileInfo(<file>5__12).Length;
<shouldStream>5__17 = <fileSize>5__16 >= 10485760;
<uwr>5__18 = UnityWebRequestMultimedia.GetAudioClip(<safeUri>5__15, <audioType>5__14);
((DownloadHandlerAudioClip)<uwr>5__18.downloadHandler).streamAudio = <shouldStream>5__17;
<>2__current = <uwr>5__18.SendWebRequest();
<>1__state = 1;
return true;
}
<>s__10 = null;
<ext>5__9 = null;
<>s__8++;
goto IL_0399;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public static Dictionary<string, AudioClip> loadedCustomClips = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase);
public static Dictionary<int, AudioClip> clipCache = new Dictionary<int, AudioClip>();
private static List<UnityWebRequest> activeStreams = new List<UnityWebRequest>();
private readonly Harmony harmony = new Harmony("com.thehalfbunny.universalaudioreplacer");
private const long StreamingThresholdBytes = 10485760L;
private void Awake()
{
((MonoBehaviour)this).StartCoroutine(LoadAudioFiles());
harmony.PatchAll();
SceneManager.sceneLoaded += OnSceneLoaded;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Universal Audio Replacer loaded! (former UKSoundTool)");
}
[IteratorStateMachine(typeof(<LoadAudioFiles>d__6))]
private IEnumerator LoadAudioFiles()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadAudioFiles>d__6(0)
{
<>4__this = this
};
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>();
AudioSource[] array2 = array;
foreach (AudioSource val in array2)
{
if ((Object)(object)val.clip != (Object)null && TryGetReplacement(val.clip, out var replacementClip) && (Object)(object)val.clip != (Object)(object)replacementClip)
{
bool isPlaying = val.isPlaying;
bool playOnAwake = val.playOnAwake;
val.clip = replacementClip;
if (((Component)val).gameObject.activeInHierarchy && ((Behaviour)val).enabled && (isPlaying || playOnAwake))
{
val.Play();
}
}
}
}
public static bool TryGetReplacement(AudioClip originalClip, out AudioClip replacementClip)
{
replacementClip = null;
if ((Object)(object)originalClip == (Object)null)
{
return false;
}
int instanceID = ((Object)originalClip).GetInstanceID();
if (clipCache.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
{
replacementClip = value;
return true;
}
if (loadedCustomClips.TryGetValue(((Object)originalClip).name, out var value2))
{
clipCache[instanceID] = value2;
replacementClip = value2;
return true;
}
return false;
}
}