Decompiled source of CustomTvVideos v0.0.1

CustomTvVideos.dll

Decompiled 2 years ago
using System;
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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
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: AssemblyCompany("CustomTvVideos")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Allowes you to set custom videos for the tv")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1")]
[assembly: AssemblyProduct("CustomTvVideos")]
[assembly: AssemblyTitle("CustomTvVideos")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.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 CustomTvVideos
{
	internal interface IGetter<out T>
	{
		T GetValue();
	}
	internal interface ITryGet<T>
	{
		bool TryGetValue(out T? value);
	}
	public class MyPluginInfo
	{
		public const string PLUGIN_GUID = "sakura.custom-tv-videos";

		public const string PLUGIN_NAME = "CustomTvVideos";

		public const string PLUGIN_VERSION = "0.0.1";
	}
	[BepInPlugin("sakura.custom-tv-videos", "CustomTvVideos", "0.0.1")]
	[HarmonyPatch(typeof(TVScript))]
	public class CustomTvVideos : BaseUnityPlugin
	{
		private static string videosDir = Path.Combine(Paths.BepInExRootPath, "CustomTvVideos", "VideoClips");

		private static ManualLogSource logger;

		private Harmony harmony = new Harmony("sakura.custom-tv-videos");

		private static FileInfo[] videoFiles;

		private static int currentClip = 0;

		private static bool wasTvOnLastFrame;

		private static float currentClipTime;

		private static float timeSinceTurningOffTV;

		private void Awake()
		{
			logger = ((BaseUnityPlugin)this).Logger;
			CreateDirectoryIfItDoesNotExist();
			if (new VideoGetter(((BaseUnityPlugin)this).Logger).TryGetValue(out var value))
			{
				List<FileInfo> list = new List<FileInfo>();
				string[] array = value;
				foreach (string fileName in array)
				{
					list.Add(new FileInfo(fileName));
				}
				videoFiles = list.ToArray();
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Got {value.Length} video files.");
				if (videoFiles.Length == 0)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"No video clips where loaded, Aborting...");
					((Component)this).gameObject.SetActive(false);
				}
				else
				{
					harmony.PatchAll(typeof(CustomTvVideos));
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin sakura.custom-tv-videos is loaded!");
				}
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogFatal((object)"Unable to get video clips.");
				((Component)this).gameObject.SetActive(false);
			}
		}

		private void CreateDirectoryIfItDoesNotExist()
		{
			Directory.CreateDirectory(videosDir);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Video Directory: " + videosDir));
		}

		private static void SetVideo(TVScript tv, FileInfo videoFile)
		{
			tv.video.clip = null;
			tv.tvSFX.clip = null;
			tv.video.url = "file://" + videoFile.FullName;
			tv.video.source = (VideoSource)1;
			tv.video.controlledAudioTrackCount = 1;
			tv.video.audioOutputMode = (VideoAudioOutputMode)1;
			tv.video.SetTargetAudioSource((ushort)0, tv.tvSFX);
			tv.video.Prepare();
			tv.video.Stop();
			tv.tvSFX.Stop();
		}

		[HarmonyPatch(typeof(TVScript), "TVFinishedClip")]
		[HarmonyPrefix]
		public static bool TV_TVFinishedClip(TVScript __instance, VideoPlayer source)
		{
			logger.LogInfo((object)"TV_TVFinishedClip");
			if (__instance.tvOn && !GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				currentClip = (currentClip + 1) % videoFiles.Length;
				FileInfo fileInfo = videoFiles[currentClip];
				logger.LogInfo((object)("Playing " + fileInfo.FullName));
				SetVideo(__instance, fileInfo);
			}
			return false;
		}

		[HarmonyPatch(typeof(TVScript), "TurnTVOnOff")]
		[HarmonyPrefix]
		public static bool TV_TurnTVOnOff(TVScript __instance, bool on)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			logger.LogInfo((object)"TV_TurnTVOnOff");
			__instance.tvOn = on;
			if ((int)__instance.video.source != 1 || __instance.video.url == "")
			{
				__instance.video.clip = null;
				__instance.tvSFX.clip = null;
				currentClip = (currentClip + 1) % videoFiles.Length;
				FileInfo videoFile = videoFiles[currentClip];
				SetVideo(__instance, videoFile);
			}
			if (on)
			{
				FileInfo videoFile2 = videoFiles[currentClip];
				SetVideo(__instance, videoFile2);
				SetTVScreenMaterial(__instance, b: true);
				__instance.video.Play();
				__instance.tvSFX.Play();
				__instance.tvSFX.PlayOneShot(__instance.switchTVOn);
				WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOn, 1f);
			}
			else
			{
				SetTVScreenMaterial(__instance, b: false);
				__instance.tvSFX.Stop();
				__instance.tvSFX.PlayOneShot(__instance.switchTVOff);
				__instance.video.Stop();
				WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOff, 1f);
			}
			return false;
		}

		[HarmonyPatch(typeof(TVScript), "Update")]
		[HarmonyPrefix]
		public static bool TV_Update(TVScript __instance)
		{
			if (NetworkManager.Singleton.ShutdownInProgress || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return false;
			}
			if (!__instance.tvOn || GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				if (wasTvOnLastFrame)
				{
					wasTvOnLastFrame = false;
					SetTVScreenMaterial(__instance, b: false);
					currentClipTime = (float)__instance.video.time;
					__instance.video.Stop();
				}
				if (((NetworkBehaviour)__instance).IsServer && !__instance.tvOn)
				{
					timeSinceTurningOffTV += Time.deltaTime;
				}
				currentClipTime += Time.deltaTime;
				if ((double)currentClipTime > __instance.video.length)
				{
					currentClip = (currentClip + 1) % videoFiles.Length;
					FileInfo videoFile = videoFiles[currentClip];
					SetVideo(__instance, videoFile);
				}
			}
			return false;
		}

		public static void SetTVScreenMaterial(TVScript instance, bool b)
		{
			((object)instance).GetType().GetMethod("SetTVScreenMaterial", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(instance, new object[1] { b });
		}
	}
	internal class VideoGetter : ITryGet<string[]>
	{
		[Flags]
		private enum PlatformFlag
		{
			Unknown = 0,
			Windows = 1,
			MacOS = 2,
			Linux = 4
		}

		private struct FileType
		{
			public string Extension;

			public PlatformFlag Platform;

			public FileType(string extension, PlatformFlag platform)
			{
				Extension = extension;
				Platform = platform;
			}
		}

		private ManualLogSource logger;

		private static string videosDir = Path.Combine(Paths.BepInExRootPath, "CustomTvVideos", "VideoClips");

		private static FileType[] videoFileTypes = new FileType[12]
		{
			new FileType(".asf", PlatformFlag.Windows),
			new FileType(".avi", PlatformFlag.Windows),
			new FileType(".dv", PlatformFlag.Windows | PlatformFlag.MacOS),
			new FileType(".mv4", PlatformFlag.Windows | PlatformFlag.MacOS),
			new FileType(".mov", PlatformFlag.Windows | PlatformFlag.MacOS),
			new FileType(".mp4", PlatformFlag.Windows | PlatformFlag.MacOS),
			new FileType(".mpg", PlatformFlag.Windows | PlatformFlag.MacOS),
			new FileType(".mpeg", PlatformFlag.Windows | PlatformFlag.MacOS),
			new FileType(".ogv", PlatformFlag.Windows | PlatformFlag.MacOS | PlatformFlag.Linux),
			new FileType(".vp8", PlatformFlag.Windows | PlatformFlag.MacOS | PlatformFlag.Linux),
			new FileType(".webm", PlatformFlag.Windows | PlatformFlag.MacOS | PlatformFlag.Linux),
			new FileType(".wmv", PlatformFlag.Windows)
		};

		public VideoGetter(ManualLogSource logger)
		{
			this.logger = logger;
		}

		private static bool IsSupportedOnCurrentPlatform(string extension, PlatformFlag platform)
		{
			return videoFileTypes.Any((FileType x) => x.Extension == extension && x.Platform.HasFlag(platform));
		}

		private string[] GetSupportedVideoFiles(string dir, PlatformFlag platform)
		{
			List<string> list = new List<string>();
			foreach (string item in Directory.EnumerateFiles(dir))
			{
				FileInfo fileInfo = new FileInfo(item);
				if (fileInfo.Exists)
				{
					if (IsSupportedOnCurrentPlatform(fileInfo.Extension, platform))
					{
						list.Add(fileInfo.FullName);
					}
					else
					{
						logger.LogWarning((object)("File: \"" + fileInfo.Name + "\" Is not supported."));
					}
				}
			}
			return list.ToArray();
		}

		public bool TryGetValue(out string[] value)
		{
			try
			{
				PlatformFlag currentPlatform = GetCurrentPlatform();
				string[] supportedVideoFiles = GetSupportedVideoFiles(videosDir, currentPlatform);
				value = supportedVideoFiles;
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError((object)ex);
				value = null;
				return false;
			}
		}

		private static PlatformFlag GetCurrentPlatform()
		{
			//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)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			RuntimePlatform platform = Application.platform;
			if ((int)platform != 1)
			{
				if ((int)platform != 2)
				{
					if ((int)platform == 13)
					{
						return PlatformFlag.Linux;
					}
					throw new PlatformNotSupportedException($"Platform: \"{platform}\" is not supported.");
				}
				return PlatformFlag.Windows;
			}
			return PlatformFlag.MacOS;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CustomTvVideos";

		public const string PLUGIN_NAME = "CustomTvVideos";

		public const string PLUGIN_VERSION = "0.0.1";
	}
}