Decompiled source of OBSControl v1.0.0

Mods/OBSControl.dll

Decompiled a month 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 BoneLib;
using BoneLib.BoneMenu;
using BoneLib.BoneMenu.Elements;
using BoneLib.Notifications;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using OBSWebsocketDotNet;
using OBSWebsocketDotNet.Types;
using OBSWebsocketDotNet.Types.Events;
using UnityEngine;
using UnityEngine.Diagnostics;
using WeatherElectric.OBSControl;
using WeatherElectric.OBSControl.Handlers;
using WeatherElectric.OBSControl.Melon;
using WeatherElectric.OBSControl.Menu;
using WeatherElectric.OBSControl.OBS;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Control OBS from within BONELAB.")]
[assembly: AssemblyDescription("Control OBS from within BONELAB.")]
[assembly: AssemblyCompany("Weather Electric")]
[assembly: AssemblyProduct("OBSControl")]
[assembly: AssemblyCopyright("Developed by SoulWithMae")]
[assembly: AssemblyTrademark("Weather Electric")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: MelonInfo(typeof(Main), "OBSControl", "1.0.0", "SoulWithMae", "https://thunderstore.io/c/bonelab/p/SoulWithMae/OBSControl/")]
[assembly: MelonColor(ConsoleColor.White)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 WeatherElectric.OBSControl
{
	internal static class ControlHandler
	{
		private static bool _isFirstTap;

		private static float _doubleTapTimer;

		public static void Update()
		{
			switch (Preferences.ReplayControlHand.Value)
			{
			case ControlHand.Left:
				HandleLeft();
				break;
			case ControlHand.Right:
				HandleRight();
				break;
			case ControlHand.Both:
				HandleBoth();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			if (_isFirstTap)
			{
				_doubleTapTimer += Time.deltaTime;
				if (_doubleTapTimer > Preferences.DoubleTapTime.Value)
				{
					_isFirstTap = false;
				}
			}
			static void HandleBoth()
			{
				if (Player.rightController._menuTap || Player.leftController._menuTap)
				{
					if (!_isFirstTap)
					{
						_isFirstTap = true;
						_doubleTapTimer = 0f;
					}
					else if (_doubleTapTimer < Preferences.DoubleTapTime.Value)
					{
						ObsBridge.SaveReplayBuffer();
						NotificationHandler.SendNotif(NotificationHandler.ReplaySaved);
						_isFirstTap = false;
					}
				}
			}
			static void HandleLeft()
			{
				if (Player.leftController._menuTap)
				{
					if (!_isFirstTap)
					{
						_isFirstTap = true;
						_doubleTapTimer = 0f;
					}
					else if (_doubleTapTimer < Preferences.DoubleTapTime.Value)
					{
						ObsBridge.SaveReplayBuffer();
						NotificationHandler.SendNotif(NotificationHandler.ReplaySaved);
						_isFirstTap = false;
					}
				}
			}
			static void HandleRight()
			{
				if (Player.rightController._menuTap)
				{
					if (!_isFirstTap)
					{
						_isFirstTap = true;
						_doubleTapTimer = 0f;
					}
					else if (_doubleTapTimer < Preferences.DoubleTapTime.Value)
					{
						ObsBridge.SaveReplayBuffer();
						NotificationHandler.SendNotif(NotificationHandler.ReplaySaved);
						_isFirstTap = false;
					}
				}
			}
		}
	}
	public class Main : MelonMod
	{
		internal const string Name = "OBSControl";

		internal const string Description = "Control OBS from within BONELAB.";

		internal const string Author = "SoulWithMae";

		internal const string Company = "Weather Electric";

		internal const string Version = "1.0.0";

		internal const string DownloadLink = "https://thunderstore.io/c/bonelab/p/SoulWithMae/OBSControl/";

		private static bool _rigExists;

		public override void OnInitializeMelon()
		{
			ModConsole.Setup(((MelonBase)this).LoggerInstance);
			Preferences.Setup();
			ObsBridge.Connect();
			ObsBridge.InitHooks();
			Hooking.OnLevelInitialized += OnLevelLoaded;
			Hooking.OnLevelUnloaded += OnLevelUnloaded;
		}

		public override void OnLateInitializeMelon()
		{
			BoneMenu.SetupBaseMenu();
		}

		public override void OnApplicationQuit()
		{
			ObsBridge.Disconnect();
		}

		public override void OnUpdate()
		{
			if (_rigExists)
			{
				ControlHandler.Update();
			}
		}

		private static void OnLevelLoaded(LevelInfo levelInfo)
		{
			_rigExists = true;
		}

		private static void OnLevelUnloaded()
		{
			_rigExists = false;
		}
	}
}
namespace WeatherElectric.OBSControl.OBS
{
	public static class ObsBridge
	{
		private static readonly OBSWebsocket Obs = new OBSWebsocket();

		public static Action<object, RecordStateChangedEventArgs> OnRecordStateChanged;

		public static Action<object, ReplayBufferSavedEventArgs> OnReplayBufferSaved;

		public static Action<object, ReplayBufferStateChangedEventArgs> OnReplayBufferStateChanged;

		public static Action<object, StreamStateChangedEventArgs> OnStreamStateChanged;

		public static Action<object, ProgramSceneChangedEventArgs> OnSceneChanged;

		public static Action<object, SceneCreatedEventArgs> OnSceneCreated;

		public static Action<object, VirtualcamStateChangedEventArgs> OnVirtualCamStateChanged;

		public static Action<object, SceneRemovedEventArgs> OnSceneRemoved;

		private static void RecordStateChanged(object sender, RecordStateChangedEventArgs e)
		{
			OnRecordStateChanged?.Invoke(sender, e);
		}

		private static void ReplaySaved(object sender, ReplayBufferSavedEventArgs e)
		{
			OnReplayBufferSaved?.Invoke(sender, e);
		}

		private static void ReplayStateChanged(object sender, ReplayBufferStateChangedEventArgs e)
		{
			OnReplayBufferStateChanged?.Invoke(sender, e);
		}

		private static void StreamStateChanged(object sender, StreamStateChangedEventArgs e)
		{
			OnStreamStateChanged?.Invoke(sender, e);
		}

		private static void SceneChanged(object sender, ProgramSceneChangedEventArgs e)
		{
			OnSceneChanged?.Invoke(sender, e);
		}

		private static void VirtualCamStateChanged(object sender, VirtualcamStateChangedEventArgs e)
		{
			OnVirtualCamStateChanged?.Invoke(sender, e);
		}

		private static void SceneCreated(object sender, SceneCreatedEventArgs e)
		{
			OnSceneCreated?.Invoke(sender, e);
		}

		private static void SceneRemoved(object sender, SceneRemovedEventArgs e)
		{
		}

		internal static void Connect()
		{
			//IL_002f: Expected O, but got Unknown
			try
			{
				Obs.ConnectAsync(Preferences.WebsocketURL.Value, Preferences.WebsocketPassword.Value);
			}
			catch (AuthFailureException)
			{
				ModConsole.Error("Failed to authenticate with OBS. Check your password.");
			}
			catch (ErrorResponseException val2)
			{
				ErrorResponseException val3 = val2;
				ModConsole.Error("Failed to connect to OBS. Error: " + ((Exception)(object)val3).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to connect to OBS. Error: " + ex.Message);
			}
		}

		internal static void Disconnect()
		{
			Obs.Disconnect();
		}

		internal static void InitHooks()
		{
			Obs.RecordStateChanged += RecordStateChanged;
			Obs.ReplayBufferSaved += ReplaySaved;
			Obs.ReplayBufferStateChanged += ReplayStateChanged;
			Obs.StreamStateChanged += StreamStateChanged;
			Obs.CurrentProgramSceneChanged += SceneChanged;
			Obs.VirtualcamStateChanged += VirtualCamStateChanged;
			Obs.SceneCreated += SceneCreated;
			Obs.SceneRemoved += SceneRemoved;
		}

		public static List<SceneBasicInfo> GetScenes()
		{
			return Obs.GetSceneList().Scenes;
		}

		public static void SetScene(string sceneName)
		{
			Obs.SetCurrentProgramScene(sceneName);
		}

		public static bool IsConnected()
		{
			return Obs.IsConnected;
		}

		public static bool IsRecording()
		{
			return Obs.GetRecordStatus().IsRecording;
		}

		public static bool IsRecordingPaused()
		{
			return Obs.GetRecordStatus().IsRecordingPaused;
		}

		public static bool IsStreaming()
		{
			return Obs.GetStreamStatus().IsActive;
		}

		public static bool IsReplayBufferActive()
		{
			return Obs.GetReplayBufferStatus();
		}

		public static bool IsVirtualCamActive()
		{
			return Obs.GetVirtualCamStatus().IsActive;
		}

		public static void StartRecording()
		{
			//IL_0016: Expected O, but got Unknown
			if (IsRecording())
			{
				return;
			}
			try
			{
				Obs.StartRecord();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to start recording. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to start recording. Error: " + ex.Message);
			}
		}

		public static void PauseRecording()
		{
			//IL_0016: Expected O, but got Unknown
			if (IsRecordingPaused())
			{
				return;
			}
			try
			{
				Obs.PauseRecord();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to pause recording. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to pause recording. Error: " + ex.Message);
			}
		}

		public static void ResumeRecording()
		{
			//IL_0016: Expected O, but got Unknown
			if (!IsRecordingPaused())
			{
				return;
			}
			try
			{
				Obs.ResumeRecord();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to resume recording. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to resume recording. Error: " + ex.Message);
			}
		}

		public static void StopRecording()
		{
			//IL_0017: Expected O, but got Unknown
			if (!IsRecording())
			{
				return;
			}
			try
			{
				Obs.StopRecord();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to stop recording. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to stop recording. Error: " + ex.Message);
			}
		}

		public static void StartStreaming()
		{
			//IL_0016: Expected O, but got Unknown
			if (IsStreaming())
			{
				return;
			}
			try
			{
				Obs.StartStream();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to start streaming. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to start streaming. Error: " + ex.Message);
			}
		}

		public static void StopStreaming()
		{
			//IL_0016: Expected O, but got Unknown
			if (!IsStreaming())
			{
				return;
			}
			try
			{
				Obs.StopStream();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to stop streaming. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to stop streaming. Error: " + ex.Message);
			}
		}

		public static void StartReplayBuffer()
		{
			//IL_0016: Expected O, but got Unknown
			if (IsReplayBufferActive())
			{
				return;
			}
			try
			{
				Obs.StartReplayBuffer();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to start replay buffer. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to start replay buffer. Error: " + ex.Message);
			}
		}

		public static void StopReplayBuffer()
		{
			//IL_0016: Expected O, but got Unknown
			if (!IsReplayBufferActive())
			{
				return;
			}
			try
			{
				Obs.StopReplayBuffer();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to stop replay buffer. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to stop replay buffer. Error: " + ex.Message);
			}
		}

		public static void SaveReplayBuffer()
		{
			//IL_0016: Expected O, but got Unknown
			if (!IsReplayBufferActive())
			{
				return;
			}
			try
			{
				Obs.SaveReplayBuffer();
			}
			catch (ErrorResponseException val)
			{
				ErrorResponseException val2 = val;
				ModConsole.Error("Failed to save replay buffer. Error: " + ((Exception)(object)val2).Message);
			}
			catch (Exception ex)
			{
				ModConsole.Error("Failed to save replay buffer. Error: " + ex.Message);
			}
		}
	}
}
namespace WeatherElectric.OBSControl.Melon
{
	internal static class ModConsole
	{
		private static Instance _logger;

		public static void Setup(Instance loggerInstance)
		{
			_logger = loggerInstance;
		}

		public static void Msg(object obj, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? $"[DEBUG] {obj}" : obj.ToString());
			ConsoleColor consoleColor = ((loggingMode == 1) ? ConsoleColor.Yellow : ConsoleColor.Gray);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Msg(consoleColor, text);
			}
		}

		public static void Msg(string txt, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			ConsoleColor consoleColor = ((loggingMode == 1) ? ConsoleColor.Yellow : ConsoleColor.Gray);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Msg(consoleColor, text);
			}
		}

		public static void Msg(ConsoleColor txtcolor, object obj, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? $"[DEBUG] {obj}" : obj.ToString());
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Msg(txtcolor, text);
			}
		}

		public static void Msg(ConsoleColor txtcolor, string txt, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Msg(txtcolor, text);
			}
		}

		public static void Msg(string txt, int loggingMode = 0, params object[] args)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			ConsoleColor consoleColor = ((loggingMode == 1) ? ConsoleColor.Yellow : ConsoleColor.Gray);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Msg(consoleColor, text, args);
			}
		}

		public static void Msg(ConsoleColor txtcolor, string txt, int loggingMode = 0, params object[] args)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Msg(txtcolor, text, args);
			}
		}

		public static void Error(object obj, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? $"[DEBUG] {obj}" : obj.ToString());
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Error(text);
			}
		}

		public static void Error(string txt, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Error(text);
			}
		}

		public static void Error(string txt, int loggingMode = 0, params object[] args)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Error(text, args);
			}
		}

		public static void Warning(object obj, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? $"[DEBUG] {obj}" : obj.ToString());
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Warning(text);
			}
		}

		public static void Warning(string txt, int loggingMode = 0)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Warning(text);
			}
		}

		public static void Warning(string txt, int loggingMode = 0, params object[] args)
		{
			string text = ((loggingMode == 1) ? ("[DEBUG] " + txt) : txt);
			if (Preferences.LoggingMode.Value >= loggingMode)
			{
				_logger.Warning(text, args);
			}
		}
	}
	internal static class Preferences
	{
		public static readonly MelonPreferences_Category GlobalCategory = MelonPreferences.CreateCategory("Global");

		public static readonly MelonPreferences_Category OwnCategory = MelonPreferences.CreateCategory("OBSControl");

		public static MelonPreferences_Entry<int> LoggingMode { get; set; }

		public static MelonPreferences_Entry<bool> ShowNotifications { get; set; }

		public static MelonPreferences_Entry<string> WebsocketURL { get; set; }

		public static MelonPreferences_Entry<string> WebsocketPassword { get; set; }

		public static MelonPreferences_Entry<ControlHand> ReplayControlHand { get; set; }

		public static MelonPreferences_Entry<float> DoubleTapTime { get; set; }

		public static void Setup()
		{
			LoggingMode = GlobalCategory.GetEntry<int>("LoggingMode") ?? GlobalCategory.CreateEntry<int>("LoggingMode", 0, "Logging Mode", "The level of logging to use. 0 = Important Only, 1 = All", false, false, (ValueValidator)null, (string)null);
			GlobalCategory.SetFilePath(MelonUtils.UserDataDirectory + "/WeatherElectric.cfg");
			GlobalCategory.SaveToFile(false);
			ShowNotifications = OwnCategory.CreateEntry<bool>("ShowNotifications", true, "Show Notifications", "Whether to show notifications when OBS events occur.", false, false, (ValueValidator)null, (string)null);
			WebsocketURL = OwnCategory.CreateEntry<string>("WebsocketURL", "ws://127.0.0.1:4455", "Websocket URL", "The URL to use for the websocket connection. Usually don't have to change this.", false, false, (ValueValidator)null, (string)null);
			WebsocketPassword = OwnCategory.CreateEntry<string>("WebsocketPassword", "REPLACEME", "Websocket Password", "The password to use for the websocket connection. Change this to the password you set in OBS.", false, false, (ValueValidator)null, (string)null);
			ReplayControlHand = OwnCategory.CreateEntry<ControlHand>("ReplayControlHand", ControlHand.Right, "Replay Control Hand", "The hand to use for saving replays. Left = Left hand, Right = Right hand, Both = Both hands.", false, false, (ValueValidator)null, (string)null);
			DoubleTapTime = OwnCategory.CreateEntry<float>("DoubleTapTime", 0.3f, "Double Tap Time", "The time to wait between taps to trigger saving a replay.", false, false, (ValueValidator)null, (string)null);
			OwnCategory.SetFilePath(MelonUtils.UserDataDirectory + "/WeatherElectric.cfg");
			OwnCategory.SaveToFile(false);
			ModConsole.Msg("Finished preferences setup for OBSControl", 1);
		}
	}
	internal enum ControlHand
	{
		Left,
		Right,
		Both
	}
}
namespace WeatherElectric.OBSControl.Handlers
{
	internal static class NotificationHandler
	{
		public static Notification SceneChanged { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Scene Changed"),
			Message = NotificationText.op_Implicit("Scene has been changed."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification RecordingStarted { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Recording Started"),
			Message = NotificationText.op_Implicit("Recording has started."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification RecordingStopped { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Recording Stopped"),
			Message = NotificationText.op_Implicit("Recording has stopped."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification RecordingPaused { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Recording Paused"),
			Message = NotificationText.op_Implicit("Recording has been paused."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification RecordingResumed { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Recording Resumed"),
			Message = NotificationText.op_Implicit("Recording has been resumed."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification StreamStarted { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Stream Started"),
			Message = NotificationText.op_Implicit("Stream has started."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification StreamStopped { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Stream Stopped"),
			Message = NotificationText.op_Implicit("Stream has stopped."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification ReplayBufferStarted { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Replay Buffer Started"),
			Message = NotificationText.op_Implicit("Replay buffer has started."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification ReplayBufferStopped { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Replay Buffer Stopped"),
			Message = NotificationText.op_Implicit("Replay buffer has stopped."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static Notification ReplaySaved { get; } = new Notification
		{
			Title = NotificationText.op_Implicit("Replay Saved"),
			Message = NotificationText.op_Implicit("Replay has been saved."),
			Type = (NotificationType)0,
			PopupLength = 1f,
			ShowTitleOnPopup = true
		};


		public static void SendNotif(Notification notification)
		{
			if (Preferences.ShowNotifications.Value)
			{
				Notifier.Send(notification);
			}
		}
	}
}
namespace WeatherElectric.OBSControl.Menu
{
	internal static class BoneMenu
	{
		private static MenuCategory _subCat;

		private static FunctionElement _recordButton;

		private static FunctionElement _pauseButton;

		private static FunctionElement _streamButton;

		private static FunctionElement _replayButton;

		private static SubPanelElement _scenesPanel;

		private static readonly List<FunctionElement> SceneButtons = new List<FunctionElement>();

		public static void SetupBaseMenu()
		{
			_subCat = MenuManager.CreateCategory("Weather Electric", "#6FBDFF").CreateCategory("OBSControl", "#284cb8");
			CheckIfConnected();
		}

		private static void CheckIfConnected()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!ObsBridge.IsConnected())
			{
				_subCat.CreateFunctionElement("OBS is not connected! Restart the game with OBS open!", Color.red, (Action)delegate
				{
					Utils.ForceCrash((ForcedCrashCategory)2);
				}, "This will crash the game intentionally to close the game!");
			}
			else
			{
				SetupObsControls();
			}
		}

		private static void SetupObsControls()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			SubPanelElement obj = _subCat.CreateSubPanel("Record", Color.green);
			_recordButton = obj.CreateFunctionElement("Record Button", Color.green, (Action)delegate
			{
				if (ObsBridge.IsRecording())
				{
					ObsBridge.StopRecording();
					NotificationHandler.SendNotif(NotificationHandler.RecordingStopped);
				}
				else
				{
					ObsBridge.StartRecording();
					NotificationHandler.SendNotif(NotificationHandler.RecordingStarted);
				}
			});
			SetRecordButton(ObsBridge.IsRecording());
			_pauseButton = obj.CreateFunctionElement("Pause Button", Color.yellow, (Action)delegate
			{
				if (ObsBridge.IsRecordingPaused())
				{
					ObsBridge.ResumeRecording();
					NotificationHandler.SendNotif(NotificationHandler.RecordingResumed);
				}
				else
				{
					ObsBridge.PauseRecording();
					NotificationHandler.SendNotif(NotificationHandler.RecordingPaused);
				}
			});
			SetPauseButton(ObsBridge.IsRecordingPaused());
			_streamButton = _subCat.CreateSubPanel("Stream", Color.blue).CreateFunctionElement("Stream Button", Color.blue, (Action)delegate
			{
				if (ObsBridge.IsStreaming())
				{
					ObsBridge.StopStreaming();
					NotificationHandler.SendNotif(NotificationHandler.StreamStopped);
				}
				else
				{
					ObsBridge.StartStreaming();
					NotificationHandler.SendNotif(NotificationHandler.StreamStarted);
				}
			});
			SetStreamButton(ObsBridge.IsStreaming());
			SubPanelElement obj2 = _subCat.CreateSubPanel("Replay", Color.yellow);
			_replayButton = obj2.CreateFunctionElement("Replay Button", Color.blue, (Action)delegate
			{
				if (ObsBridge.IsReplayBufferActive())
				{
					ObsBridge.StopReplayBuffer();
					NotificationHandler.SendNotif(NotificationHandler.ReplayBufferStopped);
				}
				else
				{
					ObsBridge.StartReplayBuffer();
					NotificationHandler.SendNotif(NotificationHandler.ReplayBufferStarted);
				}
			});
			SetReplayButton(ObsBridge.IsReplayBufferActive());
			obj2.CreateFunctionElement("Save Replay", Color.blue, (Action)delegate
			{
				ObsBridge.SaveReplayBuffer();
				NotificationHandler.SendNotif(NotificationHandler.ReplaySaved);
			});
			_scenesPanel = _subCat.CreateSubPanel("Scenes", Color.red);
			foreach (SceneBasicInfo scene in ObsBridge.GetScenes())
			{
				FunctionElement item = _scenesPanel.CreateFunctionElement(scene.Name, Color.white, (Action)delegate
				{
					//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)
					ObsBridge.SetScene(scene.Name);
					NotificationHandler.SceneChanged.Message = NotificationText.op_Implicit("Scene changed to " + scene.Name);
					NotificationHandler.SendNotif(NotificationHandler.SceneChanged);
				});
				SceneButtons.Add(item);
			}
			SubPanelElement category = _subCat.CreateSubPanel("Settings", Color.gray);
			category.CreateBoolPreference("Show Notifications", Color.white, Preferences.ShowNotifications, Preferences.OwnCategory);
			category.CreateEnumPreference<ControlHand>("Replay Control Hand", Color.white, Preferences.ReplayControlHand, Preferences.OwnCategory);
			category.CreateFloatPreference("Double Tap Time", Color.white, 0.1f, 0.1f, 1f, Preferences.DoubleTapTime, Preferences.OwnCategory);
			ConnectHooks();
		}

		private static void ConnectHooks()
		{
			ObsBridge.OnRecordStateChanged = (Action<object, RecordStateChangedEventArgs>)Delegate.Combine(ObsBridge.OnRecordStateChanged, new Action<object, RecordStateChangedEventArgs>(RecordStatusChanged));
			ObsBridge.OnStreamStateChanged = (Action<object, StreamStateChangedEventArgs>)Delegate.Combine(ObsBridge.OnStreamStateChanged, new Action<object, StreamStateChangedEventArgs>(StreamStatusChanged));
			ObsBridge.OnReplayBufferStateChanged = (Action<object, ReplayBufferStateChangedEventArgs>)Delegate.Combine(ObsBridge.OnReplayBufferStateChanged, new Action<object, ReplayBufferStateChangedEventArgs>(ReplayStatusChanged));
			ObsBridge.OnSceneCreated = (Action<object, SceneCreatedEventArgs>)Delegate.Combine(ObsBridge.OnSceneCreated, new Action<object, SceneCreatedEventArgs>(SceneCreated));
			ObsBridge.OnSceneRemoved = (Action<object, SceneRemovedEventArgs>)Delegate.Combine(ObsBridge.OnSceneRemoved, new Action<object, SceneRemovedEventArgs>(SceneDeleted));
		}

		private static void RecordStatusChanged(object sender, RecordStateChangedEventArgs e)
		{
			SetRecordButton(((OutputStateChanged)e.OutputState).IsActive);
		}

		private static void StreamStatusChanged(object sender, StreamStateChangedEventArgs e)
		{
			SetStreamButton(e.OutputState.IsActive);
		}

		private static void ReplayStatusChanged(object sender, ReplayBufferStateChangedEventArgs e)
		{
			SetReplayButton(e.OutputState.IsActive);
		}

		private static void SceneCreated(object sender, SceneCreatedEventArgs e)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			FunctionElement item = _scenesPanel.CreateFunctionElement(e.SceneName, Color.white, (Action)delegate
			{
				ObsBridge.SetScene(e.SceneName);
			});
			SceneButtons.Add(item);
		}

		private static void SceneDeleted(object sender, SceneRemovedEventArgs e)
		{
			using IEnumerator<FunctionElement> enumerator = SceneButtons.Where((FunctionElement button) => ((MenuElement)button).Name == e.SceneName).GetEnumerator();
			if (enumerator.MoveNext())
			{
				FunctionElement current = enumerator.Current;
				_scenesPanel.RemoveElement((MenuElement)(object)current);
				SceneButtons.Remove(current);
			}
		}

		private static void SetRecordButton(bool isRecording)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (isRecording)
			{
				((MenuElement)_recordButton).SetColor(Color.red);
				((MenuElement)_recordButton).SetName("Stop Recording");
			}
			else
			{
				((MenuElement)_recordButton).SetColor(Color.green);
				((MenuElement)_recordButton).SetName("Start Recording");
			}
		}

		private static void SetPauseButton(bool isPaused)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (isPaused)
			{
				((MenuElement)_pauseButton).SetColor(Color.white);
				((MenuElement)_pauseButton).SetName("Resume Recording");
			}
			else
			{
				((MenuElement)_pauseButton).SetColor(Color.yellow);
				((MenuElement)_pauseButton).SetName("Pause Recording");
			}
		}

		private static void SetStreamButton(bool isStreaming)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (isStreaming)
			{
				((MenuElement)_streamButton).SetColor(Color.red);
				((MenuElement)_streamButton).SetName("Stop Streaming");
			}
			else
			{
				((MenuElement)_streamButton).SetColor(Color.green);
				((MenuElement)_streamButton).SetName("Start Streaming");
			}
		}

		private static void SetReplayButton(bool isReplayActive)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (isReplayActive)
			{
				((MenuElement)_replayButton).SetColor(Color.red);
				((MenuElement)_replayButton).SetName("Stop Replay Buffer");
			}
			else
			{
				((MenuElement)_replayButton).SetColor(Color.green);
				((MenuElement)_replayButton).SetName("Start Replay Buffer");
			}
		}
	}
	internal static class BoneMenuExtensions
	{
		public static BoolElement CreateBoolPreference(this MenuCategory category, string name, Color color, MelonPreferences_Entry<bool> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateBoolElement(name, color, pref.Value, (Action<bool>)delegate(bool v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static BoolElement CreateBoolPreference(this MenuCategory category, string name, string hexColor, MelonPreferences_Entry<bool> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			return category.CreateBoolElement(name, hexColor, pref.Value, (Action<bool>)delegate(bool v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static BoolElement CreateBoolPreference(this SubPanelElement category, string name, Color color, MelonPreferences_Entry<bool> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateBoolElement(name, color, pref.Value, (Action<bool>)delegate(bool v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static BoolElement CreateBoolPreference(this SubPanelElement category, string name, string hexColor, MelonPreferences_Entry<bool> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			return category.CreateBoolElement(name, hexColor, pref.Value, (Action<bool>)delegate(bool v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static FloatElement CreateFloatPreference(this MenuCategory category, string name, Color color, float increment, float min, float max, MelonPreferences_Entry<float> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateFloatElement(name, color, pref.Value, increment, min, max, (Action<float>)delegate(float v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static FloatElement CreateFloatPreference(this MenuCategory category, string name, string hexColor, float increment, float min, float max, MelonPreferences_Entry<float> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			return category.CreateFloatElement(name, hexColor, pref.Value, increment, min, max, (Action<float>)delegate(float v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static FloatElement CreateFloatPreference(this SubPanelElement category, string name, Color color, float increment, float min, float max, MelonPreferences_Entry<float> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateFloatElement(name, color, pref.Value, increment, min, max, (Action<float>)delegate(float v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static FloatElement CreateFloatPreference(this SubPanelElement category, string name, string hexColor, float increment, float min, float max, MelonPreferences_Entry<float> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			return category.CreateFloatElement(name, hexColor, pref.Value, increment, min, max, (Action<float>)delegate(float v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static IntElement CreateIntPreference(this MenuCategory category, string name, Color color, int increment, int min, int max, MelonPreferences_Entry<int> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateIntElement(name, color, pref.Value, increment, min, max, (Action<int>)delegate(int v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static IntElement CreateIntPreference(this MenuCategory category, string name, string hexColor, int increment, int min, int max, MelonPreferences_Entry<int> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			return category.CreateIntElement(name, hexColor, pref.Value, increment, min, max, (Action<int>)delegate(int v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static IntElement CreateIntPreference(this SubPanelElement category, string name, Color color, int increment, int min, int max, MelonPreferences_Entry<int> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateIntElement(name, color, pref.Value, increment, min, max, (Action<int>)delegate(int v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static IntElement CreateIntPreference(this SubPanelElement category, string name, string hexColor, int increment, int min, int max, MelonPreferences_Entry<int> pref, MelonPreferences_Category prefCategory, bool autoSave = true)
		{
			return category.CreateIntElement(name, hexColor, pref.Value, increment, min, max, (Action<int>)delegate(int v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static EnumElement<TEnum> CreateEnumPreference<TEnum>(this MenuCategory category, string name, Color color, MelonPreferences_Entry<TEnum> pref, MelonPreferences_Category prefCategory, bool autoSave = true) where TEnum : Enum
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateEnumElement<TEnum>(name, color, pref.Value, (Action<TEnum>)delegate(TEnum v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static EnumElement<TEnum> CreateEnumPreference<TEnum>(this MenuCategory category, string name, string hexColor, MelonPreferences_Entry<TEnum> pref, MelonPreferences_Category prefCategory, bool autoSave = true) where TEnum : Enum
		{
			return category.CreateEnumElement<TEnum>(name, hexColor, pref.Value, (Action<TEnum>)delegate(TEnum v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static EnumElement<TEnum> CreateEnumPreference<TEnum>(this SubPanelElement category, string name, Color color, MelonPreferences_Entry<TEnum> pref, MelonPreferences_Category prefCategory, bool autoSave = true) where TEnum : Enum
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return category.CreateEnumElement<TEnum>(name, color, pref.Value, (Action<TEnum>)delegate(TEnum v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}

		public static EnumElement<TEnum> CreateEnumPreference<TEnum>(this SubPanelElement category, string name, string hexColor, MelonPreferences_Entry<TEnum> pref, MelonPreferences_Category prefCategory, bool autoSave = true) where TEnum : Enum
		{
			return category.CreateEnumElement<TEnum>(name, hexColor, pref.Value, (Action<TEnum>)delegate(TEnum v)
			{
				pref.Value = v;
				if (autoSave)
				{
					prefCategory.SaveToFile(false);
				}
			});
		}
	}
}

UserLibs/obs-websocket-dotnet.dll

Decompiled a month ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using OBSWebsocketDotNet.Communication;
using OBSWebsocketDotNet.Types;
using OBSWebsocketDotNet.Types.Events;
using WatsonWebsocket;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("BarRaider")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © BarRaider 2022")]
[assembly: AssemblyDescription("Official obs-websocket .NET library. Written in C#. Supports .NET Standard")]
[assembly: AssemblyFileVersion("5.0.0.3")]
[assembly: AssemblyInformationalVersion("5.0.0.3+a800d47920734f50bc878326aa0ac3d75a475b06")]
[assembly: AssemblyProduct("obs-websocket-dotnet")]
[assembly: AssemblyTitle("obs-websocket-dotnet")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/BarRaider/obs-websocket-dotnet")]
[assembly: AssemblyVersion("5.0.0.3")]
namespace OBSWebsocketDotNet
{
	public class OBSWebsocket : IOBSWebsocket
	{
		private delegate void RequestCallback(OBSWebsocket sender, JObject body);

		private const string WEBSOCKET_URL_PREFIX = "ws://";

		private const int SUPPORTED_RPC_VERSION = 1;

		private TimeSpan wsTimeout = TimeSpan.FromSeconds(10.0);

		private string connectionPassword;

		private WatsonWsClient wsConnection;

		private readonly ConcurrentDictionary<string, TaskCompletionSource<JObject>> responseHandlers;

		private static readonly Random random = new Random();

		private const string REQUEST_FIELD_VOLUME_DB = "inputVolumeDb";

		private const string REQUEST_FIELD_VOLUME_MUL = "inputVolumeMul";

		private const string RESPONSE_FIELD_IMAGE_DATA = "imageData";

		public TimeSpan WSTimeout { get; set; }

		public bool IsConnected
		{
			get
			{
				WatsonWsClient val = wsConnection;
				if (val != null)
				{
					return val.Connected;
				}
				return false;
			}
		}

		public event EventHandler<ProgramSceneChangedEventArgs> CurrentProgramSceneChanged;

		public event EventHandler<SceneListChangedEventArgs> SceneListChanged;

		public event EventHandler<SceneItemListReindexedEventArgs> SceneItemListReindexed;

		public event EventHandler<SceneItemCreatedEventArgs> SceneItemCreated;

		public event EventHandler<SceneItemRemovedEventArgs> SceneItemRemoved;

		public event EventHandler<SceneItemEnableStateChangedEventArgs> SceneItemEnableStateChanged;

		public event EventHandler<SceneItemLockStateChangedEventArgs> SceneItemLockStateChanged;

		public event EventHandler<CurrentSceneCollectionChangedEventArgs> CurrentSceneCollectionChanged;

		public event EventHandler<SceneCollectionListChangedEventArgs> SceneCollectionListChanged;

		public event EventHandler<CurrentSceneTransitionChangedEventArgs> CurrentSceneTransitionChanged;

		public event EventHandler<CurrentSceneTransitionDurationChangedEventArgs> CurrentSceneTransitionDurationChanged;

		public event EventHandler<SceneTransitionStartedEventArgs> SceneTransitionStarted;

		public event EventHandler<SceneTransitionEndedEventArgs> SceneTransitionEnded;

		public event EventHandler<SceneTransitionVideoEndedEventArgs> SceneTransitionVideoEnded;

		public event EventHandler<CurrentProfileChangedEventArgs> CurrentProfileChanged;

		public event EventHandler<ProfileListChangedEventArgs> ProfileListChanged;

		public event EventHandler<StreamStateChangedEventArgs> StreamStateChanged;

		public event EventHandler<RecordStateChangedEventArgs> RecordStateChanged;

		public event EventHandler<ReplayBufferStateChangedEventArgs> ReplayBufferStateChanged;

		public event EventHandler<CurrentPreviewSceneChangedEventArgs> CurrentPreviewSceneChanged;

		public event EventHandler<StudioModeStateChangedEventArgs> StudioModeStateChanged;

		public event EventHandler ExitStarted;

		public event EventHandler Connected;

		public event EventHandler<ObsDisconnectionInfo> Disconnected;

		public event EventHandler<SceneItemSelectedEventArgs> SceneItemSelected;

		public event EventHandler<SceneItemTransformEventArgs> SceneItemTransformChanged;

		public event EventHandler<InputAudioSyncOffsetChangedEventArgs> InputAudioSyncOffsetChanged;

		public event EventHandler<SourceFilterCreatedEventArgs> SourceFilterCreated;

		public event EventHandler<SourceFilterRemovedEventArgs> SourceFilterRemoved;

		public event EventHandler<SourceFilterListReindexedEventArgs> SourceFilterListReindexed;

		public event EventHandler<SourceFilterEnableStateChangedEventArgs> SourceFilterEnableStateChanged;

		public event EventHandler<InputMuteStateChangedEventArgs> InputMuteStateChanged;

		public event EventHandler<InputVolumeChangedEventArgs> InputVolumeChanged;

		public event EventHandler<VendorEventArgs> VendorEvent;

		public event EventHandler<MediaInputPlaybackEndedEventArgs> MediaInputPlaybackEnded;

		public event EventHandler<MediaInputPlaybackStartedEventArgs> MediaInputPlaybackStarted;

		public event EventHandler<MediaInputActionTriggeredEventArgs> MediaInputActionTriggered;

		public event EventHandler<VirtualcamStateChangedEventArgs> VirtualcamStateChanged;

		public event EventHandler<CurrentSceneCollectionChangingEventArgs> CurrentSceneCollectionChanging;

		public event EventHandler<CurrentProfileChangingEventArgs> CurrentProfileChanging;

		public event EventHandler<SourceFilterNameChangedEventArgs> SourceFilterNameChanged;

		public event EventHandler<InputCreatedEventArgs> InputCreated;

		public event EventHandler<InputRemovedEventArgs> InputRemoved;

		public event EventHandler<InputNameChangedEventArgs> InputNameChanged;

		public event EventHandler<InputActiveStateChangedEventArgs> InputActiveStateChanged;

		public event EventHandler<InputShowStateChangedEventArgs> InputShowStateChanged;

		public event EventHandler<InputAudioBalanceChangedEventArgs> InputAudioBalanceChanged;

		public event EventHandler<InputAudioTracksChangedEventArgs> InputAudioTracksChanged;

		public event EventHandler<InputAudioMonitorTypeChangedEventArgs> InputAudioMonitorTypeChanged;

		public event EventHandler<InputVolumeMetersEventArgs> InputVolumeMeters;

		public event EventHandler<ReplayBufferSavedEventArgs> ReplayBufferSaved;

		public event EventHandler<SceneCreatedEventArgs> SceneCreated;

		public event EventHandler<SceneRemovedEventArgs> SceneRemoved;

		public event EventHandler<SceneNameChangedEventArgs> SceneNameChanged;

		protected void ProcessEventType(string eventType, JObject body)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0f00: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f10: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f1a: Expected O, but got Unknown
			//IL_0f1a: Expected O, but got Unknown
			//IL_0c5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c6d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c77: Expected O, but got Unknown
			//IL_0c77: Expected O, but got Unknown
			//IL_104b: Unknown result type (might be due to invalid IL or missing references)
			//IL_1055: Expected O, but got Unknown
			//IL_0b66: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b70: Expected O, but got Unknown
			body = (JObject)body["eventData"];
			switch (eventType)
			{
			case "CurrentProgramSceneChanged":
				this.CurrentProgramSceneChanged?.Invoke(this, new ProgramSceneChangedEventArgs((string)body["sceneName"]));
				break;
			case "SceneListChanged":
				this.SceneListChanged?.Invoke(this, new SceneListChangedEventArgs(JsonConvert.DeserializeObject<List<JObject>>((string)body["scenes"])));
				break;
			case "SceneItemListReindexed":
				this.SceneItemListReindexed?.Invoke(this, new SceneItemListReindexedEventArgs((string)body["sceneName"], JsonConvert.DeserializeObject<List<JObject>>((string)body["sceneItems"])));
				break;
			case "SceneItemCreated":
				this.SceneItemCreated?.Invoke(this, new SceneItemCreatedEventArgs((string)body["sceneName"], (string)body["sourceName"], (int)body["sceneItemId"], (int)body["sceneItemIndex"]));
				break;
			case "SceneItemRemoved":
				this.SceneItemRemoved?.Invoke(this, new SceneItemRemovedEventArgs((string)body["sceneName"], (string)body["sourceName"], (int)body["sceneItemId"]));
				break;
			case "SceneItemEnableStateChanged":
				this.SceneItemEnableStateChanged?.Invoke(this, new SceneItemEnableStateChangedEventArgs((string)body["sceneName"], (int)body["sceneItemId"], (bool)body["sceneItemEnabled"]));
				break;
			case "SceneItemLockStateChanged":
				this.SceneItemLockStateChanged?.Invoke(this, new SceneItemLockStateChangedEventArgs((string)body["sceneName"], (int)body["sceneItemId"], (bool)body["sceneItemLocked"]));
				break;
			case "CurrentSceneCollectionChanged":
				this.CurrentSceneCollectionChanged?.Invoke(this, new CurrentSceneCollectionChangedEventArgs((string)body["sceneCollectionName"]));
				break;
			case "SceneCollectionListChanged":
				this.SceneCollectionListChanged?.Invoke(this, new SceneCollectionListChangedEventArgs(JsonConvert.DeserializeObject<List<string>>((string)body["sceneCollections"])));
				break;
			case "CurrentSceneTransitionChanged":
				this.CurrentSceneTransitionChanged?.Invoke(this, new CurrentSceneTransitionChangedEventArgs((string)body["transitionName"]));
				break;
			case "CurrentSceneTransitionDurationChanged":
				this.CurrentSceneTransitionDurationChanged?.Invoke(this, new CurrentSceneTransitionDurationChangedEventArgs((int)body["transitionDuration"]));
				break;
			case "SceneTransitionStarted":
				this.SceneTransitionStarted?.Invoke(this, new SceneTransitionStartedEventArgs((string)body["transitionName"]));
				break;
			case "SceneTransitionEnded":
				this.SceneTransitionEnded?.Invoke(this, new SceneTransitionEndedEventArgs((string)body["transitionName"]));
				break;
			case "SceneTransitionVideoEnded":
				this.SceneTransitionVideoEnded?.Invoke(this, new SceneTransitionVideoEndedEventArgs((string)body["transitionName"]));
				break;
			case "CurrentProfileChanged":
				this.CurrentProfileChanged?.Invoke(this, new CurrentProfileChangedEventArgs((string)body["profileName"]));
				break;
			case "ProfileListChanged":
				this.ProfileListChanged?.Invoke(this, new ProfileListChangedEventArgs(JsonConvert.DeserializeObject<List<string>>((string)body["profiles"])));
				break;
			case "StreamStateChanged":
				this.StreamStateChanged?.Invoke(this, new StreamStateChangedEventArgs(new OutputStateChanged(body)));
				break;
			case "RecordStateChanged":
				this.RecordStateChanged?.Invoke(this, new RecordStateChangedEventArgs(new RecordStateChanged(body)));
				break;
			case "CurrentPreviewSceneChanged":
				this.CurrentPreviewSceneChanged?.Invoke(this, new CurrentPreviewSceneChangedEventArgs((string)body["sceneName"]));
				break;
			case "StudioModeStateChanged":
				this.StudioModeStateChanged?.Invoke(this, new StudioModeStateChangedEventArgs((bool)body["studioModeEnabled"]));
				break;
			case "ReplayBufferStateChanged":
				this.ReplayBufferStateChanged?.Invoke(this, new ReplayBufferStateChangedEventArgs(new OutputStateChanged(body)));
				break;
			case "ExitStarted":
				this.ExitStarted?.Invoke(this, EventArgs.Empty);
				break;
			case "SceneItemSelected":
				this.SceneItemSelected?.Invoke(this, new SceneItemSelectedEventArgs((string)body["sceneName"], (string)body["sceneItemId"]));
				break;
			case "SceneItemTransformChanged":
				this.SceneItemTransformChanged?.Invoke(this, new SceneItemTransformEventArgs((string)body["sceneName"], (string)body["sceneItemId"], new SceneItemTransformInfo((JObject)body["sceneItemTransform"])));
				break;
			case "InputAudioSyncOffsetChanged":
				this.InputAudioSyncOffsetChanged?.Invoke(this, new InputAudioSyncOffsetChangedEventArgs((string)body["inputName"], (int)body["inputAudioSyncOffset"]));
				break;
			case "InputMuteStateChanged":
				this.InputMuteStateChanged?.Invoke(this, new InputMuteStateChangedEventArgs((string)body["inputName"], (bool)body["inputMuted"]));
				break;
			case "InputVolumeChanged":
				this.InputVolumeChanged?.Invoke(this, new InputVolumeChangedEventArgs(new InputVolume(body)));
				break;
			case "SourceFilterCreated":
				this.SourceFilterCreated?.Invoke(this, new SourceFilterCreatedEventArgs((string)body["sourceName"], (string)body["filterName"], (string)body["filterKind"], (int)body["filterIndex"], (JObject)body["filterSettings"], (JObject)body["defaultFilterSettings"]));
				break;
			case "SourceFilterRemoved":
				this.SourceFilterRemoved?.Invoke(this, new SourceFilterRemovedEventArgs((string)body["sourceName"], (string)body["filterName"]));
				break;
			case "SourceFilterListReindexed":
				if (this.SourceFilterListReindexed != null)
				{
					List<FilterReorderItem> list = new List<FilterReorderItem>();
					JsonConvert.PopulateObject(((object)body["filters"]).ToString(), (object)list);
					this.SourceFilterListReindexed?.Invoke(this, new SourceFilterListReindexedEventArgs((string)body["sourceName"], list));
				}
				break;
			case "SourceFilterEnableStateChanged":
				this.SourceFilterEnableStateChanged?.Invoke(this, new SourceFilterEnableStateChangedEventArgs((string)body["sourceName"], (string)body["filterName"], (bool)body["filterEnabled"]));
				break;
			case "VendorEvent":
				this.VendorEvent?.Invoke(this, new VendorEventArgs((string)body["vendorName"], (string)body["eventType"], body));
				break;
			case "MediaInputPlaybackEnded":
				this.MediaInputPlaybackEnded?.Invoke(this, new MediaInputPlaybackEndedEventArgs((string)body["inputName"]));
				break;
			case "MediaInputPlaybackStarted":
				this.MediaInputPlaybackStarted?.Invoke(this, new MediaInputPlaybackStartedEventArgs((string)body["sourceName"]));
				break;
			case "MediaInputActionTriggered":
				this.MediaInputActionTriggered?.Invoke(this, new MediaInputActionTriggeredEventArgs((string)body["inputName"], (string)body["mediaAction"]));
				break;
			case "VirtualcamStateChanged":
				this.VirtualcamStateChanged?.Invoke(this, new VirtualcamStateChangedEventArgs(new OutputStateChanged(body)));
				break;
			case "CurrentSceneCollectionChanging":
				this.CurrentSceneCollectionChanging?.Invoke(this, new CurrentSceneCollectionChangingEventArgs((string)body["sceneCollectionName"]));
				break;
			case "CurrentProfileChanging":
				this.CurrentProfileChanging?.Invoke(this, new CurrentProfileChangingEventArgs((string)body["profileName"]));
				break;
			case "SourceFilterNameChanged":
				this.SourceFilterNameChanged?.Invoke(this, new SourceFilterNameChangedEventArgs((string)body["sourceName"], (string)body["oldFilterName"], (string)body["filterName"]));
				break;
			case "InputCreated":
				this.InputCreated?.Invoke(this, new InputCreatedEventArgs((string)body["inputName"], (string)body["inputKind"], (string)body["unversionedInputKind"], (JObject)body["inputSettings"], (JObject)body["defaultInputSettings"]));
				break;
			case "InputRemoved":
				this.InputRemoved?.Invoke(this, new InputRemovedEventArgs((string)body["inputName"]));
				break;
			case "InputNameChanged":
				this.InputNameChanged?.Invoke(this, new InputNameChangedEventArgs((string)body["oldInputName"], (string)body["inputName"]));
				break;
			case "InputActiveStateChanged":
				this.InputActiveStateChanged?.Invoke(this, new InputActiveStateChangedEventArgs((string)body["inputName"], (bool)body["videoActive"]));
				break;
			case "InputShowStateChanged":
				this.InputShowStateChanged?.Invoke(this, new InputShowStateChangedEventArgs((string)body["inputName"], (bool)body["videoShowing"]));
				break;
			case "InputAudioBalanceChanged":
				this.InputAudioBalanceChanged?.Invoke(this, new InputAudioBalanceChangedEventArgs((string)body["inputName"], (double)body["inputAudioBalance"]));
				break;
			case "InputAudioTracksChanged":
				this.InputAudioTracksChanged?.Invoke(this, new InputAudioTracksChangedEventArgs((string)body["inputName"], (JObject)body["inputAudioTracks"]));
				break;
			case "InputAudioMonitorTypeChanged":
				this.InputAudioMonitorTypeChanged?.Invoke(this, new InputAudioMonitorTypeChangedEventArgs((string)body["inputName"], (string)body["monitorType"]));
				break;
			case "InputVolumeMeters":
				this.InputVolumeMeters?.Invoke(this, new InputVolumeMetersEventArgs(JsonConvert.DeserializeObject<List<JObject>>((string)body["inputs"])));
				break;
			case "ReplayBufferSaved":
				this.ReplayBufferSaved?.Invoke(this, new ReplayBufferSavedEventArgs((string)body["savedReplayPath"]));
				break;
			case "SceneCreated":
				this.SceneCreated?.Invoke(this, new SceneCreatedEventArgs((string)body["sceneName"], (bool)body["isGroup"]));
				break;
			case "SceneRemoved":
				this.SceneRemoved?.Invoke(this, new SceneRemovedEventArgs((string)body["sceneName"], (bool)body["isGroup"]));
				break;
			case "SceneNameChanged":
				this.SceneNameChanged?.Invoke(this, new SceneNameChangedEventArgs((string)body["oldSceneName"], (string)body["sceneName"]));
				break;
			default:
				Console.WriteLine($"Unsupported Event: {eventType}\n{body}");
				break;
			}
		}

		public OBSWebsocket()
		{
			responseHandlers = new ConcurrentDictionary<string, TaskCompletionSource<JObject>>();
		}

		[Obsolete("Please use ConnectAsync, this function will be removed in the next version")]
		public void Connect(string url, string password)
		{
			ConnectAsync(url, password);
		}

		public void ConnectAsync(string url, string password)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			if (!url.ToLower().StartsWith("ws://"))
			{
				throw new ArgumentException("Invalid url, must start with 'ws://'");
			}
			WatsonWsClient val = wsConnection;
			if (val != null && val.Connected)
			{
				Disconnect();
			}
			wsConnection = new WatsonWsClient(new Uri(url), default(Guid));
			wsConnection.MessageReceived += WebsocketMessageHandler;
			wsConnection.ServerDisconnected += OnWebsocketDisconnect;
			connectionPassword = password;
			wsConnection.Start();
		}

		public void Disconnect()
		{
			connectionPassword = null;
			if (wsConnection != null)
			{
				try
				{
					wsConnection.Stop(WebSocketCloseStatus.NormalClosure, "User requested disconnect");
					((IDisposable)wsConnection).Dispose();
				}
				catch
				{
				}
				wsConnection = null;
			}
			KeyValuePair<string, TaskCompletionSource<JObject>>[] array = responseHandlers.ToArray();
			responseHandlers.Clear();
			KeyValuePair<string, TaskCompletionSource<JObject>>[] array2 = array;
			foreach (KeyValuePair<string, TaskCompletionSource<JObject>> keyValuePair in array2)
			{
				keyValuePair.Value.TrySetCanceled();
			}
		}

		private void OnWebsocketDisconnect(object sender, EventArgs e)
		{
			this.Disconnected?.Invoke(sender, new ObsDisconnectionInfo(ObsCloseCodes.UnknownReason, null, null));
		}

		private void WebsocketMessageHandler(object sender, MessageReceivedEventArgs e)
		{
			if (e.MessageType != 0)
			{
				return;
			}
			ServerMessage serverMessage = JsonConvert.DeserializeObject<ServerMessage>(Encoding.UTF8.GetString(e.Data.Array));
			JObject body = serverMessage.Data;
			switch (serverMessage.OperationCode)
			{
			case MessageTypes.Hello:
				HandleHello(body);
				break;
			case MessageTypes.Identified:
				Task.Run(delegate
				{
					this.Connected?.Invoke(this, EventArgs.Empty);
				});
				break;
			case MessageTypes.RequestResponse:
			case MessageTypes.RequestBatchResponse:
				if (body.ContainsKey("requestId"))
				{
					string key = (string)body["requestId"];
					if (responseHandlers.TryRemove(key, out var value))
					{
						value.SetResult(body);
					}
				}
				break;
			case MessageTypes.Event:
			{
				string eventType = ((object)body["eventType"]).ToString();
				Task.Run(delegate
				{
					ProcessEventType(eventType, body);
				});
				break;
			}
			}
		}

		public JObject SendRequest(string requestType, JObject additionalFields = null)
		{
			return SendRequest(MessageTypes.Request, requestType, additionalFields);
		}

		internal JObject SendRequest(MessageTypes operationCode, string requestType, JObject additionalFields = null, bool waitForReply = true)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			if (wsConnection == null)
			{
				throw new NullReferenceException("Websocket is not initialized");
			}
			TaskCompletionSource<JObject> taskCompletionSource = new TaskCompletionSource<JObject>();
			JObject val = null;
			string messageId;
			do
			{
				val = MessageFactory.BuildMessage(operationCode, requestType, additionalFields, out messageId);
			}
			while (waitForReply && !responseHandlers.TryAdd(messageId, taskCompletionSource));
			wsConnection.SendAsync(((object)val).ToString(), WebSocketMessageType.Text, default(CancellationToken));
			if (!waitForReply)
			{
				return null;
			}
			taskCompletionSource.Task.Wait(wsTimeout.Milliseconds);
			if (taskCompletionSource.Task.IsCanceled)
			{
				throw new ErrorResponseException("Request canceled", 0);
			}
			JObject result = taskCompletionSource.Task.Result;
			if (!(bool)result["requestStatus"][(object)"result"])
			{
				JObject val2 = (JObject)result["requestStatus"];
				throw new ErrorResponseException(string.Format("ErrorCode: {0}{1}", val2["code"], val2.ContainsKey("comment") ? string.Format(", Comment: {0}", val2["comment"]) : ""), (int)val2["code"]);
			}
			if (result.ContainsKey("responseData"))
			{
				return result["responseData"].ToObject<JObject>();
			}
			return new JObject();
		}

		public OBSAuthInfo GetAuthInfo()
		{
			return new OBSAuthInfo(SendRequest("GetAuthRequired"));
		}

		protected void SendIdentify(string password, OBSAuthInfo authInfo = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("rpcVersion", JToken.op_Implicit(1));
			JObject val2 = val;
			if (authInfo != null)
			{
				string text = HashEncode(password + authInfo.PasswordSalt);
				string text2 = HashEncode(text + authInfo.Challenge);
				val2.Add("authentication", JToken.op_Implicit(text2));
			}
			SendRequest(MessageTypes.Identify, null, val2, waitForReply: false);
		}

		protected string HashEncode(string input)
		{
			using SHA256Managed sHA256Managed = new SHA256Managed();
			byte[] bytes = Encoding.ASCII.GetBytes(input);
			return Convert.ToBase64String(sHA256Managed.ComputeHash(bytes));
		}

		protected string NewMessageID(int length = 16)
		{
			string text = "";
			for (int i = 0; i < length; i++)
			{
				int index = random.Next(0, "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length - 1);
				text += "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[index];
			}
			return text;
		}

		private void HandleHello(JObject payload)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (wsConnection.Connected)
			{
				OBSAuthInfo authInfo = null;
				if (payload.ContainsKey("authentication"))
				{
					authInfo = new OBSAuthInfo((JObject)payload["authentication"]);
				}
				SendIdentify(connectionPassword, authInfo);
				connectionPassword = null;
			}
		}

		public ObsVideoSettings GetVideoSettings()
		{
			return JsonConvert.DeserializeObject<ObsVideoSettings>(((object)SendRequest("GetVideoSettings")).ToString());
		}

		public string SaveSourceScreenshot(string sourceName, string imageFormat, string imageFilePath, int imageWidth = -1, int imageHeight = -1, int imageCompressionQuality = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("imageFormat", JToken.op_Implicit(imageFormat));
			val.Add("imageFilePath", JToken.op_Implicit(imageFilePath));
			JObject val2 = val;
			if (imageWidth > -1)
			{
				val2.Add("imageWidth", JToken.op_Implicit(imageWidth));
			}
			if (imageHeight > -1)
			{
				val2.Add("imageHeight", JToken.op_Implicit(imageHeight));
			}
			if (imageCompressionQuality > -1)
			{
				val2.Add("imageCompressionQuality", JToken.op_Implicit(imageCompressionQuality));
			}
			return (string)SendRequest("SaveSourceScreenshot", val2)["imageData"];
		}

		public string SaveSourceScreenshot(string sourceName, string imageFormat, string imageFilePath)
		{
			return SaveSourceScreenshot(sourceName, imageFormat, imageFilePath, -1, -1, -1);
		}

		public void TriggerHotkeyByName(string hotkeyName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("hotkeyName", JToken.op_Implicit(hotkeyName));
			JObject additionalFields = val;
			SendRequest("TriggerHotkeyByName", additionalFields);
		}

		public void TriggerHotkeyByKeySequence(OBSHotkey keyId, KeyModifier keyModifier = KeyModifier.None)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_008a: Expected O, but got Unknown
			//IL_008b: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("keyId", JToken.op_Implicit(keyId.ToString()));
			JObject val2 = new JObject();
			val2.Add("shift", JToken.op_Implicit((keyModifier & KeyModifier.Shift) == KeyModifier.Shift));
			val2.Add("alt", JToken.op_Implicit((keyModifier & KeyModifier.Alt) == KeyModifier.Alt));
			val2.Add("control", JToken.op_Implicit((keyModifier & KeyModifier.Control) == KeyModifier.Control));
			val2.Add("command", JToken.op_Implicit((keyModifier & KeyModifier.Command) == KeyModifier.Command));
			val.Add("keyModifiers", (JToken)val2);
			JObject additionalFields = val;
			SendRequest("TriggerHotkeyByKeySequence", additionalFields);
		}

		public string GetCurrentProgramScene()
		{
			return (string)SendRequest("GetCurrentProgramScene")["currentProgramSceneName"];
		}

		public void SetCurrentProgramScene(string sceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			JObject additionalFields = val;
			SendRequest("SetCurrentProgramScene", additionalFields);
		}

		public ObsStats GetStats()
		{
			return JsonConvert.DeserializeObject<ObsStats>(((object)SendRequest("GetStats")).ToString());
		}

		public List<SceneBasicInfo> ListScenes()
		{
			return GetSceneList().Scenes;
		}

		public GetSceneListInfo GetSceneList()
		{
			return JsonConvert.DeserializeObject<GetSceneListInfo>(((object)SendRequest("GetSceneList")).ToString());
		}

		public TransitionOverrideInfo GetSceneSceneTransitionOverride(string sceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			JObject additionalFields = val;
			return ((JToken)SendRequest("GetSceneSceneTransitionOverride", additionalFields)).ToObject<TransitionOverrideInfo>();
		}

		public void SetSceneSceneTransitionOverride(string sceneName, string transitionName, int transitionDuration = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("transitionName", JToken.op_Implicit(transitionName));
			JObject val2 = val;
			if (transitionDuration >= 0)
			{
				val2.Add("transitionDuration", JToken.op_Implicit(transitionDuration));
			}
			SendRequest("SetSceneSceneTransitionOverride", val2);
		}

		public void SetTBarPosition(double position, bool release = true)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (position < 0.0 || position > 1.0)
			{
				throw new ArgumentOutOfRangeException("position");
			}
			JObject val = new JObject();
			val.Add("position", JToken.op_Implicit(position));
			val.Add("release", JToken.op_Implicit(release));
			JObject additionalFields = val;
			SendRequest("SetTBarPosition", additionalFields);
		}

		public void SetSourceFilterSettings(string sourceName, string filterName, JObject filterSettings, bool overlay = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			val.Add("filterSettings", (JToken)(object)filterSettings);
			val.Add("overlay", JToken.op_Implicit(overlay));
			JObject additionalFields = val;
			SendRequest("SetSourceFilterSettings", additionalFields);
		}

		public void SetSourceFilterSettings(string sourceName, string filterName, FilterSettings filterSettings, bool overlay = false)
		{
			SetSourceFilterSettings(sourceName, filterName, JObject.FromObject((object)filterSettings), overlay);
		}

		public void SetSourceFilterEnabled(string sourceName, string filterName, bool filterEnabled)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			val.Add("filterEnabled", JToken.op_Implicit(filterEnabled));
			JObject additionalFields = val;
			SendRequest("SetSourceFilterEnabled", additionalFields);
		}

		public List<FilterSettings> GetSourceFilterList(string sourceName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			JObject additionalFields = val;
			JObject val2 = SendRequest("GetSourceFilterList", additionalFields);
			if (!((JToken)val2).HasValues)
			{
				return new List<FilterSettings>();
			}
			return JsonConvert.DeserializeObject<List<FilterSettings>>(((object)val2["filters"]).ToString());
		}

		public FilterSettings GetSourceFilter(string sourceName, string filterName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			JObject additionalFields = val;
			return JsonConvert.DeserializeObject<FilterSettings>(((object)SendRequest("GetSourceFilter", additionalFields)).ToString());
		}

		public bool RemoveSourceFilter(string sourceName, string filterName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			JObject additionalFields = val;
			try
			{
				SendRequest("RemoveSourceFilter", additionalFields);
				return true;
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
			}
			return false;
		}

		public void CreateSourceFilter(string sourceName, string filterName, string filterKind, JObject filterSettings)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			val.Add("filterKind", JToken.op_Implicit(filterKind));
			val.Add("filterSettings", (JToken)(object)filterSettings);
			JObject additionalFields = val;
			SendRequest("CreateSourceFilter", additionalFields);
		}

		public void CreateSourceFilter(string sourceName, string filterName, string filterKind, FilterSettings filterSettings)
		{
			CreateSourceFilter(sourceName, filterName, filterKind, JObject.FromObject((object)filterSettings));
		}

		public bool ToggleStream()
		{
			return (bool)SendRequest("ToggleStream")["outputActive"];
		}

		public void ToggleRecord()
		{
			SendRequest("ToggleRecord");
		}

		public OutputStatus GetStreamStatus()
		{
			return new OutputStatus(SendRequest("GetStreamStatus"));
		}

		public TransitionSettings GetCurrentSceneTransition()
		{
			return new TransitionSettings(SendRequest("GetCurrentSceneTransition"));
		}

		public void SetCurrentSceneTransition(string transitionName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("transitionName", JToken.op_Implicit(transitionName));
			JObject additionalFields = val;
			SendRequest("SetCurrentSceneTransition", additionalFields);
		}

		public void SetCurrentSceneTransitionDuration(int transitionDuration)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("transitionDuration", JToken.op_Implicit(transitionDuration));
			JObject additionalFields = val;
			SendRequest("SetCurrentSceneTransitionDuration", additionalFields);
		}

		public void SetCurrentSceneTransitionSettings(JObject transitionSettings, bool overlay)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("transitionSettings", JToken.FromObject((object)transitionSettings));
			val.Add("overlay", JToken.op_Implicit(overlay));
			JObject additionalFields = val;
			SendRequest("SetCurrentSceneTransitionSettings", additionalFields);
		}

		public void SetInputVolume(string inputName, float inputVolume, bool inputVolumeDb = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject val2 = val;
			if (inputVolumeDb)
			{
				val2.Add("inputVolumeDb", JToken.op_Implicit(inputVolume));
			}
			else
			{
				val2.Add("inputVolumeMul", JToken.op_Implicit(inputVolume));
			}
			SendRequest("SetInputVolume", val2);
		}

		public VolumeInfo GetInputVolume(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return new VolumeInfo(SendRequest("GetInputVolume", additionalFields));
		}

		public bool GetInputMute(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return (bool)SendRequest("GetInputMute", additionalFields)["inputMuted"];
		}

		public void SetInputMute(string inputName, bool inputMuted)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("inputMuted", JToken.op_Implicit(inputMuted));
			JObject additionalFields = val;
			SendRequest("SetInputMute", additionalFields);
		}

		public void ToggleInputMute(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			SendRequest("ToggleInputMute", additionalFields);
		}

		public void SetSceneItemTransform(string sceneName, int sceneItemId, JObject sceneItemTransform)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0034: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			val.Add("sceneItemTransform", (JToken)(object)sceneItemTransform);
			JObject additionalFields = val;
			SendRequest("SetSceneItemTransform", additionalFields);
		}

		public void SetSceneItemTransform(string sceneName, int sceneItemId, SceneItemTransformInfo sceneItemTransform)
		{
			SetSceneItemTransform(sceneName, sceneItemId, JObject.FromObject((object)sceneItemTransform));
		}

		public void SetCurrentSceneCollection(string sceneCollectionName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneCollectionName", JToken.op_Implicit(sceneCollectionName));
			JObject additionalFields = val;
			SendRequest("SetCurrentSceneCollection", additionalFields);
		}

		public string GetCurrentSceneCollection()
		{
			return (string)SendRequest("GetSceneCollectionList")["currentSceneCollectionName"];
		}

		public List<string> GetSceneCollectionList()
		{
			return JsonConvert.DeserializeObject<List<string>>(((object)SendRequest("GetSceneCollectionList")["sceneCollections"]).ToString());
		}

		public void SetCurrentProfile(string profileName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("profileName", JToken.op_Implicit(profileName));
			JObject additionalFields = val;
			SendRequest("SetCurrentProfile", additionalFields);
		}

		public GetProfileListInfo GetProfileList()
		{
			return JsonConvert.DeserializeObject<GetProfileListInfo>(((object)SendRequest("GetProfileList")).ToString());
		}

		public void StartStream()
		{
			SendRequest("StartStream");
		}

		public void StopStream()
		{
			SendRequest("StopStream");
		}

		public void StartRecord()
		{
			SendRequest("StartRecord");
		}

		public string StopRecord()
		{
			return (string)SendRequest("StopRecord")["outputPath"];
		}

		public void PauseRecord()
		{
			SendRequest("PauseRecord");
		}

		public void ResumeRecord()
		{
			SendRequest("ResumeRecord");
		}

		public string GetRecordDirectory()
		{
			return (string)SendRequest("GetRecordDirectory")["recordDirectory"];
		}

		public RecordingStatus GetRecordStatus()
		{
			return JsonConvert.DeserializeObject<RecordingStatus>(((object)SendRequest("GetRecordStatus")).ToString());
		}

		public bool GetReplayBufferStatus()
		{
			return (bool)SendRequest("GetReplayBufferStatus")["outputActive"];
		}

		public GetTransitionListInfo GetSceneTransitionList()
		{
			return JsonConvert.DeserializeObject<GetTransitionListInfo>(((object)SendRequest("GetSceneTransitionList")).ToString());
		}

		public bool GetStudioModeEnabled()
		{
			return (bool)SendRequest("GetStudioModeEnabled")["studioModeEnabled"];
		}

		public void SetStudioModeEnabled(bool studioModeEnabled)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("studioModeEnabled", JToken.op_Implicit(studioModeEnabled));
			JObject additionalFields = val;
			SendRequest("SetStudioModeEnabled", additionalFields);
		}

		public string GetCurrentPreviewScene()
		{
			return (string)SendRequest("GetCurrentPreviewScene")["currentPreviewSceneName"];
		}

		public void SetCurrentPreviewScene(string sceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			JObject additionalFields = val;
			SendRequest("SetCurrentPreviewScene", additionalFields);
		}

		public void SetCurrentPreviewScene(ObsScene previewScene)
		{
			SetCurrentPreviewScene(previewScene.Name);
		}

		public void TriggerStudioModeTransition()
		{
			SendRequest("TriggerStudioModeTransition");
		}

		public void ToggleReplayBuffer()
		{
			SendRequest("ToggleReplayBuffer");
		}

		public void StartReplayBuffer()
		{
			SendRequest("StartReplayBuffer");
		}

		public void StopReplayBuffer()
		{
			SendRequest("StopReplayBuffer");
		}

		public void SaveReplayBuffer()
		{
			SendRequest("SaveReplayBuffer");
		}

		public void SetInputAudioSyncOffset(string inputName, int inputAudioSyncOffset)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("inputAudioSyncOffset", JToken.op_Implicit(inputAudioSyncOffset));
			JObject additionalFields = val;
			SendRequest("SetInputAudioSyncOffset", additionalFields);
		}

		public int GetInputAudioSyncOffset(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return (int)SendRequest("GetInputAudioSyncOffset", additionalFields)["inputAudioSyncOffset"];
		}

		public void RemoveSceneItem(string sceneName, int sceneItemId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject additionalFields = val;
			SendRequest("RemoveSceneItem", additionalFields);
		}

		public void SendStreamCaption(string captionText)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("captionText", JToken.op_Implicit(captionText));
			JObject additionalFields = val;
			SendRequest("SendStreamCaption", additionalFields);
		}

		public void DuplicateSceneItem(string sceneName, int sceneItemId, string destinationSceneName = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject val2 = val;
			if (!string.IsNullOrEmpty(destinationSceneName))
			{
				val2.Add("destinationSceneName", JToken.op_Implicit(destinationSceneName));
			}
			SendRequest("DuplicateSceneItem", val2);
		}

		public Dictionary<string, string> GetSpecialInputs()
		{
			JObject obj = SendRequest("GetSpecialInputs");
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (KeyValuePair<string, JToken> item in obj)
			{
				string key = item.Key;
				string value = (string)item.Value;
				if (key != "requestType")
				{
					dictionary.Add(key, value);
				}
			}
			return dictionary;
		}

		public void SetStreamServiceSettings(StreamingService service)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("streamServiceType", JToken.op_Implicit(service.Type));
			val.Add("streamServiceSettings", JToken.FromObject((object)service.Settings));
			JObject additionalFields = val;
			SendRequest("SetStreamServiceSettings", additionalFields);
		}

		public StreamingService GetStreamServiceSettings()
		{
			return JsonConvert.DeserializeObject<StreamingService>(((object)SendRequest("GetStreamServiceSettings")).ToString());
		}

		public string GetInputAudioMonitorType(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return (string)SendRequest("GetInputAudioMonitorType", additionalFields)["monitorType"];
		}

		public void SetInputAudioMonitorType(string inputName, string monitorType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("monitorType", JToken.op_Implicit(monitorType));
			JObject additionalFields = val;
			SendRequest("SetInputAudioMonitorType", additionalFields);
		}

		public void BroadcastCustomEvent(JObject eventData)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("eventData", (JToken)(object)eventData);
			JObject additionalFields = val;
			SendRequest("BroadcastCustomEvent", additionalFields);
		}

		public void SetMediaInputCursor(string inputName, int mediaCursor)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("mediaCursor", JToken.op_Implicit(mediaCursor));
			JObject additionalFields = val;
			SendRequest("SetMediaInputCursor", additionalFields);
		}

		public void OffsetMediaInputCursor(string inputName, int mediaCursorOffset)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("mediaCursorOffset", JToken.op_Implicit(mediaCursorOffset));
			JObject additionalFields = val;
			SendRequest("OffsetMediaInputCursor", additionalFields);
		}

		public int CreateInput(string sceneName, string inputName, string inputKind, JObject inputSettings, bool? sceneItemEnabled)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("inputKind", JToken.op_Implicit(inputKind));
			JObject val2 = val;
			if (inputSettings != null)
			{
				val2.Add("inputSettings", (JToken)(object)inputSettings);
			}
			if (sceneItemEnabled.HasValue)
			{
				val2.Add("sceneItemEnabled", JToken.op_Implicit(sceneItemEnabled.Value));
			}
			return (int)SendRequest("CreateInput", val2)["sceneItemId"];
		}

		public JObject GetInputDefaultSettings(string inputKind)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputKind", JToken.op_Implicit(inputKind));
			JObject additionalFields = val;
			return (JObject)SendRequest("GetInputDefaultSettings", additionalFields)["defaultInputSettings"];
		}

		public List<SceneItemDetails> GetSceneItemList(string sceneName)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			JObject additionalFields = null;
			if (!string.IsNullOrEmpty(sceneName))
			{
				JObject val = new JObject();
				val.Add("sceneName", JToken.op_Implicit(sceneName));
				additionalFields = val;
			}
			return ((IEnumerable<JToken>)SendRequest("GetSceneItemList", additionalFields)["sceneItems"]).Select((JToken m) => new SceneItemDetails((JObject)m)).ToList();
		}

		public int CreateSceneItem(string sceneName, string sourceName, bool sceneItemEnabled = true)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("sceneItemEnabled", JToken.op_Implicit(sceneItemEnabled));
			JObject additionalFields = val;
			return (int)SendRequest("CreateSceneItem", additionalFields)["sceneItemId"];
		}

		public void CreateScene(string sceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			JObject additionalFields = val;
			SendRequest("CreateScene", additionalFields);
		}

		public SourceTracks GetInputAudioTracks(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return new SourceTracks(SendRequest("GetInputAudioTracks", additionalFields));
		}

		public void SetInputAudioTracks(string inputName, JObject inputAudioTracks)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("inputAudioTracks", (JToken)(object)inputAudioTracks);
			JObject additionalFields = val;
			SendRequest("SetInputAudioTracks", additionalFields);
		}

		public void SetInputAudioTracks(string inputName, SourceTracks inputAudioTracks)
		{
			SetInputAudioTracks(inputName, JObject.FromObject((object)inputAudioTracks));
		}

		public SourceActiveInfo GetSourceActive(string sourceName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			JObject additionalFields = val;
			return new SourceActiveInfo(SendRequest("GetSourceActive", additionalFields));
		}

		public VirtualCamStatus GetVirtualCamStatus()
		{
			return new VirtualCamStatus(SendRequest("GetVirtualCamStatus"));
		}

		public void StartVirtualCam()
		{
			SendRequest("StartVirtualCam");
		}

		public void StopVirtualCam()
		{
			SendRequest("StopVirtualCam");
		}

		public VirtualCamStatus ToggleVirtualCam()
		{
			return new VirtualCamStatus(SendRequest("ToggleVirtualCam"));
		}

		public JObject GetPersistentData(string realm, string slotName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("realm", JToken.op_Implicit(realm));
			val.Add("slotName", JToken.op_Implicit(slotName));
			JObject additionalFields = val;
			return SendRequest("GetPersistentData", additionalFields);
		}

		public void SetPersistentData(string realm, string slotName, JObject slotValue)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0034: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("realm", JToken.op_Implicit(realm));
			val.Add("slotName", JToken.op_Implicit(slotName));
			val.Add("slotValue", (JToken)(object)slotValue);
			JObject additionalFields = val;
			SendRequest("SetPersistentData", additionalFields);
		}

		public void CreateSceneCollection(string sceneCollectionName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneCollectionName", JToken.op_Implicit(sceneCollectionName));
			JObject additionalFields = val;
			SendRequest("CreateSceneCollection", additionalFields);
		}

		public void CreateProfile(string profileName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("profileName", JToken.op_Implicit(profileName));
			JObject additionalFields = val;
			SendRequest("CreateProfile", additionalFields);
		}

		public void RemoveProfile(string profileName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("profileName", JToken.op_Implicit(profileName));
			JObject additionalFields = val;
			SendRequest("RemoveProfile", additionalFields);
		}

		public JObject GetProfileParameter(string parameterCategory, string parameterName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("parameterCategory", JToken.op_Implicit(parameterCategory));
			val.Add("parameterName", JToken.op_Implicit(parameterName));
			JObject additionalFields = val;
			return SendRequest("GetProfileParameter", additionalFields);
		}

		public void SetProfileParameter(string parameterCategory, string parameterName, string parameterValue)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("parameterCategory", JToken.op_Implicit(parameterCategory));
			val.Add("parameterName", JToken.op_Implicit(parameterName));
			val.Add("parameterValue", JToken.op_Implicit(parameterValue));
			JObject additionalFields = val;
			SendRequest("SetProfileParameter", additionalFields);
		}

		public void SetVideoSettings(ObsVideoSettings obsVideoSettings)
		{
			SendRequest("SetVideoSettings", JObject.FromObject((object)obsVideoSettings));
		}

		public JObject GetSourceFilterDefaultSettings(string filterKind)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("filterKind", JToken.op_Implicit(filterKind));
			JObject additionalFields = val;
			return SendRequest("GetSourceFilterDefaultSettings", additionalFields);
		}

		public void SetSourceFilterName(string sourceName, string filterName, string newFilterName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			val.Add("newFilterName", JToken.op_Implicit(newFilterName));
			JObject additionalFields = val;
			SendRequest("SetSourceFilterName", additionalFields);
		}

		public void SetSourceFilterIndex(string sourceName, string filterName, int filterIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("filterName", JToken.op_Implicit(filterName));
			val.Add("filterIndex", JToken.op_Implicit(filterIndex));
			JObject additionalFields = val;
			SendRequest("SetSourceFilterIndex", additionalFields);
		}

		public ObsVersion GetVersion()
		{
			return new ObsVersion(SendRequest("GetVersion"));
		}

		public JObject CallVendorRequest(string vendorName, string requestType, JObject requestData = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0034: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("vendorName", JToken.op_Implicit(vendorName));
			val.Add("requestType", JToken.op_Implicit(requestType));
			val.Add("requestData", (JToken)(object)requestData);
			JObject additionalFields = val;
			return SendRequest("CallVendorRequest", additionalFields);
		}

		public List<string> GetHotkeyList()
		{
			return JsonConvert.DeserializeObject<List<string>>(((object)SendRequest("GetHotkeyList")["hotkeys"]).ToString());
		}

		public void Sleep(int sleepMillis, int sleepFrames)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sleepMillis", JToken.op_Implicit(sleepMillis));
			val.Add("sleepFrames", JToken.op_Implicit(sleepFrames));
			JObject additionalFields = val;
			SendRequest("Sleep", additionalFields);
		}

		public List<InputBasicInfo> GetInputList(string inputKind = null)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputKind", JToken.op_Implicit(inputKind));
			JObject additionalFields = val;
			JObject obj = ((inputKind == null) ? SendRequest("GetInputList") : SendRequest("GetInputList", additionalFields));
			List<InputBasicInfo> list = new List<InputBasicInfo>();
			foreach (JToken item in (IEnumerable<JToken>)obj["inputs"])
			{
				list.Add(new InputBasicInfo((JObject)(object)((item is JObject) ? item : null)));
			}
			return list;
		}

		public List<string> GetInputKindList(bool unversioned = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("unversioned", JToken.op_Implicit(unversioned));
			JObject additionalFields = val;
			return JsonConvert.DeserializeObject<List<string>>(((object)((!unversioned) ? SendRequest("GetInputKindList") : SendRequest("GetInputKindList", additionalFields))["inputKinds"]).ToString());
		}

		public void RemoveInput(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			SendRequest("RemoveInput", additionalFields);
		}

		public void SetInputName(string inputName, string newInputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("newInputName", JToken.op_Implicit(newInputName));
			JObject additionalFields = val;
			SendRequest("SetInputName", additionalFields);
		}

		public InputSettings GetInputSettings(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject val2 = val;
			JObject obj = SendRequest("GetInputSettings", val2);
			((JContainer)obj).Merge((object)val2);
			return new InputSettings(obj);
		}

		public void SetInputSettings(InputSettings inputSettings, bool overlay = true)
		{
			SetInputSettings(inputSettings.InputName, inputSettings.Settings, overlay);
		}

		public void SetInputSettings(string inputName, JObject inputSettings, bool overlay = true)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0034: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("inputSettings", (JToken)(object)inputSettings);
			val.Add("overlay", JToken.op_Implicit(overlay));
			JObject additionalFields = val;
			SendRequest("SetInputSettings", additionalFields);
		}

		public double GetInputAudioBalance(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return (double)SendRequest("GetInputAudioBalance", additionalFields)["inputAudioBalance"];
		}

		public void SetInputAudioBalance(string inputName, double inputAudioBalance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("inputAudioBalance", JToken.op_Implicit(inputAudioBalance));
			JObject additionalFields = val;
			SendRequest("SetInputAudioBalance", additionalFields);
		}

		public List<JObject> GetInputPropertiesListPropertyItems(string inputName, string propertyName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("propertyName", JToken.op_Implicit(propertyName));
			JObject additionalFields = val;
			return Extensions.Value<List<JObject>>((IEnumerable<JToken>)SendRequest("GetInputPropertiesListPropertyItems", additionalFields)["propertyItems"]);
		}

		public void PressInputPropertiesButton(string inputName, string propertyName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("propertyName", JToken.op_Implicit(propertyName));
			JObject additionalFields = val;
			SendRequest("PressInputPropertiesButton", additionalFields);
		}

		public MediaInputStatus GetMediaInputStatus(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			return new MediaInputStatus(SendRequest("GetMediaInputStatus", additionalFields));
		}

		public void TriggerMediaInputAction(string inputName, string mediaAction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			val.Add("mediaAction", JToken.op_Implicit(mediaAction));
			JObject additionalFields = val;
			SendRequest("TriggerMediaInputAction", additionalFields);
		}

		public string GetLastReplayBufferReplay()
		{
			return (string)SendRequest("GetLastReplayBufferReplay")["savedReplayPath"];
		}

		public void ToggleRecordPause()
		{
			SendRequest("ToggleRecordPause");
		}

		public List<JObject> GetGroupSceneItemList(string sceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			JObject additionalFields = val;
			return JsonConvert.DeserializeObject<List<JObject>>((string)SendRequest("GetGroupSceneItemList", additionalFields)["sceneItems"]);
		}

		public int GetSceneItemId(string sceneName, string sourceName, int searchOffset)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("searchOffset", JToken.op_Implicit(searchOffset));
			JObject additionalFields = val;
			return (int)SendRequest("GetSceneItemId", additionalFields)["sceneItemId"];
		}

		public SceneItemTransformInfo GetSceneItemTransform(string sceneName, int sceneItemId)
		{
			return JsonConvert.DeserializeObject<SceneItemTransformInfo>(((object)GetSceneItemTransformRaw(sceneName, sceneItemId)["sceneItemTransform"]).ToString());
		}

		public JObject GetSceneItemTransformRaw(string sceneName, int sceneItemId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject additionalFields = val;
			return SendRequest("GetSceneItemTransform", additionalFields);
		}

		public bool GetSceneItemEnabled(string sceneName, int sceneItemId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject additionalFields = val;
			return (bool)SendRequest("GetSceneItemEnabled", additionalFields)["sceneItemEnabled"];
		}

		public void SetSceneItemEnabled(string sceneName, int sceneItemId, bool sceneItemEnabled)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			val.Add("sceneItemEnabled", JToken.op_Implicit(sceneItemEnabled));
			JObject additionalFields = val;
			SendRequest("SetSceneItemEnabled", additionalFields);
		}

		public bool GetSceneItemLocked(string sceneName, int sceneItemId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject additionalFields = val;
			return (bool)SendRequest("GetSceneItemLocked", additionalFields)["sceneItemLocked"];
		}

		public void SetSceneItemLocked(string sceneName, int sceneItemId, bool sceneItemLocked)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			val.Add("sceneItemLocked", JToken.op_Implicit(sceneItemLocked));
			JObject additionalFields = val;
			SendRequest("SetSceneItemLocked", additionalFields);
		}

		public int GetSceneItemIndex(string sceneName, int sceneItemId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject additionalFields = val;
			return (int)SendRequest("GetSceneItemIndex", additionalFields)["sceneItemIndex"];
		}

		public void SetSceneItemIndex(string sceneName, int sceneItemId, int sceneItemIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			val.Add("sceneItemIndex", JToken.op_Implicit(sceneItemIndex));
			JObject additionalFields = val;
			SendRequest("SetSceneItemIndex", additionalFields);
		}

		public string GetSceneItemBlendMode(string sceneName, int sceneItemId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			JObject additionalFields = val;
			return (string)SendRequest("GetSceneItemBlendMode", additionalFields)["sceneItemBlendMode"];
		}

		public void SetSceneItemBlendMode(string sceneName, int sceneItemId, string sceneItemBlendMode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("sceneItemId", JToken.op_Implicit(sceneItemId));
			val.Add("sceneItemBlendMode", JToken.op_Implicit(sceneItemBlendMode));
			JObject additionalFields = val;
			SendRequest("SetSceneItemBlendMode", additionalFields);
		}

		public List<string> GetGroupList()
		{
			return JsonConvert.DeserializeObject<List<string>>(((object)SendRequest("GetGroupList")["groups"]).ToString());
		}

		public void RemoveScene(string sceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			JObject additionalFields = val;
			SendRequest("RemoveScene", additionalFields);
		}

		public void SetSceneName(string sceneName, string newSceneName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sceneName", JToken.op_Implicit(sceneName));
			val.Add("newSceneName", JToken.op_Implicit(newSceneName));
			JObject additionalFields = val;
			SendRequest("SetSceneName", additionalFields);
		}

		public string GetSourceScreenshot(string sourceName, string imageFormat, int imageWidth = -1, int imageHeight = -1, int imageCompressionQuality = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("imageFormat", JToken.op_Implicit(imageFormat));
			JObject val2 = val;
			if (imageWidth > -1)
			{
				val2.Add("imageWidth", JToken.op_Implicit(imageWidth));
			}
			if (imageHeight > -1)
			{
				val2.Add("imageHeight", JToken.op_Implicit(imageHeight));
			}
			if (imageCompressionQuality > -1)
			{
				val2.Add("imageCompressionQuality", JToken.op_Implicit(imageCompressionQuality));
			}
			return (string)SendRequest("GetSourceScreenshot", val2)["imageData"];
		}

		public List<string> GetTransitionKindList()
		{
			return JsonConvert.DeserializeObject<List<string>>(((object)SendRequest("GetTransitionKindList")["transitionKinds"]).ToString());
		}

		public double GetCurrentSceneTransitionCursor()
		{
			return (double)SendRequest("GetCurrentSceneTransitionCursor")["transitionCursor"];
		}

		public void OpenInputPropertiesDialog(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			SendRequest("OpenInputPropertiesDialog", additionalFields);
		}

		public void OpenInputFiltersDialog(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			SendRequest("OpenInputFiltersDialog", additionalFields);
		}

		public void OpenInputInteractDialog(string inputName)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("inputName", JToken.op_Implicit(inputName));
			JObject additionalFields = val;
			SendRequest("OpenInputInteractDialog", additionalFields);
		}

		public List<OBSWebsocketDotNet.Types.Monitor> GetMonitorList()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			JObject obj = SendRequest("GetMonitorList");
			List<OBSWebsocketDotNet.Types.Monitor> list = new List<OBSWebsocketDotNet.Types.Monitor>();
			foreach (JToken item in (IEnumerable<JToken>)obj["monitors"])
			{
				list.Add(new OBSWebsocketDotNet.Types.Monitor((JObject)item));
			}
			return list;
		}

		public void OpenSourceProjector(string sourceName, string projectorGeometry, int monitorIndex = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("sourceName", JToken.op_Implicit(sourceName));
			val.Add("projectorGeometry", JToken.op_Implicit(projectorGeometry));
			val.Add("monitorIndex", JToken.op_Implicit(monitorIndex));
			JObject additionalFields = val;
			SendRequest("OpenSourceProjector", additionalFields);
		}

		public void OpenVideoMixProjector(string videoMixType, string projectorGeometry, int monitorIndex = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0039: Expected O, but got Unknown
			JObject val = new JObject();
			val.Add("videoMixType", JToken.op_Implicit(videoMixType));
			val.Add("projectorGeometry", JToken.op_Implicit(projectorGeometry));
			val.Add("monitorIndex", JToken.op_Implicit(monitorIndex));
			JObject additionalFields = val;
			SendRequest("OpenVideoMixProjector", additionalFields);
		}
	}
	public class AuthFailureException : Exception
	{
	}
	public class ErrorResponseException : Exception
	{
		public int ErrorCode { get; set; }

		public ErrorResponseException(string message, int errorCode)
			: base(message)
		{
			ErrorCode = errorCode;
		}
	}
	public interface IOBSWebsocket
	{
		TimeSpan WSTimeout { get; set; }

		bool IsConnected { get; }

		event EventHandler<ProgramSceneChangedEventArgs> CurrentProgramSceneChanged;

		event EventHandler<SceneListChangedEventArgs> SceneListChanged;

		event EventHandler<SceneItemListReindexedEventArgs> SceneItemListReindexed;

		event EventHandler<SceneItemCreatedEventArgs> SceneItemCreated;

		event EventHandler<SceneItemRemovedEventArgs> SceneItemRemoved;

		event EventHandler<SceneItemEnableStateChangedEventArgs> SceneItemEnableStateChanged;

		event EventHandler<SceneItemLockStateChangedEventArgs> SceneItemLockStateChanged;

		event EventHandler<CurrentSceneCollectionChangedEventArgs> CurrentSceneCollectionChanged;

		event EventHandler<SceneCollectionListChangedEventArgs> SceneCollectionListChanged;

		event EventHandler<CurrentSceneTransitionChangedEventArgs> CurrentSceneTransitionChanged;

		event EventHandler<CurrentSceneTransitionDurationChangedEventArgs> CurrentSceneTransitionDurationChanged;

		event EventHandler<SceneTransitionStartedEventArgs> SceneTransitionStarted;

		event EventHandler<SceneTransitionEndedEventArgs> SceneTransitionEnded;

		event EventHandler<SceneTransitionVideoEndedEventArgs> SceneTransitionVideoEnded;

		event EventHandler<CurrentProfileChangedEventArgs> CurrentProfileChanged;

		event EventHandler<ProfileListChangedEventArgs> ProfileListChanged;

		event EventHandler<StreamStateChangedEventArgs> StreamStateChanged;

		event EventHandler<RecordStateChangedEventArgs> RecordStateChanged;

		event EventHandler<ReplayBufferStateChangedEventArgs> ReplayBufferStateChanged;

		event EventHandler<CurrentPreviewSceneChangedEventArgs> CurrentPreviewSceneChanged;

		event EventHandler<StudioModeStateChangedEventArgs> StudioModeStateChanged;

		event EventHandler ExitStarted;

		event EventHandler Connected;

		event EventHandler<ObsDisconnectionInfo> Disconnected;

		event EventHandler<SceneItemSelectedEventArgs> SceneItemSelected;

		event EventHandler<SceneItemTransformEventArgs> SceneItemTransformChanged;

		event EventHandler<InputAudioSyncOffsetChangedEventArgs> InputAudioSyncOffsetChanged;

		event EventHandler<SourceFilterCreatedEventArgs> SourceFilterCreated;

		event EventHandler<SourceFilterRemovedEventArgs> SourceFilterRemoved;

		event EventHandler<SourceFilterListReindexedEventArgs> SourceFilterListReindexed;

		event EventHandler<SourceFilterEnableStateChangedEventArgs> SourceFilterEnableStateChanged;

		event EventHandler<InputMuteStateChangedEventArgs> InputMuteStateChanged;

		event EventHandler<InputVolumeChangedEventArgs> InputVolumeChanged;

		event EventHandler<VendorEventArgs> VendorEvent;

		event EventHandler<MediaInputPlaybackEndedEventArgs> MediaInputPlaybackEnded;

		event EventHandler<MediaInputPlaybackStartedEventArgs> MediaInputPlaybackStarted;

		event EventHandler<MediaInputActionTriggeredEventArgs> MediaInputActionTriggered;

		event EventHandler<VirtualcamStateChangedEventArgs> VirtualcamStateChanged;

		event EventHandler<CurrentSceneCollectionChangingEventArgs> CurrentSceneCollectionChanging;

		event EventHandler<CurrentProfileChangingEventArgs> CurrentProfileChanging;

		event EventHandler<SourceFilterNameChangedEventArgs> SourceFilterNameChanged;

		event EventHandler<InputCreatedEventArgs> InputCreated;

		event EventHandler<InputRemovedEventArgs> InputRemoved;

		event EventHandler<InputNameChangedEventArgs> InputNameChanged;

		event EventHandler<InputActiveStateChangedEventArgs> InputActiveStateChanged;

		event EventHandler<InputShowStateChangedEventArgs> InputShowStateChanged;

		event EventHandler<InputAudioBalanceChangedEventArgs> InputAudioBalanceChanged;

		event EventHandler<InputAudioTracksChangedEventArgs> InputAudioTracksChanged;

		event EventHandler<InputAudioMonitorTypeChangedEventArgs> InputAudioMonitorTypeChanged;

		event EventHandler<InputVolumeMetersEventArgs> InputVolumeMeters;

		event EventHandler<ReplayBufferSavedEventArgs> ReplayBufferSaved;

		event EventHandler<SceneCreatedEventArgs> SceneCreated;

		event EventHandler<SceneRemovedEventArgs> SceneRemoved;

		event EventHandler<SceneNameChangedEventArgs> SceneNameChanged;

		ObsVideoSettings GetVideoSettings();

		string SaveSourceScreenshot(string sourceName, string imageFormat, string imageFilePath, int imageWidth = -1, int imageHeight = -1, int imageCompressionQuality = -1);

		string SaveSourceScreenshot(string sourceName, string imageFormat, string imageFilePath);

		void TriggerHotkeyByName(string hotkeyName);

		void TriggerHotkeyByKeySequence(OBSHotkey keyId, KeyModifier keyModifier = KeyModifier.None);

		string GetCurrentProgramScene();

		void SetCurrentProgramScene(string sceneName);

		ObsStats GetStats();

		List<SceneBasicInfo> ListScenes();

		GetSceneListInfo GetSceneList();

		TransitionOverrideInfo GetSceneSceneTransitionOverride(string sceneName);

		void SetSceneSceneTransitionOverride(string sceneName, string transitionName, int transitionDuration = -1);

		void SetTBarPosition(double position, bool release = true);

		void SetSourceFilterSettings(string sourceName, string filterName, JObject filterSettings, bool overlay = false);

		void SetSourceFilterSettings(string sourceName, string filterName, FilterSettings filterSettings, bool overlay = false);

		void SetSourceFilterEnabled(string sourceName, string filterName, bool filterEnabled);

		List<FilterSettings> GetSourceFilterList(string sourceName);

		FilterSettings GetSourceFilter(string sourceName, string filterName);

		bool RemoveSourceFilter(string sourceName, string filterName);

		void CreateSourceFilter(string sourceName, string filterName, string filterKind, JObject filterSettings);

		void CreateSourceFilter(string sourceName, string filterName, string filterKind, FilterSettings filterSettings);

		bool ToggleStream();

		void ToggleRecord();

		OutputStatus GetStreamStatus();

		TransitionSettings GetCurrentSceneTransition();

		void SetCurrentSceneTransition(string transitionName);

		void SetCurrentSceneTransitionDuration(int transitionDuration);

		void SetCurrentSceneTransitionSettings(JObject transitionSettings, bool overlay);

		void SetInputVolume(string inputName, float inputVolume, bool inputVolumeDb = false);

		VolumeInfo GetInputVolume(string inputName);

		bool GetInputMute(string inputName);

		void SetInputMute(string inputName, bool inputMuted);

		void ToggleInputMute(string inputName);

		void SetSceneItemTransform(string sceneName, int sceneItemId, JObject sceneItemTransform);

		void SetSceneItemTransform(string sceneName, int sceneItemId, SceneItemTransformInfo sceneItemTransform);

		void SetCurrentSceneCollection(string sceneCollectionName);

		string GetCurrentSceneCollection();

		List<string> GetSceneCollectionList();

		void SetCurrentProfile(string profileName);

		GetProfileListInfo GetProfileList();

		void StartStream();

		void StopStream();

		void StartRecord();

		string StopRecord();

		void PauseRecord();

		void ResumeRecord();

		string GetRecordDirectory();

		RecordingStatus GetRecordStatus();

		bool GetReplayBufferStatus();

		GetTransitionListInfo GetSceneTransitionList();

		bool GetStudioModeEnabled();

		void SetStudioModeEnabled(bool studioModeEnabled);

		string GetCurrentPreviewScene();

		void SetCurrentPreviewScene(string sceneName);

		void SetCurrentPreviewScene(ObsScene previewScene);

		void TriggerStudioModeTransition();

		void ToggleReplayBuffer();

		void StartReplayBuffer();

		void StopReplayBuffer();

		void SaveReplayBuffer();

		void SetInputAudioSyncOffset(string inputName, int inputAudioSyncOffset);

		int GetInputAudioSyncOffset(string inputName);

		void RemoveSceneItem(string sceneName, int sceneItemId);

		void SendStreamCaption(string captionText);

		void DuplicateSceneItem(string sceneName, int sceneItemId, string destinationSceneName = null);

		Dictionary<string, string> GetSpecialInputs();

		void SetStreamServiceSettings(StreamingService service);

		StreamingService GetStreamServiceSettings();

		string GetInputAudioMonitorType(string inputName);

		void SetInputAudioMonitorType(string inputName, string monitorType);

		void BroadcastCustomEvent(JObject eventData);

		void SetMediaInputCursor(string inputName, int mediaCursor);

		void OffsetMediaInputCursor(string inputName, int mediaCursorOffset);

		int CreateInput(string sceneName, string inputName, string inputKind, JObject inputSettings, bool? sceneItemEnabled);

		JObject GetInputDefaultSettings(string inputKind);

		List<SceneItemDetails> GetSceneItemList(string sceneName);

		int CreateSceneItem(string sceneName, string sourceName, bool sceneItemEnabled = true);

		void CreateScene(string sceneName);

		SourceTracks GetInputAudioTracks(string inputName);

		void SetInputAudioTracks(string inputName, JObject inputAudioTracks);

		void SetInputAudioTracks(string inputName, SourceTracks inputAudioTracks);

		SourceActiveInfo GetSourceActive(string sourceName);

		VirtualCamStatus GetVirtualCamStatus();

		void StartVirtualCam();

		void StopVirtualCam();

		VirtualCamStatus ToggleVirtualCam();

		JObject GetPersistentData(string realm, string slotName);

		void SetPersistentData(string realm, string slotName, JObject slotValue);

		void CreateSceneCollection(string sceneCollectionName);

		void CreateProfile(string profileName);

		void RemoveProfile(string profileName);

		JObject GetProfileParameter(string parameterCategory, string parameterName);

		void SetProfileParameter(string parameterCategory, string parameterName, string parameterValue);

		void SetVideoSettings(ObsVideoSettings obsVideoSettings);

		JObject GetSourceFilterDefaultSettings(string filterKind);

		void SetSourceFilterName(string sourceName, string filterName, string newFilterName);

		void SetSourceFilterIndex(string sourceName, string filterName, int filterIndex);

		ObsVersion GetVersion();

		JObject CallVendorRequest(string vendorName, string requestType, JObject requestData = null);

		List<string> GetHotkeyList();

		void Sleep(int sleepMillis, int sleepFrames);

		List<InputBasicInfo> GetInputList(string inputKind = null);

		List<string> GetInputKindList(bool unversioned = false);

		void RemoveInput(string inputName);

		void SetInputName(string inputName, string newInputName);

		InputSettings GetInputSettings(string inputName);

		void SetInputSettings(InputSettings inputSettings, bool overlay = true);

		void SetInputSettings(string inputName, JObject inputSettings, bool overlay = true);

		double GetInputAudioBalance(string inputName);

		void SetInputAudioBalance(string inputName, double inputAudioBalance);

		List<JObject> GetInputPropertiesListPropertyItems(string inputName, string propertyName);

		void PressInputPropertiesButton(string inputName, string propertyName);

		MediaInputStatus GetMediaInputStatus(string inputName);

		void TriggerMediaInputAction(string inputName, string mediaAction);

		string GetLastReplayBufferReplay();

		void ToggleRecordPause();

		List<JObject> GetGroupSceneItemList(string sceneName);

		int GetSceneItemId(string sceneName, string sourceName, int searchOffset);

		SceneItemTransformInfo GetSceneItemTransform(string sceneName, int sceneItemId);

		JObject GetSceneItemTransformRaw(string sceneName, int sceneItemId);

		bool GetSceneItemEnabled(string sceneName, int sceneItemId);

		void SetSceneItemEnabled(string sceneName, int sceneItemId, bool sceneItemEnabled);

		bool GetSceneItemLocked(string sceneName, int sceneItemId);

		void SetSceneItemLocked(string sceneName, int sceneItemId, bool sceneItemLocked);

		int GetSceneItemIndex(string sceneName, int sceneItemId);

		void SetSceneItemIndex(string sceneName, int sceneItemId, int sceneItemIndex);

		string GetSceneItemBlendMode(string sceneName, int sceneItemId);

		void SetSceneItemBlendMode(string sceneName, int sceneItemId, string sceneItemBlendMode);

		List<string> GetGroupList();

		void RemoveScene(string sceneName);

		void SetSceneName(string sceneName, string newSceneName);

		string GetSourceScreenshot(string sourceName, string imageFormat, int imageWidth = -1, int imageHeight = -1, int imageCompressionQuality = -1);

		List<string> GetTransitionKindList();

		double GetCurrentSceneTransitionCursor();

		void OpenInputPropertiesDialog(string inputName);

		void OpenInputFiltersDialog(string inputName);

		void OpenInputInteractDialog(string inputName);

		List<OBSWebsocketDotNet.Types.Monitor> GetMonitorList();

		[Obsolete("Please use ConnectAsync, this function will be removed in the next version")]
		void Connect(string url, string password);

		void ConnectAsync(string url, string password);

		void Disconnect();

		JObject SendRequest(string requestType, JObject additionalFields = null);

		OBSAuthInfo GetAuthInfo();
	}
}
namespace OBSWebsocketDotNet.Types
{
	public class FilterReorderItem
	{
		[JsonProperty(PropertyName = "name")]
		public string Name { get; set; }

		[JsonProperty(PropertyName = "type")]
		public string Type { get; set; }
	}
	public class FilterSettings
	{
		[JsonProperty(PropertyName = "filterName")]
		public string Name { get; set; }

		[JsonProperty(PropertyName = "filterKind")]
		public string Kind { get; set; }

		[JsonProperty(PropertyName = "filterIndex")]
		public int Index { get; set; }

		[JsonProperty(PropertyName = "filterEnabled")]
		public bool IsEnabled { get; set; }

		[JsonProperty(PropertyName = "filterSettings")]
		public JObject Settings { get; set; }

UserLibs/WatsonWebsocket.dll

Decompiled a month ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Joel Christner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("(c)2024 Joel Christner")]
[assembly: AssemblyDescription("WatsonWebsocket is the EASIEST and FASTEST way to build client and server applications that rely on messaging using websockets.  It's.  Really.  Easy.")]
[assembly: AssemblyFileVersion("4.1.1.0")]
[assembly: AssemblyInformationalVersion("4.1.1+1791f31fa2f3895720a9f430d3dc778ff6633c33")]
[assembly: AssemblyProduct("WatsonWebsocket")]
[assembly: AssemblyTitle("WatsonWebsocket")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/jchristn/WatsonWebsocket")]
[assembly: AssemblyVersion("4.1.1.0")]
namespace WatsonWebsocket;

public class ClientMetadata
{
	private int _Port;

	internal HttpListenerContext HttpContext;

	internal WebSocket Ws;

	internal WebSocketContext WsContext;

	internal readonly CancellationTokenSource TokenSource;

	internal readonly SemaphoreSlim SendLock = new SemaphoreSlim(1);

	public Guid Guid { get; set; } = Guid.NewGuid();


	public string IpPort => Ip + ":" + Port;

	public string Ip { get; set; }

	public int Port
	{
		get
		{
			return _Port;
		}
		set
		{
			if (value < 0)
			{
				throw new ArgumentOutOfRangeException("Port");
			}
			_Port = value;
		}
	}

	public string Name { get; set; }

	public object Metadata { get; set; }

	public ClientMetadata()
	{
	}

	public ClientMetadata(HttpListenerContext httpContext, WebSocket ws, WebSocketContext wsContext, CancellationTokenSource tokenSource, Guid guid = default(Guid))
	{
		HttpContext = httpContext ?? throw new ArgumentNullException("httpContext");
		Ws = ws ?? throw new ArgumentNullException("ws");
		WsContext = wsContext ?? throw new ArgumentNullException("wsContext");
		TokenSource = tokenSource ?? throw new ArgumentNullException("tokenSource");
		Ip = HttpContext.Request.RemoteEndPoint.Address.ToString();
		Port = HttpContext.Request.RemoteEndPoint.Port;
		if (guid != default(Guid))
		{
			Guid = guid;
		}
	}

	public override string ToString()
	{
		string text = "[";
		text = text + Guid.ToString() + "|" + IpPort;
		if (!string.IsNullOrEmpty(Name))
		{
			text = text + "|" + Name;
		}
		return text + "]";
	}
}
public class ConnectionEventArgs : EventArgs
{
	public ClientMetadata Client { get; }

	public HttpListenerRequest HttpRequest { get; }

	internal ConnectionEventArgs(ClientMetadata client, HttpListenerRequest http)
	{
		Client = client;
		HttpRequest = http;
	}
}
public class DisconnectionEventArgs : EventArgs
{
	public ClientMetadata Client { get; }

	internal DisconnectionEventArgs(ClientMetadata client)
	{
		Client = client;
	}
}
public class MessageReceivedEventArgs : EventArgs
{
	public WebSocketMessageType MessageType = WebSocketMessageType.Binary;

	public ClientMetadata Client { get; }

	public ArraySegment<byte> Data { get; }

	internal MessageReceivedEventArgs(ClientMetadata client, ArraySegment<byte> data, WebSocketMessageType messageType)
	{
		Client = client;
		Data = data;
		MessageType = messageType;
	}
}
public class Statistics
{
	private DateTime _StartTime = DateTime.Now.ToUniversalTime();

	private long _ReceivedBytes;

	private long _ReceivedMessages;

	private long _SentBytes;

	private long _SentMessages;

	public DateTime StartTime => _StartTime;

	public TimeSpan UpTime => DateTime.Now.ToUniversalTime() - _StartTime;

	public long ReceivedBytes => _ReceivedBytes;

	public long ReceivedMessages => _ReceivedMessages;

	public int ReceivedMessageSizeAverage
	{
		get
		{
			if (_ReceivedBytes > 0 && _ReceivedMessages > 0)
			{
				return (int)(_ReceivedBytes / _ReceivedMessages);
			}
			return 0;
		}
	}

	public long SentBytes => _SentBytes;

	public long SentMessages => _SentMessages;

	public decimal SentMessageSizeAverage
	{
		get
		{
			if (_SentBytes > 0 && _SentMessages > 0)
			{
				return (int)(_SentBytes / _SentMessages);
			}
			return 0m;
		}
	}

	public override string ToString()
	{
		return "--- Statistics ---" + Environment.NewLine + "    Started     : " + _StartTime.ToString() + Environment.NewLine + "    Uptime      : " + UpTime.ToString() + Environment.NewLine + "    Received    : " + Environment.NewLine + "       Bytes    : " + ReceivedBytes + Environment.NewLine + "       Messages : " + ReceivedMessages + Environment.NewLine + "       Average  : " + ReceivedMessageSizeAverage + " bytes" + Environment.NewLine + "    Sent        : " + Environment.NewLine + "       Bytes    : " + SentBytes + Environment.NewLine + "       Messages : " + SentMessages + Environment.NewLine + "       Average  : " + SentMessageSizeAverage + " bytes" + Environment.NewLine;
	}

	public void Reset()
	{
		_ReceivedBytes = 0L;
		_ReceivedMessages = 0L;
		_SentBytes = 0L;
		_SentMessages = 0L;
	}

	internal void IncrementReceivedMessages()
	{
		_ReceivedMessages = Interlocked.Increment(ref _ReceivedMessages);
	}

	internal void IncrementSentMessages()
	{
		_SentMessages = Interlocked.Increment(ref _SentMessages);
	}

	internal void AddReceivedBytes(long bytes)
	{
		_ReceivedBytes = Interlocked.Add(ref _ReceivedBytes, bytes);
	}

	internal void AddSentBytes(long bytes)
	{
		_SentBytes = Interlocked.Add(ref _SentBytes, bytes);
	}
}
public class WatsonWsClient : IDisposable
{
	public Action<string> Logger;

	private string _Header = "[WatsonWsClient] ";

	private bool _AcceptInvalidCertificates = true;

	private Uri _ServerUri;

	private string _ServerIp;

	private int _ServerPort;

	private string _ServerIpPort;

	private string _Url;

	private int _KeepAliveIntervalSeconds = 30;

	private ClientWebSocket _ClientWs;

	private CookieContainer _Cookies = new CookieContainer();

	private Action<ClientWebSocketOptions> _PreConfigureOptions;

	private string _GuidHeader = "x-guid";

	private Guid _Guid;

	private readonly SemaphoreSlim _SendLock = new SemaphoreSlim(1);

	private readonly SemaphoreSlim _AwaitingSyncResposeLock = new SemaphoreSlim(1);

	private CancellationTokenSource _TokenSource = new CancellationTokenSource();

	private CancellationToken _Token;

	private Statistics _Stats = new Statistics();

	private readonly bool _IsBrowser;

	public bool AcceptInvalidCertificates
	{
		get
		{
			return _AcceptInvalidCertificates;
		}
		set
		{
			_AcceptInvalidCertificates = value;
		}
	}

	public bool Connected
	{
		get
		{
			if (_ClientWs != null && _ClientWs.State == WebSocketState.Open)
			{
				return true;
			}
			return false;
		}
	}

	public bool EnableStatistics { get; set; } = true;


	public int KeepAliveInterval
	{
		get
		{
			if (_IsBrowser)
			{
				throw new PlatformNotSupportedException();
			}
			return _KeepAliveIntervalSeconds;
		}
		set
		{
			if (_IsBrowser)
			{
				throw new PlatformNotSupportedException();
			}
			if (value < 1)
			{
				throw new ArgumentException("ConnectTimeoutSeconds must be greater than zero.");
			}
			_KeepAliveIntervalSeconds = value;
		}
	}

	public string GuidHeader
	{
		get
		{
			return _GuidHeader;
		}
		set
		{
			if (string.IsNullOrEmpty(value))
			{
				throw new ArgumentNullException("GuidHeader");
			}
			_GuidHeader = value;
		}
	}

	public Statistics Stats => _Stats;

	public event EventHandler<MessageReceivedEventArgs> MessageReceived;

	public event EventHandler ServerConnected;

	public event EventHandler ServerDisconnected;

	private event EventHandler<MessageReceivedEventArgs> _AwaitingSyncResponseEvent;

	public WatsonWsClient(string serverIp, int serverPort, bool ssl = false, Guid guid = default(Guid))
	{
		if (string.IsNullOrEmpty(serverIp))
		{
			throw new ArgumentNullException("serverIp");
		}
		if (serverPort < 1)
		{
			throw new ArgumentOutOfRangeException("serverPort");
		}
		_ServerIp = serverIp;
		_ServerPort = serverPort;
		_ServerIpPort = serverIp + ":" + serverPort;
		if (ssl)
		{
			_Url = "wss://" + _ServerIp + ":" + _ServerPort;
		}
		else
		{
			_Url = "ws://" + _ServerIp + ":" + _ServerPort;
		}
		_ServerUri = new Uri(_Url);
		_Token = _TokenSource.Token;
		_Guid = guid;
		_ClientWs = new ClientWebSocket();
	}

	public WatsonWsClient(Uri uri, Guid guid = default(Guid))
	{
		_ServerUri = uri;
		_ServerIp = uri.Host;
		_ServerPort = uri.Port;
		_ServerIpPort = uri.Host + ":" + uri.Port;
		_Token = _TokenSource.Token;
		_Guid = guid;
		_ClientWs = new ClientWebSocket();
	}

	public void Dispose()
	{
		Dispose(disposing: true);
		GC.SuppressFinalize(this);
	}

	public WatsonWsClient ConfigureOptions(Action<ClientWebSocketOptions> options)
	{
		if (_IsBrowser)
		{
			throw new PlatformNotSupportedException();
		}
		if (!Connected)
		{
			_PreConfigureOptions = options;
		}
		return this;
	}

	public void AddCookie(Cookie cookie)
	{
		if (_IsBrowser)
		{
			throw new PlatformNotSupportedException();
		}
		_Cookies.Add(cookie);
	}

	public void Start()
	{
		_Stats = new Statistics();
		if (_AcceptInvalidCertificates)
		{
			SetInvalidCertificateAcceptance();
		}
		if (!_IsBrowser)
		{
			_ClientWs.Options.Cookies = _Cookies;
			_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
			if (_PreConfigureOptions != null)
			{
				_PreConfigureOptions(_ClientWs.Options);
			}
		}
		if (_Guid != default(Guid))
		{
			_ClientWs.Options.SetRequestHeader(_GuidHeader, _Guid.ToString());
		}
		_ClientWs.ConnectAsync(_ServerUri, _Token).ContinueWith(AfterConnect).Wait();
	}

	public Task StartAsync()
	{
		_Stats = new Statistics();
		if (_AcceptInvalidCertificates)
		{
			SetInvalidCertificateAcceptance();
		}
		if (!_IsBrowser)
		{
			_ClientWs.Options.Cookies = _Cookies;
			_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
			if (_PreConfigureOptions != null)
			{
				_PreConfigureOptions(_ClientWs.Options);
			}
		}
		if (_Guid != default(Guid))
		{
			_ClientWs.Options.SetRequestHeader(_GuidHeader, _Guid.ToString());
		}
		return _ClientWs.ConnectAsync(_ServerUri, _Token).ContinueWith(AfterConnect);
	}

	public bool StartWithTimeout(int timeout = 30, CancellationToken token = default(CancellationToken))
	{
		if (timeout < 1)
		{
			throw new ArgumentException("Timeout must be greater than zero seconds.");
		}
		_Stats = new Statistics();
		if (_AcceptInvalidCertificates)
		{
			SetInvalidCertificateAcceptance();
		}
		Stopwatch stopwatch = new Stopwatch();
		TimeSpan timeSpan = TimeSpan.FromSeconds(timeout);
		stopwatch.Start();
		try
		{
			while (stopwatch.Elapsed < timeSpan && !token.IsCancellationRequested)
			{
				_ClientWs = new ClientWebSocket();
				if (!_IsBrowser)
				{
					_ClientWs.Options.Cookies = _Cookies;
					_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
					if (_PreConfigureOptions != null)
					{
						_PreConfigureOptions(_ClientWs.Options);
					}
				}
				if (_Guid != default(Guid))
				{
					_ClientWs.Options.SetRequestHeader(_GuidHeader, _Guid.ToString());
				}
				try
				{
					_ClientWs.ConnectAsync(_ServerUri, token).ContinueWith(AfterConnect).Wait();
				}
				catch (TaskCanceledException)
				{
					return false;
				}
				catch (OperationCanceledException)
				{
					return false;
				}
				catch (WebSocketException)
				{
				}
				Task.Delay(100).Wait();
				if (_ClientWs.State == WebSocketState.Open)
				{
					return true;
				}
			}
		}
		catch (TaskCanceledException)
		{
		}
		catch (OperationCanceledException)
		{
		}
		return false;
	}

	public async Task<bool> StartWithTimeoutAsync(int timeout = 30, CancellationToken token = default(CancellationToken))
	{
		if (timeout < 1)
		{
			throw new ArgumentException("Timeout must be greater than zero seconds.");
		}
		_Stats = new Statistics();
		if (_AcceptInvalidCertificates)
		{
			SetInvalidCertificateAcceptance();
		}
		Stopwatch sw = new Stopwatch();
		TimeSpan timeOut = TimeSpan.FromSeconds(timeout);
		sw.Start();
		try
		{
			while (sw.Elapsed < timeOut && !token.IsCancellationRequested)
			{
				_ClientWs = new ClientWebSocket();
				if (!_IsBrowser)
				{
					_ClientWs.Options.Cookies = _Cookies;
					_ClientWs.Options.KeepAliveInterval = TimeSpan.FromSeconds(_KeepAliveIntervalSeconds);
					if (_PreConfigureOptions != null)
					{
						_PreConfigureOptions(_ClientWs.Options);
					}
				}
				if (_Guid != default(Guid))
				{
					_ClientWs.Options.SetRequestHeader(_GuidHeader, _Guid.ToString());
				}
				try
				{
					await _ClientWs.ConnectAsync(_ServerUri, token).ContinueWith(AfterConnect);
				}
				catch (TaskCanceledException)
				{
					return false;
				}
				catch (OperationCanceledException)
				{
					return false;
				}
				catch (WebSocketException)
				{
				}
				await Task.Delay(100);
				if (_ClientWs.State == WebSocketState.Open)
				{
					return true;
				}
			}
		}
		catch (TaskCanceledException)
		{
		}
		catch (OperationCanceledException)
		{
		}
		return false;
	}

	public void Stop()
	{
		Stop(WebSocketCloseStatus.NormalClosure, _ClientWs.CloseStatusDescription);
	}

	public async Task StopAsync()
	{
		await StopAsync(WebSocketCloseStatus.NormalClosure, _ClientWs.CloseStatusDescription);
	}

	public void Stop(WebSocketCloseStatus closeCode, string reason)
	{
		_ClientWs.CloseOutputAsync(closeCode, reason, _Token).Wait();
	}

	public async Task StopAsync(WebSocketCloseStatus closeCode, string reason)
	{
		await _ClientWs.CloseOutputAsync(closeCode, reason, _Token).ConfigureAwait(continueOnCapturedContext: false);
	}

	public async Task<bool> SendAsync(string data, WebSocketMessageType msgType = WebSocketMessageType.Text, CancellationToken token = default(CancellationToken))
	{
		if (string.IsNullOrEmpty(data))
		{
			throw new ArgumentNullException("data");
		}
		return await MessageWriteAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(data)), msgType, token);
	}

	public async Task<bool> SendAsync(byte[] data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
	{
		return await MessageWriteAsync(new ArraySegment<byte>(data), msgType, token);
	}

	public async Task<bool> SendAsync(ArraySegment<byte> data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
	{
		if (data.Array == null || data.Count < 1)
		{
			throw new ArgumentNullException("data");
		}
		return await MessageWriteAsync(data, msgType, token);
	}

	public async Task<string> SendAndWaitAsync(string data, int timeout = 30, CancellationToken token = default(CancellationToken))
	{
		if (string.IsNullOrEmpty(data))
		{
			throw new ArgumentNullException("data");
		}
		if (timeout < 1)
		{
			throw new ArgumentException("Timeout must be greater than zero seconds.", "data");
		}
		string result = null;
		ManualResetEvent receivedEvent = new ManualResetEvent(initialState: false);
		await _AwaitingSyncResposeLock.WaitAsync(_Token);
		await Task.Run(async delegate
		{
			_AwaitingSyncResponseEvent += delegate(object s, MessageReceivedEventArgs e)
			{
				result = Encoding.UTF8.GetString(e.Data.Array, 0, e.Data.Count);
				receivedEvent.Set();
			};
			await MessageWriteAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(data)), WebSocketMessageType.Text, token);
			receivedEvent.WaitOne(TimeSpan.FromSeconds(timeout));
			this._AwaitingSyncResponseEvent = null;
			_AwaitingSyncResposeLock.Release();
		});
		return result;
	}

	public async Task<ArraySegment<byte>> SendAndWaitAsync(byte[] data, int timeout = 30, CancellationToken token = default(CancellationToken))
	{
		return await SendAndWaitAsync(new ArraySegment<byte>(data), timeout, token);
	}

	public async Task<ArraySegment<byte>> SendAndWaitAsync(ArraySegment<byte> data, int timeout = 30, CancellationToken token = default(CancellationToken))
	{
		if (data.Array == null || data.Count < 1)
		{
			throw new ArgumentNullException("data");
		}
		if (timeout < 1)
		{
			throw new ArgumentException("Timeout must be zero or greater.", "data");
		}
		ArraySegment<byte> result = default(ArraySegment<byte>);
		ManualResetEvent receivedEvent = new ManualResetEvent(initialState: false);
		await _AwaitingSyncResposeLock.WaitAsync(_Token);
		await Task.Run(async delegate
		{
			_AwaitingSyncResponseEvent += delegate(object s, MessageReceivedEventArgs e)
			{
				result = e.Data;
				receivedEvent.Set();
			};
			await MessageWriteAsync(data, WebSocketMessageType.Binary, token);
			receivedEvent.WaitOne(TimeSpan.FromSeconds(timeout));
			this._AwaitingSyncResponseEvent = null;
			_AwaitingSyncResposeLock.Release();
		});
		return result;
	}

	protected virtual void Dispose(bool disposing)
	{
		if (disposing)
		{
			if (_ClientWs != null && _ClientWs.State == WebSocketState.Open)
			{
				Stop();
				_ClientWs.Dispose();
			}
			_TokenSource.Cancel();
			Logger?.Invoke(_Header + "dispose complete");
		}
	}

	private void SetInvalidCertificateAcceptance()
	{
		ServicePointManager.ServerCertificateValidationCallback = (RemoteCertificateValidationCallback)Delegate.Combine(ServicePointManager.ServerCertificateValidationCallback, (RemoteCertificateValidationCallback)((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true));
	}

	private void AfterConnect(Task task)
	{
		if (task.IsFaulted || !task.IsCompleted || _ClientWs.State != WebSocketState.Open)
		{
			return;
		}
		Task.Run(delegate
		{
			Task.Run(() => DataReceiver(), _Token);
			this.ServerConnected?.Invoke(this, EventArgs.Empty);
		}, _Token);
	}

	private async Task DataReceiver()
	{
		byte[] buffer = new byte[65536];
		try
		{
			while (!_Token.IsCancellationRequested)
			{
				MessageReceivedEventArgs messageReceivedEventArgs = await MessageReadAsync(buffer);
				if (messageReceivedEventArgs == null)
				{
					continue;
				}
				if (EnableStatistics)
				{
					_Stats.IncrementReceivedMessages();
					_Stats.AddReceivedBytes(messageReceivedEventArgs.Data.Count);
				}
				if (messageReceivedEventArgs.MessageType != WebSocketMessageType.Close)
				{
					if (this._AwaitingSyncResponseEvent != null)
					{
						this._AwaitingSyncResponseEvent?.Invoke(this, messageReceivedEventArgs);
					}
					else
					{
						this.MessageReceived?.Invoke(this, messageReceivedEventArgs);
					}
				}
			}
		}
		catch (OperationCanceledException)
		{
			Logger?.Invoke(_Header + "data receiver canceled");
		}
		catch (WebSocketException)
		{
			Logger?.Invoke(_Header + "websocket disconnected");
		}
		catch (Exception ex3)
		{
			Logger?.Invoke(_Header + "exception: " + Environment.NewLine + ex3.ToString());
		}
		this.ServerDisconnected?.Invoke(this, EventArgs.Empty);
	}

	private async Task<MessageReceivedEventArgs> MessageReadAsync(byte[] buffer)
	{
		if (_ClientWs == null)
		{
			return null;
		}
		ArraySegment<byte> data = default(ArraySegment<byte>);
		WebSocketReceiveResult result = null;
		using (MemoryStream dataMs = new MemoryStream())
		{
			buffer = new byte[buffer.Length];
			ArraySegment<byte> bufferSegment = new ArraySegment<byte>(buffer);
			if (_ClientWs.State == WebSocketState.CloseReceived || _ClientWs.State == WebSocketState.Closed)
			{
				throw new WebSocketException("Websocket close received");
			}
			while (_ClientWs.State == WebSocketState.Open)
			{
				result = await _ClientWs.ReceiveAsync(bufferSegment, _Token);
				if (result.Count > 0)
				{
					await dataMs.WriteAsync(buffer, 0, result.Count);
				}
				if (result.EndOfMessage)
				{
					data = new ArraySegment<byte>(dataMs.GetBuffer(), 0, (int)dataMs.Length);
					break;
				}
			}
		}
		return new MessageReceivedEventArgs(new ClientMetadata
		{
			Guid = default(Guid),
			Ip = _ServerIp,
			Port = _ServerPort
		}, data, result.MessageType);
	}

	private async Task<bool> MessageWriteAsync(ArraySegment<byte> data, WebSocketMessageType msgType, CancellationToken token)
	{
		bool disconnectDetected = false;
		using (CancellationTokenSource.CreateLinkedTokenSource(_Token, token))
		{
			_ = 1;
			try
			{
				if (_ClientWs == null || _ClientWs.State != WebSocketState.Open)
				{
					Logger?.Invoke(_Header + "not connected");
					disconnectDetected = true;
					return false;
				}
				await _SendLock.WaitAsync(_Token).ConfigureAwait(continueOnCapturedContext: false);
				try
				{
					await _ClientWs.SendAsync(data, msgType, endOfMessage: true, token).ConfigureAwait(continueOnCapturedContext: false);
				}
				catch
				{
				}
				finally
				{
					_SendLock.Release();
				}
				if (EnableStatistics)
				{
					_Stats.IncrementSentMessages();
					_Stats.AddSentBytes(data.Count);
				}
				return true;
			}
			catch (TaskCanceledException)
			{
				if (_Token.IsCancellationRequested)
				{
					Logger?.Invoke(_Header + "canceled");
					disconnectDetected = true;
				}
				else if (token.IsCancellationRequested)
				{
					Logger?.Invoke(_Header + "message send canceled");
				}
				return false;
			}
			catch (OperationCanceledException)
			{
				if (_Token.IsCancellationRequested)
				{
					Logger?.Invoke(_Header + "canceled");
					disconnectDetected = true;
				}
				else if (token.IsCancellationRequested)
				{
					Logger?.Invoke(_Header + "message send canceled");
				}
				return false;
			}
			catch (WebSocketException)
			{
				Logger?.Invoke(_Header + "websocket disconnected");
				disconnectDetected = true;
				return false;
			}
			catch (ObjectDisposedException)
			{
				Logger?.Invoke(_Header + "disposed");
				disconnectDetected = true;
				return false;
			}
			catch (SocketException)
			{
				Logger?.Invoke(_Header + "socket disconnected");
				disconnectDetected = true;
				return false;
			}
			catch (InvalidOperationException)
			{
				Logger?.Invoke(_Header + "disconnected due to invalid operation");
				disconnectDetected = true;
				return false;
			}
			catch (IOException)
			{
				Logger?.Invoke(_Header + "IO disconnected");
				disconnectDetected = true;
				return false;
			}
			catch (Exception ex8)
			{
				Logger?.Invoke(_Header + "exception: " + Environment.NewLine + ex8.ToString());
				disconnectDetected = true;
				return false;
			}
			finally
			{
				if (disconnectDetected)
				{
					Dispose();
					this.ServerDisconnected?.Invoke(this, EventArgs.Empty);
				}
			}
		}
	}
}
public class WatsonWsServer : IDisposable
{
	public List<string> PermittedIpAddresses = new List<string>();

	public Action<string> Logger;

	public Action<HttpListenerContext> HttpHandler;

	private string _Header = "[WatsonWsServer] ";

	private bool _AcceptInvalidCertificates = true;

	private List<string> _ListenerPrefixes = new List<string>();

	private HttpListener _Listener;

	private readonly object _PermittedIpsLock = new object();

	private ConcurrentDictionary<Guid, ClientMetadata> _Clients = new ConcurrentDictionary<Guid, ClientMetadata>();

	private CancellationTokenSource _TokenSource = new CancellationTokenSource();

	private CancellationToken _Token;

	private Task _AcceptConnectionsTask;

	private Statistics _Stats = new Statistics();

	private string _GuidHeader = "x-guid";

	public bool IsListening
	{
		get
		{
			if (_Listener != null)
			{
				return _Listener.IsListening;
			}
			return false;
		}
	}

	public bool EnableStatistics { get; set; } = true;


	public bool AcceptInvalidCertificates
	{
		get
		{
			return _AcceptInvalidCertificates;
		}
		set
		{
			_AcceptInvalidCertificates = value;
		}
	}

	public string GuidHeader
	{
		get
		{
			return _GuidHeader;
		}
		set
		{
			if (string.IsNullOrEmpty(value))
			{
				throw new ArgumentNullException("GuidHeader");
			}
			_GuidHeader = value;
		}
	}

	public Statistics Stats => _Stats;

	public event EventHandler<ConnectionEventArgs> ClientConnected;

	public event EventHandler<DisconnectionEventArgs> ClientDisconnected;

	public event EventHandler ServerStopped;

	public event EventHandler<MessageReceivedEventArgs> MessageReceived;

	public WatsonWsServer(string hostname = "localhost", int port = 9000, bool ssl = false)
	{
		if (port < 0)
		{
			throw new ArgumentOutOfRangeException("port");
		}
		if (string.IsNullOrEmpty(hostname))
		{
			hostname = "localhost";
		}
		if (ssl)
		{
			_ListenerPrefixes.Add("https://" + hostname + ":" + port + "/");
		}
		else
		{
			_ListenerPrefixes.Add("http://" + hostname + ":" + port + "/");
		}
		_Listener = new HttpListener();
		foreach (string listenerPrefix in _ListenerPrefixes)
		{
			_Listener.Prefixes.Add(listenerPrefix);
		}
		_Token = _TokenSource.Token;
	}

	public WatsonWsServer(List<string> hostnames, int port, bool ssl = false)
	{
		if (port < 0)
		{
			throw new ArgumentOutOfRangeException("port");
		}
		if (hostnames == null)
		{
			throw new ArgumentNullException("hostnames");
		}
		if (hostnames.Count < 1)
		{
			throw new ArgumentException("At least one hostname must be supplied.");
		}
		foreach (string hostname in hostnames)
		{
			if (ssl)
			{
				_ListenerPrefixes.Add("https://" + hostname + ":" + port + "/");
			}
			else
			{
				_ListenerPrefixes.Add("http://" + hostname + ":" + port + "/");
			}
		}
		_Listener = new HttpListener();
		foreach (string listenerPrefix in _ListenerPrefixes)
		{
			_Listener.Prefixes.Add(listenerPrefix);
		}
		_Token = _TokenSource.Token;
	}

	public WatsonWsServer(Uri uri)
	{
		if (uri == null)
		{
			throw new ArgumentNullException("uri");
		}
		if (uri.Port < 0)
		{
			throw new ArgumentException("Port must be zero or greater.");
		}
		string host;
		if (!IPAddress.TryParse(uri.Host, out IPAddress _))
		{
			IPHostEntry hostEntry = Dns.GetHostEntry(uri.Host);
			if (hostEntry.AddressList.Length == 0)
			{
				throw new ArgumentException("Cannot resolve address to IP.");
			}
			host = hostEntry.AddressList.First().ToString();
		}
		else
		{
			host = uri.Host;
		}
		UriBuilder uriBuilder = new UriBuilder(uri)
		{
			Host = host
		};
		_ListenerPrefixes.Add(uriBuilder.ToString());
		_Listener = new HttpListener();
		foreach (string listenerPrefix in _ListenerPrefixes)
		{
			_Listener.Prefixes.Add(listenerPrefix);
		}
		_Token = _TokenSource.Token;
	}

	public void Dispose()
	{
		Dispose(disposing: true);
	}

	public void Start()
	{
		if (IsListening)
		{
			throw new InvalidOperationException("Watson websocket server is already running.");
		}
		_Stats = new Statistics();
		string text = _Header + "starting on:";
		foreach (string listenerPrefix in _ListenerPrefixes)
		{
			text = text + " " + listenerPrefix;
		}
		Logger?.Invoke(text);
		if (_AcceptInvalidCertificates)
		{
			SetInvalidCertificateAcceptance();
		}
		_TokenSource = new CancellationTokenSource();
		_Token = _TokenSource.Token;
		_Listener.Start();
		_AcceptConnectionsTask = Task.Run(() => AcceptConnections(_Token), _Token);
	}

	public Task StartAsync(CancellationToken token = default(CancellationToken))
	{
		if (IsListening)
		{
			throw new InvalidOperationException("Watson websocket server is already running.");
		}
		_Stats = new Statistics();
		string text = _Header + "starting on:";
		foreach (string listenerPrefix in _ListenerPrefixes)
		{
			text = text + " " + listenerPrefix;
		}
		Logger?.Invoke(text);
		if (_AcceptInvalidCertificates)
		{
			SetInvalidCertificateAcceptance();
		}
		_TokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationToken[1] { token });
		_Token = token;
		_Listener.Start();
		_AcceptConnectionsTask = Task.Run(() => AcceptConnections(_Token), _Token);
		return Task.Delay(1);
	}

	public void Stop()
	{
		if (!IsListening)
		{
			throw new InvalidOperationException("Watson websocket server is not running.");
		}
		Logger?.Invoke(_Header + "stopping");
		_Listener.Stop();
	}

	public Task<bool> SendAsync(Guid guid, string data, WebSocketMessageType msgType = WebSocketMessageType.Text, CancellationToken token = default(CancellationToken))
	{
		if (string.IsNullOrEmpty(data))
		{
			data = "";
		}
		return SendAsync(guid, Encoding.UTF8.GetBytes(data), msgType, token);
	}

	public Task<bool> SendAsync(Guid guid, byte[] data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
	{
		if (data == null)
		{
			data = new byte[0];
		}
		return SendAsync(guid, new ArraySegment<byte>(data), msgType, token);
	}

	public Task<bool> SendAsync(Guid guid, ArraySegment<byte> data, WebSocketMessageType msgType = WebSocketMessageType.Binary, CancellationToken token = default(CancellationToken))
	{
		if (data.Array == null || data.Count < 1)
		{
			throw new ArgumentNullException("data");
		}
		if (!_Clients.TryGetValue(guid, out var value))
		{
			Logger?.Invoke(_Header + "unable to find client " + guid);
			return Task.FromResult(result: false);
		}
		Task<bool> result = MessageWriteAsync(value, data, msgType, token);
		value = null;
		return result;
	}

	public bool IsClientConnected(Guid guid)
	{
		return _Clients.Any((KeyValuePair<Guid, ClientMetadata> c) => c.Key.Equals(guid));
	}

	public IEnumerable<ClientMetadata> ListClients()
	{
		return _Clients.Values;
	}

	public void DisconnectClient(Guid guid)
	{
		if (_Clients.TryGetValue(guid, out var value))
		{
			lock (value)
			{
				value.Ws.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", value.TokenSource.Token).Wait();
				value.TokenSource.Cancel();
				value.Ws.Dispose();
			}
		}
	}

	public TaskAwaiter GetAwaiter()
	{
		return _AcceptConnectionsTask.GetAwaiter();
	}

	protected virtual void Dispose(bool disposing)
	{
		if (!disposing)
		{
			return;
		}
		if (_Clients != null)
		{
			foreach (KeyValuePair<Guid, ClientMetadata> client in _Clients)
			{
				client.Value.Ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", client.Value.TokenSource.Token);
				client.Value.TokenSource.Cancel();
			}
		}
		if (_Listener != null)
		{
			if (_Listener.IsListening)
			{
				_Listener.Stop();
			}
			_Listener.Close();
		}
		_TokenSource.Cancel();
	}

	private void SetInvalidCertificateAcceptance()
	{
		ServicePointManager.ServerCertificateValidationCallback = (RemoteCertificateValidationCallback)Delegate.Combine(ServicePointManager.ServerCertificateValidationCallback, (RemoteCertificateValidationCallback)((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true));
	}

	private async Task AcceptConnections(CancellationToken cancelToken)
	{
		bool exiting = false;
		while (!cancelToken.IsCancellationRequested)
		{
			try
			{
				if (!_Listener.IsListening)
				{
					Task.Delay(100).Wait();
					continue;
				}
				HttpListenerContext ctx = await _Listener.GetContextAsync().ConfigureAwait(continueOnCapturedContext: false);
				string text = ctx.Request.RemoteEndPoint.Address.ToString();
				string ipPort = text + ":" + ctx.Request.RemoteEndPoint.Port;
				lock (_PermittedIpsLock)
				{
					if (PermittedIpAddresses != null && PermittedIpAddresses.Count > 0 && !PermittedIpAddresses.Contains(text))
					{
						Logger?.Invoke(_Header + "rejecting " + ipPort + " (not permitted)");
						ctx.Response.StatusCode = 401;
						ctx.Response.Close();
						continue;
					}
				}
				if (ctx.Request.IsWebSocketRequest)
				{
					await Task.Run(delegate
					{
						Logger?.Invoke(_Header + "starting data receiver for " + ipPort);
						CancellationTokenSource tokenSource = new CancellationTokenSource();
						CancellationToken token = tokenSource.Token;
						Task.Run(async delegate
						{
							Guid guid = Guid.NewGuid();
							string text2 = ctx.Request.Headers.Get(_GuidHeader);
							if (!string.IsNullOrEmpty(text2))
							{
								guid = Guid.Parse(text2);
							}
							WebSocketContext webSocketContext = await ctx.AcceptWebSocketAsync(null);
							WebSocket webSocket = webSocketContext.WebSocket;
							ClientMetadata md = new ClientMetadata(ctx, webSocket, webSocketContext, tokenSource, guid);
							_Clients.TryAdd(md.Guid, md);
							this.ClientConnected?.Invoke(this, new ConnectionEventArgs(md, ctx.Request));
							await Task.Run(() => DataReceiver(md), token);
						}, token);
					}, _Token).ConfigureAwait(continueOnCapturedContext: false);
				}
				else if (HttpHandler == null)
				{
					Logger?.Invoke(_Header + "non-websocket request rejected from " + ipPort);
					ctx.Response.StatusCode = 400;
					ctx.Response.Close();
				}
				else
				{
					Logger?.Invoke(_Header + "non-websocket request from " + ipPort + " HTTP-forwarded: " + ctx.Request.HttpMethod.ToString() + " " + ctx.Request.RawUrl);
					HttpHandler(ctx);
				}
			}
			catch (TaskCanceledException)
			{
				exiting = true;
				break;
			}
			catch (OperationCanceledException)
			{
				exiting = true;
				break;
			}
			catch (ObjectDisposedException)
			{
				exiting = true;
				break;
			}
			catch (HttpListenerException)
			{
				exiting = true;
				break;
			}
			catch (Exception ex5)
			{
				Logger?.Invoke(_Header + "listener exception:" + Environment.NewLine + ex5.ToString());
			}
			finally
			{
				if (exiting)
				{
					Logger?.Invoke(_Header + "listener stopped");
					this.ServerStopped?.Invoke(this, EventArgs.Empty);
				}
			}
		}
	}

	private async Task DataReceiver(ClientMetadata client)
	{
		string header = "[WatsonWsServer " + client.Guid.ToString() + "] ";
		Logger?.Invoke(header + "starting data receiver");
		byte[] buffer = new byte[65536];
		try
		{
			while (true)
			{
				MessageReceivedEventArgs msg = await MessageReadAsync(client, buffer).ConfigureAwait(continueOnCapturedContext: false);
				if (msg != null)
				{
					if (EnableStatistics)
					{
						_Stats.IncrementReceivedMessages();
						_Stats.AddReceivedBytes(msg.Data.Count);
					}
					_ = msg.Data;
					Task.Run(delegate
					{
						this.MessageReceived?.Invoke(this, msg);
					}, client.TokenSource.Token);
				}
			}
		}
		catch (TaskCanceledException)
		{
		}
		catch (OperationCanceledException)
		{
		}
		catch (WebSocketException)
		{
		}
		catch (Exception ex4)
		{
			Logger?.Invoke(header + "exception: " + Environment.NewLine + ex4.ToString());
		}
		finally
		{
			_Clients.TryRemove(client.Guid, out var _);
			_ = client.IpPort;
			this.ClientDisconnected?.Invoke(this, new DisconnectionEventArgs(client));
			client.Ws.Dispose();
			Logger?.Invoke(header + "disconnected");
		}
	}

	private async Task<MessageReceivedEventArgs> MessageReadAsync(ClientMetadata client, byte[] buffer)
	{
		string header = "[WatsonWsServer " + client.Guid.ToString() + "] ";
		using MemoryStream ms = new MemoryStream();
		ArraySegment<byte> seg = new ArraySegment<byte>(buffer);
		WebSocketReceiveResult webSocketReceiveResult;
		do
		{
			webSocketReceiveResult = await client.Ws.ReceiveAsync(seg, client.TokenSource.Token).ConfigureAwait(continueOnCapturedContext: false);
			if (webSocketReceiveResult.CloseStatus.HasValue)
			{
				Logger?.Invoke(header + "close received");
				await client.Ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
				throw new WebSocketException("Websocket closed.");
			}
			if (client.Ws.State != WebSocketState.Open)
			{
				Logger?.Invoke(header + "websocket no longer open");
				throw new WebSocketException("Websocket closed.");
			}
			if (client.TokenSource.Token.IsCancellationRequested)
			{
				Logger?.Invoke(header + "cancel requested");
			}
			if (webSocketReceiveResult.Count > 0)
			{
				ms.Write(buffer, 0, webSocketReceiveResult.Count);
			}
		}
		while (!webSocketReceiveResult.EndOfMessage);
		return new MessageReceivedEventArgs(client, new ArraySegment<byte>(ms.GetBuffer(), 0, (int)ms.Length), webSocketReceiveResult.MessageType);
	}

	private async Task<bool> MessageWriteAsync(ClientMetadata md, ArraySegment<byte> data, WebSocketMessageType msgType, CancellationToken token)
	{
		string header = "[WatsonWsServer " + md.IpPort + "] ";
		using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_Token, token, md.TokenSource.Token))
		{
			_ = 1;
			try
			{
				await md.SendLock.WaitAsync(md.TokenSource.Token).ConfigureAwait(continueOnCapturedContext: false);
				try
				{
					await md.Ws.SendAsync(data, msgType, endOfMessage: true, linkedCts.Token).ConfigureAwait(continueOnCapturedContext: false);
				}
				finally
				{
					md.SendLock.Release();
				}
				if (EnableStatistics)
				{
					_Stats.IncrementSentMessages();
					_Stats.AddSentBytes(data.Count);
				}
				return true;
			}
			catch (TaskCanceledException)
			{
				if (_Token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "server canceled");
				}
				else if (token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "message send canceled");
				}
				else if (md.TokenSource.Token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "client canceled");
				}
			}
			catch (OperationCanceledException)
			{
				if (_Token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "canceled");
				}
				else if (token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "message send canceled");
				}
				else if (md.TokenSource.Token.IsCancellationRequested)
				{
					Logger?.Invoke(header + "client canceled");
				}
			}
			catch (ObjectDisposedException)
			{
				Logger?.Invoke(header + "disposed");
			}
			catch (WebSocketException)
			{
				Logger?.Invoke(header + "websocket disconnected");
			}
			catch (SocketException)
			{
				Logger?.Invoke(header + "socket disconnected");
			}
			catch (InvalidOperationException)
			{
				Logger?.Invoke(header + "disconnected due to invalid operation");
			}
			catch (IOException)
			{
				Logger?.Invoke(header + "IO disconnected");
			}
			catch (Exception ex8)
			{
				Logger?.Invoke(header + "exception: " + Environment.NewLine + ex8.ToString());
			}
			finally
			{
				md = null;
			}
		}
		return false;
	}
}