[Feature] Voice channel status support (#2777)
* initial commit * MOCKED CHANNELS AGRHHHHHHHH * fix for sharded * yup
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Discord.API.Gateway;
|
||||
|
||||
internal class VoiceChannelStatusUpdateEvent
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
public ulong Id { get; set; }
|
||||
|
||||
[JsonProperty("guild_id")]
|
||||
public ulong GuildId { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
}
|
||||
@@ -76,6 +76,22 @@ namespace Discord.WebSocket
|
||||
remove { _channelUpdatedEvent.Remove(value); }
|
||||
}
|
||||
internal readonly AsyncEvent<Func<SocketChannel, SocketChannel, Task>> _channelUpdatedEvent = new AsyncEvent<Func<SocketChannel, SocketChannel, Task>>();
|
||||
|
||||
/// <summary>
|
||||
/// Fired when status of a voice channel is updated.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The previous state of the channel is passed into the first parameter; the updated channel is passed into the second one.
|
||||
/// </remarks>
|
||||
public event Func<Cacheable<SocketVoiceChannel, ulong>, string, string, Task> VoiceChannelStatusUpdated
|
||||
{
|
||||
add { _voiceChannelStatusUpdated.Add(value); }
|
||||
remove { _voiceChannelStatusUpdated.Remove(value); }
|
||||
}
|
||||
|
||||
internal readonly AsyncEvent<Func<Cacheable<SocketVoiceChannel, ulong>, string, string, Task>> _voiceChannelStatusUpdated = new();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Messages
|
||||
|
||||
@@ -519,6 +519,8 @@ namespace Discord.WebSocket
|
||||
client.WebhooksUpdated += (arg1, arg2) => _webhooksUpdated.InvokeAsync(arg1, arg2);
|
||||
client.AuditLogCreated += (arg1, arg2) => _auditLogCreated.InvokeAsync(arg1, arg2);
|
||||
|
||||
client.VoiceChannelStatusUpdated += (arg1, arg2, arg3) => _voiceChannelStatusUpdated.InvokeAsync(arg1, arg2, arg3);
|
||||
|
||||
client.EntitlementCreated += (arg1) => _entitlementCreated.InvokeAsync(arg1);
|
||||
client.EntitlementUpdated += (arg1, arg2) => _entitlementUpdated.InvokeAsync(arg1, arg2);
|
||||
client.EntitlementDeleted += (arg1) => _entitlementDeleted.InvokeAsync(arg1);
|
||||
|
||||
@@ -2333,6 +2333,24 @@ namespace Discord.WebSocket
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case "VOICE_CHANNEL_STATUS_UPDATE":
|
||||
{
|
||||
await _gatewayLogger.DebugAsync("Received Dispatch (VOICE_CHANNEL_STATUS_UPDATE)").ConfigureAwait(false);
|
||||
|
||||
var data = (payload as JToken).ToObject<VoiceChannelStatusUpdateEvent>(_serializer);
|
||||
var guild = State.GetGuild(data.GuildId);
|
||||
|
||||
var channel = State.GetChannel(data.Id) as SocketVoiceChannel;
|
||||
var channelCacheable = new Cacheable<SocketVoiceChannel, ulong>(channel, data.Id, channel is not null, () => null);
|
||||
|
||||
var before = (string)channel?.Status?.Clone();
|
||||
var after = data.Status;
|
||||
channel?.UpdateVoiceStatus(data.Status);
|
||||
|
||||
await TimedInvokeAsync(_voiceChannelStatusUpdated, nameof(VoiceChannelStatusUpdated), channelCacheable, before, after);
|
||||
}
|
||||
break;
|
||||
#endregion
|
||||
|
||||
#region Invites
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLog;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a voice channel status delete.
|
||||
/// </summary>
|
||||
public class SocketVoiceChannelStatusDeleteAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketVoiceChannelStatusDeleteAuditLogData(ulong channelId)
|
||||
{
|
||||
ChannelId = channelId;
|
||||
}
|
||||
|
||||
internal static SocketVoiceChannelStatusDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new (entry.TargetId!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the id of the channel status was removed in.
|
||||
/// </summary>
|
||||
public ulong ChannelId { get; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using EntryModel = Discord.API.AuditLogEntry;
|
||||
using Model = Discord.API.AuditLog;
|
||||
|
||||
namespace Discord.WebSocket;
|
||||
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a voice channel status update.
|
||||
/// </summary>
|
||||
public class SocketVoiceChannelStatusUpdatedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketVoiceChannelStatusUpdatedAuditLogData(string status, ulong channelId)
|
||||
{
|
||||
Status = status;
|
||||
ChannelId = channelId;
|
||||
}
|
||||
|
||||
internal static SocketVoiceChannelStatusUpdatedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
return new (entry.Options.Status, entry.TargetId!.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status that was set in the voice channel.
|
||||
/// </summary>
|
||||
public string Status { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the id of the channel status was updated in.
|
||||
/// </summary>
|
||||
public ulong ChannelId { get; }
|
||||
}
|
||||
@@ -8,9 +8,9 @@ namespace Discord.WebSocket;
|
||||
/// <summary>
|
||||
/// Contains a piece of audit log data related to a webhook deletion.
|
||||
/// </summary>
|
||||
public class SocketWebhookDeleteAuditLogData : ISocketAuditLogData
|
||||
public class SocketWebhookDeletedAuditLogData : ISocketAuditLogData
|
||||
{
|
||||
private SocketWebhookDeleteAuditLogData(ulong id, Model model)
|
||||
private SocketWebhookDeletedAuditLogData(ulong id, Model model)
|
||||
{
|
||||
WebhookId = id;
|
||||
ChannelId = model.ChannelId!.Value;
|
||||
@@ -19,13 +19,13 @@ public class SocketWebhookDeleteAuditLogData : ISocketAuditLogData
|
||||
Avatar = model.AvatarHash;
|
||||
}
|
||||
|
||||
internal static SocketWebhookDeleteAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
internal static SocketWebhookDeletedAuditLogData Create(DiscordSocketClient discord, EntryModel entry)
|
||||
{
|
||||
var changes = entry.Changes;
|
||||
|
||||
var (data, _) = AuditLogHelper.CreateAuditLogEntityInfo<Model>(changes, discord);
|
||||
|
||||
return new SocketWebhookDeleteAuditLogData(entry.TargetId!.Value,data);
|
||||
return new SocketWebhookDeletedAuditLogData(entry.TargetId!.Value,data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -40,7 +40,7 @@ internal static class SocketAuditLogHelper
|
||||
|
||||
[ActionType.WebhookCreated] = SocketWebhookCreateAuditLogData.Create,
|
||||
[ActionType.WebhookUpdated] = SocketWebhookUpdateAuditLogData.Create,
|
||||
[ActionType.WebhookDeleted] = SocketWebhookDeleteAuditLogData.Create,
|
||||
[ActionType.WebhookDeleted] = SocketWebhookDeletedAuditLogData.Create,
|
||||
|
||||
[ActionType.EmojiCreated] = SocketEmoteCreateAuditLogData.Create,
|
||||
[ActionType.EmojiUpdated] = SocketEmoteUpdateAuditLogData.Create,
|
||||
@@ -84,6 +84,10 @@ internal static class SocketAuditLogHelper
|
||||
[ActionType.OnboardingQuestionCreated] = SocketOnboardingPromptCreatedAuditLogData.Create,
|
||||
[ActionType.OnboardingQuestionUpdated] = SocketOnboardingPromptUpdatedAuditLogData.Create,
|
||||
[ActionType.OnboardingUpdated] = SocketOnboardingUpdatedAuditLogData.Create,
|
||||
|
||||
[ActionType.VoiceChannelStatusUpdated] = SocketVoiceChannelStatusUpdatedAuditLogData.Create,
|
||||
[ActionType.VoiceChannelStatusDeleted] = SocketVoiceChannelStatusDeleteAuditLogData.Create,
|
||||
|
||||
};
|
||||
|
||||
public static ISocketAuditLogData CreateData(DiscordSocketClient discord, EntryModel entry)
|
||||
|
||||
@@ -43,6 +43,12 @@ namespace Discord.WebSocket
|
||||
public IReadOnlyCollection<SocketGuildUser> Speakers
|
||||
=> Users.Where(x => !x.IsSuppressed).ToImmutableArray();
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <remarks>
|
||||
/// This property is not supported in stage channels and will always return <see cref="string.Empty"/>.
|
||||
/// </remarks>
|
||||
public override string Status => string.Empty;
|
||||
|
||||
internal new SocketStageChannel Clone() => MemberwiseClone() as SocketStageChannel;
|
||||
|
||||
internal SocketStageChannel(DiscordSocketClient discord, ulong id, SocketGuild guild)
|
||||
@@ -156,5 +162,13 @@ namespace Discord.WebSocket
|
||||
|
||||
return Discord.ApiClient.ModifyUserVoiceState(Guild.Id, user.Id, args);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// Setting voice channel status is not supported in stage channels.
|
||||
/// </remarks>
|
||||
/// <exception cref="NotSupportedException">Setting voice channel status is not supported in stage channels.</exception>
|
||||
public override Task SetStatusAsync(string status, RequestOptions options = null)
|
||||
=> throw new NotSupportedException("Setting voice channel status is not supported in stage channels.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ namespace Discord.WebSocket
|
||||
/// <inheritdoc/>
|
||||
public VideoQualityMode VideoQualityMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the voice channel status set in this channel. <see langword="null" /> if it is not set.
|
||||
/// </summary>
|
||||
public virtual string Status { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of users that are currently connected to this voice channel.
|
||||
/// </summary>
|
||||
@@ -51,12 +56,19 @@ namespace Discord.WebSocket
|
||||
: base(discord, id, guild)
|
||||
{
|
||||
}
|
||||
|
||||
internal new static SocketVoiceChannel Create(SocketGuild guild, ClientState state, Model model)
|
||||
{
|
||||
var entity = new SocketVoiceChannel(guild?.Discord, model.Id, guild);
|
||||
entity.Update(state, model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
internal void UpdateVoiceStatus(string status)
|
||||
{
|
||||
Status = status;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
internal override void Update(ClientState state, Model model)
|
||||
{
|
||||
@@ -65,8 +77,13 @@ namespace Discord.WebSocket
|
||||
UserLimit = model.UserLimit.GetValueOrDefault() != 0 ? model.UserLimit.Value : (int?)null;
|
||||
VideoQualityMode = model.VideoQualityMode.GetValueOrDefault(VideoQualityMode.Auto);
|
||||
RTCRegion = model.RTCRegion.GetValueOrDefault(null);
|
||||
Status = model.Status.GetValueOrDefault(null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Task SetStatusAsync(string status, RequestOptions options = null)
|
||||
=> ChannelHelper.ModifyVoiceChannelStatusAsync(this, status, Discord, options);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task ModifyAsync(Action<VoiceChannelProperties> func, RequestOptions options = null)
|
||||
=> ChannelHelper.ModifyAsync(this, Discord, func, options);
|
||||
|
||||
Reference in New Issue
Block a user