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 SonicOST v0.0.3
SonicCustomOST/CustomSoundtrack.dll
Decompiled 4 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using EntityStates.MeridianEvent; using EntityStates.Missions.BrotherEncounter; using NAudio.Wave; using NAudio.Wave.SampleProviders; using Newtonsoft.Json; using On.EntityStates.MeridianEvent; using On.EntityStates.Missions.BrotherEncounter; using On.RoR2; using RoR2; using RoR2.ConVar; using UnityEngine; using UnityEngine.SceneManagement; [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("CustomSoundtrack")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+890e9cce56011104b4fce7bf625bc2a076e9c112")] [assembly: AssemblyProduct("CustomSoundtrack")] [assembly: AssemblyTitle("CustomSoundtrack")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace CustomSoundtrack; [BepInPlugin("com.penumbrah.customsoundtrack", "CustomSoundtrack", "2025.5.18")] public class CustomSoundtrack : BaseUnityPlugin { private enum GameState { Normal, BossFight, PostBoss } private string playbackMode = "next"; private string trackPath; private Dictionary<string, List<string>> bossPlaylists = new Dictionary<string, List<string>>(); private Dictionary<string, List<string>> postBossPlaylists = new Dictionary<string, List<string>>(); private Dictionary<string, List<string>> playlists = new Dictionary<string, List<string>>(); private GameState currentState; private string currentScene = ""; private List<string> currentPlaylist = new List<string>(); private string currentTrack = ""; private bool paused; private bool start; private AudioFileReader currentAudioFileReader; private FadeInOutSampleProvider currentFadeInOutSampleProvider; private WaveOutEvent player = new WaveOutEvent(); private bool logging; private string logPath = "log.txt"; private bool locked; public void Awake() { //IL_05a8: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Expected O, but got Unknown //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Expected O, but got Unknown //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Expected O, but got Unknown //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Expected O, but got Unknown //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_0607: Expected O, but got Unknown //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_0618: Expected O, but got Unknown //IL_061f: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Expected O, but got Unknown //IL_0630: Unknown result type (might be due to invalid IL or missing references) //IL_063a: Expected O, but got Unknown string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); logPath = Path.Combine(directoryName, logPath); trackPath = directoryName; if (!File.Exists(logPath)) { logging = true; } Settings settings = null; try { settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(Path.Combine(directoryName, "settings.json"))); } catch (Exception ex) { log("could not parse settings.json: " + Environment.NewLine + ex); } if (settings != null) { if (settings.trackPath != null && settings.trackPath != "") { trackPath = settings.trackPath; } if (settings.playbackMode != null) { playbackMode = settings.playbackMode; } if (settings.playlists != null) { foreach (Dictionary<string, List<string>> playlist in settings.playlists) { if (!playlist.ContainsKey("scenes")) { continue; } foreach (string item in playlist["scenes"]) { if (!playlists.Keys.Contains(item)) { playlists.Add(item, new List<string>()); } if (playlist.ContainsKey("tracks")) { foreach (string item2 in playlist["tracks"]) { playlists[item].Add(Path.Combine(trackPath, item2)); } } if (!bossPlaylists.Keys.Contains(item)) { bossPlaylists.Add(item, new List<string>()); } if (playlist.ContainsKey("bossTracks")) { foreach (string item3 in playlist["bossTracks"]) { bossPlaylists[item].Add(Path.Combine(trackPath, item3)); } } if (!postBossPlaylists.Keys.Contains(item)) { postBossPlaylists.Add(item, new List<string>()); } if (!playlist.ContainsKey("postBossTracks")) { continue; } foreach (string item4 in playlist["postBossTracks"]) { postBossPlaylists[item].Add(Path.Combine(trackPath, item4)); } } } } } playlists.Add("_default", new List<string>()); foreach (string item5 in from fileName in Directory.GetFiles(trackPath, "*", SearchOption.AllDirectories) where fileName.ToLower().EndsWith(".aiff") || fileName.ToLower().EndsWith(".mp3") || fileName.ToLower().EndsWith(".wav") select fileName) { playlists["_default"].Add(item5); } if (logging) { log("track directory: " + trackPath); log("playback mode: " + playbackMode); log("playlists: "); foreach (string key in playlists.Keys) { log(" " + key + ": "); foreach (string item6 in playlists[key]) { log(" " + item6); } } log("boss playlists: "); foreach (string key2 in bossPlaylists.Keys) { log(" " + key2 + ": "); foreach (string item7 in bossPlaylists[key2]) { log(" " + item7); } } log("tp playlists: "); foreach (string key3 in postBossPlaylists.Keys) { log(" " + key3 + ": "); foreach (string item8 in postBossPlaylists[key3]) { log(" " + item8); } } } SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "splash") { start = true; } if (start && currentScene != ((Scene)(ref scene)).name) { currentState = GameState.Normal; currentPlaylist = playlists["_default"]; currentScene = ((Scene)(ref scene)).name; nextPlaylist(); } if (logging) { log("loaded scene: " + ((Scene)(ref scene)).name); } }; TeleporterInteraction.RpcClientOnActivated += (hook_RpcClientOnActivated)delegate(orig_RpcClientOnActivated orig, TeleporterInteraction self, GameObject activator) { orig.Invoke(self, activator); if (currentState != GameState.BossFight && currentState != GameState.PostBoss) { currentState = GameState.BossFight; nextPlaylist(); } if (logging) { log("activated teleporter"); } }; TeleporterInteraction.onTeleporterChargedGlobal += delegate { if (currentState != GameState.PostBoss) { currentState = GameState.PostBoss; nextPlaylist(); } if (logging) { log("tp event over"); } }; Phase1.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Phase1 self) { orig.Invoke(self); if (currentState != GameState.BossFight) { currentState = GameState.BossFight; nextPlaylist(); } if (logging) { log("started mithrix fight"); } }; BossDeath.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, BossDeath self) { orig.Invoke(self); if (currentState != GameState.PostBoss) { currentState = GameState.PostBoss; nextPlaylist(); } if (logging) { log("finished mithrix fight"); } }; Phase1.OnEnter += (hook_OnEnter)delegate(orig_OnEnter orig, Phase1 self) { orig.Invoke(self); if (currentState != GameState.BossFight) { currentState = GameState.BossFight; nextPlaylist(); } if (logging) { log("started false son fight"); } }; Phase3.OnExit += (hook_OnExit)delegate(orig_OnExit orig, Phase3 self) { orig.Invoke(self); if (currentState != 0) { currentState = GameState.Normal; nextPlaylist(); } if (logging) { log("finished false son fight"); } }; AudioFocusedOnlyConVar.OnApplicationFocus += (hook_OnApplicationFocus)delegate(orig_OnApplicationFocus orig, BaseConVar self, bool isFocussed) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 orig.Invoke(self, isFocussed); if (isFocussed && (int)player.PlaybackState == 2) { paused = false; if (!locked) { player.Play(); } } if (!isFocussed && (int)player.PlaybackState == 1) { paused = true; if (!locked) { player.Pause(); } } }; MusicController.PickCurrentTrack += new hook_PickCurrentTrack(disableOriginalSoundtrack); MusicTrackOverride.PickMusicTrack += new hook_PickMusicTrack(disableOriginalSoundtrack); } private void disableOriginalSoundtrack(orig_PickMusicTrack orig, MusicController self, ref MusicTrackDef track) { orig.Invoke(self, ref track); track = null; } private void disableOriginalSoundtrack(orig_PickCurrentTrack orig, MusicController self, ref MusicTrackDef track) { orig.Invoke(self, ref track); track = null; } public void Update() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (start && !locked && (int)player.PlaybackState == 0) { nextTrack(); } applyVolume(); } private void nextPlaylist() { switch (currentState) { case GameState.Normal: if (playlists.ContainsKey(currentScene) && playlists[currentScene].Count > 0) { currentPlaylist = playlists[currentScene]; } break; case GameState.BossFight: if (bossPlaylists.ContainsKey(currentScene) && bossPlaylists[currentScene].Count > 0) { currentPlaylist = bossPlaylists[currentScene]; break; } return; case GameState.PostBoss: if (postBossPlaylists.ContainsKey(currentScene) && postBossPlaylists[currentScene].Count > 0) { currentPlaylist = postBossPlaylists[currentScene]; } break; } if (playbackMode == "next") { nextTrack(); return; } Random randomizer = new Random(); currentPlaylist = currentPlaylist.OrderBy((string _) => randomizer.Next()).ToList(); if (playbackMode == "shuffle") { nextTrack(); return; } currentPlaylist = currentPlaylist.GetRange(0, 1); nextTrack(); } private void nextTrack() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (currentPlaylist.Count <= 0) { return; } string text = currentPlaylist[0]; if (!(text != currentTrack) && (int)player.PlaybackState != 0) { return; } FadeInOutSampleProvider val = currentFadeInOutSampleProvider; currentTrack = text; currentAudioFileReader = new AudioFileReader(currentTrack); currentFadeInOutSampleProvider = new FadeInOutSampleProvider((ISampleProvider)(object)currentAudioFileReader, false); currentPlaylist.Add(currentTrack); currentPlaylist.RemoveAt(0); applyVolume(); if (logging) { log("current track: " + currentTrack); log("current playlist: "); foreach (string item in currentPlaylist) { log(" " + item); } } if (locked) { return; } locked = true; FadeInOutSampleProvider newTrack = currentFadeInOutSampleProvider; FadeInOutSampleProvider oldTrack = val; new Thread((ThreadStart)delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)player.PlaybackState != 0) { oldTrack.BeginFadeOut(1500.0); Thread.Sleep(1500); player.Stop(); } WaveExtensionMethods.Init((IWavePlayer)(object)player, (ISampleProvider)(object)newTrack, false); if (!paused) { player.Play(); } locked = false; }).Start(); } private void applyVolume() { if (currentAudioFileReader != null) { float.TryParse(((BaseConVar)AudioManager.cvVolumeMaster).GetString(), out var result); float.TryParse(((BaseConVar)AudioManager.cvVolumeMsx).GetString(), out var result2); result /= 100f; result2 /= 100f; currentAudioFileReader.Volume = result * result2; } } private void log(string message) { File.AppendAllText(logPath, "[" + DateTime.Now.ToString("hh:mm:ss") + "] " + message + Environment.NewLine); } } public class Settings { public string playbackMode { get; set; } public string trackPath { get; set; } public List<Dictionary<string, List<string>>> playlists { get; set; } }