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 TVLoaderExtended v1.1.4
BepInEx/plugins/TVLoaderExtended/TVLoaderExtended.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using TVLoaderExtended.Utils; using Unity.Netcode; using UnityEngine; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("TVLoaderExtended")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TVLoaderExtended")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5F5ACB51-F9E6-4E85-B3A4-028FEE7B0650")] [assembly: AssemblyFileVersion("1.1.3")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.1.3.0")] namespace TVLoaderExtended { [BepInPlugin("Filigrani.TVLoaderExtended", "TVLoaderExtended", "1.1.3")] public class TVLoaderExtendedPlugin : BaseUnityPlugin { private const string MyGUID = "Filigrani.TVLoaderExtended"; private const string PluginName = "TVLoaderExtended"; private const string VersionString = "1.1.3"; private static readonly Harmony Harmony = new Harmony("Filigrani.TVLoaderExtended"); public static ManualLogSource Log = new ManualLogSource("TVLoaderExtended"); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Harmony.PatchAll(); VideoManager.Load(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("PluginName: {0}, VersionString: {1} is loaded. Video Count: {2}", "TVLoaderExtended", "1.1.3", VideoManager.Videos.Count)); } } } namespace TVLoaderExtended.Utils { internal static class VideoManager { public static List<string> Videos = new List<string>(); public static void Load() { Videos.Clear(); string[] directories = Directory.GetDirectories(Paths.PluginPath); string[] array = directories; foreach (string text in array) { string path = Path.Combine(Paths.PluginPath, text, "Television Videos"); if (Directory.Exists(path)) { string[] files = Directory.GetFiles(path, "*.mp4"); Videos.AddRange(files); TVLoaderExtendedPlugin.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); TVLoaderExtendedPlugin.Log.LogInfo((object)$"Global has {files2.Length} videos."); TVLoaderExtendedPlugin.Log.LogInfo((object)$"Loaded {Videos.Count} total."); } } } namespace TVLoaderExtended.Patches { [HarmonyPatch(typeof(StartOfRound))] internal class NewSave { [HarmonyPatch("firstDayAnimation")] [HarmonyPostfix] internal static void StartPatching() { StartOfRound instance = StartOfRound.Instance; if (!((NetworkBehaviour)instance).NetworkManager.IsHost) { return; } List<UnlockableItem> unlockables = instance.unlockablesList.unlockables; foreach (UnlockableItem item in unlockables) { if (item.unlockableName == "Television") { UnlockShipItem(instance, unlockables.IndexOf(item), item.unlockableName); break; } } } private static void UnlockShipItem(StartOfRound instance, int unlockableID, string name) { try { MethodInfo method = ((object)instance).GetType().GetMethod("UnlockShipObject", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(instance, new object[1] { unlockableID }); } catch (NullReferenceException) { } } } [HarmonyPatch(typeof(TVScript))] internal class TVScriptPatches { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__22_0; internal void <PrepareVideo>b__22_0(VideoPlayer source) { TVLoaderExtendedPlugin.Log.LogInfo((object)"Prepared video!"); } } private static FieldInfo currentClipProperty = typeof(TVScript).GetField("currentClip", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo currentTimeProperty = typeof(TVScript).GetField("currentClipTime", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo wasTvOnLastFrameProp = typeof(TVScript).GetField("wasTvOnLastFrame", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo timeSinceTurningOffTVProp = typeof(TVScript).GetField("timeSinceTurningOffTV", BindingFlags.Instance | BindingFlags.NonPublic); private static MethodInfo setMatMethod = typeof(TVScript).GetMethod("SetTVScreenMaterial", BindingFlags.Instance | BindingFlags.NonPublic); private static MethodInfo onEnableMethod = typeof(TVScript).GetMethod("OnEnable", BindingFlags.Instance | BindingFlags.NonPublic); private static bool s_EverWasOn = false; private static RenderTexture renderTexture; private static List<string> m_Videos = new List<string>(); private static int s_LastSeed = 0; private static int s_LastSeenIndex = -1; private static string GetVideoPath(int Index) { return GetFullPath(m_Videos[Index]); } private static int GetSeed(TVScript Instance) { return ((NetworkBehaviour)Instance).NetworkObjectId.ToString().GetHashCode(); } private static void Shuffle<T>(List<T> List, int Seed) { Random random = new Random(Seed); int count = List.Count; for (int i = 0; i < count - 1; i++) { int index = i + random.Next(count - i); T value = List[index]; List[index] = List[i]; List[i] = value; } } public static List<string> GetClearList(List<string> Pathes) { List<string> list = new List<string>(); for (int i = 0; i < Pathes.Count; i++) { string text = Pathes[i]; string[] separator = new string[1] { "plugins" }; string[] array = text.Split(separator, StringSplitOptions.None); string item = array[1]; list.Add(item); } list.Sort(); return list; } public static string GetFullPath(string ShortPath) { foreach (string video in VideoManager.Videos) { if (video.EndsWith(ShortPath)) { return video; } } return ""; } public static void ShuffleVideos(TVScript Instance) { m_Videos = GetClearList(VideoManager.Videos); TVLoaderExtendedPlugin.Log.LogInfo((object)("[TVScriptExtended] ShuffleVideos " + GetSeed(Instance))); Shuffle(m_Videos, GetSeed(Instance)); for (int i = 0; i < m_Videos.Count; i++) { TVLoaderExtendedPlugin.Log.LogInfo((object)("[TVScriptExtended] m_Videos[" + i + "] " + m_Videos[i])); } } public static void ClientUpdate(TVScript Instance) { int num = (int)currentClipProperty.GetValue(Instance); if (s_LastSeenIndex != num) { s_LastSeenIndex = num; TVLoaderExtendedPlugin.Log.LogInfo((object)("[ClientUpdate] currentClip " + num + " Instance.tvOn " + Instance.tvOn)); if (Instance.tvOn) { PlayVideo(Instance); } } } public static bool PlayerIsHost(TVScript __instance) { if (Object.op_Implicit((Object)(object)__instance)) { return ((NetworkBehaviour)__instance).NetworkManager.IsHost; } return false; } [HarmonyPrefix] [HarmonyPatch("Update")] public static bool Update(TVScript __instance) { if ((Object)(object)renderTexture == (Object)null) { renderTexture = ((Component)__instance).GetComponent<VideoPlayer>().targetTexture; } if (!PlayerIsHost(__instance)) { ClientUpdate(__instance); } if (s_LastSeed != GetSeed(__instance)) { s_LastSeed = GetSeed(__instance); ShuffleVideos(__instance); if (PlayerIsHost(__instance)) { currentClipProperty.SetValue(__instance, 0); } else { currentClipProperty.SetValue(__instance, -1); } s_EverWasOn = false; } return false; } [HarmonyPrefix] [HarmonyPatch("TurnTVOnOff")] public static bool TurnTVOnOff(TVScript __instance, bool on) { TVLoaderExtendedPlugin.Log.LogInfo((object)$"TVOnOff: {on}"); if (VideoManager.Videos.Count == 0) { return false; } int num = (int)currentClipProperty.GetValue(__instance); __instance.tvOn = on; if (PlayerIsHost(__instance)) { if (on) { if (!s_EverWasOn) { s_EverWasOn = true; } else { num = (num + 1) % VideoManager.Videos.Count; currentClipProperty.SetValue(__instance, num); } PlayVideo(__instance); } } else if (on) { currentTimeProperty.SetValue(__instance, 0f); } if (on) { __instance.tvSFX.PlayOneShot(__instance.switchTVOn); WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOn, 1f); } else { __instance.video.Stop(); __instance.tvSFX.PlayOneShot(__instance.switchTVOff); WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOff, 1f); } setMatMethod.Invoke(__instance, new object[1] { on }); return false; } [HarmonyPrefix] [HarmonyPatch("TVFinishedClip")] public static bool TVFinishedClip(TVScript __instance, VideoPlayer source) { if (__instance.tvOn && PlayerIsHost(__instance)) { TVLoaderExtendedPlugin.Log.LogInfo((object)"TVFinishedClip"); int num = (int)currentClipProperty.GetValue(__instance); if (VideoManager.Videos.Count > 0) { num = (num + 1) % VideoManager.Videos.Count; } currentTimeProperty.SetValue(__instance, 0f); currentClipProperty.SetValue(__instance, num); PlayVideo(__instance); } return false; } private static void PrepareVideo(TVScript instance, int index) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown if (index < 0) { return; } string videoPath = GetVideoPath(index); Object.Destroy((Object)(object)instance.video); VideoPlayer val = ((Component)instance).gameObject.AddComponent<VideoPlayer>(); val.playOnAwake = false; val.isLooping = false; val.source = (VideoSource)1; val.controlledAudioTrackCount = 1; val.audioOutputMode = (VideoAudioOutputMode)1; val.SetTargetAudioSource((ushort)0, instance.tvSFX); TVLoaderExtendedPlugin.Log.LogInfo((object)("Going to prepare: " + videoPath)); val.url = "file://" + videoPath; val.skipOnDrop = true; val.Prepare(); object obj = <>c.<>9__22_0; if (obj == null) { EventHandler val2 = delegate { TVLoaderExtendedPlugin.Log.LogInfo((object)"Prepared video!"); }; <>c.<>9__22_0 = val2; obj = (object)val2; } val.prepareCompleted += (EventHandler)obj; instance.video = val; } private static void PlayVideo(TVScript instance) { if (VideoManager.Videos.Count != 0) { currentTimeProperty.SetValue(instance, 0f); PrepareVideo(instance, (int)currentClipProperty.GetValue(instance)); onEnableMethod.Invoke(instance, new object[0]); TVLoaderExtendedPlugin.Log.LogInfo((object)("TV Current Video Index " + (int)currentClipProperty.GetValue(instance))); instance.video.targetTexture = renderTexture; instance.video.Play(); if (PlayerIsHost(instance)) { instance.SyncTVServerRpc(); } } } } }