using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using Configgy; using HarmonyLib; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] public class CarouselBase : MonoBehaviour { [CompilerGenerated] private sealed class d__15 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CarouselBase <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CarouselBase carouselBase = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; } bool flag = carouselBase.hoofTV.currentSeason == 3; if (flag != carouselBase.halfModeActive) { carouselBase.halfModeActive = flag; if (carouselBase.halfModeActive) { carouselBase.currentOptions = carouselBase.fullOptions.Take(carouselBase.fullOptions.Length / 2).ToArray(); } else { carouselBase.currentOptions = carouselBase.fullOptions; } if (carouselBase.currentOptions.Length == 0) { carouselBase.currentIndex = 0; carouselBase.selectedText.text = "Nothing here!"; } else { carouselBase.currentIndex = Mathf.Clamp(carouselBase.currentIndex, 0, carouselBase.currentOptions.Length - 1); carouselBase.selectedText.text = carouselBase.currentOptions[carouselBase.currentIndex]; } carouselBase.UpdateText(); } <>2__current = null; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [Header("UI Elements")] [SerializeField] private TMP_Text selectedText; [SerializeField] private Button leftArrow; [SerializeField] private Button rightArrow; [Header("Options")] [SerializeField] private string[] options; [Header("Half Mode Settings (Optional)")] [SerializeField] private bool enableHalfModeBehavior; [SerializeField] private TMP_Text textToCheck; [SerializeField] private HoofTVBase hoofTV; private string[] fullOptions; private string[] currentOptions; private int currentIndex; private bool halfModeActive; private Coroutine monitorRoutine; private void OnEnable() { if (enableHalfModeBehavior && monitorRoutine == null) { monitorRoutine = ((MonoBehaviour)this).StartCoroutine(MonitorTextToCheck()); } } private void OnDisable() { if (monitorRoutine != null) { ((MonoBehaviour)this).StopCoroutine(monitorRoutine); monitorRoutine = null; } } private void Awake() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown if ((Object)(object)leftArrow == (Object)null || (Object)(object)rightArrow == (Object)null || (Object)(object)selectedText == (Object)null) { Debug.LogError((object)"CarouselBase: Missing UI elements! Drag them in the Inspector."); ((Behaviour)this).enabled = false; return; } if (enableHalfModeBehavior && (Object)(object)textToCheck == (Object)null) { Debug.LogError((object)"CarouselBase: Half Mode enabled but textToCheck is not assigned."); ((Behaviour)this).enabled = false; return; } if (options == null || options.Length == 0) { Debug.LogWarning((object)"CarouselBase: No options set in the Inspector!"); fullOptions = new string[0]; } else { fullOptions = options; } currentOptions = fullOptions; ((UnityEventBase)leftArrow.onClick).RemoveAllListeners(); ((UnityEventBase)rightArrow.onClick).RemoveAllListeners(); ((UnityEvent)leftArrow.onClick).AddListener(new UnityAction(GoLeft)); ((UnityEvent)rightArrow.onClick).AddListener(new UnityAction(GoRight)); UpdateText(); if (enableHalfModeBehavior) { ((MonoBehaviour)this).StartCoroutine(MonitorTextToCheck()); } } [IteratorStateMachine(typeof(d__15))] private IEnumerator MonitorTextToCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { <>4__this = this }; } public void GoLeft() { if (currentOptions == null || currentOptions.Length == 0) { Debug.LogWarning((object)"CarouselBase: No options to scroll through!"); return; } currentIndex--; if (currentIndex < 0) { currentIndex = currentOptions.Length - 1; } UpdateText(); } public void GoRight() { if (currentOptions == null || currentOptions.Length == 0) { Debug.LogWarning((object)"CarouselBase: No options to scroll through!"); return; } currentIndex++; if (currentIndex >= currentOptions.Length) { currentIndex = 0; } UpdateText(); } private void UpdateText() { if (currentOptions == null || currentOptions.Length == 0) { selectedText.text = "Nothing here!"; } else { selectedText.text = currentOptions[currentIndex]; } } } public class HoofTVBase : MonoBehaviour { public enum ResolutionOption { R480p = 480, R720p = 720, R1080p = 1080 } [CompilerGenerated] private sealed class d__38 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string downloadUrl; public string localPath; public HoofTVBase <>4__this; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 bool result; try { int num = <>1__state; HoofTVBase hoofTVBase = <>4__this; switch (num) { default: result = false; break; case 0: <>1__state = -1; Debug.Log((object)("HoofTV: Starting download from " + downloadUrl + " to " + localPath)); if ((Object)(object)hoofTVBase.downloadingObj != (Object)null) { hoofTVBase.downloadingObj.SetActive(true); } 5__2 = UnityWebRequest.Get(downloadUrl); <>1__state = -3; 5__2.downloadHandler = (DownloadHandler)new DownloadHandlerFile(localPath); <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; case 1: <>1__state = -3; if ((int)5__2.result != 1) { Debug.LogError((object)("HoofTV: Download failed: " + 5__2.error)); if ((Object)(object)hoofTVBase.downloadingObj != (Object)null) { hoofTVBase.downloadingObj.SetActive(false); } hoofTVBase.isPreparingVideo = false; hoofTVBase.AttemptRetryOrFallback(); result = false; <>m__Finally1(); } else { Debug.Log((object)$"HoofTV: Download completed. File size: {new FileInfo(localPath).Length} bytes"); hoofTVBase.PlayVideoFromFile(localPath); <>m__Finally1(); 5__2 = null; result = false; } break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__35 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float delaySeconds; public string url; public HoofTVBase <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__35(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown int num = <>1__state; HoofTVBase hoofTVBase = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delaySeconds); <>1__state = 1; return true; case 1: <>1__state = -1; if (!string.IsNullOrEmpty(url)) { hoofTVBase.PlayVideo(url); } 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(); } } [Header("UI Elements")] [SerializeField] private TMP_Text seasonLabel; [SerializeField] private TMP_Text episodeLabel; [SerializeField] private Canvas canvas; [Header("Screen & Video")] [SerializeField] private GameObject screenToEnable; [SerializeField] private GameObject warningText; [SerializeField] private GameObject errorObj; [SerializeField] private GameObject downloadingObj; [SerializeField] private TMP_Text errorText; [Header("Control Buttons (Hidden initially)")] [SerializeField] private Button startButton; [SerializeField] private Button stopButton; [SerializeField] private Button pauseButton; [SerializeField] private Button resumeButton; [Header("Audio")] [SerializeField] private AudioMixerGroup audioOutputGroup; [Header("Render Texture")] [SerializeField] private RenderTexture targetRenderTexture; [Header("Playback Settings")] [SerializeField] private int maxRetries = 3; [SerializeField] private float prepareTimeoutSeconds = 30f; [Configgable("Video Config", null, 0, null)] private static ConfigToggle DownloadVideoBeforePlaying = new ConfigToggle(false); [Configgable("Video Config", null, 0, null)] private static ConfigLabel DownloadVideoWarningLabel = new ConfigLabel("WARNING: This makes video loading slow (around 130mb per video) while also being at a lower quality. Use ONLY if you have issues with how videos are streamed by default!", 55f); private VideoPlayer videoPlayer; private AudioSource audioSource; private ResolutionOption currentResolution = ResolutionOption.R720p; private bool isMeantToBePaused; private double pausedTimestamp; public int currentSeason; public int currentEpisode; private int currentRetryCount; private float prepareStartTime; private bool isPreparingVideo; private string pendingVideoUrl = ""; private string videoCachePath = ""; private void Update() { if (!((Object)(object)videoPlayer == (Object)null)) { if (isMeantToBePaused) { videoPlayer.Pause(); videoPlayer.time = pausedTimestamp; } TMP_Text obj = seasonLabel; currentSeason = ParseLabelNumber(((obj != null) ? obj.text : null) ?? ""); TMP_Text obj2 = episodeLabel; currentEpisode = ParseLabelNumber(((obj2 != null) ? obj2.text : null) ?? ""); if (isPreparingVideo && Time.time - prepareStartTime > prepareTimeoutSeconds) { Debug.LogWarning((object)$"HoofTV: Preparation timeout after {prepareTimeoutSeconds}s. Attempting retry..."); isPreparingVideo = false; AttemptRetryOrFallback(); } } } private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Expected O, but got Unknown videoCachePath = Path.Combine(Path.GetTempPath(), "hooftv-cache.mp4"); if ((Object)(object)startButton != (Object)null) { ((UnityEvent)startButton.onClick).AddListener(new UnityAction(OnStartClicked)); } if ((Object)(object)stopButton != (Object)null) { ((UnityEvent)stopButton.onClick).AddListener(new UnityAction(OnStopClicked)); ((Component)stopButton).gameObject.SetActive(false); } if ((Object)(object)pauseButton != (Object)null) { ((UnityEvent)pauseButton.onClick).AddListener(new UnityAction(OnPauseClicked)); ((Component)pauseButton).gameObject.SetActive(false); } if ((Object)(object)resumeButton != (Object)null) { ((UnityEvent)resumeButton.onClick).AddListener(new UnityAction(OnResumeClicked)); ((Component)resumeButton).gameObject.SetActive(false); } if ((Object)(object)canvas != (Object)null) { canvas.worldCamera = Camera.main; } videoPlayer = ((Component)this).gameObject.AddComponent(); videoPlayer.playOnAwake = false; videoPlayer.renderMode = (VideoRenderMode)2; videoPlayer.audioOutputMode = (VideoAudioOutputMode)1; videoPlayer.source = (VideoSource)1; videoPlayer.waitForFirstFrame = true; videoPlayer.skipOnDrop = true; audioSource = ((Component)this).gameObject.AddComponent(); if ((Object)(object)audioOutputGroup != (Object)null) { audioSource.outputAudioMixerGroup = audioOutputGroup; } videoPlayer.SetTargetAudioSource((ushort)0, audioSource); audioSource.spatialBlend = 1f; audioSource.rolloffMode = (AudioRolloffMode)0; audioSource.minDistance = 2f; audioSource.maxDistance = 350f; audioSource.spread = 180f; videoPlayer.loopPointReached += new EventHandler(OnVideoEnd); videoPlayer.prepareCompleted += new EventHandler(OnPrepareCompleted); videoPlayer.errorReceived += new ErrorEventHandler(OnVideoError); if ((Object)(object)screenToEnable != (Object)null) { screenToEnable.SetActive(false); } EnsureRenderTexture((int)currentResolution); } private void EnsureRenderTexture(int verticalResolution) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown int num = verticalResolution * 16 / 9; if ((Object)(object)targetRenderTexture == (Object)null) { targetRenderTexture = new RenderTexture(num, verticalResolution, 0) { name = $"HoofTV_RT_{verticalResolution}p" }; targetRenderTexture.Create(); Debug.Log((object)$"HoofTV: Created RenderTexture {((Object)targetRenderTexture).name} ({num}x{verticalResolution})"); } else if (((Texture)targetRenderTexture).width != num || ((Texture)targetRenderTexture).height != verticalResolution) { Debug.Log((object)$"HoofTV: Recreating RenderTexture. Old: {((Texture)targetRenderTexture).width}x{((Texture)targetRenderTexture).height} -> New: {num}x{verticalResolution}"); videoPlayer.targetTexture = null; targetRenderTexture.Release(); ((Texture)targetRenderTexture).width = num; ((Texture)targetRenderTexture).height = verticalResolution; targetRenderTexture.Create(); } videoPlayer.targetTexture = targetRenderTexture; if ((Object)(object)screenToEnable != (Object)null) { Renderer component = screenToEnable.GetComponent(); if ((Object)(object)component != (Object)null) { component.material.mainTexture = (Texture)(object)targetRenderTexture; } } } private void AttemptRetryOrFallback() { if (currentRetryCount < maxRetries) { currentRetryCount++; float num = Mathf.Pow(2f, (float)(currentRetryCount - 1)); Debug.Log((object)$"HoofTV: Retry attempt {currentRetryCount}/{maxRetries} in {num}s"); ((MonoBehaviour)this).StartCoroutine(RetryAfterDelay(num, pendingVideoUrl)); return; } ResolutionOption lowerResolution = GetLowerResolution(currentResolution); if (lowerResolution != currentResolution) { Debug.Log((object)$"HoofTV: Fallback to lower resolution: {(int)lowerResolution}p"); currentResolution = lowerResolution; currentRetryCount = 0; TMP_Text obj = seasonLabel; int season = ParseLabelNumber(((obj != null) ? obj.text : null) ?? ""); TMP_Text obj2 = episodeLabel; int episode = ParseLabelNumber(((obj2 != null) ? obj2.text : null) ?? ""); string url = GenerateUrl(season, episode, (int)currentResolution); PlayVideo(url); } else { ShowError("Unable to load video after all retry attempts and fallback resolutions."); } } [IteratorStateMachine(typeof(d__35))] private IEnumerator RetryAfterDelay(float delaySeconds, string url) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__35(0) { <>4__this = this, delaySeconds = delaySeconds, url = url }; } private ResolutionOption GetLowerResolution(ResolutionOption current) { return current switch { ResolutionOption.R1080p => ResolutionOption.R720p, ResolutionOption.R720p => ResolutionOption.R480p, _ => current, }; } private void ShowError(string message) { Debug.LogError((object)("HoofTV: " + message)); if ((Object)(object)downloadingObj != (Object)null) { downloadingObj.SetActive(false); } if ((Object)(object)errorObj != (Object)null) { errorObj.SetActive(true); } if ((Object)(object)errorText != (Object)null) { errorText.text = "Error: " + message; } ToggleControls(startVisible: true, stopVisible: false, pauseVisible: false, resumeVisible: false); } [IteratorStateMachine(typeof(d__38))] private IEnumerator DownloadVideoCoroutine(string downloadUrl, string localPath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__38(0) { <>4__this = this, downloadUrl = downloadUrl, localPath = localPath }; } private void PlayVideoFromFile(string filePath) { if (!File.Exists(filePath)) { Debug.LogError((object)("HoofTV: Downloaded file not found at " + filePath)); isPreparingVideo = false; AttemptRetryOrFallback(); return; } Debug.Log((object)("HoofTV: Playing video from local file: " + filePath)); if ((Object)(object)videoPlayer == (Object)null) { Debug.LogError((object)"HoofTV: VideoPlayer is null!"); return; } pendingVideoUrl = filePath; videoPlayer.source = (VideoSource)1; videoPlayer.url = "file://" + filePath; if ((Object)(object)videoPlayer.targetTexture == (Object)null) { EnsureRenderTexture((int)currentResolution); } if (videoPlayer.isPlaying) { videoPlayer.Stop(); } videoPlayer.controlledAudioTrackCount = 1; videoPlayer.EnableAudioTrack((ushort)0, true); videoPlayer.Prepare(); } public void OnStopClicked() { if ((Object)(object)videoPlayer != (Object)null && videoPlayer.isPlaying) { videoPlayer.Stop(); } isPreparingVideo = false; currentRetryCount = 0; pendingVideoUrl = ""; if ((Object)(object)downloadingObj != (Object)null) { downloadingObj.SetActive(false); } if ((Object)(object)screenToEnable != (Object)null) { screenToEnable.SetActive(false); } ToggleControls(startVisible: true, stopVisible: false, pauseVisible: false, resumeVisible: false); } public void OnPauseClicked() { if ((Object)(object)videoPlayer != (Object)null && videoPlayer.isPlaying) { videoPlayer.Pause(); isMeantToBePaused = true; pausedTimestamp = videoPlayer.time; ToggleControls(startVisible: false, stopVisible: true, pauseVisible: false, resumeVisible: true); } } public void OnResumeClicked() { if ((Object)(object)videoPlayer != (Object)null && !videoPlayer.isPlaying) { videoPlayer.Play(); isMeantToBePaused = false; videoPlayer.time = pausedTimestamp; ToggleControls(startVisible: false, stopVisible: true, pauseVisible: true, resumeVisible: false); } } private void ToggleControls(bool startVisible, bool stopVisible, bool pauseVisible, bool resumeVisible) { if ((Object)(object)startButton != (Object)null) { ((Component)startButton).gameObject.SetActive(startVisible); } if ((Object)(object)stopButton != (Object)null) { ((Component)stopButton).gameObject.SetActive(stopVisible); } if ((Object)(object)pauseButton != (Object)null) { ((Component)pauseButton).gameObject.SetActive(pauseVisible); } if ((Object)(object)resumeButton != (Object)null) { ((Component)resumeButton).gameObject.SetActive(resumeVisible); } } private void OnStartClicked() { TMP_Text obj = seasonLabel; int num = ParseLabelNumber(((obj != null) ? obj.text : null) ?? ""); TMP_Text obj2 = episodeLabel; int num2 = ParseLabelNumber(((obj2 != null) ? obj2.text : null) ?? ""); if (num <= 0 || num2 <= 0) { Debug.LogWarning((object)"Season or Episode label is not a valid positive integer."); return; } currentResolution = ResolutionOption.R720p; errorObj.SetActive(false); EnsureRenderTexture((int)currentResolution); string text = GenerateUrl(num, num2, (int)currentResolution); Debug.Log((object)("HoofTV: Starting video playback: " + text)); if ((Object)(object)warningText != (Object)null) { warningText.SetActive(false); } ToggleControls(startVisible: false, stopVisible: true, pauseVisible: true, resumeVisible: false); PlayVideo(text); } private int ParseLabelNumber(string label) { if (string.IsNullOrEmpty(label)) { return -1; } string[] array = label.Split(' '); for (int i = 0; i < array.Length; i++) { if (int.TryParse(array[i], out var result)) { return result; } } return -1; } private string GenerateUrl(int season, int episode, int resolution) { return $"https://static.heartshine.gay/g4-fim/s{season:D2}e{episode:D2}-720p.mp4"; } private string GenerateUrlForDownlaod(int season, int episode) { return $"https://static.heartshine.gay/g4-fim/s{season:D2}e{episode:D2}-480p.mp4"; } private void OnPrepareCompleted(VideoPlayer vp) { Debug.Log((object)("HoofTV: Prepare completed for url: " + vp.url)); isPreparingVideo = false; currentRetryCount = 0; if ((Object)(object)downloadingObj != (Object)null) { downloadingObj.SetActive(false); } vp.Play(); if ((Object)(object)screenToEnable != (Object)null) { screenToEnable.SetActive(true); } ToggleControls(startVisible: false, stopVisible: true, pauseVisible: true, resumeVisible: false); } public void PlayVideo(string url) { if (string.IsNullOrEmpty(url)) { Debug.LogError((object)"HoofTV: PlayVideo called with null/empty url."); return; } Debug.Log((object)("HoofTV: PlayVideo called. Setting url and preparing: " + url)); if ((Object)(object)videoPlayer == (Object)null) { Debug.LogError((object)"HoofTV: VideoPlayer is null!"); return; } isPreparingVideo = true; prepareStartTime = Time.time; if (((ConfigValueElement)(object)DownloadVideoBeforePlaying).Value) { TMP_Text obj = seasonLabel; int season = ParseLabelNumber(((obj != null) ? obj.text : null) ?? ""); TMP_Text obj2 = episodeLabel; int episode = ParseLabelNumber(((obj2 != null) ? obj2.text : null) ?? ""); string downloadUrl = GenerateUrlForDownlaod(season, episode); try { if (File.Exists(videoCachePath)) { File.Delete(videoCachePath); Debug.Log((object)"HoofTV: Deleted old cache file"); } } catch (Exception ex) { Debug.LogWarning((object)("HoofTV: Could not delete old cache file: " + ex.Message)); } ((MonoBehaviour)this).StartCoroutine(DownloadVideoCoroutine(downloadUrl, videoCachePath)); } else { pendingVideoUrl = url; videoPlayer.source = (VideoSource)1; videoPlayer.url = url; if ((Object)(object)videoPlayer.targetTexture == (Object)null) { EnsureRenderTexture((int)currentResolution); } if (videoPlayer.isPlaying) { videoPlayer.Stop(); } videoPlayer.controlledAudioTrackCount = 1; videoPlayer.EnableAudioTrack((ushort)0, true); videoPlayer.Prepare(); } } private void OnVideoEnd(VideoPlayer vp) { Debug.Log((object)"HoofTV: Video ended."); if ((Object)(object)screenToEnable != (Object)null) { screenToEnable.SetActive(false); } ToggleControls(startVisible: true, stopVisible: false, pauseVisible: false, resumeVisible: false); } private void OnVideoError(VideoPlayer vp, string message) { Debug.LogError((object)("HoofTV: VideoPlayer error: " + message + " | url: " + ((vp != null) ? vp.url : null))); isPreparingVideo = false; AttemptRetryOrFallback(); } private void OnDestroy() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if ((Object)(object)videoPlayer != (Object)null) { videoPlayer.loopPointReached -= new EventHandler(OnVideoEnd); videoPlayer.prepareCompleted -= new EventHandler(OnPrepareCompleted); videoPlayer.errorReceived -= new ErrorEventHandler(OnVideoError); } if ((Object)(object)targetRenderTexture != (Object)null) { targetRenderTexture.Release(); Object.Destroy((Object)(object)targetRenderTexture); } } public void PauseVideo() { if ((Object)(object)videoPlayer != (Object)null && videoPlayer.isPlaying) { videoPlayer.Pause(); isMeantToBePaused = true; pausedTimestamp = videoPlayer.time; } } public void ResumeVideo() { if ((Object)(object)videoPlayer != (Object)null && !videoPlayer.isPlaying) { isMeantToBePaused = false; videoPlayer.time = pausedTimestamp; videoPlayer.Play(); } } public void StopVideo() { if ((Object)(object)videoPlayer != (Object)null && videoPlayer.isPlaying) { videoPlayer.Stop(); if ((Object)(object)screenToEnable != (Object)null) { screenToEnable.SetActive(false); } } } } namespace HoofTV { [BepInPlugin("com.NOTHANKYOU.hooftv", "HoofTV", "1.0.0")] public class HoofTVPlugin : BaseUnityPlugin { public class CoroutineRunner : MonoBehaviour { private static CoroutineRunner _instance; public static CoroutineRunner Instance { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("CoroutineRunner"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } return _instance; } } } [HarmonyPatch(typeof(StockMapInfo), "Awake")] internal class Magic { [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private AsyncOperationHandle 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) 5__2 = default(AsyncOperationHandle); <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0054: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = Addressables.LoadAssetAsync((object)"f1ff75d10ab733a4fb4a7d0abb3c170a"); <>2__current = 5__2; <>1__state = 1; return true; case 1: <>1__state = -1; if ((int)5__2.Status == 1) { GameObject result = 5__2.Result; Object.Instantiate(result, result.transform.position, result.transform.rotation); Debug.Log((object)$"HoofTV: TV prefab instantiated at {result.transform.position}."); } else { Debug.LogError((object)"HoofTV: Failed to load TV prefab."); } 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 static void Postfix(StockMapInfo __instance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name.StartsWith("7b3cb6a0a")) { ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(LoadAndInstantiatePrefab()); } } [IteratorStateMachine(typeof(d__1))] private static IEnumerator LoadAndInstantiatePrefab() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0); } } [CompilerGenerated] private sealed class d__8 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private AsyncOperationHandle 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) 5__2 = default(AsyncOperationHandle); <>1__state = -2; } private bool MoveNext() { //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Invalid comparison between Unknown and I4 //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Invalid comparison between Unknown and I4 //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string text = Path.Combine(addrDataPath, "catalog.json"); string text2 = Path.Combine(addrDataPath, "patched_catalog.json"); if (!File.Exists(text)) { Debug.LogError((object)("HoofTV: Catalog file not found at: " + text)); return false; } try { JObject val = JObject.Parse(File.ReadAllText(text)); string text3 = "AngryLevelLoader.Plugin.tempFolderPath"; string text4 = addrDataPath.Replace("\\", "/"); if (!text4.EndsWith("/")) { text4 += "/"; } JToken val2 = ((JToken)val).SelectToken("m_InternalIds"); if (val2 != null && (int)val2.Type == 2) { JArray val3 = (JArray)val2; for (int i = 0; i < ((JContainer)val3).Count; i++) { string text5 = ((object)val3[i]).ToString(); if (text5.Contains(text3)) { string text6 = text5.Replace(text3, text4); Debug.Log((object)("HoofTV: Replacing path\n" + text5 + "\n->\n" + text6)); val3[i] = JToken.op_Implicit(text6); } } } File.WriteAllText(text2, ((JToken)val).ToString((Formatting)1, Array.Empty())); Debug.Log((object)"HoofTV: Patched catalog created successfully."); } catch (Exception arg) { Debug.LogError((object)$"HoofTV: Error while patching catalog: {arg}"); return false; } Debug.Log((object)("HoofTV: Loading patched catalog from: " + text2)); 5__2 = Addressables.LoadContentCatalogAsync(text2, false, (string)null); <>2__current = 5__2; <>1__state = 1; return true; } case 1: <>1__state = -1; if ((int)5__2.Status == 1) { Debug.Log((object)"HoofTV: Catalog loaded successfully."); } else { Debug.LogError((object)$"HoofTV: Failed to load patched catalog: {5__2.OperationException}"); } 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 bool isCatalogLoaded; private ConfigBuilder config; public static string addrDataPath = Path.Combine(ModPath(), "Addressable"); public static HoofTVPlugin instance; public static string toolsPath = Path.Combine(ModPath(), "Tools"); public static string libPath = Path.Combine(toolsPath, "lib"); public static string ModPath() { return Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(Path.DirectorySeparatorChar)); } private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown instance = this; ((BaseUnityPlugin)this).Logger.LogInfo((object)"HoofTV: neigh"); if (!isCatalogLoaded) { ((MonoBehaviour)this).StartCoroutine(loadHoofTVAddr()); isCatalogLoaded = true; } new Harmony("com.NOTHANKYOU.hooftv").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"HoofTV: Harmony patches applied."); config = new ConfigBuilder("probablysarah.hooftv", "HoofTV"); config.BuildAll(); } [IteratorStateMachine(typeof(d__8))] private IEnumerator loadHoofTVAddr() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(0); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }