using System; using System.Collections; using System.Collections.Generic; 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SkeletonJumpscare")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("1/10000 Chance for a Skeleton to Run Across Your Screen Every Second")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SkeletonJumpscare")] [assembly: AssemblyTitle("SkeletonJumpscare")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SkeletonJumpscare { public class JumpscareController : MonoBehaviour { private SkeletonAnimator skeletonAnimator; private float timer; private bool isChecking; public void Initialize(SkeletonAnimator animator) { skeletonAnimator = animator; } public void StartChecking() { isChecking = true; timer = 1f; } public void StopChecking() { isChecking = false; } private void Update() { if (isChecking && !((Object)(object)skeletonAnimator == (Object)null)) { timer -= Time.deltaTime; if (timer <= 0f) { timer = 1f; CheckForJumpscare(); } } } private void CheckForJumpscare() { if (Random.Range(1, SkeletonJumpscareMod.ConfigChance.Value + 1) == 1) { skeletonAnimator.PlayAnimation(); } } } public static class PluginInfo { public const string PLUGIN_GUID = "com.mrbub.runningskeletonjumpscare"; public const string PLUGIN_NAME = "RunningSkeletonJumpscare"; public const string PLUGIN_VERSION = "1.0.0"; } public class SkeletonAnimator : MonoBehaviour { [CompilerGenerated] private sealed class d__12 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SkeletonAnimator <>4__this; private float 5__2; private float 5__3; private int 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown int num = <>1__state; SkeletonAnimator skeletonAnimator = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; skeletonAnimator.isPlaying = true; if (SkeletonJumpscareMod.ConfigEnableSound.Value && (Object)(object)skeletonAnimator.skeletonSound != (Object)null && (Object)(object)skeletonAnimator.audioSource != (Object)null) { skeletonAnimator.audioSource.PlayOneShot(skeletonAnimator.skeletonSound); } 5__2 = 1f / SkeletonJumpscareMod.ConfigAnimationSpeed.Value; 5__3 = 5__2 * (float)skeletonAnimator.frames.Length; 5__4 = 0; goto IL_010a; case 1: <>1__state = -1; 5__4++; goto IL_010a; case 2: { <>1__state = -1; break; } IL_010a: if (5__4 < skeletonAnimator.frames.Length) { if ((Object)(object)skeletonAnimator.frames[5__4] != (Object)null && (Object)(object)skeletonAnimator.image != (Object)null) { skeletonAnimator.image.sprite = skeletonAnimator.frames[5__4]; } <>2__current = (object)new WaitForSeconds(5__2); <>1__state = 1; return true; } if (SkeletonJumpscareMod.ConfigEnableSound.Value && (Object)(object)skeletonAnimator.skeletonSound != (Object)null && 5__3 < skeletonAnimator.skeletonSound.length) { float num2 = skeletonAnimator.skeletonSound.length - 5__3; <>2__current = (object)new WaitForSeconds(num2); <>1__state = 2; return true; } break; } ((Component)skeletonAnimator).gameObject.SetActive(false); skeletonAnimator.isPlaying = false; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Image image; private AudioSource audioSource; private Sprite[] frames; private AudioClip skeletonSound; private bool isPlaying; private const int FRAME_COUNT = 43; private void Awake() { image = ((Component)this).GetComponent(); audioSource = ((Component)this).GetComponent(); LoadAssets(); } private void LoadAssets() { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SkeletonAssets"); if (!Directory.Exists(text)) { SkeletonJumpscareMod.Log.LogError((object)("Assets folder not found at: " + text)); return; } LoadFrames(text); LoadSound(text); } private void LoadFrames(string assetsPath) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) frames = (Sprite[])(object)new Sprite[43]; int num = 0; for (int i = 1; i <= 43; i++) { string path = Path.Combine(assetsPath, "running_skeleton_frames", $"frame{i}.png"); if (!File.Exists(path)) { continue; } try { byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2); if (ImageConversion.LoadImage(val, array)) { ((Texture)val).filterMode = (FilterMode)0; frames[i - 1] = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); num++; } } catch (Exception ex) { SkeletonJumpscareMod.Log.LogError((object)$"Error loading frame {i}: {ex.Message}"); } } if (num != 43) { SkeletonJumpscareMod.Log.LogWarning((object)$"Only loaded {num}/{43} skeleton frames"); } } private void LoadSound(string assetsPath) { string path = Path.Combine(assetsPath, "running_skeleton_sound.wav"); if (!File.Exists(path)) { return; } try { byte[] wavBytes = File.ReadAllBytes(path); skeletonSound = LoadWavFromBytes(wavBytes); if ((Object)(object)skeletonSound == (Object)null) { SkeletonJumpscareMod.Log.LogError((object)"Failed to create AudioClip from WAV data"); } } catch (Exception ex) { SkeletonJumpscareMod.Log.LogError((object)("Error loading sound: " + ex.Message)); } } private AudioClip LoadWavFromBytes(byte[] wavBytes) { int num = BitConverter.ToInt16(wavBytes, 22); int num2 = BitConverter.ToInt32(wavBytes, 24); int num3 = 44; int num4 = (wavBytes.Length - num3) / 2; float[] array = new float[num4]; for (int i = 0; i < num4; i++) { short num5 = BitConverter.ToInt16(wavBytes, num3 + i * 2); array[i] = (float)num5 / 32768f; } AudioClip obj = AudioClip.Create("SkeletonSound", num4 / num, num, num2, false); obj.SetData(array, 0); return obj; } public void PlayAnimation() { if (!isPlaying && frames != null && frames.Length != 0) { ((Component)this).gameObject.SetActive(true); ((MonoBehaviour)this).StartCoroutine(AnimationRoutine()); } } [IteratorStateMachine(typeof(d__12))] private IEnumerator AnimationRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__12(0) { <>4__this = this }; } } [BepInPlugin("com.mrbub.runningskeletonjumpscare", "RunningSkeletonJumpscare", "1.0.0")] public class SkeletonJumpscareMod : BaseUnityPlugin { internal static ManualLogSource Log; public static ConfigEntry ConfigChance; public static ConfigEntry ConfigAnimationSpeed; public static ConfigEntry ConfigEnableSound; private GameObject skeletonCanvas; private JumpscareController controller; private static readonly string[] MenuScenes = new string[3] { "MainMenu", "InitScene", "InitSceneLaunchOptions" }; public static SkeletonJumpscareMod Instance { get; private set; } private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; InitializeConfig(); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.mrbub.runningskeletonjumpscare"); Log.LogInfo((object)"RunningSkeletonJumpscare v1.0.0 loaded!"); CreateSkeletonCanvas(); SceneManager.sceneLoaded += OnSceneLoaded; Scene activeScene = SceneManager.GetActiveScene(); if (IsGameplayScene(((Scene)(ref activeScene)).name)) { controller?.StartChecking(); } } private void InitializeConfig() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown ConfigChance = ((BaseUnityPlugin)this).Config.Bind("Settings", "Chance", 10000, new ConfigDescription("1 in X chance for skeleton to appear each check (e.g., 10000 = 1/10000 chance)", (AcceptableValueBase)(object)new AcceptableValueRange(10, 10000), Array.Empty())); ConfigAnimationSpeed = ((BaseUnityPlugin)this).Config.Bind("Settings", "AnimationSpeed", 60f, new ConfigDescription("Frames per second for skeleton animation", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 60f), Array.Empty())); ConfigEnableSound = ((BaseUnityPlugin)this).Config.Bind("Settings", "EnableSound", true, "Enable or disable the skeleton sound effect"); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if ((Object)(object)skeletonCanvas == (Object)null) { CreateSkeletonCanvas(); } if ((Object)(object)controller == (Object)null && (Object)(object)skeletonCanvas != (Object)null) { controller = skeletonCanvas.GetComponent(); if ((Object)(object)controller == (Object)null) { RecreateController(); } } if (IsGameplayScene(((Scene)(ref scene)).name)) { controller?.StartChecking(); } else { controller?.StopChecking(); } } private bool IsGameplayScene(string sceneName) { string[] menuScenes = MenuScenes; foreach (string text in menuScenes) { if (sceneName == text) { return false; } } return true; } private void RecreateController() { controller = skeletonCanvas.AddComponent(); Transform val = skeletonCanvas.transform.Find("SkeletonImage"); if ((Object)(object)val != (Object)null) { SkeletonAnimator component = ((Component)val).GetComponent(); controller.Initialize(component); } } private void CreateSkeletonCanvas() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) skeletonCanvas = new GameObject("SkeletonJumpscareCanvas"); Object.DontDestroyOnLoad((Object)(object)skeletonCanvas); Canvas obj = skeletonCanvas.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 9999; CanvasScaler obj2 = skeletonCanvas.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); skeletonCanvas.AddComponent(); GameObject obj3 = CreateSkeletonImage(); SkeletonAnimator animator = obj3.AddComponent(); obj3.SetActive(false); controller = skeletonCanvas.AddComponent(); controller.Initialize(animator); } private GameObject CreateSkeletonImage() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown GameObject val = new GameObject("SkeletonImage"); val.transform.SetParent(skeletonCanvas.transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.sizeDelta = Vector2.zero; obj.anchoredPosition = Vector2.zero; Image obj2 = val.AddComponent(); ((Graphic)obj2).color = Color.white; ((Graphic)obj2).raycastTarget = false; obj2.preserveAspect = false; AudioSource obj3 = val.AddComponent(); obj3.playOnAwake = false; obj3.volume = 1f; return val; } } }