C# 机器人不';设置GuilduserProperty时取消禁用用户。禁用为false

C# 机器人不';设置GuilduserProperty时取消禁用用户。禁用为false,c#,discord.net,C#,Discord.net,我使用Discord.Net创建了一个Discord机器人,它正在观察来自多个协会的多个语音频道。我正在监听UserVoiceStateUpdated事件,因为每当用户加入一个观察到的静音语音频道时,该用户应该被bot静音。每当用户离开观察到的语音通道时,该用户应取消静音 我有一个内存缓存,里面保存着所有观察到的语音通道的信息。每个信息对象都提供这些信息 public class ObservedVoiceChannelInfo { public ulong VoiceChannelId

我使用Discord.Net创建了一个Discord机器人,它正在观察来自多个协会的多个语音频道。我正在监听
UserVoiceStateUpdated
事件,因为每当用户加入一个观察到的静音语音频道时,该用户应该被bot静音。每当用户离开观察到的语音通道时,该用户应取消静音

我有一个内存缓存,里面保存着所有观察到的语音通道的信息。每个信息对象都提供这些信息

public class ObservedVoiceChannelInfo
{
    public ulong VoiceChannelId { get; set; }
    public bool Muted { get; set; }
    public List<ulong> MutedUserIds { get; set; } = new List<ulong>();
}
else块似乎工作正常(加入观察到的静音通道)。但是第一个if块(留下一个观察到的静音通道)不起作用。用户将从列表中删除,但当使用
false
调用
SetUserVoiceState
时,用户不会被bot解除静音。我可以通过加入一个观察到的静音语音通道,离开它并加入另一个未观察到的语音通道来复制它。那时我还是沉默着


有人知道这里缺少什么吗?

注意:重要注释下的变量需要在bot启动时初始化

该脚本的工作原理是跟踪已禁用的用户,而不是取消已被管理员禁用的用户的禁用。bot只能在活动时跟踪静音用户,因此您可能希望为SelfOrAdminMutedUsersIds列表包含一个保存功能,或者开发一种从discord接收该列表的方法

public class ObservedVoiceChannelInfo
{
    public ulong VoiceChannelId { get; set; }
    public bool Muted { get; set; }
    public List<ulong> MutedUserIds { get; set; } = new List<ulong>();
}
public class ObservedGuildsMutingInfo
{
    public ulong GuildId { get; set; }
    public List<ulong> SelfOrAdminMutedUsersIds { get; set; }
}

//IMPORTANT: make sure to initialize on bot start:
public Dictionary<ulong, ObservedGuildsMutingInfo> _observedGuildsMutingInfoCache = new Dictionary<ulong, ObservedGuildsMutingInfo>();
//IMPORTANT: make sure to initialize on bot start:
public Dictionary<ulong, ObservedVoiceChannelInfo> _observedVoiceChannelsCache = new Dictionary<ulong, ObservedGuildsMutingInfo>();

private async Task OnUserVoiceStateUpdated(SocketUser socketUser, SocketVoiceState oldSocketVoiceState,
    SocketVoiceState newSocketVoiceState)
{
    SocketGuildUser socketGuildUser = socketUser as SocketGuildUser;
    
    if (!oldSocketVoiceState.IsMuted && newSocketVoiceState.IsMuted && 
        _observedGuildsMutingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id, out ObservedGuildsMutingInfo newObservedMutinglInfo))
    {
        // a user was muted by someone
        if (_observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id, out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo)&&
            !oldObservedVoiceChannelInfo.MutedUserIds.Contains(socketGuildUser.Id))
        {
            // the user was not muted by the bot
            // meaning that the user muted theirselfs or were muted by admin
            newObservedMutingInfo.SelfOrAdminMutedUsersIds.Add(socketGuildUser.Id);
        }
    }
    else if (!oldSocketVoiceState.IsMuted && newSocketVoiceState.IsMuted && 
        _observedGuildsMutingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id, out ObservedGuildsMutingInfo newObservedMutinglInfo))
    {
        // a user was un-muted by someone
        newObservedMutingInfo.SelfOrAdminMutedUsersIds.Remove(socketGuildUser.Id);
    }
    else if (!newSocketVoiceState.IsMuted &&
        newSocketVoiceState.VoiceChannel != null &&
        _observedVoiceChannelsCache.TryGetValue(newSocketVoiceState.VoiceChannel.Id,
        out ObservedVoiceChannelInfo newObservedVoiceChannelInfo) &&
        !newObservedVoiceChannelInfo.Muted)
    {
        // user has joined a un-muted channel
        if(_observedGuildsMutingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id, out ObservedGuildsMutingInfo newObservedGuildsMutingInfo)&&
            !newObservedGuildsMutingInfo.SelfOrAdminMutedUsersIds.Contains(socketGuildUser.Id))
        {
            await SetUserVoiceState(socketGuildUser, false);
        }
    }
    else if (newSocketVoiceState.IsMuted &&
        newSocketVoiceState.VoiceChannel == null &&
        _observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id,
            out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo) &&
        oldObservedVoiceChannelInfo.Muted)
    {
        oldObservedVoiceChannelInfo.MutedUserIds.Remove(socketGuildUser.Id);
    }
    else if (!newSocketVoiceState.IsMuted &&
         newSocketVoiceState.VoiceChannel != null &&
         _observedVoiceChannelsCache.TryGetValue(newSocketVoiceState.VoiceChannel.Id,
             out ObservedVoiceChannelInfo newObservedVoiceChannelInfo) &&
             newObservedVoiceChannelInfo.Muted)
    {
        await SetUserVoiceState(socketGuildUser, true);
        newObservedVoiceChannelInfo.MutedUserIds.Add(socketGuildUser.Id);
    }
}

