Decompiled source of CustomTvVideos v0.1.3

CustomTvVideos.dll

Decompiled 11 months 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 CustomTvVideos.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using JetBrains.Annotations;
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.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3")]
[assembly: AssemblyProduct("CustomTvVideos")]
[assembly: AssemblyTitle("CustomTvVideos")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.3.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 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.1.3";
	}
	[BepInPlugin("sakura.custom-tv-videos", "CustomTvVideos", "0.1.3")]
	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");

		[UsedImplicitly]
		private void Awake()
		{
			try
			{
				logger = ((BaseUnityPlugin)this).Logger;
				CreateDirectoryIfItDoesNotExist();
				if (LoadClips())
				{
					harmony.PatchAll(typeof(TvScriptPatch));
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin sakura.custom-tv-videos is loaded!");
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Encountered an error in Awake()\n {arg}");
			}
		}

		private bool LoadClips()
		{
			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));
				}
				FileInfo[] array2 = list.ToArray();
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Got {value.Length} video files.");
				if (array2.Length == 0)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"No video clips where loaded, Aborting...");
					((Component)this).gameObject.SetActive(false);
					return false;
				}
				TvScriptPatch.Init(array2, logger);
				return true;
			}
			((BaseUnityPlugin)this).Logger.LogFatal((object)"Unable to get video clips.");
			((Component)this).gameObject.SetActive(false);
			return false;
		}

		private void CreateDirectoryIfItDoesNotExist()
		{
			Directory.CreateDirectory(videosDir);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Video Directory: " + videosDir));
		}
	}
	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) => string.Compare(x.Extension, extension) == 0 && 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.1.3";
	}
}
namespace CustomTvVideos.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
	}
	[HarmonyPatch(typeof(TVScript))]
	internal class TvScriptPatch
	{
		private static ManualLogSource logger;

		private static FileInfo[] videoFiles;

		private static int currentClip;

		private static bool setupDone;

		private static bool wasTvOnLastFrame;

		private static float currentClipTime;

		internal static void Init(FileInfo[] videos, ManualLogSource logSource)
		{
			videoFiles = videos;
			logger = logSource;
		}

		private static void IncrementCurrentClip()
		{
			if (currentClip + 1 >= videoFiles.Length)
			{
				currentClip = 0;
			}
			else
			{
				currentClip++;
			}
		}

		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]
		private static bool TV_TVFinishedClip(TVScript __instance, VideoPlayer source)
		{
			logger.LogInfo((object)"TV_TVFinishedClip");
			if (__instance.tvOn && !GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				IncrementCurrentClip();
				FileInfo fileInfo = videoFiles[currentClip];
				logger.LogInfo((object)("Playing " + fileInfo.FullName));
				SetVideo(__instance, fileInfo);
			}
			return false;
		}

		[HarmonyPatch(typeof(TVScript), "TurnTVOnOff")]
		[HarmonyPrefix]
		private static bool TV_TurnTVOnOff(TVScript __instance, bool on)
		{
			logger.LogInfo((object)"TV_TurnTVOnOff");
			__instance.tvOn = on;
			if (!setupDone)
			{
				__instance.video.clip = null;
				__instance.tvSFX.clip = null;
				IncrementCurrentClip();
				FileInfo videoFile = videoFiles[currentClip];
				SetVideo(__instance, videoFile);
				setupDone = true;
			}
			if (on)
			{
				IncrementCurrentClip();
				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]
		private 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) && wasTvOnLastFrame)
			{
				wasTvOnLastFrame = false;
				SetTVScreenMaterial(__instance, b: false);
				currentClipTime = (float)__instance.video.time;
				__instance.video.Stop();
			}
			return false;
		}

		private static void SetTVScreenMaterial(TVScript instance, bool b)
		{
			((object)instance).GetType().GetMethod("SetTVScreenMaterial", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(instance, new object[1] { b });
		}
	}
}