Please disclose if your mod was created primarily 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 WapakoTV v1.0.1
WapakoTV.dll
Decompiled 7 months 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.Configuration; using BepInEx.Logging; using HarmonyLib; using PTV.NetcodePatcher; 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("PTV")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PTV")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b31351bc-9f05-4a83-ab84-20ca395fc6df")] [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")] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } namespace PTV { [BepInPlugin("Gavinboy3000.PTV", "PTV", "1.0.1")] public class PTV : BaseUnityPlugin { public const string modGUID = "Gavinboy3000.PTV"; public const string modName = "PTV"; public const string modVersion = "1.0.1"; public static ConfigEntry<bool> configBeginWithIntro; public static ConfigEntry<bool> configTVInShop; private readonly Harmony harmony = new Harmony("Gavinboy3000.PTV"); public static ManualLogSource logger = new ManualLogSource("Gavinboy3000.PTV"); public static GameObject networkPrefab; private void Awake() { configBeginWithIntro = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Begin With Intro", true, "Puts main intro at the beginning of every shuffle."); configTVInShop = ((BaseUnityPlugin)this).Config.Bind<bool>("QOL", "TV in Shop", true, "Makes it so the television is always in the shop."); NetcodePatcher(); logger = ((BaseUnityPlugin)this).Logger; string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "asset"); AssetBundle val = AssetBundle.LoadFromFile(text); networkPrefab = val.LoadAsset<GameObject>("Assets/NetworkHandler.prefab"); networkPrefab.AddComponent<NetworkHandler>(); VideoManager.Load(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location)); harmony.PatchAll(); logger.LogInfo((object)"PTV version 1.0.1 has loaded!"); } private static void NetcodePatcher() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } [HarmonyPatch(typeof(TVScript))] internal static class TVScriptPatch { 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 TVScript tv; private static RenderTexture renderTexture; private static VideoPlayer currentVP; private static VideoPlayer nextVP; private static int currentIndex = -1; private static int nextIndex = 0; private static double forceTime = -1.0; private static bool tvExists = true; [HarmonyPrefix] [HarmonyPatch("Update")] public static bool Update(TVScript __instance) { tv = __instance; if ((Object)(object)currentVP != (Object)null) { return false; } currentVP = ((Component)tv).GetComponent<VideoPlayer>(); renderTexture = currentVP.targetTexture; if (VideoManager.Videos.Count < 1) { return false; } if (!NetworkHandler.Hosting()) { if (!tvExists) { tvExists = true; TurnTVOnOff(tv, on: false); } PrepareNextVideo(tv); return false; } TurnTVOnOff(tv, on: false); VideoManager.ShuffledVideos = new List<string>(VideoManager.Videos); VideoManager.Shuffle(); currentIndex = -1; nextIndex = 0; PrepareNextVideo(tv); return false; } [HarmonyPrefix] [HarmonyPatch("TurnTVOnOff")] public static bool TurnTVOnOff(TVScript __instance, bool on) { tv = __instance; if (VideoManager.Videos.Count < 1) { return false; } tv.tvOn = on; if (on) { PlayNextVideo(); tv.tvSFX.PlayOneShot(tv.switchTVOn); WalkieTalkie.TransmitOneShotAudio(tv.tvSFX, tv.switchTVOn, 1f); } else { tv.video.Stop(); tv.tvSFX.PlayOneShot(tv.switchTVOff); WalkieTalkie.TransmitOneShotAudio(tv.tvSFX, tv.switchTVOff, 1f); } setMatMethod.Invoke(tv, new object[1] { on }); return false; } [HarmonyPrefix] [HarmonyPatch("TVFinishedClip")] public static bool TVFinishedClip(TVScript __instance, VideoPlayer source) { tv = __instance; PlayNextVideo(); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(TVScript), "OnDisable")] public static void TVDisabled() { if (!NetworkHandler.Hosting()) { tvExists = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(Terminal), "RotateShipDecorSelection")] public static void AddTV(Terminal __instance) { if (!PTV.configTVInShop.Value) { return; } int num = -1; for (int i = 0; i < StartOfRound.Instance.unlockablesList.unlockables.Count; i++) { if (StartOfRound.Instance.unlockablesList.unlockables[i].unlockableName == "Television") { num = i; break; } } if (num != -1) { TerminalNode shopSelectionNode = StartOfRound.Instance.unlockablesList.unlockables[num].shopSelectionNode; if (!__instance.ShipDecorSelection.Contains(shopSelectionNode)) { __instance.ShipDecorSelection.Add(shopSelectionNode); } } } private static void PrepareNextVideo(TVScript tv) { if ((Object)(object)nextVP != (Object)null && ((Component)nextVP).gameObject.activeInHierarchy) { Object.Destroy((Object)(object)nextVP); } nextVP = ((Component)tv).gameObject.AddComponent<VideoPlayer>(); nextVP.playOnAwake = false; nextVP.source = (VideoSource)1; nextVP.controlledAudioTrackCount = 1; nextVP.audioOutputMode = (VideoAudioOutputMode)1; nextVP.SetTargetAudioSource((ushort)0, tv.tvSFX); nextVP.skipOnDrop = true; if (NetworkHandler.Hosting()) { nextVP.url = "file://" + VideoManager.ShuffledVideos[nextIndex]; } else { nextVP.url = "file://" + VideoManager.Videos[nextIndex]; } nextVP.Prepare(); } private static void PlayNextVideo(int index = -1) { if (!((Object)(object)nextVP == (Object)null)) { VideoPlayer val = currentVP; tv.video = (currentVP = nextVP); nextVP = null; Object.Destroy((Object)(object)val); onEnableMethod.Invoke(tv, new object[0]); currentIndex = nextIndex; if (NetworkHandler.Hosting()) { nextIndex = VideoManager.NextIndex(currentIndex); } else if (index != -1) { nextIndex = index; } if (NetworkHandler.Hosting()) { UpdateInfo(); } tv.video.targetTexture = renderTexture; tv.video.Play(); PrepareNextVideo(tv); } } [HarmonyPostfix] [HarmonyPatch(typeof(NetworkManager), "SetSingleton")] public static void Init() { NetworkManager.Singleton.OnClientConnectedCallback += ClientConnected; } private static void ClientConnected(ulong id) { if (!NetworkHandler.Hosting() || id == 0) { return; } if ((Object)(object)tv != (Object)null) { if (tv.tvOn) { UpdateInfo(1); } else { UpdateInfo(0); } } else { UpdateInfo(0); } } private static void ForceTime(VideoPlayer source) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (forceTime != -1.0) { source.time = forceTime; source.prepareCompleted -= new EventHandler(ForceTime); forceTime = -1.0; } } public static void RecievedInfo(int current, double time, int next, int tvOn) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown if (NetworkHandler.Hosting()) { return; } if ((Object)(object)tv == (Object)null) { tvExists = false; currentIndex = current; nextIndex = next; return; } switch (tvOn) { case 0: TurnTVOnOff(tv, on: false); break; case 1: nextIndex = current; PrepareNextVideo(tv); TurnTVOnOff(tv, on: true); break; } if (currentIndex != current) { if (tv.tvOn) { nextIndex = current; PrepareNextVideo(tv); PlayNextVideo(next); } else { currentIndex = current; nextIndex = next; PrepareNextVideo(tv); } } else if (nextIndex != next) { nextIndex = next; PrepareNextVideo(tv); } double num = time - currentVP.time; if (Mathf.Abs((float)num) >= 1f) { forceTime = time; currentVP.prepareCompleted += new EventHandler(ForceTime); } } private static void UpdateInfo(int tvOn = -1) { double time = 0.0; if (Object.op_Implicit((Object)(object)currentVP)) { time = currentVP.time; } NetworkHandler.instance.UpdateInfoClientRpc(VideoManager.GetTrueIndex(currentIndex), time, VideoManager.GetTrueIndex(nextIndex), tvOn); } } internal static class VideoManager { public static List<string> Videos = new List<string>(); public static List<string> ShuffledVideos; public static void Load(string basePath) { string text = Path.Combine(basePath, "Videos"); if (!Directory.Exists(basePath)) { return; } string[] files; if (!Directory.Exists(text)) { files = Directory.GetFiles(basePath, "*.mp4"); if (files.Length < 1) { return; } Directory.CreateDirectory(text); for (int i = 0; i < files.Length; i++) { string destFileName = Path.Combine(text, Path.GetFileName(files[i])); File.Move(files[i], destFileName); } } files = Directory.GetFiles(text, "*.mp4"); Videos.AddRange(files); PTV.logger.LogInfo((object)$"Successfully loaded {Videos.Count} videos!"); } public static void Shuffle() { int num = ShuffledVideos.Count; while (num > 1) { num--; int index = Random.Range(0, num + 1); string value = ShuffledVideos[index]; ShuffledVideos[index] = ShuffledVideos[num]; ShuffledVideos[num] = value; } if (PTV.configBeginWithIntro.Value) { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Videos", "MainIntro.mp4"); int num2 = ShuffledVideos.IndexOf(text); if (num2 != -1) { string value2 = ShuffledVideos[0]; ShuffledVideos[0] = text; ShuffledVideos[num2] = value2; } } } public static int GetTrueIndex(int index) { if (ShuffledVideos == null) { return 0; } if (index < 0) { index = 0; } int num = Videos.IndexOf(ShuffledVideos[index]); if (num == -1) { return index; } return num; } public static int NextIndex(int index) { if (index + 1 >= Videos.Count) { Shuffle(); } return (index + 1) % Videos.Count; } } [HarmonyPatch] public class NetworkObjectManager { [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Start")] private static void Init(GameNetworkManager __instance) { ((Component)__instance).GetComponent<NetworkManager>().AddNetworkPrefab(PTV.networkPrefab); } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Awake")] private static void SpawnNetworkHandler() { if (NetworkHandler.Hosting()) { GameObject val = Object.Instantiate<GameObject>(PTV.networkPrefab); val.GetComponent<NetworkObject>().Spawn(false); } } } public class NetworkHandler : NetworkBehaviour { public static NetworkHandler instance; public static bool Hosting() { return NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer; } public override void OnNetworkSpawn() { instance = this; ((NetworkBehaviour)this).OnNetworkSpawn(); } [ClientRpc] public void UpdateInfoClientRpc(int current, double time, int next, int tvOn) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2660303476u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, current); ((FastBufferWriter)(ref val2)).WriteValueSafe<double>(ref time, default(ForPrimitives)); BytePacker.WriteValueBitPacked(val2, next); BytePacker.WriteValueBitPacked(val2, tvOn); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2660303476u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost)) { TVScriptPatch.RecievedInfo(current, time, next, tvOn); } } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_NetworkHandler() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(2660303476u, new RpcReceiveHandler(__rpc_handler_2660303476)); } private static void __rpc_handler_2660303476(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int current = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref current); double time = default(double); ((FastBufferReader)(ref reader)).ReadValueSafe<double>(ref time, default(ForPrimitives)); int next = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref next); int tvOn = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref tvOn); target.__rpc_exec_stage = (__RpcExecStage)2; ((NetworkHandler)(object)target).UpdateInfoClientRpc(current, time, next, tvOn); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "NetworkHandler"; } } } namespace PTV.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }