将 guildUserProperties.Mute 设置为 false 时,机器人不会取消静音用户
Bot doesn't unmute user when setting guildUserProperties.Mute to false
我使用 Discord.Net 创建了一个 Discord 机器人,它正在观察来自多个公会的多个语音通道。我正在监听 UserVoiceStateUpdated
事件,因为每当用户加入观察到的被静音的语音频道时,该用户应该被机器人静音。每当用户离开观察到的语音频道时,用户应该取消静音。
我有一个内存缓存,其中包含有关所有观察到的语音通道的信息。每个信息对象提供这些信息
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
时,用户不会被机器人取消静音。我可以通过加入观察到的静音语音通道、离开它并加入另一个未观察到的语音通道来重现它。那我还是哑了
有人知道这里缺少什么吗?
注意:重要注释下的变量需要在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; });
}
希望对您有所帮助。
我使用 Discord.Net 创建了一个 Discord 机器人,它正在观察来自多个公会的多个语音通道。我正在监听 UserVoiceStateUpdated
事件,因为每当用户加入观察到的被静音的语音频道时,该用户应该被机器人静音。每当用户离开观察到的语音频道时,用户应该取消静音。
我有一个内存缓存,其中包含有关所有观察到的语音通道的信息。每个信息对象提供这些信息
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
时,用户不会被机器人取消静音。我可以通过加入观察到的静音语音通道、离开它并加入另一个未观察到的语音通道来重现它。那我还是哑了
有人知道这里缺少什么吗?
注意:重要注释下的变量需要在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; });
}
希望对您有所帮助。