Decompiled source of OverheadWebcamCCTV v1.0.0

OverheadCameraMod.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[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("OverheadCameraMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Sandbox testing with network sync.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OverheadCameraMod")]
[assembly: AssemblyTitle("OverheadCameraMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 OverheadCameraMod
{
	[BepInPlugin("com.professional.overheadcam", "Overhead WebCam Mod", "1.0.0")]
	public class OverheadCamPlugin : BaseUnityPlugin
	{
		public const string ModGUID = "com.professional.overheadcam";

		public const string ModName = "Overhead WebCam Mod";

		public const string ModVersion = "1.0.0";

		private readonly Harmony _harmony = new Harmony("com.professional.overheadcam");

		public static ConfigEntry<string> ConfigSelectedCamera;

		private void Awake()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			string[] array = WebCamTexture.devices.Select((WebCamDevice d) => ((WebCamDevice)(ref d)).name).ToArray();
			if (array.Length == 0)
			{
				array = new string[1] { "Aucune caméra" };
			}
			ConfigSelectedCamera = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Active Camera", array[0], new ConfigDescription("Sélectionnez la webcam.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>()));
			ConfigSelectedCamera.SettingChanged += delegate
			{
				SandboxPatches.RestartWebcam();
			};
			_harmony.PatchAll(typeof(SandboxPatches));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"=== OverheadCam: CCTV RC (No-DLL Dropdown) Loaded ===");
		}
	}
	public class IndependentDroneFollower : MonoBehaviour
	{
		public PlayerControllerB TargetPlayer;

		private bool _isFixedOnDeath;

		private Vector3 _deathPosition;

		private void LateUpdate()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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)
			if ((Object)(object)TargetPlayer == (Object)null)
			{
				return;
			}
			if (TargetPlayer.isPlayerDead)
			{
				if (!_isFixedOnDeath)
				{
					_deathPosition = ((Component)TargetPlayer).transform.position + Vector3.up * 1f;
					_isFixedOnDeath = true;
				}
				((Component)this).transform.position = _deathPosition;
			}
			else
			{
				_isFixedOnDeath = false;
				float num = (((NetworkBehaviour)TargetPlayer).IsOwner ? 3.5f : 2.8f);
				((Component)this).transform.position = ((Component)TargetPlayer).transform.position + ((Component)TargetPlayer).transform.up * num + ((Component)TargetPlayer).transform.forward * 0.5f;
			}
		}
	}
	public class CCTVEffects : MonoBehaviour
	{
		private GameObject _recLight;

		private Renderer _screenRenderer;

		private float _timer;

		private Color _cctvColor = new Color(0.75f, 0.92f, 0.82f, 1f);

		public void Setup(Renderer r)
		{
			_screenRenderer = r;
		}

		private void Start()
		{
			//IL_004d: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00a5: Expected O, but got Unknown
			_recLight = GameObject.CreatePrimitive((PrimitiveType)0);
			Object.Destroy((Object)(object)_recLight.GetComponent<Collider>());
			_recLight.transform.SetParent(((Component)this).transform, false);
			_recLight.transform.localPosition = new Vector3(-0.45f, 0.35f, -0.02f);
			_recLight.transform.localScale = new Vector3(0.04f, 0.04f, 0.01f);
			_recLight.GetComponent<Renderer>().material = new Material(Shader.Find("Sprites/Default"))
			{
				color = Color.red
			};
		}

		private void Update()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			_timer += Time.deltaTime;
			if ((Object)(object)_recLight != (Object)null)
			{
				_recLight.SetActive(Mathf.Sin(_timer * 5f) > 0f);
			}
			if ((Object)(object)_screenRenderer != (Object)null)
			{
				float num = Random.Range(0.98f, 1.02f);
				_screenRenderer.material.color = _cctvColor * num;
			}
		}
	}
	internal class SandboxPatches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnReceiveFrame;
		}

		public static WebCamTexture HardwareStream;

		private static Texture2D _sendBuffer;

		private static Texture2D _scanlineTex;

		private static Dictionary<ulong, GameObject> _playerDrones = new Dictionary<ulong, GameObject>();

		private static float _nextSendTime;

		private const string MSG_NAME = "OverheadCam_CCTV_Final";

		public static void RestartWebcam()
		{
			if ((Object)(object)HardwareStream != (Object)null)
			{
				HardwareStream.Stop();
				HardwareStream = null;
			}
			InitResources();
			foreach (GameObject value in _playerDrones.Values)
			{
				Transform obj = value.transform.Find("CCTV_Container/Screen");
				Renderer val = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
				if ((Object)(object)val != (Object)null && (Object)(object)HardwareStream != (Object)null)
				{
					val.material.mainTexture = (Texture)(object)HardwareStream;
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void PostfixStart()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			foreach (GameObject value in _playerDrones.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			_playerDrones.Clear();
			NetworkManager singleton = NetworkManager.Singleton;
			if (((singleton != null) ? singleton.CustomMessagingManager : null) != null)
			{
				CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
				object obj = <>O.<0>__OnReceiveFrame;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnReceiveFrame;
					<>O.<0>__OnReceiveFrame = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("OverheadCam_CCTV_Final", (HandleNamedMessageDelegate)obj);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void PostfixUpdate(PlayerControllerB __instance)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.isPlayerControlled && _playerDrones.ContainsKey(__instance.actualClientId))
			{
				Object.Destroy((Object)(object)_playerDrones[__instance.actualClientId]);
				_playerDrones.Remove(__instance.actualClientId);
				return;
			}
			if (!_playerDrones.ContainsKey(__instance.actualClientId) && __instance.isPlayerControlled)
			{
				InitResources();
				GameObject val = new GameObject($"CCTV_{__instance.actualClientId}");
				val.AddComponent<IndependentDroneFollower>().TargetPlayer = __instance;
				Texture tex = (Texture)(((NetworkBehaviour)__instance).IsOwner ? ((object)HardwareStream) : ((object)new Texture2D(512, 512)));
				CreateCCTVScreen(val.transform, tex);
				_playerDrones.Add(__instance.actualClientId, val);
			}
			if (((NetworkBehaviour)__instance).IsOwner && Time.time > _nextSendTime && (Object)(object)HardwareStream != (Object)null && HardwareStream.isPlaying)
			{
				_nextSendTime = Time.time + 0.6f;
				SendFrame();
			}
		}

		private static void SendFrame()
		{
			//IL_0067: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if ((Object)(object)_sendBuffer == (Object)null)
			{
				_sendBuffer = new Texture2D(512, 512, (TextureFormat)3, false);
			}
			_sendBuffer.SetPixels(HardwareStream.GetPixels());
			byte[] array = ImageConversion.EncodeToJPG(_sendBuffer, 45);
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(array.Length + 8, (Allocator)2, 1000000);
			ulong localClientId = NetworkManager.Singleton.LocalClientId;
			((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref localClientId, default(ForPrimitives));
			((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
			NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("OverheadCam_CCTV_Final", val, (NetworkDelivery)4);
			((FastBufferWriter)(ref val)).Dispose();
		}

		private static void OnReceiveFrame(ulong senderId, FastBufferReader reader)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ulong key = default(ulong);
			((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref key, default(ForPrimitives));
			byte[] array = new byte[((FastBufferReader)(ref reader)).Length - 8];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref array, array.Length, 0);
			if (!_playerDrones.TryGetValue(key, out var value))
			{
				return;
			}
			Transform val = value.transform.Find("CCTV_Container/Screen");
			if ((Object)(object)val != (Object)null)
			{
				Texture mainTexture = ((Component)val).GetComponent<Renderer>().material.mainTexture;
				Texture2D val2 = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null);
				if ((Object)(object)val2 != (Object)null)
				{
					ImageConversion.LoadImage(val2, array);
				}
			}
		}

		public static void InitResources()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)HardwareStream == (Object)null && WebCamTexture.devices.Length != 0)
			{
				string value = OverheadCamPlugin.ConfigSelectedCamera.Value;
				HardwareStream = new WebCamTexture(value, 512, 512, 15);
				HardwareStream.Play();
			}
			if ((Object)(object)_scanlineTex == (Object)null)
			{
				_scanlineTex = new Texture2D(1, 128);
				for (int i = 0; i < 128; i++)
				{
					_scanlineTex.SetPixel(0, i, (i % 2 == 0) ? new Color(0f, 0f, 0f, 0.3f) : new Color(0f, 0f, 0f, 0f));
				}
				_scanlineTex.Apply();
			}
		}

		private static void CreateCCTVScreen(Transform parent, Texture tex)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			GameObject val = new GameObject("CCTV_Container");
			val.transform.SetParent(parent, false);
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)5);
			((Object)val2).name = "Screen";
			Object.Destroy((Object)(object)val2.GetComponent<Collider>());
			val2.transform.SetParent(val.transform, false);
			val2.transform.localScale = new Vector3(1.4f, 1f, 1f);
			Renderer component = val2.GetComponent<Renderer>();
			component.material = new Material(Shader.Find("Sprites/Default"))
			{
				mainTexture = tex
			};
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)5);
			Object.Destroy((Object)(object)val3.GetComponent<Collider>());
			val3.transform.SetParent(val2.transform, false);
			val3.transform.localPosition = new Vector3(0f, 0f, -0.01f);
			val3.GetComponent<Renderer>().material = new Material(Shader.Find("Sprites/Default"))
			{
				mainTexture = (Texture)(object)_scanlineTex
			};
			val2.AddComponent<BillboardDisplay>();
			val2.AddComponent<CCTVEffects>().Setup(component);
		}
	}
	public class BillboardDisplay : MonoBehaviour
	{
		private Camera _cam;

		private void LateUpdate()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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)
			if ((Object)(object)_cam == (Object)null)
			{
				_cam = GameNetworkManager.Instance?.localPlayerController?.gameplayCamera;
			}
			if ((Object)(object)_cam != (Object)null)
			{
				((Component)this).transform.forward = ((Component)this).transform.position - ((Component)_cam).transform.position;
			}
		}
	}
}