using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("EQLevelUpDing")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("EQLevelUpDing")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5e232ec2-b494-4be9-a9df-5787616b1a6c")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace EQLevelUpDing; [BepInPlugin("com.yourname.eqlevelupding", "EQ Level-Up Ding", "1.0.0")] public class Plugin : BaseUnityPlugin { private static AudioClip dingClip = null; private static AudioSource sfxSource = null; private static int lastKnownLevel = -1; private static float nextCheckTime = 0f; private static bool soundsTried = false; private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"EQ Level-Up Ding 1.0.0 loaded (1.22.56-style, menu-safe)"); } private void Update() { if (!(Time.time < nextCheckTime)) { nextCheckTime = Time.time + 0.25f; TryLoadSound(); CheckLevelUpDing(); } } private static void CheckLevelUpDing() { if (!IsGameplayWorld()) { lastKnownLevel = -1; } else { if ((Object)(object)GameData.PlayerStats == (Object)null) { return; } int level = GameData.PlayerStats.Level; if (lastKnownLevel < 0) { lastKnownLevel = level; } else if (level > lastKnownLevel) { int num = level - lastKnownLevel; lastKnownLevel = level; if (num > 3) { Debug.Log((object)("[EQDing] Level jump ignored: " + (level - num) + " -> " + level)); return; } Debug.Log((object)("[EQDing] Level-up: " + (level - num) + " -> " + level)); PlayDing(); } else if (level < lastKnownLevel) { lastKnownLevel = level; } } } private static bool IsGameplayWorld() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string text = ((Scene)(ref activeScene)).name ?? ""; if (string.IsNullOrEmpty(text)) { return false; } string text2 = text.ToLowerInvariant(); if (text2.Contains("menu") || text2.Contains("title") || text2.Contains("login") || text2.Contains("character") || text2.Contains("charselect") || text2.Contains("lobby") || text2.Contains("boot") || text2.Contains("start") || text2.Contains("select") || text2.Contains("load")) { return false; } if ((Object)(object)GameData.PlayerStats == (Object)null) { return false; } if ((Object)(object)GameData.PlayerControl == (Object)null) { return false; } return true; } catch { return false; } } private static void PlayDing() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)dingClip == (Object)null) && IsGameplayWorld()) { EnsureSfxSource(); if ((Object)(object)sfxSource != (Object)null) { sfxSource.PlayOneShot(dingClip, 1f); Debug.Log((object)("[EQDing] *sound* " + ((Object)dingClip).name)); } else { Vector3 val = (((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform.position : Vector3.zero); AudioSource.PlayClipAtPoint(dingClip, val, 1f); Debug.Log((object)("[EQDing] *sound* " + ((Object)dingClip).name + " (fallback)")); } } } private static void EnsureSfxSource() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)sfxSource != (Object)null)) { GameObject val = new GameObject("EQLevelUpDing_SFX"); Object.DontDestroyOnLoad((Object)(object)val); sfxSource = val.AddComponent(); sfxSource.playOnAwake = false; sfxSource.spatialBlend = 0f; sfxSource.volume = 1f; sfxSource.bypassListenerEffects = true; } } private static void TryLoadSound() { if (soundsTried) { return; } soundsTried = true; try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, "EQ_DING.wav"); dingClip = LoadWav(text); Debug.Log((object)("[EQDing] EQ_DING loaded: " + ((Object)(object)dingClip != (Object)null) + " path=" + text)); } catch (Exception ex) { Debug.LogWarning((object)("[EQDing] Load failed: " + ex.Message)); } } private static AudioClip LoadWav(string path) { try { if (!File.Exists(path)) { Debug.LogWarning((object)("[EQDing] Missing file: " + path)); return null; } byte[] array = File.ReadAllBytes(path); if (array.Length < 44) { return null; } if (array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70) { return null; } int num = BitConverter.ToInt16(array, 22); int num2 = BitConverter.ToInt32(array, 24); int num3 = BitConverter.ToInt16(array, 34); int num4 = BitConverter.ToInt16(array, 20); int i = 12; int num5 = 0; int num6; for (; i + 8 < array.Length; i += 8 + num6) { string text = Encoding.ASCII.GetString(array, i, 4); num6 = BitConverter.ToInt32(array, i + 4); if (text == "data") { i += 8; num5 = num6; break; } } if (num5 <= 0 || i + num5 > array.Length) { return null; } int num7; float[] array2; if (num4 == 1 && num3 == 16) { num7 = num5 / 2; array2 = new float[num7]; for (int j = 0; j < num7; j++) { short num8 = BitConverter.ToInt16(array, i + j * 2); array2[j] = (float)num8 / 32768f; } } else if (num4 == 1 && num3 == 8) { num7 = num5; array2 = new float[num7]; for (int k = 0; k < num7; k++) { array2[k] = (float)(array[i + k] - 128) / 128f; } } else if (num4 == 1 && num3 == 24) { num7 = num5 / 3; array2 = new float[num7]; for (int l = 0; l < num7; l++) { int num9 = array[i + l * 3]; int num10 = array[i + l * 3 + 1]; int num11 = array[i + l * 3 + 2]; int num12 = num9 | (num10 << 8) | (num11 << 16); if ((num12 & 0x800000) != 0) { num12 |= -16777216; } array2[l] = (float)num12 / 8388608f; } } else { if (num4 != 3 || num3 != 32) { Debug.LogWarning((object)("[EQDing] Unsupported WAV format: " + path)); return null; } num7 = num5 / 4; array2 = new float[num7]; for (int m = 0; m < num7; m++) { array2[m] = BitConverter.ToSingle(array, i + m * 4); } } int num13 = num7 / Math.Max(1, num); AudioClip val = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num13, num, num2, false); val.SetData(array2, 0); ((Object)val).name = "EQ_DING"; return val; } catch (Exception ex) { Debug.LogWarning((object)("[EQDing] WAV parse failed: " + ex.Message)); return null; } } }