private async Task SetUserVoiceState(SocketGuildUser socketGuildUser, bool muted)
{
    await socketGuildUser.ModifyAsync(guildUserProperties => { guildUserProperties.Mute = muted; });
}
公共类ObservedVoiceChannelInfo
{
公共ulong VoiceChannelId{get;set;}
公共布尔静音{get;set;}
公共列表mutedUserID{get;set;}=new List();
}
公共类ObservedBuilderSmutingInfo
{
公共ulong GuildId{get;set;}
公共列表SelfOrAdminMutedUsersIds{get;set;}
}
//重要提示:确保在bot启动时初始化:
公共字典_observedgebuildsmutinginfocache=新字典();
//重要提示:确保在bot启动时初始化:
公共词典_observedVoiceChannelsCache=新词典();
专用异步任务OnServoiceStateUpdated(SocketUser SocketUser,SocketVoiceState oldSocketVoiceState,
SocketVoiceState新闻SocketVoiceState)
{
SocketGuildUser SocketGuildUser=作为SocketGuildUser的socketUser;
如果(!oldSocketVoiceState.ismute&&newSocketVoiceState.ismute&&
_observedBuilderSmatingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id,out observedBuilderSmatingInfo newobservedMutingInfo))
{
//某个用户被某人静音
if(_observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id,out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo)&&
!oldObservedVoiceChannelInfo.MutedUserId.Contains(socketGuildUser.Id))
{
//该用户未被bot禁用
//这意味着用户将自己静音或被管理员静音
newObservedMutingInfo.SelfOrAdminMutedUsersIds.Add(socketGuiduser.Id);
}
}
如果(!oldSocketVoiceState.ismute&&newSocketVoiceState.ismute&&
_observedBuilderSmatingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id,out observedBuilderSmatingInfo newobservedMutingInfo))
{
//有人取消了用户的静音
newObservedMutingInfo.SelfOrAdminMutedUsersIds.Remove(socketGuiduser.Id);
}
如果(!newSocketVoiceState.IsMuted),则为else&&
newSocketVoiceState.VoiceChannel!=null&&
_observedVoiceChannelsCache.TryGetValue(newSocketVoiceState.VoiceChannel.Id,
out ObservedVoiceChannelInfo新建ObservedVoiceChannelInfo)&&
!newObservedVoiceChannelInfo.mute)
{
//用户已加入非静音频道
if(_observedgebuildsmutinginfocache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id,out observedgebuildsmutinginfo newobservedgebuildsmutinginfo)&&
!newobservedgebuildsmutinginfo.SelfOrAdminMutedUsersIds.Contains(socketGuildUser.Id))
{
等待SetUserVoiceState(socketGuiduser,false);
}
}
else if(newSocketVoiceState.IsMuted&&
newSocketVoiceState.VoiceChannel==null&&
_observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id,
out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo)&&
oldObservedVoiceChannelInfo.静音)
{
oldObservedVoiceChannelInfo.MutedUserId.Remove(socketGuildUser.Id);
}
如果(!newSocketVoiceState.IsMuted),则为else&&
newSocketVoiceState.VoiceChannel!=null&&
_observedVoiceChannelsCache.TryGetValue(newSocketVoiceState.VoiceChannel.Id,
out ObservedVoiceChannelInfo新建ObservedVoiceChannelInfo)&&
newObservedVoiceChannelInfo.静音)
{
等待SetUserVoiceState(socketGuildUser,true);
newObservedVoiceChannelInfo.mutedUserId.Add(socketGuildUser.Id);
}
}
专用异步任务SetUserVoiceState(SocketGuildUser SocketGuildUser,布尔静音)
{
等待socketGuildUser.ModifyAsync(guildUserProperties=>{guildUserProperties.Mute=Mute;});
}

