Please disclose if your mod was created primarily 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 Shanty4Heim v1.1.0
plugins/SeaShanty4Heim.dll
Decompiled 4 months agousing 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 BepInEx.Logging; using HarmonyLib; 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("SeaShanty4Heim")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SeaShanty4Heim")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("82659a80-5ea4-4861-89b2-1482c7681b90")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace SeaShantyMod; [BepInPlugin("com.yourname.seashantymod", "Sea Shanty 2 Dance Mod", "1.0.0")] public class SeaShantyPlugin : BaseUnityPlugin { private const string pluginGUID = "com.yourname.seashantymod"; private const string pluginName = "Sea Shanty 2 Dance Mod"; private const string pluginVersion = "1.0.0"; private readonly Harmony harmony = new Harmony("com.yourname.seashantymod"); public static ManualLogSource logger; public static AudioClip seaShanty2Clip; private static Dictionary<ZDOID, AudioSource> playerAudioSources = new Dictionary<ZDOID, AudioSource>(); public void Awake() { logger = ((BaseUnityPlugin)this).Logger; logger.LogInfo((object)"Sea Shanty 2 Mod loaded!"); LoadAudioClip(); harmony.PatchAll(Assembly.GetExecutingAssembly()); } private void LoadAudioClip() { try { string text = "SeaShanty4Heim.Assets.Sea_Shanty_2.wav"; using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text); if (stream == null) { logger.LogError((object)("Could not find embedded resource: " + text)); logger.LogInfo((object)"Available resources:"); string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { logger.LogInfo((object)(" - " + text2)); } } else { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); string path = Path.Combine(Path.GetTempPath(), "seashanty2.wav"); File.WriteAllBytes(path, array); ((MonoBehaviour)this).StartCoroutine(LoadAudioFromFile(path)); } } catch (Exception arg) { logger.LogError((object)$"Error loading audio: {arg}"); } } private IEnumerator LoadAudioFromFile(string path) { WWW www = new WWW("file:///" + path); try { yield return www; if (string.IsNullOrEmpty(www.error)) { seaShanty2Clip = www.GetAudioClip(false, false, (AudioType)20); logger.LogInfo((object)"Sea Shanty 2 audio loaded successfully!"); } else { logger.LogError((object)("Failed to load audio: " + www.error)); } } finally { ((IDisposable)www)?.Dispose(); } } public static void PlaySeaShanty(Player player) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seaShanty2Clip == (Object)null) { logger.LogWarning((object)"Audio clip not loaded yet!"); return; } if ((Object)(object)player == (Object)null) { logger.LogWarning((object)"Player is null!"); return; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDOID uid = component.GetZDO().m_uid; if (playerAudioSources.ContainsKey(uid)) { AudioSource val = playerAudioSources[uid]; if ((Object)(object)val != (Object)null && val.isPlaying) { return; } } ZDOID val2 = uid; GameObject val3 = new GameObject("SeaShantyAudioSource_" + ((object)(ZDOID)(ref val2)).ToString()); val3.transform.SetParent(((Component)player).transform); val3.transform.localPosition = Vector3.zero; AudioSource val4 = val3.AddComponent<AudioSource>(); val4.spatialBlend = 1f; val4.volume = 0.6f; val4.loop = true; val4.maxDistance = 50f; val4.minDistance = 5f; val4.rolloffMode = (AudioRolloffMode)1; val4.dopplerLevel = 0f; val4.clip = seaShanty2Clip; val4.Play(); playerAudioSources[uid] = val4; logger.LogInfo((object)$"Started Sea Shanty 3D audio for player {uid}"); } public static void StopSeaShanty(Player player) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDOID uid = component.GetZDO().m_uid; if (playerAudioSources.ContainsKey(uid)) { AudioSource val = playerAudioSources[uid]; if ((Object)(object)val != (Object)null) { val.Stop(); Object.Destroy((Object)(object)((Component)val).gameObject); } playerAudioSources.Remove(uid); logger.LogInfo((object)$"Stopped Sea Shanty audio for player {uid}"); } } public static void CleanupAudioSources() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) List<ZDOID> list = new List<ZDOID>(); foreach (KeyValuePair<ZDOID, AudioSource> playerAudioSource in playerAudioSources) { if ((Object)(object)playerAudioSource.Value == (Object)null) { list.Add(playerAudioSource.Key); } } foreach (ZDOID item in list) { playerAudioSources.Remove(item); } } } [HarmonyPatch(typeof(Player), "Awake")] public static class Patch_Player_Awake { private static void Postfix(Player __instance) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.Register<long, uint>("RPC_PlaySeaShanty", (Action<long, long, uint>)RPC_PlaySeaShanty); component.Register<long, uint>("RPC_StopSeaShanty", (Action<long, long, uint>)RPC_StopSeaShanty); SeaShantyPlugin.logger.LogInfo((object)"Registered Sea Shanty RPCs"); } } private static void RPC_PlaySeaShanty(long sender, long userID, uint idNum) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) Player val = FindPlayerByZDOID(new ZDOID(userID, idNum)); if ((Object)(object)val != (Object)null) { SeaShantyPlugin.PlaySeaShanty(val); SeaShantyPlugin.logger.LogInfo((object)$"RPC: Playing Sea Shanty for player {userID}:{idNum}"); } } private static void RPC_StopSeaShanty(long sender, long userID, uint idNum) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) Player val = FindPlayerByZDOID(new ZDOID(userID, idNum)); if ((Object)(object)val != (Object)null) { SeaShantyPlugin.StopSeaShanty(val); SeaShantyPlugin.logger.LogInfo((object)$"RPC: Stopping Sea Shanty for player {userID}:{idNum}"); } } private static Player FindPlayerByZDOID(ZDOID id) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) foreach (Player allPlayer in Player.GetAllPlayers()) { ZNetView component = ((Component)allPlayer).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().m_uid == id) { return allPlayer; } } return null; } } [HarmonyPatch(typeof(Player), "UpdateEmote")] public static class Patch_Player_UpdateEmote { private static Dictionary<ZDOID, bool> playerStates = new Dictionary<ZDOID, bool>(); private static void Postfix(Player __instance) { //IL_0044: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { ZDOID uid = component.GetZDO().m_uid; bool flag = ((Character)__instance).InEmote(); Ship standingOnShip = ((Character)__instance).GetStandingOnShip(); bool flag2 = (Object)(object)standingOnShip != (Object)null; bool flag3 = flag && flag2; bool flag4 = playerStates.ContainsKey(uid) && playerStates[uid]; if (flag3 && !flag4) { SeaShantyPlugin.PlaySeaShanty(__instance); component.InvokeRPC(ZNetView.Everybody, "RPC_PlaySeaShanty", new object[2] { ((ZDOID)(ref uid)).UserID, ((ZDOID)(ref uid)).ID }); playerStates[uid] = true; SeaShantyPlugin.logger.LogInfo((object)("Playing Sea Shanty for " + __instance.GetPlayerName())); } else if (!flag3 && flag4) { SeaShantyPlugin.StopSeaShanty(__instance); component.InvokeRPC(ZNetView.Everybody, "RPC_StopSeaShanty", new object[2] { ((ZDOID)(ref uid)).UserID, ((ZDOID)(ref uid)).ID }); playerStates[uid] = false; SeaShantyPlugin.logger.LogInfo((object)("Stopping Sea Shanty for " + __instance.GetPlayerName())); } } } } [HarmonyPatch(typeof(Player), "OnDestroy")] public static class Patch_Player_OnDestroy { private static void Prefix(Player __instance) { SeaShantyPlugin.StopSeaShanty(__instance); SeaShantyPlugin.CleanupAudioSources(); } }