V2: full rewrite - #6
Conversation
…ware volume polling - Real-time events from Sonar's /sock WebSocket (chatmix, snapshots, invalidations) - Automatic reconnection with backoff; connection doubles as GG liveness detection - Opt-in polling with mode-aware diffing for volume/mute changes (not broadcast by Sonar) - Typed event records with Previous/New state and convenience accessors - Explorer: ws command; Sample: full state dump + event bench
Also renamed VolumePollingInterval to PollingInterval
There was a problem hiding this comment.
🟡 Changes recommended
Core transport/discovery code currently leaks resources and can throw non-library exceptions on malformed JSON/IO paths, breaking the promised exception contract and affecting reliability on failure scenarios.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR is a v2 rewrite of the SteelSeries Sonar .NET library, replacing the prior synchronous “bridge + packet-sniff listener” design with an async, transport-based architecture (discovery + resilient HTTP + WebSocket/polling events) aimed at improving stability across GG updates and removing admin-right requirements for events.
Changes:
- Introduces a new
SonarCliententry point with async managers backed byISonarTransport, plus centralized route/event registries (SonarRoutes,SonarEventNames). - Replaces the old raw-socket listener and retrievers with a discovery+transport core (
ServerDiscovery,SonarHttpClient, exception taxonomy, JSON helpers). - Adds an Explorer tool, refreshed docs (architecture + contributing), CI workflow, and extensive xUnit coverage using
FakeTransport.
File summaries
| File | Description |
|---|---|
| SteelSeriesAPI/SteelSeriesRetriever.cs | Removed legacy GG process/coreProps retriever (replaced by ServerDiscovery). |
| SteelSeriesAPI/SteelSeriesAPI.csproj | Retargets + packages NuGet metadata; enables XML docs + warning enforcement; adds logging abstractions + InternalsVisibleTo tests. |
| SteelSeriesAPI/Sonar/SonarSocket.cs | Removed raw socket packet-sniff listener implementation. |
| SteelSeriesAPI/Sonar/SonarRoutes.cs | New centralized registry for all Sonar HTTP routes + route builders. |
| SteelSeriesAPI/Sonar/SonarRetriever.cs | Removed legacy /subApps retriever + blocking calls. |
| SteelSeriesAPI/Sonar/SonarClient.cs | New primary public API surface (client + managers + event listener wiring). |
| SteelSeriesAPI/Sonar/SonarBridge.cs | Removed legacy “bridge” façade. |
| SteelSeriesAPI/Sonar/Models/VolumeSettings.cs | Adds immutable model for volume+mute state (VolumeSetting). |
| SteelSeriesAPI/Sonar/Models/SonarConfig.cs | Adds config header model (SonarConfig). |
| SteelSeriesAPI/Sonar/Models/SonarAudioConfiguration.cs | Removes legacy config model. |
| SteelSeriesAPI/Sonar/Models/RoutedProcess.cs | Removes legacy routed-process model (replaced by routing/session models). |
| SteelSeriesAPI/Sonar/Models/Redirections.cs | Adds classic/stream redirection models. |
| SteelSeriesAPI/Sonar/Models/PlaybackDevice.cs | Removes legacy playback-device model. |
| SteelSeriesAPI/Sonar/Models/ChatMixSetting.cs | Adds chat-mix state model. |
| SteelSeriesAPI/Sonar/Models/AudioDevice.cs | Adds audio device model (physical + Sonar virtual). |
| SteelSeriesAPI/Sonar/Models/AppRouting.cs | Adds routing/session models (AudioSessionInfo, DeviceRouting). |
| SteelSeriesAPI/Sonar/Managers/VolumeSettingsManager.cs | Rewritten manager to async transport-based operations + validation + tolerant parsing. |
| SteelSeriesAPI/Sonar/Managers/RoutedProcessManager.cs | Removes legacy routed-process manager. |
| SteelSeriesAPI/Sonar/Managers/RedirectionsManager.cs | New async manager for classic/stream redirections + monitoring. |
| SteelSeriesAPI/Sonar/Managers/ModeManager.cs | Rewritten async mode manager with confirmed switch polling + typed errors. |
| SteelSeriesAPI/Sonar/Managers/MixManager.cs | Removes legacy mix toggle manager (covered under redirections in v2). |
| SteelSeriesAPI/Sonar/Managers/IVolumeSettingsManager.cs | New public async interface for volume/mute operations. |
| SteelSeriesAPI/Sonar/Managers/IRedirectionsManager.cs | New public async interface for redirection operations. |
| SteelSeriesAPI/Sonar/Managers/IModeManager.cs | New public async interface for mode operations. |
| SteelSeriesAPI/Sonar/Managers/IConfigManager.cs | New public async interface for config operations. |
| SteelSeriesAPI/Sonar/Managers/IChatMixManager.cs | New public async interface for chat-mix operations. |
| SteelSeriesAPI/Sonar/Managers/IAudioDeviceManager.cs | New public async interface for audio-device operations. |
| SteelSeriesAPI/Sonar/Managers/IAppRoutingManager.cs | New public async interface for app routing operations. |
| SteelSeriesAPI/Sonar/Managers/EventManager.cs | Removes legacy event manager (replaced by SonarEventListener). |
| SteelSeriesAPI/Sonar/Managers/ConfigurationManager.cs | Removes legacy configuration manager (replaced by ConfigManager). |
| SteelSeriesAPI/Sonar/Managers/ConfigManager.cs | New async manager for listing/selecting configs with header-only parsing. |
| SteelSeriesAPI/Sonar/Managers/ChatMixManager.cs | Rewritten async chat-mix manager using /v1/chatMix + validation. |
| SteelSeriesAPI/Sonar/Managers/AudioDeviceManager.cs | New async manager for parsing/listing devices. |
| SteelSeriesAPI/Sonar/Managers/AudienceMonitoringManager.cs | Removes legacy audience monitoring manager (folded into redirections). |
| SteelSeriesAPI/Sonar/Managers/AppRoutingManager.cs | New async manager for parsing routing state and routing apps. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IVolumeSettingsManager.cs | Removes legacy sync manager interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IRoutedProcessManager.cs | Removes legacy routed-process interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IPlaybackDeviceManager.cs | Removes legacy playback-device interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IModeManager.cs | Removes legacy sync mode interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IMixManager.cs | Removes legacy mix interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IConfigurationManager.cs | Removes legacy config interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IChatMixManager.cs | Removes legacy chat-mix interface. |
| SteelSeriesAPI/Sonar/Interfaces/Managers/IAudienceMonitoringManager.cs | Removes legacy audience-monitoring interface. |
| SteelSeriesAPI/Sonar/Interfaces/ISonarSocket.cs | Removes legacy socket abstraction. |
| SteelSeriesAPI/Sonar/Interfaces/ISonarBridge.cs | Removes legacy bridge abstraction. |
| SteelSeriesAPI/Sonar/Http/Fetcher.cs | Removes legacy HTTP wrapper (replaced by SonarHttpClient + ISonarTransport). |
| SteelSeriesAPI/Sonar/Exceptions/SonarNotRunningException.cs | Removes legacy exception (replaced by core exception taxonomy). |
| SteelSeriesAPI/Sonar/Exceptions/SonarListenerNotConnectedException.cs | Removes legacy listener exception. |
| SteelSeriesAPI/Sonar/Exceptions/RoutedProcessNotFoundException.cs | Removes legacy routed-process exception. |
| SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceNotFoundException.cs | Removes legacy playback-device exception. |
| SteelSeriesAPI/Sonar/Exceptions/PlaybackDeviceDataFlowException.cs | Removes legacy playback-device dataflow exception. |
| SteelSeriesAPI/Sonar/Exceptions/MixNotFoundException.cs | Removes legacy mix exception. |
| SteelSeriesAPI/Sonar/Exceptions/MasterChannelNotSupportedException.cs | Removes legacy master-channel exception. |
| SteelSeriesAPI/Sonar/Exceptions/ConfigNotFoundException.cs | Removes legacy config exception. |
| SteelSeriesAPI/Sonar/Exceptions/ChatMixDisabledException.cs | Removes legacy chat-mix disabled exception. |
| SteelSeriesAPI/Sonar/Exceptions/ChatMixBalanceException.cs | Removes legacy chat-mix balance exception. |
| SteelSeriesAPI/Sonar/Exceptions/ChannelNotFoundException.cs | Removes legacy channel-not-found exception. |
| SteelSeriesAPI/Sonar/Exceptions/ChannelNoStreamerSupportException.cs | Removes legacy channel streamer support exception. |
| SteelSeriesAPI/Sonar/Events/VolumeSnapshot.cs | Adds typed snapshot models (VolumeSnapshot, ChannelVolumes, unknown event wrapper). |
| SteelSeriesAPI/Sonar/Events/VolumeChange.cs | Adds typed granular volume change event model. |
| SteelSeriesAPI/Sonar/Events/SonarVolumeEvent.cs | Removes legacy volume event args type. |
| SteelSeriesAPI/Sonar/Events/SonarRoutedProcessEvent.cs | Removes legacy routed-process event args type. |
| SteelSeriesAPI/Sonar/Events/SonarPlaybackDeviceEvent.cs | Removes legacy playback device event args type. |
| SteelSeriesAPI/Sonar/Events/SonarMuteEvent.cs | Removes legacy mute event args type. |
| SteelSeriesAPI/Sonar/Events/SonarModeEvent.cs | Removes legacy mode event args type. |
| SteelSeriesAPI/Sonar/Events/SonarMixEvent.cs | Removes legacy mix event args type. |
| SteelSeriesAPI/Sonar/Events/SonarEventNames.cs | Centralizes WebSocket event-name catalog. |
| SteelSeriesAPI/Sonar/Events/SonarConfigEvent.cs | Removes legacy config event args type. |
| SteelSeriesAPI/Sonar/Events/SonarChatMixEvent.cs | Removes legacy chat-mix event args type. |
| SteelSeriesAPI/Sonar/Events/SonarAudienceMonitoringEvent.cs | Removes legacy audience monitoring event args type. |
| SteelSeriesAPI/Sonar/Events/RedirectionChanges.cs | Adds typed redirection diff/change event models. |
| SteelSeriesAPI/Sonar/Events/ModeChange.cs | Adds typed mode change event model. |
| SteelSeriesAPI/Sonar/Events/Listener/SonarEventListener.Volumes.cs | Adds polling-based mode+volume diffing + events. |
| SteelSeriesAPI/Sonar/Events/Listener/SonarEventListener.Redirections.cs | Adds hybrid invalidation+polling redirection refresh + diffs. |
| SteelSeriesAPI/Sonar/Events/Listener/SonarEventListener.Configs.cs | Adds hybrid invalidation+polling selected-config refresh + diffs. |
| SteelSeriesAPI/Sonar/Events/Listener/DebouncedRefresher.cs | Adds debounced refresh utility for invalidation bursts. |
| SteelSeriesAPI/Sonar/Events/ConfigSelectionChange.cs | Adds typed config selection change event model. |
| SteelSeriesAPI/Sonar/Enums/RoutedProcessState.cs | Removes legacy routed-process state enum. |
| SteelSeriesAPI/Sonar/Enums/Mode.cs | Reworks mode enum naming + mapping helpers. |
| SteelSeriesAPI/Sonar/Enums/Mix.cs | Reworks mix enum naming + mapping helpers. |
| SteelSeriesAPI/Sonar/Enums/DataFlow.cs | Removes legacy dataflow enum (replaced by AudioDataFlow). |
| SteelSeriesAPI/Sonar/Enums/Channel.cs | Reworks channel enum naming + mapping helpers (JSON/route/redirection vocabularies). |
| SteelSeriesAPI/Sonar/Enums/AudioDataFlow.cs | Adds new dataflow enum (Render/Capture). |
| SteelSeriesAPI/Interfaces/ISteelSeriesRetriever.cs | Removes legacy retriever interface. |
| SteelSeriesAPI/Interfaces/IAppRetriever.cs | Removes legacy app retriever interface. |
| SteelSeriesAPI/Exceptions/SteelSeriesNotRunningException.cs | Removes legacy exception (replaced by core taxonomy). |
| SteelSeriesAPI/Core/SonarHttpClient.cs | Adds resilient transport with rediscovery-on-failure and typed error mapping. |
| SteelSeriesAPI/Core/SonarExceptions.cs | Adds unified exception taxonomy rooted at SteelSeriesException. |
| SteelSeriesAPI/Core/ServerDiscovery.cs | Adds discovery via coreProps.json + GG /subApps query. |
| SteelSeriesAPI/Core/JsonExtensions.cs | Adds tolerant JSON navigation/helpers used across parsers. |
| SteelSeriesAPI/Core/ISonarTransport.cs | Adds low-level transport abstraction for managers + tests. |
| SteelSeriesAPI.Tests/VolumeSettingsManagerTests.cs | Adds xUnit coverage for volume parsing + route formatting + validation. |
| SteelSeriesAPI.Tests/SteelSeriesAPI.Tests.csproj | Updates test project targeting and adds test/coverage packages. |
| SteelSeriesAPI.Tests/SonarEventListenerTests.cs | Adds tests for event parsing + snapshot parsing + diff behavior. |
| SteelSeriesAPI.Tests/ServerDiscoveryTests.cs | Adds discovery JSON parsing tests + regressions. |
| SteelSeriesAPI.Tests/RedirectionsManagerTests.cs | Adds tests for redirection parsing + route building. |
| SteelSeriesAPI.Tests/Program.cs | Removes legacy manual test console program from tests project. |
| SteelSeriesAPI.Tests/ModeManagerTests.cs | Adds tests for mode parsing + confirmed set behavior. |
| SteelSeriesAPI.Tests/FakeTransport.cs | Adds canned-response transport for unit tests. |
| SteelSeriesAPI.Tests/ConfigManagerTests.cs | Adds tests for config listing/selection parsing + route building. |
| SteelSeriesAPI.Tests/ChatMixManagerTests.cs | Adds tests for chat mix parsing + validation + route building. |
| SteelSeriesAPI.Tests/AudioDeviceManagerTests.cs | Adds tests for audio device parsing/filtering behavior. |
| SteelSeriesAPI.Tests/AppRoutingManagerTests.cs | Adds tests for routing parsing + route building + channel resolution behavior. |
| SteelSeriesAPI.Sample/SteelSeriesAPI.Sample.csproj | Updates sample targeting and adds console logging dependency. |
| SteelSeriesAPI.Explorer/SteelSeriesAPI.Explorer.csproj | Adds new Explorer tool project for probing/verifying Sonar routes. |
| SteelSeriesAPI.Explorer/reference-shapes/volumeSettings_streamer.shape.json | Adds reference structure for streamer volume settings payload. |
| SteelSeriesAPI.Explorer/reference-shapes/volumeSettings_classic.shape.json | Adds reference structure for classic volume settings payload. |
| SteelSeriesAPI.Explorer/reference-shapes/v1_chatMix.shape.json | Adds reference structure for chat mix payload. |
| SteelSeriesAPI.Explorer/reference-shapes/streamRedirections.shape.json | Adds reference structure for stream redirections payload. |
| SteelSeriesAPI.Explorer/reference-shapes/streamRedirections_isStreamMonitoringEnabled.shape.json | Adds reference structure for monitoring-enabled payload. |
| SteelSeriesAPI.Explorer/reference-shapes/mode.shape.json | Adds reference structure for mode payload. |
| SteelSeriesAPI.Explorer/reference-shapes/classicRedirections.shape.json | Adds reference structure for classic redirections payload. |
| SteelSeriesAPI.Explorer/reference-shapes/audioDevices.shape.json | Adds reference structure for audio devices payload. |
| SteelSeriesAPI.Explorer/reference-shapes/AudioDeviceRouting.shape.json | Adds reference structure for device routing payload. |
| SteelSeries-NET-API.sln | Updates solution structure/guids and adds Explorer project. |
| README.md | Rewrites docs for v2 API usage, events, migration guidance, and contributor pointers. |
| global.json | Removes SDK roll-forward pinning configuration. |
| docs/CONTRIBUTING.md | Adds contributor guide + Explorer workflow + post-GG-update checklist. |
| docs/ARCHITECTURE.md | Adds architecture doc detailing layers, event mechanisms, and Sonar API lessons. |
| .github/workflows/ci.yml | Adds CI pipeline for restore/build/test on net8 + net10. |
Review details
Suppressed comments (2)
SteelSeriesAPI/Core/ServerDiscovery.cs:80
ServerDiscovery.ParseSonarAddresscallsJsonDocument.Parsewithout handling malformed JSON; aJsonExceptionwould escape the library’s exception taxonomy. CatchJsonExceptionand rethrow aDiscoveryException(withInnerException) so callers can handle discovery failures consistently.
SteelSeriesAPI/Core/SonarHttpClient.cs:84- On non-success HTTP responses,
SendAsyncthrows without disposing theHttpResponseMessage. This leaks the response/content resources on every error path (e.g., wrong mode, 404, 500). Dispose the response before throwing.
- Files reviewed: 125/126 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| public async Task<JsonDocument> GetAsync(string route, CancellationToken ct = default) | ||
| { | ||
| using var response = await SendAsync(HttpMethod.Get, route, ct); | ||
| await using var stream = await response.Content.ReadAsStreamAsync(ct); | ||
| return await JsonDocument.ParseAsync(stream, cancellationToken: ct); | ||
| } |
| Uri baseAddress = await GetBaseAddressAsync(ct); | ||
| var request = new HttpRequestMessage(method, new Uri(baseAddress, route)); |
| if (!File.Exists(_corePropsPath)) | ||
| throw new SteelSeriesNotFoundException( | ||
| $"coreProps.json not found at '{_corePropsPath}'. Is SteelSeries GG installed and running?"); | ||
|
|
||
| using var coreProps = JsonDocument.Parse(File.ReadAllText(_corePropsPath)); | ||
|
|
Full rewrite of the lib, for better performances and stability