using Discord.WebSocket;
using Newtonsoft.Json.Linq;
using Noikoio.RegexBot.ConfigItem;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
namespace Noikoio.RegexBot.Module.VoiceRoleSync
{
///
/// Synchronizes a user's state in a voice channel with a role.
/// In other words: applies a role to a user entering a voice channel. Removes the role when exiting.
///
class VoiceRoleSync : BotModule
{
// Wishlist: specify multiple definitions - multiple channels associated with multiple roles.
public VoiceRoleSync(DiscordSocketClient client) : base(client)
{
client.UserVoiceStateUpdated += Client_UserVoiceStateUpdated;
}
private async Task Client_UserVoiceStateUpdated(SocketUser argUser, SocketVoiceState before, SocketVoiceState after)
{
// Gather data.
if (!(argUser is SocketGuildUser user)) return; // not a guild user
var settings = GetState(user.Guild.Id);
if (settings == null) return; // not enabled here
var deafened = after.IsDeafened || after.IsSelfDeafened;
var (settingBefore, settingAfter) = settings.GetChannelSettings(before.VoiceChannel, after.VoiceChannel);
// Determine action(s) to take
if (before.VoiceChannel?.Id != after.VoiceChannel?.Id)
{
// Joined / Left / Moved voice channels.
if (settingBefore?.Id != settingAfter?.Id)
{
// Replace roles only if the roles to be applied are different.
if (settingBefore != null && user.Roles.Contains(settingBefore)) await user.RemoveRoleAsync(settingBefore);
if (settingAfter != null && !user.Roles.Contains(settingAfter)) await user.AddRoleAsync(settingAfter);
}
}
else
{
// In same voice channel. Deafen state may have changed.
if (after.IsDeafened || after.IsSelfDeafened)
{
if (settingAfter != null && user.Roles.Contains(settingAfter)) await user.RemoveRoleAsync(settingAfter);
}
else
{
if (settingAfter != null && !user.Roles.Contains(settingAfter)) await user.AddRoleAsync(settingAfter);
}
}
}
public override Task