1
0
mirror of https://github.com/DarthAffe/RGB.NET.git synced 2026-06-24 02:27:01 +00:00
RGB.NET/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
Danielle 9271b442c2 Added more SteelSeries devices
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 18:10:49 +10:00

201 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using RGB.NET.Core;
using RGB.NET.Devices.SteelSeries.API;
using RGB.NET.HID;
namespace RGB.NET.Devices.SteelSeries;
/// <inheritdoc />
/// <summary>
/// Represents a device provider responsible for SteelSeries-devices.
/// </summary>
public sealed class SteelSeriesDeviceProvider : AbstractRGBDeviceProvider
{
#region Constants
private const int HEARTBEAT_TIMER = 5000; // flush the device every 5 seconds to prevent timeouts
#endregion
#region Properties & Fields
// ReSharper disable once InconsistentNaming
private static readonly Lock _lock = new();
private static SteelSeriesDeviceProvider? _instance;
/// <summary>
/// Gets the singleton <see cref="SteelSeriesDeviceProvider"/> instance.
/// </summary>
public static SteelSeriesDeviceProvider Instance
{
get
{
lock (_lock)
return _instance ?? new SteelSeriesDeviceProvider();
}
}
private const int VENDOR_ID = 0x1038;
/// <summary>
/// Gets the HID-definitions for SteelSeries-devices.
/// </summary>
public static HIDLoader<SteelSeriesLedId, SteelSeriesDeviceType> DeviceDefinitions { get; } = new(VENDOR_ID)
{
//Mice
{ 0x1836, RGBDeviceType.Mouse, "Aerox 3", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x183A, RGBDeviceType.Mouse, "Aerox 3 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1858, RGBDeviceType.Mouse, "Aerox 9 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1702, RGBDeviceType.Mouse, "Rival 100", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone },
{ 0x1814, RGBDeviceType.Mouse, "Rival 105", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone },
{ 0x1816, RGBDeviceType.Mouse, "Rival 106", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone },
{ 0x1729, RGBDeviceType.Mouse, "Rival 110", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone },
{ 0x0472, RGBDeviceType.Mouse, "Rival 150", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone },
{ 0x1710, RGBDeviceType.Mouse, "Rival 300", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1720, RGBDeviceType.Mouse, "Rival 310", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1722, RGBDeviceType.Mouse, "Sensei 310", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x170E, RGBDeviceType.Mouse, "Rival 500", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1724, RGBDeviceType.Mouse, "Rival 600", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone },
{ 0x1726, RGBDeviceType.Mouse, "Rival 650", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone },
{ 0x172B, RGBDeviceType.Mouse, "Rival 650", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone },
{ 0x1700, RGBDeviceType.Mouse, "Rival 700", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1824, RGBDeviceType.Mouse, "Rival 3 (Old Firmware)", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x184C, RGBDeviceType.Mouse, "Rival 3", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1830, RGBDeviceType.Mouse, "Rival 3 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1832, RGBDeviceType.Mouse, "Sensei Ten", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1838, RGBDeviceType.Mouse, "Aerox 3 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x183C, RGBDeviceType.Mouse, "Rival 5", LedMappings.MouseTenZone, SteelSeriesDeviceType.TenZone },
{ 0x1854, RGBDeviceType.Mouse, "Aerox 5 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1852, RGBDeviceType.Mouse, "Aerox 5 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1850, RGBDeviceType.Mouse, "Aerox 5 Wired", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x185A, RGBDeviceType.Mouse, "Aerox 9 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1878, RGBDeviceType.Mouse, "Aerox 3 CS2 Dragon Lore Edition", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x187A, RGBDeviceType.Mouse, "Aerox 3 CS2 Dragon Lore Edition", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x185C, RGBDeviceType.Mouse, "Aerox 5 Destiny 2 Edition", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x185E, RGBDeviceType.Mouse, "Aerox 5 Destiny 2 Edition", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1860, RGBDeviceType.Mouse, "Aerox 5 Diablo IV Edition", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1862, RGBDeviceType.Mouse, "Aerox 5 Diablo IV Edition", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone },
{ 0x1730, RGBDeviceType.Mouse, "Rival 710", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x172E, RGBDeviceType.Mouse, "Rival 600 Dota 2 Edition", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone },
{ 0x1834, RGBDeviceType.Mouse, "Sensei Ten CS:GO Neon Rider Edition", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone },
//Keyboards
{ 0x161A, RGBDeviceType.Keyboard, "Apex 3", LedMappings.KeyboardTenZone, SteelSeriesDeviceType.TenZone },
{ 0x161C, RGBDeviceType.Keyboard, "Apex 5", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1612, RGBDeviceType.Keyboard, "Apex 7", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1618, RGBDeviceType.Keyboard, "Apex 7 TKL", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x0616, RGBDeviceType.Keyboard, "Apex M750", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1600, RGBDeviceType.Keyboard, "Apex M800", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1610, RGBDeviceType.Keyboard, "Apex Pro", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1614, RGBDeviceType.Keyboard, "Apex Pro TKL", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1628, RGBDeviceType.Keyboard, "Apex Pro TKL 2023", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1644, RGBDeviceType.Keyboard, "Apex Pro TKL Wireless Gen3", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1630, RGBDeviceType.Keyboard, "Apex Pro TKL", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey }, // DarthAffe 27.05.2024: This could be a generic wireless connector
{ 0x1640, RGBDeviceType.Keyboard, "Apex Pro 3", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x2036, RGBDeviceType.Keyboard, "MSI Notebook", LedMappings.KeyboardNotebookMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x113A, RGBDeviceType.Keyboard, "MSI GE78HX", LedMappings.KeyboardMSIGE78Mapping, SteelSeriesDeviceType.PerKey },
{ 0x1122, RGBDeviceType.Keyboard, "MSI Notebook", LedMappings.KeyboardNotebookMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1622, RGBDeviceType.Keyboard, "Apex 3 TKL", LedMappings.KeyboardTenZone, SteelSeriesDeviceType.TenZone },
{ 0x1620, RGBDeviceType.Keyboard, "Apex 9 Mini", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1634, RGBDeviceType.Keyboard, "Apex 9 TKL", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1642, RGBDeviceType.Keyboard, "Apex Pro TKL Gen 3", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1646, RGBDeviceType.Keyboard, "Apex Pro TKL Gen 3 Wireless", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
{ 0x1632, RGBDeviceType.Keyboard, "Apex Pro TKL 2023 Wireless", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey },
//Headsets
{ 0x12AA, RGBDeviceType.Headset, "Arctis 5", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1250, RGBDeviceType.Headset, "Arctis 5 Game", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1251, RGBDeviceType.Headset, "Arctis 5 Game - Dota 2 edition", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x12A8, RGBDeviceType.Headset, "Arctis 5 Game - PUBG edition", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1252, RGBDeviceType.Headset, "Arctis Pro Game", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone },
//Mousepads
{ 0x1507, RGBDeviceType.Mousepad, "QCK Prism", LedMappings.MousepadTwelveZone, SteelSeriesDeviceType.TwelveZone },
{ 0x150D, RGBDeviceType.Mousepad, "QCK Prism Cloth", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1516, RGBDeviceType.Mousepad, "QCK Prism Cloth 3XL", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x150A, RGBDeviceType.Mousepad, "QCK Prism Cloth Medium", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1518, RGBDeviceType.Mousepad, "QCK Prism Cloth 4XL", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x151A, RGBDeviceType.Mousepad, "QCK Prism Cloth 5XL", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x151E, RGBDeviceType.Mousepad, "QCK Prism Cloth XL Destiny Edition", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1520, RGBDeviceType.Mousepad, "QCK Prism Cloth XL Destiny 2 Lightfall Edition", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x1514, RGBDeviceType.Mousepad, "QCK Prism Cloth XL CS:GO Neon Rider Edition", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
{ 0x151C, RGBDeviceType.Mousepad, "QCK Prism Cloth XL CS:GO Neo Noir Edition", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone },
//Monitors
{ 0x1126, RGBDeviceType.Monitor, "MGP27C", LedMappings.MonitorOnehundredandthreeZone, SteelSeriesDeviceType.OneHundredAndThreeZone },
//Speaker
{ 0x1A05, RGBDeviceType.Speaker, "Arena 9", LedMappings.SpeakerFourZone, SteelSeriesDeviceType.FourZone },
};
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="SteelSeriesDeviceProvider"/> class.
/// </summary>
/// <exception cref="InvalidOperationException">Thrown if this constructor is called even if there is already an instance of this class.</exception>
public SteelSeriesDeviceProvider()
{
lock (_lock)
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SteelSeriesDeviceProvider)}");
_instance = this;
}
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeSDK()
{
if (!SteelSeriesSDK.IsInitialized)
SteelSeriesSDK.Initialize();
}
/// <inheritdoc />
protected override IEnumerable<IRGBDevice> GetLoadedDevices(RGBDeviceType loadFilter)
{
DeviceDefinitions.LoadFilter = loadFilter;
return base.GetLoadedDevices(loadFilter);
}
/// <inheritdoc />
protected override IEnumerable<IRGBDevice> LoadDevices()
{
foreach ((HIDDeviceDefinition<SteelSeriesLedId, SteelSeriesDeviceType> definition, _) in DeviceDefinitions.GetConnectedDevices(x => x.CustomData))
{
string? apiName = definition.CustomData.GetAPIName();
if (apiName == null)
Throw(new RGBDeviceException($"Missing API-name for device {definition.Name}"));
else
yield return new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(definition.DeviceType, definition.Name, definition.CustomData), apiName, definition.LedMapping, GetUpdateTrigger());
}
}
/// <inheritdoc />
protected override IDeviceUpdateTrigger CreateUpdateTrigger(int id, double updateRateHardLimit) => new DeviceUpdateTrigger(updateRateHardLimit) { HeartbeatTimer = HEARTBEAT_TIMER };
/// <inheritdoc />
protected override void Dispose(bool disposing)
{
lock (_lock)
{
base.Dispose(disposing);
try { SteelSeriesSDK.Dispose(); }
catch { /* shit happens */ }
_instance = null;
}
}
#endregion
}