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 ComingInHotMod v1.0.0
MyRepoMod.dll
Decompiled a year agousing System; using System.Collections; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using MyAudioMod; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MyRepoMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MyRepoMod")] [assembly: AssemblyTitle("MyRepoMod")] [assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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; } } } [HarmonyPatch(typeof(TumbleUI), "Update")] public static class TumbleStartPatch { private static bool wasActive; [HarmonyPostfix] public static void Postfix(TumbleUI __instance) { //IL_01b9: Unknown result type (might be due to invalid IL or missing references) if (!LevelGenerator.Instance.Generated) { return; } LoadingUI instance = LoadingUI.instance; if ((Object)(object)instance != (Object)null) { Type type = ((object)instance).GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "levelAnimationCompleted"); if (fieldInfo != null && !(bool)(fieldInfo.GetValue(instance) ?? ((object)false))) { return; } } PlayerController instance2 = PlayerController.instance; if ((Object)(object)instance2 == (Object)null) { return; } Type type2 = ((object)instance2).GetType(); FieldInfo fieldInfo2 = AccessTools.Field(type2, "InputDisableTimer"); if (fieldInfo2 != null) { float num = (float)(fieldInfo2.GetValue(instance2) ?? ((object)0f)); if (num > 0f) { return; } } PlayerAvatar playerAvatarScript = instance2.playerAvatarScript; if (!((Object)(object)playerAvatarScript == (Object)null)) { Type type3 = ((object)playerAvatarScript).GetType(); bool flag = (bool)(AccessTools.Field(type3, "isTumbling")?.GetValue(playerAvatarScript) ?? ((object)false)); bool flag2 = (bool)(AccessTools.Field(type3, "isDisabled")?.GetValue(playerAvatarScript) ?? ((object)false)); bool flag3 = flag && !flag2; if (flag3 && !wasActive && Time.timeSinceLevelLoad > 1f) { Plugin.Logger.LogInfo((object)"\ud83d\udd25 Tumble started — playing Hot.wav"); Plugin.Instance?.PlayComingInHotAt(((Component)__instance).transform.position); } wasActive = flag3; } } } [HarmonyPatch(typeof(TumbleUI), "Update")] public static class TumbleUI_Update_Patch { private static bool previousCanExit; [HarmonyPostfix] public static void Postfix(TumbleUI __instance) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)Plugin.Instance == (Object)null) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(TumbleUI), "canExit"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(TumbleUI), "canExitPrevious"); if (fieldInfo == null || fieldInfo2 == null) { Plugin.Logger.LogError((object)"❌ Could not access canExit or canExitPrevious fields via reflection."); return; } bool flag = (bool)fieldInfo.GetValue(__instance); bool flag2 = (bool)fieldInfo2.GetValue(__instance); if (flag && !flag2) { Plugin.Logger.LogInfo((object)"\ud83d\udca5 Detected tumble exit transition — replacing sound with ComingInHot.wav"); object? obj = AccessTools.Field(typeof(TumbleUI), "canExitSound")?.GetValue(__instance); Sound val = (Sound)((obj is Sound) ? obj : null); if ((Object)(object)val?.Source != (Object)null && val.Source.isPlaying) { val.Source.Stop(); Plugin.Logger.LogInfo((object)"❌ Original tumble sound stopped."); } ((MonoBehaviour)Plugin.Instance).StartCoroutine(PlaySoundDelayed(((Component)__instance).transform.position)); } } private static IEnumerator PlaySoundDelayed(Vector3 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) yield return (object)new WaitForSeconds(0.1f); Plugin.Logger.LogInfo((object)$"\ud83d\udd0a Playing ComingInHot at {position}"); Plugin.Instance.PlayComingInHotAt(position); } } namespace MyAudioMod { [BepInPlugin("com.yourname.audioMod", "Audio Mod", "1.0.0")] public class Plugin : BaseUnityPlugin { public class AutoDestroyAudio : MonoBehaviour { public float duration; private void Start() { Object.Destroy((Object)(object)((Component)this).gameObject, duration); } } private ManualLogSource _logger = null; private AudioClip? comingInHotClip; public static bool ReadyToPlayHot; public static ManualLogSource Logger => Instance._logger; public static Plugin Instance { get; private set; } private void Awake() { Instance = this; _logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"\ud83d\udd0a Audio Mod initializing..."); Harmony.CreateAndPatchAll(typeof(Plugin), (string)null); Harmony.CreateAndPatchAll(typeof(TumbleStartPatch), (string)null); Harmony.CreateAndPatchAll(typeof(TumbleSoundReplacePatch), (string)null); ((MonoBehaviour)this).StartCoroutine(MarkReadyToPlay()); ((MonoBehaviour)this).StartCoroutine(LoadEmbeddedClip("MyRepoMod.Hot.wav", delegate(AudioClip? clip) { comingInHotClip = clip; })); } private IEnumerator MarkReadyToPlay() { Logger.LogInfo((object)"\ud83d\udd53 Waiting 2 seconds before allowing Hot.wav playback..."); yield return (object)new WaitForSeconds(2f); ReadyToPlayHot = true; Logger.LogInfo((object)"✅ ReadyToPlayHot is now TRUE"); } private IEnumerator SetupInputHandler() { yield return (object)new WaitForSeconds(2f); GameObject go = new GameObject("AudioInputHandler"); Object.DontDestroyOnLoad((Object)(object)go); go.AddComponent<AudioUpdate>().Plugin = this; } private IEnumerator LoadEmbeddedClip(string resourceName, Action<AudioClip?> callback) { Assembly assembly = Assembly.GetExecutingAssembly(); using Stream stream = assembly.GetManifestResourceStream(resourceName); if (stream == null) { Logger.LogError((object)("❌ Embedded WAV not found: " + resourceName)); yield break; } string tempPath = Path.Combine(Application.temporaryCachePath, Path.GetFileName(resourceName)); using (FileStream file = File.Create(tempPath)) { stream.CopyTo(file); } UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip("file://" + tempPath, (AudioType)20); yield return request.SendWebRequest(); if ((int)request.result == 1) { AudioClip clip = DownloadHandlerAudioClip.GetContent(request); callback(clip); Logger.LogInfo((object)("✅ Loaded " + resourceName)); } else { Logger.LogError((object)("❌ Failed to load " + resourceName + ": " + request.error)); } } public void PlayComingInHot() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)comingInHotClip != (Object)null) { AudioSource val = new GameObject("LocalAudio").AddComponent<AudioSource>(); val.clip = comingInHotClip; val.spatialBlend = 0f; val.volume = 1f; val.Play(); Object.Destroy((Object)(object)((Component)val).gameObject, comingInHotClip.length); } } public void PlayComingInHotAt(Vector3 position) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)comingInHotClip == (Object)null) { Logger.LogError((object)"❌ Hot.wav is null."); return; } Logger.LogWarning((object)"\ud83d\udd25 Hot.wav triggered!"); Logger.LogWarning((object)Environment.StackTrace); GameObject val = new GameObject("HotAudio"); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.clip = comingInHotClip; val2.volume = 1f; val2.spatialBlend = 0f; val2.Play(); val.AddComponent<AutoDestroyAudio>().duration = comingInHotClip.length + 0.5f; } private void EnsureAudioListenerExists() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if ((Object)(object)Object.FindObjectOfType<AudioListener>() == (Object)null) { Logger.LogWarning((object)"⚠\ufe0f No AudioListener found — creating fallback AudioListener."); GameObject val = new GameObject("FallbackAudioListener"); val.AddComponent<AudioListener>(); Object.DontDestroyOnLoad((Object)(object)val); Logger.LogInfo((object)"✅ Fallback AudioListener created."); } else { Logger.LogInfo((object)"\ud83c\udfa7 AudioListener found in scene."); } } } public class AudioUpdate : MonoBehaviour { public Plugin? Plugin; private void Update() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown((KeyCode)116)) { MyAudioMod.Plugin.Logger.LogInfo((object)"\ud83d\udd34 Manual test: playing Hot.wav in 2D"); Plugin?.PlayComingInHotAt(Vector3.zero); } } } [HarmonyPatch(typeof(Sound), "Play")] public static class DebugSoundPlay { [HarmonyPrefix] public static void Prefix(Sound __instance) { if (__instance.Sounds != null && __instance.Sounds.Length != 0) { AudioClip obj = __instance.Sounds[0]; string text = ((obj != null) ? ((Object)obj).name : null) ?? "null"; Plugin.Logger.LogInfo((object)("\ud83d\udd0a Sound.Play called: " + text)); } } } [HarmonyPatch(typeof(Sound), "Play")] public static class TumbleSoundInterceptPatch { [HarmonyPrefix] public static bool Prefix(Sound __instance, Vector3 position) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) StackTrace stackTrace = new StackTrace(); for (int i = 0; i < stackTrace.FrameCount; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase?.DeclaringType?.Name == "TumbleUI") || !(methodBase.Name == "Update")) { continue; } Type declaringType = methodBase.DeclaringType; FieldInfo fieldInfo = AccessTools.Field(declaringType, "canExitSound"); StackFrame[] frames = stackTrace.GetFrames(); foreach (StackFrame stackFrame in frames) { if (!(stackFrame?.GetMethod()?.DeclaringType == declaringType)) { continue; } object value = Traverse.Create(stackFrame.GetMethod().IsStatic ? null : stackFrame.GetMethod()?.ReflectedType).Field("this").GetValue(); if (value != null) { object? value2 = fieldInfo.GetValue(value); Sound val = (Sound)((value2 is Sound) ? value2 : null); if (val == __instance) { Plugin.Logger.LogInfo((object)"\ud83c\udfaf Intercepted canExitSound from TumbleUI. Playing ComingInHot.wav instead."); Plugin.Instance?.PlayComingInHotAt(position); return false; } } } } return true; } } [HarmonyPatch(typeof(Sound), "Play")] public static class TumbleSoundReplacePatch { [HarmonyPrefix] public static bool Prefix(Sound __instance, Vector3 position) { AudioClip value = Traverse.Create((object)__instance).Field("clip").GetValue<AudioClip>(); if ((Object)(object)value != (Object)null && ((Object)value).name.Contains("player tumble can exit")) { Plugin.Logger.LogInfo((object)("\ud83d\ude45 Suppressing tumble exit sound: " + ((Object)value).name)); return false; } return true; } } [HarmonyPatch] public static class TumbleUI_Update_Patch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("TumbleUI"); if (type == null) { Plugin.Logger.LogError((object)"❌ TumbleUI type not found!"); return null; } MethodInfo methodInfo = AccessTools.Method(type, "Update", (Type[])null, (Type[])null); if (methodInfo == null) { Plugin.Logger.LogError((object)"❌ TumbleUI.Update not found!"); return null; } Plugin.Logger.LogInfo((object)("✅ Patch target resolved: " + methodInfo.DeclaringType.FullName + "." + methodInfo.Name)); return methodInfo; } private static bool Prefix(object __instance) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "canExit"); FieldInfo fieldInfo2 = AccessTools.Field(type, "canExitPrevious"); if (fieldInfo == null || fieldInfo2 == null) { Plugin.Logger.LogWarning((object)"❌ TumbleUI fields not found."); return true; } bool flag = (bool)fieldInfo.GetValue(__instance); bool flag2 = (bool)fieldInfo2.GetValue(__instance); if (flag && !flag2) { Plugin.Logger.LogInfo((object)"\ud83d\udca5 Detected tumble exit — playing ComingInHot.wav"); Plugin.Instance.PlayComingInHotAt(((Component)(MonoBehaviour)__instance).transform.position); } return true; } } } namespace MyRepoMod { [HarmonyPatch(typeof(PlayerController))] internal static class ExamplePlayerControllerPatch { [HarmonyPrefix] [HarmonyPatch("Update")] private static void Update_Prefix(PlayerController __instance) { MyRepoMod.Logger.LogDebug((object)$"{__instance} Update Prefix"); } [HarmonyPostfix] [HarmonyPatch("Update")] private static void Update_Postfix(PlayerController __instance) { MyRepoMod.Logger.LogDebug((object)$"{__instance} Update Postfix"); } } [BepInPlugin("YourName.MyRepoMod", "MyRepoMod", "1.0")] public class MyRepoMod : BaseUnityPlugin { internal static MyRepoMod Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } }