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<byte>.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<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
_mr = _quad.GetComponent<MeshRenderer>();
_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<AudioSource>();
_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<float>(array2), 0);
return obj;
}
}
public static class FoxySettings
{
private static MelonPreferences_Category _cat;
private static MelonPreferences_Entry<bool> _enabled;
private static MelonPreferences_Entry<int> _odds;
private static MelonPreferences_Entry<float> _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<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_odds = _cat.CreateEntry<int>("Odds", 10000, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
_volume = _cat.CreateEntry<float>("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<bool>)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<int>)delegate(int v)
{
FoxySettings.Odds = v;
});
obj.CreateFloat("Volume", Color.white, FoxySettings.Volume, 0.05f, 0f, 1f, (Action<float>)delegate(float v)
{
FoxySettings.Volume = v;
});
obj.CreateFunction("Test Jumpscare", new Color(1f, 0.2f, 0.2f), (Action)delegate
{
FoxyController.Trigger();
});
}
}
}