Decompiled source of SyncVideo Theater v1.0.0

plugins/SyncVideoTheater/SyncVideoTheater.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace OsakaTheater
{
	public enum LowerTheLightsMode
	{
		Enabled,
		Disabled,
		Automatic
	}
	public sealed class SyncVideoTheaterConfig
	{
		public ConfigEntry<LowerTheLightsMode> LowerTheLights { get; }

		public SyncVideoTheaterConfig(ConfigFile config)
		{
			LowerTheLights = config.Bind<LowerTheLightsMode>("Theater", "Lower the Lights!", LowerTheLightsMode.Automatic, "Adjust the ambient lighting inside the theater. Enabled darkens the theater, Disabled never darkens the theater, and Automatic only darkens the theater when you're in a SyncVideo lobby.");
		}
	}
	[BepInPlugin("OsakaTheater.SyncVideoTheater", "Sync Video Theater", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <LoadBundleAsync>d__8 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private string <pluginFolder>5__1;

			private string <bundlePath>5__2;

			private AssetBundleCreateRequest <bundleRequest>5__3;

			private AssetBundle <bundle>5__4;

			private AssetBundleRequest <assetRequest>5__5;

			private Object[] <>s__6;

			private int <>s__7;

			private Object <asset>5__8;

			private string <lower>5__9;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadBundleAsync>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<pluginFolder>5__1 = null;
				<bundlePath>5__2 = null;
				<bundleRequest>5__3 = null;
				<bundle>5__4 = null;
				<assetRequest>5__5 = null;
				<>s__6 = null;
				<asset>5__8 = null;
				<lower>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0259: Unknown result type (might be due to invalid IL or missing references)
				//IL_0263: Expected O, but got Unknown
				//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ef: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<pluginFolder>5__1 = Path.GetDirectoryName(((BaseUnityPlugin)<>4__this).Info.Location);
					<bundlePath>5__2 = Path.Combine(<pluginFolder>5__1, "theater");
					Log.LogInfo((object)("Looking for AssetBundle at: " + <bundlePath>5__2));
					if (!File.Exists(<bundlePath>5__2))
					{
						Log.LogError((object)("Bundle not found: " + <bundlePath>5__2));
						return false;
					}
					<bundleRequest>5__3 = AssetBundle.LoadFromFileAsync(<bundlePath>5__2);
					<>2__current = <bundleRequest>5__3;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<bundle>5__4 = <bundleRequest>5__3.assetBundle;
					if ((Object)(object)<bundle>5__4 == (Object)null)
					{
						Log.LogError((object)"Failed to load AssetBundle.");
						return false;
					}
					<assetRequest>5__5 = <bundle>5__4.LoadAllAssetsAsync<GameObject>();
					<>2__current = <assetRequest>5__5;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>s__6 = <assetRequest>5__5.allAssets;
					for (<>s__7 = 0; <>s__7 < <>s__6.Length; <>s__7++)
					{
						<asset>5__8 = <>s__6[<>s__7];
						Log.LogInfo((object)("Bundle asset: " + <asset>5__8.name));
						if (!((Object)(object)theaterPrefab != (Object)null))
						{
							<lower>5__9 = <asset>5__8.name.ToLowerInvariant();
							if (<lower>5__9.Contains("theater") || <lower>5__9.Contains("theatre"))
							{
								theaterPrefab = (GameObject)<asset>5__8;
							}
							<lower>5__9 = null;
							<asset>5__8 = null;
						}
					}
					<>s__6 = null;
					if ((Object)(object)theaterPrefab == (Object)null && <assetRequest>5__5.allAssets.Length != 0)
					{
						theaterPrefab = (GameObject)<assetRequest>5__5.allAssets[0];
						Log.LogInfo((object)("Loaded first GameObject as fallback: " + ((Object)theaterPrefab).name));
					}
					if ((Object)(object)theaterPrefab == (Object)null)
					{
						Log.LogError((object)"Failed to load theater prefab.");
					}
					else
					{
						Log.LogInfo((object)("Theater prefab loaded: " + ((Object)theaterPrefab).name));
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LogPlayerPositionLoop>d__7 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private Player <p>5__1;

			private Vector3 <pos>5__2;

			private Vector3 <rot>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LogPlayerPositionLoop>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<p>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					if (!((Object)(object)WorldHandler.instance == (Object)null))
					{
						<p>5__1 = WorldHandler.instance.GetCurrentPlayer();
						if (!((Object)(object)<p>5__1 == (Object)null))
						{
							<pos>5__2 = ((Component)<p>5__1).transform.position;
							<rot>5__3 = ((Component)<p>5__1).transform.eulerAngles;
							Log.LogWarning((object)$"[PlayerPos] Position: {<pos>5__2} | Rotation: {<rot>5__3}");
							<p>5__1 = null;
						}
					}
					break;
				}
				<>2__current = (object)new WaitForSeconds(0.5f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static GameObject theaterPrefab;

		public static ManualLogSource Log;

		public static Plugin Instance;

		public static bool debug;

		public static SyncVideoTheaterConfig ConfigSettings;

		public static ConfigFile TheaterConfigFile;

		private void Awake()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			string text = Path.Combine(Paths.ConfigPath, "transrights.SyncVideoTheater.cfg");
			TheaterConfigFile = new ConfigFile(text, true);
			ConfigSettings = new SyncVideoTheaterConfig(TheaterConfigFile);
			Harmony val = new Harmony("OsakaTheater.SyncVideoTheater");
			val.PatchAll();
			((MonoBehaviour)this).StartCoroutine(LoadBundleAsync());
			ScenePatch.TrySubscribeToSyncVideoLobbyEvent();
			if (debug)
			{
				((MonoBehaviour)this).StartCoroutine(LogPlayerPositionLoop());
			}
		}

		[IteratorStateMachine(typeof(<LogPlayerPositionLoop>d__7))]
		private IEnumerator LogPlayerPositionLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LogPlayerPositionLoop>d__7(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<LoadBundleAsync>d__8))]
		private IEnumerator LoadBundleAsync()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadBundleAsync>d__8(0)
			{
				<>4__this = this
			};
		}
	}
	[HarmonyPatch(typeof(ASceneSetupInstruction), "SetSceneActive")]
	public class ScenePatch
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass23_0
		{
			public int maxFrames;

			public Transform tvRoot;

			internal bool <ScaleSyncVideoScreenAfterSpawn>b__0()
			{
				maxFrames--;
				return (Object)(object)tvRoot == (Object)null || tvRoot.childCount > 0 || maxFrames <= 0;
			}
		}

		[CompilerGenerated]
		private sealed class <ScaleSyncVideoScreenAfterSpawn>d__23 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Transform tvRoot;

			private <>c__DisplayClass23_0 <>8__1;

			private int <c>5__2;

			private Transform <child>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ScaleSyncVideoScreenAfterSpawn>d__23(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<child>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Expected O, but got Unknown
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass23_0();
					<>8__1.tvRoot = tvRoot;
					<>8__1.maxFrames = 60;
					<>2__current = (object)new WaitUntil((Func<bool>)delegate
					{
						<>8__1.maxFrames--;
						return (Object)(object)<>8__1.tvRoot == (Object)null || <>8__1.tvRoot.childCount > 0 || <>8__1.maxFrames <= 0;
					});
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)<>8__1.tvRoot == (Object)null)
					{
						return false;
					}
					if (<>8__1.tvRoot.childCount == 0)
					{
						Plugin.Log.LogWarning((object)"No SyncVideo child appeared under TV.");
						return false;
					}
					<c>5__2 = 0;
					while (<c>5__2 < <>8__1.tvRoot.childCount)
					{
						<child>5__3 = <>8__1.tvRoot.GetChild(<c>5__2);
						<child>5__3.localScale = new Vector3(2f, 2f, 2f);
						Plugin.Log.LogInfo((object)$"Scaled SyncVideo child: {((Object)<child>5__3).name} to {<child>5__3.localScale}");
						<child>5__3 = null;
						<c>5__2++;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const string TargetSceneName = "osaka";

		private const string TargetObjectName = "StageChunks/OsakaStart/NotVisibleFromBridge/CombinedMeshes_osaka_OsakaFronts01_-1429972";

		private const string SpawnedName = "Theater_Instance";

		private const string AmbientTriggerName = "SyncVideoTheater_AmbientTrigger";

		private static GameObject spawnedTheater;

		private static GameObject ambientTriggerObject;

		private static bool lastAutomaticLobbyState;

		private static LowerTheLightsMode lastLowerLightsMode = (LowerTheLightsMode)(-1);

		private static bool syncVideoLookupAttempted;

		private static PropertyInfo syncVideoLobbyManagerProperty;

		private static PropertyInfo syncVideoInLobbyProperty;

		private static object cachedSyncVideoLobbyManager;

		private static void Postfix(string sceneToSetActive)
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			if (sceneToSetActive != "osaka")
			{
				return;
			}
			if ((Object)(object)Plugin.theaterPrefab == (Object)null)
			{
				Plugin.Log.LogError((object)"Theater prefab is null.");
				return;
			}
			if ((Object)(object)GameObject.Find("Theater_Instance") != (Object)null)
			{
				Plugin.Log.LogInfo((object)"Theater already spawned. Skipping.");
				return;
			}
			GameObject val = GameObject.Find("StageChunks/OsakaStart/NotVisibleFromBridge/CombinedMeshes_osaka_OsakaFronts01_-1429972");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Could not find target object: StageChunks/OsakaStart/NotVisibleFromBridge/CombinedMeshes_osaka_OsakaFronts01_-1429972");
				return;
			}
			Plugin.Log.LogInfo((object)("Found target object: " + GetHierarchyPath(val.transform)));
			GameObject val2 = GameObject.Find("OS_CinemaFront");
			if ((Object)(object)val2 != (Object)null)
			{
				Plugin.Log.LogInfo((object)"Disabling OS_CinemaFront...");
				val2.SetActive(false);
			}
			else
			{
				Plugin.Log.LogWarning((object)"OS_CinemaFront not found.");
			}
			Bounds combinedBounds = GetCombinedBounds(val);
			Quaternion rotation = val.transform.rotation;
			Plugin.Log.LogInfo((object)$"Target bounds center {((Bounds)(ref combinedBounds)).center}, size {((Bounds)(ref combinedBounds)).size}, minY {((Bounds)(ref combinedBounds)).min.y}");
			ApplyTextureToSceneBillboard();
			RemoveTargetObject(val);
			GameObject val3 = SpawnReplacement(combinedBounds, rotation);
		}

		private static void RemoveTargetObject(GameObject targetObject)
		{
			Plugin.Log.LogInfo((object)("Removing target object: " + GetHierarchyPath(targetObject.transform)));
			targetObject.SetActive(false);
			Object.Destroy((Object)(object)targetObject);
			Plugin.Log.LogInfo((object)"Target object removed.");
		}

		private static GameObject SpawnReplacement(Bounds targetBounds, Quaternion targetRotation)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)"Spawning theater replacement...");
			GameObject val = Object.Instantiate<GameObject>(Plugin.theaterPrefab);
			((Object)val).name = "Theater_Instance";
			val.transform.rotation = targetRotation;
			MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val2 in componentsInChildren)
			{
				((Renderer)val2).enabled = true;
			}
			spawnedTheater = val;
			ApplyLowerTheLightsForCurrentState();
			SpawnSyncVideoTvMarker(val.transform);
			Plugin.Log.LogInfo((object)$"Spawned theater at {val.transform.position}");
			return val;
		}

		public static void TrySubscribeToSyncVideoLobbyEvent()
		{
			try
			{
				Type type = Type.GetType("SyncVideo.SyncVideoPlugin, SyncVideo");
				if (type == null)
				{
					Plugin.Log.LogInfo((object)"[SyncVideoTheater] SyncVideo not present; lobby lighting disabled.");
					return;
				}
				EventInfo @event = type.GetEvent("LobbyStateChanged", BindingFlags.Static | BindingFlags.Public);
				if (@event == null)
				{
					Plugin.Log.LogWarning((object)"[SyncVideoTheater] LobbyStateChanged event not found on SyncVideoPlugin.");
					return;
				}
				Action<bool> handler = OnSyncVideoLobbyStateChanged;
				@event.AddEventHandler(null, handler);
				Plugin.Log.LogInfo((object)"[SyncVideoTheater] Subscribed to SyncVideo.LobbyStateChanged.");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[SyncVideoTheater] Failed to subscribe to SyncVideo lobby event: " + ex.Message));
			}
		}

		public static void OnSyncVideoLobbyStateChanged(bool inLobby)
		{
			if ((Object)(object)spawnedTheater == (Object)null)
			{
				return;
			}
			SyncVideoTheaterConfig configSettings = Plugin.ConfigSettings;
			if (configSettings != null && configSettings.LowerTheLights.Value == LowerTheLightsMode.Automatic && inLobby != lastAutomaticLobbyState)
			{
				lastAutomaticLobbyState = inLobby;
				if (inLobby)
				{
					EnsureAmbientTrigger();
				}
				else
				{
					DestroyAmbientTrigger();
				}
			}
		}

		private static void ApplyLowerTheLightsForCurrentState()
		{
			if (Plugin.ConfigSettings == null)
			{
				return;
			}
			switch (lastLowerLightsMode = Plugin.ConfigSettings.LowerTheLights.Value)
			{
			case LowerTheLightsMode.Enabled:
				EnsureAmbientTrigger();
				return;
			case LowerTheLightsMode.Disabled:
				DestroyAmbientTrigger();
				return;
			}
			lastAutomaticLobbyState = IsInSyncVideoLobby();
			if (lastAutomaticLobbyState)
			{
				EnsureAmbientTrigger();
			}
			else
			{
				DestroyAmbientTrigger();
			}
		}

		private static void EnsureAmbientTrigger()
		{
			if (!((Object)(object)ambientTriggerObject != (Object)null))
			{
				SpawnAmbientTrigger(spawnedTheater);
			}
		}

		private static void DestroyAmbientTrigger()
		{
			if ((Object)(object)ambientTriggerObject == (Object)null)
			{
				GameObject val = GameObject.Find("SyncVideoTheater_AmbientTrigger");
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
			else
			{
				Object.Destroy((Object)(object)ambientTriggerObject);
				ambientTriggerObject = null;
				Plugin.Log.LogInfo((object)"Destroyed SyncVideo Theater ambient trigger.");
			}
		}

		private static bool IsInSyncVideoLobby()
		{
			try
			{
				if (!TryGetSyncVideoLobbyManager(out var lobbyManager))
				{
					return false;
				}
				if (syncVideoInLobbyProperty == null || cachedSyncVideoLobbyManager != lobbyManager)
				{
					cachedSyncVideoLobbyManager = lobbyManager;
					syncVideoInLobbyProperty = lobbyManager.GetType().GetProperty("InLobby", BindingFlags.Instance | BindingFlags.Public);
				}
				if (syncVideoInLobbyProperty == null)
				{
					return false;
				}
				object value = syncVideoInLobbyProperty.GetValue(lobbyManager, null);
				bool flag = default(bool);
				int num;
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			}
			catch (Exception ex)
			{
				if (Plugin.debug)
				{
					Plugin.Log.LogWarning((object)("Failed to read SyncVideo lobby state: " + ex.Message));
				}
				return false;
			}
		}

		private static bool TryGetSyncVideoLobbyManager(out object lobbyManager)
		{
			lobbyManager = null;
			if (!syncVideoLookupAttempted)
			{
				syncVideoLookupAttempted = true;
				Type type = Type.GetType("SyncVideo.SyncVideoPlugin, SyncVideo");
				if (type != null)
				{
					syncVideoLobbyManagerProperty = type.GetProperty("LobbyManager", BindingFlags.Static | BindingFlags.Public);
				}
			}
			if (syncVideoLobbyManagerProperty == null)
			{
				return false;
			}
			lobbyManager = syncVideoLobbyManagerProperty.GetValue(null, null);
			return lobbyManager != null;
		}

		private static void SpawnSyncVideoTvMarker(Transform theaterRoot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TV");
			val.transform.SetParent(theaterRoot, false);
			val.transform.localPosition = new Vector3(115.0057f, -5.59f, -82.3467f);
			val.transform.localRotation = Quaternion.Euler(0f, 306.1724f, 0f);
			val.transform.localScale = new Vector3(20f, 20f, 1f);
			if ((Object)(object)val.GetComponent<Junk>() == (Object)null)
			{
				val.AddComponent<Junk>();
			}
			Plugin.Log.LogInfo((object)$"Spawned SyncVideo TV marker at {val.transform.position}");
			((MonoBehaviour)Plugin.Instance).StartCoroutine(ScaleSyncVideoScreenAfterSpawn(val.transform));
		}

		[IteratorStateMachine(typeof(<ScaleSyncVideoScreenAfterSpawn>d__23))]
		private static IEnumerator ScaleSyncVideoScreenAfterSpawn(Transform tvRoot)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScaleSyncVideoScreenAfterSpawn>d__23(0)
			{
				tvRoot = tvRoot
			};
		}

		private static Bounds GetCombinedBounds(GameObject root)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren.Length == 0)
			{
				return new Bounds(root.transform.position, Vector3.zero);
			}
			Bounds bounds = componentsInChildren[0].bounds;
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
			}
			return bounds;
		}

		private static string GetHierarchyPath(Transform current)
		{
			StringBuilder stringBuilder = new StringBuilder(((Object)current).name);
			while ((Object)(object)current.parent != (Object)null)
			{
				current = current.parent;
				stringBuilder.Insert(0, '/');
				stringBuilder.Insert(0, ((Object)current).name);
			}
			return stringBuilder.ToString();
		}

		private static void ApplyTextureToSceneBillboard()
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			string text = "StageChunks/OsakaStart/NotVisibleFromBridge/Buildings_OsakaStart/North/Buildings/BillboardSquare03";
			GameObject val = GameObject.Find(text);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)("Scene billboard not found: " + text));
				return;
			}
			Renderer val2 = val.GetComponent<Renderer>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.GetComponentInChildren<Renderer>(true);
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogError((object)"Renderer not found on scene billboard.");
				return;
			}
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
			string text2 = Path.Combine(directoryName, "NewBillboardAtlas.png");
			if (!File.Exists(text2))
			{
				Plugin.Log.LogError((object)("Texture not found: " + text2));
				return;
			}
			byte[] array = File.ReadAllBytes(text2);
			Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val3, array))
			{
				Plugin.Log.LogError((object)"Failed to load NewBillboardAtlas.png.");
				return;
			}
			((Object)val3).name = "NewBillboardAtlas";
			((Texture)val3).wrapMode = (TextureWrapMode)0;
			((Texture)val3).filterMode = (FilterMode)1;
			val3.Apply(false, false);
			Shader val4 = Shader.Find("Unlit/Texture");
			if ((Object)(object)val4 == (Object)null)
			{
				Plugin.Log.LogError((object)"Could not find Unlit/Texture shader.");
				return;
			}
			Material val5 = new Material(val4);
			((Object)val5).name = "NewBillboardAtlas_Opaque_Unlit";
			val5.mainTexture = (Texture)(object)val3;
			if (val5.HasProperty("_MainTex"))
			{
				val5.SetTexture("_MainTex", (Texture)(object)val3);
				val5.SetTextureScale("_MainTex", Vector2.one);
				val5.SetTextureOffset("_MainTex", Vector2.zero);
			}
			if (val5.HasProperty("_Color"))
			{
				val5.SetColor("_Color", Color.white);
			}
			if (val5.HasProperty("_SrcBlend"))
			{
				val5.SetFloat("_SrcBlend", 1f);
			}
			if (val5.HasProperty("_DstBlend"))
			{
				val5.SetFloat("_DstBlend", 0f);
			}
			if (val5.HasProperty("_ZWrite"))
			{
				val5.SetFloat("_ZWrite", 1f);
			}
			val5.renderQueue = 2000;
			val5.DisableKeyword("_ALPHABLEND_ON");
			val5.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			val5.DisableKeyword("_ALPHATEST_ON");
			val5.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
			val5.DisableKeyword("_EMISSION");
			val5.DisableKeyword("_DETAIL_MULX2");
			val5.DisableKeyword("_DETAIL_SCALED");
			val2.SetPropertyBlock((MaterialPropertyBlock)null);
			Material[] array2 = (Material[])(object)new Material[val2.sharedMaterials.Length];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = val5;
			}
			val2.sharedMaterials = array2;
			val2.materials = array2;
			val2.SetPropertyBlock((MaterialPropertyBlock)null);
			Plugin.Log.LogInfo((object)("Forced opaque unlit New Billboard Atlas material on: " + GetHierarchyPath(((Component)val2).transform)));
		}

		private static void SpawnAmbientTrigger(GameObject theater)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(0.02f, 0.02f, 0.02f, 0.75f);
			Vector3[] array = (Vector3[])(object)new Vector3[8]
			{
				new Vector3(125.62f, 8.27f, -73.94f),
				new Vector3(109.94f, 7.58f, -95.58f),
				new Vector3(125.62f, -8.77f, -73.94f),
				new Vector3(109.65f, -8.86f, -95.17f),
				new Vector3(96.32f, 8.53f, -51.23f),
				new Vector3(79.63f, 8.53f, -73.32f),
				new Vector3(94.86f, -7.73f, -51.64f),
				new Vector3(78.16f, -8.85f, -72.33f)
			};
			Bounds val2 = default(Bounds);
			((Bounds)(ref val2))..ctor(array[0], Vector3.zero);
			for (int i = 1; i < array.Length; i++)
			{
				((Bounds)(ref val2)).Encapsulate(array[i]);
			}
			if ((Object)(object)ambientTriggerObject != (Object)null)
			{
				return;
			}
			GameObject val3 = (ambientTriggerObject = new GameObject("SyncVideoTheater_AmbientTrigger"));
			val3.transform.position = new Vector3(107.2773f, -0.165f, -74.805f);
			val3.transform.rotation = Quaternion.Euler(0f, 36.5862f, 0f);
			BoxCollider val4 = val3.AddComponent<BoxCollider>();
			((Collider)val4).isTrigger = true;
			val4.center = Vector3.zero;
			val4.size = ((Bounds)(ref val2)).size;
			if (Plugin.debug)
			{
				GameObject val5 = new GameObject("AmbientTrigger_Visual");
				val5.transform.SetParent(val3.transform, false);
				val5.transform.localPosition = val4.center;
				val5.transform.localRotation = Quaternion.identity;
				val5.transform.localScale = val4.size;
				MeshFilter val6 = val5.AddComponent<MeshFilter>();
				MeshRenderer val7 = val5.AddComponent<MeshRenderer>();
				val6.sharedMesh = CreateDebugCubeMesh();
				Shader val8 = Shader.Find("Unlit/Color");
				if ((Object)(object)val8 == (Object)null)
				{
					val8 = Shader.Find("Sprites/Default");
				}
				Material val9 = new Material(val8);
				((Object)val9).name = "AmbientTrigger_Debug_Black_Transparent";
				val9.color = new Color(0f, 0f, 0f, 0.35f);
				if (val9.HasProperty("_Color"))
				{
					val9.SetColor("_Color", new Color(0f, 0f, 0f, 0.35f));
				}
				if (val9.HasProperty("_SrcBlend"))
				{
					val9.SetInt("_SrcBlend", 5);
				}
				if (val9.HasProperty("_DstBlend"))
				{
					val9.SetInt("_DstBlend", 10);
				}
				if (val9.HasProperty("_ZWrite"))
				{
					val9.SetInt("_ZWrite", 0);
				}
				val9.DisableKeyword("_ALPHATEST_ON");
				val9.EnableKeyword("_ALPHABLEND_ON");
				val9.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val9.renderQueue = 3000;
				((Renderer)val7).sharedMaterial = val9;
			}
			AmbientTrigger val10 = val3.AddComponent<AmbientTrigger>();
			val10.AmbientEnvLight = val;
			val10.AmbientEnvShadow = val;
			Plugin.Log.LogInfo((object)"Spawned SyncVideo Theater ambient trigger.");
		}

		private static Bounds ComputeInteriorBounds(GameObject theater)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			Transform[] componentsInChildren = theater.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "OuterAreas")
				{
					Bounds combinedBounds = GetCombinedBounds(((Component)val).gameObject);
					Plugin.Log.LogInfo((object)$"AmbientTrigger bounds from OuterAreas: center {((Bounds)(ref combinedBounds)).center}, size {((Bounds)(ref combinedBounds)).size}");
					return combinedBounds;
				}
			}
			Renderer[] componentsInChildren2 = theater.GetComponentsInChildren<Renderer>(true);
			bool flag = false;
			Bounds result = default(Bounds);
			Renderer[] array = componentsInChildren2;
			foreach (Renderer val2 in array)
			{
				if (!((Object)((Component)val2).gameObject).name.StartsWith("CombinedMeshes_"))
				{
					if (!flag)
					{
						result = val2.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val2.bounds);
					}
				}
			}
			if (!flag)
			{
				result = GetCombinedBounds(theater);
			}
			Plugin.Log.LogWarning((object)$"OuterAreas not found, using fallback bounds: center {((Bounds)(ref result)).center}, size {((Bounds)(ref result)).size}");
			return result;
		}

		private static Mesh CreateDebugCubeMesh()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh();
			((Object)val).name = "AmbientTrigger_DebugCubeMesh";
			Vector3[] vertices = (Vector3[])(object)new Vector3[8]
			{
				new Vector3(-0.5f, -0.5f, -0.5f),
				new Vector3(0.5f, -0.5f, -0.5f),
				new Vector3(0.5f, 0.5f, -0.5f),
				new Vector3(-0.5f, 0.5f, -0.5f),
				new Vector3(-0.5f, -0.5f, 0.5f),
				new Vector3(0.5f, -0.5f, 0.5f),
				new Vector3(0.5f, 0.5f, 0.5f),
				new Vector3(-0.5f, 0.5f, 0.5f)
			};
			int[] triangles = new int[36]
			{
				0, 2, 1, 0, 3, 2, 4, 5, 6, 4,
				6, 7, 0, 1, 5, 0, 5, 4, 2, 3,
				7, 2, 7, 6, 0, 4, 7, 0, 7, 3,
				1, 2, 6, 1, 6, 5
			};
			val.vertices = vertices;
			val.triangles = triangles;
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}
	}
}
namespace SyncVideo
{
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "transrights.SyncVideoTheater";

		public const string PLUGIN_NAME = "Versum Video Venue";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}