diff --git a/OBSClient/Exceptions/ObsResponseException.cs b/OBSClient/Exceptions/ObsResponseException.cs index 5323fab..f5311e2 100644 --- a/OBSClient/Exceptions/ObsResponseException.cs +++ b/OBSClient/Exceptions/ObsResponseException.cs @@ -5,8 +5,13 @@ using System.Runtime.Serialization; /// - /// Represents an exception that occured on the OBS Studio side. + /// Represents an exception that is thrown when OBS Studio returns an error in a message. /// + /// + /// You can continue using the after this exception is thrown. + /// This exception does not indicate that the communication between the client and OBS Studio is lost, but merely that OBS Studio has returned an error in reply to your request. + /// For example, when you call GetCurrentPreviewScene, but Studio Mode is not turned on in OBS Studio. + /// [Serializable] public class ObsResponseException : Exception { diff --git a/OBSClient/MessageClasses/EventMessage.cs b/OBSClient/MessageClasses/EventMessage.cs deleted file mode 100644 index e70a5a4..0000000 --- a/OBSClient/MessageClasses/EventMessage.cs +++ /dev/null @@ -1,148 +0,0 @@ -namespace OBSStudioClient.MessageClasses -{ - using OBSStudioClient.Enums; - using OBSStudioClient.Events; - using OBSStudioClient.Exceptions; - using OBSStudioClient.Interfaces; - using System.Text.Json; - using System.Text.Json.Serialization; - - /// - /// Class for Event Messages - /// - public class EventMessage : IMessage, IJsonOnDeserialized - { - /// - /// The type of Event - /// - [JsonConverter(typeof(JsonStringEnumConverter))] - [JsonPropertyName("eventType")] - public EventType EventType { get; } - - /// - /// The Events you have subscribed to - /// - [JsonPropertyName("eventIntent")] - public EventSubscriptions EventIntent { get; } - - /// - /// The raw JSON data sent to or received from OBS Studio - /// - [JsonPropertyName("eventData")] - public JsonElement? RawEventData { get; } - - /// - /// The deserialized event - /// - [JsonIgnore] - public EventArgs? EventData { get; private set; } - - /// - /// Creates a new instance of an object. - /// - /// The type of event. - /// The subscribed events. - /// The json data for the event data. - [JsonConstructor] - public EventMessage(EventType eventType, EventSubscriptions eventIntent, JsonElement? rawEventData) - { - this.EventType = eventType; - this.EventIntent = eventIntent; - this.RawEventData = rawEventData; - } - - /// - /// Deserializes the raw JSON data to EventArgs. - /// - /// When the event isn't expected to hold any event data. - /// When deserialization failed. - public void OnDeserialized() - { - if (this.RawEventData != null) - { - this.EventData = this.EventType switch - { - // General Events - EventType.ExitStarted => null, - EventType.VendorEvent => this.RawEventData.Value.Deserialize(), - EventType.CustomEvent => this.RawEventData.Value.Deserialize(), - - // Config Events - EventType.CurrentSceneCollectionChanging => this.RawEventData.Value.Deserialize(), - EventType.CurrentSceneCollectionChanged => this.RawEventData.Value.Deserialize(), - EventType.SceneCollectionListChanged => this.RawEventData.Value.Deserialize(), - EventType.CurrentProfileChanging => this.RawEventData.Value.Deserialize(), - EventType.CurrentProfileChanged => this.RawEventData.Value.Deserialize(), - EventType.ProfileListChanged => this.RawEventData.Value.Deserialize(), - - // Scenes Events - EventType.SceneCreated => this.RawEventData.Value.Deserialize(), - EventType.SceneRemoved => this.RawEventData.Value.Deserialize(), - EventType.SceneNameChanged => this.RawEventData.Value.Deserialize(), - EventType.CurrentProgramSceneChanged => this.RawEventData.Value.Deserialize(), - EventType.CurrentPreviewSceneChanged => this.RawEventData.Value.Deserialize(), - EventType.SceneListChanged => this.RawEventData.Value.Deserialize(), - - // Inputs Events - EventType.InputCreated => this.RawEventData.Value.Deserialize(), - EventType.InputRemoved => this.RawEventData.Value.Deserialize(), - EventType.InputNameChanged => this.RawEventData.Value.Deserialize(), - EventType.InputActiveStateChanged => this.RawEventData.Value.Deserialize(), - EventType.InputShowStateChanged => this.RawEventData.Value.Deserialize(), - EventType.InputMuteStateChanged => this.RawEventData.Value.Deserialize(), - EventType.InputVolumeChanged => this.RawEventData.Value.Deserialize(), - EventType.InputAudioBalanceChanged => this.RawEventData.Value.Deserialize(), - EventType.InputAudioSyncOffsetChanged => this.RawEventData.Value.Deserialize(), - EventType.InputAudioTracksChanged => this.RawEventData.Value.Deserialize(), - EventType.InputAudioMonitorTypeChanged => this.RawEventData.Value.Deserialize(), - EventType.InputVolumeMeters => this.RawEventData.Value.Deserialize(), - - // Transitions Events - EventType.CurrentSceneTransitionChanged => this.RawEventData.Value.Deserialize(), - EventType.CurrentSceneTransitionDurationChanged => this.RawEventData.Value.Deserialize(), - EventType.SceneTransitionStarted => this.RawEventData.Value.Deserialize(), - EventType.SceneTransitionEnded => this.RawEventData.Value.Deserialize(), - EventType.SceneTransitionVideoEnded => this.RawEventData.Value.Deserialize(), - - // Filters Events - EventType.SourceFilterListReindexed => this.RawEventData.Value.Deserialize(), - EventType.SourceFilterCreated => this.RawEventData.Value.Deserialize(), - EventType.SourceFilterRemoved => this.RawEventData.Value.Deserialize(), - EventType.SourceFilterNameChanged => this.RawEventData.Value.Deserialize(), - EventType.SourceFilterEnableStateChanged => this.RawEventData.Value.Deserialize(), - - // Scene Items Events - EventType.SceneItemCreated => this.RawEventData.Value.Deserialize(), - EventType.SceneItemRemoved => this.RawEventData.Value.Deserialize(), - EventType.SceneItemListReindexed => this.RawEventData.Value.Deserialize(), - EventType.SceneItemEnableStateChanged => this.RawEventData.Value.Deserialize(), - EventType.SceneItemLockStateChanged => this.RawEventData.Value.Deserialize(), - EventType.SceneItemSelected => this.RawEventData.Value.Deserialize(), - EventType.SceneItemTransformChanged => this.RawEventData.Value.Deserialize(), - - // Outputs Events - EventType.StreamStateChanged => this.RawEventData.Value.Deserialize(), - EventType.RecordStateChanged => this.RawEventData.Value.Deserialize(), - EventType.ReplayBufferStateChanged => this.RawEventData.Value.Deserialize(), - EventType.VirtualcamStateChanged => this.RawEventData.Value.Deserialize(), - EventType.ReplayBufferSaved => this.RawEventData.Value.Deserialize(), - - // Media Inputs Events - EventType.MediaInputPlaybackStarted => this.RawEventData.Value.Deserialize(), - EventType.MediaInputPlaybackEnded => this.RawEventData.Value.Deserialize(), - EventType.MediaInputActionTriggered => this.RawEventData.Value.Deserialize(), - EventType.StudioModeStateChanged => this.RawEventData.Value.Deserialize(), - EventType.ScreenshotSaved => this.RawEventData.Value.Deserialize(), - - // Otherwise... - _ => throw new NotImplementedException(), - }; - - if (this.EventData == null) - { - throw new ObsClientException("Deserialization failure of EventResponseData."); - } - } - } - } -} diff --git a/OBSClient/Messages/EventMessage.cs b/OBSClient/Messages/EventMessage.cs new file mode 100644 index 0000000..6ef10a2 --- /dev/null +++ b/OBSClient/Messages/EventMessage.cs @@ -0,0 +1,162 @@ +namespace OBSStudioClient.Messages +{ + using OBSStudioClient.Enums; + using OBSStudioClient.Events; + using OBSStudioClient.Exceptions; + using OBSStudioClient.Interfaces; + using System.Text.Json; + using System.Text.Json.Serialization; + + /// + /// Class for Event Messages + /// + public class EventMessage : IMessage, IJsonOnDeserialized + { + /// + /// Gets the type of the event based on the request type. + /// + private static readonly Dictionary _responseTypeMap = new() + { + // General Events + { EventType.VendorEvent, typeof(VendorEventEventArgs) }, + { EventType.CustomEvent, typeof(CustomEventEventArgs) }, + + // Config Events + { EventType.CurrentSceneCollectionChanging, typeof(SceneCollectionNameEventArgs) }, + { EventType.CurrentSceneCollectionChanged, typeof(SceneCollectionNameEventArgs) }, + { EventType.SceneCollectionListChanged, typeof(SceneCollectionListEventArgs) }, + { EventType.CurrentProfileChanging, typeof(ProfileNameEventArgs) }, + { EventType.CurrentProfileChanged, typeof(ProfileNameEventArgs) }, + { EventType.ProfileListChanged, typeof(ProfileListEventArgs) }, + + // Scenes Events + { EventType.SceneCreated, typeof(SceneModifiedEventArgs) }, + { EventType.SceneRemoved, typeof(SceneModifiedEventArgs) }, + { EventType.SceneNameChanged, typeof(SceneNameChangedEventArgs) }, + { EventType.CurrentProgramSceneChanged, typeof(SceneNameEventArgs) }, + { EventType.CurrentPreviewSceneChanged, typeof(SceneNameEventArgs) }, + { EventType.SceneListChanged, typeof(SceneListEventArgs) }, + + // Inputs Events + { EventType.InputCreated, typeof(InputCreatedEventArgs) }, + { EventType.InputRemoved, typeof(InputNameEventArgs) }, + { EventType.InputNameChanged, typeof(InputNameChangedEventArgs) }, + { EventType.InputActiveStateChanged, typeof(InputActiveStateChangedEventArgs) }, + { EventType.InputShowStateChanged, typeof(InputShowStateChangedEventArgs) }, + { EventType.InputMuteStateChanged, typeof(InputMuteStateChangedEventArgs) }, + { EventType.InputVolumeChanged, typeof(InputVolumeChangedEventArgs) }, + { EventType.InputAudioBalanceChanged, typeof(InputAudioBalanceChangedEventArgs) }, + { EventType.InputAudioSyncOffsetChanged, typeof(InputAudioSyncOffsetChangedEventArgs) }, + { EventType.InputAudioTracksChanged, typeof(InputAudioTracksChangedEventArgs) }, + { EventType.InputAudioMonitorTypeChanged, typeof(InputAudioMonitorTypeChangedEventArgs) }, + { EventType.InputVolumeMeters, typeof(InputVolumeMetersEventArgs) }, + + // Transitions Events + { EventType.CurrentSceneTransitionChanged, typeof(TransitionNameEventArgs) }, + { EventType.CurrentSceneTransitionDurationChanged, typeof(TransitionDurationEventArgs) }, + { EventType.SceneTransitionStarted, typeof(TransitionNameEventArgs) }, + { EventType.SceneTransitionEnded, typeof(TransitionNameEventArgs) }, + { EventType.SceneTransitionVideoEnded, typeof(TransitionNameEventArgs) }, + + // Filters Events + { EventType.SourceFilterListReindexed, typeof(SourceFiltersEventArgs) }, + { EventType.SourceFilterCreated, typeof(SourceFilterCreatedEventArgs) }, + { EventType.SourceFilterRemoved, typeof(SourceFilterRemovedEventArgs) }, + { EventType.SourceFilterNameChanged, typeof(SourceFilterNameChangedEventArgs) }, + { EventType.SourceFilterEnableStateChanged, typeof(SourceFilterEnableStateChangedEventArgs) }, + + // Scene Items Events + { EventType.SceneItemCreated, typeof(SceneItemCreatedEventArgs) }, + { EventType.SceneItemRemoved, typeof(SceneItemRemovedEventArgs) }, + { EventType.SceneItemListReindexed, typeof(SceneItemListReindexedEventArgs) }, + { EventType.SceneItemEnableStateChanged, typeof(SceneItemEnableStateChangedEventArgs) }, + { EventType.SceneItemLockStateChanged, typeof(SceneItemLockStateChangedEventArgs) }, + { EventType.SceneItemSelected, typeof(SceneItemSelectedEventArgs) }, + { EventType.SceneItemTransformChanged, typeof(SceneItemTransformChangedEventArgs) }, + + // Outputs Events + { EventType.StreamStateChanged, typeof(OutputStateChangedEventArgs) }, + { EventType.RecordStateChanged, typeof(RecordStateChangedEventArgs) }, + { EventType.ReplayBufferStateChanged, typeof(OutputStateChangedEventArgs) }, + { EventType.VirtualcamStateChanged, typeof(OutputStateChangedEventArgs) }, + { EventType.ReplayBufferSaved, typeof(ReplayBufferSavedEventArgs) }, + + // Media Inputs Events + { EventType.MediaInputPlaybackStarted, typeof(InputNameEventArgs) }, + { EventType.MediaInputPlaybackEnded, typeof(InputNameEventArgs) }, + { EventType.MediaInputActionTriggered, typeof(MediaInputActionTriggeredEventArgs) }, + { EventType.StudioModeStateChanged, typeof(StudioModeStateChangedEventArgs) }, + { EventType.ScreenshotSaved, typeof(ScreenshotSavedEventArgs) }, + }; + + /// + /// The type of Event + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + [JsonPropertyName("eventType")] + public EventType EventType { get; } + + /// + /// The Events you have subscribed to + /// + [JsonPropertyName("eventIntent")] + public EventSubscriptions EventIntent { get; } + + /// + /// The raw JSON data sent to or received from OBS Studio + /// + [JsonPropertyName("eventData")] + public JsonElement? RawEventData { get; } + + /// + /// The deserialized event + /// + [JsonIgnore] + public EventArgs EventData { get; private set; } + + /// + /// Creates a new instance of an object. + /// + /// The type of event. + /// The subscribed events. + /// The json data for the event data. + [JsonConstructor] + public EventMessage(EventType eventType, EventSubscriptions eventIntent, JsonElement? rawEventData) + { + this.EventType = eventType; + this.EventIntent = eventIntent; + this.RawEventData = rawEventData; + this.EventData = EventArgs.Empty; + } + + /// + /// Deserializes the raw JSON data to EventArgs. + /// + /// When the event isn't expected to hold any event data. + /// When deserialization failed. + public void OnDeserialized() + { + if (!this.RawEventData.HasValue) + { + if (_responseTypeMap.ContainsKey(this.EventType)) + { + throw new ObsClientException("OBS Studio returned an empty event."); + } + + return; + } + + if (!_responseTypeMap.TryGetValue(this.EventType, out Type? responseType)) + { + throw new ObsClientException("OBS Studio event could not be mapped."); + } + + if (JsonSerializer.Deserialize(this.RawEventData.Value.GetRawText(), responseType) is not EventArgs eventArgs) + { + throw new ObsClientException("OBS Studio event could not read."); + } + + this.EventData = eventArgs; + } + } +} diff --git a/OBSClient/MessageClasses/HelloMessage.cs b/OBSClient/Messages/HelloMessage.cs similarity index 97% rename from OBSClient/MessageClasses/HelloMessage.cs rename to OBSClient/Messages/HelloMessage.cs index cfb405a..6cb417a 100644 --- a/OBSClient/MessageClasses/HelloMessage.cs +++ b/OBSClient/Messages/HelloMessage.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/MessageClasses/IdentifiedMessage.cs b/OBSClient/Messages/IdentifiedMessage.cs similarity index 94% rename from OBSClient/MessageClasses/IdentifiedMessage.cs rename to OBSClient/Messages/IdentifiedMessage.cs index a94b26d..956b3c7 100644 --- a/OBSClient/MessageClasses/IdentifiedMessage.cs +++ b/OBSClient/Messages/IdentifiedMessage.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/MessageClasses/IdentifyMessage.cs b/OBSClient/Messages/IdentifyMessage.cs similarity index 97% rename from OBSClient/MessageClasses/IdentifyMessage.cs rename to OBSClient/Messages/IdentifyMessage.cs index 2c8afcd..6ada024 100644 --- a/OBSClient/MessageClasses/IdentifyMessage.cs +++ b/OBSClient/Messages/IdentifyMessage.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/MessageClasses/OBSMessage.cs b/OBSClient/Messages/ObsMessage.cs similarity index 96% rename from OBSClient/MessageClasses/OBSMessage.cs rename to OBSClient/Messages/ObsMessage.cs index a85eea3..055a2bd 100644 --- a/OBSClient/MessageClasses/OBSMessage.cs +++ b/OBSClient/Messages/ObsMessage.cs @@ -1,9 +1,8 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Enums; using OBSStudioClient.Exceptions; using OBSStudioClient.Interfaces; - using OBSStudioClient.Messages; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/OBSClient/MessageClasses/ReidentifyMessage.cs b/OBSClient/Messages/ReidentifyMessage.cs similarity index 94% rename from OBSClient/MessageClasses/ReidentifyMessage.cs rename to OBSClient/Messages/ReidentifyMessage.cs index 81c25b1..4e16f47 100644 --- a/OBSClient/MessageClasses/ReidentifyMessage.cs +++ b/OBSClient/Messages/ReidentifyMessage.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/MessageClasses/RequestBatchMessage.cs b/OBSClient/Messages/RequestBatchMessage.cs similarity index 97% rename from OBSClient/MessageClasses/RequestBatchMessage.cs rename to OBSClient/Messages/RequestBatchMessage.cs index dad1e8b..cba6516 100644 --- a/OBSClient/MessageClasses/RequestBatchMessage.cs +++ b/OBSClient/Messages/RequestBatchMessage.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/MessageClasses/RequestBatchResponseMessage.cs b/OBSClient/Messages/RequestBatchResponseMessage.cs similarity index 93% rename from OBSClient/MessageClasses/RequestBatchResponseMessage.cs rename to OBSClient/Messages/RequestBatchResponseMessage.cs index 3f2067e..cb3575c 100644 --- a/OBSClient/MessageClasses/RequestBatchResponseMessage.cs +++ b/OBSClient/Messages/RequestBatchResponseMessage.cs @@ -1,7 +1,6 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Interfaces; - using OBSStudioClient.Messages; using System.Text.Json.Serialization; /// diff --git a/OBSClient/MessageClasses/RequestMessage.cs b/OBSClient/Messages/RequestMessage.cs similarity index 98% rename from OBSClient/MessageClasses/RequestMessage.cs rename to OBSClient/Messages/RequestMessage.cs index da75855..ed3be1d 100644 --- a/OBSClient/MessageClasses/RequestMessage.cs +++ b/OBSClient/Messages/RequestMessage.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.MessageClasses +namespace OBSStudioClient.Messages { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/MessageClasses/RequestResponseMessage.cs b/OBSClient/Messages/RequestResponseMessage.cs similarity index 69% rename from OBSClient/MessageClasses/RequestResponseMessage.cs rename to OBSClient/Messages/RequestResponseMessage.cs index f695bf9..d539a4c 100644 --- a/OBSClient/MessageClasses/RequestResponseMessage.cs +++ b/OBSClient/Messages/RequestResponseMessage.cs @@ -4,6 +4,8 @@ using OBSStudioClient.Enums; using OBSStudioClient.Exceptions; using OBSStudioClient.Interfaces; + using OBSStudioClient.Requests; + using OBSStudioClient.Responses; using System; using System.Text.Json; using System.Text.Json.Serialization; @@ -13,6 +15,106 @@ /// public class RequestResponseMessage : IMessage, IJsonOnDeserialized { + /// + /// Gets the type of the response based on the request type. + /// + private static readonly Dictionary _responseTypeMap = new () + { + // General Requests + {RequestType.GetVersion, typeof(VersionResponse) }, + {RequestType.GetStats, typeof(StatsResponse) }, + {RequestType.CallVendorRequest, typeof(CallVendorResponse) }, + {RequestType.GetHotkeyList, typeof(HotkeysResponse) }, + + // Config Requests + {RequestType.GetPersistentData, typeof(SlotValueResponse) }, + {RequestType.GetSceneCollectionList, typeof(SceneCollectionListResponse) }, + {RequestType.GetProfileList, typeof(ProfileListResponse) }, + {RequestType.GetProfileParameter, typeof(ProfileParameterResponse) }, + {RequestType.GetVideoSettings, typeof(VideoSettingsResponse) }, + {RequestType.GetStreamServiceSettings, typeof(StreamServiceSettingsResponse) }, + {RequestType.GetRecordDirectory, typeof(RecordDirectoryResponse) }, + + // Sources Requests + {RequestType.GetSourceActive, typeof(SourceActiveResponse) }, + {RequestType.GetSourceScreenshot, typeof(ImageDataResponse) }, + {RequestType.SaveSourceScreenshot, typeof(ImageDataResponse) }, + + // Scenes Requests + {RequestType.GetSceneList, typeof(SceneListResponse) }, + {RequestType.GetGroupList, typeof(GroupsResponse) }, + {RequestType.GetCurrentProgramScene, typeof(CurrentProgramSceneNameResponse) }, + {RequestType.GetCurrentPreviewScene, typeof(CurrentPreviewSceneNameResponse) }, + {RequestType.GetSceneSceneTransitionOverride, typeof(SceneTransitionResponse) }, + + // Inputs Requests + {RequestType.GetInputList, typeof(InputsResponse) }, + {RequestType.GetInputKindList, typeof(InputKindsResponse) }, + {RequestType.GetSpecialInputs, typeof(SpecialInputsResponse) }, + {RequestType.CreateInput, typeof(SceneItemIdResponse) }, + {RequestType.GetInputDefaultSettings, typeof(DefaultInputSettingsResponse) }, + {RequestType.GetInputSettings, typeof(InputSettingsResponse) }, + {RequestType.GetInputMute, typeof(InputMutedResponse) }, + {RequestType.ToggleInputMute, typeof(InputMutedResponse) }, + {RequestType.GetInputVolume, typeof(InputVolumeResponse) }, + {RequestType.GetInputAudioBalance, typeof(InputAudioBalanceResponse) }, + {RequestType.GetInputAudioSyncOffset, typeof(InputAudioSyncOffsetResponse) }, + {RequestType.GetInputAudioMonitorType, typeof(InputAudioMonitorTypeResponse) }, + {RequestType.GetInputAudioTracks, typeof(InputAudioTracksResponse) }, + {RequestType.GetInputPropertiesListPropertyItems, typeof(PropertyItemsResponse) }, + + // Transitions Requests + {RequestType.GetTransitionKindList, typeof(TransitionKindsResponse) }, + {RequestType.GetSceneTransitionList, typeof(SceneTransitionListResponse) }, + {RequestType.GetCurrentSceneTransition, typeof(TransitionResponse) }, + {RequestType.GetCurrentSceneTransitionCursor, typeof(TransitionCursorResponse) }, + + // Filters Requests + {RequestType.GetSourceFilterList, typeof(FiltersResponse) }, + {RequestType.GetSourceFilterDefaultSettings, typeof(DefaultFilterSettingsResponse) }, + {RequestType.GetSourceFilter, typeof(SourceFilterResponse) }, + + // Scene Items Requests + {RequestType.GetSceneItemList, typeof(SceneItemsResponse) }, + {RequestType.GetGroupSceneItemList, typeof(SceneItemsResponse) }, + {RequestType.GetSceneItemId, typeof(SceneItemIdResponse) }, + {RequestType.CreateSceneItem, typeof(SceneItemIdResponse) }, + {RequestType.DuplicateSceneItem, typeof(SceneItemIdResponse) }, + {RequestType.GetSceneItemTransform, typeof(SceneItemIdResponse) }, + {RequestType.GetSceneItemEnabled, typeof(SceneItemEnabledResponse) }, + {RequestType.GetSceneItemLocked, typeof(SceneItemlockedResponse) }, + {RequestType.GetSceneItemIndex, typeof(SceneItemIndexResponse) }, + {RequestType.GetSceneItemBlendMode, typeof(SceneItemBlendModeResponse) }, + + // Outputs Requests + {RequestType.GetVirtualCamStatus, typeof(OutputActiveResponse) }, + {RequestType.ToggleVirtualCam, typeof(OutputActiveResponse) }, + {RequestType.GetReplayBufferStatus, typeof(OutputActiveResponse) }, + {RequestType.ToggleReplayBuffer, typeof(OutputActiveResponse) }, + {RequestType.GetLastReplayBufferReplay, typeof(SavedReplayPathResponse) }, + {RequestType.GetOutputList, typeof(OutputsResponse) }, + {RequestType.GetOutputStatus, typeof(OutputStatusResponse) }, + {RequestType.ToggleOutput, typeof(OutputActiveResponse) }, + {RequestType.GetOutputSettings, typeof(OutputSettingsResponse) }, + + // Stream Requests + {RequestType.GetStreamStatus, typeof(OutputStatusResponse) }, + {RequestType.ToggleStream, typeof(OutputActiveResponse) }, + + // Record Requests + {RequestType.GetRecordStatus, typeof(RecordStatusResponse) }, + {RequestType.ToggleRecord, typeof(OutputActiveResponse) }, + {RequestType.StopRecord, typeof(OutputPathResponse) }, + {RequestType.ToggleRecordPause, typeof(OutputPausedResponse) }, + + // Media Inputs Requests + {RequestType.GetMediaInputStatus, typeof(MediaInputStatusResponse) }, + + // Ui Requests + {RequestType.GetStudioModeEnabled, typeof(StudioModeEnabledResponse) }, + {RequestType.GetMonitorList, typeof(MonitorListResponse) }, + }; + /// /// The type of request this is a response to. /// @@ -68,6 +170,32 @@ public RequestResponseMessage(RequestType requestType, string requestId, Request /// Deserialization failed public void OnDeserialized() { + if (!this.RawResponseData.HasValue) + { + if (this.RequestStatus.Result && _responseTypeMap.ContainsKey(this.RequestType)) + { + throw new ObsClientException("OBS Studio returned an empty response."); + } + + return; + } + + if (!_responseTypeMap.TryGetValue(this.RequestType, out Type? responseType)) + { + throw new ObsClientException("OBS Studio response could not be mapped."); + } + + if (JsonSerializer.Deserialize(this.RawResponseData.Value.GetRawText(), responseType) is not IResponse response) + { + throw new ObsClientException("OBS Studio response could not be read."); + } + + this.ResponseData = response; + + /* + * V1 + * + if (this.RawResponseData != null) { this.ResponseData = this.RequestType switch @@ -147,7 +275,7 @@ public void OnDeserialized() // Transitions Requests RequestType.GetTransitionKindList => this.RawResponseData.Value.Deserialize(), RequestType.GetSceneTransitionList => this.RawResponseData.Value.Deserialize(), - RequestType.GetCurrentSceneTransition => this.RawResponseData.Value.Deserialize(), + RequestType.GetCurrentSceneTransition => this.RawResponseData.Value.Deserialize(), RequestType.SetCurrentSceneTransition => null, RequestType.SetCurrentSceneTransitionDuration => null, RequestType.SetCurrentSceneTransitionSettings => null, @@ -243,7 +371,8 @@ public void OnDeserialized() { throw new ObsClientException("Deserialization failure of RequestResponseData."); } - } + + */ } } } diff --git a/OBSClient/OBSClient.csproj b/OBSClient/OBSClient.csproj index 0466d3e..e02a5d4 100644 --- a/OBSClient/OBSClient.csproj +++ b/OBSClient/OBSClient.csproj @@ -15,15 +15,10 @@ git obs LICENSE - 1.3.0 + 2.0.0-preview.1 True - - - - - True diff --git a/OBSClient/ObsClient.cs b/OBSClient/ObsClient.cs index 18e582f..dc526f4 100644 --- a/OBSClient/ObsClient.cs +++ b/OBSClient/ObsClient.cs @@ -3,13 +3,14 @@ using OBSStudioClient.Enums; using OBSStudioClient.Exceptions; using OBSStudioClient.Interfaces; - using OBSStudioClient.MessageClasses; using OBSStudioClient.Messages; + using System; using System.Collections.Concurrent; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Net.WebSockets; + using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; @@ -23,9 +24,7 @@ /// public partial class ObsClient : INotifyPropertyChanged, IDisposable { - private string _hostname = "localhost"; - - private int _port = 4455; + private Uri _uri = new("ws://localhost:4455"); private string _password = string.Empty; @@ -41,15 +40,24 @@ public partial class ObsClient : INotifyPropertyChanged, IDisposable private TaskCompletionSource _authenticationComplete = new(); - private bool _disposed; + private bool _disposed = false; private readonly ConcurrentDictionary> _requests = new(); + private bool _autoReconnect = false; + + private readonly int _reconnectInterval = 3000; + + private readonly Timer _reconnectTimer; + + private readonly Dictionary _eventsMap = new(); + /// - /// The maximum amount of time, in milliseconds, to wait for an OBS Studio response after a request. + /// Gets or sets the maximum amount of time, in milliseconds, the to wait for an OBS Studio response after making a request. /// /// /// The minimum value is 150. Please take into account that when sending Batch Requests, specifically with long Sleep requests, this default value of 500 might not be enough. + /// Should a response not be received in time, an Exception will be thrown. /// public int RequestTimeout { @@ -59,20 +67,21 @@ public int RequestTimeout } set { - if (value < 150) - { - this._requestTimeout = 150; - } - else + value = Math.Max(value, 150); + if (this._requestTimeout != value) { this._requestTimeout = value; + this.OnPropertyChanged(); } } } /// - /// The current state of the connection to OBS Studio. + /// Gets the current state of the connection to OBS Studio. /// + /// + /// You should only call when this state is . + /// public ConnectionState ConnectionState { get @@ -90,41 +99,69 @@ private set } /// - /// Asynchronous event, triggered when the connection with OBS Studio is closed. + /// Gets or sets the value that indicates whether the should automatically try to reconnect to OBS Studio. /// - public event AsyncEventHandler? ConnectionClosed; + /// + /// When the value is True, the client will automatically try to reconnect to OBS Studio when: + /// - The connection was closed by OBS Studio + /// - You were kicked + /// - OBS Studio closed + /// - You sent an invalid message or your password was incorrect. + /// When you call , this setting is automatically set to False."/> + /// Setting it back to True, after calling , will automatically try to reconnect. + /// + public bool AutoReconnect + { + get + { + return this._autoReconnect; + } + set + { + if (this._autoReconnect != value) + { + if (value) + { + this._reconnectTimer.Change(this._reconnectInterval, this._reconnectInterval); + } + else + { + this._reconnectTimer.Change(Timeout.Infinite, Timeout.Infinite); + } - /// - /// Synchronous event, triggered when an important property changes. - /// - public event PropertyChangedEventHandler? PropertyChanged; + this._autoReconnect = value; + this.OnPropertyChanged(); + } + } + } /// - /// Async delegate for events that have event data. + /// Asynchronous event, triggered when the connection with OBS Studio is closed. /// - /// The type of event data. - /// The that initiated the event. - /// The event data. - /// A delegate for the event. - public delegate Task AsyncEventHandler(object? sender, T e) where T : EventArgs; + public event EventHandler? ConnectionClosed; /// - /// Async delegate for events that don't have event data. + /// Synchronous event, triggered when an important property changes. /// - /// The that initiated the event. - /// A delegate for the event. - public delegate Task AsyncEventHandler(object? sender); + public event PropertyChangedEventHandler? PropertyChanged; /// /// Creates a new instance of the class. /// public ObsClient() { + this._reconnectTimer = new(this.ReconnectTimerCallback, null, Timeout.Infinite, Timeout.Infinite); + // The _eventsMap is merely a helper, such that we don't have to invoke these reflection calls for every event. + foreach (var field in this.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Where(f => f.FieldType != typeof(PropertyChangedEventHandler) && f.FieldType.BaseType == typeof(MulticastDelegate))) + { + this._eventsMap.Add(field.Name, field); + } } /// /// Opens the connection to OBS Studio and tries to authenticate the session. /// + /// Value to indicate whether the client should automatically try to reconnect to OBS Studio. /// The OBS Studio WebSockets password or empty to connect without authentication. Defaults to empty. /// The hostname of the computer running OBS Studio to connect to. Defaults to "localhost". /// The Port on which the OBS Studio WebSocket interface is listenting. Default to 4455. @@ -133,31 +170,43 @@ public ObsClient() /// /// When True is returned, this does not mean that authentication has succeeded. Authentication will be handled asynchronously. /// You can use the event to see whether the is Connected, which indicates succesfull authenticaiton. + /// When the client is already connected, disconnect first. /// - public async Task ConnectAsync(string password = "", string hostname = "localhost", int port = 4455, EventSubscriptions eventSubscription = EventSubscriptions.All) + public async Task ConnectAsync(bool autoReconnect = false, string password = "", string hostname = "localhost", int port = 4455, EventSubscriptions eventSubscription = EventSubscriptions.All) { if (this._connectionState != ConnectionState.Disconnected) { return true; } - this._hostname = hostname; - this._port = port; + if (port is < 1 or > 65534) + { + throw new ArgumentOutOfRangeException(nameof(port), "Port number must be between 1 and 65534."); + } + + if (!Uri.TryCreate($"ws://{hostname}:{port}", UriKind.Absolute, out Uri? uri)) + { + throw new ArgumentException("Invalid hostname.", nameof(hostname)); + } + + this.AutoReconnect = autoReconnect; + this._uri = uri; this._password = password; this._eventSubscriptions = eventSubscription; this._cancellationTokenSource = new CancellationTokenSource(); - this._client = new(); this._authenticationComplete = new(); - if (!Uri.TryCreate($"ws://{this._hostname}:{this._port}", UriKind.Absolute, out Uri? uri)) - { - throw new ArgumentException("Invalid hostname or port number."); - } + return await this.StartAsync(); + } + private async Task StartAsync() + { + this._client = new(); this.ConnectionState = ConnectionState.Connecting; + try { - await this._client.ConnectAsync(uri, this._cancellationTokenSource.Token); + await this._client.ConnectAsync(this._uri, this._cancellationTokenSource.Token); } catch (WebSocketException) { @@ -165,7 +214,7 @@ public async Task ConnectAsync(string password = "", string hostname = "lo return false; } - _ = Task.Run(() => this.Receiver(this._cancellationTokenSource.Token)); + _ = Task.Run(() => this.ReceiverAsync(this._cancellationTokenSource.Token)); return this._authenticationComplete.Task.Result; } @@ -176,6 +225,7 @@ public void Disconnect() { if (this._connectionState != ConnectionState.Disconnected) { + this.AutoReconnect = false; this._cancellationTokenSource.Cancel(); } } @@ -187,7 +237,7 @@ public void Disconnect() /// The Requests in the batch. /// True, to continue processing requests even though one might have failed, or False to stop when any requests fails. /// The responses for the individual requests. - public async Task SendRequestBatch(RequestBatchExecutionType requestBatchExecutionType, RequestMessage[] requests, bool haltOnFailure = false) + public async Task SendRequestBatchAsync(RequestBatchExecutionType requestBatchExecutionType, RequestMessage[] requests, bool haltOnFailure = false) { TaskCompletionSource tcs = new(); CancellationTokenSource cts = new(this._requestTimeout); @@ -203,10 +253,8 @@ public async Task SendRequestBatch(RequestBatchExecuti { return requestBatchResponseData.Results; } - else - { - throw new ObsClientException("Unexpected response."); - } + + throw new ObsClientException($"Unexpected response type {result?.GetType().Name} in {MethodBase.GetCurrentMethod()?.Name}"); } /// @@ -302,7 +350,7 @@ private async Task ProcessHelloMessageAsync(ObsMessage responseMessage) } else { - throw new ObsClientException("responseMessage.Data is not expected HelloResponseData"); + throw new ObsClientException($"Unexpected response type {responseMessage.Data?.GetType().Name} in {MethodBase.GetCurrentMethod()?.Name}"); } } @@ -311,7 +359,7 @@ private void ProcessIdentifiedMessage(ObsMessage responseMessage) // We have succesfully authenticated - OR - we did a Reidentify. if (responseMessage.Data is not IdentifiedMessage) { - throw new ObsClientException("responseMessage.Data is not expected IdentifyResponseData"); + throw new ObsClientException($"Unexpected response type {responseMessage.Data?.GetType().Name} in {MethodBase.GetCurrentMethod()?.Name}"); } if (this._authenticationComplete.Task.Status != TaskStatus.RanToCompletion) this._authenticationComplete.SetResult(true); @@ -329,186 +377,24 @@ private void ProcessRequestResponseMessage(ObsMessage responseMessage) } else { - throw new ObsClientException("responseMessage.Data is not expected RequestResponseData"); + throw new ObsClientException($"Unexpected response type {responseMessage.Data?.GetType().Name} in {MethodBase.GetCurrentMethod()?.Name}"); } } private void ProcessEventMessage(ObsMessage responseMessage) { + if (responseMessage.Data is EventMessage eventResponseData) { - switch (eventResponseData.EventType) + if (this._eventsMap.TryGetValue(eventResponseData.EventType.ToString(), out var field) && field.GetValue(this) is MulticastDelegate eventDelegate) { - case EventType.ExitStarted: - this.ConnectionState = ConnectionState.Disconnecting; - this.InvokeAsyncEvent(ExitStarted); - break; - case EventType.VendorEvent: - this.InvokeAsyncEvent(VendorEvent, eventResponseData.EventData); - break; - case EventType.CustomEvent: - this.InvokeAsyncEvent(CustomEvent, eventResponseData.EventData); - break; - case EventType.CurrentSceneCollectionChanging: - this.InvokeAsyncEvent(CurrentSceneCollectionChanging, eventResponseData.EventData); - break; - case EventType.CurrentSceneCollectionChanged: - this.InvokeAsyncEvent(CurrentSceneCollectionChanged, eventResponseData.EventData); - break; - case EventType.SceneCollectionListChanged: - this.InvokeAsyncEvent(SceneCollectionListChanged, eventResponseData.EventData); - break; - case EventType.CurrentProfileChanging: - this.InvokeAsyncEvent(CurrentProfileChanging, eventResponseData.EventData); - break; - case EventType.CurrentProfileChanged: - this.InvokeAsyncEvent(CurrentProfileChanged, eventResponseData.EventData); - break; - case EventType.ProfileListChanged: - this.InvokeAsyncEvent(ProfileListChanged, eventResponseData.EventData); - break; - case EventType.SceneCreated: - this.InvokeAsyncEvent(SceneCreated, eventResponseData.EventData); - break; - case EventType.SceneRemoved: - this.InvokeAsyncEvent(SceneRemoved, eventResponseData.EventData); - break; - case EventType.SceneNameChanged: - this.InvokeAsyncEvent(SceneNameChanged, eventResponseData.EventData); - break; - case EventType.CurrentProgramSceneChanged: - this.InvokeAsyncEvent(CurrentProgramSceneChanged, eventResponseData.EventData); - break; - case EventType.CurrentPreviewSceneChanged: - this.InvokeAsyncEvent(CurrentPreviewSceneChanged, eventResponseData.EventData); - break; - case EventType.SceneListChanged: - this.InvokeAsyncEvent(SceneListChanged, eventResponseData.EventData); - break; - case EventType.InputCreated: - this.InvokeAsyncEvent(InputCreated, eventResponseData.EventData); - break; - case EventType.InputRemoved: - this.InvokeAsyncEvent(InputRemoved, eventResponseData.EventData); - break; - case EventType.InputNameChanged: - this.InvokeAsyncEvent(InputNameChanged, eventResponseData.EventData); - break; - case EventType.InputActiveStateChanged: - this.InvokeAsyncEvent(InputActiveStateChanged, eventResponseData.EventData); - break; - case EventType.InputShowStateChanged: - this.InvokeAsyncEvent(InputShowStateChanged, eventResponseData.EventData); - break; - case EventType.InputMuteStateChanged: - this.InvokeAsyncEvent(InputMuteStateChanged, eventResponseData.EventData); - break; - case EventType.InputVolumeChanged: - this.InvokeAsyncEvent(InputVolumeChanged, eventResponseData.EventData); - break; - case EventType.InputAudioBalanceChanged: - this.InvokeAsyncEvent(InputAudioBalanceChanged, eventResponseData.EventData); - break; - case EventType.InputAudioSyncOffsetChanged: - this.InvokeAsyncEvent(InputAudioSyncOffsetChanged, eventResponseData.EventData); - break; - case EventType.InputAudioTracksChanged: - this.InvokeAsyncEvent(InputAudioTracksChanged, eventResponseData.EventData); - break; - case EventType.InputAudioMonitorTypeChanged: - this.InvokeAsyncEvent(InputAudioMonitorTypeChanged, eventResponseData.EventData); - break; - case EventType.InputVolumeMeters: - this.InvokeAsyncEvent(InputVolumeMeters, eventResponseData.EventData); - break; - case EventType.CurrentSceneTransitionChanged: - this.InvokeAsyncEvent(CurrentSceneTransitionChanged, eventResponseData.EventData); - break; - case EventType.CurrentSceneTransitionDurationChanged: - this.InvokeAsyncEvent(CurrentSceneTransitionDurationChanged, eventResponseData.EventData); - break; - case EventType.SceneTransitionStarted: - this.InvokeAsyncEvent(SceneTransitionStarted, eventResponseData.EventData); - break; - case EventType.SceneTransitionEnded: - this.InvokeAsyncEvent(SceneTransitionEnded, eventResponseData.EventData); - break; - case EventType.SceneTransitionVideoEnded: - this.InvokeAsyncEvent(SceneTransitionVideoEnded, eventResponseData.EventData); - break; - case EventType.SourceFilterListReindexed: - this.InvokeAsyncEvent(SourceFilterListReindexed, eventResponseData.EventData); - break; - case EventType.SourceFilterCreated: - this.InvokeAsyncEvent(SourceFilterCreated, eventResponseData.EventData); - break; - case EventType.SourceFilterRemoved: - this.InvokeAsyncEvent(SourceFilterRemoved, eventResponseData.EventData); - break; - case EventType.SourceFilterNameChanged: - this.InvokeAsyncEvent(SourceFilterNameChanged, eventResponseData.EventData); - break; - case EventType.SourceFilterEnableStateChanged: - this.InvokeAsyncEvent(SourceFilterEnableStateChanged, eventResponseData.EventData); - break; - case EventType.SceneItemCreated: - this.InvokeAsyncEvent(SceneItemCreated, eventResponseData.EventData); - break; - case EventType.SceneItemRemoved: - this.InvokeAsyncEvent(SceneItemRemoved, eventResponseData.EventData); - break; - case EventType.SceneItemListReindexed: - this.InvokeAsyncEvent(SceneItemListReindexed, eventResponseData.EventData); - break; - case EventType.SceneItemEnableStateChanged: - this.InvokeAsyncEvent(SceneItemEnableStateChanged, eventResponseData.EventData); - break; - case EventType.SceneItemLockStateChanged: - this.InvokeAsyncEvent(SceneItemLockStateChanged, eventResponseData.EventData); - break; - case EventType.SceneItemSelected: - this.InvokeAsyncEvent(SceneItemSelected, eventResponseData.EventData); - break; - case EventType.SceneItemTransformChanged: - this.InvokeAsyncEvent(SceneItemTransformChanged, eventResponseData.EventData); - break; - case EventType.StreamStateChanged: - this.InvokeAsyncEvent(StreamStateChanged, eventResponseData.EventData); - break; - case EventType.RecordStateChanged: - this.InvokeAsyncEvent(RecordStateChanged, eventResponseData.EventData); - break; - case EventType.ReplayBufferStateChanged: - this.InvokeAsyncEvent(ReplayBufferStateChanged, eventResponseData.EventData); - break; - case EventType.VirtualcamStateChanged: - this.InvokeAsyncEvent(VirtualcamStateChanged, eventResponseData.EventData); - break; - case EventType.ReplayBufferSaved: - this.InvokeAsyncEvent(ReplayBufferSaved, eventResponseData.EventData); - break; - case EventType.MediaInputPlaybackStarted: - this.InvokeAsyncEvent(MediaInputPlaybackStarted, eventResponseData.EventData); - break; - case EventType.MediaInputPlaybackEnded: - this.InvokeAsyncEvent(MediaInputPlaybackEnded, eventResponseData.EventData); - break; - case EventType.MediaInputActionTriggered: - this.InvokeAsyncEvent(MediaInputActionTriggered, eventResponseData.EventData); - break; - case EventType.StudioModeStateChanged: - this.InvokeAsyncEvent(StudioModeStateChanged, eventResponseData.EventData); - break; - case EventType.ScreenshotSaved: - this.InvokeAsyncEvent(ScreenshotSaved, eventResponseData.EventData); - break; - default: - throw new ObsClientException($"Unknown Event '{eventResponseData.EventType}'"); + object[] args = eventResponseData.EventData == null ? new object[] { this } : new object[] { this, eventResponseData.EventData }; + _ = Task.WhenAll(eventDelegate.GetInvocationList().Select(handler => Task.Run(() => handler.Method.Invoke(handler.Target, args)))); } } else { - throw new ObsClientException("responseMessage.Data is not expected EventResponseData"); + throw new ObsClientException($"Unexpected response type {responseMessage.Data?.GetType().Name} in {MethodBase.GetCurrentMethod()?.Name}"); } } @@ -523,11 +409,11 @@ private void ProcessRequestBatchResponseMessage(ObsMessage responseMessage) } else { - throw new ObsClientException("responseMessage.Data is not expected RequestBatchResponseData"); + throw new ObsClientException($"Unexpected response type {responseMessage.Data?.GetType().Name} in {MethodBase.GetCurrentMethod()?.Name}"); } } - private async Task ResponseReceived(ObsMessage responseMessage) + private async Task ResponseReceivedAsync(ObsMessage responseMessage) { switch (responseMessage.Op) { @@ -550,45 +436,7 @@ private async Task ResponseReceived(ObsMessage responseMessage) case OpCode.Reidentify: case OpCode.Request: case OpCode.RequestBatch: - throw new ObsClientException($"OpCode '{responseMessage.Op}' is not expected to be received."); - default: - throw new ObsClientException($"Unknown OpCode '{responseMessage.Op}'"); - } - } - - private void InvokeAsyncEvent(AsyncEventHandler? asyncEventHandler, EventArgs? e) where T : EventArgs - { - if (asyncEventHandler is not null) - { - _ = Task.Factory.StartNew(async state => - { - try - { - await asyncEventHandler(this, (T)state!); - } - catch - { - // We don't care about consumers not being able to handle the event. - } - }, e ?? EventArgs.Empty, CancellationToken.None); - } - } - - private void InvokeAsyncEvent(AsyncEventHandler? asyncEventHandler) - { - if (asyncEventHandler is not null) - { - _ = Task.Factory.StartNew(async () => - { - try - { - await asyncEventHandler(this); - } - catch - { - // We don't care about consumers not being able to handle the event. - } - }, CancellationToken.None); + break; } } @@ -596,25 +444,23 @@ private async Task SendAsync(dynamic request) { if (this._client.State != WebSocketState.Open) { - throw new ObsClientException("Client is not connected."); + throw new ObsClientException("Not connected."); } -#if DEBUG Debug.WriteLine($"Sending: {JsonSerializer.Serialize(request)}"); -#endif - var bytes = JsonSerializer.SerializeToUtf8Bytes(request); var sendBuffer = new ArraySegment(bytes); await this._client.SendAsync(sendBuffer, WebSocketMessageType.Text, true, this._cancellationTokenSource.Token); } - private async Task Receiver(CancellationToken cancellationToken) + private async Task ReceiverAsync(CancellationToken cancellationToken) { var connectionOpen = true; while (!cancellationToken.IsCancellationRequested && connectionOpen) { StringBuilder responseBuilder = new(); var messageRead = false; + // Read one message. do { @@ -628,7 +474,8 @@ private async Task Receiver(CancellationToken cancellationToken) WebSocketCloseCode closeCode = res.CloseStatus.HasValue ? (WebSocketCloseCode)(int)res.CloseStatus.Value : WebSocketCloseCode.UnknownReason; await this._client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None); this.ConnectionState = ConnectionState.Disconnected; - this.InvokeAsyncEvent(ConnectionClosed, new ConnectionClosedEventArgs(closeCode, res.CloseStatusDescription ?? "Unknown")); + //this.InvokeAsyncEvent(ConnectionClosed, new ConnectionClosedEventArgs(closeCode, res.CloseStatusDescription ?? "Unknown")); + this.ConnectionClosed?.Invoke(this, new ConnectionClosedEventArgs(closeCode, res.CloseStatusDescription ?? "Unknown")); connectionOpen = false; if (closeCode == WebSocketCloseCode.AuthenticationFailed && this._authenticationComplete.Task.Status != TaskStatus.RanToCompletion) { @@ -652,18 +499,15 @@ private async Task Receiver(CancellationToken cancellationToken) { var response = responseBuilder.ToString(); -#if DEBUG Debug.WriteLine($"Received: {response}"); -#endif - ObsMessage? responseMessage = JsonSerializer.Deserialize(response); if (responseMessage == null) { - throw new ObsClientException("Could not deserialize OBS Studio message."); + throw new ObsClientException($"Could not read message from OBS Studio."); } else { - _ = Task.Run(() => this.ResponseReceived(responseMessage), CancellationToken.None).ConfigureAwait(false); + _ = Task.Run(() => this.ResponseReceivedAsync(responseMessage), CancellationToken.None).ConfigureAwait(false); } } } @@ -671,11 +515,11 @@ private async Task Receiver(CancellationToken cancellationToken) if (connectionOpen) { this.ConnectionState = ConnectionState.Disconnected; - this.InvokeAsyncEvent(ConnectionClosed, new ConnectionClosedEventArgs(WebSocketCloseCode.NormalClosure, "Disconnecting due to request.")); + this.ConnectionClosed?.Invoke(this, new ConnectionClosedEventArgs(WebSocketCloseCode.NormalClosure, "Disconnecting due to request.")); } } - private async Task SendAndWaitAsync(dynamic request) + private async Task SendAndWaitAsync(dynamic request) { if (this._connectionState != ConnectionState.Connected) { @@ -694,23 +538,11 @@ private async Task Receiver(CancellationToken cancellationToken) var result = tcs.Task.Result; return result; } - catch (ObsResponseException) - { - throw; - } - catch - { - // Something went wrong. We'll throw a generic error later. - } finally { this._requests.TryRemove(requestId, out _); } } - else - { - throw new ObsClientException($"Unexpected error trying to add an already added tasks ({requestId}) to the task list."); - } throw new TimeoutException($"Timeout waiting for OBS Studio response to request {requestId}."); } @@ -753,12 +585,20 @@ private async Task SendRequestAndWaitAsync(string reques throw new ObsResponseException(requestResponseData.RequestStatus); } } - else + + throw new ObsClientException($"Unexpected response type {result?.GetType().Name} for request {requestId} in {MethodBase.GetCurrentMethod()?.Name}"); + } + + private async void ReconnectTimerCallback(object? state) + { + if (this._autoReconnect && this._connectionState == ConnectionState.Disconnected) { - throw new ObsClientException($"Unexpected response from OBS Studio to request {requestId}."); + this.ConnectionState = ConnectionState.Connecting; + _ = await this.StartAsync(); } } + /// /// Disposes of the . /// @@ -767,6 +607,8 @@ protected virtual void Dispose(bool disposing) { if (!_disposed) { + this._reconnectTimer.Dispose(); + if (disposing) { this.Disconnect(); @@ -774,6 +616,7 @@ protected virtual void Dispose(bool disposing) } this._requests.Clear(); + this._eventsMap.Clear(); _disposed = true; } } diff --git a/OBSClient/ObsClient_ConfigRequests.cs b/OBSClient/ObsClient_ConfigRequests.cs index 427289e..870e2c1 100644 --- a/OBSClient/ObsClient_ConfigRequests.cs +++ b/OBSClient/ObsClient_ConfigRequests.cs @@ -1,7 +1,7 @@ namespace OBSStudioClient { using OBSStudioClient.Enums; - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_Events.cs b/OBSClient/ObsClient_Events.cs index c0a3c38..a8ddebe 100644 --- a/OBSClient/ObsClient_Events.cs +++ b/OBSClient/ObsClient_Events.cs @@ -13,7 +13,7 @@ public partial class ObsClient /// /// Occurs when OBS has begun the shutdown process. /// - public event AsyncEventHandler? ExitStarted; + public event EventHandler? ExitStarted; /// /// Occurs when an event has been emitted from a vendor. @@ -21,12 +21,12 @@ public partial class ObsClient /// /// A vendor is a unique name registered by a third-party plugin or script, which allows for custom requests and events to be added to obs-websocket. If a plugin or script implements vendor requests or events, documentation is expected to be provided with them. /// - public event AsyncEventHandler? VendorEvent; + public event EventHandler? VendorEvent; /// - /// Occurs when a custom event emitted by . + /// Occurs when a custom event emitted by . /// - public event AsyncEventHandler? CustomEvent; + public event EventHandler? CustomEvent; // // @@ -40,7 +40,7 @@ public partial class ObsClient /// /// Note: We recommend using this event to trigger a pause of all polling requests, as performing any requests during a scene collection change is considered undefined behavior and can cause crashes! /// - public event AsyncEventHandler? CurrentSceneCollectionChanging; + public event EventHandler? CurrentSceneCollectionChanging; /// /// Occurs when the current scene collection has changed. @@ -48,27 +48,27 @@ public partial class ObsClient /// /// Note: If polling has been paused during CurrentSceneCollectionChanging, this is the que to restart polling. /// - public event AsyncEventHandler? CurrentSceneCollectionChanged; + public event EventHandler? CurrentSceneCollectionChanged; /// /// Occurs when the scene collection list has changed. /// - public event AsyncEventHandler? SceneCollectionListChanged; + public event EventHandler? SceneCollectionListChanged; /// /// Occurs when the current profile has begun changing. /// - public event AsyncEventHandler? CurrentProfileChanging; + public event EventHandler? CurrentProfileChanging; /// /// Occurs when the current profile has changed. /// - public event AsyncEventHandler? CurrentProfileChanged; + public event EventHandler? CurrentProfileChanged; /// /// Occurs when the profile list has changed. /// - public event AsyncEventHandler? ProfileListChanged; + public event EventHandler? ProfileListChanged; // // @@ -79,32 +79,32 @@ public partial class ObsClient /// /// Occurs when a new scene has been created. /// - public event AsyncEventHandler? SceneCreated; + public event EventHandler? SceneCreated; /// /// Occurs when a scene has been removed. /// - public event AsyncEventHandler? SceneRemoved; + public event EventHandler? SceneRemoved; /// /// Occurs when the name of a scene has changed. /// - public event AsyncEventHandler? SceneNameChanged; + public event EventHandler? SceneNameChanged; /// /// Occurs when the current program scene has changed. /// - public event AsyncEventHandler? CurrentProgramSceneChanged; + public event EventHandler? CurrentProgramSceneChanged; /// /// Occurs when the current preview scene has changed. /// - public event AsyncEventHandler? CurrentPreviewSceneChanged; + public event EventHandler? CurrentPreviewSceneChanged; /// /// Occurs when the list of scenes has changed. /// - public event AsyncEventHandler? SceneListChanged; + public event EventHandler? SceneListChanged; // // @@ -115,17 +115,17 @@ public partial class ObsClient /// /// Occurs when an input has been created. /// - public event AsyncEventHandler? InputCreated; + public event EventHandler? InputCreated; /// /// Occurs when an input has been removed. /// - public event AsyncEventHandler? InputRemoved; + public event EventHandler? InputRemoved; /// /// Occurs when the name of an input has changed. /// - public event AsyncEventHandler? InputNameChanged; + public event EventHandler? InputNameChanged; /// /// Occurs when an input's active state has changed. @@ -133,7 +133,7 @@ public partial class ObsClient /// /// When an input is active, it means it's being shown by the program feed. /// - public event AsyncEventHandler? InputActiveStateChanged; + public event EventHandler? InputActiveStateChanged; /// /// Occurs when an input's show state has changed. @@ -141,42 +141,42 @@ public partial class ObsClient /// /// When an input is showing, it means it's being shown by the preview or a dialog. /// - public event AsyncEventHandler? InputShowStateChanged; + public event EventHandler? InputShowStateChanged; /// /// Occurs when an input's mute state has changed. /// - public event AsyncEventHandler? InputMuteStateChanged; + public event EventHandler? InputMuteStateChanged; /// /// Occurs when an input's volume level has changed. /// - public event AsyncEventHandler? InputVolumeChanged; + public event EventHandler? InputVolumeChanged; /// /// Occurs when the audio balance value of an input has changed. /// - public event AsyncEventHandler? InputAudioBalanceChanged; + public event EventHandler? InputAudioBalanceChanged; /// /// Occurs when the sync offset of an input has changed. /// - public event AsyncEventHandler? InputAudioSyncOffsetChanged; + public event EventHandler? InputAudioSyncOffsetChanged; /// /// Occurs when the audio tracks of an input have changed. /// - public event AsyncEventHandler? InputAudioTracksChanged; + public event EventHandler? InputAudioTracksChanged; /// /// Occurs when the monitor type of an input has changed. /// - public event AsyncEventHandler? InputAudioMonitorTypeChanged; + public event EventHandler? InputAudioMonitorTypeChanged; /// /// Occurs every 50 milliseconds providing volume levels of all active inputs. /// - public event AsyncEventHandler? InputVolumeMeters; + public event EventHandler? InputVolumeMeters; // // @@ -187,17 +187,17 @@ public partial class ObsClient /// /// Occurs when the current scene transition has changed. /// - public event AsyncEventHandler? CurrentSceneTransitionChanged; + public event EventHandler? CurrentSceneTransitionChanged; /// /// Occurs when the current scene transition duration has changed. /// - public event AsyncEventHandler? CurrentSceneTransitionDurationChanged; + public event EventHandler? CurrentSceneTransitionDurationChanged; /// /// Occurs when a scene transition has started. /// - public event AsyncEventHandler? SceneTransitionStarted; + public event EventHandler? SceneTransitionStarted; /// /// Occurs when a scene transition has completed fully. @@ -205,7 +205,7 @@ public partial class ObsClient /// /// Note: Does not appear to trigger when the transition is interrupted by the user. /// - public event AsyncEventHandler? SceneTransitionEnded; + public event EventHandler? SceneTransitionEnded; /// /// Occurs when a scene transition's video has completed fully. @@ -214,7 +214,7 @@ public partial class ObsClient /// Useful for stinger transitions to tell when the video actually ends. SceneTransitionEnded only signifies the cut point, not the completion of transition playback. /// Note: Appears to be called by every transition, regardless of relevance. /// - public event AsyncEventHandler? SceneTransitionVideoEnded; + public event EventHandler? SceneTransitionVideoEnded; // // @@ -225,27 +225,27 @@ public partial class ObsClient /// /// Occurs when a source's filter list has been reindexed. /// - public event AsyncEventHandler? SourceFilterListReindexed; + public event EventHandler? SourceFilterListReindexed; /// /// Occurs when a filter has been added to a source. /// - public event AsyncEventHandler? SourceFilterCreated; + public event EventHandler? SourceFilterCreated; /// /// Occurs when a filter has been removed from a source. /// - public event AsyncEventHandler? SourceFilterRemoved; + public event EventHandler? SourceFilterRemoved; /// /// Occurs when the name of a source filter has changed. /// - public event AsyncEventHandler? SourceFilterNameChanged; + public event EventHandler? SourceFilterNameChanged; /// /// Occurs when a source filter's enable state has changed. /// - public event AsyncEventHandler? SourceFilterEnableStateChanged; + public event EventHandler? SourceFilterEnableStateChanged; // // @@ -256,37 +256,37 @@ public partial class ObsClient /// /// Occurs when a scene item has been created. /// - public event AsyncEventHandler? SceneItemCreated; + public event EventHandler? SceneItemCreated; /// /// Occurs when a scene item has been removed. /// - public event AsyncEventHandler? SceneItemRemoved; + public event EventHandler? SceneItemRemoved; /// /// Occurs when a scene's item list has been reindexed. /// - public event AsyncEventHandler? SceneItemListReindexed; + public event EventHandler? SceneItemListReindexed; /// /// Occurs when a scene item's enable state has changed. /// - public event AsyncEventHandler? SceneItemEnableStateChanged; + public event EventHandler? SceneItemEnableStateChanged; /// /// Occurs when a scene item's lock state has changed. /// - public event AsyncEventHandler? SceneItemLockStateChanged; + public event EventHandler? SceneItemLockStateChanged; /// /// Occurs when a scene item has been selected in the Ui. /// - public event AsyncEventHandler? SceneItemSelected; + public event EventHandler? SceneItemSelected; /// /// Occurs when the transform/crop of a scene item has changed. /// - public event AsyncEventHandler? SceneItemTransformChanged; + public event EventHandler? SceneItemTransformChanged; // // @@ -297,27 +297,27 @@ public partial class ObsClient /// /// Occurs when the state of the stream output has changed. /// - public event AsyncEventHandler? StreamStateChanged; + public event EventHandler? StreamStateChanged; /// /// Occurs when the state of the record output has changed. /// - public event AsyncEventHandler? RecordStateChanged; + public event EventHandler? RecordStateChanged; /// /// Occurs when the state of the replay buffer output has changed. /// - public event AsyncEventHandler? ReplayBufferStateChanged; + public event EventHandler? ReplayBufferStateChanged; /// /// Occurs when the state of the virtualcam output has changed. /// - public event AsyncEventHandler? VirtualcamStateChanged; + public event EventHandler? VirtualcamStateChanged; /// /// Occurs when the replay buffer has been saved. /// - public event AsyncEventHandler? ReplayBufferSaved; + public event EventHandler? ReplayBufferSaved; // // @@ -328,17 +328,17 @@ public partial class ObsClient /// /// Occurs when a media input has started playing. /// - public event AsyncEventHandler? MediaInputPlaybackStarted; + public event EventHandler? MediaInputPlaybackStarted; /// /// Occurs when a media input has finished playing. /// - public event AsyncEventHandler? MediaInputPlaybackEnded; + public event EventHandler? MediaInputPlaybackEnded; /// /// Occurs when an action has been performed on an input. /// - public event AsyncEventHandler? MediaInputActionTriggered; + public event EventHandler? MediaInputActionTriggered; // // @@ -349,7 +349,7 @@ public partial class ObsClient /// /// Occurs when Studio mode has been enabled or disabled. /// - public event AsyncEventHandler? StudioModeStateChanged; + public event EventHandler? StudioModeStateChanged; /// /// Occurs when a screenshot has been saved. @@ -357,6 +357,6 @@ public partial class ObsClient /// /// Note: Triggered for the screenshot feature available in Settings -> Hotkeys -> Screenshot Output ONLY. Applications using Get/SaveSourceScreenshot should implement a CustomEvent if this kind of inter-client communication is desired. /// - public event AsyncEventHandler? ScreenshotSaved; + public event EventHandler? ScreenshotSaved; } } diff --git a/OBSClient/ObsClient_FiltersRequests.cs b/OBSClient/ObsClient_FiltersRequests.cs index bd528aa..2419560 100644 --- a/OBSClient/ObsClient_FiltersRequests.cs +++ b/OBSClient/ObsClient_FiltersRequests.cs @@ -1,7 +1,8 @@ namespace OBSStudioClient { using OBSStudioClient.Classes; - using OBSStudioClient.Messages; + using OBSStudioClient.Requests; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_GeneralRequests.cs b/OBSClient/ObsClient_GeneralRequests.cs index 522b5ce..1a376d0 100644 --- a/OBSClient/ObsClient_GeneralRequests.cs +++ b/OBSClient/ObsClient_GeneralRequests.cs @@ -2,7 +2,8 @@ { using OBSStudioClient.Classes; using OBSStudioClient.Enums; - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; + using System.Text.Json; public partial class ObsClient { @@ -28,7 +29,7 @@ public async Task GetStats() /// Broadcasts a CustomEvent to all WebSocket clients. Receivers are clients which are identified and subscribed. /// /// Data payload to emit to all receivers - public async Task BroadcastCustomEvent(object eventData) + public async Task BroadcastCustomEvent(JsonElement eventData) { await this.SendRequestAsync(new { eventData }); } @@ -39,9 +40,9 @@ public async Task BroadcastCustomEvent(object eventData) /// Name of the vendor to use /// The request type to call /// Object containing appropriate request data - public async Task CallVendorRequest(string vendorName, string requestType, object? requestData) + public async Task CallVendorRequest(string vendorName, string requestType, JsonElement? requestData) { - return await this.SendRequestAsync(new { vendorName, requestType, requestData }); + return await this.SendRequestAsync(new { vendorName, requestType, requestData }); } /// @@ -80,7 +81,7 @@ public async Task TriggerHotkeyByKeySequence(ObsKey? keyId, KeyModifier? keyModi /// Number of frames to sleep for (if SERIAL_FRAME mode) /// /// - /// This method was only added for your reference. You can use Sleep in and the method here is just added for parameter reference. + /// This method was only added for your reference. You can use Sleep in and the method here is just added for parameter reference. /// #pragma warning disable IDE0060 public void Sleep(int? sleepMillis, int? sleepFrames) diff --git a/OBSClient/ObsClient_InputsRequests.cs b/OBSClient/ObsClient_InputsRequests.cs index 8a220c9..e6a1e26 100644 --- a/OBSClient/ObsClient_InputsRequests.cs +++ b/OBSClient/ObsClient_InputsRequests.cs @@ -3,6 +3,7 @@ using OBSStudioClient.Classes; using OBSStudioClient.Enums; using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_MediaInputsRequests.cs b/OBSClient/ObsClient_MediaInputsRequests.cs index c7b9938..877ceb7 100644 --- a/OBSClient/ObsClient_MediaInputsRequests.cs +++ b/OBSClient/ObsClient_MediaInputsRequests.cs @@ -1,7 +1,7 @@ namespace OBSStudioClient { using OBSStudioClient.Enums; - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_OutputsRequests.cs b/OBSClient/ObsClient_OutputsRequests.cs index 4ca5990..6940e27 100644 --- a/OBSClient/ObsClient_OutputsRequests.cs +++ b/OBSClient/ObsClient_OutputsRequests.cs @@ -1,7 +1,7 @@ namespace OBSStudioClient { using OBSStudioClient.Classes; - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; using System.Collections.Generic; public partial class ObsClient diff --git a/OBSClient/ObsClient_RecordRequests.cs b/OBSClient/ObsClient_RecordRequests.cs index e5f2862..5e015c5 100644 --- a/OBSClient/ObsClient_RecordRequests.cs +++ b/OBSClient/ObsClient_RecordRequests.cs @@ -1,6 +1,6 @@ namespace OBSStudioClient { - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_SceneItemsRequests.cs b/OBSClient/ObsClient_SceneItemsRequests.cs index a757206..8aa7c0c 100644 --- a/OBSClient/ObsClient_SceneItemsRequests.cs +++ b/OBSClient/ObsClient_SceneItemsRequests.cs @@ -2,7 +2,7 @@ { using OBSStudioClient.Classes; using OBSStudioClient.Enums; - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_ScenesRequests.cs b/OBSClient/ObsClient_ScenesRequests.cs index 0dad7db..1ce3aec 100644 --- a/OBSClient/ObsClient_ScenesRequests.cs +++ b/OBSClient/ObsClient_ScenesRequests.cs @@ -1,6 +1,6 @@ namespace OBSStudioClient { - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_SourcesRequests.cs b/OBSClient/ObsClient_SourcesRequests.cs index 6009f58..7a2b692 100644 --- a/OBSClient/ObsClient_SourcesRequests.cs +++ b/OBSClient/ObsClient_SourcesRequests.cs @@ -1,6 +1,6 @@ namespace OBSStudioClient { - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_StreamRequests.cs b/OBSClient/ObsClient_StreamRequests.cs index 22a2cde..2554ab0 100644 --- a/OBSClient/ObsClient_StreamRequests.cs +++ b/OBSClient/ObsClient_StreamRequests.cs @@ -1,6 +1,6 @@ namespace OBSStudioClient { - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/ObsClient_TransitionsRequests.cs b/OBSClient/ObsClient_TransitionsRequests.cs index 49f5769..7d02dfb 100644 --- a/OBSClient/ObsClient_TransitionsRequests.cs +++ b/OBSClient/ObsClient_TransitionsRequests.cs @@ -1,6 +1,6 @@ namespace OBSStudioClient { - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { @@ -25,10 +25,10 @@ public async Task GetSceneTransitionList() /// /// Gets information about the current scene transition. /// - /// A - public async Task GetCurrentSceneTransition() + /// A + public async Task GetCurrentSceneTransition() { - return await this.SendRequestAsync(); + return await this.SendRequestAsync(); } /// @@ -57,7 +57,7 @@ public async Task SetCurrentSceneTransitionDuration(float transitionDuration) /// /// Settings object to apply to the transition. Can be {} /// Whether to overlay over the current settings or replace them - public async Task SetCurrentSceneTransitionSettings(ExtendedTransitionResponse? transitionSettings, bool overlay = true) + public async Task SetCurrentSceneTransitionSettings(TransitionResponse? transitionSettings, bool overlay = true) { await this.SendRequestAsync(new { transitionSettings, overlay }); } diff --git a/OBSClient/ObsClient_UiRequests.cs b/OBSClient/ObsClient_UiRequests.cs index b562115..d294e14 100644 --- a/OBSClient/ObsClient_UiRequests.cs +++ b/OBSClient/ObsClient_UiRequests.cs @@ -2,7 +2,7 @@ { using OBSStudioClient.Classes; using OBSStudioClient.Enums; - using OBSStudioClient.Messages; + using OBSStudioClient.Responses; public partial class ObsClient { diff --git a/OBSClient/Messages/CaptionTextRequest.cs b/OBSClient/Requests/CaptionTextRequest.cs similarity index 95% rename from OBSClient/Messages/CaptionTextRequest.cs rename to OBSClient/Requests/CaptionTextRequest.cs index 8ed413d..ba7bb1f 100644 --- a/OBSClient/Messages/CaptionTextRequest.cs +++ b/OBSClient/Requests/CaptionTextRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/CreateSceneItemRequest.cs b/OBSClient/Requests/CreateSceneItemRequest.cs similarity index 97% rename from OBSClient/Messages/CreateSceneItemRequest.cs rename to OBSClient/Requests/CreateSceneItemRequest.cs index bd7da8d..27c68de 100644 --- a/OBSClient/Messages/CreateSceneItemRequest.cs +++ b/OBSClient/Requests/CreateSceneItemRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/DuplicateSceneRequest.cs b/OBSClient/Requests/DuplicateSceneRequest.cs similarity index 97% rename from OBSClient/Messages/DuplicateSceneRequest.cs rename to OBSClient/Requests/DuplicateSceneRequest.cs index 0b59aed..33ac3db 100644 --- a/OBSClient/Messages/DuplicateSceneRequest.cs +++ b/OBSClient/Requests/DuplicateSceneRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/HotkeyNameRequest.cs b/OBSClient/Requests/HotkeyNameRequest.cs similarity index 94% rename from OBSClient/Messages/HotkeyNameRequest.cs rename to OBSClient/Requests/HotkeyNameRequest.cs index 113f1c8..cfbf73b 100644 --- a/OBSClient/Messages/HotkeyNameRequest.cs +++ b/OBSClient/Requests/HotkeyNameRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputNameRequest.cs b/OBSClient/Requests/InputNameRequest.cs similarity index 94% rename from OBSClient/Messages/InputNameRequest.cs rename to OBSClient/Requests/InputNameRequest.cs index 0ca1702..2411949 100644 --- a/OBSClient/Messages/InputNameRequest.cs +++ b/OBSClient/Requests/InputNameRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/MediaInputActionRequest.cs b/OBSClient/Requests/MediaInputActionRequest.cs similarity index 96% rename from OBSClient/Messages/MediaInputActionRequest.cs rename to OBSClient/Requests/MediaInputActionRequest.cs index 0ea0f8a..a3995f8 100644 --- a/OBSClient/Messages/MediaInputActionRequest.cs +++ b/OBSClient/Requests/MediaInputActionRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using OBSStudioClient.Enums; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/MediaInputCursorOffsetRequest.cs b/OBSClient/Requests/MediaInputCursorOffsetRequest.cs similarity index 96% rename from OBSClient/Messages/MediaInputCursorOffsetRequest.cs rename to OBSClient/Requests/MediaInputCursorOffsetRequest.cs index 6b5268a..728f4a1 100644 --- a/OBSClient/Messages/MediaInputCursorOffsetRequest.cs +++ b/OBSClient/Requests/MediaInputCursorOffsetRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/MediaInputCursorRequest.cs b/OBSClient/Requests/MediaInputCursorRequest.cs similarity index 96% rename from OBSClient/Messages/MediaInputCursorRequest.cs rename to OBSClient/Requests/MediaInputCursorRequest.cs index 21e5c3b..fb22db7 100644 --- a/OBSClient/Messages/MediaInputCursorRequest.cs +++ b/OBSClient/Requests/MediaInputCursorRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/OutputNameRequest.cs b/OBSClient/Requests/OutputNameRequest.cs similarity index 95% rename from OBSClient/Messages/OutputNameRequest.cs rename to OBSClient/Requests/OutputNameRequest.cs index e133cc0..7ad5821 100644 --- a/OBSClient/Messages/OutputNameRequest.cs +++ b/OBSClient/Requests/OutputNameRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/OutputSettingsRequest.cs b/OBSClient/Requests/OutputSettingsRequest.cs similarity index 96% rename from OBSClient/Messages/OutputSettingsRequest.cs rename to OBSClient/Requests/OutputSettingsRequest.cs index 00666d8..d0c9a66 100644 --- a/OBSClient/Messages/OutputSettingsRequest.cs +++ b/OBSClient/Requests/OutputSettingsRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/RecordDirectoryRequest.cs b/OBSClient/Requests/RecordDirectoryRequest.cs similarity index 95% rename from OBSClient/Messages/RecordDirectoryRequest.cs rename to OBSClient/Requests/RecordDirectoryRequest.cs index e9cf7d3..22e3214 100644 --- a/OBSClient/Messages/RecordDirectoryRequest.cs +++ b/OBSClient/Requests/RecordDirectoryRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemBlendModeRequest.cs b/OBSClient/Requests/SceneItemBlendModeRequest.cs similarity index 96% rename from OBSClient/Messages/SceneItemBlendModeRequest.cs rename to OBSClient/Requests/SceneItemBlendModeRequest.cs index c4d2257..b0ac895 100644 --- a/OBSClient/Messages/SceneItemBlendModeRequest.cs +++ b/OBSClient/Requests/SceneItemBlendModeRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using OBSStudioClient.Enums; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemEnabledRequest.cs b/OBSClient/Requests/SceneItemEnabledRequest.cs similarity index 96% rename from OBSClient/Messages/SceneItemEnabledRequest.cs rename to OBSClient/Requests/SceneItemEnabledRequest.cs index 36f7321..91adfa6 100644 --- a/OBSClient/Messages/SceneItemEnabledRequest.cs +++ b/OBSClient/Requests/SceneItemEnabledRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemIdRequest.cs b/OBSClient/Requests/SceneItemIdRequest.cs similarity index 97% rename from OBSClient/Messages/SceneItemIdRequest.cs rename to OBSClient/Requests/SceneItemIdRequest.cs index 8d8a012..bacb41c 100644 --- a/OBSClient/Messages/SceneItemIdRequest.cs +++ b/OBSClient/Requests/SceneItemIdRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemIndexRequest.cs b/OBSClient/Requests/SceneItemIndexRequest.cs similarity index 90% rename from OBSClient/Messages/SceneItemIndexRequest.cs rename to OBSClient/Requests/SceneItemIndexRequest.cs index fc920a5..1cd5a74 100644 --- a/OBSClient/Messages/SceneItemIndexRequest.cs +++ b/OBSClient/Requests/SceneItemIndexRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; @@ -20,7 +20,7 @@ public class SceneItemIndexRequest : SceneItemRequest /// The scene item id. /// The scene item index. [JsonConstructor] - public SceneItemIndexRequest(string sceneName, int sceneItemId, int sceneItemIndex) : base (sceneName, sceneItemId) + public SceneItemIndexRequest(string sceneName, int sceneItemId, int sceneItemIndex) : base(sceneName, sceneItemId) { this.SceneItemIndex = sceneItemIndex; } diff --git a/OBSClient/Messages/SceneItemLockedRequest.cs b/OBSClient/Requests/SceneItemLockedRequest.cs similarity index 96% rename from OBSClient/Messages/SceneItemLockedRequest.cs rename to OBSClient/Requests/SceneItemLockedRequest.cs index 2fea489..a51f1fc 100644 --- a/OBSClient/Messages/SceneItemLockedRequest.cs +++ b/OBSClient/Requests/SceneItemLockedRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemRequest.cs b/OBSClient/Requests/SceneItemRequest.cs similarity index 96% rename from OBSClient/Messages/SceneItemRequest.cs rename to OBSClient/Requests/SceneItemRequest.cs index 6c751b5..f1ac819 100644 --- a/OBSClient/Messages/SceneItemRequest.cs +++ b/OBSClient/Requests/SceneItemRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemTransformRequest.cs b/OBSClient/Requests/SceneItemTransformRequest.cs similarity index 96% rename from OBSClient/Messages/SceneItemTransformRequest.cs rename to OBSClient/Requests/SceneItemTransformRequest.cs index b6074ec..0f7622d 100644 --- a/OBSClient/Messages/SceneItemTransformRequest.cs +++ b/OBSClient/Requests/SceneItemTransformRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using OBSStudioClient.Classes; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneNameRequest.cs b/OBSClient/Requests/SceneNameRequest.cs similarity index 94% rename from OBSClient/Messages/SceneNameRequest.cs rename to OBSClient/Requests/SceneNameRequest.cs index ff60bb8..c1142c3 100644 --- a/OBSClient/Messages/SceneNameRequest.cs +++ b/OBSClient/Requests/SceneNameRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneTransitionRequest.cs b/OBSClient/Requests/SceneTransitionRequest.cs similarity index 97% rename from OBSClient/Messages/SceneTransitionRequest.cs rename to OBSClient/Requests/SceneTransitionRequest.cs index 9840bdf..952d497 100644 --- a/OBSClient/Messages/SceneTransitionRequest.cs +++ b/OBSClient/Requests/SceneTransitionRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/ScreenshotFileRequest.cs b/OBSClient/Requests/ScreenshotFileRequest.cs similarity index 93% rename from OBSClient/Messages/ScreenshotFileRequest.cs rename to OBSClient/Requests/ScreenshotFileRequest.cs index b36f44f..89f1df2 100644 --- a/OBSClient/Messages/ScreenshotFileRequest.cs +++ b/OBSClient/Requests/ScreenshotFileRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/ScreenshotRequest.cs b/OBSClient/Requests/ScreenshotRequest.cs similarity index 98% rename from OBSClient/Messages/ScreenshotRequest.cs rename to OBSClient/Requests/ScreenshotRequest.cs index 550db25..98587f2 100644 --- a/OBSClient/Messages/ScreenshotRequest.cs +++ b/OBSClient/Requests/ScreenshotRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SetSceneNameRequest.cs b/OBSClient/Requests/SetSceneNameRequest.cs similarity index 96% rename from OBSClient/Messages/SetSceneNameRequest.cs rename to OBSClient/Requests/SetSceneNameRequest.cs index 9b8cb31..df0ab0f 100644 --- a/OBSClient/Messages/SetSceneNameRequest.cs +++ b/OBSClient/Requests/SetSceneNameRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SourceFilterResponse.cs b/OBSClient/Requests/SourceFilterResponse.cs similarity index 96% rename from OBSClient/Messages/SourceFilterResponse.cs rename to OBSClient/Requests/SourceFilterResponse.cs index a315898..889915e 100644 --- a/OBSClient/Messages/SourceFilterResponse.cs +++ b/OBSClient/Requests/SourceFilterResponse.cs @@ -1,6 +1,5 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { - using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SourceNameRequest.cs b/OBSClient/Requests/SourceNameRequest.cs similarity index 95% rename from OBSClient/Messages/SourceNameRequest.cs rename to OBSClient/Requests/SourceNameRequest.cs index 6289a8d..1581713 100644 --- a/OBSClient/Messages/SourceNameRequest.cs +++ b/OBSClient/Requests/SourceNameRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SourceProjectorRequest.cs b/OBSClient/Requests/SourceProjectorRequest.cs similarity index 95% rename from OBSClient/Messages/SourceProjectorRequest.cs rename to OBSClient/Requests/SourceProjectorRequest.cs index c7e2324..35814c1 100644 --- a/OBSClient/Messages/SourceProjectorRequest.cs +++ b/OBSClient/Requests/SourceProjectorRequest.cs @@ -1,5 +1,6 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { + using OBSStudioClient; using System.Text.Json.Serialization; /// diff --git a/OBSClient/Messages/TriggerHotkeyBySequenceRequest.cs b/OBSClient/Requests/TriggerHotkeyBySequenceRequest.cs similarity index 97% rename from OBSClient/Messages/TriggerHotkeyBySequenceRequest.cs rename to OBSClient/Requests/TriggerHotkeyBySequenceRequest.cs index bda4adb..e5131cd 100644 --- a/OBSClient/Messages/TriggerHotkeyBySequenceRequest.cs +++ b/OBSClient/Requests/TriggerHotkeyBySequenceRequest.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { using OBSStudioClient.Classes; using OBSStudioClient.Enums; diff --git a/OBSClient/Messages/VideoMixProjectorRequest.cs b/OBSClient/Requests/VideoMixProjectorRequest.cs similarity index 96% rename from OBSClient/Messages/VideoMixProjectorRequest.cs rename to OBSClient/Requests/VideoMixProjectorRequest.cs index 881234a..5c1ae84 100644 --- a/OBSClient/Messages/VideoMixProjectorRequest.cs +++ b/OBSClient/Requests/VideoMixProjectorRequest.cs @@ -1,5 +1,6 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Requests { + using OBSStudioClient; using OBSStudioClient.Enums; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/CallVendorRequestResponse.cs b/OBSClient/Responses/CallVendorResponse.cs similarity index 81% rename from OBSClient/Messages/CallVendorRequestResponse.cs rename to OBSClient/Responses/CallVendorResponse.cs index ab3e428..9101308 100644 --- a/OBSClient/Messages/CallVendorRequestResponse.cs +++ b/OBSClient/Responses/CallVendorResponse.cs @@ -1,12 +1,13 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; + using System.Text.Json; using System.Text.Json.Serialization; /// /// Provides the Response Data () in the Response Message () returned by OBS Studio after sending a successful CallVendorRequest request. /// - public class CallVendorRequestResponse : IResponse + public class CallVendorResponse : IResponse { /// /// Gets the name of the vendor. @@ -24,15 +25,15 @@ public class CallVendorRequestResponse : IResponse /// Gets the response data object, as defined by the vendor. /// [JsonPropertyName("responseData")] - public object? ResponseData { get; } + public JsonElement? ResponseData { get; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Name of the vendor. /// Type of request. /// The response data. - public CallVendorRequestResponse(string vendorName, string requestType, object? responseData) + public CallVendorResponse(string vendorName, string requestType, JsonElement? responseData) { this.VendorName = vendorName; this.RequestType = requestType; diff --git a/OBSClient/Messages/CurrentPreviewSceneNameResponse.cs b/OBSClient/Responses/CurrentPreviewSceneNameResponse.cs similarity index 96% rename from OBSClient/Messages/CurrentPreviewSceneNameResponse.cs rename to OBSClient/Responses/CurrentPreviewSceneNameResponse.cs index e0541e3..7631c97 100644 --- a/OBSClient/Messages/CurrentPreviewSceneNameResponse.cs +++ b/OBSClient/Responses/CurrentPreviewSceneNameResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/CurrentProgramSceneNameResponse.cs b/OBSClient/Responses/CurrentProgramSceneNameResponse.cs similarity index 96% rename from OBSClient/Messages/CurrentProgramSceneNameResponse.cs rename to OBSClient/Responses/CurrentProgramSceneNameResponse.cs index 8ad0f1b..5a5018f 100644 --- a/OBSClient/Messages/CurrentProgramSceneNameResponse.cs +++ b/OBSClient/Responses/CurrentProgramSceneNameResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/DefaultFilterSettingsResponse.cs b/OBSClient/Responses/DefaultFilterSettingsResponse.cs similarity index 96% rename from OBSClient/Messages/DefaultFilterSettingsResponse.cs rename to OBSClient/Responses/DefaultFilterSettingsResponse.cs index 8cde2d8..6c13291 100644 --- a/OBSClient/Messages/DefaultFilterSettingsResponse.cs +++ b/OBSClient/Responses/DefaultFilterSettingsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/DefaultInputSettingsResponse.cs b/OBSClient/Responses/DefaultInputSettingsResponse.cs similarity index 96% rename from OBSClient/Messages/DefaultInputSettingsResponse.cs rename to OBSClient/Responses/DefaultInputSettingsResponse.cs index aada6a5..3d12fac 100644 --- a/OBSClient/Messages/DefaultInputSettingsResponse.cs +++ b/OBSClient/Responses/DefaultInputSettingsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/FiltersResponse.cs b/OBSClient/Responses/FiltersResponse.cs similarity index 95% rename from OBSClient/Messages/FiltersResponse.cs rename to OBSClient/Responses/FiltersResponse.cs index 43b1fa5..7042b52 100644 --- a/OBSClient/Messages/FiltersResponse.cs +++ b/OBSClient/Responses/FiltersResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/GroupsResponse.cs b/OBSClient/Responses/GroupsResponse.cs similarity index 95% rename from OBSClient/Messages/GroupsResponse.cs rename to OBSClient/Responses/GroupsResponse.cs index 24c5eda..24c265b 100644 --- a/OBSClient/Messages/GroupsResponse.cs +++ b/OBSClient/Responses/GroupsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/HotkeysResponse.cs b/OBSClient/Responses/HotkeysResponse.cs similarity index 95% rename from OBSClient/Messages/HotkeysResponse.cs rename to OBSClient/Responses/HotkeysResponse.cs index 715e55f..ca6d86f 100644 --- a/OBSClient/Messages/HotkeysResponse.cs +++ b/OBSClient/Responses/HotkeysResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/ImageDataResponse.cs b/OBSClient/Responses/ImageDataResponse.cs similarity index 95% rename from OBSClient/Messages/ImageDataResponse.cs rename to OBSClient/Responses/ImageDataResponse.cs index d426ccf..6822063 100644 --- a/OBSClient/Messages/ImageDataResponse.cs +++ b/OBSClient/Responses/ImageDataResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputAudioBalanceResponse.cs b/OBSClient/Responses/InputAudioBalanceResponse.cs similarity index 96% rename from OBSClient/Messages/InputAudioBalanceResponse.cs rename to OBSClient/Responses/InputAudioBalanceResponse.cs index f35feb6..de8f758 100644 --- a/OBSClient/Messages/InputAudioBalanceResponse.cs +++ b/OBSClient/Responses/InputAudioBalanceResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputAudioMonitorTypeResponse.cs b/OBSClient/Responses/InputAudioMonitorTypeResponse.cs similarity index 96% rename from OBSClient/Messages/InputAudioMonitorTypeResponse.cs rename to OBSClient/Responses/InputAudioMonitorTypeResponse.cs index 0563e14..13b618e 100644 --- a/OBSClient/Messages/InputAudioMonitorTypeResponse.cs +++ b/OBSClient/Responses/InputAudioMonitorTypeResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/InputAudioSyncOffsetResponse.cs b/OBSClient/Responses/InputAudioSyncOffsetResponse.cs similarity index 96% rename from OBSClient/Messages/InputAudioSyncOffsetResponse.cs rename to OBSClient/Responses/InputAudioSyncOffsetResponse.cs index 95dafec..06a6cb0 100644 --- a/OBSClient/Messages/InputAudioSyncOffsetResponse.cs +++ b/OBSClient/Responses/InputAudioSyncOffsetResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputAudioTracksResponse.cs b/OBSClient/Responses/InputAudioTracksResponse.cs similarity index 96% rename from OBSClient/Messages/InputAudioTracksResponse.cs rename to OBSClient/Responses/InputAudioTracksResponse.cs index 08c0920..fdb4820 100644 --- a/OBSClient/Messages/InputAudioTracksResponse.cs +++ b/OBSClient/Responses/InputAudioTracksResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/InputKindsResponse.cs b/OBSClient/Responses/InputKindsResponse.cs similarity index 95% rename from OBSClient/Messages/InputKindsResponse.cs rename to OBSClient/Responses/InputKindsResponse.cs index fc295c9..c68b2d3 100644 --- a/OBSClient/Messages/InputKindsResponse.cs +++ b/OBSClient/Responses/InputKindsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputMutedResponse.cs b/OBSClient/Responses/InputMutedResponse.cs similarity index 96% rename from OBSClient/Messages/InputMutedResponse.cs rename to OBSClient/Responses/InputMutedResponse.cs index 9bbc4f4..f72d5aa 100644 --- a/OBSClient/Messages/InputMutedResponse.cs +++ b/OBSClient/Responses/InputMutedResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputSettingsResponse.cs b/OBSClient/Responses/InputSettingsResponse.cs similarity index 96% rename from OBSClient/Messages/InputSettingsResponse.cs rename to OBSClient/Responses/InputSettingsResponse.cs index b04d000..2681d5a 100644 --- a/OBSClient/Messages/InputSettingsResponse.cs +++ b/OBSClient/Responses/InputSettingsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputVolumeResponse.cs b/OBSClient/Responses/InputVolumeResponse.cs similarity index 97% rename from OBSClient/Messages/InputVolumeResponse.cs rename to OBSClient/Responses/InputVolumeResponse.cs index 83c3d7e..cb32434 100644 --- a/OBSClient/Messages/InputVolumeResponse.cs +++ b/OBSClient/Responses/InputVolumeResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/InputsResponse.cs b/OBSClient/Responses/InputsResponse.cs similarity index 91% rename from OBSClient/Messages/InputsResponse.cs rename to OBSClient/Responses/InputsResponse.cs index d1f5320..c6eba14 100644 --- a/OBSClient/Messages/InputsResponse.cs +++ b/OBSClient/Responses/InputsResponse.cs @@ -1,6 +1,7 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; + using OBSStudioClient.Messages; using System.Text.Json.Serialization; /// diff --git a/OBSClient/Messages/MediaInputStatusResponse.cs b/OBSClient/Responses/MediaInputStatusResponse.cs similarity index 97% rename from OBSClient/Messages/MediaInputStatusResponse.cs rename to OBSClient/Responses/MediaInputStatusResponse.cs index 6d29774..66aae06 100644 --- a/OBSClient/Messages/MediaInputStatusResponse.cs +++ b/OBSClient/Responses/MediaInputStatusResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/MonitorListResponse.cs b/OBSClient/Responses/MonitorListResponse.cs similarity index 95% rename from OBSClient/Messages/MonitorListResponse.cs rename to OBSClient/Responses/MonitorListResponse.cs index 1ce35cd..c04e002 100644 --- a/OBSClient/Messages/MonitorListResponse.cs +++ b/OBSClient/Responses/MonitorListResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/MonitorTypeResponse.cs b/OBSClient/Responses/MonitorTypeResponse.cs similarity index 95% rename from OBSClient/Messages/MonitorTypeResponse.cs rename to OBSClient/Responses/MonitorTypeResponse.cs index 02cd091..62b1205 100644 --- a/OBSClient/Messages/MonitorTypeResponse.cs +++ b/OBSClient/Responses/MonitorTypeResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/OutputActiveResponse.cs b/OBSClient/Responses/OutputActiveResponse.cs similarity index 96% rename from OBSClient/Messages/OutputActiveResponse.cs rename to OBSClient/Responses/OutputActiveResponse.cs index f6dd8cc..e2a5888 100644 --- a/OBSClient/Messages/OutputActiveResponse.cs +++ b/OBSClient/Responses/OutputActiveResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/OutputPathResponse.cs b/OBSClient/Responses/OutputPathResponse.cs similarity index 95% rename from OBSClient/Messages/OutputPathResponse.cs rename to OBSClient/Responses/OutputPathResponse.cs index 7a265be..f0c557d 100644 --- a/OBSClient/Messages/OutputPathResponse.cs +++ b/OBSClient/Responses/OutputPathResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/OutputPausedResponse.cs b/OBSClient/Responses/OutputPausedResponse.cs similarity index 96% rename from OBSClient/Messages/OutputPausedResponse.cs rename to OBSClient/Responses/OutputPausedResponse.cs index 59d2509..43e6dbb 100644 --- a/OBSClient/Messages/OutputPausedResponse.cs +++ b/OBSClient/Responses/OutputPausedResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/OutputSettingsResponse.cs b/OBSClient/Responses/OutputSettingsResponse.cs similarity index 96% rename from OBSClient/Messages/OutputSettingsResponse.cs rename to OBSClient/Responses/OutputSettingsResponse.cs index fc5d22b..0defe7b 100644 --- a/OBSClient/Messages/OutputSettingsResponse.cs +++ b/OBSClient/Responses/OutputSettingsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/OutputStatusResponse.cs b/OBSClient/Responses/OutputStatusResponse.cs similarity index 98% rename from OBSClient/Messages/OutputStatusResponse.cs rename to OBSClient/Responses/OutputStatusResponse.cs index db7aaeb..bb8b6b5 100644 --- a/OBSClient/Messages/OutputStatusResponse.cs +++ b/OBSClient/Responses/OutputStatusResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Converters; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/OutputsResponse.cs b/OBSClient/Responses/OutputsResponse.cs similarity index 95% rename from OBSClient/Messages/OutputsResponse.cs rename to OBSClient/Responses/OutputsResponse.cs index b7f9694..3bfebae 100644 --- a/OBSClient/Messages/OutputsResponse.cs +++ b/OBSClient/Responses/OutputsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/ProfileListResponse.cs b/OBSClient/Responses/ProfileListResponse.cs similarity index 97% rename from OBSClient/Messages/ProfileListResponse.cs rename to OBSClient/Responses/ProfileListResponse.cs index f345659..c52a751 100644 --- a/OBSClient/Messages/ProfileListResponse.cs +++ b/OBSClient/Responses/ProfileListResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/ProfileParameterResponse.cs b/OBSClient/Responses/ProfileParameterResponse.cs similarity index 97% rename from OBSClient/Messages/ProfileParameterResponse.cs rename to OBSClient/Responses/ProfileParameterResponse.cs index 4ef37e2..bcaab89 100644 --- a/OBSClient/Messages/ProfileParameterResponse.cs +++ b/OBSClient/Responses/ProfileParameterResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/PropertyItemsResponse.cs b/OBSClient/Responses/PropertyItemsResponse.cs similarity index 96% rename from OBSClient/Messages/PropertyItemsResponse.cs rename to OBSClient/Responses/PropertyItemsResponse.cs index 35cc348..09dc494 100644 --- a/OBSClient/Messages/PropertyItemsResponse.cs +++ b/OBSClient/Responses/PropertyItemsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/RecordDirectoryResponse.cs b/OBSClient/Responses/RecordDirectoryResponse.cs similarity index 96% rename from OBSClient/Messages/RecordDirectoryResponse.cs rename to OBSClient/Responses/RecordDirectoryResponse.cs index f5e3165..5459a72 100644 --- a/OBSClient/Messages/RecordDirectoryResponse.cs +++ b/OBSClient/Responses/RecordDirectoryResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/RecordStatusResponse.cs b/OBSClient/Responses/RecordStatusResponse.cs similarity index 98% rename from OBSClient/Messages/RecordStatusResponse.cs rename to OBSClient/Responses/RecordStatusResponse.cs index 5625c99..1aa7281 100644 --- a/OBSClient/Messages/RecordStatusResponse.cs +++ b/OBSClient/Responses/RecordStatusResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SavedReplayPathResponse.cs b/OBSClient/Responses/SavedReplayPathResponse.cs similarity index 96% rename from OBSClient/Messages/SavedReplayPathResponse.cs rename to OBSClient/Responses/SavedReplayPathResponse.cs index e8f7cae..b7fef7c 100644 --- a/OBSClient/Messages/SavedReplayPathResponse.cs +++ b/OBSClient/Responses/SavedReplayPathResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneCollectionListResponse.cs b/OBSClient/Responses/SceneCollectionListResponse.cs similarity index 97% rename from OBSClient/Messages/SceneCollectionListResponse.cs rename to OBSClient/Responses/SceneCollectionListResponse.cs index 91d191e..184aa54 100644 --- a/OBSClient/Messages/SceneCollectionListResponse.cs +++ b/OBSClient/Responses/SceneCollectionListResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemBlendModeResponse.cs b/OBSClient/Responses/SceneItemBlendModeResponse.cs similarity index 96% rename from OBSClient/Messages/SceneItemBlendModeResponse.cs rename to OBSClient/Responses/SceneItemBlendModeResponse.cs index 96ec8bb..2dd9039 100644 --- a/OBSClient/Messages/SceneItemBlendModeResponse.cs +++ b/OBSClient/Responses/SceneItemBlendModeResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/SceneItemEnabledResponse.cs b/OBSClient/Responses/SceneItemEnabledResponse.cs similarity index 96% rename from OBSClient/Messages/SceneItemEnabledResponse.cs rename to OBSClient/Responses/SceneItemEnabledResponse.cs index 6fe24ac..c76b1c8 100644 --- a/OBSClient/Messages/SceneItemEnabledResponse.cs +++ b/OBSClient/Responses/SceneItemEnabledResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemIdResponse.cs b/OBSClient/Responses/SceneItemIdResponse.cs similarity index 96% rename from OBSClient/Messages/SceneItemIdResponse.cs rename to OBSClient/Responses/SceneItemIdResponse.cs index 1439214..11493e4 100644 --- a/OBSClient/Messages/SceneItemIdResponse.cs +++ b/OBSClient/Responses/SceneItemIdResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemIndexResponse.cs b/OBSClient/Responses/SceneItemIndexResponse.cs similarity index 95% rename from OBSClient/Messages/SceneItemIndexResponse.cs rename to OBSClient/Responses/SceneItemIndexResponse.cs index 9832e09..7a89272 100644 --- a/OBSClient/Messages/SceneItemIndexResponse.cs +++ b/OBSClient/Responses/SceneItemIndexResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemTransformResponse.cs b/OBSClient/Responses/SceneItemTransformResponse.cs similarity index 96% rename from OBSClient/Messages/SceneItemTransformResponse.cs rename to OBSClient/Responses/SceneItemTransformResponse.cs index 378e7a5..03f9673 100644 --- a/OBSClient/Messages/SceneItemTransformResponse.cs +++ b/OBSClient/Responses/SceneItemTransformResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/SceneItemlockedResponse.cs b/OBSClient/Responses/SceneItemlockedResponse.cs similarity index 96% rename from OBSClient/Messages/SceneItemlockedResponse.cs rename to OBSClient/Responses/SceneItemlockedResponse.cs index 9322fd6..1cf4f8c 100644 --- a/OBSClient/Messages/SceneItemlockedResponse.cs +++ b/OBSClient/Responses/SceneItemlockedResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SceneItemsResponse.cs b/OBSClient/Responses/SceneItemsResponse.cs similarity index 96% rename from OBSClient/Messages/SceneItemsResponse.cs rename to OBSClient/Responses/SceneItemsResponse.cs index a1180c1..a376409 100644 --- a/OBSClient/Messages/SceneItemsResponse.cs +++ b/OBSClient/Responses/SceneItemsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/SceneListResponse.cs b/OBSClient/Responses/SceneListResponse.cs similarity index 97% rename from OBSClient/Messages/SceneListResponse.cs rename to OBSClient/Responses/SceneListResponse.cs index d7ac656..f82f35b 100644 --- a/OBSClient/Messages/SceneListResponse.cs +++ b/OBSClient/Responses/SceneListResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/SceneTransitionListResponse.cs b/OBSClient/Responses/SceneTransitionListResponse.cs similarity index 97% rename from OBSClient/Messages/SceneTransitionListResponse.cs rename to OBSClient/Responses/SceneTransitionListResponse.cs index 1a53378..3bfa841 100644 --- a/OBSClient/Messages/SceneTransitionListResponse.cs +++ b/OBSClient/Responses/SceneTransitionListResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; diff --git a/OBSClient/Messages/SceneTransitionResponse.cs b/OBSClient/Responses/SceneTransitionResponse.cs similarity index 97% rename from OBSClient/Messages/SceneTransitionResponse.cs rename to OBSClient/Responses/SceneTransitionResponse.cs index 1b2140a..db5bf5f 100644 --- a/OBSClient/Messages/SceneTransitionResponse.cs +++ b/OBSClient/Responses/SceneTransitionResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SlotValueResponse.cs b/OBSClient/Responses/SlotValueResponse.cs similarity index 95% rename from OBSClient/Messages/SlotValueResponse.cs rename to OBSClient/Responses/SlotValueResponse.cs index 0dd4b47..b24e972 100644 --- a/OBSClient/Messages/SlotValueResponse.cs +++ b/OBSClient/Responses/SlotValueResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SourceActiveResponse.cs b/OBSClient/Responses/SourceActiveResponse.cs similarity index 97% rename from OBSClient/Messages/SourceActiveResponse.cs rename to OBSClient/Responses/SourceActiveResponse.cs index 65d0ab6..86ecce7 100644 --- a/OBSClient/Messages/SourceActiveResponse.cs +++ b/OBSClient/Responses/SourceActiveResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/SpecialInputsResponse.cs b/OBSClient/Responses/SpecialInputsResponse.cs similarity index 98% rename from OBSClient/Messages/SpecialInputsResponse.cs rename to OBSClient/Responses/SpecialInputsResponse.cs index 2f0375d..08beef5 100644 --- a/OBSClient/Messages/SpecialInputsResponse.cs +++ b/OBSClient/Responses/SpecialInputsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/StatsResponse.cs b/OBSClient/Responses/StatsResponse.cs similarity index 99% rename from OBSClient/Messages/StatsResponse.cs rename to OBSClient/Responses/StatsResponse.cs index 958d145..9b43772 100644 --- a/OBSClient/Messages/StatsResponse.cs +++ b/OBSClient/Responses/StatsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/StreamServiceSettingsResponse.cs b/OBSClient/Responses/StreamServiceSettingsResponse.cs similarity index 97% rename from OBSClient/Messages/StreamServiceSettingsResponse.cs rename to OBSClient/Responses/StreamServiceSettingsResponse.cs index 2428648..416ec33 100644 --- a/OBSClient/Messages/StreamServiceSettingsResponse.cs +++ b/OBSClient/Responses/StreamServiceSettingsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/StudioModeEnabledResponse.cs b/OBSClient/Responses/StudioModeEnabledResponse.cs similarity index 96% rename from OBSClient/Messages/StudioModeEnabledResponse.cs rename to OBSClient/Responses/StudioModeEnabledResponse.cs index 2768f21..e01a6ef 100644 --- a/OBSClient/Messages/StudioModeEnabledResponse.cs +++ b/OBSClient/Responses/StudioModeEnabledResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/TransitionCursorResponse.cs b/OBSClient/Responses/TransitionCursorResponse.cs similarity index 96% rename from OBSClient/Messages/TransitionCursorResponse.cs rename to OBSClient/Responses/TransitionCursorResponse.cs index 9565ad7..69b2a5f 100644 --- a/OBSClient/Messages/TransitionCursorResponse.cs +++ b/OBSClient/Responses/TransitionCursorResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/TransitionKindsResponse.cs b/OBSClient/Responses/TransitionKindsResponse.cs similarity index 96% rename from OBSClient/Messages/TransitionKindsResponse.cs rename to OBSClient/Responses/TransitionKindsResponse.cs index 86b6066..d873a55 100644 --- a/OBSClient/Messages/TransitionKindsResponse.cs +++ b/OBSClient/Responses/TransitionKindsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/ExtendedTransitionResponse.cs b/OBSClient/Responses/TransitionResponse.cs similarity index 76% rename from OBSClient/Messages/ExtendedTransitionResponse.cs rename to OBSClient/Responses/TransitionResponse.cs index 056b38b..9f761f1 100644 --- a/OBSClient/Messages/ExtendedTransitionResponse.cs +++ b/OBSClient/Responses/TransitionResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Classes; using OBSStudioClient.Interfaces; @@ -8,7 +8,7 @@ /// Provides the Response Data () in the Response Message () returned by OBS Studio after sending a successful GetCurrentSceneTransition request. /// Also used as the Request Data in the Request Message sent to OBS Studio in a SetCurrentSceneTransitionSettings request. /// - public class ExtendedTransitionResponse : Transition, IResponse + public class TransitionResponse : Transition, IResponse { /// /// Gets the duration of the transition. @@ -23,7 +23,7 @@ public class ExtendedTransitionResponse : Transition, IResponse public Dictionary TransitionSettings { get; } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Duration of the transition. /// Setting of the transition. @@ -32,7 +32,7 @@ public class ExtendedTransitionResponse : Transition, IResponse /// The kind of transition. /// The name of the transition. [JsonConstructor] - public ExtendedTransitionResponse(float? transitionDuration, Dictionary transitionSettings, bool transitionConfigurable, bool transitionFixed, string transitionKind, string transitionName) : base(transitionConfigurable, transitionFixed, transitionKind, transitionName) + public TransitionResponse(float? transitionDuration, Dictionary transitionSettings, bool transitionConfigurable, bool transitionFixed, string transitionKind, string transitionName) : base(transitionConfigurable, transitionFixed, transitionKind, transitionName) { this.TransitionDuration = transitionDuration; this.TransitionSettings = transitionSettings ?? new(); diff --git a/OBSClient/Messages/VersionResponse.cs b/OBSClient/Responses/VersionResponse.cs similarity index 97% rename from OBSClient/Messages/VersionResponse.cs rename to OBSClient/Responses/VersionResponse.cs index c4e7261..9e12f13 100644 --- a/OBSClient/Messages/VersionResponse.cs +++ b/OBSClient/Responses/VersionResponse.cs @@ -1,5 +1,6 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { + using OBSStudioClient.Enums; using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/OBSClient/Messages/VideoSettingsResponse.cs b/OBSClient/Responses/VideoSettingsResponse.cs similarity index 98% rename from OBSClient/Messages/VideoSettingsResponse.cs rename to OBSClient/Responses/VideoSettingsResponse.cs index e6a21d1..d8e1f42 100644 --- a/OBSClient/Messages/VideoSettingsResponse.cs +++ b/OBSClient/Responses/VideoSettingsResponse.cs @@ -1,4 +1,4 @@ -namespace OBSStudioClient.Messages +namespace OBSStudioClient.Responses { using OBSStudioClient.Interfaces; using System.Text.Json.Serialization; diff --git a/README.md b/README.md index 466e11d..49b700b 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,16 @@ A Complete cross platform .NET WebSocket Client for OBS Studio version 28 and up. Currently implementing: [**obs-websocket 5.3.0 Protocol**](https://github.com/obsproject/obs-websocket/blob/master/docs/generated/protocol.md) +## Version 2 +We're working on Version 2 of the client. You can download and use our first preview version. +Although the changes between v1 and v2 are not huge, they are breaking compatibility with previous versions, so we decided to bump the major version. (See: [SemVer](https://semver.org/)) + +For now, the main branch will contain the latest preview version of the code. For future releases (post V2-release), we will use seperate branches. + ## Installation Install from the [NuGet Gallery](https://www.nuget.org/packages/OBSClient) -Or through the NuGet CLI: `NuGet\Install-Package OBSClient -Version 1.3.0` -From the command line: `dotnet add package OBSClient --version 1.3.0` +Or through the NuGet CLI: `NuGet\Install-Package OBSClient -Version 1.4.0` +From the command line: `dotnet add package OBSClient --version 1.4.0` ## Sample usage ``` diff --git a/SampleWindowsAppliation/Form1.Designer.cs b/SampleWindowsAppliation/Form1.Designer.cs index 7666744..26f6e40 100644 --- a/SampleWindowsAppliation/Form1.Designer.cs +++ b/SampleWindowsAppliation/Form1.Designer.cs @@ -135,6 +135,7 @@ private void InitializeComponent() lblRecordState = new Label(); label8 = new Label(); tbRecordFolder = new TextBox(); + cbAutoReconnect = new CheckBox(); ((System.ComponentModel.ISupportInitialize)nudPort).BeginInit(); tabControl1.SuspendLayout(); tpGeneralRequests.SuspendLayout(); @@ -1214,7 +1215,7 @@ private void InitializeComponent() // // tbNameItem // - tbNameItem.Location = new Point(167, 192); + tbNameItem.Location = new Point(168, 203); tbNameItem.Name = "tbNameItem"; tbNameItem.Size = new Size(200, 39); tbNameItem.TabIndex = 24; @@ -1223,7 +1224,7 @@ private void InitializeComponent() // label6 // label6.AutoSize = true; - label6.Location = new Point(23, 195); + label6.Location = new Point(24, 206); label6.Name = "label6"; label6.Size = new Size(138, 32); label6.TabIndex = 25; @@ -1263,11 +1264,25 @@ private void InitializeComponent() tbRecordFolder.Size = new Size(200, 39); tbRecordFolder.TabIndex = 29; // + // cbAutoReconnect + // + cbAutoReconnect.AutoSize = true; + cbAutoReconnect.Checked = true; + cbAutoReconnect.CheckState = CheckState.Checked; + cbAutoReconnect.Location = new Point(146, 150); + cbAutoReconnect.Name = "cbAutoReconnect"; + cbAutoReconnect.Size = new Size(208, 36); + cbAutoReconnect.TabIndex = 30; + cbAutoReconnect.Text = "AutoReconnect"; + cbAutoReconnect.UseVisualStyleBackColor = true; + cbAutoReconnect.CheckedChanged += this.cbAutoReconnect_CheckedChanged; + // // Form1 // this.AutoScaleDimensions = new SizeF(13F, 32F); this.AutoScaleMode = AutoScaleMode.Font; this.ClientSize = new Size(1986, 849); + this.Controls.Add(cbAutoReconnect); this.Controls.Add(tbRecordFolder); this.Controls.Add(label8); this.Controls.Add(lblRecordState); @@ -1413,5 +1428,6 @@ private void InitializeComponent() private Button button2; private Label label8; private TextBox tbRecordFolder; + private CheckBox cbAutoReconnect; } } \ No newline at end of file diff --git a/SampleWindowsAppliation/Form1.cs b/SampleWindowsAppliation/Form1.cs index 79c01f4..d0057fe 100644 --- a/SampleWindowsAppliation/Form1.cs +++ b/SampleWindowsAppliation/Form1.cs @@ -4,24 +4,27 @@ namespace SampleWindowsAppliation using System.Diagnostics; using OBSStudioClient; using OBSStudioClient.Classes; - using OBSStudioClient.Enums; using OBSStudioClient.Events; - using OBSStudioClient.Exceptions; - using OBSStudioClient.MessageClasses; public partial class Form1 : Form { - private ObsClient _client = new(); + private readonly ObsClient _client = new(); + private delegate void SafeListboxRemove(object itemToRemove, ListBox listBox); + private delegate void SafeListboxRefresh(ListBox listBox); + private delegate void SafeUpdateTitle(); + private delegate void SafeUpdateRecordState(string text); + private delegate void SafeUpdateRecordFolder(string text); + private const string Title = "Obs Client"; + public Form1() { InitializeComponent(); - _client.ConnectionClosed += ObsConnectionClosed; _client.CurrentPreviewSceneChanged += CurrentPreviewSceneChanged; _client.CurrentProfileChanged += CurrentProfileChanged; @@ -93,72 +96,59 @@ private void PropertyChanged(object? sender, PropertyChangedEventArgs e) Debug.WriteLine($"{e.PropertyName} - {_client.ConnectionState}"); } - private Task VirtualcamStateChanged(object? sender, OutputStateChangedEventArgs e) + private void VirtualcamStateChanged(object? sender, OutputStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task VendorEvent(object? sender, VendorEventEventArgs e) + private void VendorEvent(object? sender, VendorEventEventArgs e) { - return Task.CompletedTask; } - private Task StudioModeStateChanged(object? sender, StudioModeStateChangedEventArgs e) + private void StudioModeStateChanged(object? sender, StudioModeStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task StreamStateChanged(object? sender, OutputStateChangedEventArgs e) + private void StreamStateChanged(object? sender, OutputStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task SourceFilterRemoved(object? sender, SourceFilterRemovedEventArgs e) + private void SourceFilterRemoved(object? sender, SourceFilterRemovedEventArgs e) { - return Task.CompletedTask; } - private Task SourceFilterNameChanged(object? sender, SourceFilterNameChangedEventArgs e) + private void SourceFilterNameChanged(object? sender, SourceFilterNameChangedEventArgs e) { - return Task.CompletedTask; } - private Task SourceFilterListReindexed(object? sender, SourceFiltersEventArgs e) + private void SourceFilterListReindexed(object? sender, SourceFiltersEventArgs e) { - return Task.CompletedTask; } - private Task SourceFilterEnableStateChanged(object? sender, SourceFilterEnableStateChangedEventArgs e) + private void SourceFilterEnableStateChanged(object? sender, SourceFilterEnableStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task SourceFilterCreated(object? sender, SourceFilterCreatedEventArgs e) + private void SourceFilterCreated(object? sender, SourceFilterCreatedEventArgs e) { - return Task.CompletedTask; } - private Task ScreenshotSaved(object? sender, ScreenshotSavedEventArgs e) + private void ScreenshotSaved(object? sender, ScreenshotSavedEventArgs e) { - return Task.CompletedTask; } - private Task SceneTransitionVideoEnded(object? sender, TransitionNameEventArgs e) + private void SceneTransitionVideoEnded(object? sender, TransitionNameEventArgs e) { - return Task.CompletedTask; } - private Task SceneTransitionStarted(object? sender, TransitionNameEventArgs e) + private void SceneTransitionStarted(object? sender, TransitionNameEventArgs e) { - return Task.CompletedTask; } - private Task SceneTransitionEnded(object? sender, TransitionNameEventArgs e) + private void SceneTransitionEnded(object? sender, TransitionNameEventArgs e) { - return Task.CompletedTask; } - private Task SceneRemoved(object? sender, SceneModifiedEventArgs e) + private void SceneRemoved(object? sender, SceneModifiedEventArgs e) { Scene? scene = null; foreach (Scene s in this.lbScenes.Items) @@ -174,213 +164,172 @@ private Task SceneRemoved(object? sender, SceneModifiedEventArgs e) { this.RemoveItemFromListbox(scene, this.lbScenes); } - - return Task.CompletedTask; } - private Task SceneNameChanged(object? sender, SceneNameChangedEventArgs e) + private void SceneNameChanged(object? sender, SceneNameChangedEventArgs e) { MessageBox.Show($"Scene '{e.OldSceneName}' was renamed to '{e.SceneName}'. Refresh the Scenes List using Get Scene List."); - return Task.CompletedTask; } - private Task SceneListChanged(object? sender, SceneListEventArgs e) + private void SceneListChanged(object? sender, SceneListEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemTransformChanged(object? sender, SceneItemTransformChangedEventArgs e) + private void SceneItemTransformChanged(object? sender, SceneItemTransformChangedEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemSelected(object? sender, SceneItemSelectedEventArgs e) + private void SceneItemSelected(object? sender, SceneItemSelectedEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemRemoved(object? sender, SceneItemRemovedEventArgs e) + private void SceneItemRemoved(object? sender, SceneItemRemovedEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemLockStateChanged(object? sender, SceneItemLockStateChangedEventArgs e) + private void SceneItemLockStateChanged(object? sender, SceneItemLockStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemListReindexed(object? sender, SceneItemListReindexedEventArgs e) + private void SceneItemListReindexed(object? sender, SceneItemListReindexedEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemEnableStateChanged(object? sender, SceneItemEnableStateChangedEventArgs e) + private void SceneItemEnableStateChanged(object? sender, SceneItemEnableStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task SceneItemCreated(object? sender, SceneItemCreatedEventArgs e) + private void SceneItemCreated(object? sender, SceneItemCreatedEventArgs e) { - return Task.CompletedTask; } - private Task SceneCreated(object? sender, SceneModifiedEventArgs e) + private void SceneCreated(object? sender, SceneModifiedEventArgs e) { MessageBox.Show($"Scene '{e.SceneName}' created. Refresh the Scenes List using Get Scene List."); - return Task.CompletedTask; } - private Task SceneCollectionListChanged(object? sender, SceneCollectionListEventArgs e) + private void SceneCollectionListChanged(object? sender, SceneCollectionListEventArgs e) { - return Task.CompletedTask; } - private Task ReplayBufferStateChanged(object? sender, OutputStateChangedEventArgs e) + private void ReplayBufferStateChanged(object? sender, OutputStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task ReplayBufferSaved(object? sender, ReplayBufferSavedEventArgs e) + private void ReplayBufferSaved(object? sender, ReplayBufferSavedEventArgs e) { - return Task.CompletedTask; } - private Task RecordStateChanged(object? sender, RecordStateChangedEventArgs e) + private void RecordStateChanged(object? sender, RecordStateChangedEventArgs e) { var active = e.OutputActive ? "Active" : "Inactive"; RefreshRecordState($"{e.OutputState} ({active})"); RefreshRecordFolder(e.OutputPath); - return Task.CompletedTask; } - private Task ProfileListChanged(object? sender, ProfileListEventArgs e) + private void ProfileListChanged(object? sender, ProfileListEventArgs e) { - return Task.CompletedTask; } - private Task MediaInputPlaybackStarted(object? sender, InputNameEventArgs e) + private void MediaInputPlaybackStarted(object? sender, InputNameEventArgs e) { - return Task.CompletedTask; } - private Task MediaInputPlaybackEnded(object? sender, InputNameEventArgs e) + private void MediaInputPlaybackEnded(object? sender, InputNameEventArgs e) { - return Task.CompletedTask; } - private Task MediaInputActionTriggered(object? sender, MediaInputActionTriggeredEventArgs e) + private void MediaInputActionTriggered(object? sender, MediaInputActionTriggeredEventArgs e) { - return Task.CompletedTask; } - private Task InputVolumeMeters(object? sender, InputVolumeMetersEventArgs e) + private void InputVolumeMeters(object? sender, InputVolumeMetersEventArgs e) { - return Task.CompletedTask; } - private Task InputVolumeChanged(object? sender, InputVolumeChangedEventArgs e) + private void InputVolumeChanged(object? sender, InputVolumeChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputShowStateChanged(object? sender, InputShowStateChangedEventArgs e) + private void InputShowStateChanged(object? sender, InputShowStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputRemoved(object? sender, InputNameEventArgs e) + private void InputRemoved(object? sender, InputNameEventArgs e) { - return Task.CompletedTask; } - private Task InputNameChanged(object? sender, InputNameChangedEventArgs e) + private void InputNameChanged(object? sender, InputNameChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputMuteStateChanged(object? sender, InputMuteStateChangedEventArgs e) + private void InputMuteStateChanged(object? sender, InputMuteStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputCreated(object? sender, InputCreatedEventArgs e) + private void InputCreated(object? sender, InputCreatedEventArgs e) { - return Task.CompletedTask; } - private Task InputAudioTracksChanged(object? sender, InputAudioTracksChangedEventArgs e) + private void InputAudioTracksChanged(object? sender, InputAudioTracksChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputAudioSyncOffsetChanged(object? sender, InputAudioSyncOffsetChangedEventArgs e) + private void InputAudioSyncOffsetChanged(object? sender, InputAudioSyncOffsetChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputAudioMonitorTypeChanged(object? sender, InputAudioMonitorTypeChangedEventArgs e) + private void InputAudioMonitorTypeChanged(object? sender, InputAudioMonitorTypeChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputAudioBalanceChanged(object? sender, InputAudioBalanceChangedEventArgs e) + private void InputAudioBalanceChanged(object? sender, InputAudioBalanceChangedEventArgs e) { - return Task.CompletedTask; } - private Task InputActiveStateChanged(object? sender, InputActiveStateChangedEventArgs e) + private void InputActiveStateChanged(object? sender, InputActiveStateChangedEventArgs e) { - return Task.CompletedTask; } - private Task ExitStarted(object? sender) + private void ExitStarted(object? sender, EventArgs e) { - return Task.CompletedTask; } - private Task CustomEvent(object? sender, CustomEventEventArgs e) + private void CustomEvent(object? sender, CustomEventEventArgs e) { - return Task.CompletedTask; } - private Task CurrentSceneTransitionDurationChanged(object? sender, TransitionDurationEventArgs e) + private void CurrentSceneTransitionDurationChanged(object? sender, TransitionDurationEventArgs e) { - return Task.CompletedTask; } - private Task CurrentSceneTransitionChanged(object? sender, TransitionNameEventArgs e) + private void CurrentSceneTransitionChanged(object? sender, TransitionNameEventArgs e) { - return Task.CompletedTask; } - private Task CurrentSceneCollectionChanging(object? sender, SceneCollectionNameEventArgs e) + private void CurrentSceneCollectionChanging(object? sender, SceneCollectionNameEventArgs e) { - return Task.CompletedTask; } - private Task CurrentSceneCollectionChanged(object? sender, SceneCollectionNameEventArgs e) + private void CurrentSceneCollectionChanged(object? sender, SceneCollectionNameEventArgs e) { - return Task.CompletedTask; } - private Task CurrentProgramSceneChanged(object? sender, SceneNameEventArgs e) + private void CurrentProgramSceneChanged(object? sender, SceneNameEventArgs e) { - return Task.CompletedTask; + MessageBox.Show(e.SceneName, "CurrentProgramSceneChanged"); } - private Task CurrentProfileChanging(object? sender, ProfileNameEventArgs e) + private void CurrentProfileChanging(object? sender, ProfileNameEventArgs e) { - return Task.CompletedTask; } - private Task CurrentProfileChanged(object? sender, ProfileNameEventArgs e) + private void CurrentProfileChanged(object? sender, ProfileNameEventArgs e) { - return Task.CompletedTask; } - private Task CurrentPreviewSceneChanged(object? sender, SceneNameEventArgs e) + private void CurrentPreviewSceneChanged(object? sender, SceneNameEventArgs e) { - return Task.CompletedTask; } private void RemoveItemFromListbox(object itemToRemove, ListBox listBox) @@ -412,8 +361,6 @@ private void UpdateTitle() { this.Text = $"{Title} - {_client.ConnectionState}"; } - - //Application.DoEvents(); } private void RefreshListbox(ListBox listBox) @@ -457,17 +404,16 @@ private void RefreshRecordFolder(string text) private async void button1_Click(object sender, EventArgs e) { - var result = await _client.ConnectAsync(this.tbPassword.Text, this.tbHostname.Text, Convert.ToInt32(this.nudPort.Value)); + var result = await _client.ConnectAsync(this.cbAutoReconnect.Checked, this.tbPassword.Text, this.tbHostname.Text, Convert.ToInt32(this.nudPort.Value)); if (!result) { MessageBox.Show("Could not connect."); } } - private Task ObsConnectionClosed(object? sender, ConnectionClosedEventArgs e) + private void ObsConnectionClosed(object? sender, ConnectionClosedEventArgs e) { MessageBox.Show($"{e.WebSocketCloseCode}: {e.WebSocketCloseDescription}", "Connection Closed"); - return Task.CompletedTask; } private async void btnStartVirtualCam_Click(object sender, EventArgs e) @@ -779,5 +725,10 @@ private async void button2_Click(object sender, EventArgs e) { await _client.SetRecordDirectory(this.tbRecordFolder.Text); } + + private void cbAutoReconnect_CheckedChanged(object sender, EventArgs e) + { + _client.AutoReconnect = this.cbAutoReconnect.Checked; + } } } \ No newline at end of file