Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BestestTelevisionMod v1.3.2
BestestTelevisionMod.dll
Decompiled 6 days agousing System; 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.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; 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] [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.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] [Microsoft.CodeAnalysis.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; } } [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 BestestTVModPlugin { public static class KeySymbolConverter { public static string GetKeySymbol(Key key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected I4, but got Unknown switch ((int)key) { case 0: return ""; case 1: return "[Space]"; case 2: return "[Enter]"; case 3: return "[Tab]"; case 4: return "[`]"; case 5: return "[']"; case 6: return "[;]"; case 7: return "[,]"; case 8: return "[.]"; case 9: return "[/]"; case 10: return "[\\]"; case 11: return "[[]"; case 12: return "[]]"; case 13: return "[-]"; case 14: return "[=]"; case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: return "[" + ((object)(Key)(ref key)).ToString() + "]"; case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: return "[" + ((object)(Key)(ref key)).ToString().Substring(5) + "]"; case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: case 60: case 61: return "[←]"; case 62: return "[→]"; case 63: return "[↑]"; case 64: return "[↓]"; case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: return "[÷]"; case 79: return "[*]"; case 80: return "[+]"; case 81: return "[-]"; case 82: return "[.]"; case 83: return "[=]"; case 84: return "[#0]"; case 85: return "[#1]"; case 86: return "[#2]"; case 87: return "[#3]"; case 88: return "[#4]"; case 89: return "[#5]"; case 90: return "[#6]"; case 91: return "[#7]"; case 92: return "[#8]"; case 93: return "[#9]"; default: return "[" + ((object)(Key)(ref key)).ToString() + "]"; } } } public class ConfigManager { public static ConfigManager Instance { get; private set; } public static ConfigEntry<bool> enableLogging { get; set; } public static ConfigEntry<bool> storingResets { get; set; } public static ConfigEntry<bool> reloadedVideosHUD { get; set; } public static ConfigEntry<bool> tvOnAlways { get; set; } public static ConfigEntry<bool> tvPlaysSequentially { get; set; } public static ConfigEntry<bool> tvSkipsAfterOffOn { get; set; } public static ConfigEntry<bool> shuffleVideos { get; set; } public static ConfigEntry<bool> enableSeeking { get; set; } public static ConfigEntry<bool> enableChannels { get; set; } public static ConfigEntry<bool> mouseWheelVolume { get; set; } public static ConfigEntry<bool> hideHoverTip { get; set; } public static ConfigEntry<bool> restrictChannels { get; set; } public static ConfigEntry<bool> tvLightEnabled { get; set; } public static ConfigEntry<VideoAspectRatio> tvScalingOption { get; set; } public static ConfigEntry<Key> reloadVideosKeyBind { get; set; } public static ConfigEntry<Key> seekReverseKeyBind { get; set; } public static ConfigEntry<Key> seekForwardKeyBind { get; set; } public static ConfigEntry<Key> skipReverseKeyBind { get; set; } public static ConfigEntry<Key> skipForwardKeyBind { get; set; } public static ConfigFile configFile { get; private set; } public static void Init(ConfigFile config) { Instance = new ConfigManager(config); } private ConfigManager(ConfigFile cfg) { configFile = cfg; tvScalingOption = cfg.Bind<VideoAspectRatio>("Options", "Aspect Ratio", (VideoAspectRatio)1, "Available choices:\nNoScaling\nFitVertically\nFitHorizontally\nFitInside\nFitOutside\nStretch"); storingResets = cfg.Bind<bool>("Options", "Storing Resets List", true, "Does storing the television reset the video index back to 1?"); shuffleVideos = cfg.Bind<bool>("Options", "Shuffle Videos", false, "Load videos in a random order instead of alphabetically"); tvLightEnabled = cfg.Bind<bool>("Options", "Television Lights", true, "Does light emit from the television when it is turned on?"); tvOnAlways = cfg.Bind<bool>("Options", "TV Always On", false, "Should the TV stay on after it's been turned on once?\n"); tvPlaysSequentially = cfg.Bind<bool>("Options", "TV Plays Sequentially", true, "Play videos in order or loop?\n"); tvSkipsAfterOffOn = cfg.Bind<bool>("Options", "TV Skips After Off On", false, "Should what is currently playing be skipped after the television is turned off and back on again?\n"); enableSeeking = cfg.Bind<bool>("Options", "Enable Seeking", true, "Use brackets to fast forward or rewind?"); enableChannels = cfg.Bind<bool>("Options", "Enable Channels", true, "Use comma or period to skip videos?"); mouseWheelVolume = cfg.Bind<bool>("Options", "Mouse Wheel Volume", true, "Should the mouse wheel control the volume?"); hideHoverTip = cfg.Bind<bool>("Options", "Hide Hovertips", false, "Hide the controls when hovering over the TV"); restrictChannels = cfg.Bind<bool>("Options", "Restrict Channels", false, "Disable the channel controls, but keep the UI, unless Hide Hovertips is also checked"); reloadedVideosHUD = cfg.Bind<bool>("Options", "Videos Reloaded Prompt", true, "A prompt that pops up indicating that the videos have been reloaded after pressing the keybind."); reloadVideosKeyBind = cfg.Bind<Key>("Bindings", "Reload Videos", (Key)63, "Reload videos list, prevents having to restart if you turn shuffle on."); seekReverseKeyBind = cfg.Bind<Key>("Bindings", "Seek Backwards", (Key)11, "Go backwards in the currently playing video."); seekForwardKeyBind = cfg.Bind<Key>("Bindings", "Seek Forwards", (Key)12, "Go forwards in the currently playing video."); skipReverseKeyBind = cfg.Bind<Key>("Bindings", "Skip Backwards", (Key)7, "Skip to the previous video."); skipForwardKeyBind = cfg.Bind<Key>("Bindings", "Skip Forwards", (Key)8, "Skip to the next video."); enableLogging = cfg.Bind<bool>("Debug", "Logging Enabled", false, "Is logging enabled?"); } } [HarmonyPatch(typeof(TVScript))] public class TVScriptPatches { [CompilerGenerated] private static class <>O { public static EventHandler <0>__OnVideoEnded; } public static MethodInfo aspectRatio = typeof(VideoPlayer).GetMethod("VideoAspectRatio", BindingFlags.Instance | BindingFlags.NonPublic); public static FieldInfo? currentClipProperty = typeof(TVScript).GetField("currentClip", BindingFlags.Instance | BindingFlags.NonPublic); public static FieldInfo currentTimeProperty = typeof(TVScript).GetField("currentClipTime", BindingFlags.Instance | BindingFlags.NonPublic); public static bool tvIsCurrentlyOn = false; public static RenderTexture renderTexture; public static AudioSource audioSource; public static VideoPlayer videoSource; public Light tvLight; public static int TVIndex; [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] public static void SetTVIndex() { TVIndex = 0; tvIsCurrentlyOn = false; } [HarmonyPatch(typeof(TVScript), "Update")] [HarmonyPrefix] public static bool Update(TVScript __instance) { if (!tvIsCurrentlyOn) { SetTVScreenMaterial(__instance, b: false); } if ((Object)(object)videoSource == (Object)null) { videoSource = ((Component)__instance).GetComponent<VideoPlayer>(); renderTexture = videoSource.targetTexture; if (VideoManager.Videos.Count > 0) { WhatItDo(__instance, TVIndex); } } return false; } [HarmonyPatch(typeof(TVScript), "TurnTVOnOff")] [HarmonyPrefix] public static bool TurnTVOnOff(bool on, TVScript __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 __instance.tvOn = on; audioSource = __instance.tvSFX; videoSource = __instance.video; if ((int)videoSource.source != 1 || videoSource.url == "") { WhatItDo(__instance, TVIndex); } if (on) { if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)"Turning on TV"); } SetTVScreenMaterial(__instance, b: true); tvIsCurrentlyOn = true; audioSource.Play(); videoSource.Play(); videoSource.time = audioSource.time; audioSource.PlayOneShot(__instance.switchTVOn); WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOn, 1f); } else { if (ConfigManager.tvSkipsAfterOffOn.Value) { videoSource.source = (VideoSource)1; videoSource.controlledAudioTrackCount = 1; videoSource.audioOutputMode = (VideoAudioOutputMode)1; videoSource.SetTargetAudioSource((ushort)0, audioSource); videoSource.url = "file://" + VideoManager.Videos[TVIndex + 1]; TVIndex++; videoSource.Prepare(); } if (!ConfigManager.tvOnAlways.Value) { if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)"Turning off TV"); } SetTVScreenMaterial(__instance, b: false); audioSource.Stop(); videoSource.Stop(); audioSource.PlayOneShot(__instance.switchTVOn); WalkieTalkie.TransmitOneShotAudio(audioSource, __instance.switchTVOff, 1f); tvIsCurrentlyOn = false; } else { if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)"Turning on TV"); } SetTVScreenMaterial(__instance, b: true); tvIsCurrentlyOn = true; audioSource.Play(); videoSource.Play(); videoSource.time = audioSource.time; audioSource.PlayOneShot(__instance.switchTVOn); WalkieTalkie.TransmitOneShotAudio(audioSource, __instance.switchTVOn, 1f); } } return false; } public static void TVIndexUp() { if (TVIndex >= VideoManager.Videos.Count - 1) { TVIndex = 0; } else { TVIndex++; } SetVideoSourceUrl(); } public static void TVIndexDown() { if (TVIndex <= 0) { TVIndex = VideoManager.Videos.Count - 1; } else { TVIndex--; } SetVideoSourceUrl(); } private static void SetVideoSourceUrl() { videoSource.Stop(); videoSource.time = 0.0; videoSource.url = "file://" + VideoManager.Videos[TVIndex]; } public static void SetTVScreenMaterial(TVScript __instance, bool b) { ((object)__instance).GetType().GetMethod("SetTVScreenMaterial", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[1] { b }); if (!ConfigManager.tvLightEnabled.Value) { ((Behaviour)__instance.tvLight).enabled = false; } } [HarmonyPatch(typeof(TVScript), "TVFinishedClip")] [HarmonyPrefix] public static bool TVFinishedClip(TVScript __instance) { return false; } private static void OnVideoEnded(VideoPlayer source) { if (VideoManager.Videos.Count > 0 && ConfigManager.tvPlaysSequentially.Value) { TVIndexUp(); } } private static void WhatItDo(TVScript __instance, int TVIndex = -1) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown audioSource = __instance.tvSFX; if (VideoManager.Videos.Count > 0) { videoSource.aspectRatio = ConfigManager.tvScalingOption.Value; videoSource.clip = null; audioSource.clip = null; string text = "file://" + VideoManager.Videos[TVIndex]; if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)text); } videoSource.url = text; videoSource.source = (VideoSource)1; VideoPlayer obj = videoSource; object obj2 = <>O.<0>__OnVideoEnded; if (obj2 == null) { EventHandler val = OnVideoEnded; <>O.<0>__OnVideoEnded = val; obj2 = (object)val; } obj.loopPointReached -= (EventHandler)obj2; VideoPlayer obj3 = videoSource; object obj4 = <>O.<0>__OnVideoEnded; if (obj4 == null) { EventHandler val2 = OnVideoEnded; <>O.<0>__OnVideoEnded = val2; obj4 = (object)val2; } obj3.loopPointReached += (EventHandler)obj4; if (tvIsCurrentlyOn) { videoSource.Play(); } videoSource.controlledAudioTrackCount = 1; videoSource.audioOutputMode = (VideoAudioOutputMode)1; videoSource.SetTargetAudioSource((ushort)0, audioSource); videoSource.Stop(); videoSource.Prepare(); } else if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogError((object)"VideoManager.Videos list is empty. Put some videos in Television Videos folder."); } } [HarmonyPatch(typeof(ShipBuildModeManager), "StoreShipObjectClientRpc")] [HarmonyPostfix] private static void StoreShipObjectClientRpcPostfix(int unlockableID) { if (!ConfigManager.storingResets.Value) { return; } UnlockableItem val = StartOfRound.Instance.unlockablesList.unlockables[unlockableID]; if (val.inStorage && val.unlockableName == "Television" && TVIndex != 0) { if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)"Resetting play sequence..."); } SetTVIndex(); } } [HarmonyPatch(typeof(TVScript), "__initializeVariables")] [HarmonyPostfix] public static void SetTelevisionHoverTip(TVScript __instance) { Transform parent = ((Component)__instance).transform.parent; if (((Object)(object)(((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponentInChildren<InteractTrigger>() : null) == (Object)null || (!ConfigManager.enableSeeking.Value && !ConfigManager.enableChannels.Value && !ConfigManager.mouseWheelVolume.Value)) && ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)"Television trigger missing!"); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] public static void GetTVInput(PlayerControllerB __instance) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || __instance.inTerminalMenu || __instance.isTypingChat || __instance.isPlayerDead) { return; } InteractTrigger hoveringOverTrigger = __instance.hoveringOverTrigger; if ((Object)(object)hoveringOverTrigger == (Object)null) { return; } Transform parent = ((Component)hoveringOverTrigger).transform.parent; GameObject val = (((Object)(object)parent != (Object)null) ? ((Component)parent).gameObject : null); if (!((Object)(object)val != (Object)null) || !((Object)val).name.Contains("Television")) { return; } videoSource = val.GetComponentInChildren<VideoPlayer>(); audioSource = ((Component)val.transform.Find("TVAudio")).GetComponent<AudioSource>(); double num = videoSource.time; float y = ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue().y; float volume = audioSource.volume; Key value = ConfigManager.seekReverseKeyBind.Value; Key value2 = ConfigManager.seekForwardKeyBind.Value; Key value3 = ConfigManager.skipReverseKeyBind.Value; Key value4 = ConfigManager.skipForwardKeyBind.Value; if (!((Object)(object)videoSource != (Object)null)) { return; } if (((ButtonControl)Keyboard.current[value]).wasPressedThisFrame && ConfigManager.enableSeeking.Value) { num -= 15.0; if (num < 0.0) { num = 0.0; if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)("AdjustTime: " + num)); } } else { videoSource.time = audioSource.time; videoSource.time = num; if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)("AdjustTime: " + num)); } } } if (((ButtonControl)Keyboard.current[value2]).wasPressedThisFrame && ConfigManager.enableSeeking.Value) { num += 15.0; videoSource.time = audioSource.time; videoSource.time = num; if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)("AdjustTime: " + num)); } } if (((ButtonControl)Keyboard.current[value3]).wasPressedThisFrame && ConfigManager.enableChannels.Value && !ConfigManager.restrictChannels.Value && tvIsCurrentlyOn) { TVIndexDown(); } if (((ButtonControl)Keyboard.current[value4]).wasPressedThisFrame && ConfigManager.enableChannels.Value && !ConfigManager.restrictChannels.Value && tvIsCurrentlyOn) { TVIndexUp(); } if (!videoSource.isPlaying || !tvIsCurrentlyOn) { num = 0.0; videoSource.time = audioSource.time; videoSource.time = num; } InteractTrigger componentInChildren = ((Component)parent).GetComponentInChildren<InteractTrigger>(); if ((Object)(object)componentInChildren == (Object)null && ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)"Television trigger missing!"); } string text = "Seek: " + KeySymbolConverter.GetKeySymbol(value) + KeySymbolConverter.GetKeySymbol(value2) + "\n" + TimeSpan.FromSeconds(num).ToString("hh\\:mm\\:ss\\.fff"); string text2 = "Volume: " + KeySymbolConverter.GetKeySymbol((Key)13) + KeySymbolConverter.GetKeySymbol((Key)80) + "\n" + (volume * 150f).ToString("0") + "%"; string text3 = $"Channel: {KeySymbolConverter.GetKeySymbol(value3)}{KeySymbolConverter.GetKeySymbol(value4)}\n{TVIndex + 1}/{VideoManager.Videos.Count}"; if (!ConfigManager.hideHoverTip.Value) { string text4 = ""; if (ConfigManager.enableSeeking.Value) { text4 += text; } if (ConfigManager.enableChannels.Value) { text4 = text4 + (string.IsNullOrEmpty(text4) ? "" : "\n") + text3; } if (ConfigManager.mouseWheelVolume.Value) { text4 = text4 + (string.IsNullOrEmpty(text4) ? "" : "\n") + text2; } componentInChildren.hoverTip = text4; } if (TVIndex != TVIndex && ConfigManager.enableChannels.Value) { if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)("AdjustMediaFile: " + VideoManager.Videos[TVIndex])); } if (!videoSource.isPlaying || !tvIsCurrentlyOn) { num = 0.0; videoSource.time = audioSource.time; videoSource.time = num; } } if (y != 0f && ConfigManager.mouseWheelVolume.Value) { y /= 6000f; volume = Mathf.Clamp(volume + y, 0f, 1f); audioSource.volume = volume; if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)("Changed volume: " + volume)); } } } } [BepInPlugin("DeathWrench.BestestTelevisionMod", "\u200bBestestTelevisionMod", "1.3.2")] public class BestestTVModPlugin : BaseUnityPlugin { public const string PLUGIN_GUID = "DeathWrench.BestestTelevisionMod"; public const string PLUGIN_NAME = "\u200bBestestTelevisionMod"; public const string PLUGIN_VERSION = "1.3.2"; private static readonly Harmony Harmony = new Harmony("DeathWrench.BestestTelevisionMod".ToString()); public static ManualLogSource Log = new ManualLogSource("\u200b\u200bBestestTelevisionMod"); private InputAction reloadVideosAction; private GameObject gameObject; public static BestestTVModPlugin instance; private void Start() { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown Key value = ConfigManager.reloadVideosKeyBind.Value; reloadVideosAction = new InputAction((string)null, (InputActionType)0, $"<Keyboard>/{value}", "press", (string)null, (string)null); reloadVideosAction.Enable(); reloadVideosAction.performed += OnReloadVideosActionPerformed; } private async void OnReloadVideosActionPerformed(CallbackContext ctx) { //IL_0016: 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) if (((CallbackContext)(ref ctx)).ReadValueAsButton()) { await RefreshVideos(); } } public void ReloadVideos() { VideoManager.Videos.Clear(); VideoManager.Load(); if (ConfigManager.reloadedVideosHUD.Value) { HUDManager.Instance.DisplayTip("Reloaded Videos", "Video list has been reloaded.", false, false, "ReloadVideosTip"); } } public async Task RefreshVideos() { ReloadVideos(); TVScriptPatches.videoSource = instance.gameObject.AddComponent<VideoPlayer>(); TVScriptPatches.videoSource.playOnAwake = false; TVScriptPatches.videoSource.isLooping = false; TVScriptPatches.videoSource.source = (VideoSource)1; TVScriptPatches.videoSource.controlledAudioTrackCount = 1; TVScriptPatches.videoSource.audioOutputMode = (VideoAudioOutputMode)1; TVScriptPatches.videoSource.SetTargetAudioSource((ushort)0, TVScriptPatches.audioSource); TVScriptPatches.videoSource.url = "file://" + VideoManager.Videos[TVScriptPatches.TVIndex]; TVScriptPatches.videoSource.Prepare(); TVScriptPatches.SetTVIndex(); await Task.Delay(100); TVScriptPatches.TVIndexDown(); await Task.Delay(100); TVScriptPatches.TVIndexUp(); } private void OnDisable() { reloadVideosAction.performed -= OnReloadVideosActionPerformed; reloadVideosAction.Disable(); } private void Awake() { ConfigManager.Init(((BaseUnityPlugin)this).Config); instance = this; Log = ((BaseUnityPlugin)this).Logger; Harmony.PatchAll(); VideoManager.Load(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DeathWrench.BestestTelevisionMod 1.3.2 is loaded!"); } } public static class VideoManager { public static List<string> Videos = new List<string>(); public static void Load() { string[] directories = Directory.GetDirectories(Paths.PluginPath); foreach (string text in directories) { string path = Path.Combine(Paths.PluginPath, text, "Television Videos"); if (Directory.Exists(path)) { string[] files = Directory.GetFiles(path, "*.mp4"); Videos.AddRange(files); if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)$"{text} has {files.Length} videos."); } } } string path2 = Path.Combine(Paths.PluginPath, "Television Videos"); if (!Directory.Exists(path2)) { Directory.CreateDirectory(path2); } string[] files2 = Directory.GetFiles(path2, "*.mp4"); Videos.AddRange(files2); if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)$"Global has {files2.Length} videos."); } if (ConfigManager.enableLogging.Value) { BestestTVModPlugin.Log.LogInfo((object)$"Loaded {Videos.Count} total."); } if (ConfigManager.shuffleVideos.Value) { Shuffle(Videos); } } public static void Shuffle<T>(IList<T> list) { Random random = new Random(); Action<IList<T>>[] array = new Action<IList<T>>[5] { FisherYatesShuffle, DurstenfeldShuffle, InsideOutShuffle, SattoloShuffle, RandomPerfectShuffle }; for (int i = 0; i < array.Length; i++) { int num = random.Next(i, array.Length); Action<IList<T>> action = array[i]; array[i] = array[num]; array[num] = action; } Action<IList<T>>[] array2 = array; for (int j = 0; j < array2.Length; j++) { array2[j](list); } } public static void FisherYatesShuffle<T>(IList<T> list) { Random random = new Random(); int count = list.Count; for (int i = 0; i < count; i++) { int index = random.Next(i + 1); T value = list[index]; list[index] = list[i]; list[i] = value; } } public static void DurstenfeldShuffle<T>(IList<T> list) { Random random = new Random(); for (int num = list.Count - 1; num >= 0; num--) { int index = random.Next(num + 1); T value = list[index]; list[index] = list[num]; list[num] = value; } } public static void InsideOutShuffle<T>(IList<T> list) { Random random = new Random(); int count = list.Count; for (int i = 0; i < count; i++) { int num = random.Next(i + 1); if (num != i) { T value = list[num]; list[num] = list[i]; list[i] = value; } } } public static void SattoloShuffle<T>(IList<T> list) { Random random = new Random(); for (int num = list.Count - 1; num > 0; num--) { int index = random.Next(num); T value = list[index]; list[index] = list[num - 1]; list[num - 1] = value; } } public static void RandomPerfectShuffle<T>(IList<T> list) { Random random = new Random(); for (int num = list.Count - 1; num > 0; num--) { int index = random.Next(num + 1); T value = list[index]; list[index] = list[num]; list[num] = value; } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }