将 guildUserProperties.Mute 设置为 false 时,Bot 不会取消静音用户

Posted

技术标签:

【中文标题】将 guildUserProperties.Mute 设置为 false 时,Bot 不会取消静音用户【英文标题】:Bot doesn't unmute user when setting guildUserProperties.Mute to false 【发布时间】:2021-03-29 18:58:24 【问题描述】:

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

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

public class ObservedVoiceChannelInfo

    public ulong VoiceChannelId  get; set; 
    public bool Muted  get; set; 
    public List<ulong> MutedUserIds  get; set;  = new List<ulong>();

对于活动部分,我想到了以下几点:

如果用户离开观察到的语音频道,该频道处于静音状态,该用户应被机器人取消静音 如果用户加入观察到的语音频道,该频道处于静音状态,该用户应被机器人静音

基本上我想要实现的是:如果有人加入观察到的静音语音频道,则将该用户静音。如果该用户离开此频道,如果状态为静音,则取消静音。

这是我当前的实现(observedVoiceChannelsCache 是内存缓存字典,带有观察到的语音通道)

    private async Task OnUserVoiceStateUpdated(SocketUser socketUser, SocketVoiceState oldSocketVoiceState,
        SocketVoiceState newSocketVoiceState)
    
        SocketGuildUser socketGuildUser = socketUser as SocketGuildUser;

        if (newSocketVoiceState.IsMuted &&
            newSocketVoiceState.VoiceChannel == null &&
            _observedVoiceChannelsCache.TryGetValue(oldSocketVoiceState.VoiceChannel.Id,
                out ObservedVoiceChannelInfo oldObservedVoiceChannelInfo) &&
            oldObservedVoiceChannelInfo.Muted)
        
            bool userRemovedFromMuteList = oldObservedVoiceChannelInfo.MutedUserIds.Remove(socketGuildUser.Id);

            if (userRemovedFromMuteList)
                await SetUserVoiceState(socketGuildUser, false);
        
        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; );
    

else 块似乎工作正常(加入观察到的静音频道)。但是第一个 if 块(离开观察到的静音通道)不起作用。用户被从列表中删除,但是当使用false 调用SetUserVoiceState 时,机器人不会取消静音。我可以通过加入观察到的静音语音通道、离开它并加入另一个未观察到的语音通道来重现它。那我还是静音吧。

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

【问题讨论】:

据我所知,用户需要连接到语音通道才能静音/取消静音 您是否考虑过在用户加入未静音频道时取消静音,或者由于某种原因无法使用? @Mikah 我考虑过这一点,但想象一个用户因不良行为被版主静音。我认为这个用户应该保持静音 @Question3r 好的,我知道我正在编写一个可以解决问题的脚本。如果用户将自己静音或被管理员静音,我会将用户添加到列表中,如果他们在列表中,我不会取消静音。 【参考方案1】:

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

该脚本通过跟踪已静音的用户来工作,并且不会取消已被管理员静音的用户的静音。该机器人只能在活动时跟踪静音用户,因此您可能希望为 SelfOrAdminMutedUsersIds 列表包含一个保存功能或开发一种从不和谐接收该列表的方法。

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; );

我希望这会有所帮助。

【讨论】:

以上是关于将 guildUserProperties.Mute 设置为 false 时,Bot 不会取消静音用户的主要内容,如果未能解决你的问题,请参考以下文章

如何将Ios文件上传到

Javascript 将正则表达式 \\n 替换为 \n,将 \\t 替换为 \t,将 \\r 替换为 \r 等等

如何将视频文件转换格式

sh 一个将生成CA的脚本,将CA导入到钥匙串中,然后它将创建一个证书并与CA签名,然后将其导入到

python怎么将0写入文件?

如何将CMD窗口背景改成透明?