| @@ -0,0 +1,12 @@ | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API.Rpc | |||||
| { | |||||
| public class VoiceDevice | |||||
| { | |||||
| [JsonProperty("id")] | |||||
| public string Id { get; set; } | |||||
| [JsonProperty("name")] | |||||
| public string Name { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API.Rpc | |||||
| { | |||||
| public class VoiceDeviceSettings | |||||
| { | |||||
| [JsonProperty("device_id")] | |||||
| public string DeviceId { get; set; } | |||||
| [JsonProperty("volume")] | |||||
| public float Volume { get; set; } | |||||
| [JsonProperty("available_devices")] | |||||
| public VoiceDevice[] AvailableDevices { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API.Rpc | |||||
| { | |||||
| public class VoiceMode | |||||
| { | |||||
| [JsonProperty("type")] | |||||
| public string Type { get; set; } | |||||
| [JsonProperty("auto_threshold")] | |||||
| public bool AutoThreshold { get; set; } | |||||
| [JsonProperty("threshold")] | |||||
| public float Threshold { get; set; } | |||||
| [JsonProperty("shortcut")] | |||||
| public VoiceShortcut[] Shortcut { get; set; } | |||||
| [JsonProperty("delay")] | |||||
| public float Delay { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| #pragma warning disable CS1591 | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API.Rpc | |||||
| { | |||||
| public class VoiceSettings | |||||
| { | |||||
| [JsonProperty("input")] | |||||
| public VoiceDeviceSettings Input { get; set; } | |||||
| [JsonProperty("output")] | |||||
| public VoiceDeviceSettings Output { get; set; } | |||||
| [JsonProperty("mode")] | |||||
| public VoiceMode Mode { get; set; } | |||||
| [JsonProperty("automatic_gain_control")] | |||||
| public bool AutomaticGainControl { get; set; } | |||||
| [JsonProperty("echo_cancellation")] | |||||
| public bool EchoCancellation { get; set; } | |||||
| [JsonProperty("noise_suppression")] | |||||
| public bool NoiseSuppression { get; set; } | |||||
| [JsonProperty("qos")] | |||||
| public bool QualityOfService { get; set; } | |||||
| [JsonProperty("silence_warning")] | |||||
| public bool SilenceWarning { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,15 @@ | |||||
| using Discord.Rpc; | |||||
| using Newtonsoft.Json; | |||||
| namespace Discord.API.Rpc | |||||
| { | |||||
| public class VoiceShortcut | |||||
| { | |||||
| [JsonProperty("type")] | |||||
| public VoiceShortcutType Type { get; set; } | |||||
| [JsonProperty("code")] | |||||
| public int Code { get; set; } | |||||
| [JsonProperty("name")] | |||||
| public string Name { get; set; } | |||||
| } | |||||
| } | |||||
| @@ -82,6 +82,13 @@ namespace Discord.Rpc | |||||
| } | } | ||||
| private readonly AsyncEvent<Func<ulong, Task>> _speakingStoppedEvent = new AsyncEvent<Func<ulong, Task>>(); | private readonly AsyncEvent<Func<ulong, Task>> _speakingStoppedEvent = new AsyncEvent<Func<ulong, Task>>(); | ||||
| public event Func<VoiceSettings, Task> VoiceSettingsUpdated | |||||
| { | |||||
| add { _voiceSettingsUpdated.Add(value); } | |||||
| remove { _voiceSettingsUpdated.Remove(value); } | |||||
| } | |||||
| private readonly AsyncEvent<Func<VoiceSettings, Task>> _voiceSettingsUpdated = new AsyncEvent<Func<VoiceSettings, Task>>(); | |||||
| //Messages | //Messages | ||||
| public event Func<RpcMessage, Task> MessageReceived | public event Func<RpcMessage, Task> MessageReceived | ||||
| { | { | ||||
| @@ -271,6 +271,7 @@ namespace Discord.Rpc | |||||
| { | { | ||||
| case RpcGlobalEvent.ChannelCreated: return "CHANNEL_CREATE"; | case RpcGlobalEvent.ChannelCreated: return "CHANNEL_CREATE"; | ||||
| case RpcGlobalEvent.GuildCreated: return "GUILD_CREATE"; | case RpcGlobalEvent.GuildCreated: return "GUILD_CREATE"; | ||||
| case RpcGlobalEvent.VoiceSettingsUpdated: return "VOICE_SETTINGS_UPDATE"; | |||||
| default: | default: | ||||
| throw new InvalidOperationException($"Unknown RPC Global Event: {rpcEvent}"); | throw new InvalidOperationException($"Unknown RPC Global Event: {rpcEvent}"); | ||||
| } | } | ||||
| @@ -419,6 +420,15 @@ namespace Discord.Rpc | |||||
| await _speakingStoppedEvent.InvokeAsync(data.UserId).ConfigureAwait(false); | await _speakingStoppedEvent.InvokeAsync(data.UserId).ConfigureAwait(false); | ||||
| } | } | ||||
| break; | break; | ||||
| case "VOICE_SETTINGS_UPDATE": | |||||
| { | |||||
| await _rpcLogger.DebugAsync("Received Dispatch (VOICE_SETTINGS_UPDATE)").ConfigureAwait(false); | |||||
| var data = (payload.Value as JToken).ToObject<API.Rpc.VoiceSettings>(_serializer); | |||||
| var settings = VoiceSettings.Create(data); | |||||
| await _voiceSettingsUpdated.InvokeAsync(settings).ConfigureAwait(false); | |||||
| } | |||||
| break; | |||||
| //Messages | //Messages | ||||
| case "MESSAGE_CREATE": | case "MESSAGE_CREATE": | ||||
| @@ -0,0 +1,20 @@ | |||||
| using Model = Discord.API.Rpc.VoiceDevice; | |||||
| namespace Discord.Rpc | |||||
| { | |||||
| public struct VoiceDevice | |||||
| { | |||||
| public string Id { get; } | |||||
| public string Name { get; } | |||||
| internal VoiceDevice(string id, string name) | |||||
| { | |||||
| Id = id; | |||||
| Name = name; | |||||
| } | |||||
| internal static VoiceDevice Create(Model model) | |||||
| { | |||||
| return new VoiceDevice(model.Id, model.Name); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,60 @@ | |||||
| using System.Collections.Generic; | |||||
| using System.Collections.Immutable; | |||||
| using System.Linq; | |||||
| using Model = Discord.API.Rpc.VoiceSettings; | |||||
| namespace Discord.Rpc | |||||
| { | |||||
| public class VoiceSettings | |||||
| { | |||||
| public string InputDeviceId { get; private set; } | |||||
| public float InputVolume { get; private set; } | |||||
| public IReadOnlyCollection<VoiceDevice> AvailableInputDevices { get; private set; } | |||||
| public string OutputDeviceId { get; private set; } | |||||
| public float OutputVolume { get; private set; } | |||||
| public IReadOnlyCollection<VoiceDevice> AvailableOutputDevices { get; private set; } | |||||
| public bool AutomaticGainControl { get; private set; } | |||||
| public bool EchoCancellation { get; private set; } | |||||
| public bool NoiseSuppression { get; private set; } | |||||
| public bool QualityOfService { get; private set; } | |||||
| public bool SilenceWarning { get; private set; } | |||||
| public string ActivationMode { get; private set; } | |||||
| public bool AutoThreshold { get; private set; } | |||||
| public float Threshold { get; private set; } | |||||
| public IReadOnlyCollection<VoiceShortcut> Shortcuts { get; private set; } | |||||
| public float Delay { get; private set; } | |||||
| internal VoiceSettings() { } | |||||
| internal static VoiceSettings Create(Model model) | |||||
| { | |||||
| var entity = new VoiceSettings(); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | |||||
| AutomaticGainControl = model.AutomaticGainControl; | |||||
| EchoCancellation = model.EchoCancellation; | |||||
| NoiseSuppression = model.NoiseSuppression; | |||||
| QualityOfService = model.QualityOfService; | |||||
| SilenceWarning = model.SilenceWarning; | |||||
| InputDeviceId = model.Input.DeviceId; | |||||
| InputVolume = model.Input.Volume; | |||||
| AvailableInputDevices = model.Input.AvailableDevices.Select(x => VoiceDevice.Create(x)).ToImmutableArray(); | |||||
| OutputDeviceId = model.Output.DeviceId; | |||||
| OutputVolume = model.Output.Volume; | |||||
| AvailableInputDevices = model.Output.AvailableDevices.Select(x => VoiceDevice.Create(x)).ToImmutableArray(); | |||||
| ActivationMode = model.Mode.Type; | |||||
| AutoThreshold = model.Mode.AutoThreshold; | |||||
| Threshold = model.Mode.Threshold; | |||||
| Shortcuts = model.Mode.Shortcut.Select(x => VoiceShortcut.Create(x)).ToImmutableArray(); | |||||
| Delay = model.Mode.Delay; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| using Model = Discord.API.Rpc.VoiceShortcut; | |||||
| namespace Discord.Rpc | |||||
| { | |||||
| public struct VoiceShortcut | |||||
| { | |||||
| public VoiceShortcutType Type { get; } | |||||
| public int Code { get; } | |||||
| public string Name { get; } | |||||
| internal VoiceShortcut(VoiceShortcutType type, int code, string name) | |||||
| { | |||||
| Type = type; | |||||
| Code = code; | |||||
| Name = name; | |||||
| } | |||||
| internal static VoiceShortcut Create(Model model) | |||||
| { | |||||
| return new VoiceShortcut(model.Type, model.Code, model.Name); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,10 @@ | |||||
| namespace Discord.Rpc | |||||
| { | |||||
| public enum VoiceShortcutType | |||||
| { | |||||
| KeyboardKey = 0, | |||||
| MouseButton = 1, | |||||
| KeyboardModifierKey = 2, | |||||
| GamepadButton = 3 | |||||
| } | |||||
| } | |||||
| @@ -3,6 +3,7 @@ | |||||
| public enum RpcGlobalEvent | public enum RpcGlobalEvent | ||||
| { | { | ||||
| ChannelCreated, | ChannelCreated, | ||||
| GuildCreated | |||||
| GuildCreated, | |||||
| VoiceSettingsUpdated | |||||
| } | } | ||||
| } | } | ||||