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 PluginConfig.API; using PluginConfig.API.Fields; using UnityEngine; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Ultraflash")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Ultraflash")] [assembly: AssemblyTitle("Ultraflash")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace UltrakillFlashbangMod { [BepInPlugin("com.smileos.flashbangmod", "ULTRAKILL Flashbang Roulette", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class FlashbangMod : BaseUnityPlugin { public static ManualLogSource Log = null; public static FlashbangMod Instance = null; private Harmony? harmony; private static Random rng = new Random(); private static AudioClip? customMp3Audio; private static AudioClip? fallbackProceduralAudio; private static AudioClip? fallbackSubBassAudio; private static string audioFilePath = string.Empty; public static PluginConfigurator config = null; public static FloatField flashChance = null; public static FloatField flashVolume = null; public static FloatField bassBoost = null; public static BoolField forceProceduralAudio = null; private void Awake() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"=== [Flashbang Mod] Configurable Roulette Initialized ==="); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Awake() called. Starting setup..."); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Creating PluginConfigurator menu..."); config = PluginConfigurator.Create("Flashbang Roulette", "com.smileos.flashbangmod"); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Initializing config fields..."); flashChance = new FloatField(config.rootPanel, "Flashbang Chance (%)", "flashChance", 5f, 0f, 100f); flashVolume = new FloatField(config.rootPanel, "Flashbang Volume", "flashVolume", 2f, 0f, 1000f); bassBoost = new FloatField(config.rootPanel, "Bass Boost Intensity", "bassBoost", 1f, 0f, 50f); forceProceduralAudio = new BoolField(config.rootPanel, "Force Built-in Sound (Ignore MP3)", "forceProcedural", false); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Resolving audio file path..."); string path = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty; audioFilePath = Path.Combine(path, "flashbang.mp3"); Log.LogDebug((object)("[Flashbang Mod - DEBUG] Audio path resolved to: " + audioFilePath)); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Generating fallback procedural audio and sub-bass..."); fallbackProceduralAudio = CreateProceduralFlashbangSound(); fallbackSubBassAudio = CreateProceduralSubBassSound(); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Starting LoadFlashbangAudio coroutine..."); ((MonoBehaviour)this).StartCoroutine(LoadFlashbangAudio()); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Applying Harmony patches..."); try { harmony = new Harmony("com.smileos.flashbangmod"); harmony.PatchAll(); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Harmony patches applied successfully."); } catch (Exception ex) { Log.LogError((object)("[Flashbang Mod - ERROR] Failed to apply Harmony patches: " + ex.Message)); } } private void OnDestroy() { Log.LogDebug((object)"[Flashbang Mod - DEBUG] OnDestroy() called. Unpatching Harmony..."); Harmony? obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static bool RollFlashbang() { double num = rng.NextDouble() * 100.0; bool flag = num < (double)flashChance.value; Log.LogDebug((object)string.Format("[Flashbang Mod - DEBUG] Rolled: {0:F2} / Threshold: {1:F2} | Result: {2}", num, flashChance.value, flag ? "BANG!" : "Safe")); return flag; } private static AudioClip CreateProceduralFlashbangSound() { Log.LogDebug((object)"[Flashbang Mod - DEBUG] CreateProceduralFlashbangSound() started."); int num = 44100; float num2 = 3.5f; int num3 = Mathf.RoundToInt((float)num * num2); float[] array = new float[num3]; for (int i = 0; i < num3; i++) { float num4 = (float)i / (float)num; float num5 = Random.Range(-1f, 1f) * Mathf.Exp((0f - num4) * 2f); float num6 = Mathf.Sin(MathF.PI * 4800f * num4) * Mathf.Exp((0f - num4) * 1.2f); array[i] = num5 * 0.6f + num6 * 0.4f; } AudioClip val = AudioClip.Create("BuiltInFlashbang", num3, 1, num, false); val.SetData(array, 0); Log.LogDebug((object)"[Flashbang Mod - DEBUG] Procedural audio generated successfully."); return val; } private static AudioClip CreateProceduralSubBassSound() { int num = 44100; float num2 = 2f; int num3 = Mathf.RoundToInt((float)num * num2); float[] array = new float[num3]; for (int i = 0; i < num3; i++) { float num4 = (float)i / (float)num; float num5 = Mathf.Lerp(120f, 25f, num4 / num2); float num6 = Mathf.Sin(MathF.PI * 2f * num5 * num4) * Mathf.Exp((0f - num4) * 3f); array[i] = num6; } AudioClip val = AudioClip.Create("SubBassBoom", num3, 1, num, false); val.SetData(array, 0); return val; } private IEnumerator LoadFlashbangAudio() { Log.LogDebug((object)"[Flashbang Mod - DEBUG] LoadFlashbangAudio() coroutine started."); if (!File.Exists(audioFilePath)) { Log.LogWarning((object)("[Flashbang Mod] 'flashbang.mp3' not found at " + audioFilePath + ". Will use built-in procedural audio instead.")); yield break; } Log.LogDebug((object)"[Flashbang Mod - DEBUG] MP3 file found. Sending UnityWebRequest..."); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip("file://" + audioFilePath, (AudioType)13); try { yield return www.SendWebRequest(); if ((int)www.result == 2 || (int)www.result == 3) { Log.LogError((object)("[Flashbang Mod] MP3 Load Error: " + www.error)); yield break; } Log.LogDebug((object)"[Flashbang Mod - DEBUG] WebRequest successful. Extracting AudioClip..."); customMp3Audio = DownloadHandlerAudioClip.GetContent(www); Log.LogInfo((object)"[Flashbang Mod] Custom MP3 loaded successfully!"); } finally { ((IDisposable)www)?.Dispose(); } } public static void TriggerFlashbang() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Expected O, but got Unknown //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo((object)"[Flashbang Mod] BANG! Flashbanged on weapon fire!"); AudioClip val = fallbackProceduralAudio; if (forceProceduralAudio.value) { Log.LogDebug((object)"[Flashbang Mod - DEBUG] Config: Force Procedural is TRUE."); } else if ((Object)(object)customMp3Audio != (Object)null) { Log.LogDebug((object)"[Flashbang Mod - DEBUG] Config: Using custom MP3 audio."); val = customMp3Audio; } else { Log.LogDebug((object)"[Flashbang Mod - DEBUG] Custom MP3 not loaded. Falling back to procedural."); } GameObject val2 = null; if ((Object)(object)val != (Object)null && (Object)(object)Camera.main != (Object)null) { Log.LogDebug((object)$"[Flashbang Mod - DEBUG] Spawning stacked audio sources for earrape volume {flashVolume.value}."); val2 = new GameObject("FlashbangAudioSource"); val2.transform.SetParent(((Component)Camera.main).transform, false); val2.transform.localPosition = Vector3.zero; int num = Mathf.Clamp(Mathf.RoundToInt(flashVolume.value), 1, 20); for (int i = 0; i < num; i++) { AudioSource val3 = val2.AddComponent(); val3.clip = val; val3.volume = 1f; val3.spatialBlend = 0f; val3.Play(); } if ((Object)(object)fallbackSubBassAudio != (Object)null && bassBoost.value > 0f) { int num2 = Mathf.Clamp(Mathf.RoundToInt(bassBoost.value * 2f), 1, 20); for (int j = 0; j < num2; j++) { AudioSource val4 = val2.AddComponent(); val4.clip = fallbackSubBassAudio; val4.volume = 1f; val4.spatialBlend = 0f; val4.Play(); } } } else { Log.LogWarning((object)"[Flashbang Mod - WARNING] Could not play audio! Camera.main or clipToPlay is null."); } Log.LogDebug((object)"[Flashbang Mod - DEBUG] Creating dedicated FlashbangOverlayCanvas..."); GameObject val5 = new GameObject("FlashbangOverlayCanvas"); Canvas val6 = val5.AddComponent(); val6.renderMode = (RenderMode)0; val6.sortingOrder = 32767; CanvasScaler val7 = val5.AddComponent(); val7.uiScaleMode = (ScaleMode)1; val7.referenceResolution = new Vector2(1920f, 1080f); val5.AddComponent(); GameObject val8 = new GameObject("FlashbangPanel"); val8.transform.SetParent(val5.transform, false); RectTransform val9 = val8.AddComponent(); val9.anchorMin = Vector2.zero; val9.anchorMax = Vector2.one; val9.sizeDelta = Vector2.zero; val9.offsetMin = Vector2.zero; val9.offsetMax = Vector2.zero; Image val10 = val8.AddComponent(); ((Graphic)val10).color = Color.white; if ((Object)(object)Instance != (Object)null) { ((MonoBehaviour)Instance).StartCoroutine(ClearFlash(val5, val2, val10)); } } private static IEnumerator ClearFlash(GameObject canvasObj, GameObject? audioObj, Image img) { float fullBlindDuration = 2f; float fadeOutDuration = 1.5f; Log.LogDebug((object)$"[Flashbang Mod - DEBUG] ClearFlash() started. Solid white for {fullBlindDuration}s, fading over {fadeOutDuration}s."); yield return (object)new WaitForSeconds(fullBlindDuration); if ((Object)(object)img != (Object)null) { Log.LogDebug((object)"[Flashbang Mod - DEBUG] Full blind finished. Beginning alpha fade..."); float elapsed = 0f; Color startColor = ((Graphic)img).color; while (elapsed < fadeOutDuration && !((Object)(object)img == (Object)null)) { elapsed += Time.deltaTime; float alpha = Mathf.Lerp(1f, 0f, elapsed / fadeOutDuration); startColor.a = alpha; ((Graphic)img).color = startColor; yield return null; } } Log.LogDebug((object)"[Flashbang Mod - DEBUG] Fade complete. Cutting off sound and destroying canvas overlay..."); if ((Object)(object)audioObj != (Object)null) { Object.Destroy((Object)(object)audioObj); } if ((Object)(object)canvasObj != (Object)null) { Object.Destroy((Object)(object)canvasObj); } } } [HarmonyPatch(typeof(Revolver), "Shoot")] public static class RevolverShootPatch { public static void Postfix() { FlashbangMod.Log.LogDebug((object)"[Flashbang Mod - DEBUG] Revolver fired. Rolling dice..."); if (FlashbangMod.RollFlashbang()) { FlashbangMod.TriggerFlashbang(); } } } [HarmonyPatch(typeof(Shotgun), "Shoot")] public static class ShotgunShootPatch { public static void Postfix() { FlashbangMod.Log.LogDebug((object)"[Flashbang Mod - DEBUG] Shotgun fired. Rolling dice..."); if (FlashbangMod.RollFlashbang()) { FlashbangMod.TriggerFlashbang(); } } } [HarmonyPatch(typeof(Nailgun), "Shoot")] public static class NailgunShootPatch { public static void Postfix() { FlashbangMod.Log.LogDebug((object)"[Flashbang Mod - DEBUG] Nailgun fired. Rolling dice..."); if (FlashbangMod.RollFlashbang()) { FlashbangMod.TriggerFlashbang(); } } } [HarmonyPatch(typeof(Railcannon), "Shoot")] public static class RailcannonShootPatch { public static void Postfix() { FlashbangMod.Log.LogDebug((object)"[Flashbang Mod - DEBUG] Railcannon fired. Rolling dice..."); if (FlashbangMod.RollFlashbang()) { FlashbangMod.TriggerFlashbang(); } } } [HarmonyPatch(typeof(RocketLauncher), "Shoot")] public static class RocketLauncherShootPatch { public static void Postfix() { FlashbangMod.Log.LogDebug((object)"[Flashbang Mod - DEBUG] RocketLauncher fired. Rolling dice..."); if (FlashbangMod.RollFlashbang()) { FlashbangMod.TriggerFlashbang(); } } } }