using 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 TVLoader.Utils;
using UnityEngine;
using UnityEngine.Video;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("TVLoader")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TVLoader")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e59845a7-f2f7-4416-9a61-ca1939ce6e2d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TVLoader
{
[BepInPlugin("rattenbonkers.TVLoader", "TVLoader", "1.1.2")]
public class TVLoaderPlugin : BaseUnityPlugin
{
private const string MyGUID = "rattenbonkers.TVLoader";
private const string PluginName = "TVLoader";
private const string VersionString = "1.1.2";
private static readonly Harmony Harmony = new Harmony("rattenbonkers.TVLoader");
public static ManualLogSource Log = new ManualLogSource("TVLoader");
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}", "TVLoader", "1.1.2", VideoManager.Videos.Count));
}
}
}
namespace TVLoader.Utils
{
internal 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);
TVLoaderPlugin.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);
TVLoaderPlugin.Log.LogInfo((object)$"Global has {files2.Length} videos.");
TVLoaderPlugin.Log.LogInfo((object)$"Loaded {Videos.Count} total.");
}
}
}
namespace TVLoader.Patches
{
[HarmonyPatch(typeof(TVScript))]
internal class TVScriptPatches
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static EventHandler <>9__13_0;
internal void <PrepareVideo>b__13_0(VideoPlayer source)
{
TVLoaderPlugin.Log.LogInfo((object)"Prepared next 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 tvHasPlayedBefore = false;
private static RenderTexture renderTexture;
private static VideoPlayer currentVideoPlayer;
private static VideoPlayer nextVideoPlayer;
[HarmonyPrefix]
[HarmonyPatch("Update")]
public static bool Update(TVScript __instance)
{
if ((Object)(object)currentVideoPlayer == (Object)null)
{
currentVideoPlayer = ((Component)__instance).GetComponent<VideoPlayer>();
renderTexture = currentVideoPlayer.targetTexture;
if (VideoManager.Videos.Count > 0)
{
PrepareVideo(__instance, 0);
}
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch("TurnTVOnOff")]
public static bool TurnTVOnOff(TVScript __instance, bool on)
{
TVLoaderPlugin.Log.LogInfo((object)$"VideoPlayer Resolution: {((Texture)currentVideoPlayer.targetTexture).width}x{((Texture)currentVideoPlayer.targetTexture).height}");
TVLoaderPlugin.Log.LogInfo((object)$"TVOnOff: {on}");
if (VideoManager.Videos.Count == 0)
{
return false;
}
int num = (int)currentClipProperty.GetValue(__instance);
if (on && tvHasPlayedBefore)
{
num = (num + 1) % VideoManager.Videos.Count;
currentClipProperty.SetValue(__instance, num);
}
__instance.tvOn = on;
if (on)
{
PlayVideo(__instance);
__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 || GameNetworkManager.Instance.localPlayerController.isInsideFactory)
{
return false;
}
TVLoaderPlugin.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 = -1)
{
//IL_00f0: 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_00fb: Expected O, but got Unknown
if (index == -1)
{
index = (int)currentClipProperty.GetValue(instance) + 1;
}
if ((Object)(object)nextVideoPlayer != (Object)null && ((Component)nextVideoPlayer).gameObject.activeInHierarchy)
{
Object.Destroy((Object)(object)nextVideoPlayer);
}
nextVideoPlayer = ((Component)instance).gameObject.AddComponent<VideoPlayer>();
nextVideoPlayer.playOnAwake = false;
nextVideoPlayer.isLooping = false;
nextVideoPlayer.source = (VideoSource)1;
nextVideoPlayer.controlledAudioTrackCount = 1;
nextVideoPlayer.audioOutputMode = (VideoAudioOutputMode)1;
nextVideoPlayer.SetTargetAudioSource((ushort)0, instance.tvSFX);
nextVideoPlayer.url = "file://" + VideoManager.Videos[index % VideoManager.Videos.Count];
nextVideoPlayer.skipOnDrop = true;
nextVideoPlayer.Prepare();
VideoPlayer obj = nextVideoPlayer;
object obj2 = <>c.<>9__13_0;
if (obj2 == null)
{
EventHandler val = delegate
{
TVLoaderPlugin.Log.LogInfo((object)"Prepared next video!");
};
<>c.<>9__13_0 = val;
obj2 = (object)val;
}
obj.prepareCompleted += (EventHandler)obj2;
}
private static void PlayVideo(TVScript instance)
{
tvHasPlayedBefore = true;
if (VideoManager.Videos.Count != 0)
{
if ((Object)(object)nextVideoPlayer != (Object)null)
{
VideoPlayer val = currentVideoPlayer;
instance.video = (currentVideoPlayer = nextVideoPlayer);
nextVideoPlayer = null;
TVLoaderPlugin.Log.LogInfo((object)$"Destroy {val}");
Object.Destroy((Object)(object)val);
onEnableMethod.Invoke(instance, new object[0]);
}
currentTimeProperty.SetValue(instance, 0f);
instance.video.targetTexture = renderTexture;
instance.video.Play();
PrepareVideo(instance);
}
}
}
}