Decompiled source of BestestTelevisionMod v1.3.1

BestestTelevisionMod.dll

Decompiled 7 months ago
using 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
	{
		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)
		{
			if (!__instance.tvOn || GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				return false;
			}
			if (ConfigManager.enableLogging.Value)
			{
				BestestTVModPlugin.Log.LogInfo((object)"TVFinishedClip");
			}
			if (VideoManager.Videos.Count > 0 && ConfigManager.tvPlaysSequentially.Value)
			{
				TVIndexUp();
			}
			WhatItDo(__instance, TVIndex);
			return false;
		}

		private static void WhatItDo(TVScript __instance, int TVIndex = -1)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			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;
				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.1")]
	public class BestestTVModPlugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "DeathWrench.BestestTelevisionMod";

		public const string PLUGIN_NAME = "\u200bBestestTelevisionMod";

		public const string PLUGIN_VERSION = "1.3.1";

		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.1 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)
		{
		}
	}
}