using 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()
{
}
}
}