我希望这会有所帮助。

据我所知,用户需要连接到语音频道才能静音/取消静音。当用户加入取消静音频道时,您是否想过取消静音,或者这会因为某种原因不起作用?@Mikah我想了想,但想象一个用户因不良行为而被主持人静音。这个用户应该保持沉默,我think@Question3r好的,我有一个想法,我正在编写一个脚本来解决这个问题。我会将用户添加到一个列表中,如果他们自己静音,或者如果他们被管理员静音,我不会取消静音,如果他们在列表中。
public class ObservedVoiceChannelInfo
{
    public ulong VoiceChannelId { get; set; }
    public bool Muted { get; set; }
    public List<ulong> MutedUserIds { get; set; } = new List<ulong>();
}
public class ObservedGuildsMutingInfo
{
    public ulong GuildId { get; set; }
    public List<ulong> SelfOrAdminMutedUsersIds { get; set; }
}

//IMPORTANT: make sure to initialize on bot start:
public Dictionary<ulong, ObservedGuildsMutingInfo> _observedGuildsMutingInfoCache = new Dictionary<ulong, ObservedGuildsMutingInfo>();
//IMPORTANT: make sure to initialize on bot start:
public Dictionary<ulong, ObservedVoiceChannelInfo> _observedVoiceChannelsCache = new Dictionary<ulong, ObservedGuildsMutingInfo>();

private async Task OnUserVoiceStateUpdated(SocketUser socketUser, SocketVoiceState oldSocketVoiceState,
    SocketVoiceState newSocketVoiceState)
{
    SocketGuildUser socketGuildUser = socketUser as SocketGuildUser;
    
    if (!oldSocketVoiceState.IsMuted && newSocketVoiceState.IsMuted && 
        _observedGuildsMutingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id, out ObservedGuildsMutingInfo newObservedMutinglInfo))
    {
        // a user was muted by someone
        if (_observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id, out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo)&&
            !oldObservedVoiceChannelInfo.MutedUserIds.Contains(socketGuildUser.Id))
        {
            // the user was not muted by the bot
            // meaning that the user muted theirselfs or were muted by admin
            newObservedMutingInfo.SelfOrAdminMutedUsersIds.Add(socketGuildUser.Id);
        }
    }
    else if (!oldSocketVoiceState.IsMuted && newSocketVoiceState.IsMuted && 
        _observedGuildsMutingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id, out ObservedGuildsMutingInfo newObservedMutinglInfo))
    {
        // a user was un-muted by someone
        newObservedMutingInfo.SelfOrAdminMutedUsersIds.Remove(socketGuildUser.Id);
    }
    else if (!newSocketVoiceState.IsMuted &&
        newSocketVoiceState.VoiceChannel != null &&
        _observedVoiceChannelsCache.TryGetValue(newSocketVoiceState.VoiceChannel.Id,
        out ObservedVoiceChannelInfo newObservedVoiceChannelInfo) &&
        !newObservedVoiceChannelInfo.Muted)
    {
        // user has joined a un-muted channel
        if(_observedGuildsMutingInfoCache.TryGetValue(newSocketVoiceState.VoiceChannel.Guild.Id, out ObservedGuildsMutingInfo newObservedGuildsMutingInfo)&&
            !newObservedGuildsMutingInfo.SelfOrAdminMutedUsersIds.Contains(socketGuildUser.Id))
        {
            await SetUserVoiceState(socketGuildUser, false);
        }
    }
    else if (newSocketVoiceState.IsMuted &&
        newSocketVoiceState.VoiceChannel == null &&
        _observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id,
            out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo) &&
        oldObservedVoiceChannelInfo.Muted)
    {
        oldObservedVoiceChannelInfo.MutedUserIds.Remove(socketGuildUser.Id);
    }
    else if (!newSocketVoiceState.IsMuted &&
         newSocketVoiceState.VoiceChannel != null &&
         _observedVoiceChannelsCache.TryGetValue(newSocketVoiceState.VoiceChannel.Id,
             out ObservedVoiceChannelInfo newObservedVoiceChannelInfo) &&
             newObservedVoiceChannelInfo.Muted)
    {
        await SetUserVoiceState(socketGuildUser, true);
        newObservedVoiceChannelInfo.MutedUserIds.Add(socketGuildUser.Id);
    }
}

private async Task SetUserVoiceState(SocketGuildUser socketGuildUser, bool muted)
{
    await socketGuildUser.ModifyAsync(guildUserProperties => { guildUserProperties.Mute = muted; });
}