Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ShipHornReplacer v1.0.1
plugins/ShipHornReplacer/ShipHornReplacer.dll
Decompiled 2 hours agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShipHornReplacer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("ShipHornReplacer")] [assembly: AssemblyTitle("ShipHornReplacer")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 ShipHornReplacer { public static class MyPluginInfo { public const string PLUGIN_GUID = "ShipHornReplacer"; public const string PLUGIN_NAME = "ShipHornReplacer"; public const string PLUGIN_VERSION = "1.0.1"; } } namespace CustomShipHorn { public static class AudioLoader { public static AudioClip LoadWavFromDisk(string path) { try { return ParseWav(File.ReadAllBytes(path), Path.GetFileNameWithoutExtension(path)); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to load WAV from " + path + ": " + ex.Message)); return null; } } private static AudioClip ParseWav(byte[] data, string clipName) { if (data.Length < 44 || data[0] != 82 || data[1] != 73 || data[2] != 70 || data[3] != 70 || data[8] != 87 || data[9] != 65 || data[10] != 86 || data[11] != 69) { Plugin.Log.LogError((object)"Not a valid WAV file (missing RIFF/WAVE header)."); return null; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6; for (int i = 12; i < data.Length - 8; i += 8 + num6) { string @string = Encoding.ASCII.GetString(data, i, 4); num6 = BitConverter.ToInt32(data, i + 4); if (@string == "fmt ") { num = BitConverter.ToInt16(data, i + 10); num2 = BitConverter.ToInt32(data, i + 12); num3 = BitConverter.ToInt16(data, i + 22); } else if (@string == "data") { num4 = i + 8; num5 = num6; break; } } if (num == 0 || num2 == 0 || num5 == 0) { Plugin.Log.LogError((object)"Could not find required WAV chunks (fmt or data)."); return null; } int num7 = num3 / 8; int num8 = num5 / num7; float[] array = new float[num8]; switch (num3) { case 16: { for (int m = 0; m < num8; m++) { short num13 = BitConverter.ToInt16(data, num4 + m * 2); array[m] = (float)num13 / 32768f; } break; } case 8: { for (int k = 0; k < num8; k++) { array[k] = (float)(data[num4 + k] - 128) / 128f; } break; } case 24: { for (int l = 0; l < num8; l++) { int num10 = data[num4 + l * 3]; int num11 = data[num4 + l * 3 + 1]; int num12 = ((data[num4 + l * 3 + 2] << 24) | (num11 << 16) | (num10 << 8)) >> 8; array[l] = (float)num12 / 8388608f; } break; } case 32: { for (int j = 0; j < num8; j++) { int num9 = BitConverter.ToInt32(data, num4 + j * 4); array[j] = (float)num9 / 2.1474836E+09f; } break; } default: Plugin.Log.LogError((object)$"Unsupported WAV bit depth: {num3}. Use 8, 16, 24, or 32-bit PCM."); return null; } int num14 = num8 / num; AudioClip obj = AudioClip.Create(clipName, num14, num, num2, false); obj.SetData(array, 0); return obj; } } [BepInPlugin("com.horngremlin.shiphornreplacer", "ShipHornReplacer", "1.0.1")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.horngremlin.shiphornreplacer"; public const string PluginName = "ShipHornReplacer"; public const string PluginVersion = "1.0.1"; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } public static AudioClip CustomHornClip { get; private set; } private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Loading ShipHornReplacer v1.0.1..."); LoadCustomAudio(); new Harmony("com.horngremlin.shiphornreplacer").PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"ShipHornReplacer loaded successfully."); } private void LoadCustomAudio() { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string text = Path.Combine(directoryName, "horn.wav"); if (!File.Exists(text)) { Log.LogWarning((object)("horn.wav not found in " + directoryName + ". The mod will use vanilla audio.")); return; } Log.LogInfo((object)("Found custom horn file: " + text)); CustomHornClip = AudioLoader.LoadWavFromDisk(text); if ((Object)(object)CustomHornClip != (Object)null) { Log.LogInfo((object)("Custom horn audio loaded: " + ((Object)CustomHornClip).name + " " + $"({CustomHornClip.length:F2}s, {CustomHornClip.channels}ch, {CustomHornClip.frequency}Hz)")); } else { Log.LogError((object)"WAV decoder returned null — see earlier errors."); } } } [HarmonyPatch(typeof(ShipAlarmCord))] public class ShipAlarmCordPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start_Postfix(ShipAlarmCord __instance) { AudioClip customHornClip = Plugin.CustomHornClip; if ((Object)(object)customHornClip == (Object)null) { Plugin.Log.LogWarning((object)"Custom horn clip not loaded yet; using vanilla audio."); return; } if ((Object)(object)__instance.hornClose != (Object)null) { __instance.hornClose.clip = customHornClip; } if ((Object)(object)__instance.hornFar != (Object)null) { __instance.hornFar.clip = customHornClip; } Plugin.Log.LogInfo((object)"Replaced ship horn audio clips with custom sound."); } } }