Decompiled source of ResoniteSpout v1.0.4

plugins/ResoniteSpout.Engine/ResoniteSpout.Engine.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using BepisResoniteWrapper;
using Elements.Core;
using FrooxEngine;
using HarmonyLib;
using InterprocessLib;
using Renderite.Shared;
using ResoniteSpout.Shared;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")]
[assembly: AssemblyCompany("YourName")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a79062f8b6250f2397ea5adcf5400491f4acfd24")]
[assembly: AssemblyProduct("ResoniteSpout.Engine")]
[assembly: AssemblyTitle("ResoniteSpout.Engine")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Zozokasu/ResoniteSpout")]
[assembly: SecurityPermission(8, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace ResoniteSpout.Shared
{
	public enum SpoutCommandType
	{
		Create,
		Delete,
		Update
	}
	public class SpoutCommand : RendererCommand
	{
		public SpoutCommandType Type;

		public string SpoutName = "";

		public int AssetId;

		public override void Pack(ref MemoryPacker packer)
		{
			((MemoryPacker)(ref packer)).Write<SpoutCommandType>(Type);
			((MemoryPacker)(ref packer)).Write<int>(AssetId);
			((MemoryPacker)(ref packer)).Write(SpoutName);
		}

		public override void Unpack(ref MemoryUnpacker unpacker)
		{
			((MemoryUnpacker)(ref unpacker)).Read<SpoutCommandType>(ref Type);
			((MemoryUnpacker)(ref unpacker)).Read<int>(ref AssetId);
			((MemoryUnpacker)(ref unpacker)).Read(ref SpoutName);
		}
	}
}
namespace ResoniteSpout.Engine
{
	[ResonitePlugin("Zozokasu.ResoniteSpout.Engine", "ResoniteSpout.Engine", "1.0.0", "YourName", "https://github.com/Zozokasu/ResoniteSpout")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ResoniteSpout : BasePlugin
	{
		[HarmonyPatch]
		public static class DynamicVariableSpacePatch
		{
			private class SpoutCameraInfo
			{
				public string SpoutName;

				public int AssetId;

				public string Suffix;

				public string CameraName;

				public DynamicVariableSpace Space;
			}

			public class SpaceMonitor
			{
				public DynamicVariableSpace Space;

				public string SpaceName;

				public Dictionary<string, object> LastValues = new Dictionary<string, object>();

				private bool _isMonitoring = false;

				private string _cachedCameraName = null;

				private HashSet<string> _ownedSpoutNames = new HashSet<string>();

				private string _monitorId;

				public SpaceMonitor(DynamicVariableSpace space, string spaceName)
				{
					//IL_005d: Unknown result type (might be due to invalid IL or missing references)
					Space = space;
					SpaceName = spaceName;
					_monitorId = $"{spaceName}@{((Worker)space).ReferenceID}";
				}

				public void StartMonitoring()
				{
					//IL_0031: Unknown result type (might be due to invalid IL or missing references)
					//IL_0038: Expected O, but got Unknown
					//IL_009f: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a6: Expected O, but got Unknown
					//IL_010c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0113: Expected O, but got Unknown
					//IL_0163: Unknown result type (might be due to invalid IL or missing references)
					//IL_0168: Unknown result type (might be due to invalid IL or missing references)
					//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
					//IL_01d9: Expected O, but got Unknown
					//IL_0280: Unknown result type (might be due to invalid IL or missing references)
					//IL_0287: Expected O, but got Unknown
					if (_isMonitoring || Space == null)
					{
						return;
					}
					_isMonitoring = true;
					ManualLogSource log = Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_monitorId);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Starting monitoring...");
					}
					log.LogInfo(val);
					FieldInfo field = typeof(DynamicVariableSpace).GetField("_dynamicValues", (BindingFlags)36);
					if (field == (FieldInfo)null)
					{
						ManualLogSource log2 = Log;
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_monitorId);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Could not find _dynamicValues field!");
						}
						log2.LogError(val2);
						return;
					}
					object value = field.GetValue((object)Space);
					IDictionary val3 = (IDictionary)((value is IDictionary) ? value : null);
					if (val3 == null)
					{
						ManualLogSource log3 = Log;
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(38, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_monitorId);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] _dynamicValues is not a dictionary!");
						}
						log3.LogError(val2);
						return;
					}
					IDictionaryEnumerator enumerator = val3.GetEnumerator();
					try
					{
						while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
						{
							DictionaryEntry val4 = (DictionaryEntry)((global::System.Collections.IEnumerator)enumerator).Current;
							object key = ((DictionaryEntry)(ref val4)).Key;
							object value2 = ((DictionaryEntry)(ref val4)).Value;
							global::System.Type type = key.GetType();
							FieldInfo field2 = type.GetField("name", (BindingFlags)20);
							string text = (string)field2.GetValue(key);
							FieldInfo field3 = type.GetField("type", (BindingFlags)20);
							global::System.Type type2 = (global::System.Type)field3.GetValue(key);
							ManualLogSource log4 = Log;
							val = new BepInExInfoLogInterpolatedStringHandler(30, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_monitorId);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Found variable: '");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (Type: ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((MemberInfo)type2).Name);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
							}
							log4.LogInfo(val);
							SetupMonitoringForManager(text, type2, value2);
						}
					}
					finally
					{
						if (enumerator is global::System.IDisposable disposable)
						{
							disposable.Dispose();
						}
					}
					ManualLogSource log5 = Log;
					val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_monitorId);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Monitoring started");
					}
					log5.LogInfo(val);
				}

				private void SetupMonitoringForManager(string varName, global::System.Type varType, object valueManager)
				{
					//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ab: Expected O, but got Unknown
					//IL_002a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0031: Expected O, but got Unknown
					//IL_014e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0155: Expected O, but got Unknown
					PropertyInfo property = valueManager.GetType().GetProperty("Value");
					bool flag = default(bool);
					if (property == (PropertyInfo)null)
					{
						ManualLogSource log = Log;
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_monitorId);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Could not find Value property for '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(varName);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
						}
						log.LogWarning(val);
						return;
					}
					object value = property.GetValue(valueManager);
					LastValues[varName] = value;
					ManualLogSource log2 = Log;
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(23, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_monitorId);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Initial value: '");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(varName);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' = ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<object>(value);
					}
					log2.LogInfo(val2);
					if (varName == "CameraName" && value is string cachedCameraName)
					{
						_cachedCameraName = cachedCameraName;
					}
					if (value != null && !IsDefaultValue(value, varType))
					{
						ManualLogSource log3 = Log;
						val2 = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_monitorId);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Processing initial value for '");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(varName);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
						}
						log3.LogInfo(val2);
						OnVariableChanged(Space, SpaceName, varName, value, _cachedCameraName, this);
					}
					StartPolling(varName, property, valueManager);
				}

				private void StartPolling(string varName, PropertyInfo valueProperty, object valueManager)
				{
					//IL_0036: Unknown result type (might be due to invalid IL or missing references)
					//IL_0040: Expected O, but got Unknown
					//IL_003b: Unknown result type (might be due to invalid IL or missing references)
					PropertyInfo valueProperty2 = valueProperty;
					object valueManager2 = valueManager;
					string varName2 = varName;
					((ComponentBase<Component>)(object)Space).RunInSeconds(0.1f, new Action(Poll));
					void Poll()
					{
						//IL_0354: Unknown result type (might be due to invalid IL or missing references)
						//IL_035b: Expected O, but got Unknown
						//IL_03da: Unknown result type (might be due to invalid IL or missing references)
						//IL_03e4: Expected O, but got Unknown
						//IL_03df: Unknown result type (might be due to invalid IL or missing references)
						//IL_01db: Unknown result type (might be due to invalid IL or missing references)
						//IL_01e2: Expected O, but got Unknown
						//IL_0298: Unknown result type (might be due to invalid IL or missing references)
						//IL_029f: Expected O, but got Unknown
						//IL_010b: Unknown result type (might be due to invalid IL or missing references)
						//IL_0112: Expected O, but got Unknown
						if (Space != null && !((Worker)Space).IsRemoved && _isMonitoring)
						{
							bool flag2 = default(bool);
							try
							{
								object value = valueProperty2.GetValue(valueManager2);
								object obj = (LastValues.ContainsKey(varName2) ? LastValues[varName2] : null);
								bool flag = false;
								if (varName2 == "TargetRTP")
								{
									RenderTextureProvider val = (RenderTextureProvider)((value is RenderTextureProvider) ? value : null);
									if (val != null)
									{
										RenderTextureProvider val2 = (RenderTextureProvider)((obj is RenderTextureProvider) ? obj : null);
										if (val2 != null)
										{
											int num = ((DynamicRendererAsset<RenderTexture>)(object)((AssetProvider<RenderTexture>)(object)val).Asset)?.AssetId ?? (-1);
											int num2 = ((DynamicRendererAsset<RenderTexture>)(object)((AssetProvider<RenderTexture>)(object)val2).Asset)?.AssetId ?? (-1);
											if (num != num2)
											{
												ManualLogSource log = Log;
												BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(27, 3, ref flag2);
												if (flag2)
												{
													((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[");
													((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(_monitorId);
													((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] RTP AssetId changed: ");
													((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num2);
													((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" → ");
													((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
												}
												log.LogInfo(val3);
												flag = true;
											}
										}
										else
										{
											flag = true;
										}
										goto IL_0281;
									}
								}
								if (varName2 == "CameraName" && value is string)
								{
									if (value as string != obj as string)
									{
										_cachedCameraName = value as string;
										ManualLogSource log2 = Log;
										BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(26, 2, ref flag2);
										if (flag2)
										{
											((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[");
											((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(_monitorId);
											((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] CameraName changed to: ");
											((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(_cachedCameraName);
										}
										log2.LogInfo(val3);
										flag = true;
									}
								}
								else if (value == null && obj != null)
								{
									flag = true;
								}
								else if (value != null && obj == null)
								{
									flag = true;
								}
								else if (value != null && obj != null && !value.Equals(obj))
								{
									flag = true;
								}
								goto IL_0281;
								IL_0281:
								if (flag)
								{
									ManualLogSource log3 = Log;
									BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag2);
									if (flag2)
									{
										((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[");
										((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(_monitorId);
										((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] Variable '");
										((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(varName2);
										((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' changed");
									}
									log3.LogInfo(val3);
									LastValues[varName2] = value;
									OnVariableChanged(Space, SpaceName, varName2, value, _cachedCameraName, this);
								}
							}
							catch (global::System.Exception ex)
							{
								ManualLogSource log4 = Log;
								BepInExErrorLogInterpolatedStringHandler val4 = new BepInExErrorLogInterpolatedStringHandler(33, 3, ref flag2);
								if (flag2)
								{
									((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Error polling variable '");
									((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(varName2);
									((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("' in [");
									((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(_monitorId);
									((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("]: ");
									((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message);
								}
								log4.LogError(val4);
							}
							((ComponentBase<Component>)(object)Space).RunInSeconds(0.1f, new Action(Poll));
						}
					}
				}

				private bool IsDefaultValue(object value, global::System.Type type)
				{
					if (value == null)
					{
						return true;
					}
					if (type.IsValueType)
					{
						object obj = Activator.CreateInstance(type);
						return value.Equals(obj);
					}
					if (type == typeof(string))
					{
						return string.IsNullOrEmpty((string)value);
					}
					return false;
				}

				public void RegisterSpoutName(string spoutName)
				{
					_ownedSpoutNames.Add(spoutName);
				}

				public void UnregisterSpoutName(string spoutName)
				{
					_ownedSpoutNames.Remove(spoutName);
				}

				public void Dispose()
				{
					//IL_000c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Expected O, but got Unknown
					//IL_006c: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00db: Expected O, but got Unknown
					ManualLogSource log = Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_monitorId);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Monitor disposed, cleaning up ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_ownedSpoutNames.Count);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Spout cameras");
					}
					log.LogInfo(val);
					Enumerator<string> enumerator = Enumerable.ToList<string>((global::System.Collections.Generic.IEnumerable<string>)_ownedSpoutNames).GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							string current = enumerator.Current;
							if (spoutCameras.ContainsKey(current))
							{
								SpoutCommand spoutCommand = new SpoutCommand
								{
									Type = SpoutCommandType.Delete,
									SpoutName = current
								};
								_messenger.SendObject<SpoutCommand>("SpoutCommand", spoutCommand);
								spoutCameras.Remove(current);
								ManualLogSource log2 = Log;
								val = new BepInExInfoLogInterpolatedStringHandler(24, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Deleted Spout camera: '");
									((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(current);
									((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
								}
								log2.LogInfo(val);
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator).Dispose();
					}
					_ownedSpoutNames.Clear();
					_isMonitoring = false;
					LastValues.Clear();
					Space = null;
				}
			}

			private static Dictionary<DynamicVariableSpace, SpaceMonitor> _monitors = new Dictionary<DynamicVariableSpace, SpaceMonitor>();

			private static Dictionary<string, SpoutCameraInfo> spoutCameras = new Dictionary<string, SpoutCameraInfo>();

			[HarmonyPatch(typeof(DynamicVariableSpace), "UpdateName")]
			[HarmonyPostfix]
			public static void UpdateName(DynamicVariableSpace __instance)
			{
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Expected O, but got Unknown
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Expected O, but got Unknown
				//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: Expected O, but got Unknown
				//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Expected O, but got Unknown
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
				DynamicVariableSpace __instance2 = __instance;
				string spaceName = ((SyncField<string>)(object)__instance2.SpaceName).Value;
				if (!spaceName.StartsWith("ResoniteSpout."))
				{
					return;
				}
				if (!string.IsNullOrEmpty(ConfigSpacePrefix.Value))
				{
					string targetVariableSpaceName = TargetVariableSpaceName;
					if (spaceName != targetVariableSpaceName)
					{
						return;
					}
				}
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val;
				if (_monitors.ContainsKey(__instance2))
				{
					ManualLogSource log = Log;
					val = new BepInExInfoLogInterpolatedStringHandler(83, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Space '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spaceName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (ReferenceID: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<RefID>(((Worker)__instance2).ReferenceID);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") UpdateName called on already monitored instance, ignoring.");
					}
					log.LogInfo(val);
					return;
				}
				ManualLogSource log2 = Log;
				val = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Target space detected: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spaceName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (ReferenceID: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<RefID>(((Worker)__instance2).ReferenceID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
				}
				log2.LogInfo(val);
				SpaceMonitor monitor = new SpaceMonitor(__instance2, spaceName);
				_monitors[__instance2] = monitor;
				((ComponentBase<Component>)(object)__instance2).RunInUpdates(10, (Action)delegate
				{
					//IL_004e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0054: Expected O, but got Unknown
					//IL_0083: Unknown result type (might be due to invalid IL or missing references)
					if (_monitors.ContainsKey(__instance2) && _monitors[__instance2] == monitor)
					{
						monitor.StartMonitoring();
					}
					else
					{
						ManualLogSource log4 = Log;
						bool flag2 = default(bool);
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref flag2);
						if (flag2)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(spaceName);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("@");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<RefID>(((Worker)__instance2).ReferenceID);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] Monitor was replaced before StartMonitoring, skipping.");
						}
						log4.LogInfo(val2);
					}
				});
				ManualLogSource log3 = Log;
				val = new BepInExInfoLogInterpolatedStringHandler(48, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Monitoring scheduled for space: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spaceName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (ReferenceID: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<RefID>(((Worker)__instance2).ReferenceID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
				}
				log3.LogInfo(val);
			}

			[HarmonyPatch(typeof(DynamicVariableSpace), "OnDispose")]
			[HarmonyPostfix]
			public static void OnDispose(DynamicVariableSpace __instance)
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Expected O, but got Unknown
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				if (_monitors.ContainsKey(__instance))
				{
					string value = ((SyncField<string>)(object)__instance.SpaceName).Value;
					_monitors[__instance].Dispose();
					_monitors.Remove(__instance);
					ManualLogSource log = Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Stopped monitoring space: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(value);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (ReferenceID: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<RefID>(((Worker)__instance).ReferenceID);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
					}
					log.LogInfo(val);
				}
			}

			private static void OnVariableChanged(DynamicVariableSpace space, string spaceName, string varName, object value, string cameraName, SpaceMonitor monitor)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Expected O, but got Unknown
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Expected O, but got Unknown
				string text = $"{spaceName}@{((Worker)space).ReferenceID}";
				ManualLogSource log = Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] Processing change for variable '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(varName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
				}
				log.LogInfo(val);
				if (varName == "TargetRTP")
				{
					RenderTextureProvider val2 = (RenderTextureProvider)((value is RenderTextureProvider) ? value : null);
					if (val2 != null)
					{
						if (((AssetProvider<RenderTexture>)(object)val2)?.Asset != null)
						{
							ManualLogSource log2 = Log;
							val = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] TargetRTP AssetId: ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(((DynamicRendererAsset<RenderTexture>)(object)((AssetProvider<RenderTexture>)(object)val2).Asset).AssetId);
							}
							log2.LogInfo(val);
							string[] array = spaceName.Split('.', (StringSplitOptions)0);
							if (array.Length == 2)
							{
								string suffix = array[1];
								CreateOrUpdateSpoutCamera(space, suffix, ((DynamicRendererAsset<RenderTexture>)(object)((AssetProvider<RenderTexture>)(object)val2).Asset).AssetId, cameraName, monitor);
							}
						}
						else
						{
							ManualLogSource log3 = Log;
							BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(25, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[");
								((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
								((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] TargetRTP has no Asset");
							}
							log3.LogWarning(val3);
						}
						return;
					}
				}
				if (!(varName == "CameraName"))
				{
					return;
				}
				string[] array2 = spaceName.Split('.', (StringSplitOptions)0);
				if (array2.Length != 2)
				{
					return;
				}
				string suffix2 = array2[1];
				if (!_monitors.ContainsKey(space))
				{
					return;
				}
				SpaceMonitor spaceMonitor = _monitors[space];
				if (spaceMonitor.LastValues.ContainsKey("TargetRTP"))
				{
					object obj = spaceMonitor.LastValues["TargetRTP"];
					RenderTextureProvider val4 = (RenderTextureProvider)((obj is RenderTextureProvider) ? obj : null);
					if (val4 != null && ((AssetProvider<RenderTexture>)(object)val4)?.Asset != null)
					{
						CreateOrUpdateSpoutCamera(space, suffix2, ((DynamicRendererAsset<RenderTexture>)(object)((AssetProvider<RenderTexture>)(object)val4).Asset).AssetId, cameraName, spaceMonitor);
					}
				}
			}

			public static void CreateOrUpdateSpoutCamera(DynamicVariableSpace space, string suffix, int assetId, string cameraName, SpaceMonitor monitor)
			{
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_033a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0341: Expected O, but got Unknown
				//IL_024f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0256: Expected O, but got Unknown
				//IL_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Expected O, but got Unknown
				//IL_0199: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Expected O, but got Unknown
				DynamicVariableSpace space2 = space;
				string suffix2 = suffix;
				string spoutName;
				if (!string.IsNullOrEmpty(cameraName))
				{
					spoutName = "[ResoSpout] " + suffix2 + " - " + cameraName;
				}
				else
				{
					spoutName = "[ResoSpout] " + suffix2;
				}
				string text = $"{spoutName}@{((Worker)space2).ReferenceID}";
				SpoutCommand spoutCommand = new SpoutCommand();
				SpoutCameraInfo spoutCameraInfo = Enumerable.FirstOrDefault<SpoutCameraInfo>((global::System.Collections.Generic.IEnumerable<SpoutCameraInfo>)spoutCameras.Values, (Func<SpoutCameraInfo, bool>)((SpoutCameraInfo info) => info.Space == space2 && (info.SpoutName == spoutName || info.Suffix == suffix2)));
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val;
				if (spoutCameraInfo != null)
				{
					if (spoutCameraInfo.SpoutName != spoutName)
					{
						SpoutCommand spoutCommand2 = new SpoutCommand
						{
							Type = SpoutCommandType.Delete,
							SpoutName = spoutCameraInfo.SpoutName
						};
						_messenger.SendObject<SpoutCommand>("SpoutCommand", spoutCommand2);
						spoutCameras.Remove(spoutCameraInfo.SpoutName);
						monitor.UnregisterSpoutName(spoutCameraInfo.SpoutName);
						ManualLogSource log = Log;
						val = new BepInExInfoLogInterpolatedStringHandler(28, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Deleted old Spout camera: '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spoutCameraInfo.SpoutName);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'");
						}
						log.LogInfo(val);
					}
					else if (spoutCameraInfo.AssetId == assetId)
					{
						ManualLogSource log2 = Log;
						val = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Spout camera '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spoutName);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' unchanged, skipping.");
						}
						log2.LogInfo(val);
						return;
					}
				}
				if (spoutCameras.ContainsKey(spoutName))
				{
					SpoutCameraInfo spoutCameraInfo2 = spoutCameras[spoutName];
					spoutCameraInfo2.AssetId = assetId;
					spoutCameraInfo2.CameraName = cameraName;
					spoutCommand.Type = SpoutCommandType.Update;
					spoutCommand.SpoutName = spoutName;
					spoutCommand.AssetId = assetId;
					_messenger.SendObject<SpoutCommand>("SpoutCommand", spoutCommand);
					ManualLogSource log3 = Log;
					val = new BepInExInfoLogInterpolatedStringHandler(38, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Updated Spout camera: '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spoutName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (AssetId: → ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(assetId);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
					}
					log3.LogInfo(val);
					return;
				}
				SpoutCameraInfo spoutCameraInfo3 = new SpoutCameraInfo
				{
					SpoutName = spoutName,
					AssetId = assetId,
					Suffix = suffix2,
					CameraName = cameraName,
					Space = space2
				};
				spoutCameras.Add(spoutName, spoutCameraInfo3);
				monitor.RegisterSpoutName(spoutName);
				spoutCommand.Type = SpoutCommandType.Create;
				spoutCommand.SpoutName = spoutName;
				spoutCommand.AssetId = assetId;
				_messenger.SendObject<SpoutCommand>("SpoutCommand", spoutCommand);
				ManualLogSource log4 = Log;
				val = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Created Spout camera: '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(spoutName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (AssetId: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(assetId);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
				}
				log4.LogInfo(val);
			}
		}

		internal static ManualLogSource Log = null;

		private static ConfigFile config;

		public static Dictionary<string, int> spoutCameras = new Dictionary<string, int>();

		public static Messenger? _messenger;

		public static ConfigEntry<string> ConfigSpacePrefix;

		private static string TargetVariableSpaceName => ConfigSpacePrefix.Value;

		public override void Load()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			config = ((BasePlugin)this).Config;
			ConfigSpacePrefix = config.Bind<string>("General", "SpacePrefixes", "", "Comma-separated list of suffixes to monitor.\nEmpty: Monitor all 'ResoniteSpout.*'\nExample: 'Zozokasu, kokoa, aetoriz' → Monitor 'ResoniteSpout.Zozokasu', 'ResoniteSpout.kokoa', and 'ResoniteSpout.aetoriz'");
			ResoniteHooks.OnEngineReady += new Action(OnEngineReady);
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Zozokasu.ResoniteSpout.Engine");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			log.LogInfo(val);
			int num = 1;
			List<global::System.Type> val2 = new List<global::System.Type>(num);
			CollectionsMarshal.SetCount<global::System.Type>(val2, num);
			global::System.Span<global::System.Type> span = CollectionsMarshal.AsSpan<global::System.Type>(val2);
			int num2 = 0;
			span[num2] = typeof(SpoutCommand);
			_messenger = new Messenger("Zozokasu.ResoniteSpout", val2, (List<global::System.Type>)null);
		}

		private void OnEngineReady()
		{
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				Harmony val = new Harmony("Zozokasu.ResoniteSpout.Engine");
				val.PatchAll();
				Log.LogInfo((object)"Harmony patches installed.");
				global::System.Collections.Generic.IEnumerable<MethodBase> allPatchedMethods = Harmony.GetAllPatchedMethods();
				Log.LogInfo((object)"=== Patched Methods ===");
				global::System.Collections.Generic.IEnumerator<MethodBase> enumerator = allPatchedMethods.GetEnumerator();
				try
				{
					while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
					{
						MethodBase current = enumerator.Current;
						ManualLogSource log = Log;
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Patched: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((MemberInfo)current).DeclaringType?.FullName);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((MemberInfo)current).Name);
						}
						log.LogInfo(val2);
						Patches patchInfo = Harmony.GetPatchInfo(current);
						if (patchInfo != null)
						{
							ManualLogSource log2 = Log;
							val2 = new BepInExInfoLogInterpolatedStringHandler(12, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  Prefixes: ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(patchInfo.Prefixes.Count);
							}
							log2.LogInfo(val2);
							ManualLogSource log3 = Log;
							val2 = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("  Postfixes: ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(patchInfo.Postfixes.Count);
							}
							log3.LogInfo(val2);
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator)?.Dispose();
				}
				Log.LogInfo((object)"=== End of Patched Methods ===");
				Log.LogInfo((object)"Harmony patches installed.");
			}
			catch (global::System.Exception ex)
			{
				ManualLogSource log4 = Log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(27, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to install patches: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<global::System.Exception>(ex);
				}
				log4.LogError(val3);
			}
		}
	}
	public static class PluginMetadata
	{
		public const string GUID = "Zozokasu.ResoniteSpout.Engine";

		public const string NAME = "ResoniteSpout.Engine";

		public const string VERSION = "1.0.0";

		public const string AUTHORS = "YourName";

		public const string REPOSITORY_URL = "https://github.com/Zozokasu/ResoniteSpout";
	}
}

Renderer/BepInEx/Plugins/ResoniteSpout.Renderer/ResoniteSpout.Renderer.dll

Decompiled 5 days ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using InterprocessLib;
using Microsoft.CodeAnalysis;
using Renderite.Shared;
using Renderite.Unity;
using ResoniteSpout.Shared;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ResoniteSpout.Renderer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a79062f8b6250f2397ea5adcf5400491f4acfd24")]
[assembly: AssemblyProduct("ResoniteSpout.Renderer")]
[assembly: AssemblyTitle("ResoniteSpout.Renderer")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ResoniteSpout.Shared
{
	public enum SpoutCommandType
	{
		Create,
		Delete,
		Update
	}
	public class SpoutCommand : RendererCommand
	{
		public SpoutCommandType Type;

		public string SpoutName = "";

		public int AssetId;

		public override void Pack(ref MemoryPacker packer)
		{
			((MemoryPacker)(ref packer)).Write<SpoutCommandType>(Type);
			((MemoryPacker)(ref packer)).Write<int>(AssetId);
			((MemoryPacker)(ref packer)).Write(SpoutName);
		}

		public override void Unpack(ref MemoryUnpacker unpacker)
		{
			((MemoryUnpacker)(ref unpacker)).Read<SpoutCommandType>(ref Type);
			((MemoryUnpacker)(ref unpacker)).Read<int>(ref AssetId);
			((MemoryUnpacker)(ref unpacker)).Read(ref SpoutName);
		}
	}
}
namespace ResoniteSpoutRenderer
{
	[BepInPlugin("zozokasu.ResoniteSpout.Renderer", "ResoniteSpoutRenderer", "0.1.0")]
	public class ResoniteSpoutRenderer : BaseUnityPlugin
	{
		public class SpoutStruct
		{
			public string SpoutName;

			public int AssetId;

			public IntPtr SpoutSender;

			public Texture2D SharedTexture;

			public int InitializationAttempts;

			public bool IsValid => SpoutSender != IntPtr.Zero;

			public bool IsReady => IsValid && (Object)(object)SharedTexture != (Object)null;

			public bool TryCreateSharedTexture()
			{
				InitializationAttempts++;
				if (SpoutSender == IntPtr.Zero)
				{
					Log.LogError((object)("[" + SpoutName + "] Sender is null, cannot create shared texture"));
					return false;
				}
				IntPtr texturePointer = PluginEntry.GetTexturePointer(SpoutSender);
				if (texturePointer == IntPtr.Zero)
				{
					if (InitializationAttempts > 100)
					{
						Log.LogError((object)$"[{SpoutName}] Failed to get texture pointer after {InitializationAttempts} attempts");
						return false;
					}
					return false;
				}
				int textureWidth = PluginEntry.GetTextureWidth(SpoutSender);
				int textureHeight = PluginEntry.GetTextureHeight(SpoutSender);
				SharedTexture = Texture2D.CreateExternalTexture(textureWidth, textureHeight, (TextureFormat)5, false, false, texturePointer);
				((Object)SharedTexture).hideFlags = (HideFlags)52;
				Log.LogInfo((object)$"[{SpoutName}] Created shared texture {textureWidth}x{textureHeight} after {InitializationAttempts} attempts");
				return true;
			}

			public void Dispose()
			{
				if (SpoutSender != IntPtr.Zero)
				{
					PluginEntry.DestroySharedObject(SpoutSender);
					SpoutSender = IntPtr.Zero;
				}
				if ((Object)(object)SharedTexture != (Object)null)
				{
					Object.Destroy((Object)(object)SharedTexture);
					SharedTexture = null;
				}
				Log.LogInfo((object)("[" + SpoutName + "] Disposed"));
			}
		}

		public static ManualLogSource Log;

		private Messenger _msg;

		private readonly ConcurrentQueue<Action> _mainQueue = new ConcurrentQueue<Action>();

		private static Dictionary<string, SpoutStruct> spouts = new Dictionary<string, SpoutStruct>();

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			_msg = new Messenger("Zozokasu.ResoniteSpout", new List<Type>(1) { typeof(SpoutCommand) }, (List<Type>)null);
			_msg.ReceiveObject<SpoutCommand>("SpoutCommand", (Action<SpoutCommand>)delegate(SpoutCommand command)
			{
				SpoutCommand command2 = command;
				_mainQueue.Enqueue(delegate
				{
					ProcessCommand(command2);
				});
				Log.LogInfo((object)$"Command received: {command2.Type}, Name: '{command2.SpoutName}', AssetId: {command2.AssetId}");
			});
			_msg.ReceiveString("DbgMessage", (Action<string>)delegate(string? s)
			{
				Log.LogInfo((object)("[DEBUG]: " + s));
			});
			Log.LogInfo((object)$"[ResoniteSpoutRenderer] Initialized. Graphics: {SystemInfo.graphicsDeviceType}");
		}

		private void Update()
		{
			Action result;
			while (_mainQueue.TryDequeue(out result))
			{
				try
				{
					result();
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Error processing command: {arg}");
				}
			}
			SendRenderTextures();
		}

		private void OnDestroy()
		{
			foreach (SpoutStruct value in spouts.Values)
			{
				value.Dispose();
			}
			spouts.Clear();
		}

		private void ProcessCommand(SpoutCommand command)
		{
			switch (command.Type)
			{
			case SpoutCommandType.Create:
				CreateSpout(command.SpoutName, command.AssetId);
				break;
			case SpoutCommandType.Update:
				UpdateSpout(command.SpoutName, command.AssetId);
				break;
			case SpoutCommandType.Delete:
				DeleteSpout(command.SpoutName);
				break;
			}
		}

		private void CreateSpout(string spoutName, int assetId)
		{
			Log.LogInfo((object)$"[{spoutName}] CreateSpout called with AssetId: {assetId}");
			if (spouts.ContainsKey(spoutName))
			{
				Log.LogInfo((object)("[" + spoutName + "] Already exists, recreating..."));
				spouts[spoutName].Dispose();
				spouts.Remove(spoutName);
			}
			RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(assetId);
			if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null)
			{
				Log.LogError((object)$"[{spoutName}] RenderTexture not found for AssetId: {assetId}");
				return;
			}
			RenderTexture texture = asset.Texture;
			Log.LogInfo((object)$"[{spoutName}] RenderTexture found: {((Texture)texture).width}x{((Texture)texture).height}");
			IntPtr intPtr = PluginEntry.CreateSender(spoutName, ((Texture)texture).width, ((Texture)texture).height);
			if (intPtr == IntPtr.Zero)
			{
				Log.LogError((object)("[" + spoutName + "] Failed to create Spout sender"));
				return;
			}
			Log.LogInfo((object)$"[{spoutName}] Spout sender created: {intPtr}");
			Util.IssuePluginEvent(PluginEntry.Event.Update, intPtr);
			SpoutStruct value = new SpoutStruct
			{
				SpoutName = spoutName,
				AssetId = assetId,
				SpoutSender = intPtr,
				InitializationAttempts = 0
			};
			spouts[spoutName] = value;
			Log.LogInfo((object)$"[{spoutName}] Added to spouts dictionary. Total spouts: {spouts.Count}");
		}

		private void UpdateSpout(string spoutName, int assetId)
		{
			if (!spouts.ContainsKey(spoutName))
			{
				Log.LogWarning((object)("[" + spoutName + "] Not found for update, creating new..."));
				CreateSpout(spoutName, assetId);
				return;
			}
			SpoutStruct spoutStruct = spouts[spoutName];
			if (spoutStruct.AssetId == assetId)
			{
				Log.LogInfo((object)$"[{spoutName}] AssetId unchanged ({assetId}), skipping update");
				return;
			}
			Log.LogInfo((object)$"[{spoutName}] Updating: AssetId {spoutStruct.AssetId} → {assetId}");
			CreateSpout(spoutName, assetId);
		}

		private void DeleteSpout(string spoutName)
		{
			if (spouts.ContainsKey(spoutName))
			{
				spouts[spoutName].Dispose();
				spouts.Remove(spoutName);
				Log.LogInfo((object)$"[{spoutName}] Deleted. Remaining spouts: {spouts.Count}");
			}
			else
			{
				Log.LogWarning((object)("[" + spoutName + "] Not found for deletion"));
			}
		}

		private void SendRenderTextures()
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			if (spouts.Count == 0)
			{
				return;
			}
			foreach (KeyValuePair<string, SpoutStruct> spout in spouts)
			{
				string key = spout.Key;
				SpoutStruct value = spout.Value;
				try
				{
					if (!value.IsValid)
					{
						continue;
					}
					RenderTextureAsset asset = RenderingManager.Instance.RenderTextures.GetAsset(value.AssetId);
					if ((Object)(object)((asset != null) ? asset.Texture : null) == (Object)null)
					{
						if (value.InitializationAttempts == 1)
						{
							Log.LogWarning((object)$"[{key}] RenderTexture not available for AssetId: {value.AssetId}");
						}
						continue;
					}
					if (!((Object)(object)value.SharedTexture == (Object)null))
					{
						goto IL_0134;
					}
					if (value.InitializationAttempts < 5 || value.InitializationAttempts % 60 == 0)
					{
						Log.LogInfo((object)$"[{key}] Attempting to create shared texture (attempt {value.InitializationAttempts})...");
					}
					if (value.TryCreateSharedTexture())
					{
						goto IL_0134;
					}
					goto end_IL_0042;
					IL_0134:
					RenderTexture texture = asset.Texture;
					RenderTexture temporary = RenderTexture.GetTemporary(((Texture)value.SharedTexture).width, ((Texture)value.SharedTexture).height, 0, (RenderTextureFormat)0);
					Graphics.Blit((Texture)(object)texture, temporary, new Vector2(1f, -1f), new Vector2(0f, 1f));
					Graphics.CopyTexture((Texture)(object)temporary, (Texture)(object)value.SharedTexture);
					RenderTexture.ReleaseTemporary(temporary);
					end_IL_0042:;
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"[{key}] Error sending texture: {arg}");
				}
			}
			foreach (SpoutStruct value2 in spouts.Values)
			{
				if (value2.IsReady)
				{
					Util.IssuePluginEvent(PluginEntry.Event.Update, value2.SpoutSender);
				}
			}
		}
	}
	internal static class PluginEntry
	{
		internal enum Event
		{
			Update,
			Dispose
		}

		private static int _lastUpdateFrame = -1;

		internal static bool IsAvailable => (int)SystemInfo.graphicsDeviceType == 2;

		public static void Poll()
		{
			if (Time.frameCount != _lastUpdateFrame)
			{
				GL.IssuePluginEvent(GetRenderEventFunc(), 0);
				_lastUpdateFrame = Time.frameCount;
			}
		}

		[DllImport("KlakSpout.dll")]
		internal static extern IntPtr GetRenderEventFunc();

		[DllImport("KlakSpout.dll")]
		internal static extern IntPtr CreateSender(string name, int width, int height);

		[DllImport("KlakSpout.dll")]
		internal static extern IntPtr CreateReceiver(string name);

		[DllImport("KlakSpout")]
		public static extern void DestroySharedObject(IntPtr ptr);

		[DllImport("KlakSpout.dll")]
		internal static extern IntPtr GetTexturePointer(IntPtr ptr);

		[DllImport("KlakSpout.dll")]
		internal static extern int GetTextureWidth(IntPtr ptr);

		[DllImport("KlakSpout.dll")]
		internal static extern int GetTextureHeight(IntPtr ptr);

		[DllImport("KlakSpout.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		internal static extern bool CheckValid(IntPtr ptr);

		[DllImport("KlakSpout.dll")]
		internal static extern int ScanSharedObjects();

		[DllImport("KlakSpout.dll")]
		internal static extern IntPtr GetSharedObjectName(int index);

		internal static string GetSharedObjectNameString(int index)
		{
			IntPtr sharedObjectName = GetSharedObjectName(index);
			return (sharedObjectName != IntPtr.Zero) ? Marshal.PtrToStringAnsi(sharedObjectName) : null;
		}
	}
	internal static class Util
	{
		private static CommandBuffer _commandBuffer;

		internal static void Destroy(Object obj)
		{
			if (!(obj == (Object)null))
			{
				if (Application.isPlaying)
				{
					Object.Destroy(obj);
				}
				else
				{
					Object.DestroyImmediate(obj);
				}
			}
		}

		internal static void IssuePluginEvent(PluginEntry.Event pluginEvent, IntPtr ptr)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (_commandBuffer == null)
			{
				_commandBuffer = new CommandBuffer();
			}
			_commandBuffer.IssuePluginEventAndData(PluginEntry.GetRenderEventFunc(), (int)pluginEvent, ptr);
			Graphics.ExecuteCommandBuffer(_commandBuffer);
			_commandBuffer.Clear();
		}
	}
}