diff --git a/README.md b/README.md index ac5d6d3..79beca7 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,21 @@ > This library is **NOT** affiliated in any way with **SteelSeries** > I've made it because it was interesting and funny to do, also I wanted to share this project for people to use it for their own projects -This library allows you to take control over the SteelSeries GG app. +This library allows you to take control over the SteelSeries GG app (only Sonar for now). -The API is available via a [nuget package](https://www.nuget.org/packages/Steelseries-NET-API). +The library is available via a [nuget package](https://www.nuget.org/packages/Steelseries-NET-API). It is also available in the [Releases](https://github.com/mpaperno/SteelSeries-NET-API/releases) tab as a .zip archive for each supported .NET version. ## Features - Full Sonar control + - Mode + - Volume + - Mute + - ChatMix + - Configs (Can't edit a config) + - Playback Devices + - Streamer mode Personal & Stream Mixes + - Streamer mode Audience Monitoring ## Getting Started To get started, you only need to create a Sonar Object. @@ -25,6 +33,9 @@ To get started, you only need to create a Sonar Object. // Create Sonar object SonarBridge sonarManager = new SonarBridge(); +// Wait for GG to start before continuing +sonarManager.WaitUntilSteelSeriesStarted(); + // Wait for sonar to start before continuing sonarManager.WaitUntilSonarStarted(); @@ -32,23 +43,15 @@ sonarManager.WaitUntilSonarStarted(); sonarManager.StartListener(); sonarManager.SonarEventManager.OnSonarModeChange += OnModeChangeHandler; // Register event -Mode currentMode = sonarManager.GetMode(); // Returns the current mode -sonarManager.SetVolume(0.5, Device.Game); // Set the Game Device volume +Mode currentMode = sonarManager.Mode.Get(); // Returns the current mode +sonarManager.VolumeSettings.SetVolume(0.5, Device.Game); // Set the Game Device volume ... ````` -For more example, you can check the [Tests](https://github.com/DataNext27/SteelSeries-NET-API/tree/main/SteelSeriesAPI.Tests) and the [Sample](https://github.com/DataNext27/SteelSeries-NET-API/tree/main/SteelSeriesAPI.Sample) folders. +For more example, you can check the [Sample](SteelSeriesAPI.Sample/Program.cs) and the [Tests](SteelSeriesAPI.Tests/Program.cs) folders. If you need any sort of Documentation, go check the [Repo's Wiki](https://github.com/DataNext27/SteelSeries-NET-API/wiki) for more information. -### Some Vocabulary -- Mode : Classic/Stream -- Device : Master/Game/Chat/Media/Aux/Mic -- Channel : *(Streamer mode)* Monitoring/Stream -- Audio Configs : It's in the name -- Redirection States : *(Streamer mode)* Button above sliders to un/mute a channel of a device -- Redirection Device : Device where the sound got by GG is redirected (your headset for example) - ## Todo -(Actually not possible, maybe one day i guess :/ ) +(Actually not planned as not possible, maybe one day I guess :/ ) - Moments - Engine - Settings diff --git a/SteelSeriesAPI.Sample/Program.cs b/SteelSeriesAPI.Sample/Program.cs index 1ce22e2..22f5b93 100644 --- a/SteelSeriesAPI.Sample/Program.cs +++ b/SteelSeriesAPI.Sample/Program.cs @@ -1,4 +1,5 @@ -using SteelSeriesAPI.Events; +using SteelSeriesAPI.Sonar; +using SteelSeriesAPI.Sonar.Events; using SteelSeriesAPI.Sonar.Enums; using SteelSeriesAPI.Sonar.Models; @@ -11,81 +12,97 @@ static void Main(string[] args) // Create a Sonar Object to control Sonar SonarBridge sonarManager = new SonarBridge(); + // Wait until GG is started before continuing + sonarManager.WaitUntilSteelSeriesStarted(); // Wait until GG and Sonar are both started before continuing sonarManager.WaitUntilSonarStarted(); - // If I want to detect changes made on GG, I can use the listener (require admin rights) + // If you want to detect changes made on GG, you can use the listener (require admin rights) sonarManager.StartListener(); - // Then I register the events I want (I've put them all to demonstrate) - sonarManager.SonarEventManager.OnSonarModeChange += OnModeChangeHandler; // When the mode is change - sonarManager.SonarEventManager.OnSonarVolumeChange += OnVolumeChangeHandler; // When the volume of a Sonar Device or Channel is changed - sonarManager.SonarEventManager.OnSonarMuteChange += OnMuteChangeHandler; // When a Sonar Device or Channel is muted or unmuted - sonarManager.SonarEventManager.OnSonarConfigChange += OnConfigChangeHandler; // When a new config is set to a Sonar Device - sonarManager.SonarEventManager.OnSonarChatMixChange += OnChatMixChangeHandler; // When the ChatMix value is changed - sonarManager.SonarEventManager.OnSonarRedirectionDeviceChange += OnRedirectionDeviceChangeHandler; // When the Redirection Device of a Sonar Device is changed - sonarManager.SonarEventManager.OnSonarRedirectionStateChange += OnRedirectionStateChangeHandler; // When the Redirection of a Sonar Channel is muted or unmuted - sonarManager.SonarEventManager.OnSonarAudienceMonitoringChange += OnAudienceMonitoringChangeHandler; // When the Audience Monitoring is muted or unmuted + // Then you register the events you need (I've put them all to demonstrate) + sonarManager.Events.OnSonarModeChange += OnModeChangeHandler; // When the mode gets changed + sonarManager.Events.OnSonarVolumeChange += OnVolumeChangeHandler; // When the volume of a Sonar Channel or Mix gets changed + sonarManager.Events.OnSonarMuteChange += OnMuteChangeHandler; // When a Sonar Channel or Mix gets muted or unmuted + sonarManager.Events.OnSonarConfigChange += OnConfigChangeHandler; // When a new config is set to a Sonar Channel + sonarManager.Events.OnSonarChatMixChange += OnChatMixChangeHandler; // When the ChatMix value gets changed + sonarManager.Events.OnSonarPlaybackDeviceChange += OnPlaybackDeviceChangeHandler; // When the Redirection Channel of a Sonar Channel is changed + sonarManager.Events.OnSonarRoutedProcessChange += OnRoutedProcessChangeHandler; // When a routed process gets routed to a new Sonar Channel + sonarManager.Events.OnSonarMixChange += OnMixChangeHandler; // When the Mix of a Sonar Channem gets activated or deactivated + sonarManager.Events.OnSonarAudienceMonitoringChange += OnAudienceMonitoringChangeHandler; // When the Audience Monitoring gets muted or unmuted // Get current sonar mode - Mode mode = sonarManager.GetMode(); + Mode mode = sonarManager.Mode.Get(); // Change sonar mode to Streamer - sonarManager.SetMode(Mode.Streamer); + sonarManager.Mode.Set(Mode.STREAMER); - // Get current volume of a Sonar Device - double vol = sonarManager.GetVolume(Device.Media); // Get current volume of a Sonar Channel - double vol2 = sonarManager.GetVolume(Device.Chat, Channel.Stream); - // Set the volume of a Sonar Device - sonarManager.SetVolume(0.75, Device.Game); + double vol = sonarManager.VolumeSettings.GetVolume(Channel.MEDIA); + // Get current volume of a Sonar Mix + double vol2 = sonarManager.VolumeSettings.GetVolume(Channel.CHAT, Mix.STREAM); // Set the volume of a Sonar Channel - sonarManager.SetVolume(0.1, Device.Media, Channel.Monitoring); + sonarManager.VolumeSettings.SetVolume(0.75, Channel.GAME); + // Set the volume of a Sonar Mix + sonarManager.VolumeSettings.SetVolume(0.1, Channel.MEDIA, Mix.PERSONAL); - // Get the current mute state of a Sonar Device - bool state = sonarManager.GetMute(Device.Chat); - bool state2 = sonarManager.GetMute(Device.Master, Channel.Monitoring); - // Set the current mute state of a Sonar Device - sonarManager.SetMute(true, Device.Chat); // Mute chat + // Get the current mute state of a Sonar Channel + bool state = sonarManager.VolumeSettings.GetMute(Channel.CHAT); + bool state2 = sonarManager.VolumeSettings.GetMute(Channel.MASTER, Mix.PERSONAL); + // Set the current mute state of a Sonar Channel + sonarManager.VolumeSettings.SetMute(true, Channel.CHAT); // Mute chat // Get audio configs - List allConfigs = sonarManager.GetAllAudioConfigurations().ToList(); // Return all configs (A SonarAudioConfiguration contains an Id, a Name and an AssociatedDevice) - List mediaConfigs = sonarManager.GetAudioConfigurations(Device.Media).ToList(); // Return all configs of a Sonar Device - SonarAudioConfiguration currentConfig = sonarManager.GetSelectedAudioConfiguration(Device.Media); // Return the currently used config of a Sonar Device - // Set the config of a Sonar Device - sonarManager.SetConfig(Device.Media, "Podcast"); // Using its name - sonarManager.SetConfig(currentConfig.Id); // Using its id (no need to precise which Sonar Device, one id goes to one Sonar Device) + List allConfigs = sonarManager.Configurations.GetAllAudioConfigurations().ToList(); // Return all configs (A SonarAudioConfiguration contains an Id, a Name and an AssociatedChannel) + List mediaConfigs = sonarManager.Configurations.GetAudioConfigurations(Channel.MEDIA).ToList(); // Return all configs of a Sonar Channel + SonarAudioConfiguration currentConfig = sonarManager.Configurations.GetSelectedAudioConfiguration(Channel.MEDIA); // Return the currently used config of a Sonar Channel + // Set the config of a Sonar Channel + sonarManager.Configurations.SetConfigByName(Channel.MEDIA, "Podcast"); // Using its name + sonarManager.Configurations.SetConfig(currentConfig); // Using directly the config object + sonarManager.Configurations.SetConfig(currentConfig.Id); // Or Using its id (no need to precise which Sonar Channel, one id = one config = one Sonar Channel) // Get ChatMix info - double chatMixBalance = sonarManager.GetChatMixBalance(); // The ChatMix value between -1 and 1 - bool chatMixState = sonarManager.GetChatMixState(); // If ChatMix is usable or not + double chatMixBalance = sonarManager.ChatMix.GetBalance(); // The ChatMix value between -1 and 1 + bool chatMixState = sonarManager.ChatMix.GetState(); // If ChatMix is usable or not // Change ChatMix value - sonarManager.SetChatMixBalance(0.5); // 0.5 is halfway to Chat + sonarManager.ChatMix.SetBalance(0.5); // 0.5 is halfway to Chat - // Get redirection devices (Windows devices) - List inputDevices = sonarManager.GetRedirectionDevices(Direction.Input).ToList(); // Input devices (Mics...) - sonarManager.GetRedirectionDevices(Direction.Output); // Output devices (headset, speakers...) - sonarManager.GetRedirectionDeviceFromId("{0.0.0.00000000}.{192b4f5b-9cc1-4eb2-b752-c5e15b99d548}"); // Get a redirection device from its id - RedirectionDevice gameRDevice = sonarManager.GetClassicRedirectionDevice(Device.Game); // Give currently used Redirection Device for classic mode - sonarManager.GetStreamRedirectionDevice(Channel.Monitoring); // Give currently used Redirection Device for Streamer mode - sonarManager.GetStreamRedirectionDevice(Device.Mic); // Give currently used Redirection Device for Mic in streamer mode - // Change redirection devices using their id - sonarManager.SetClassicRedirectionDevice(gameRDevice.Id, Device.Game); - sonarManager.SetStreamRedirectionDevice(gameRDevice.Id, Channel.Monitoring); - sonarManager.SetStreamRedirectionDevice(inputDevices[0].Id, Device.Mic); + // Get playback devices (Windows devices) + List playbackDevices = sonarManager.PlaybackDevices.GetAllPlaybackDevices().ToList(); // All playback devices + List inputDevices = sonarManager.PlaybackDevices.GetInputPlaybackDevices().ToList(); // Input devices (Mics...) + List outputDevices = sonarManager.PlaybackDevices.GetOutputPlaybackDevices().ToList(); // Output devices (headset, speakers...) + PlaybackDevice gameDevice = sonarManager.PlaybackDevices.GetPlaybackDevice(Channel.GAME); // Get the currently used Playback device of a Channel + sonarManager.PlaybackDevices.GetPlaybackDevice(Mix.STREAM); // Get the currently used Playback device of a Mix + sonarManager.PlaybackDevices.GetPlaybackDevice(Channel.MIC, Mode.STREAMER); // Get the currently used Playback device of the streamer mode Mic + sonarManager.PlaybackDevices.GetPlaybackDevice("{0.0.0.00000000}.{192b4f5b-9cc1-4eb2-b752-c5e15b99d548}"); // Get a playback device from its id + // Change playback devices + sonarManager.PlaybackDevices.SetPlaybackDevice(gameDevice, Channel.GAME); // Using the playback device object + sonarManager.PlaybackDevices.SetPlaybackDevice("{0.0.0.00000000}.{192b4f5b-9cc1-4eb2-b752-c5e15b99d548}", Channel.AUX); // Using the playback device ID - // Get the redirections states - sonarManager.GetRedirectionState(Device.Media, Channel.Monitoring); - // Change the redirections states - sonarManager.SetRedirectionState(false, Device.Media, Channel.Monitoring); + // Get the mixes states + sonarManager.Mix.GetState(Channel.MEDIA, Mix.PERSONAL); + // Change the mixes states + sonarManager.Mix.Activate(Channel.MEDIA, Mix.PERSONAL); + sonarManager.Mix.Deactivate(Channel.CHAT, Mix.STREAM); + sonarManager.Mix.SetState(false, Channel.MEDIA, Mix.PERSONAL); // Same as deactivating here // Get Audience Monitoring state - sonarManager.GetAudienceMonitoringState(); + sonarManager.AudienceMonitoring.GetState(); // Change Audience Monitoring state - sonarManager.SetAudienceMonitoringState(false); - - // Get routed processes of a Sonar Device - List mediaProcesses = sonarManager.GetRoutedProcess(Device.Media).ToList(); // Will surely return apps like Google Chrome or Spotify - // Route a process to a Sonar Device using its process ID (pid) - sonarManager.SetProcessToDeviceRouting(mediaProcesses[0].PId, Device.Media); + sonarManager.AudienceMonitoring.SetState(false); + + // Get all routed processes whether they are active, inactive or expired + List allProcesses = sonarManager.RoutedProcesses.GetAllRoutedProcesses().ToList(); + // Get all active routed processes (currently in use) + List allActiveProcesses = sonarManager.RoutedProcesses.GetAllActiveRoutedProcesses().ToList(); + // Same but for a specific channel + List gameProcesses = sonarManager.RoutedProcesses.GetRoutedProcesses(Channel.GAME).ToList(); // Will surely return apps like Minecraft... + List mediaActiveProcesses = sonarManager.RoutedProcesses.GetActiveRoutedProcesses(Channel.MEDIA).ToList(); // Will surely return apps like Google Chrome or Spotify + // Same idea but by giving the ID of an audio process + sonarManager.RoutedProcesses.GetRoutedProcessesById(2063); + sonarManager.RoutedProcesses.GetActiveRoutedProcessesById(10548); + // Route a process to a Sonar Channel using the RoutedProcess object + sonarManager.RoutedProcesses.RouteProcessToChannel(mediaActiveProcesses[0], Channel.AUX); + // Route a process to a Sonar Channel using its process ID (pid) + sonarManager.RoutedProcesses.RouteProcessToChannel(15482, Channel.MEDIA); } static void OnModeChangeHandler(object? sender, SonarModeEvent eventArgs) @@ -95,12 +112,12 @@ static void OnModeChangeHandler(object? sender, SonarModeEvent eventArgs) static void OnVolumeChangeHandler(object? sender, SonarVolumeEvent eventArgs) { - Console.WriteLine("Received Volume Event : " + eventArgs.Volume + ", " + eventArgs.Mode + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Volume Event : " + eventArgs.Volume + ", " + eventArgs.Mode + ", " + eventArgs.Channel + ", " + eventArgs.Mix); } static void OnMuteChangeHandler(object? sender, SonarMuteEvent eventArgs) { - Console.WriteLine("Received Mute Event : " + eventArgs.Muted + ", " + eventArgs.Mode + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Mute Event : " + eventArgs.Muted + ", " + eventArgs.Mode + ", " + eventArgs.Channel + ", " + eventArgs.Mix); } static void OnConfigChangeHandler(object? sender, SonarConfigEvent eventArgs) @@ -113,18 +130,23 @@ static void OnChatMixChangeHandler(object? sender, SonarChatMixEvent eventArgs) Console.WriteLine("Received ChatMix Event : " + eventArgs.Balance); } - static void OnRedirectionDeviceChangeHandler(object? sender, SonarRedirectionDeviceEvent eventArgs) + static void OnPlaybackDeviceChangeHandler(object? sender, SonarPlaybackDeviceEvent eventArgs) + { + Console.WriteLine("Received Redirection Channel Event : " + eventArgs.PlaybackDeviceId + ", " + eventArgs.Mode + ", " + eventArgs.Channel + ", " + eventArgs.Mix); + } + + static void OnRoutedProcessChangeHandler(object? sender, SonarRoutedProcessEvent eventArgs) { - Console.WriteLine("Received Redirection Device Event : " + eventArgs.RedirectionDeviceId + ", " + eventArgs.Mode + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Routed Process Event : " + eventArgs.ProcessId + ", " + eventArgs.NewChannel); } - static void OnRedirectionStateChangeHandler(object? sender, SonarRedirectionStateEvent eventArgs) + static void OnMixChangeHandler(object? sender, SonarMixEvent eventArgs) { - Console.WriteLine("Received Redirection State Event : " + eventArgs.State + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Redirection State Event : " + eventArgs.NewState + ", " + eventArgs.Channel + ", " + eventArgs.Mix); } static void OnAudienceMonitoringChangeHandler(object? sender, SonarAudienceMonitoringEvent eventArgs) { - Console.WriteLine("Received Audience Monitoring Event : " + eventArgs.AudienceMonitoringState); + Console.WriteLine("Received Audience Monitoring Event : " + eventArgs.NewState); } } \ No newline at end of file diff --git a/SteelSeriesAPI.Tests/Program.cs b/SteelSeriesAPI.Tests/Program.cs index 092d874..cb3c195 100644 --- a/SteelSeriesAPI.Tests/Program.cs +++ b/SteelSeriesAPI.Tests/Program.cs @@ -1,6 +1,7 @@ -using SteelSeriesAPI.Events; -using SteelSeriesAPI.Sonar; +using SteelSeriesAPI.Sonar; +using SteelSeriesAPI.Sonar.Events; using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Exceptions; using SteelSeriesAPI.Sonar.Models; namespace SteelSeriesAPI.Tests; @@ -10,228 +11,213 @@ class Program static void Main(string[] args) { SonarBridge sonarManager = new SonarBridge(); + sonarManager.WaitUntilSteelSeriesStarted(); sonarManager.WaitUntilSonarStarted(); - Console.WriteLine(new SonarRetriever().WebServerAddress()); - + Console.WriteLine(SonarRetriever.Instance.WebServerAddress()); + sonarManager.StartListener(); // Thread.Sleep(1000); // sonarManager.StopListener(); - sonarManager.SonarEventManager.OnSonarModeChange += OnModeChangeHandler; - sonarManager.SonarEventManager.OnSonarVolumeChange += OnVolumeChangeHandler; - sonarManager.SonarEventManager.OnSonarMuteChange += OnMuteChangeHandler; - sonarManager.SonarEventManager.OnSonarConfigChange += OnConfigChangeHandler; - sonarManager.SonarEventManager.OnSonarChatMixChange += OnChatMixChangeHandler; - sonarManager.SonarEventManager.OnSonarRedirectionDeviceChange += OnRedirectionDeviceChangeHandler; - sonarManager.SonarEventManager.OnSonarRedirectionStateChange += OnRedirectionStateChangeHandler; - sonarManager.SonarEventManager.OnSonarAudienceMonitoringChange += OnAudienceMonitoringChangeHandler; - - // new Program().GetTest(sonarManager); - // new Program().SetTest(sonarManager); - // new Program().TestMaster(sonarManager); - } - - void TestMaster(SonarBridge sonarManager) - { + sonarManager.Events.OnSonarModeChange += OnModeChangeHandler; + sonarManager.Events.OnSonarVolumeChange += OnVolumeChangeHandler; + sonarManager.Events.OnSonarMuteChange += OnMuteChangeHandler; + sonarManager.Events.OnSonarConfigChange += OnConfigChangeHandler; + sonarManager.Events.OnSonarChatMixChange += OnChatMixChangeHandler; + sonarManager.Events.OnSonarPlaybackDeviceChange += OnPlaybackDeviceChangeHandler; + sonarManager.Events.OnSonarRoutedProcessChange += OnRoutedProcessChangeHandler; + sonarManager.Events.OnSonarMixChange += OnMixChangeHandler; + sonarManager.Events.OnSonarAudienceMonitoringChange += OnAudienceMonitoringChangeHandler; + + // Save current settings + var mode = sonarManager.Mode.Get(); + var chatmix = sonarManager.ChatMix.GetBalance(); + var audienceMonitoring = sonarManager.AudienceMonitoring.GetState(); - // Classic - sonarManager.SetMode(Mode.Classic); - Console.WriteLine("------ Classic Master Test ------"); - Console.WriteLine(sonarManager.GetVolume(Device.Master)); - Console.WriteLine(sonarManager.GetMute(Device.Master)); - sonarManager.SetVolume(0.25f, Device.Master); - sonarManager.SetVolume(1, Device.Master); - sonarManager.SetMute(true, Device.Master); - sonarManager.SetMute(false, Device.Master); - - // Streamer - sonarManager.SetMode(Mode.Streamer); - Console.WriteLine("------ Streamer Master Test ------"); - Console.WriteLine(sonarManager.GetVolume(Device.Master, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetVolume(Device.Master, Channel.Stream)); - Console.WriteLine(sonarManager.GetMute(Device.Master, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetMute(Device.Master, Channel.Stream)); - sonarManager.SetVolume(0.25f, Device.Master, Channel.Monitoring); - sonarManager.SetVolume(0.25f, Device.Master, Channel.Stream); - sonarManager.SetVolume(1, Device.Master, Channel.Monitoring); - sonarManager.SetVolume(1, Device.Master, Channel.Stream); - sonarManager.SetMute(true, Device.Master, Channel.Monitoring); - sonarManager.SetMute(true, Device.Master, Channel.Stream); - sonarManager.SetMute(false, Device.Master, Channel.Monitoring); - sonarManager.SetMute(false, Device.Master, Channel.Stream); + sonarManager.Mode.Set(Mode.CLASSIC); - sonarManager.SetMode(Mode.Classic); - } - - void GetTest(SonarBridge sonarManager) - { - - Console.WriteLine(sonarManager.GetMode()); - Console.WriteLine("" + sonarManager.GetVolume(Device.Master) + " " + sonarManager.GetMute(Device.Master)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Game) + " " + sonarManager.GetMute(Device.Game)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Chat) + " " + sonarManager.GetMute(Device.Chat)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Media) + " " + sonarManager.GetMute(Device.Media)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Aux) + " " + sonarManager.GetMute(Device.Aux)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Mic) + " " + sonarManager.GetMute(Device.Mic)); - Console.WriteLine("-----------------Streamer-Monitoring-------------"); - Console.WriteLine("" + sonarManager.GetVolume(Device.Master, Channel.Monitoring) + " " + sonarManager.GetMute(Device.Master, Channel.Monitoring)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Game, Channel.Monitoring) + " " + sonarManager.GetMute(Device.Game, Channel.Monitoring)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Chat, Channel.Monitoring) + " " + sonarManager.GetMute(Device.Chat, Channel.Monitoring)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Media, Channel.Monitoring) + " " + sonarManager.GetMute(Device.Media, Channel.Monitoring)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Aux, Channel.Monitoring) + " " + sonarManager.GetMute(Device.Aux, Channel.Monitoring)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Mic, Channel.Monitoring) + " " + sonarManager.GetMute(Device.Mic, Channel.Monitoring)); - Console.WriteLine("-----------------Streamer-Stream-------------"); - Console.WriteLine("" + sonarManager.GetVolume(Device.Master, Channel.Stream) + " " + sonarManager.GetMute(Device.Master, Channel.Stream)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Game, Channel.Stream) + " " + sonarManager.GetMute(Device.Game, Channel.Stream)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Chat, Channel.Stream) + " " + sonarManager.GetMute(Device.Chat, Channel.Stream)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Media, Channel.Stream) + " " + sonarManager.GetMute(Device.Media, Channel.Stream)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Aux, Channel.Stream) + " " + sonarManager.GetMute(Device.Aux, Channel.Stream)); - Console.WriteLine("" + sonarManager.GetVolume(Device.Mic, Channel.Stream) + " " + sonarManager.GetMute(Device.Mic, Channel.Stream)); - Console.WriteLine("----AudioConfigs----------"); - foreach (var config in sonarManager.GetAllAudioConfigurations()) + foreach (Channel channel in (Channel[])Enum.GetValues(typeof(Channel))) { - Console.WriteLine(config.Id + ", " + config.Name + ", " + config.AssociatedDevice); - } + Console.WriteLine("------ " + channel + " ------"); + if (channel == Channel.MASTER) + { + var volume = sonarManager.VolumeSettings.GetVolume(channel); + var mute = sonarManager.VolumeSettings.GetMute(channel); + + Console.WriteLine("Volume test..."); + sonarManager.VolumeSettings.SetVolume(volume + 0.2, channel); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetVolume(volume, channel); + + Thread.Sleep(500); - Console.WriteLine("----Media-Configs----------"); - foreach (var config in sonarManager.GetAudioConfigurations(Device.Media)) - { - Console.WriteLine(config.Id + ", " + config.Name); + Console.WriteLine("Mute test..."); + sonarManager.VolumeSettings.SetMute(!mute, channel); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetMute(mute, channel); + } + else + { + var volume = sonarManager.VolumeSettings.GetVolume(channel); + var mute = sonarManager.VolumeSettings.GetMute(channel); + var config = sonarManager.Configurations.GetSelectedAudioConfiguration(channel); + var playbackDevice = sonarManager.PlaybackDevices.GetPlaybackDevice(channel); + var routedProcesses = new List(sonarManager.RoutedProcesses.GetActiveRoutedProcesses(channel)); + + Console.WriteLine("Volume test..."); + sonarManager.VolumeSettings.SetVolume(volume + 0.2, channel); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetVolume(volume, channel); + + Thread.Sleep(500); + + Console.WriteLine("Mute test..."); + sonarManager.VolumeSettings.SetMute(!mute, channel); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetMute(mute, channel); + + Thread.Sleep(500); + + Console.WriteLine("Config test..."); + sonarManager.Configurations.SetConfig(sonarManager.Configurations.GetAudioConfigurations(channel).ToList()[4]); + Thread.Sleep(1000); + sonarManager.Configurations.SetConfig(config); + + Thread.Sleep(500); + + Console.WriteLine("Playback Device test..."); + if (channel == Channel.MIC) + { + sonarManager.PlaybackDevices.SetPlaybackDevice(sonarManager.PlaybackDevices.GetInputPlaybackDevices().First(), channel); + } + else + { + sonarManager.PlaybackDevices.SetPlaybackDevice(sonarManager.PlaybackDevices.GetOutputPlaybackDevices().First(), channel); + } + Thread.Sleep(1000); + sonarManager.PlaybackDevices.SetPlaybackDevice(playbackDevice, channel); + + Console.WriteLine("Routed Processes test..."); + foreach (var r in routedProcesses) + { + if (channel == Channel.GAME) + { + sonarManager.RoutedProcesses.RouteProcessToChannel(r, Channel.AUX); + } + else + { + sonarManager.RoutedProcesses.RouteProcessToChannel(r, Channel.GAME); + } + } + Thread.Sleep(1000); + foreach (var r in routedProcesses) + { + sonarManager.RoutedProcesses.RouteProcessToChannel(r, channel); + } + } } - Console.WriteLine("----Mic-Configs----------"); - foreach (var config in sonarManager.GetAudioConfigurations(Device.Mic)) + if (sonarManager.ChatMix.GetState()) { - Console.WriteLine(config.Id + ", " + config.Name); + Console.WriteLine("Chat Mix Test..."); + sonarManager.ChatMix.SetBalance(chatmix + 0.2); + Thread.Sleep(1000); + sonarManager.ChatMix.SetBalance(chatmix); } - - Console.WriteLine("----Current Media Config----------"); - Console.WriteLine(sonarManager.GetSelectedAudioConfiguration(Device.Media).Name); - Console.WriteLine("----Device from config ID----------"); - Console.WriteLine(sonarManager.GetAudioConfiguration("29ae2c02-792b-4487-863c-dc3e11a7a469").AssociatedDevice); - Console.WriteLine("--------ChatMix---------"); - Console.WriteLine(sonarManager.GetChatMixBalance()); - Console.WriteLine(sonarManager.GetChatMixState()); - - Console.WriteLine("-----Redirection Devices-----------"); - Console.WriteLine("---Output---"); - foreach (var rDevice in sonarManager.GetRedirectionDevices(Direction.Output)) + else { - Console.WriteLine(rDevice.Id + ", " + rDevice.Name); - foreach (var device in rDevice.AssociatedClassicDevices) - { - Console.WriteLine("...." + device); - } + Console.WriteLine("Chat Mix disabled. Can't do test"); + } + + sonarManager.Mode.Set(Mode.STREAMER); - foreach (var channel in rDevice.AssociatedStreamDevices) + foreach (Channel channel in (Channel[])Enum.GetValues(typeof(Channel))) + { + foreach (Mix mix in (Mix[])Enum.GetValues(typeof(Mix))) { - Console.WriteLine("...." + channel); + Console.WriteLine("------ " + channel + " - " + mix + " ------"); + if (channel == Channel.MASTER) + { + var volume = sonarManager.VolumeSettings.GetVolume(channel, mix); + var mute = sonarManager.VolumeSettings.GetMute(channel, mix); + + Console.WriteLine("Volume test..."); + sonarManager.VolumeSettings.SetVolume(volume - 0.2, channel, mix); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetVolume(volume, channel, mix); + + Thread.Sleep(500); + + Console.WriteLine("Mute test..."); + sonarManager.VolumeSettings.SetMute(!mute, channel, mix); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetMute(mute, channel, mix); + } + else + { + var volume = sonarManager.VolumeSettings.GetVolume(channel, mix); + var mute = sonarManager.VolumeSettings.GetMute(channel, mix); + var redirection = sonarManager.Mix.GetState(channel, mix); + + Console.WriteLine("Volume test..."); + sonarManager.VolumeSettings.SetVolume(volume - 0.2, channel, mix); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetVolume(volume, channel, mix); + + Thread.Sleep(500); + + Console.WriteLine("Mute test..."); + sonarManager.VolumeSettings.SetMute(!mute, channel, mix); + Thread.Sleep(1000); + sonarManager.VolumeSettings.SetMute(mute, channel, mix); + + Console.WriteLine("Mix test..."); + sonarManager.Mix.SetState(!redirection, channel, mix); + Thread.Sleep(1000); + sonarManager.Mix.SetState(redirection, channel, mix); + } } } - - Console.WriteLine("---Input---"); - foreach (var rDevice in sonarManager.GetRedirectionDevices(Direction.Input)) + + Console.WriteLine("Playback Device test..."); + foreach (Mix mix in (Mix[])Enum.GetValues(typeof(Mix))) { - Console.WriteLine(rDevice.Id + ", " + rDevice.Name); - foreach (var device in rDevice.AssociatedClassicDevices) + try { - Console.WriteLine("...." + device); + Console.WriteLine(mix); + var playbackDevice = sonarManager.PlaybackDevices.GetPlaybackDevice(mix); + sonarManager.PlaybackDevices.SetPlaybackDevice(sonarManager.PlaybackDevices.GetOutputPlaybackDevices().First(), mix); + Thread.Sleep(1000); + sonarManager.PlaybackDevices.SetPlaybackDevice(playbackDevice, mix); } - - foreach (var channel in rDevice.AssociatedStreamDevices) + catch (PlaybackDeviceNotFoundException e) { - Console.WriteLine("...." + channel); + Console.WriteLine(e); + Console.WriteLine("No playback device set for : " + mix); } } - Console.WriteLine("-----Classic Redirection Devices------------"); - RedirectionDevice reDevice = sonarManager.GetClassicRedirectionDevice(Device.Game); - Console.WriteLine(reDevice.Id + ", " + reDevice.Name); - foreach (var device in reDevice.AssociatedClassicDevices) + try { - Console.WriteLine("...." + device); + Console.WriteLine(Channel.MIC + " " + Mode.STREAMER); + var micPlaybackDevice = sonarManager.PlaybackDevices.GetPlaybackDevice(Channel.MIC, Mode.STREAMER); + sonarManager.PlaybackDevices.SetPlaybackDevice(sonarManager.PlaybackDevices.GetOutputPlaybackDevices().First(), Channel.MIC, Mode.STREAMER); + Thread.Sleep(1000); + sonarManager.PlaybackDevices.SetPlaybackDevice(micPlaybackDevice, Channel.MIC, Mode.STREAMER); } - - foreach (var channel in reDevice.AssociatedStreamDevices) + catch (PlaybackDeviceNotFoundException e) { - Console.WriteLine("...." + channel); + Console.WriteLine(e); + Console.WriteLine("No playback device set for : " + Channel.MIC + Mode.STREAMER); } - - Console.WriteLine("-----Stream Redirection Devices------------"); - RedirectionDevice reDeviceS = sonarManager.GetStreamRedirectionDevice(Device.Mic); // sonarManager.GetStreamRedirectionDevice(Channel.Monitoring); - Console.WriteLine(reDeviceS.Id + ", " + reDeviceS.Name); - foreach (var device in reDeviceS.AssociatedClassicDevices) - { - Console.WriteLine("...." + device); - } - - foreach (var channel in reDeviceS.AssociatedStreamDevices) - { - Console.WriteLine("...." + channel); - } - - Console.WriteLine("-----Redirection Device From Id"); - // RedirectionDevice someDevice = sonarManager.GetRedirectionDeviceFromId("{0.0.0.00000000}.{453f6e2f-375e-4b36-97b2-2aa55691ab3c}"); - // Console.WriteLine(someDevice.Id + ", " + someDevice.Name + ", " + someDevice.DataFlow); - // foreach (var associatedClassicDevice in someDevice.AssociatedClassicDevices) - // { - // Console.WriteLine("...." + associatedClassicDevice); - // } - // - // foreach (var associatedStreamDevice in someDevice.AssociatedStreamDevices) - // { - // Console.WriteLine("...." + associatedStreamDevice); - // } - - Console.WriteLine("-----Redirection States---------"); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Game, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Chat, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Media, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Aux, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Mic, Channel.Monitoring)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Game, Channel.Stream)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Chat, Channel.Stream)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Media, Channel.Stream)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Aux, Channel.Stream)); - Console.WriteLine(sonarManager.GetRedirectionState(Device.Mic, Channel.Stream)); - Console.WriteLine("-----Audience Monitoring-------"); - Console.WriteLine(sonarManager.GetAudienceMonitoringState()); - Console.WriteLine("-----Routed Processes-----------"); - foreach (Device device in (Device[])Enum.GetValues(typeof(Device))) - { - if (device == Device.Master) - { - continue; - } - - Console.WriteLine("-- " + device); - foreach (var routed in sonarManager.GetRoutedProcess(device)) - { - Console.WriteLine(routed.Id + ", " + routed.ProcessName + ", " + routed.PId + ", " + routed.State + - ", " + routed.DisplayName); - } - } - } - - void SetTest(SonarBridge sonarManager){ - - sonarManager.SetMode(Mode.Classic); - sonarManager.SetVolume(0.4, Device.Media); - sonarManager.SetMute(false, Device.Media); - string configId = sonarManager.GetAudioConfigurations(Device.Media).FirstOrDefault(config => config.Name == "Default")?.Id; - sonarManager.SetConfig(configId); - sonarManager.SetConfig(Device.Media, "Default"); - sonarManager.SetChatMixBalance(0.5); - var redirectionDevices = sonarManager.GetRedirectionDevices(Direction.Input); - redirectionDevices.GetEnumerator().MoveNext(); - sonarManager.SetClassicRedirectionDevice(redirectionDevices.GetEnumerator().Current.Id, Device.Mic); - sonarManager.SetStreamRedirectionDevice(redirectionDevices.GetEnumerator().Current.Id, Device.Mic); + Console.WriteLine("Audience Monitoring Test..."); + sonarManager.AudienceMonitoring.SetState(!audienceMonitoring); + Thread.Sleep(1000); + sonarManager.AudienceMonitoring.SetState(audienceMonitoring); - sonarManager.SetRedirectionState(true, Device.Media, Channel.Stream); - sonarManager.SetAudienceMonitoringState(false); - sonarManager.SetProcessToDeviceRouting(19152, Device.Mic); + sonarManager.Mode.Set(mode); } static void OnModeChangeHandler(object? sender, SonarModeEvent eventArgs) @@ -241,12 +227,12 @@ static void OnModeChangeHandler(object? sender, SonarModeEvent eventArgs) static void OnVolumeChangeHandler(object? sender, SonarVolumeEvent eventArgs) { - Console.WriteLine("Received Volume Event : " + eventArgs.Volume + ", " + eventArgs.Mode + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Volume Event : " + eventArgs.Volume + ", " + eventArgs.Mode + ", " + eventArgs.Channel + ", " + eventArgs.Mix); } static void OnMuteChangeHandler(object? sender, SonarMuteEvent eventArgs) { - Console.WriteLine("Received Mute Event : " + eventArgs.Muted + ", " + eventArgs.Mode + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Mute Event : " + eventArgs.Muted + ", " + eventArgs.Mode + ", " + eventArgs.Channel + ", " + eventArgs.Mix); } static void OnConfigChangeHandler(object? sender, SonarConfigEvent eventArgs) @@ -259,18 +245,23 @@ static void OnChatMixChangeHandler(object? sender, SonarChatMixEvent eventArgs) Console.WriteLine("Received ChatMix Event : " + eventArgs.Balance); } - static void OnRedirectionDeviceChangeHandler(object? sender, SonarRedirectionDeviceEvent eventArgs) + static void OnPlaybackDeviceChangeHandler(object? sender, SonarPlaybackDeviceEvent eventArgs) + { + Console.WriteLine("Received Redirection Channel Event : " + eventArgs.PlaybackDeviceId + ", " + eventArgs.Mode + ", " + eventArgs.Channel + ", " + eventArgs.Mix); + } + + static void OnRoutedProcessChangeHandler(object? sender, SonarRoutedProcessEvent eventArgs) { - Console.WriteLine("Received Redirection Device Event : " + eventArgs.RedirectionDeviceId + ", " + eventArgs.Mode + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Routed Process Event : " + eventArgs.ProcessId + ", " + eventArgs.NewChannel); } - static void OnRedirectionStateChangeHandler(object? sender, SonarRedirectionStateEvent eventArgs) + static void OnMixChangeHandler(object? sender, SonarMixEvent eventArgs) { - Console.WriteLine("Received Redirection State Event : " + eventArgs.State + ", " + eventArgs.Device + ", " + eventArgs.Channel); + Console.WriteLine("Received Redirection State Event : " + eventArgs.NewState + ", " + eventArgs.Channel + ", " + eventArgs.Mix); } static void OnAudienceMonitoringChangeHandler(object? sender, SonarAudienceMonitoringEvent eventArgs) { - Console.WriteLine("Received Audience Monitoring Event : " + eventArgs.AudienceMonitoringState); + Console.WriteLine("Received Audience Monitoring Event : " + eventArgs.NewState); } } \ No newline at end of file diff --git a/SteelSeriesAPI/Events/SonarAudienceMonitoringEvent.cs b/SteelSeriesAPI/Events/SonarAudienceMonitoringEvent.cs deleted file mode 100644 index 2b81278..0000000 --- a/SteelSeriesAPI/Events/SonarAudienceMonitoringEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SteelSeriesAPI.Events; - -public class SonarAudienceMonitoringEvent : EventArgs -{ - // /streamRedirections/isStreamMonitoringEnabled/bool - public bool AudienceMonitoringState { get; set; } -} \ No newline at end of file diff --git a/SteelSeriesAPI/Exceptions/SteelSeriesNotRunningException.cs b/SteelSeriesAPI/Exceptions/SteelSeriesNotRunningException.cs new file mode 100644 index 0000000..a2de28a --- /dev/null +++ b/SteelSeriesAPI/Exceptions/SteelSeriesNotRunningException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Exceptions; + +public class SteelSeriesNotRunningException : Exception +{ + public SteelSeriesNotRunningException() : base("SteelSeries is not running.") { } + public SteelSeriesNotRunningException(string message) : base(message) { } + public SteelSeriesNotRunningException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Interfaces/ISonarCommandHandler.cs b/SteelSeriesAPI/Interfaces/ISonarCommandHandler.cs deleted file mode 100644 index 1896656..0000000 --- a/SteelSeriesAPI/Interfaces/ISonarCommandHandler.cs +++ /dev/null @@ -1,107 +0,0 @@ -using SteelSeriesAPI.Sonar.Enums; - -namespace SteelSeriesAPI.Interfaces; - -public interface ISonarCommandHandler -{ - /// - /// Set the Sonar will be using - /// - /// The you want to set - void SetMode(Mode mode); - - /// - /// Set the volume of a Sonar - /// - /// The volume you want to set, between 1 and 0 - /// The you want to change the volume - void SetVolume(double vol, Device device); - - /// - /// Set the volume of a Streamer mode Sonar - /// - /// The volume you want to set, between 1 and 0 - /// The you want to change the volume - /// The you want to change the volume - void SetVolume(double vol, Device device, Channel channel); - - /// - /// Mute or unmute a Sonar - /// - /// The new muted state - /// The you want to un/mute - void SetMute(bool mute, Device device); - - /// - /// Mute or unmute a Streamer mode Sonar - /// - /// The new muted state - /// The you want to un/mute - /// The you want to un/mute - void SetMute(bool mute, Device device, Channel channel); - - /// - /// Set the config of a Sonar by giving its id - /// - /// For more explanation, go on the GitHub wiki - /// The id of the config - void SetConfig(string configId); - - /// - /// Set the config of a Sonar by giving its name - /// - /// For more explanation, go on the GitHub wiki - /// The you want to change the config - /// The name of the config - void SetConfig(Device device, string name); - - /// - /// Set the balance of the ChatMix - /// - /// -1 to balance to Game device
1 to balance to Chat device
- /// A between -1 and 1 - void SetChatMixBalance(double balance); - - /// - /// Set the Redirection Device of a Sonar using its ID - /// - /// The id of the new Redirection Device - /// The Sonar you want to change the Redirection Device - void SetClassicRedirectionDevice(string deviceId, Device device); - - /// - /// Set the Redirection Device of a Streamer mode Sonar using its ID - /// - /// The id of the new Redirection Device - /// The Sonar you want to change the Redirection Device - void SetStreamRedirectionDevice(string deviceId, Channel channel); - - /// - /// Set the Redirection Device of the Streamer mode Sonar using its ID - /// - /// The id of the new Redirection Device - /// The Sonar you want to change the redirection device - /// should be set to for it to work - void SetStreamRedirectionDevice(string deviceId, Device device = Device.Mic); - - /// - /// Enable or disable the Redirection of the chosen Sonar of the chosen Sonar - /// - /// The new state of the Redirection - /// The Sonar you want to un/mute a Sonar redirection channel - /// The Sonar you want to un/mute - void SetRedirectionState(bool newState, Device device, Channel channel); - - /// - /// Listen to what your audience hear - /// - /// The new state, un/muted - void SetAudienceMonitoringState(bool newState); - - /// - /// Redirect the audio of an app to a Sonar - /// - /// The process ID of the app - /// The Sonar you want to set the app audio - void SetProcessToDeviceRouting(int pId, Device device); -} \ No newline at end of file diff --git a/SteelSeriesAPI/Interfaces/ISonarDataProvider.cs b/SteelSeriesAPI/Interfaces/ISonarDataProvider.cs deleted file mode 100644 index faba306..0000000 --- a/SteelSeriesAPI/Interfaces/ISonarDataProvider.cs +++ /dev/null @@ -1,139 +0,0 @@ -using SteelSeriesAPI.Sonar.Enums; -using SteelSeriesAPI.Sonar.Models; - -namespace SteelSeriesAPI.Interfaces; - -public interface ISonarDataProvider -{ - /// - /// Get the current mode used by Sonar - /// - /// A , either Classic or Streamer - Mode GetMode(); - - /// - /// Get the volume of a Sonar - /// - /// The Sonar you want the volume - /// The volume of the channel in double, value between 0 and 1 - double GetVolume(Device device); - - /// - /// Get the volume of a Steamer mode Sonar - /// - /// The Sonar you want the volume - /// The Sonar you want the volume - /// The volume of the channel in double, value between 0 and 1 - double GetVolume(Device device, Channel channel); - - /// - /// Get the mute state of a Sonar - /// - /// The Sonar you want the mute state - /// The mute state, a boolean - bool GetMute(Device device); - - /// - /// Get the mute state of a Streamer mode Sonar - /// - /// The Sonar you want the mute state - /// The Sonar you want the mute state - /// The mute state, a boolean - bool GetMute(Device device, Channel channel); - - /// - /// Get all audio configurations from Sonar - /// - /// An IEnumerable of - IEnumerable GetAllAudioConfigurations(); - - /// - /// Get a specific audio configuration from Sonar - /// - /// The id of the config - /// A - SonarAudioConfiguration GetAudioConfiguration(string configId); - - /// - /// Get all audio configurations of a from Sonar - /// - /// The device you want the configs - /// An IEnumerable of ordered alphabetically - IEnumerable GetAudioConfigurations(Device device); - - /// - /// Get the current audio configuration of a chosen - /// - /// The device you want the current config - /// A - SonarAudioConfiguration GetSelectedAudioConfiguration(Device device); - - /// - /// Get the actual ChatMix balance value - /// - /// A double between -1 and 1 - double GetChatMixBalance(); - - /// - /// Get the actual state of the ChatMix - /// - /// True if ChatMix is enabled
False if ChatMix is disabled
- bool GetChatMixState(); - - /// - /// Get all the in/output Redirection Devices (Windows devices) - /// - /// The DataFlow of the device (In/Output) - /// A list of - IEnumerable GetRedirectionDevices(Direction direction); - - /// - /// Get the current Redirection Device of a Sonar - /// - /// The Sonar you want the redirection device - /// - RedirectionDevice GetClassicRedirectionDevice(Device device); - - /// - /// Get the current Redirection Device of a Streamer mode Sonar - /// - /// The Sonar you want the redirection device - /// A - RedirectionDevice GetStreamRedirectionDevice(Channel channel); - - /// - /// Get the current Redirection Device of the Streamer mode Sonar - /// - /// The Sonar you want to change the redirection device - /// - /// should be set to for it to work - RedirectionDevice GetStreamRedirectionDevice(Device device = Device.Mic); - - /// - /// Get a Redirection Device using its ID - /// - /// The ID of the Redirection Device - /// - RedirectionDevice GetRedirectionDeviceFromId(string deviceId); - - /// - /// Get the mute state of the Redirection of the chosen Sonar of the chosen Sonar - /// - /// The Sonar you want the mute state of a Redirection channel - /// The Sonar you want to get the mute state - /// The current state, un/muted - bool GetRedirectionState(Device device, Channel channel); - - /// - /// Get the current state of the Audience Monitoring - /// - /// The current state, un/muted - bool GetAudienceMonitoringState(); - - /// - /// Get the apps which their audio is redirected to a Sonar - /// - /// The Sonar you want the associated processes - /// A list of - IEnumerable GetRoutedProcess(Device device); -} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Enums/Channel.cs b/SteelSeriesAPI/Sonar/Enums/Channel.cs index 367bc5c..4e82dec 100644 --- a/SteelSeriesAPI/Sonar/Enums/Channel.cs +++ b/SteelSeriesAPI/Sonar/Enums/Channel.cs @@ -2,30 +2,82 @@ namespace SteelSeriesAPI.Sonar.Enums; public enum Channel { - Monitoring, - Stream + MASTER, + GAME, + CHAT, + MEDIA, + AUX, + MIC +} + +public enum ChannelMapChoice +{ + JsonDict, + HttpDict, + ChannelDict } public static class ChannelExtensions { - private static readonly Dictionary ChannelMap = new Dictionary + private static readonly Dictionary ChannelJsonMap = new Dictionary + { + { Channel.MASTER, "masters" }, + { Channel.GAME, "game" }, + { Channel.CHAT, "chatRender" }, + { Channel.MEDIA, "media" }, + { Channel.AUX, "aux" }, + { Channel.MIC, "chatCapture" } + }; + + private static readonly Dictionary ChannelHttpMap = new Dictionary { - { Channel.Monitoring, "monitoring" }, - { Channel.Stream, "streaming" } + { Channel.MASTER, "Master" }, + { Channel.GAME, "game" }, + { Channel.CHAT, "chatRender" }, + { Channel.MEDIA, "media" }, + { Channel.AUX, "aux" }, + { Channel.MIC, "chatCapture" } }; - public static string ToDictKey(this Channel channel) + private static readonly Dictionary ChannelMap = new Dictionary + { + { Channel.MASTER, "master" }, + { Channel.GAME, "game" }, + { Channel.CHAT, "chat" }, + { Channel.MEDIA, "media" }, + { Channel.AUX, "aux" }, + { Channel.MIC, "mic" } + }; + + public static string ToDictKey(this Channel channel, ChannelMapChoice context = ChannelMapChoice.JsonDict) { - return ChannelMap[channel]; + return context switch + { + ChannelMapChoice.JsonDict => ChannelJsonMap.ContainsKey(channel) ? ChannelJsonMap[channel] : null, + ChannelMapChoice.HttpDict => ChannelHttpMap.ContainsKey(channel) ? ChannelHttpMap[channel] : null, + ChannelMapChoice.ChannelDict => ChannelMap.ContainsKey(channel) ? ChannelMap[channel] : null, + _ => null + }; } - public static Channel? FromDictKey(string jsonKey) + public static Channel? FromDictKey(string jsonKey, ChannelMapChoice context = ChannelMapChoice.JsonDict) { - foreach (var pair in ChannelMap) + var map = context switch + { + ChannelMapChoice.JsonDict => ChannelJsonMap, + ChannelMapChoice.HttpDict => ChannelHttpMap, + ChannelMapChoice.ChannelDict => ChannelMap, + _ => null + }; + + if (map != null) { - if (pair.Value == jsonKey) + foreach (var pair in map) { - return pair.Key; + if (pair.Value.ToLower() == jsonKey.ToLower()) + { + return pair.Key; + } } } diff --git a/SteelSeriesAPI/Sonar/Enums/DataFlow.cs b/SteelSeriesAPI/Sonar/Enums/DataFlow.cs new file mode 100644 index 0000000..082ff07 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Enums/DataFlow.cs @@ -0,0 +1,34 @@ +namespace SteelSeriesAPI.Sonar.Enums; + +public enum DataFlow +{ + INPUT, + OUTPUT +} + +public static class DataFlowExtensions +{ + private static readonly Dictionary DataFlowMap = new Dictionary + { + { DataFlow.INPUT, "capture" }, + { DataFlow.OUTPUT, "render" } + }; + + public static string ToDictKey(this DataFlow dataFlow) + { + return DataFlowMap[dataFlow]; + } + + public static DataFlow? FromDictKey(string jsonKey) + { + foreach (var pair in DataFlowMap) + { + if (pair.Value == jsonKey) + { + return pair.Key; + } + } + + return null; + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Enums/Device.cs b/SteelSeriesAPI/Sonar/Enums/Device.cs deleted file mode 100644 index 539f81d..0000000 --- a/SteelSeriesAPI/Sonar/Enums/Device.cs +++ /dev/null @@ -1,86 +0,0 @@ -namespace SteelSeriesAPI.Sonar.Enums; - -public enum Device -{ - Master, - Game, - Chat, - Media, - Aux, - Mic -} - -public enum DeviceMapChoice -{ - JsonDict, - HttpDict, - DeviceDict -} - -public static class DeviceExtensions -{ - private static readonly Dictionary DeviceJsonMap = new Dictionary - { - { Device.Master, "masters" }, - { Device.Game, "game" }, - { Device.Chat, "chatRender" }, - { Device.Media, "media" }, - { Device.Aux, "aux" }, - { Device.Mic, "chatCapture" } - }; - - private static readonly Dictionary DeviceHttpMap = new Dictionary - { - { Device.Master, "Master" }, - { Device.Game, "game" }, - { Device.Chat, "chatRender" }, - { Device.Media, "media" }, - { Device.Aux, "aux" }, - { Device.Mic, "chatCapture" } - }; - - private static readonly Dictionary DeviceMap = new Dictionary - { - { Device.Master, "master" }, - { Device.Game, "game" }, - { Device.Chat, "chat" }, - { Device.Media, "media" }, - { Device.Aux, "aux" }, - { Device.Mic, "mic" } - }; - - public static string ToDictKey(this Device device, DeviceMapChoice context = DeviceMapChoice.JsonDict) - { - return context switch - { - DeviceMapChoice.JsonDict => DeviceJsonMap.ContainsKey(device) ? DeviceJsonMap[device] : null, - DeviceMapChoice.HttpDict => DeviceHttpMap.ContainsKey(device) ? DeviceHttpMap[device] : null, - DeviceMapChoice.DeviceDict => DeviceMap.ContainsKey(device) ? DeviceMap[device] : null, - _ => null - }; - } - - public static Device? FromDictKey(string jsonKey, DeviceMapChoice context = DeviceMapChoice.JsonDict) - { - var map = context switch - { - DeviceMapChoice.JsonDict => DeviceJsonMap, - DeviceMapChoice.HttpDict => DeviceHttpMap, - DeviceMapChoice.DeviceDict => DeviceMap, - _ => null - }; - - if (map != null) - { - foreach (var pair in map) - { - if (pair.Value.ToLower() == jsonKey.ToLower()) - { - return pair.Key; - } - } - } - - return null; - } -} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Enums/Direction.cs b/SteelSeriesAPI/Sonar/Enums/Direction.cs deleted file mode 100644 index 58e641b..0000000 --- a/SteelSeriesAPI/Sonar/Enums/Direction.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace SteelSeriesAPI.Sonar.Enums; - -public enum Direction -{ - Input, - Output -} - -public static class DirectionExtensions -{ - private static readonly Dictionary DirectionMap = new Dictionary - { - { Direction.Input, "capture" }, - { Direction.Output, "render" } - }; - - public static string ToDictKey(this Direction direction) - { - return DirectionMap[direction]; - } - - public static Direction? FromDictKey(string jsonKey) - { - foreach (var pair in DirectionMap) - { - if (pair.Value == jsonKey) - { - return pair.Key; - } - } - - return null; - } -} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Enums/Mix.cs b/SteelSeriesAPI/Sonar/Enums/Mix.cs new file mode 100644 index 0000000..6203d9d --- /dev/null +++ b/SteelSeriesAPI/Sonar/Enums/Mix.cs @@ -0,0 +1,34 @@ +namespace SteelSeriesAPI.Sonar.Enums; + +public enum Mix +{ + PERSONAL, + STREAM +} + +public static class MixExtensions +{ + private static readonly Dictionary MixMap = new Dictionary + { + { Mix.PERSONAL, "monitoring" }, + { Mix.STREAM, "streaming" } + }; + + public static string ToDictKey(this Mix mix) + { + return MixMap[mix]; + } + + public static Mix? FromDictKey(string jsonKey) + { + foreach (var pair in MixMap) + { + if (pair.Value == jsonKey) + { + return pair.Key; + } + } + + return null; + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Enums/Mode.cs b/SteelSeriesAPI/Sonar/Enums/Mode.cs index 0eca32a..de0a76a 100644 --- a/SteelSeriesAPI/Sonar/Enums/Mode.cs +++ b/SteelSeriesAPI/Sonar/Enums/Mode.cs @@ -2,8 +2,8 @@ namespace SteelSeriesAPI.Sonar.Enums; public enum Mode { - Classic, - Streamer + CLASSIC, + STREAMER } public enum ModeMapChoice @@ -16,14 +16,14 @@ public static class ModeExtensions { private static readonly Dictionary PrimaryModeMap = new Dictionary { - { Mode.Classic, "classic" }, - { Mode.Streamer, "streamer" } + { Mode.CLASSIC, "classic" }, + { Mode.STREAMER, "streamer" } }; private static readonly Dictionary SecondaryModeMap = new Dictionary { - { Mode.Classic, "classic" }, - { Mode.Streamer, "stream" } + { Mode.CLASSIC, "classic" }, + { Mode.STREAMER, "stream" } }; public static string ToDictKey(this Mode mode, ModeMapChoice context = ModeMapChoice.StreamerDict) diff --git a/SteelSeriesAPI/Sonar/Enums/RoutedProcessState.cs b/SteelSeriesAPI/Sonar/Enums/RoutedProcessState.cs index 57985bd..5e0a91a 100644 --- a/SteelSeriesAPI/Sonar/Enums/RoutedProcessState.cs +++ b/SteelSeriesAPI/Sonar/Enums/RoutedProcessState.cs @@ -2,18 +2,18 @@ namespace SteelSeriesAPI.Sonar.Enums; public enum RoutedProcessState { - Active, - Inactive, - Expired + ACTIVE, + INACTIVE, + EXPIRED } public static class RoutedProcessStateExtensions { private static readonly Dictionary RoutedProcessStateMap = new Dictionary { - { RoutedProcessState.Active, "active" }, - { RoutedProcessState.Inactive, "inactive" }, - { RoutedProcessState.Expired, "expired" }, + { RoutedProcessState.ACTIVE, "active" }, + { RoutedProcessState.INACTIVE, "inactive" }, + { RoutedProcessState.EXPIRED, "expired" }, }; public static string ToDictKey(this RoutedProcessState state) diff --git a/SteelSeriesAPI/Sonar/Events/SonarAudienceMonitoringEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarAudienceMonitoringEvent.cs new file mode 100644 index 0000000..279839d --- /dev/null +++ b/SteelSeriesAPI/Sonar/Events/SonarAudienceMonitoringEvent.cs @@ -0,0 +1,7 @@ +namespace SteelSeriesAPI.Sonar.Events; + +public class SonarAudienceMonitoringEvent : EventArgs +{ + // /streamRedirections/isStreamMonitoringEnabled/true + public bool NewState { get; set; } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Events/SonarChatMixEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarChatMixEvent.cs similarity index 74% rename from SteelSeriesAPI/Events/SonarChatMixEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarChatMixEvent.cs index 551539e..352ab66 100644 --- a/SteelSeriesAPI/Events/SonarChatMixEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarChatMixEvent.cs @@ -1,4 +1,4 @@ -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; public class SonarChatMixEvent : EventArgs { diff --git a/SteelSeriesAPI/Events/SonarConfigEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarConfigEvent.cs similarity index 81% rename from SteelSeriesAPI/Events/SonarConfigEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarConfigEvent.cs index 2d53fdb..5777090 100644 --- a/SteelSeriesAPI/Events/SonarConfigEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarConfigEvent.cs @@ -1,4 +1,4 @@ -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; public class SonarConfigEvent : EventArgs { diff --git a/SteelSeriesAPI/Events/SonarRedirectionStateEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarMixEvent.cs similarity index 51% rename from SteelSeriesAPI/Events/SonarRedirectionStateEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarMixEvent.cs index e16d110..d4fae6c 100644 --- a/SteelSeriesAPI/Events/SonarRedirectionStateEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarMixEvent.cs @@ -1,13 +1,14 @@ using SteelSeriesAPI.Sonar.Enums; -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; -public class SonarRedirectionStateEvent : EventArgs +public class SonarMixEvent : EventArgs { // /streamRedirections/monitoring/redirections/chatRender/isEnabled/true - public bool State { get; set; } + public bool NewState { get; set; } - public Device Device { get; set; } public Channel Channel { get; set; } + + public Mix Mix { get; set; } } \ No newline at end of file diff --git a/SteelSeriesAPI/Events/SonarModeEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarModeEvent.cs similarity index 78% rename from SteelSeriesAPI/Events/SonarModeEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarModeEvent.cs index c432ac5..965313c 100644 --- a/SteelSeriesAPI/Events/SonarModeEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarModeEvent.cs @@ -1,6 +1,6 @@ using SteelSeriesAPI.Sonar.Enums; -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; public class SonarModeEvent : EventArgs { diff --git a/SteelSeriesAPI/Events/SonarMuteEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarMuteEvent.cs similarity index 69% rename from SteelSeriesAPI/Events/SonarMuteEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarMuteEvent.cs index 836be38..1cce0a9 100644 --- a/SteelSeriesAPI/Events/SonarMuteEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarMuteEvent.cs @@ -1,6 +1,6 @@ using SteelSeriesAPI.Sonar.Enums; -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; public class SonarMuteEvent : EventArgs { @@ -11,6 +11,7 @@ public class SonarMuteEvent : EventArgs public Mode Mode { get; set; } - public Device Device { get; set; } - public Channel? Channel { get; set; } + public Channel Channel { get; set; } + + public Mix? Mix { get; set; } } \ No newline at end of file diff --git a/SteelSeriesAPI/Events/SonarRedirectionDeviceEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarPlaybackDeviceEvent.cs similarity index 66% rename from SteelSeriesAPI/Events/SonarRedirectionDeviceEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarPlaybackDeviceEvent.cs index 146dbbe..28692bc 100644 --- a/SteelSeriesAPI/Events/SonarRedirectionDeviceEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarPlaybackDeviceEvent.cs @@ -1,16 +1,17 @@ using SteelSeriesAPI.Sonar.Enums; -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; -public class SonarRedirectionDeviceEvent : EventArgs +public class SonarPlaybackDeviceEvent : EventArgs { // /classicRedirections/game/deviceId/%7B0.0.0.00000000%7D.%7B1e1ebefc-2c51-4675-aebe-085a06efd255%7D // /streamRedirections/monitoring/deviceId/%7B0.0.0.00000000%7D.%7B1e1ebefc-2c51-4675-aebe-085a06efd255%7D - public string RedirectionDeviceId { get; set; } + public string PlaybackDeviceId { get; set; } public Mode Mode { get; set; } - public Device? Device { get; set; } public Channel? Channel { get; set; } + + public Mix? Mix { get; set; } } \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Events/SonarRoutedProcessEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarRoutedProcessEvent.cs new file mode 100644 index 0000000..86271e7 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Events/SonarRoutedProcessEvent.cs @@ -0,0 +1,40 @@ +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; +using SteelSeriesAPI.Sonar.Exceptions; + +using System.Text.Json; + +namespace SteelSeriesAPI.Sonar.Events; + +public class SonarRoutedProcessEvent : EventArgs +{ + // /AudioDeviceRouting/render/%7B0.0.0.00000000%7D.%7Beb78557a-9882-4205-8014-ad9384173901%7D/4476 + // /AudioDeviceRouting/capture/%7B0.0.1.00000000%7D.%7B989ad130-4b1f-4828-a85a-7aef7fd362b7%7D/4476 + + public int ProcessId { get; init; } + + public Channel NewChannel { get; init; } + + internal SonarRoutedProcessEvent(string deviceId) + { + NewChannel = DeviceIdToChannel(deviceId); + } + + private Channel DeviceIdToChannel(string deviceId) + { + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + if (device.GetProperty("role").GetString() != "none") + { + if (device.GetProperty("deviceId").GetString() == deviceId) + { + return (Channel)ChannelExtensions.FromDictKey(device.GetProperty("role").GetString()!)!; + } + } + } + + throw new RoutedProcessNotFoundException("Event error: Could not find the channel"); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Events/SonarVolumeEvent.cs b/SteelSeriesAPI/Sonar/Events/SonarVolumeEvent.cs similarity index 70% rename from SteelSeriesAPI/Events/SonarVolumeEvent.cs rename to SteelSeriesAPI/Sonar/Events/SonarVolumeEvent.cs index f9c798a..e00607e 100644 --- a/SteelSeriesAPI/Events/SonarVolumeEvent.cs +++ b/SteelSeriesAPI/Sonar/Events/SonarVolumeEvent.cs @@ -1,6 +1,6 @@ using SteelSeriesAPI.Sonar.Enums; -namespace SteelSeriesAPI.Events; +namespace SteelSeriesAPI.Sonar.Events; public class SonarVolumeEvent : EventArgs { @@ -11,6 +11,7 @@ public class SonarVolumeEvent : EventArgs public Mode Mode { get; set; } - public Device Device { get; set; } - public Channel? Channel { get; set; } + public Channel Channel { get; set; } + + public Mix? Mix { get; set; } } \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/ChannelNoStreamerSupportException.cs b/SteelSeriesAPI/Sonar/Exceptions/ChannelNoStreamerSupportException.cs new file mode 100644 index 0000000..db31ce5 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/ChannelNoStreamerSupportException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class ChannelNoStreamerSupportException : Exception +{ + public ChannelNoStreamerSupportException() : base("Only the Mic Channel is supported in this case.") { } + public ChannelNoStreamerSupportException(string message) : base(message) { } + public ChannelNoStreamerSupportException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/ChannelNotFoundException.cs b/SteelSeriesAPI/Sonar/Exceptions/ChannelNotFoundException.cs new file mode 100644 index 0000000..73a5baf --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/ChannelNotFoundException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class ChannelNotFoundException : Exception +{ + public ChannelNotFoundException() : base("Channel could not be found.") { } + public ChannelNotFoundException(string message) : base(message) { } + public ChannelNotFoundException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/ChatMixBalanceException.cs b/SteelSeriesAPI/Sonar/Exceptions/ChatMixBalanceException.cs new file mode 100644 index 0000000..b00a8dc --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/ChatMixBalanceException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class ChatMixBalanceException : Exception +{ + public ChatMixBalanceException() : base("ChatMix balance out of range.") { } + public ChatMixBalanceException(string message) : base(message) { } + public ChatMixBalanceException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/ChatMixDisabledException.cs b/SteelSeriesAPI/Sonar/Exceptions/ChatMixDisabledException.cs new file mode 100644 index 0000000..be52eff --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/ChatMixDisabledException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class ChatMixDisabledException : Exception +{ + public ChatMixDisabledException() : base("ChatMix is not enabled.") { } + public ChatMixDisabledException(string message) : base(message) { } + public ChatMixDisabledException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/ConfigNotFoundException.cs b/SteelSeriesAPI/Sonar/Exceptions/ConfigNotFoundException.cs new file mode 100644 index 0000000..1084652 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/ConfigNotFoundException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class ConfigNotFoundException : Exception +{ + public ConfigNotFoundException() : base("No audio configuration found.") { } + public ConfigNotFoundException(string message) : base(message) { } + public ConfigNotFoundException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/MasterChannelNotSupportedException.cs b/SteelSeriesAPI/Sonar/Exceptions/MasterChannelNotSupportedException.cs new file mode 100644 index 0000000..91b8755 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/MasterChannelNotSupportedException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class MasterChannelNotSupportedException : Exception +{ + public MasterChannelNotSupportedException() : base("Master Channel is not supported in this case.") { } + public MasterChannelNotSupportedException(string message) : base(message) { } + public MasterChannelNotSupportedException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/MixNotFoundException.cs b/SteelSeriesAPI/Sonar/Exceptions/MixNotFoundException.cs new file mode 100644 index 0000000..65b339f --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/MixNotFoundException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class MixNotFoundException : Exception +{ + public MixNotFoundException() : base("Mix could not be found.") { } + public MixNotFoundException(string message) : base(message) { } + public MixNotFoundException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceDataFlowException.cs b/SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceDataFlowException.cs new file mode 100644 index 0000000..3fb0027 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceDataFlowException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class PlaybackDeviceDataFlowException : Exception +{ + public PlaybackDeviceDataFlowException() : base("DataFlows do not match.") { } + public PlaybackDeviceDataFlowException(string message) : base(message) { } + public PlaybackDeviceDataFlowException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceNotFoundException.cs b/SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceNotFoundException.cs new file mode 100644 index 0000000..25296e7 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceNotFoundException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class PlaybackDeviceNotFoundException : Exception +{ + public PlaybackDeviceNotFoundException() : base("Could not find corresponding playback device") { } + public PlaybackDeviceNotFoundException(string message) : base(message) { } + public PlaybackDeviceNotFoundException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/RoutedProcessNotFoundException.cs b/SteelSeriesAPI/Sonar/Exceptions/RoutedProcessNotFoundException.cs new file mode 100644 index 0000000..604deaa --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/RoutedProcessNotFoundException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class RoutedProcessNotFoundException : Exception +{ + public RoutedProcessNotFoundException() : base("Could not find any routed process") { } + public RoutedProcessNotFoundException(string message) : base(message) { } + public RoutedProcessNotFoundException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/SonarListenerNotConnectedException.cs b/SteelSeriesAPI/Sonar/Exceptions/SonarListenerNotConnectedException.cs new file mode 100644 index 0000000..03294b7 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/SonarListenerNotConnectedException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class SonarListenerNotConnectedException : Exception +{ + public SonarListenerNotConnectedException() : base("Listener need to be connected before listening") { } + public SonarListenerNotConnectedException(string message) : base(message) { } + public SonarListenerNotConnectedException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Exceptions/SonarNotRunningException.cs b/SteelSeriesAPI/Sonar/Exceptions/SonarNotRunningException.cs new file mode 100644 index 0000000..96b60e8 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Exceptions/SonarNotRunningException.cs @@ -0,0 +1,8 @@ +namespace SteelSeriesAPI.Sonar.Exceptions; + +public class SonarNotRunningException : Exception +{ + public SonarNotRunningException() : base("Sonar is not running.") { } + public SonarNotRunningException(string message) : base(message) { } + public SonarNotRunningException(string message, Exception innerException) : base(message, innerException) { } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Http/HttpPut.cs b/SteelSeriesAPI/Sonar/Http/Fetcher.cs similarity index 54% rename from SteelSeriesAPI/Sonar/Http/HttpPut.cs rename to SteelSeriesAPI/Sonar/Http/Fetcher.cs index e501824..d405f4e 100644 --- a/SteelSeriesAPI/Sonar/Http/HttpPut.cs +++ b/SteelSeriesAPI/Sonar/Http/Fetcher.cs @@ -1,29 +1,49 @@ -using SteelSeriesAPI.Interfaces; +using SteelSeriesAPI.Sonar.Exceptions; +using SteelSeriesAPI.Interfaces; + +using System.Text.Json; namespace SteelSeriesAPI.Sonar.Http; -public class HttpPut +public class Fetcher { private readonly HttpClient _httpClient; private readonly IAppRetriever _sonarRetriever; - - public HttpPut(string targetHttp) + + public Fetcher() { _sonarRetriever = SonarRetriever.Instance; HttpClientHandler clientHandler = new HttpClientHandler(); clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; _httpClient = new(clientHandler); - - Put(targetHttp); } - private void Put(string targetHttp) + public JsonDocument Provide(string targetHttp) + { + if (_sonarRetriever is { IsEnabled: false, IsReady: false, IsRunning: false }) + { + throw new SonarNotRunningException(); + } + + try + { + JsonDocument response = JsonDocument.Parse(_httpClient.GetStringAsync(_sonarRetriever.WebServerAddress() + targetHttp).Result); + return response; + } + catch (Exception e) + { + Console.WriteLine(e); + Console.WriteLine("Sonar may not be running."); + throw; + } + } + + public void Put(string targetHttp) { if (_sonarRetriever is { IsEnabled: false, IsReady: false, IsRunning: false }) { - Console.WriteLine("Sonar is not running."); - return; + throw new SonarNotRunningException(); } try diff --git a/SteelSeriesAPI/Sonar/Http/HttpProvider.cs b/SteelSeriesAPI/Sonar/Http/HttpProvider.cs deleted file mode 100644 index 9f81858..0000000 --- a/SteelSeriesAPI/Sonar/Http/HttpProvider.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Text.Json; -using SteelSeriesAPI.Interfaces; - -namespace SteelSeriesAPI.Sonar.Http; - -public class HttpProvider -{ - private readonly HttpClient _httpClient; - private readonly IAppRetriever _sonarRetriever; - - private readonly string _targetHttp; - - public HttpProvider(string targetHttp) - { - _targetHttp = targetHttp; - _sonarRetriever = SonarRetriever.Instance; - - HttpClientHandler clientHandler = new HttpClientHandler(); - clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; - _httpClient = new(clientHandler); - } - - public JsonDocument Provide() - { - if (_sonarRetriever is { IsEnabled: false, IsReady: false, IsRunning: false }) - { - Console.WriteLine("Sonar is not running."); - return null; - } - - try - { - JsonDocument response = JsonDocument.Parse(_httpClient.GetStringAsync(_sonarRetriever.WebServerAddress() + _targetHttp).Result); - return response; - } - catch (Exception e) - { - Console.WriteLine(e); - Console.WriteLine("Sonar may not be running."); - throw; - } - } -} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Http/SonarHttpCommand.cs b/SteelSeriesAPI/Sonar/Http/SonarHttpCommand.cs deleted file mode 100644 index a9d55c1..0000000 --- a/SteelSeriesAPI/Sonar/Http/SonarHttpCommand.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System.Globalization; -using System.Text.Json; -using SteelSeriesAPI.Interfaces; -using SteelSeriesAPI.Sonar.Enums; -using Channel = SteelSeriesAPI.Sonar.Enums.Channel; - -namespace SteelSeriesAPI.Sonar.Http; - -public class SonarHttpCommand : ISonarCommandHandler -{ - private readonly ISonarBridge _sonarBridge; - - public SonarHttpCommand(SonarBridge sonarBridge) - { - _sonarBridge = sonarBridge; - } - - public void SetMode(Mode mode) - { - new HttpPut("mode/" + mode.ToDictKey(ModeMapChoice.StreamDict)); - Thread.Sleep(100); // Prevent bugs/freezes/crashes - } - - public void SetVolume(double vol, Device device) - { - string _vol = vol.ToString("0.00", CultureInfo.InvariantCulture); - new HttpPut("volumeSettings/classic/" + device.ToDictKey(DeviceMapChoice.HttpDict) + "/Volume/" + _vol); - } - - public void SetVolume(double vol, Device device, Channel channel) - { - string _vol = vol.ToString("0.00", CultureInfo.InvariantCulture); - new HttpPut("volumeSettings/streamer/" + channel.ToDictKey() + "/" + device.ToDictKey(DeviceMapChoice.HttpDict) + "/volume/" + _vol); - } - - public void SetMute(bool mute, Device device) - { - new HttpPut("volumeSettings/classic/" + device.ToDictKey(DeviceMapChoice.HttpDict) + "/Mute/" + mute); - } - - public void SetMute(bool mute, Device device, Channel channel) - { - new HttpPut("volumeSettings/streamer/" + channel.ToDictKey() + "/" + device.ToDictKey(DeviceMapChoice.HttpDict) + "/isMuted/" + mute); - } - - public void SetConfig(string configId) - { - if (string.IsNullOrEmpty(configId)) throw new Exception("Couldn't retrieve config id"); - - new HttpPut("configs/" + configId + "/select"); - } - - public void SetConfig(Device device, string name) - { - var configs = _sonarBridge.GetAudioConfigurations(device).ToList(); - foreach (var config in configs) - { - if (config.Name == name) - { - SetConfig(config.Id); - break; - } - } - } - - public void SetChatMixBalance(double balance) - { - if (!_sonarBridge.GetChatMixState()) - { - throw new Exception("Can't change the value of the balance of the ChatMix when it is not enabled"); - } - - if (balance > 1 || balance < -1) - { - throw new Exception("ChatMix balance can't be less than -1 and greater than 1"); - } - - new HttpPut("chatMix?balance=" + balance.ToString("0.00", CultureInfo.InvariantCulture)); - } - - public void SetClassicRedirectionDevice(string deviceId, Device device) - { - new HttpPut("classicRedirections/" + device.ToDictKey(DeviceMapChoice.DeviceDict) +"/deviceId/" + deviceId); - } - - public void SetStreamRedirectionDevice(string deviceId, Channel channel) - { - new HttpPut("streamRedirections/" + channel.ToDictKey() +"/deviceId/" + deviceId); - } - - public void SetStreamRedirectionDevice(string deviceId, Device device) - { - if (device != Device.Mic) - { - throw new Exception("Can only change stream redirection device for Mic"); - } - - new HttpPut("streamRedirections/" + device.ToDictKey(DeviceMapChoice.DeviceDict) +"/deviceId/" + deviceId); - } - - public void SetRedirectionState(bool newState, Device device, Channel channel) - { - new HttpPut("streamRedirections/" + channel.ToDictKey() + "/redirections/" + device.ToDictKey() + - "/isEnabled/" + newState); - } - - public void SetAudienceMonitoringState(bool newState) - { - new HttpPut("streamRedirections/isStreamMonitoringEnabled/" + newState); - } - - public void SetProcessToDeviceRouting(int pId, Device device) - { - if (device == Device.Master) - { - throw new Exception("Can't set process to master routing"); - } - - JsonDocument audioDeviceRouting = new HttpProvider("AudioDeviceRouting").Provide(); - - foreach (var element in audioDeviceRouting.RootElement.EnumerateArray()) - { - if (element.GetProperty("role").GetString() == device.ToDictKey()) - { - if (device == Device.Mic) - { - new HttpPut("AudioDeviceRouting/capture/" + element.GetProperty("deviceId").GetString() + "/" + pId); - break; - } - else - { - new HttpPut("AudioDeviceRouting/render/" + element.GetProperty("deviceId").GetString() + "/" + pId); - break; - } - } - } - } -} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Http/SonarHttpProvider.cs b/SteelSeriesAPI/Sonar/Http/SonarHttpProvider.cs deleted file mode 100644 index 9185e18..0000000 --- a/SteelSeriesAPI/Sonar/Http/SonarHttpProvider.cs +++ /dev/null @@ -1,420 +0,0 @@ -using System.Collections; -using System.Text.Json; -using SteelSeriesAPI.Interfaces; -using SteelSeriesAPI.Sonar.Enums; -using SteelSeriesAPI.Sonar.Models; - -namespace SteelSeriesAPI.Sonar.Http; - -public class SonarHttpProvider : ISonarDataProvider -{ - private readonly ISonarBridge _sonarBridge; - - public SonarHttpProvider(SonarBridge sonarBridge) - { - _sonarBridge = sonarBridge; - } - - public Mode GetMode() - { - string mode = new HttpProvider("mode").Provide().RootElement.ToString(); - - return (Mode)ModeExtensions.FromDictKey(mode, ModeMapChoice.StreamDict); - } - - public double GetVolume(Device device) - { - JsonDocument volumeSettings = new HttpProvider("volumeSettings/classic/").Provide(); - - if (device == Device.Master) - return volumeSettings.RootElement.GetProperty("masters").GetProperty("classic").GetProperty("volume").GetDouble(); - return volumeSettings.RootElement.GetProperty("devices").GetProperty(device.ToDictKey()).GetProperty("classic").GetProperty("volume").GetDouble(); - } - - public double GetVolume(Device device, Channel channel) - { - JsonDocument volumeSettings = new HttpProvider("volumeSettings/streamer/").Provide(); - - if (device == Device.Master) - return volumeSettings.RootElement.GetProperty("masters").GetProperty("stream").GetProperty(channel.ToDictKey()).GetProperty("volume").GetDouble(); - return volumeSettings.RootElement.GetProperty("devices").GetProperty(device.ToDictKey()).GetProperty("stream").GetProperty(channel.ToDictKey()).GetProperty("volume").GetDouble(); - } - - public bool GetMute(Device device) - { - JsonDocument volumeSettings = new HttpProvider("volumeSettings/classic/").Provide(); - - if (device == Device.Master) - return volumeSettings.RootElement.GetProperty("masters").GetProperty("classic").GetProperty("muted").GetBoolean(); - return volumeSettings.RootElement.GetProperty("devices").GetProperty(device.ToDictKey()).GetProperty("classic").GetProperty("muted").GetBoolean(); - } - - public bool GetMute(Device device, Channel channel) - { - JsonDocument volumeSettings = new HttpProvider("volumeSettings/streamer/").Provide(); - - if (device == Device.Master) - return volumeSettings.RootElement.GetProperty("masters").GetProperty("stream").GetProperty(channel.ToDictKey()).GetProperty("muted").GetBoolean(); - return volumeSettings.RootElement.GetProperty("devices").GetProperty(device.ToDictKey()).GetProperty("stream").GetProperty(channel.ToDictKey()).GetProperty("muted").GetBoolean(); - } - - #region AudioConfigs - - public IEnumerable GetAllAudioConfigurations() - { - JsonDocument configs = new HttpProvider("configs").Provide(); - - foreach (var element in configs.RootElement.EnumerateArray()) - { - string vDevice = element.GetProperty("virtualAudioDevice").GetString(); - string id = element.GetProperty("id").GetString(); - string name = element.GetProperty("name").GetString(); - - yield return new SonarAudioConfiguration(id, name, (Device)DeviceExtensions.FromDictKey(vDevice)); - } - } - - public SonarAudioConfiguration GetAudioConfiguration(string configId) - { - IEnumerable configs = GetAllAudioConfigurations(); - SonarAudioConfiguration sonarConfig = null; - - foreach (var config in configs) - { - if (config.Id == configId) - { - sonarConfig = config; - break; - } - } - - return sonarConfig; - } - - public IEnumerable GetAudioConfigurations(Device device) - { - if (device == Device.Master) - { - throw new Exception("Can't get audio configurations for master"); - } - - IEnumerable configs = GetAllAudioConfigurations(); - List deviceConfigs = new List(); - - foreach (var config in configs) - { - if (config.AssociatedDevice == device) - { - deviceConfigs.Add(config); - } - } - - return deviceConfigs.OrderBy(s => s.Name); - } - - public SonarAudioConfiguration GetSelectedAudioConfiguration(Device device) - { - if (device == Device.Master) - { - throw new Exception("Can't get audio configuration for master"); - } - - JsonDocument selectedConfigs = new HttpProvider("configs/selected").Provide(); - JsonElement sConfig = default; - - foreach (var config in selectedConfigs.RootElement.EnumerateArray()) - { - if (config.GetProperty("virtualAudioDevice").GetString() == device.ToDictKey()) - { - sConfig = config; - break; - } - } - - string id = sConfig.GetProperty("id").GetString(); - string name = sConfig.GetProperty("name").GetString(); - string vDevice = sConfig.GetProperty("virtualAudioDevice").GetString(); - - return new SonarAudioConfiguration(id, name, (Device)DeviceExtensions.FromDictKey(vDevice)); - } - - #endregion - - #region ChatMix - - public double GetChatMixBalance() - { - JsonDocument chatMix = new HttpProvider("chatMix").Provide(); - - return chatMix.RootElement.GetProperty("balance").GetDouble(); - } - - public bool GetChatMixState() - { - JsonDocument chatMix = new HttpProvider("chatMix").Provide(); - string cState = chatMix.RootElement.GetProperty("state").ToString(); - if (cState == "enabled") - { - return true; - } - else if (cState == "differentDeviceSelected") - { - return false; - } - - return false; - } - - #endregion - - public IEnumerable GetRedirectionDevices(Direction direction) - { - JsonDocument audioDevices = new HttpProvider("audioDevices").Provide(); - JsonDocument classicRedirections = new HttpProvider("classicRedirections").Provide(); - JsonDocument streamRedirections = new HttpProvider("streamRedirections").Provide(); - - foreach (var element in audioDevices.RootElement.EnumerateArray()) - { - if (element.GetProperty("role").GetString() != "none") - { - continue; - } - - string id = element.GetProperty("id").GetString(); - string name = element.GetProperty("friendlyName").GetString(); - string dataFlow = element.GetProperty("dataFlow").GetString(); - List associatedClassicDevices = new List(); - ArrayList associatedStreamDevices = new ArrayList(); - - GetAssociatedDevices(id, associatedClassicDevices, associatedStreamDevices); - - if (dataFlow == direction.ToDictKey()) - { - yield return new RedirectionDevice(id, name, (Direction)DirectionExtensions.FromDictKey(dataFlow), associatedClassicDevices, associatedStreamDevices); - } - } - } - - public RedirectionDevice GetClassicRedirectionDevice(Device device) - { - if (device == Device.Master) - { - throw new Exception("Can't get redirection device for master"); - } - - JsonDocument classicRedirections = new HttpProvider("classicRedirections").Provide(); - JsonElement cRedirections = default; - - foreach (var element in classicRedirections.RootElement.EnumerateArray()) - { - if (element.GetProperty("id").GetString() == device.ToDictKey(DeviceMapChoice.DeviceDict)) - { - cRedirections = element; - break; - } - } - - string deviceId = cRedirections.GetProperty("deviceId").GetString(); - List associatedClassicDevices = new List(); - ArrayList associatedStreamDevices = new ArrayList(); - - GetAssociatedDevices(deviceId, associatedClassicDevices, associatedStreamDevices); - - JsonDocument audioDevice = new HttpProvider("audioDevices/" + deviceId).Provide(); - - string name = audioDevice.RootElement.GetProperty("friendlyName").GetString(); - Direction dataFlow = (Direction)DirectionExtensions.FromDictKey(audioDevice.RootElement.GetProperty("dataFlow").GetString()); - - return new RedirectionDevice(deviceId, name, dataFlow, associatedClassicDevices, associatedStreamDevices); - } - - public RedirectionDevice GetStreamRedirectionDevice(Channel channel) - { - JsonDocument streamRedirections = new HttpProvider("streamRedirections").Provide(); - JsonElement sRedirections = default; - - foreach (var element in streamRedirections.RootElement.EnumerateArray()) - { - if (element.GetProperty("streamRedirectionId").GetString() == channel.ToDictKey()) - { - sRedirections = element; - break; - } - } - - string deviceId = sRedirections.GetProperty("deviceId").GetString(); - List associatedClassicDevices = new List();ArrayList associatedStreamDevices = new ArrayList(); - - GetAssociatedDevices(deviceId, associatedClassicDevices, associatedStreamDevices); - - JsonDocument audioDevice = new HttpProvider("audioDevices/" + deviceId).Provide(); - - string name = audioDevice.RootElement.GetProperty("friendlyName").GetString(); - Direction dataFlow = (Direction)DirectionExtensions.FromDictKey(audioDevice.RootElement.GetProperty("dataFlow").GetString()); - - return new RedirectionDevice(deviceId, name, dataFlow, associatedClassicDevices, associatedStreamDevices); - } - - public RedirectionDevice GetStreamRedirectionDevice(Device device) - { - if (device != Device.Mic) - { - throw new Exception("Can only get stream redirection device for Mic"); - } - - JsonDocument streamRedirections = new HttpProvider("streamRedirections").Provide(); - JsonElement sRedirections = default; - - foreach (var element in streamRedirections.RootElement.EnumerateArray()) - { - if (element.GetProperty("streamRedirectionId").GetString() == device.ToDictKey(DeviceMapChoice.DeviceDict)) - { - sRedirections = element; - break; - } - } - - string deviceId = sRedirections.GetProperty("deviceId").GetString(); - List associatedClassicDevices = new List(); - ArrayList associatedStreamDevices = new ArrayList(); - - GetAssociatedDevices(deviceId, associatedClassicDevices, associatedStreamDevices); - - JsonDocument audioDevice = new HttpProvider("audioDevices/" + deviceId).Provide(); - - string name = audioDevice.RootElement.GetProperty("friendlyName").GetString(); - Direction dataFlow = (Direction)DirectionExtensions.FromDictKey(audioDevice.RootElement.GetProperty("dataFlow").GetString()); - - return new RedirectionDevice(deviceId, name, dataFlow, associatedClassicDevices, associatedStreamDevices); - } - - public RedirectionDevice GetRedirectionDeviceFromId(string deviceId) - { - try - { - JsonElement device = new HttpProvider("audioDevices/" + deviceId).Provide().RootElement; - - string id = device.GetProperty("id").GetString(); - string name = device.GetProperty("friendlyName").GetString(); - string dataFlow = device.GetProperty("dataFlow").GetString(); - List associatedClassicDevices = new List(); - ArrayList associatedStreamDevices = new ArrayList(); - - GetAssociatedDevices(deviceId, associatedClassicDevices, associatedStreamDevices); - - return new RedirectionDevice(id, name, (Direction)DirectionExtensions.FromDictKey(dataFlow), associatedClassicDevices, associatedStreamDevices); - } - catch (Exception e) - { - Console.WriteLine(e); - throw new Exception("Can't get any device from this Id, maybe the device doesn't exist or its Id changed."); - } - } - - private void GetAssociatedDevices(string deviceId, List associatedClassicDevices, ArrayList associatedStreamDevices) - { - JsonDocument classicRedirections = new HttpProvider("classicRedirections").Provide(); - JsonDocument streamRedirections = new HttpProvider("streamRedirections").Provide(); - - foreach (var element in classicRedirections.RootElement.EnumerateArray()) - { - if (element.GetProperty("deviceId").GetString() == deviceId) - { - associatedClassicDevices.Add((Device)DeviceExtensions.FromDictKey(element.GetProperty("id").GetString(), DeviceMapChoice.DeviceDict)); - } - } - - foreach (var element in streamRedirections.RootElement.EnumerateArray()) - { - if (element.GetProperty("deviceId").GetString() == deviceId) - { - if (element.GetProperty("streamRedirectionId").GetString() == "mic") - { - associatedStreamDevices.Add((Device)DeviceExtensions.FromDictKey(element.GetProperty("streamRedirectionId").GetString(), DeviceMapChoice.DeviceDict)); - } - else - { - associatedStreamDevices.Add((Channel)ChannelExtensions.FromDictKey(element.GetProperty("streamRedirectionId").GetString())); - } - } - } - } - - public bool GetRedirectionState(Device device, Channel channel) - { - if (device == Device.Master) - { - throw new Exception("Can't get redirection state for master"); - } - - JsonDocument streamRedirections = new HttpProvider("streamRedirections").Provide(); - JsonElement streamChannel = default; - - foreach (var element in streamRedirections.RootElement.EnumerateArray()) - { - if (element.GetProperty("streamRedirectionId").GetString() == channel.ToDictKey()) - { - streamChannel = element; - break; - } - } - - JsonElement status = default; - - foreach (var element in streamChannel.GetProperty("status").EnumerateArray()) - { - if (element.GetProperty("role").GetString() == device.ToDictKey()) - { - status = element; - break; - } - } - - bool state = status.GetProperty("isEnabled").GetBoolean(); - - return state; - } - - public bool GetAudienceMonitoringState() - { - JsonDocument streamMonitoring = new HttpProvider("streamRedirections/isStreamMonitoringEnabled").Provide(); - - return streamMonitoring.RootElement.GetBoolean(); - } - - public IEnumerable GetRoutedProcess(Device device) - { - if (device == Device.Master) - { - throw new Exception("Can't get routed process for Master"); - } - - JsonDocument audioDeviceRoutings = new HttpProvider("AudioDeviceRouting").Provide(); - - foreach (var element in audioDeviceRoutings.RootElement.EnumerateArray()) - { - if (element.GetProperty("role").GetString() != device.ToDictKey()) - { - continue; - } - - var audioSessions = element.GetProperty("audioSessions"); - - foreach (var session in audioSessions.EnumerateArray()) - { - string id = session.GetProperty("id").GetString().Split("|")[0]; - string processName = session.GetProperty("processName").GetString(); - int pId = session.GetProperty("processId").GetInt32(); - RoutedProcessState state = (RoutedProcessState)RoutedProcessStateExtensions.FromDictKey(session.GetProperty("state").GetString()); - string displayName = session.GetProperty("displayName").GetString(); - - if (processName == "Idle" && displayName == "Idle" && state == RoutedProcessState.Inactive && pId == 0) - { - continue; - } - - yield return new RoutedProcess(id, processName, pId, state, displayName); - } - } - } -} \ No newline at end of file diff --git a/SteelSeriesAPI/Interfaces/ISonarBridge.cs b/SteelSeriesAPI/Sonar/Interfaces/ISonarBridge.cs similarity index 78% rename from SteelSeriesAPI/Interfaces/ISonarBridge.cs rename to SteelSeriesAPI/Sonar/Interfaces/ISonarBridge.cs index 712a80c..4091bbc 100644 --- a/SteelSeriesAPI/Interfaces/ISonarBridge.cs +++ b/SteelSeriesAPI/Sonar/Interfaces/ISonarBridge.cs @@ -1,6 +1,9 @@ -namespace SteelSeriesAPI.Interfaces; +namespace SteelSeriesAPI.Sonar.Interfaces; -public interface ISonarBridge : ISonarDataProvider, ISonarCommandHandler +/// +/// Manage Sonar +/// +public interface ISonarBridge { /// /// The running state of Sonar diff --git a/SteelSeriesAPI/Interfaces/ISonarSocket.cs b/SteelSeriesAPI/Sonar/Interfaces/ISonarSocket.cs similarity index 75% rename from SteelSeriesAPI/Interfaces/ISonarSocket.cs rename to SteelSeriesAPI/Sonar/Interfaces/ISonarSocket.cs index c59296c..0ec5e69 100644 --- a/SteelSeriesAPI/Interfaces/ISonarSocket.cs +++ b/SteelSeriesAPI/Sonar/Interfaces/ISonarSocket.cs @@ -1,4 +1,4 @@ -namespace SteelSeriesAPI.Interfaces; +namespace SteelSeriesAPI.Sonar.Interfaces; public interface ISonarSocket { diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IAudienceMonitoringManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IAudienceMonitoringManager.cs new file mode 100644 index 0000000..69c20d9 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IAudienceMonitoringManager.cs @@ -0,0 +1,20 @@ +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage the Audience Monitoring feature of the streamer mode +/// +public interface IAudienceMonitoringManager +{ + /// + /// Get the current state of the Audience Monitoring + /// + /// The current state, un/muted + bool GetState(); + + /// + /// Activate or deactivate Audience Monitoring
+ /// Listen to what your audience hear + ///
+ /// The new state, un/muted + void SetState(bool newState); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IChatMixManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IChatMixManager.cs new file mode 100644 index 0000000..8ee2b79 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IChatMixManager.cs @@ -0,0 +1,26 @@ +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage the balance of ChatMix +/// +public interface IChatMixManager +{ + /// + /// Get the actual ChatMix balance value + /// + /// A double between -1 and 1 + double GetBalance(); + + /// + /// Get the actual state of the ChatMix + /// + /// True if ChatMix is enabled
False if ChatMix is disabled
+ bool GetState(); + + /// + /// Set the balance of the ChatMix + /// + /// -1 to balance to Game channel
1 to balance to Chat channel
+ /// A between -1 and 1 + void SetBalance(double balance); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IConfigurationManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IConfigurationManager.cs new file mode 100644 index 0000000..3b865e4 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IConfigurationManager.cs @@ -0,0 +1,60 @@ +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Models; + +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage audio configurations for each +/// +public interface IConfigurationManager +{ + + /// + /// Get all audio configurations of Sonar + /// + /// An IEnumerable of + IEnumerable GetAllAudioConfigurations(); + + /// + /// Get all audio configurations of a + /// + /// The channel you want the configs of + /// An IEnumerable of + IEnumerable GetAudioConfigurations(Channel channel); + + /// + /// Get the current audio configuration of a + /// + /// The channel you want the current config + /// A + SonarAudioConfiguration GetSelectedAudioConfiguration(Channel channel); + + /// + /// Get a specific audio configuration from Sonar + /// + /// The id of the config + /// A + SonarAudioConfiguration GetAudioConfiguration(string configId); + + /// + /// Set the config of a Sonar by giving its id + /// + /// For more explanation, go on the GitHub wiki + /// The id of the config + void SetConfig(string configId); + + /// + /// Set the config of a Sonar by giving a + /// + /// For more explanation, go on the GitHub wiki + /// The id + void SetConfig(SonarAudioConfiguration config); + + /// + /// Set the config of a Sonar by giving its name + /// + /// For more explanation, go on the GitHub wiki + /// The you want to change the config + /// The name of the config + void SetConfigByName(Channel channel, string name); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IMixManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IMixManager.cs new file mode 100644 index 0000000..d867d74 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IMixManager.cs @@ -0,0 +1,39 @@ +using SteelSeriesAPI.Sonar.Enums; + +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage the personal and stream mix for each channel +/// +public interface IMixManager +{ + /// + /// Get the state of the chosen Sonar of the chosen Sonar + /// + /// The Sonar of the + /// The Sonar you want the state of + /// The current state, activated/deactivated + bool GetState(Channel channel, Mix mix); + + /// + /// Activate or deactivate a Sonar of a Sonar + /// + /// The new state of the Mix + /// The Sonar of the + /// The Sonar you want to activate/deactivate + void SetState(bool newState, Channel channel, Mix mix); + + /// + /// Activate a Sonar of a Sonar + /// + /// The Sonar of the + /// The Sonar you want to activate + void Activate(Channel channel, Mix mix); + + /// + /// Deactivate a Sonar of a Sonar + /// + /// The Sonar of the + /// The Sonar you want to deactivate + void Deactivate(Channel channel, Mix mix); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IModeManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IModeManager.cs new file mode 100644 index 0000000..d827430 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IModeManager.cs @@ -0,0 +1,21 @@ +using SteelSeriesAPI.Sonar.Enums; + +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage the Sonar +/// +public interface IModeManager +{ + /// + /// Get the current used by Sonar + /// + /// + Mode Get(); + + /// + /// Set the Sonar will be using + /// + /// + void Set(Mode mode); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IPlaybackDeviceManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IPlaybackDeviceManager.cs new file mode 100644 index 0000000..b761e5e --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IPlaybackDeviceManager.cs @@ -0,0 +1,106 @@ +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Models; + +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage the playback device of each +/// +public interface IPlaybackDeviceManager +{ + + + /// + /// Get all the Playback Devices (Windows devices) + /// + /// A list of + IEnumerable GetAllPlaybackDevices(); + + /// + /// Get all output playback devices + /// + /// A list of + IEnumerable GetOutputPlaybackDevices(); + + /// + /// Get all input playback devices + /// + /// A list of + IEnumerable GetInputPlaybackDevices(); + + /// + /// Get the playback device of a + /// + /// + /// + PlaybackDevice GetPlaybackDevice(Channel channel); + + /// + /// Get the playback device of a depending on the mode
+ /// Mainly used to get the Streamer Mode Mic + ///
+ /// + /// + /// + PlaybackDevice GetPlaybackDevice(Channel channel, Mode mode); + + /// + /// Get the playback device of a + /// + /// + /// + PlaybackDevice GetPlaybackDevice(Mix mix); + + /// + /// Get a playback device using its id + /// + /// The id of the device + /// + PlaybackDevice GetPlaybackDevice(string deviceId); + + /// + /// Set the playback device of a + /// + /// The id of the device + /// + void SetPlaybackDevice(string deviceId, Channel channel); + + /// + /// Set the playback device of a depending on the mode
+ /// Mainly used to change the playback device of the Streamer Mode + ///
+ /// The id of the device + /// + /// + void SetPlaybackDevice(string deviceId, Channel channel, Mode mode); + + /// + /// Set the playback device of a + /// + /// The id of the device + /// + void SetPlaybackDevice(string deviceId, Mix mix); + + /// + /// Set the playback device of a + /// + /// + /// + void SetPlaybackDevice(PlaybackDevice device, Channel channel); + + /// + /// Set the playback device of a depending on the mode
+ /// Mainly used to change the playback device of the Streamer Mode + ///
+ /// + /// + /// + void SetPlaybackDevice(PlaybackDevice device, Channel channel, Mode mode); + + /// + /// Set the playback device of a + /// + /// + /// + void SetPlaybackDevice(PlaybackDevice device, Mix mix); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IRoutedProcessManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IRoutedProcessManager.cs new file mode 100644 index 0000000..af010e0 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IRoutedProcessManager.cs @@ -0,0 +1,64 @@ +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Models; + +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage routed audio processes +/// +public interface IRoutedProcessManager +{ + /// + /// Get all audio processes that are routed to Sonar + /// + /// A list of + IEnumerable GetAllRoutedProcesses(); + + /// + /// Get all audio processes that are routed to Sonar and currently active + /// + /// A list of + IEnumerable GetAllActiveRoutedProcesses(); + + /// + /// Get all audio processes that are routed to a + /// + /// + /// A list of + IEnumerable GetRoutedProcesses(Channel channel); + + /// + /// Get all audio processes that are routed to a and currently active + /// + /// + /// A list of + IEnumerable GetActiveRoutedProcesses(Channel channel); + + /// + /// Get an audio process that is routed to Sonar whatever its state + /// + /// The id of the process + /// A list of + IEnumerable GetRoutedProcessesById(int processId); + + /// + /// Get an audio process that is routed to Sonar and is active + /// + /// The id of the process + /// + IEnumerable GetActiveRoutedProcessesById(int processId); + + /// + /// Route an audio process to a specific + /// + /// The id of the process + /// + void RouteProcessToChannel(int processId, Channel channel); + + /// + /// Route an audio process to a specific + /// + /// + /// + void RouteProcessToChannel(RoutedProcess process, Channel channel); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Interfaces/Managers/IVolumeSettingsManager.cs b/SteelSeriesAPI/Sonar/Interfaces/Managers/IVolumeSettingsManager.cs new file mode 100644 index 0000000..99f6d38 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Interfaces/Managers/IVolumeSettingsManager.cs @@ -0,0 +1,69 @@ +using SteelSeriesAPI.Sonar.Enums; + +namespace SteelSeriesAPI.Sonar.Interfaces.Managers; + +/// +/// Manage the volumes and muted state of each +/// +public interface IVolumeSettingsManager +{ + /// + /// Get the volume of a Sonar + /// + /// The Sonar you want the volume of + /// The volume of the channel in double, value between 0 and 1 + double GetVolume(Channel channel); + + /// + /// Get the volume of a Steamer mode Sonar + /// + /// The Sonar of the you want the volume of + /// The Sonar you want the volume of + /// The volume of the mix in double, value between 0 and 1 + double GetVolume(Channel channel, Mix mix); + + /// + /// Get the mute state of a Sonar + /// + /// The Sonar you want the mute state of + /// The mute state, a boolean + bool GetMute(Channel channel); + + /// + /// Get the mute state of a Streamer mode Sonar + /// + /// The Sonar of the you want the mute state of + /// The Sonar you want the mute state of + /// The mute state, a boolean + bool GetMute(Channel channel, Mix mix); + + /// + /// Set the volume of a Sonar + /// + /// The volume you want to set, between 1 and 0 + /// The you want to change the volume of + void SetVolume(double volume, Channel channel); + + /// + /// Set the volume of a Streamer mode Sonar + /// + /// The volume you want to set, between 1 and 0 + /// The of the you want to change the volume of + /// The you want to change the volume of + void SetVolume(double volume, Channel channel, Mix mix); + + /// + /// Mute or unmute a Sonar + /// + /// The new muted state + /// The you want to un/mute + void SetMute(bool mute, Channel channel); + + /// + /// Mute or unmute a Streamer mode Sonar + /// + /// The new muted state + /// The of the you want to un/mute + /// The you want to un/mute + void SetMute(bool mute, Channel channel, Mix mix); +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/AudienceMonitoringManager.cs b/SteelSeriesAPI/Sonar/Managers/AudienceMonitoringManager.cs new file mode 100644 index 0000000..4378dcf --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/AudienceMonitoringManager.cs @@ -0,0 +1,21 @@ +using SteelSeriesAPI.Sonar.Http; +using SteelSeriesAPI.Sonar.Interfaces.Managers; + +using System.Text.Json; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class AudienceMonitoringManager : IAudienceMonitoringManager +{ + public bool GetState() + { + JsonDocument streamMonitoring = new Fetcher().Provide("streamRedirections/isStreamMonitoringEnabled"); + + return streamMonitoring.RootElement.GetBoolean(); + } + + public void SetState(bool newState) + { + new Fetcher().Put("streamRedirections/isStreamMonitoringEnabled/" + newState); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/ChatMixManager.cs b/SteelSeriesAPI/Sonar/Managers/ChatMixManager.cs new file mode 100644 index 0000000..06c0a71 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/ChatMixManager.cs @@ -0,0 +1,46 @@ +using SteelSeriesAPI.Sonar.Exceptions; +using SteelSeriesAPI.Sonar.Interfaces.Managers; +using SteelSeriesAPI.Sonar.Http; + +using System.Text.Json; +using System.Globalization; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class ChatMixManager : IChatMixManager +{ + public double GetBalance() + { + JsonDocument chatMix = new Fetcher().Provide("chatMix"); + + return chatMix.RootElement.GetProperty("balance").GetDouble(); + } + + public bool GetState() + { + JsonDocument chatMix = new Fetcher().Provide("chatMix"); + string cState = chatMix.RootElement.GetProperty("state").ToString(); + + if (cState == "enabled") + { + return true; + } + + return false; + } + + public void SetBalance(double balance) + { + if (!GetState()) + { + throw new ChatMixDisabledException(); + } + + if (balance > 1 || balance < -1) + { + throw new ChatMixBalanceException(); + } + + new Fetcher().Put("chatMix?balance=" + balance.ToString("0.00", CultureInfo.InvariantCulture)); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/ConfigurationManager.cs b/SteelSeriesAPI/Sonar/Managers/ConfigurationManager.cs new file mode 100644 index 0000000..1cf0cd5 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/ConfigurationManager.cs @@ -0,0 +1,128 @@ +using SteelSeriesAPI.Sonar.Interfaces.Managers; +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; +using SteelSeriesAPI.Sonar.Models; + +using System.Text.Json; +using SteelSeriesAPI.Sonar.Exceptions; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class ConfigurationManager : IConfigurationManager +{ + public IEnumerable GetAllAudioConfigurations() + { + JsonElement configs = new Fetcher().Provide("configs").RootElement; + + foreach (JsonElement config in configs.EnumerateArray()) + { + string device = config.GetProperty("virtualAudioDevice").GetString()!; + string id = config.GetProperty("id").GetString()!; + string name = config.GetProperty("name").GetString()!; + + yield return new SonarAudioConfiguration(id, name, (Channel)ChannelExtensions.FromDictKey(device)!); + } + } + + public IEnumerable GetAudioConfigurations(Channel channel) + { + if (channel == Channel.MASTER) + { + throw new MasterChannelNotSupportedException(); + } + + JsonElement configs = new Fetcher().Provide("configs").RootElement; + + foreach (JsonElement config in configs.EnumerateArray()) + { + string device = config.GetProperty("virtualAudioDevice").GetString()!; + if (device == channel.ToDictKey()) + { + string id = config.GetProperty("id").GetString()!; + string name = config.GetProperty("name").GetString()!; + + yield return new SonarAudioConfiguration(id, name, (Channel)ChannelExtensions.FromDictKey(device)!); + } + } + } + + public SonarAudioConfiguration GetSelectedAudioConfiguration(Channel channel) + { + if (channel == Channel.MASTER) + { + throw new MasterChannelNotSupportedException(); + } + + JsonElement selectedConfigs = new Fetcher().Provide("configs/selected").RootElement; + + foreach (JsonElement config in selectedConfigs.EnumerateArray()) + { + var device = config.GetProperty("virtualAudioDevice").GetString()!; + if (device == channel.ToDictKey()) + { + string id = config.GetProperty("id").GetString()!; + string name = config.GetProperty("name").GetString()!; + + return new SonarAudioConfiguration(id, name, (Channel)ChannelExtensions.FromDictKey(device)!); + } + } + + throw new ChannelNotFoundException(); + } + + public SonarAudioConfiguration GetAudioConfiguration(string configId) + { + JsonElement configs = new Fetcher().Provide("configs").RootElement; + + foreach (JsonElement config in configs.EnumerateArray()) + { + string id = config.GetProperty("id").GetString()!; + if (id == configId) + { + string device = config.GetProperty("virtualAudioDevice").GetString()!; + string name = config.GetProperty("name").GetString()!; + + return new SonarAudioConfiguration(id, name, (Channel)ChannelExtensions.FromDictKey(device)!); + } + } + + throw new ConfigNotFoundException($"No audio configuration found with this id: {configId}"); + } + + public void SetConfig(string configId) + { + if (string.IsNullOrEmpty(configId)) throw new ConfigNotFoundException("Id can't be null or empty"); + + JsonElement configs = new Fetcher().Provide("configs").RootElement; + + foreach (JsonElement config in configs.EnumerateArray()) + { + string id = config.GetProperty("id").GetString()!; + if (id == configId) + { + new Fetcher().Put("configs/" + configId + "/select"); + return; + } + } + + throw new ConfigNotFoundException($"No audio configuration found with this id: {configId}"); + } + + public void SetConfig(SonarAudioConfiguration config) + { + SetConfig(config.Id); + } + + public void SetConfigByName(Channel channel, string name) + { + var configs = GetAudioConfigurations(channel).ToList(); + foreach (var config in configs) + { + if (config.Name == name) + { + SetConfig(config.Id); + break; + } + } + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/SonarEventManager.cs b/SteelSeriesAPI/Sonar/Managers/EventManager.cs similarity index 56% rename from SteelSeriesAPI/Sonar/SonarEventManager.cs rename to SteelSeriesAPI/Sonar/Managers/EventManager.cs index a0f1835..4ab738d 100644 --- a/SteelSeriesAPI/Sonar/SonarEventManager.cs +++ b/SteelSeriesAPI/Sonar/Managers/EventManager.cs @@ -1,28 +1,31 @@ using System.Globalization; -using SteelSeriesAPI.Events; +using SteelSeriesAPI.Sonar.Events; using SteelSeriesAPI.Sonar.Enums; -namespace SteelSeriesAPI.Sonar; +namespace SteelSeriesAPI.Sonar.Managers; -public class SonarEventManager +/// +/// Manage the different Sonar Events +/// +public class EventManager { /// - /// Notify when mode changed + /// Notify when the current changed /// public event EventHandler OnSonarModeChange = delegate{ }; /// - /// Notify when a volume of a device changed + /// Notify when the volume of a has changed /// public event EventHandler OnSonarVolumeChange = delegate{ }; /// - /// Notify when a device is un/muted + /// Notify when a gets un/muted /// public event EventHandler OnSonarMuteChange = delegate{ }; /// - /// Notify when the config of a device is changed + /// Notify when the config of a is changed /// public event EventHandler OnSonarConfigChange = delegate{ }; @@ -32,21 +35,26 @@ public class SonarEventManager public event EventHandler OnSonarChatMixChange = delegate{ }; /// - /// Notify when a redirection device of a device is changed + /// Notify when the playback device of a is changed /// - public event EventHandler OnSonarRedirectionDeviceChange = delegate{ }; + public event EventHandler OnSonarPlaybackDeviceChange = delegate{ }; /// - /// Notify when a redirection state is changed + /// Notify when an audio process is routed to a new /// - public event EventHandler OnSonarRedirectionStateChange = delegate{ }; + public event EventHandler OnSonarRoutedProcessChange = delegate{ }; + + /// + /// Notify when a gets de/activated + /// + public event EventHandler OnSonarMixChange = delegate{ }; /// /// Notify when the audience monitoring state is changed /// public event EventHandler OnSonarAudienceMonitoringChange = delegate{ }; - public void HandleEvent(string path) + internal void HandleEvent(string path) { var eventMessage = PathResolver(path); switch (eventMessage) @@ -66,11 +74,14 @@ public void HandleEvent(string path) case SonarChatMixEvent sonarChatMixEvent: OnSonarChatMixChange(this, sonarChatMixEvent); break; - case SonarRedirectionDeviceEvent sonarRedirectionDeviceEvent: - OnSonarRedirectionDeviceChange(this, sonarRedirectionDeviceEvent); + case SonarPlaybackDeviceEvent sonarPlaybackDeviceEvent: + OnSonarPlaybackDeviceChange(this, sonarPlaybackDeviceEvent); + break; + case SonarRoutedProcessEvent sonarRoutedProcessEvent: + OnSonarRoutedProcessChange(this, sonarRoutedProcessEvent); break; - case SonarRedirectionStateEvent sonarRedirectionStateEvent: - OnSonarRedirectionStateChange(this, sonarRedirectionStateEvent); + case SonarMixEvent sonarMixEvent: + OnSonarMixChange(this, sonarMixEvent); break; case SonarAudienceMonitoringEvent sonarAudienceMonitoringEvent: OnSonarAudienceMonitoringChange(this, sonarAudienceMonitoringEvent); @@ -81,13 +92,13 @@ public void HandleEvent(string path) private EventArgs PathResolver(string path) { string[] subs = path.Split("/"); - EventArgs eventArgs = null; + EventArgs eventArgs = null!; switch (subs[1]) { case "mode": - eventArgs = new SonarModeEvent() - { NewMode = (Mode)ModeExtensions.FromDictKey(subs[2], ModeMapChoice.StreamDict) }; + eventArgs = new SonarModeEvent + { NewMode = (Mode)ModeExtensions.FromDictKey(subs[2], ModeMapChoice.StreamDict)! }; break; case "volumeSettings": switch (subs[2]) @@ -96,19 +107,19 @@ private EventArgs PathResolver(string path) switch (subs[4]) { case "Volume": - eventArgs = new SonarVolumeEvent() + eventArgs = new SonarVolumeEvent { Volume = double.Parse(subs[5], CultureInfo.InvariantCulture.NumberFormat), - Mode = Mode.Classic, - Device = (Device)DeviceExtensions.FromDictKey(subs[3], DeviceMapChoice.HttpDict) + Mode = Mode.CLASSIC, + Channel = (Channel)ChannelExtensions.FromDictKey(subs[3], ChannelMapChoice.HttpDict)! }; break; case"Mute": - eventArgs = new SonarMuteEvent() + eventArgs = new SonarMuteEvent { Muted = Convert.ToBoolean(subs[5]), - Mode = Mode.Classic, - Device = (Device)DeviceExtensions.FromDictKey(subs[3], DeviceMapChoice.HttpDict) + Mode = Mode.CLASSIC, + Channel = (Channel)ChannelExtensions.FromDictKey(subs[3], ChannelMapChoice.HttpDict)! }; break; } @@ -117,21 +128,21 @@ private EventArgs PathResolver(string path) switch (subs[5]) { case "volume": - eventArgs = new SonarVolumeEvent() + eventArgs = new SonarVolumeEvent { Volume = double.Parse(subs[6], CultureInfo.InvariantCulture.NumberFormat), - Mode = Mode.Streamer, - Device = (Device)DeviceExtensions.FromDictKey(subs[4], DeviceMapChoice.HttpDict), - Channel = (Channel)ChannelExtensions.FromDictKey(subs[3]) + Mode = Mode.STREAMER, + Channel = (Channel)ChannelExtensions.FromDictKey(subs[4], ChannelMapChoice.HttpDict)!, + Mix = (Mix)MixExtensions.FromDictKey(subs[3])! }; break; case "isMuted": - eventArgs = new SonarMuteEvent() + eventArgs = new SonarMuteEvent { Muted = Convert.ToBoolean(subs[6]), - Mode = Mode.Streamer, - Device = (Device)DeviceExtensions.FromDictKey(subs[4], DeviceMapChoice.HttpDict), - Channel = (Channel)ChannelExtensions.FromDictKey(subs[3]) + Mode = Mode.STREAMER, + Channel = (Channel)ChannelExtensions.FromDictKey(subs[4], ChannelMapChoice.HttpDict)!, + Mix = (Mix)MixExtensions.FromDictKey(subs[3])! }; break; } @@ -141,21 +152,21 @@ private EventArgs PathResolver(string path) case "configs": if (!(subs.Length < 3)) { - eventArgs = new SonarConfigEvent() { ConfigId = subs[2] }; + eventArgs = new SonarConfigEvent { ConfigId = subs[2] }; } break; case "classicRedirections": - eventArgs = new SonarRedirectionDeviceEvent() + eventArgs = new SonarPlaybackDeviceEvent { - RedirectionDeviceId = subs[4].Replace("%7B", "{").Replace("%7D", "}"), - Mode = Mode.Classic, - Device = (Device)DeviceExtensions.FromDictKey(subs[2], DeviceMapChoice.DeviceDict) + PlaybackDeviceId = subs[4].Replace("%7B", "{").Replace("%7D", "}"), + Mode = Mode.CLASSIC, + Channel = (Channel)ChannelExtensions.FromDictKey(subs[2], ChannelMapChoice.ChannelDict)! }; break; case "streamRedirections": if (subs[2] == "isStreamMonitoringEnabled") { - eventArgs = new SonarAudienceMonitoringEvent() { AudienceMonitoringState = Convert.ToBoolean(subs[3]) }; + eventArgs = new SonarAudienceMonitoringEvent { NewState = Convert.ToBoolean(subs[3]) }; break; } @@ -164,36 +175,42 @@ private EventArgs PathResolver(string path) case "deviceId": if (subs[2] == "mic") { - eventArgs = new SonarRedirectionDeviceEvent() + eventArgs = new SonarPlaybackDeviceEvent { - RedirectionDeviceId = subs[4].Replace("%7B", "{").Replace("%7D", "}"), - Mode = Mode.Streamer, - Device = Device.Mic + PlaybackDeviceId = subs[4].Replace("%7B", "{").Replace("%7D", "}"), + Mode = Mode.STREAMER, + Channel = Channel.MIC }; break; } - eventArgs = new SonarRedirectionDeviceEvent() + eventArgs = new SonarPlaybackDeviceEvent { - RedirectionDeviceId = subs[4].Replace("%7B", "{").Replace("%7D", "}"), - Mode = Mode.Streamer, - Channel = (Channel)ChannelExtensions.FromDictKey(subs[2]) + PlaybackDeviceId = subs[4].Replace("%7B", "{").Replace("%7D", "}"), + Mode = Mode.STREAMER, + Mix = (Mix)MixExtensions.FromDictKey(subs[2])! }; break; case "redirections": - eventArgs = new SonarRedirectionStateEvent() + eventArgs = new SonarMixEvent { - State = Convert.ToBoolean(subs[6]), - Device = (Device)DeviceExtensions.FromDictKey(subs[4]), - Channel = (Channel)ChannelExtensions.FromDictKey(subs[2]) + NewState = Convert.ToBoolean(subs[6]), + Channel = (Channel)ChannelExtensions.FromDictKey(subs[4])!, + Mix = (Mix)MixExtensions.FromDictKey(subs[2])! }; break; } break; + case "AudioDeviceRouting": + eventArgs = new SonarRoutedProcessEvent(subs[3].Replace("%7B", "{").Replace("%7D", "}")) + { + ProcessId = Convert.ToInt32(subs[4]) + }; + break; default: if (subs[1].StartsWith("chatMix")) { - eventArgs = new SonarChatMixEvent() { Balance = Convert.ToDouble(subs[1].Split("=")[1], CultureInfo.InvariantCulture) }; + eventArgs = new SonarChatMixEvent { Balance = Convert.ToDouble(subs[1].Split("=")[1], CultureInfo.InvariantCulture) }; } break; } diff --git a/SteelSeriesAPI/Sonar/Managers/MixManager.cs b/SteelSeriesAPI/Sonar/Managers/MixManager.cs new file mode 100644 index 0000000..8c8c555 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/MixManager.cs @@ -0,0 +1,49 @@ +using SteelSeriesAPI.Sonar.Exceptions; +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; + +using System.Text.Json; +using SteelSeriesAPI.Sonar.Interfaces.Managers; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class MixManager : IMixManager +{ + public bool GetState(Channel channel, Mix mix) + { + JsonElement streamRedirections = new Fetcher().Provide("streamRedirections").RootElement; + + foreach (JsonElement element in streamRedirections.EnumerateArray()) + { + if (element.GetProperty("streamRedirectionId").GetString() == mix.ToDictKey()) + { + foreach (JsonElement status in element.GetProperty("status").EnumerateArray()) + { + if (status.GetProperty("role").GetString() == channel.ToDictKey()) + { + return status.GetProperty("isEnabled").GetBoolean(); + } + } + + throw new ChannelNotFoundException(); + } + } + + throw new MixNotFoundException(); + } + + public void SetState(bool newState,Channel channel, Mix mix) + { + new Fetcher().Put("streamRedirections/" + mix.ToDictKey() + "/redirections/" + channel.ToDictKey() + "/isEnabled/" + newState); + } + + public void Activate(Channel channel, Mix mix) + { + new Fetcher().Put("streamRedirections/" + mix.ToDictKey() + "/redirections/" + channel.ToDictKey() + "/isEnabled/true"); + } + + public void Deactivate(Channel channel, Mix mix) + { + new Fetcher().Put("streamRedirections/" + mix.ToDictKey() + "/redirections/" + channel.ToDictKey() + "/isEnabled/false"); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/ModeManager.cs b/SteelSeriesAPI/Sonar/Managers/ModeManager.cs new file mode 100644 index 0000000..f8ce852 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/ModeManager.cs @@ -0,0 +1,21 @@ +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; +using SteelSeriesAPI.Sonar.Interfaces.Managers; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class ModeManager : IModeManager +{ + public Mode Get() + { + string mode = new Fetcher().Provide("mode").RootElement.ToString(); + + return (Mode)ModeExtensions.FromDictKey(mode, ModeMapChoice.StreamDict)!; + } + + public void Set(Mode mode) + { + new Fetcher().Put("mode/" + mode.ToDictKey(ModeMapChoice.StreamDict)); + Thread.Sleep(100); // Prevent bugs/freezes/crashes + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/PlaybackDeviceManager.cs b/SteelSeriesAPI/Sonar/Managers/PlaybackDeviceManager.cs new file mode 100644 index 0000000..02d93dd --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/PlaybackDeviceManager.cs @@ -0,0 +1,351 @@ +using System.Collections; +using SteelSeriesAPI.Sonar.Exceptions; +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; +using SteelSeriesAPI.Sonar.Interfaces.Managers; +using SteelSeriesAPI.Sonar.Models; + +using System.Text.Json; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class PlaybackDeviceManager : IPlaybackDeviceManager +{ + public IEnumerable GetAllPlaybackDevices() + { + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("role").GetString() == "none") + { + string id = device.GetProperty("id").GetString()!; + string name = device.GetProperty("friendlyName").GetString()!; + DataFlow dataFlow = (DataFlow)DataFlowExtensions.FromDictKey(device.GetProperty("dataFlow").GetString()!)!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(id, channels, mixes); + + yield return new PlaybackDevice(id, name, dataFlow, channels, mixes); + } + } + } + + public IEnumerable GetOutputPlaybackDevices() + { + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("role").GetString() == "none") + { + string dataFlow = device.GetProperty("dataFlow").GetString()!; + if (dataFlow == "render") + { + string id = device.GetProperty("id").GetString()!; + string name = device.GetProperty("friendlyName").GetString()!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(id, channels, mixes); + + yield return new PlaybackDevice(id, name, DataFlow.OUTPUT, channels, mixes); + } + } + } + } + + public IEnumerable GetInputPlaybackDevices() + { + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("role").GetString() == "none") + { + string dataFlow = device.GetProperty("dataFlow").GetString()!; + if (dataFlow == "capture") + { + string id = device.GetProperty("id").GetString()!; + string name = device.GetProperty("friendlyName").GetString()!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(id, channels, mixes); + + yield return new PlaybackDevice(id, name, DataFlow.INPUT, channels, mixes); + } + } + } + } + + public PlaybackDevice GetPlaybackDevice(Channel channel) + { + JsonElement classicRedirections = new Fetcher().Provide("classicRedirections").RootElement; + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement redirection in classicRedirections.EnumerateArray()) + { + if (redirection.GetProperty("id").GetString() == channel.ToDictKey(ChannelMapChoice.ChannelDict)) + { + string deviceId = redirection.GetProperty("deviceId").GetString()!; + + if (string.IsNullOrEmpty(deviceId)) + { + throw new PlaybackDeviceNotFoundException("No device set on this channel"); + } + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string name = device.GetProperty("friendlyName").GetString()!; + DataFlow dataFlow = (DataFlow)DataFlowExtensions.FromDictKey(device.GetProperty("dataFlow").GetString()!)!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(deviceId, channels, mixes); + + return new PlaybackDevice(deviceId, name, dataFlow, channels, mixes); + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + } + + throw new ChannelNotFoundException("Could not find the Channel"); + } + + public PlaybackDevice GetPlaybackDevice(Channel channel, Mode mode) + { + if (mode == Mode.CLASSIC) + { + return GetPlaybackDevice(channel); + } + + if (mode == Mode.STREAMER && channel != Channel.MIC) + { + throw new ChannelNoStreamerSupportException(); + } + + JsonElement streamRedirections = new Fetcher().Provide("streamRedirections").RootElement; + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement redirection in streamRedirections.EnumerateArray()) + { + if (redirection.GetProperty("streamRedirectionId").GetString() == channel.ToDictKey(ChannelMapChoice.ChannelDict)) + { + string deviceId = redirection.GetProperty("deviceId").GetString()!; + + if (string.IsNullOrEmpty(deviceId)) + { + throw new PlaybackDeviceNotFoundException("No device set on this channel"); + } + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string name = device.GetProperty("friendlyName").GetString()!; + DataFlow dataFlow = (DataFlow)DataFlowExtensions.FromDictKey(device.GetProperty("dataFlow").GetString()!)!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(deviceId, channels, mixes); + + return new PlaybackDevice(deviceId, name, dataFlow, channels, mixes); + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + } + + throw new ChannelNotFoundException("Could not find the Channel"); + } + + public PlaybackDevice GetPlaybackDevice(Mix mix) + { + JsonElement streamRedirections = new Fetcher().Provide("streamRedirections").RootElement; + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement redirection in streamRedirections.EnumerateArray()) + { + if (redirection.GetProperty("streamRedirectionId").GetString() == mix.ToDictKey()) + { + string deviceId = redirection.GetProperty("deviceId").GetString()!; + + if (string.IsNullOrEmpty(deviceId)) + { + throw new PlaybackDeviceNotFoundException("No device set on this channel"); + } + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string name = device.GetProperty("friendlyName").GetString()!; + DataFlow dataFlow = (DataFlow)DataFlowExtensions.FromDictKey(device.GetProperty("dataFlow").GetString()!)!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(deviceId, channels, mixes); + + return new PlaybackDevice(deviceId, name, dataFlow, channels, mixes); + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + } + + throw new ChannelNotFoundException("Could not find the Channel"); + } + + public PlaybackDevice GetPlaybackDevice(string deviceId) + { + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string name = device.GetProperty("friendlyName").GetString()!; + DataFlow dataFlow = (DataFlow)DataFlowExtensions.FromDictKey(device.GetProperty("dataFlow").GetString()!)!; + List> channels = new List>(); + List mixes = new List(); + + GetChannelsAndMixes(deviceId, channels, mixes); + + return new PlaybackDevice(deviceId, name, dataFlow, channels, mixes); + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + + private void GetChannelsAndMixes(string deviceId, List> channels, List mixes) + { + JsonElement classicRedirections = new Fetcher().Provide("classicRedirections").RootElement; + + foreach (JsonElement redirection in classicRedirections.EnumerateArray()) + { + if (redirection.GetProperty("deviceId").GetString() == deviceId) + { + channels.Add(new Tuple((Channel)ChannelExtensions.FromDictKey(redirection.GetProperty("id").GetString()!, ChannelMapChoice.ChannelDict)!, Mode.CLASSIC)); + } + } + + JsonElement streamRedirections = new Fetcher().Provide("streamRedirections").RootElement; + + foreach (JsonElement redirection in streamRedirections.EnumerateArray()) + { + if (redirection.GetProperty("deviceId").GetString() == deviceId) + { + var id = redirection.GetProperty("streamRedirectionId").GetString()!; + if (id == "mic") + { + channels.Add(new Tuple(Channel.MIC, Mode.STREAMER)); + } + else + { + mixes.Add((Mix)MixExtensions.FromDictKey(id)!); + } + } + } + } + + public void SetPlaybackDevice(string deviceId, Channel channel) + { + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string dataFlow = device.GetProperty("dataFlow").GetString()!; + if ((dataFlow == "render" && channel == Channel.MIC) + || (dataFlow == "capture" && channel != Channel.MIC)) + { + throw new PlaybackDeviceDataFlowException(); + } + + new Fetcher().Put("classicRedirections/" + channel.ToDictKey(ChannelMapChoice.ChannelDict) +"/deviceId/" + deviceId); + return; + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + + public void SetPlaybackDevice(string deviceId, Channel channel, Mode mode) + { + if (mode == Mode.CLASSIC) + { + SetPlaybackDevice(deviceId, channel); + } + + if (mode == Mode.STREAMER && channel != Channel.MIC) + { + throw new ChannelNoStreamerSupportException(); + } + + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string dataFlow = device.GetProperty("dataFlow").GetString()!; + if (dataFlow == "capture" && channel != Channel.MIC) + { + throw new PlaybackDeviceDataFlowException(); + } + + new Fetcher().Put("streamRedirections/" + channel.ToDictKey(ChannelMapChoice.ChannelDict) +"/deviceId/" + deviceId); + return; + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + + public void SetPlaybackDevice(string deviceId, Mix mix) + { + JsonElement audioDevices = new Fetcher().Provide("audioDevices").RootElement; + + foreach (JsonElement device in audioDevices.EnumerateArray()) + { + if (device.GetProperty("id").GetString() == deviceId) + { + string dataFlow = device.GetProperty("dataFlow").GetString()!; + if (dataFlow == "capture") + { + throw new PlaybackDeviceDataFlowException(); + } + + new Fetcher().Put("streamRedirections/" + mix.ToDictKey() +"/deviceId/" + deviceId); + return; + } + } + + throw new PlaybackDeviceNotFoundException("Could not find the device"); + } + + public void SetPlaybackDevice(PlaybackDevice device, Channel channel) + { + SetPlaybackDevice(device.Id, channel); + } + + public void SetPlaybackDevice(PlaybackDevice device, Channel channel, Mode mode) + { + SetPlaybackDevice(device.Id, channel, mode); + } + + public void SetPlaybackDevice(PlaybackDevice device, Mix mix) + { + SetPlaybackDevice(device.Id, mix); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/RoutedProcessManager.cs b/SteelSeriesAPI/Sonar/Managers/RoutedProcessManager.cs new file mode 100644 index 0000000..1ca7017 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/RoutedProcessManager.cs @@ -0,0 +1,225 @@ +using SteelSeriesAPI.Sonar.Exceptions; +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; +using SteelSeriesAPI.Sonar.Interfaces.Managers; +using SteelSeriesAPI.Sonar.Models; + +using System.Text.Json; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class RoutedProcessManager : IRoutedProcessManager +{ + public IEnumerable GetAllRoutedProcesses() + { + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + string role = device.GetProperty("role").GetString()!; + if (role != "none") + { + foreach (JsonElement session in device.GetProperty("audioSessions").EnumerateArray()) + { + int processId = session.GetProperty("processId").GetInt32(); + string processName = session.GetProperty("processName").GetString()!; + string displayName = session.GetProperty("displayName").GetString()!; + + if (processId == 0 && processName == "Idle" && displayName == "Idle") continue; + + RoutedProcessState state = (RoutedProcessState)RoutedProcessStateExtensions.FromDictKey(device.GetProperty("state").GetString()!)!; + Channel channel = (Channel)ChannelExtensions.FromDictKey(role)!; + string processPath = session.GetProperty("id").GetString()!.Split("|")[1].Replace('\\', '/'); + + yield return new RoutedProcess(processId, processName, displayName, state, channel, processPath); + } + } + } + } + + public IEnumerable GetAllActiveRoutedProcesses() + { + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + string role = device.GetProperty("role").GetString()!; + if (role != "none") + { + foreach (JsonElement session in device.GetProperty("audioSessions").EnumerateArray()) + { + if (session.GetProperty("state").GetString() == "active") + { + int processId = session.GetProperty("processId").GetInt32(); + string processName = session.GetProperty("processName").GetString()!; + string displayName = session.GetProperty("displayName").GetString()!; + + if (processId == 0 && processName == "Idle" && displayName == "Idle") continue; + + RoutedProcessState state = RoutedProcessState.ACTIVE; + Channel channel = (Channel)ChannelExtensions.FromDictKey(role)!; + string processPath = session.GetProperty("id").GetString()!.Split("|")[1].Replace('\\', '/'); + + yield return new RoutedProcess(processId, processName, displayName, state, channel, processPath); + } + } + } + } + } + + public IEnumerable GetRoutedProcesses(Channel channel) + { + if (channel == Channel.MASTER) + { + throw new MasterChannelNotSupportedException(); + } + + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + if (device.GetProperty("role").GetString() == channel.ToDictKey()) + { + foreach (JsonElement session in device.GetProperty("audioSessions").EnumerateArray()) + { + int processId = session.GetProperty("processId").GetInt32(); + string processName = session.GetProperty("processName").GetString()!; + string displayName = session.GetProperty("displayName").GetString()!; + + if (processId == 0 && processName == "Idle" && displayName == "Idle") continue; + + RoutedProcessState state = (RoutedProcessState)RoutedProcessStateExtensions.FromDictKey(device.GetProperty("state").GetString()!)!; + string processPath = session.GetProperty("id").GetString()!.Split("|")[1].Replace('\\', '/'); + + yield return new RoutedProcess(processId, processName, displayName, state, channel, processPath); + } + } + } + } + + public IEnumerable GetActiveRoutedProcesses(Channel channel) + { + if (channel == Channel.MASTER) + { + throw new MasterChannelNotSupportedException(); + } + + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + if (device.GetProperty("role").GetString() == channel.ToDictKey()) + { + foreach (JsonElement session in device.GetProperty("audioSessions").EnumerateArray()) + { + if (session.GetProperty("state").GetString() == "active") + { + int processId = session.GetProperty("processId").GetInt32(); + string processName = session.GetProperty("processName").GetString()!; + string displayName = session.GetProperty("displayName").GetString()!; + + if (processId == 0 && processName == "Idle" && displayName == "Idle") continue; + + RoutedProcessState state = RoutedProcessState.ACTIVE; + string processPath = session.GetProperty("id").GetString()!.Split("|")[1].Replace('\\', '/'); + + yield return new RoutedProcess(processId, processName, displayName, state, channel, processPath); + } + } + } + } + } + + public IEnumerable GetRoutedProcessesById(int processId) + { + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + string role = device.GetProperty("role").GetString()!; + if (role != "none") + { + foreach (JsonElement session in device.GetProperty("audioSessions").EnumerateArray()) + { + if (session.GetProperty("processId").GetInt32() == processId) + { + string processName = session.GetProperty("processName").GetString()!; + string displayName = session.GetProperty("displayName").GetString()!; + RoutedProcessState state = (RoutedProcessState)RoutedProcessStateExtensions.FromDictKey(device.GetProperty("state").GetString()!)!; + Channel channel = (Channel)ChannelExtensions.FromDictKey(role)!; + string processPath = session.GetProperty("id").GetString()!.Split("|")[1].Replace('\\', '/'); + + yield return new RoutedProcess(processId, processName, displayName, state, channel, processPath); + } + } + } + } + } + + public IEnumerable GetActiveRoutedProcessesById(int processId) + { + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + string role = device.GetProperty("role").GetString()!; + if (role != "none") + { + foreach (JsonElement session in device.GetProperty("audioSessions").EnumerateArray()) + { + if (session.GetProperty("state").GetString() == "active" && session.GetProperty("processId").GetInt32() == processId) + { + string processName = session.GetProperty("processName").GetString()!; + string displayName = session.GetProperty("displayName").GetString()!; + RoutedProcessState state = RoutedProcessState.ACTIVE; + Channel channel = (Channel)ChannelExtensions.FromDictKey(role)!; + string processPath = session.GetProperty("id").GetString()!.Split("|")[1].Replace('\\', '/'); + + yield return new RoutedProcess(processId, processName, displayName, state, channel, processPath); + } + } + } + } + + throw new RoutedProcessNotFoundException("No active processes with id " + processId + " found"); + } + + public void RouteProcessToChannel(int processId, Channel channel) + { + if (channel == Channel.MASTER) + { + throw new MasterChannelNotSupportedException(); + } + + JsonElement audioDeviceRouting = new Fetcher().Provide("AudioDeviceRouting").RootElement; + + foreach (JsonElement device in audioDeviceRouting.EnumerateArray()) + { + if (device.GetProperty("role").GetString() == channel.ToDictKey()) + { + if (channel == Channel.MIC) + { + new Fetcher().Put("AudioDeviceRouting/capture/" + device.GetProperty("deviceId").GetString() + "/" + processId); + break; + } + + new Fetcher().Put("AudioDeviceRouting/render/" + device.GetProperty("deviceId").GetString() + "/" + processId); + break; + } + } + } + + public void RouteProcessToChannel(RoutedProcess process, Channel channel) + { + RouteProcessToChannel(process.ProcessId, channel); + + if (process.Channel == channel) + { + process.State = RoutedProcessState.ACTIVE; + } + else + { + process.State = RoutedProcessState.INACTIVE; + } + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Managers/VolumeSettingsManager.cs b/SteelSeriesAPI/Sonar/Managers/VolumeSettingsManager.cs new file mode 100644 index 0000000..0b4d394 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Managers/VolumeSettingsManager.cs @@ -0,0 +1,70 @@ +using SteelSeriesAPI.Sonar.Interfaces.Managers; +using SteelSeriesAPI.Sonar.Enums; +using SteelSeriesAPI.Sonar.Http; + +using System.Globalization; +using System.Text.Json; + +namespace SteelSeriesAPI.Sonar.Managers; + +internal class VolumeSettingsManager : IVolumeSettingsManager +{ + // volume = 0,00000000 <-- 8 decimal max + public double GetVolume(Channel channel) + { + JsonDocument volumeSettings = new Fetcher().Provide("volumeSettings/classic/"); + + if (channel == Channel.MASTER) + return volumeSettings.RootElement.GetProperty("masters").GetProperty("classic").GetProperty("volume").GetDouble(); + return volumeSettings.RootElement.GetProperty("devices").GetProperty(channel.ToDictKey()).GetProperty("classic").GetProperty("volume").GetDouble(); + } + + public double GetVolume(Channel channel, Mix mix) + { + JsonDocument volumeSettings = new Fetcher().Provide("volumeSettings/streamer/"); + + if (channel == Channel.MASTER) + return volumeSettings.RootElement.GetProperty("masters").GetProperty("stream").GetProperty(mix.ToDictKey()).GetProperty("volume").GetDouble(); + return volumeSettings.RootElement.GetProperty("devices").GetProperty(channel.ToDictKey()).GetProperty("stream").GetProperty(mix.ToDictKey()).GetProperty("volume").GetDouble(); + } + + public bool GetMute(Channel channel) + { + JsonDocument volumeSettings = new Fetcher().Provide("volumeSettings/classic/"); + + if (channel == Channel.MASTER) + return volumeSettings.RootElement.GetProperty("masters").GetProperty("classic").GetProperty("muted").GetBoolean(); + return volumeSettings.RootElement.GetProperty("devices").GetProperty(channel.ToDictKey()).GetProperty("classic").GetProperty("muted").GetBoolean(); + } + + public bool GetMute(Channel channel, Mix mix) + { + JsonDocument volumeSettings = new Fetcher().Provide("volumeSettings/streamer/"); + + if (channel == Channel.MASTER) + return volumeSettings.RootElement.GetProperty("masters").GetProperty("stream").GetProperty(mix.ToDictKey()).GetProperty("muted").GetBoolean(); + return volumeSettings.RootElement.GetProperty("devices").GetProperty(channel.ToDictKey()).GetProperty("stream").GetProperty(mix.ToDictKey()).GetProperty("muted").GetBoolean(); + } + + public void SetVolume(double volume, Channel channel) + { + string vol = volume.ToString("0.00", CultureInfo.InvariantCulture); + new Fetcher().Put("volumeSettings/classic/" + channel.ToDictKey(ChannelMapChoice.HttpDict) + "/Volume/" + vol); + } + + public void SetVolume(double volume, Channel channel, Mix mix) + { + string vol = volume.ToString("0.00", CultureInfo.InvariantCulture); + new Fetcher().Put("volumeSettings/streamer/" + mix.ToDictKey() + "/" + channel.ToDictKey(ChannelMapChoice.HttpDict) + "/volume/" + vol); + } + + public void SetMute(bool mute, Channel channel) + { + new Fetcher().Put("volumeSettings/classic/" + channel.ToDictKey(ChannelMapChoice.HttpDict) + "/Mute/" + mute); + } + + public void SetMute(bool mute, Channel channel, Mix mix) + { + new Fetcher().Put("volumeSettings/streamer/" + mix.ToDictKey() + "/" + channel.ToDictKey(ChannelMapChoice.HttpDict) + "/isMuted/" + mute); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Models/PlaybackDevice.cs b/SteelSeriesAPI/Sonar/Models/PlaybackDevice.cs new file mode 100644 index 0000000..9104b24 --- /dev/null +++ b/SteelSeriesAPI/Sonar/Models/PlaybackDevice.cs @@ -0,0 +1,6 @@ +using SteelSeriesAPI.Sonar.Enums; +using System.Collections; + +namespace SteelSeriesAPI.Sonar.Models; + +public record PlaybackDevice(string Id, string Name, DataFlow DataFlow, List> Channels, List Mixes); \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Models/RedirectionDevice.cs b/SteelSeriesAPI/Sonar/Models/RedirectionDevice.cs deleted file mode 100644 index c371e83..0000000 --- a/SteelSeriesAPI/Sonar/Models/RedirectionDevice.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Collections; -using SteelSeriesAPI.Sonar.Enums; - -namespace SteelSeriesAPI.Sonar.Models; - -public record RedirectionDevice(string Id, string Name, Direction DataFlow, List? AssociatedClassicDevices, ArrayList? AssociatedStreamDevices); \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Models/RoutedProcess.cs b/SteelSeriesAPI/Sonar/Models/RoutedProcess.cs index bcb256f..beae57f 100644 --- a/SteelSeriesAPI/Sonar/Models/RoutedProcess.cs +++ b/SteelSeriesAPI/Sonar/Models/RoutedProcess.cs @@ -2,4 +2,22 @@ namespace SteelSeriesAPI.Sonar.Models; -public record RoutedProcess(string Id, string ProcessName, int PId, RoutedProcessState State, string DisplayName); \ No newline at end of file +public record RoutedProcess +{ + public int ProcessId { get; init; } + public string ProcessName { get; init; } + public string DisplayName { get; init; } + public RoutedProcessState State { get; internal set; } + public Channel Channel { get; init; } + public string ProcessPath { get; init; } + + public RoutedProcess(int processId, string processName, string displayName, RoutedProcessState state, Channel channel, string processPath) + { + ProcessId = processId; + ProcessName = processName; + DisplayName = displayName; + State = state; + Channel = channel; + ProcessPath = processPath; + } +}; \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/Models/SonarAudioConfiguration.cs b/SteelSeriesAPI/Sonar/Models/SonarAudioConfiguration.cs index b4e5725..c76b2fe 100644 --- a/SteelSeriesAPI/Sonar/Models/SonarAudioConfiguration.cs +++ b/SteelSeriesAPI/Sonar/Models/SonarAudioConfiguration.cs @@ -2,4 +2,4 @@ namespace SteelSeriesAPI.Sonar.Models; -public record SonarAudioConfiguration(string Id, string Name, Device AssociatedDevice); \ No newline at end of file +public record SonarAudioConfiguration(string Id, string Name, Channel AssociatedChannel); \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/SonarBridge.cs b/SteelSeriesAPI/Sonar/SonarBridge.cs new file mode 100644 index 0000000..c92c9b5 --- /dev/null +++ b/SteelSeriesAPI/Sonar/SonarBridge.cs @@ -0,0 +1,155 @@ +using SteelSeriesAPI.Sonar.Interfaces; +using SteelSeriesAPI.Sonar.Interfaces.Managers; +using SteelSeriesAPI.Sonar.Managers; +using SteelSeriesAPI.Sonar.Enums; + +using System.Security.Principal; +using System.Runtime.Versioning; + +namespace SteelSeriesAPI.Sonar; + +/// +/// The Sonar object, to control Sonar
Allow you to listen for event, get or set volumes, muted states, ... +///
+public class SonarBridge : ISonarBridge +{ + /// + /// The running state of Sonar + /// + public bool IsRunning => SonarRetriever.Instance is { IsEnabled: true, IsReady: true, IsRunning: true }; + + private readonly ISonarSocket _sonarSocket; + + /// + /// Manage the Sonar + /// + public readonly IModeManager Mode; + + /// + /// Manage the volumes and muted state of each + /// + public readonly IVolumeSettingsManager VolumeSettings; + + /// + /// Manage the balance of ChatMix + /// + public readonly IChatMixManager ChatMix; + + /// + /// Manage audio configurations for each + /// + public readonly IConfigurationManager Configurations; + + /// + /// Manage the playback device of each + /// + public readonly IPlaybackDeviceManager PlaybackDevices; + + /// + /// Manage routed audio processes + /// + public readonly IRoutedProcessManager RoutedProcesses; + + /// + /// Manage the personal and stream mix for each channel + /// + public readonly IMixManager Mix; + + /// + /// Manage the Audience Monitoring feature of the streamer mode + /// + public readonly IAudienceMonitoringManager AudienceMonitoring; + + /// + /// Manage the different Sonar Events + /// + public readonly EventManager Events; + + /// + /// The Sonar object, to control Sonar
Allow you to listen for event, get or set volumes, muted states, ... + ///
+ public SonarBridge() + { + Mode = new ModeManager(); + VolumeSettings = new VolumeSettingsManager(); + ChatMix = new ChatMixManager(); + Configurations = new ConfigurationManager(); + PlaybackDevices = new PlaybackDeviceManager(); + RoutedProcesses = new RoutedProcessManager(); + Mix = new MixManager(); + AudienceMonitoring = new AudienceMonitoringManager(); + Events = new EventManager(); + + _sonarSocket = new SonarSocket(Events); + } + + #region Listener + + /// + /// Start listening to events happening on Sonar, such as changing volume... + /// + /// The state of the listener (false if it didn't start) + [SupportedOSPlatform("windows")] + public bool StartListener() + { + if (!IsRunAsAdmin()) + { + throw new ApplicationException("Listener requires Administrator rights to be used"); + } + + if (_sonarSocket.IsConnected) + { + throw new Exception("Listener already started"); + } + + var connected = _sonarSocket.Connect(); + if (!connected) + { + return false; + } + + var listening = _sonarSocket.Listen(); + if (!listening) + { + return false; + } + + return true; + } + + /// + /// Stop the listener + /// + [SupportedOSPlatform("windows")] + public void StopListener() + { + _sonarSocket.CloseSocket(); + } + + [SupportedOSPlatform("windows")] + private bool IsRunAsAdmin() + { + WindowsIdentity id = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(id); + + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + + #endregion + + /// + /// Wait until SteelSeries GG is started and running before running your code below + /// + public void WaitUntilSteelSeriesStarted() + { + SteelSeriesRetriever.Instance.WaitUntilSteelSeriesStarted(); + } + + /// + /// Wait until Sonar is started and running before running your code below + /// + public void WaitUntilSonarStarted() + { + SonarRetriever.Instance.WaitUntilAppStarted(); + } +} \ No newline at end of file diff --git a/SteelSeriesAPI/Sonar/SonarRetriever.cs b/SteelSeriesAPI/Sonar/SonarRetriever.cs index c957eba..14dd3a5 100644 --- a/SteelSeriesAPI/Sonar/SonarRetriever.cs +++ b/SteelSeriesAPI/Sonar/SonarRetriever.cs @@ -1,6 +1,8 @@ using System.Diagnostics; using System.Text.Json; +using SteelSeriesAPI.Exceptions; using SteelSeriesAPI.Interfaces; +using SteelSeriesAPI.Sonar.Exceptions; namespace SteelSeriesAPI.Sonar; @@ -20,8 +22,6 @@ public class SonarRetriever : IAppRetriever public bool ToggleViaSettings => GetMetaDatas()[6]; public bool IsBrowserViewSupported => GetMetaDatas()[7]; - private readonly ISteelSeriesRetriever _ssRetriever; - private readonly string _ggEncryptedAddress; private readonly HttpClient _httpClient; /// @@ -29,10 +29,6 @@ public class SonarRetriever : IAppRetriever /// public SonarRetriever() { - _ssRetriever = SteelSeriesRetriever.Instance; - _ssRetriever.WaitUntilSteelSeriesStarted(); - _ggEncryptedAddress = _ssRetriever.GetggEncryptedAddress(); - HttpClientHandler clientHandler = new HttpClientHandler(); clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }; _httpClient = new(clientHandler); @@ -40,14 +36,14 @@ public SonarRetriever() public bool[] GetMetaDatas() { - if (!_ssRetriever.Running) + if (!SteelSeriesRetriever.Instance.Running) { - throw new Exception("SteelSeries Sonar is not running."); + throw new SteelSeriesNotRunningException(); } try { - JsonDocument subApps = JsonDocument.Parse(_httpClient.GetStringAsync("https://" + _ggEncryptedAddress + "/subApps").Result); + JsonDocument subApps = JsonDocument.Parse(_httpClient.GetStringAsync("https://" + SteelSeriesRetriever.Instance.GetggEncryptedAddress() + "/subApps").Result); JsonElement appElement = subApps.RootElement.GetProperty("subApps").GetProperty(Name); bool isEnabled = appElement.GetProperty("isEnabled").GetBoolean(); @@ -78,10 +74,10 @@ public string WebServerAddress() { if (!IsEnabled || !IsReady || !IsRunning) { - throw new Exception("SteelSeries Sonar not running"); + throw new SonarNotRunningException(); } - JsonDocument subApps = JsonDocument.Parse(_httpClient.GetStringAsync("https://" + _ggEncryptedAddress + "/subApps").Result); + JsonDocument subApps = JsonDocument.Parse(_httpClient.GetStringAsync("https://" + SteelSeriesRetriever.Instance.GetggEncryptedAddress() + "/subApps").Result); JsonElement appElement = subApps.RootElement.GetProperty("subApps").GetProperty(Name); return appElement.GetProperty("metadata").GetProperty("webServerAddress") + "/"; @@ -92,6 +88,11 @@ public string WebServerAddress() ///
public void WaitUntilAppStarted() { + if (!SteelSeriesRetriever.Instance.Running) + { + SteelSeriesRetriever.Instance.WaitUntilSteelSeriesStarted(); + } + if (!IsEnabled || !IsReady || !IsRunning) { Console.WriteLine("Waiting for Sonar to start"); diff --git a/SteelSeriesAPI/Sonar/SonarSocket.cs b/SteelSeriesAPI/Sonar/SonarSocket.cs index 58b5932..5c8d5f2 100644 --- a/SteelSeriesAPI/Sonar/SonarSocket.cs +++ b/SteelSeriesAPI/Sonar/SonarSocket.cs @@ -1,7 +1,10 @@ -using System.Net; +using SteelSeriesAPI.Sonar.Exceptions; +using SteelSeriesAPI.Sonar.Interfaces; +using SteelSeriesAPI.Sonar.Managers; + +using System.Net; using System.Net.Sockets; using System.Text; -using SteelSeriesAPI.Interfaces; namespace SteelSeriesAPI.Sonar; @@ -10,21 +13,21 @@ public class SonarSocket : ISonarSocket public bool IsConnected => _socket?.IsBound ?? false; private readonly Thread _listenerThread; - private readonly Uri _sonarWebServerAddress; - private readonly SonarEventManager _sonarEventManager; + private readonly EventManager _eventManager; + private Uri _sonarWebServerAddress; private Socket _socket; private bool _isClosing; - public SonarSocket(string sonarWebServerAddress, SonarEventManager sonarEventManager) + public SonarSocket(EventManager eventManager) { - _sonarWebServerAddress = new Uri(sonarWebServerAddress); _listenerThread = new Thread(ListenerThreadSync) { IsBackground = false }; - _sonarEventManager = sonarEventManager; + _eventManager = eventManager; } public bool Connect() { + _sonarWebServerAddress = new Uri(SonarRetriever.Instance.WebServerAddress()); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); try { @@ -45,7 +48,7 @@ public bool Listen() { if (!IsConnected) { - throw new Exception("Listener need to be connected before listening"); + throw new SonarListenerNotConnectedException(); } _listenerThread.Start(); @@ -102,7 +105,7 @@ private void ListenerThreadSync() { string path = putData.Split("PUT ")[1].Split(" HTTP")[0]; // Console.WriteLine(path); // For debugging - _sonarEventManager.HandleEvent(path); // Invoke events + _eventManager.HandleEvent(path); // Invoke events } } } diff --git a/SteelSeriesAPI/SonarBridge.cs b/SteelSeriesAPI/SonarBridge.cs deleted file mode 100644 index eb4eb53..0000000 --- a/SteelSeriesAPI/SonarBridge.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System.Security.Principal; -using SteelSeriesAPI.Interfaces; -using SteelSeriesAPI.Sonar; -using SteelSeriesAPI.Sonar.Enums; -using SteelSeriesAPI.Sonar.Http; -using SteelSeriesAPI.Sonar.Models; - -namespace SteelSeriesAPI; - -/// -/// The Sonar object, to control Sonar
Allow you to listen for event, get or set volumes, muted states, ... -///
-public class SonarBridge : ISonarBridge -{ - public bool IsRunning => _sonarRetriever is { IsEnabled: true, IsReady: true, IsRunning: true }; - - private readonly IAppRetriever _sonarRetriever; - private readonly ISonarCommandHandler _sonarCommand; - private readonly ISonarDataProvider _sonarProvider; - private readonly ISonarSocket _sonarSocket; - public readonly SonarEventManager SonarEventManager; - - private string _sonarWebServerAddress; - - public SonarBridge() - { - _sonarRetriever = SonarRetriever.Instance; - WaitUntilSonarStarted(); - _sonarWebServerAddress = _sonarRetriever.WebServerAddress(); - SonarEventManager = new SonarEventManager(); - _sonarSocket = new SonarSocket(_sonarWebServerAddress, SonarEventManager); - _sonarCommand = new SonarHttpCommand(this); - _sonarProvider = new SonarHttpProvider(this); - } - - #region Listener - - public bool StartListener() - { - if (!IsRunAsAdmin()) - { - throw new ApplicationException("Listener requires Administrator rights to be used"); - } - - if (_sonarSocket.IsConnected) - { - throw new Exception("Listener already started"); - } - - var connected = _sonarSocket.Connect(); - if (!connected) - { - return false; - } - - var listening = _sonarSocket.Listen(); - if (!listening) - { - return false; - } - - return true; - } - - public void StopListener() - { - _sonarSocket.CloseSocket(); - } - - private bool IsRunAsAdmin() - { - WindowsIdentity id = WindowsIdentity.GetCurrent(); - WindowsPrincipal principal = new WindowsPrincipal(id); - - return principal.IsInRole(WindowsBuiltInRole.Administrator); - } - - #endregion - - /// - /// Wait until Sonar is started and running before running your code below - /// - public void WaitUntilSonarStarted() - { - _sonarRetriever.WaitUntilAppStarted(); - } - - #region Providers - - public Mode GetMode() - { - return _sonarProvider.GetMode(); - } - - // volume = 0,00000000 <-- 8 decimal max - public double GetVolume(Device device) - { - return _sonarProvider.GetVolume(device); - } - - public double GetVolume(Device device, Channel channel) - { - return _sonarProvider.GetVolume(device, channel); - } - - public bool GetMute(Device device) - { - return _sonarProvider.GetMute(device); - } - - public bool GetMute(Device device, Channel channel) - { - return _sonarProvider.GetMute(device, channel); - } - - public IEnumerable GetAllAudioConfigurations() - { - return _sonarProvider.GetAllAudioConfigurations(); - } - - public SonarAudioConfiguration GetAudioConfiguration(string configId) - { - return _sonarProvider.GetAudioConfiguration(configId); - } - - public IEnumerable GetAudioConfigurations(Device device) - { - return _sonarProvider.GetAudioConfigurations(device); - } - - public SonarAudioConfiguration GetSelectedAudioConfiguration(Device device) - { - return _sonarProvider.GetSelectedAudioConfiguration(device); - } - - public double GetChatMixBalance() - { - return _sonarProvider.GetChatMixBalance(); - } - - public bool GetChatMixState() - { - return _sonarProvider.GetChatMixState(); - } - - public IEnumerable GetRedirectionDevices(Direction direction) - { - return _sonarProvider.GetRedirectionDevices(direction); - } - - public RedirectionDevice GetClassicRedirectionDevice(Device device) - { - return _sonarProvider.GetClassicRedirectionDevice(device); - } - - public RedirectionDevice GetStreamRedirectionDevice(Channel channel) - { - return _sonarProvider.GetStreamRedirectionDevice(channel); - } - - public RedirectionDevice GetStreamRedirectionDevice(Device device = Device.Mic) - { - return _sonarProvider.GetStreamRedirectionDevice(device); - } - - public RedirectionDevice GetRedirectionDeviceFromId(string deviceId) - { - return _sonarProvider.GetRedirectionDeviceFromId(deviceId); - } - - public bool GetRedirectionState(Device device, Channel channel) - { - return _sonarProvider.GetRedirectionState(device, channel); - } - - public bool GetAudienceMonitoringState() - { - return _sonarProvider.GetAudienceMonitoringState(); - } - - public IEnumerable GetRoutedProcess(Device device) - { - return _sonarProvider.GetRoutedProcess(device); - } - - #endregion - - #region Commands - - public void SetMode(Mode mode) - { - _sonarCommand.SetMode(mode); - } - - public void SetVolume(double vol, Device device) - { - _sonarCommand.SetVolume(vol, device); - } - - public void SetVolume(double vol, Device device, Channel channel) - { - _sonarCommand.SetVolume(vol, device, channel); - } - - public void SetMute(bool mute, Device device) - { - _sonarCommand.SetMute(mute, device); - } - - public void SetMute(bool mute, Device device, Channel channel) - { - _sonarCommand.SetMute(mute, device, channel); - } - - public void SetConfig(string configId) - { - _sonarCommand.SetConfig(configId); - } - - public void SetConfig(Device device, string name) - { - _sonarCommand.SetConfig(device, name); - } - - public void SetChatMixBalance(double balance) - { - _sonarCommand.SetChatMixBalance(balance); - } - - public void SetClassicRedirectionDevice(string deviceId, Device device) - { - _sonarCommand.SetClassicRedirectionDevice(deviceId, device); - } - - public void SetStreamRedirectionDevice(string deviceId, Channel channel) - { - _sonarCommand.SetStreamRedirectionDevice(deviceId, channel); - } - - public void SetStreamRedirectionDevice(string deviceId, Device device = Device.Mic) - { - _sonarCommand.SetStreamRedirectionDevice(deviceId, device); - } - - public void SetRedirectionState(bool newState, Device device, Channel channel) - { - _sonarCommand.SetRedirectionState(newState, device, channel); - } - - public void SetAudienceMonitoringState(bool newState) - { - _sonarCommand.SetAudienceMonitoringState(newState); - } - - public void SetProcessToDeviceRouting(int pId, Device device) - { - _sonarCommand.SetProcessToDeviceRouting(pId, device); - } - - #endregion -} \ No newline at end of file diff --git a/SteelSeriesAPI/SteelSeriesAPI.csproj b/SteelSeriesAPI/SteelSeriesAPI.csproj index cee74ab..05b5235 100644 --- a/SteelSeriesAPI/SteelSeriesAPI.csproj +++ b/SteelSeriesAPI/SteelSeriesAPI.csproj @@ -4,7 +4,7 @@ enable enable net8.0;net9.0;net7.0 - 1.0.5 + 1.1.0 Steelseries-NET-API Steelseries-NET-API SteelSeries .NET API Client diff --git a/SteelSeriesAPI/SteelSeriesRetriever.cs b/SteelSeriesAPI/SteelSeriesRetriever.cs index 413d23f..ccc98be 100644 --- a/SteelSeriesAPI/SteelSeriesRetriever.cs +++ b/SteelSeriesAPI/SteelSeriesRetriever.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Text.Json; +using SteelSeriesAPI.Exceptions; using SteelSeriesAPI.Interfaces; namespace SteelSeriesAPI; @@ -10,23 +11,20 @@ public class SteelSeriesRetriever : ISteelSeriesRetriever public static SteelSeriesRetriever Instance => _instance.Value; - public bool Running => _steelSeriesProcesses.Length > 0; + public bool Running => SteelSeriesProcessesChecker(); - private readonly Thread _checkerThread; private Process[] _steelSeriesProcesses; public SteelSeriesRetriever() { - _steelSeriesProcesses = Process.GetProcessesByName("SteelSeriesSonar"); - _checkerThread = new Thread(SteelSeriesProcessesCheckerThread) { IsBackground = true }; - _checkerThread.Start(); + _steelSeriesProcesses = Process.GetProcessesByName("SteelSeriesGG"); } public string GetggEncryptedAddress() { if (!Running) { - throw new Exception("SteelSeries is not started"); + throw new SteelSeriesNotRunningException(); } try @@ -54,12 +52,9 @@ public void WaitUntilSteelSeriesStarted() } } - private void SteelSeriesProcessesCheckerThread() + private bool SteelSeriesProcessesChecker() { - while (_checkerThread.IsAlive) - { - Thread.Sleep(100); - _steelSeriesProcesses = Process.GetProcessesByName("SteelSeriesSonar"); - } + _steelSeriesProcesses = Process.GetProcessesByName("SteelSeriesGG"); + return _steelSeriesProcesses.Length > 0; } } \ No newline at end of file