using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BoneLib; using BoneLib.BoneMenu; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using QuickFoxy; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.XR; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(QuickFoxyMod), "QuickFoxy", "1.0.1", "nontendo", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("QuickFoxy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("QuickFoxy")] [assembly: AssemblyTitle("QuickFoxy")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] 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 QuickFoxy { public static class FoxyController { private const int FrameCount = 13; private const float FrameTime = 0.06f; private static Texture2D[]? _frames; private static AudioClip? _clip; private static bool _loadTried; private static GameObject? _quad; private static MeshRenderer? _mr; private static Material? _mat; private static AudioSource? _src; private static float _rollTimer; private static bool _scaring; private static float _scareStart; private static float _scareLen = 1.8f; public static void Update() { if (!FoxySettings.Enabled) { if (_scaring) { EndScare(); } return; } if (_scaring) { UpdateScare(); return; } _rollTimer += Time.deltaTime; if (!(_rollTimer < 1f)) { _rollTimer -= 1f; int num = Mathf.Max(1, FoxySettings.Odds); if (Random.Range(0, num) == 0) { Trigger(); } } } public static void Trigger() { EnsureAssets(); if (_frames != null && !((Object)(object)_quad == (Object)null)) { _scaring = true; _scareStart = Time.time; if ((Object)(object)_src != (Object)null && (Object)(object)_clip != (Object)null) { _scareLen = Mathf.Max(0.8f, _clip.length); _src.clip = _clip; _src.volume = Mathf.Clamp01(FoxySettings.Volume); _src.Play(); } _quad.SetActive(true); Rumble(); UpdateScare(); } } private static void Rumble() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) XRNode[] array = (XRNode[])(object)new XRNode[2] { (XRNode)4, (XRNode)5 }; for (int i = 0; i < array.Length; i++) { InputDevice deviceAtXRNode = InputDevices.GetDeviceAtXRNode(array[i]); try { if (((InputDevice)(ref deviceAtXRNode)).isValid) { ((InputDevice)(ref deviceAtXRNode)).SendHapticImpulse(0u, 1f, _scareLen); } } catch { } } } private static void UpdateScare() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) float num = Time.time - _scareStart; if (num >= _scareLen) { EndScare(); return; } Transform head = Player.Head; if ((Object)(object)head != (Object)null && (Object)(object)_quad != (Object)null) { _quad.transform.position = head.position + head.forward * 0.32f; _quad.transform.rotation = Quaternion.LookRotation(head.forward, head.up); _quad.transform.localScale = new Vector3(0.85f, 0.64f, 1f); } if ((Object)(object)_mr != (Object)null && _frames != null) { int num2 = (int)(num / 0.06f) % 13; Texture2D val = _frames[num2]; if ((Object)(object)val != (Object)null) { ((Renderer)_mr).material.mainTexture = (Texture)(object)val; } } } private static void EndScare() { _scaring = false; if ((Object)(object)_quad != (Object)null) { _quad.SetActive(false); } if ((Object)(object)_src != (Object)null) { try { _src.Stop(); } catch { } } } private static void EnsureAssets() { if (_loadTried) { return; } _loadTried = true; try { string path = Path.Combine(MelonEnvironment.UserDataDirectory, "QuickFoxy"); LoadFrames(Path.Combine(path, "frames")); _clip = LoadWav(Path.Combine(path, "foxy.wav")); BuildObjects(); MelonLogger.Msg($"[QuickFoxy] loaded {((_frames != null) ? _frames.Length : 0)} frames, clip={(Object)(object)_clip != (Object)null}"); } catch (Exception ex) { MelonLogger.Warning("[QuickFoxy] asset load failed: " + ex.Message); } } private static void LoadFrames(string framesDir) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown Texture2D[] array = (Texture2D[])(object)new Texture2D[13]; for (int i = 0; i < 13; i++) { string text = Path.Combine(framesDir, $"foxy_{i:00}.png"); if (!File.Exists(text)) { MelonLogger.Warning("[QuickFoxy] missing frame " + text); continue; } byte[] array2 = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1 }; ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(array2)); array[i] = val; } _frames = array; } private static void BuildObjects() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown _quad = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)_quad).name = "[QuickFoxy] Jumpscare"; Object.DontDestroyOnLoad((Object)(object)_quad); Collider component = _quad.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } _mr = _quad.GetComponent(); _mat = new Material(Shader.Find("Sprites/Default")); _mat.renderQueue = 5000; ((Renderer)_mr).material = _mat; ((Renderer)_mr).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_mr).receiveShadows = false; _quad.SetActive(false); GameObject val = new GameObject("[QuickFoxy] Audio"); Object.DontDestroyOnLoad((Object)val); _src = val.AddComponent(); _src.playOnAwake = false; _src.spatialBlend = 0f; } private static AudioClip? LoadWav(string path) { if (!File.Exists(path)) { MelonLogger.Warning("[QuickFoxy] missing " + path); return null; } byte[] array = File.ReadAllBytes(path); int num = BitConverter.ToInt16(array, 22); int num2 = BitConverter.ToInt32(array, 24); int num3 = BitConverter.ToInt16(array, 34); int i = 12; int num4 = -1; int num5 = 0; int num6; for (; i + 8 <= array.Length; i += 8 + num6 + (num6 & 1)) { string text = Encoding.ASCII.GetString(array, i, 4); num6 = BitConverter.ToInt32(array, i + 4); if (text == "data") { num4 = i + 8; num5 = num6; break; } } if (num4 < 0 || num3 != 16) { MelonLogger.Warning("[QuickFoxy] unsupported wav"); return null; } int num7 = num5 / 2; float[] array2 = new float[num7]; for (int j = 0; j < num7; j++) { array2[j] = (float)BitConverter.ToInt16(array, num4 + j * 2) / 32768f; } int num8 = num7 / Mathf.Max(1, num); AudioClip obj = AudioClip.Create("foxy_scream", num8, num, num2, false); obj.SetData(new Il2CppStructArray(array2), 0); return obj; } } public static class FoxySettings { private static MelonPreferences_Category _cat; private static MelonPreferences_Entry _enabled; private static MelonPreferences_Entry _odds; private static MelonPreferences_Entry _volume; public static bool Enabled { get { return _enabled.Value; } set { _enabled.Value = value; Save(); } } public static int Odds { get { return _odds.Value; } set { _odds.Value = value; Save(); } } public static float Volume { get { return _volume.Value; } set { _volume.Value = value; Save(); } } public static void Initialize() { _cat = MelonPreferences.CreateCategory("QuickFoxy"); _enabled = _cat.CreateEntry("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _odds = _cat.CreateEntry("Odds", 10000, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _volume = _cat.CreateEntry("Volume", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } private static void Save() { _cat.SaveToFile(false); } } public class QuickFoxyMod : MelonMod { public override void OnInitializeMelon() { FoxySettings.Initialize(); SetupMenu(); ((MelonBase)this).LoggerInstance.Msg("QuickFoxy loaded! (1 in " + FoxySettings.Odds + "/sec)"); } public override void OnUpdate() { FoxyController.Update(); } private static Page GetOrCreateQuickModsPage() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) object? data = AppDomain.CurrentDomain.GetData("QuickMods.RootPage"); Page val = (Page)((data is Page) ? data : null); if (val != null) { return val; } Page val2 = Page.Root.CreatePage("Quick Mods", new Color(0.35f, 0.27f, 0.9f), 0, true); AppDomain.CurrentDomain.SetData("QuickMods.RootPage", val2); return val2; } private static void SetupMenu() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) Page obj = GetOrCreateQuickModsPage().CreatePage("QuickFoxy", new Color(0.9f, 0.35f, 0.1f), 0, true); obj.CreateBool("Enabled", Color.white, FoxySettings.Enabled, (Action)delegate(bool v) { FoxySettings.Enabled = v; }); obj.CreateInt("1 in (per second)", new Color(1f, 0.6f, 0.2f), FoxySettings.Odds, 500, 1, 1000000, (Action)delegate(int v) { FoxySettings.Odds = v; }); obj.CreateFloat("Volume", Color.white, FoxySettings.Volume, 0.05f, 0f, 1f, (Action)delegate(float v) { FoxySettings.Volume = v; }); obj.CreateFunction("Test Jumpscare", new Color(1f, 0.2f, 0.2f), (Action)delegate { FoxyController.Trigger(); }); } } }