Please disclose if any significant portion of your mod was created 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 CustomTvVideos v0.0.1
CustomTvVideos.dll
Decompiled 2 years agousing 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"; } }