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 Tailwind v1.0.7
Tailwind.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using HarmonyLib; using Jotunn; using Jotunn.Utils; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Tailwind")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Tailwind")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4e327c88-7b4a-4569-8bbc-a67aaad1a422")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Tailwind; [BepInPlugin("vaffle.Tailwind", "Tailwind", "1.0.2")] public class Class1 : BaseUnityPlugin { [HarmonyPatch(typeof(Player), "StartDoodadControl")] private static class AddMusic_Ship { [CompilerGenerated] private sealed class <LoadAndPlayMusicFromFolder>d__1 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private string <randomMp3Path>5__1; private UnityWebRequest <www>5__2; private AudioClip <clip>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAndPlayMusicFromFolder>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <randomMp3Path>5__1 = null; <www>5__2 = null; <clip>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Invalid comparison between Unknown and I4 try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!Directory.Exists(musicFolderPath)) { Logger.LogError((object)("Music folder not found at: " + musicFolderPath)); return false; } mp3Files = Directory.GetFiles(musicFolderPath, "*.mp3"); Logger.LogWarning((object)$"Found {mp3Files.Length} .mp3 files"); if (mp3Files.Length == 0) { Logger.LogError((object)("No .mp3 files found in " + musicFolderPath)); return false; } <randomMp3Path>5__1 = mp3Files[Random.Range(0, mp3Files.Length)]; <www>5__2 = UnityWebRequestMultimedia.GetAudioClip("file://" + <randomMp3Path>5__1, (AudioType)13); <>1__state = -3; <>2__current = <www>5__2.SendWebRequest(); <>1__state = 1; return true; case 1: <>1__state = -3; if ((int)<www>5__2.result == 1) { <clip>5__3 = DownloadHandlerAudioClip.GetContent(<www>5__2); ((Object)<clip>5__3).name = Path.GetFileNameWithoutExtension(<randomMp3Path>5__1); audioSource.clip = <clip>5__3; audioSource.Play(); isPlaying = true; UpdateMusicNameDisplay(((Object)<clip>5__3).name); Logger.LogWarning((object)("Now playing: " + ((Object)<clip>5__3).name)); <clip>5__3 = null; } else { Logger.LogError((object)("Failed to load audio clip: " + <www>5__2.error)); } <>m__Finally1(); <www>5__2 = null; return false; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<www>5__2 != null) { ((IDisposable)<www>5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static void Postfix(Player __instance, IDoodadController shipControl) { LoadUIPrefab(); Ship localShip = Ship.GetLocalShip(); Transform? obj = ((IEnumerable<Transform>)((Component)((Component)localShip).transform).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "InWaterSounds")); GameObject val = ((obj != null) ? ((Component)((IEnumerable<Transform>)((Component)((Component)obj).gameObject.transform).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "Decksound"))).gameObject : null); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"Music piece (Decksound) not found!"); return; } if ((Object)(object)audioSource == (Object)null) { audioSource = val.AddComponent<AudioSource>(); Logger.LogWarning((object)"AudioSource added"); } else { Logger.LogWarning((object)"AudioSource already exists"); } ((MonoBehaviour)__instance).StartCoroutine(LoadAndPlayMusicFromFolder()); } [IteratorStateMachine(typeof(<LoadAndPlayMusicFromFolder>d__1))] private static IEnumerator LoadAndPlayMusicFromFolder() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAndPlayMusicFromFolder>d__1(0); } } [HarmonyPatch(typeof(Player), "StopDoodadControl")] private static class RemoveUI_ShipEffects { private static void Postfix(Player __instance) { Object.Destroy((Object)(object)uiPanel); audioSource.Stop(); Object.Destroy((Object)(object)audioSource); } } [CompilerGenerated] private sealed class <FadeOutText>d__14 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public TextMeshProUGUI text; public float duration; private float <elapsedTime>5__1; private Color <originalColor>5__2; private float <alpha>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FadeOutText>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <elapsedTime>5__1 = 0f; <originalColor>5__2 = ((Graphic)text).color; <originalColor>5__2.a = 1f; break; case 1: <>1__state = -1; break; } if (<elapsedTime>5__1 < duration) { <elapsedTime>5__1 += Time.deltaTime; <alpha>5__3 = 1f - <elapsedTime>5__1 / duration; ((Graphic)text).color = new Color(<originalColor>5__2.r, <originalColor>5__2.g, <originalColor>5__2.b, <alpha>5__3); <>2__current = null; <>1__state = 1; return true; } ((Graphic)text).color = new Color(<originalColor>5__2.r, <originalColor>5__2.g, <originalColor>5__2.b, 0f); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadAndSwitchTrack>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string mp3Path; private UnityWebRequest <www>5__1; private AudioClip <clip>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAndSwitchTrack>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <www>5__1 = null; <clip>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <www>5__1 = UnityWebRequestMultimedia.GetAudioClip("file://" + mp3Path, (AudioType)13); <>1__state = -3; <>2__current = <www>5__1.SendWebRequest(); <>1__state = 1; return true; case 1: <>1__state = -3; if ((int)<www>5__1.result == 1) { <clip>5__2 = DownloadHandlerAudioClip.GetContent(<www>5__1); ((Object)<clip>5__2).name = Path.GetFileNameWithoutExtension(mp3Path); audioSource.clip = <clip>5__2; audioSource.Play(); isPlaying = true; UpdateMusicNameDisplay(((Object)<clip>5__2).name); Logger.LogWarning((object)("Now playing: " + ((Object)<clip>5__2).name)); <clip>5__2 = null; } else { Logger.LogError((object)("Failed to load audio clip: " + <www>5__1.error)); } <>m__Finally1(); <www>5__1 = null; return false; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<www>5__1 != null) { ((IDisposable)<www>5__1).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static AudioSource audioSource; private static bool isPlaying = false; private static string musicFolderPath = Path.Combine(Paths.PluginPath, "Shanty"); private static GameObject uiPanel; private static TextMeshProUGUI musicNameText; private static Button skipButton; private static Button pauseButton; private static string[] mp3Files; private void Awake() { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private void Update() { if (Input.GetKeyDown((KeyCode)284) && (Object)(object)audioSource != (Object)null) { if (isPlaying) { PauseMusic(); Logger.LogWarning((object)"Music paused with F3"); } else { ResumeMusic(); } } if (Input.GetKeyDown((KeyCode)285) && (Object)(object)audioSource != (Object)null) { SwitchTrack(); Logger.LogWarning((object)"Track switched with F4"); } } private static void LoadUIPrefab() { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown AssetBundle val = AssetUtils.LoadAssetBundleFromResources("tailwind", Assembly.GetExecutingAssembly()); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Failed to load tailwindbundle AssetBundle!"); return; } GameObject val2 = val.LoadAsset<GameObject>("Tailwind"); if ((Object)(object)val2 == (Object)null) { Logger.LogError((object)"Tailwind prefab not found in AssetBundle!"); val.Unload(false); return; } uiPanel = Object.Instantiate<GameObject>(val2); ((Object)uiPanel).name = "TailwindUI"; Object.DontDestroyOnLoad((Object)(object)uiPanel); Transform obj = uiPanel.transform.Find("MusicNameBackground/MusicName"); musicNameText = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null); Transform obj2 = uiPanel.transform.Find("SkipButton"); skipButton = ((obj2 != null) ? ((Component)obj2).GetComponent<Button>() : null); Transform obj3 = uiPanel.transform.Find("PauseButton"); pauseButton = ((obj3 != null) ? ((Component)obj3).GetComponent<Button>() : null); if ((Object)(object)musicNameText == (Object)null) { Logger.LogWarning((object)"MusicName text not found!"); } if ((Object)(object)skipButton == (Object)null) { Logger.LogWarning((object)"SkipButton not found!"); } if ((Object)(object)pauseButton == (Object)null) { Logger.LogWarning((object)"PauseButton not found!"); } if ((Object)(object)skipButton != (Object)null) { ((UnityEvent)skipButton.onClick).AddListener(new UnityAction(SwitchTrack)); } if ((Object)(object)pauseButton != (Object)null) { ((UnityEvent)pauseButton.onClick).AddListener(new UnityAction(PauseMusic)); } val.Unload(false); } private static void UpdateMusicNameDisplay(string trackName) { if ((Object)(object)musicNameText != (Object)null) { ((TMP_Text)musicNameText).text = trackName; ((TMP_Text)musicNameText).alpha = 1f; MonoBehaviour val = Object.FindObjectOfType<MonoBehaviour>(); val.StartCoroutine(FadeOutText(musicNameText, 3f)); } } [IteratorStateMachine(typeof(<FadeOutText>d__14))] private static IEnumerator FadeOutText(TextMeshProUGUI text, float duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FadeOutText>d__14(0) { text = text, duration = duration }; } private static void SwitchTrack() { if (mp3Files == null || mp3Files.Length == 0) { Logger.LogError((object)"No tracks available to switch!"); return; } string text = (((Object)(object)audioSource.clip != (Object)null) ? ((Object)audioSource.clip).name : ""); string text2; do { text2 = mp3Files[Random.Range(0, mp3Files.Length)]; } while (Path.GetFileNameWithoutExtension(text2) == text && mp3Files.Length > 1); MonoBehaviour val = Object.FindObjectOfType<MonoBehaviour>(); val.StartCoroutine(LoadAndSwitchTrack(text2)); } [IteratorStateMachine(typeof(<LoadAndSwitchTrack>d__16))] private static IEnumerator LoadAndSwitchTrack(string mp3Path) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAndSwitchTrack>d__16(0) { mp3Path = mp3Path }; } public static void PauseMusic() { if ((Object)(object)audioSource != (Object)null && isPlaying) { audioSource.Pause(); isPlaying = false; Logger.LogWarning((object)"Music paused"); } } public static void ResumeMusic() { if ((Object)(object)audioSource != (Object)null && !isPlaying) { audioSource.UnPause(); isPlaying = true; Logger.LogWarning((object)"Music resumed"); } } public static void StopMusic() { if ((Object)(object)audioSource != (Object)null && isPlaying) { audioSource.Stop(); isPlaying = false; Logger.LogWarning((object)"Music stopped"); } } }