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 System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("RewindThat")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RewindThat")] [assembly: AssemblyTitle("RewindThat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 RewindThat { [BepInPlugin("com.zylow.rewindthat", "REWIND THAT", "1.0.0")] public class Plugin : BaseUnityPlugin { public struct FrameSnapshot { public Vector3 position; public Quaternion rotation; public int health; public FrameSnapshot(Vector3 pos, Quaternion rot, int hp) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) position = pos; rotation = rot; health = hp; } } private static Harmony harmony; internal static ManualLogSource Log; public static List history = new List(); public const int maxFrames = 1200; public const int rewindSpeed = 3; public const KeyCode rewindKey = (KeyCode)99; public static bool isRewinding = false; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"[REWIND THAT] Initialisiere Mod..."); GameObject val = new GameObject("RewindThat_FX"); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); harmony = new Harmony("com.zylow.rewindthat"); harmony.PatchAll(); } } public class RewindFx : MonoBehaviour { private static readonly Color overlayColor = Color.white; private const float soundVolume = 1f; private Material overlayMat; private AudioSource audioSource; private int soundStartSample; private bool effectsActive; private void Awake() { SetupOverlayMaterial(); SetupAudio(); ((MonoBehaviour)this).StartCoroutine(DrawOverlayAtEndOfFrame()); } private void LateUpdate() { bool flag = Plugin.isRewinding && Input.GetKey((KeyCode)99); if ((Object)(object)audioSource != (Object)null && (Object)(object)audioSource.clip != (Object)null) { if (!audioSource.isPlaying) { audioSource.Play(); } if (flag && !effectsActive) { audioSource.timeSamples = soundStartSample; audioSource.volume = 1f; } else if (!flag && effectsActive) { audioSource.volume = 0f; } } effectsActive = flag; } private void SetupOverlayMaterial() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown Shader val = Shader.Find("Hidden/Internal-Colored"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[REWIND THAT] Shader 'Hidden/Internal-Colored' nicht gefunden – kein Overlay."); return; } overlayMat = new Material(val) { hideFlags = (HideFlags)61 }; overlayMat.SetInt("_SrcBlend", 4); overlayMat.SetInt("_DstBlend", 0); overlayMat.SetInt("_Cull", 0); overlayMat.SetInt("_ZWrite", 0); overlayMat.SetInt("_ZTest", 8); } private IEnumerator DrawOverlayAtEndOfFrame() { WaitForEndOfFrame endOfFrame = new WaitForEndOfFrame(); while (true) { yield return endOfFrame; if (effectsActive && !((Object)(object)overlayMat == (Object)null)) { RenderTexture previous = RenderTexture.active; RenderTexture.active = null; bool previousSrgbWrite = GL.sRGBWrite; GL.sRGBWrite = false; GL.PushMatrix(); GL.LoadOrtho(); overlayMat.SetPass(0); GL.Begin(7); GL.Color(overlayColor); GL.Vertex3(0f, 0f, 0f); GL.Vertex3(0f, 1f, 0f); GL.Vertex3(1f, 1f, 0f); GL.Vertex3(1f, 0f, 0f); GL.End(); GL.PopMatrix(); GL.sRGBWrite = previousSrgbWrite; RenderTexture.active = previous; } } } private void SetupAudio() { audioSource = ((Component)this).gameObject.AddComponent(); audioSource.playOnAwake = false; audioSource.loop = true; audioSource.spatialBlend = 0f; audioSource.priority = 0; audioSource.bypassReverbZones = true; audioSource.dopplerLevel = 0f; audioSource.volume = 0f; string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, "mandom.wav"); if (!File.Exists(text)) { Plugin.Log.LogError((object)("[REWIND THAT] Sound nicht gefunden: " + text)); return; } string error; AudioClip val = WavLoader.Load(text, out soundStartSample, out error); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)("[REWIND THAT] WAV konnte nicht geladen werden: " + error)); return; } audioSource.clip = val; audioSource.Play(); Plugin.Log.LogInfo((object)$"[REWIND THAT] Sound geladen: {val.length:0.00}s, {val.frequency} Hz, {val.channels} Kanäle, Stille am Anfang übersprungen: {(float)soundStartSample / (float)val.frequency:0.000}s"); } } internal static class WavLoader { private const float silenceThreshold = 0.01f; public static AudioClip Load(string path, out int firstAudibleSample, out string error) { firstAudibleSample = 0; error = null; byte[] array = File.ReadAllBytes(path); if (array.Length < 12 || Encoding.ASCII.GetString(array, 0, 4) != "RIFF" || Encoding.ASCII.GetString(array, 8, 4) != "WAVE") { error = "Keine gültige WAV-Datei (RIFF/WAVE-Header fehlt). Ist es evtl. eine umbenannte MP3/OGG?"; return null; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = -1; int num6 = 0; int num7 = 12; while (num7 + 8 <= array.Length) { string text = Encoding.ASCII.GetString(array, num7, 4); int num8 = BitConverter.ToInt32(array, num7 + 4); int num9 = num7 + 8; if (num8 < 0 || num9 + num8 > array.Length) { num8 = array.Length - num9; } if (text == "fmt ") { num = BitConverter.ToUInt16(array, num9); num2 = BitConverter.ToUInt16(array, num9 + 2); num3 = BitConverter.ToInt32(array, num9 + 4); num4 = BitConverter.ToUInt16(array, num9 + 14); if (num == 65534 && num8 >= 26) { num = BitConverter.ToUInt16(array, num9 + 24); } } else if (text == "data") { num5 = num9; num6 = num8; } num7 = num9 + num8 + (num8 & 1); } if (num5 < 0 || num2 <= 0 || num3 <= 0 || num4 <= 0) { error = "fmt- oder data-Chunk fehlt."; return null; } bool flag = num == 3 && num4 == 32; if (num != 1 && !flag) { error = "Nicht unterstütztes Format (Format-Tag " + num + ", " + num4 + " Bit). Bitte als PCM 16 Bit exportieren."; return null; } int num10 = num4 / 8; int num11 = num6 / num10 / num2; float[] array2 = new float[num11 * num2]; for (int i = 0; i < array2.Length; i++) { int num12 = num5 + i * num10; if (flag) { array2[i] = BitConverter.ToSingle(array, num12); continue; } switch (num4) { case 8: array2[i] = (float)(array[num12] - 128) / 128f; break; case 16: array2[i] = (float)(short)(array[num12] | (array[num12 + 1] << 8)) / 32768f; break; case 24: array2[i] = (float)((array[num12] << 8) | (array[num12 + 1] << 16) | (array[num12 + 2] << 24)) / 2.1474836E+09f; break; case 32: array2[i] = (float)BitConverter.ToInt32(array, num12) / 2.1474836E+09f; break; } } for (int j = 0; j < array2.Length; j++) { if (Math.Abs(array2[j]) > 0.01f) { firstAudibleSample = j / num2; break; } } AudioClip val = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num11, num2, num3, false); val.SetData(array2, 0); return val; } } [HarmonyPatch(typeof(NewMovement), "Update")] public class NewMovementUpdatePatch { [HarmonyPostfix] public static void Postfix(NewMovement __instance) { //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKey((KeyCode)99)) { Plugin.isRewinding = true; Rigidbody val = (((Object)(object)__instance.rb != (Object)null) ? __instance.rb : ((Component)__instance).GetComponent()); if ((Object)(object)val != (Object)null) { val.velocity = Vector3.zero; val.angularVelocity = Vector3.zero; } if (Plugin.history.Count != 0) { int num = Mathf.Min(3, Plugin.history.Count); int index = Plugin.history.Count - num; Plugin.FrameSnapshot frameSnapshot = Plugin.history[index]; ((Component)__instance).transform.position = frameSnapshot.position; ((Component)__instance).transform.rotation = frameSnapshot.rotation; __instance.hp = frameSnapshot.health; Plugin.history.RemoveRange(index, num); if ((Object)(object)MonoSingleton.Instance != (Object)null && Time.frameCount % 10 == 0) { MonoSingleton.Instance.SendHudMessage("<<< MANDOM: REWINDING 20s", "", "", 0, false, false, true); } } } else { Plugin.isRewinding = false; if (Plugin.history.Count >= 1200) { Plugin.history.RemoveAt(0); } Plugin.history.Add(new Plugin.FrameSnapshot(((Component)__instance).transform.position, ((Component)__instance).transform.rotation, __instance.hp)); } } } }