Decompiled source of OBSControl v1.0.0
Mods/OBSControl.dll
Decompiled 7 months agousing 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 7 months ago
The result has been truncated due to the large size, download it to view full contents!
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 7 months agousing 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; } }