首页 > 解决方案 > permissionOverwrites 不会注意到授予@everyone 角色的权限。我该如何解决?

问题描述

我想创建一个脚本,当一个人连接到特定的语音频道时,它会创建一个只有那个人可以加入而其他人不能加入的房间。

脚本的逻辑很简单;它为连接到频道的人创建权限(说话、语音活动等)并拒绝该角色CONNECT的权限。@everyone

问题是我的机器人向连接到语音通道的人授予权限,但没有更改@everyone角色的任何权限。我该如何解决?

const { VoiceState } = require('discord.js');
const SettingsJSON = require('../../Configuration/Settings.json');
const Settings = SettingsJSON.PrivHub;

module.exports = async (oldState, newState) => {
  let mainChannel = oldState.guild.channels.cache.get(Settings.Room);
  if (!mainChannel) return;

  if (
    !oldState.channelID &&
    newState.channelID &&
    newState.channel.parentID == mainChannel.parentID &&
    newState.channelID == mainChannel.id
  ) {
    newState.guild.channels
      .create(
        `${Settings.Symbol} ${newState.member.displayName} kişisinin odası`,
        {
          type: 'voice',
          parent: mainChannel.parentID,
          permissionOverwrites: [
            mainChannel.permissionOverwrites.clone().set(
              newState.member.id,
              {
                id: newState.member.id,
                allow: [
                  'MANAGE_CHANNELS',
                  'STREAM',
                  'VIEW_CHANNEL',
                  'CONNECT',
                  'SPEAK',
                  'USE_VAD',
                ],
              },
              {
                id: oldState.guild.roles.everyone.id,
                deny: ["CONNECT"],
              },
            ),
          ],
        },
      )
      .then((channel) => {
        if (newState.member && newState.member.voice.channelID)
          newState.member.voice.setChannel(channel);
      });
    return;
  } else if (oldState.channelID && newState.channelID) {
    let oldChannel = oldState.channel;
    if (
      oldChannel.position > mainChannel.position &&
      oldChannel.parentID == mainChannel.parentID &&
      oldChannel.members.size <= 0 &&
      !oldChannel.deleted
    )
      oldChannel.delete().catch(undefined);
    if (
      newState.channelID == mainChannel.id &&
      newState.channel.parentID == mainChannel.parentID
    ) {
      newState.guild.channels
        .create(
          `${Settings.Symbol} ${newState.member.displayName} kişisinin odası`,
          {
            type: 'voice',
            parent: mainChannel.parentID,
            permissionOverwrites: [
              mainChannel.permissionOverwrites.clone().set(
                newState.member.id,
                {
                  id: newState.member.id,
                  allow: [
                    'MANAGE_CHANNELS',
                    'STREAM',
                    'VIEW_CHANNEL',
                    'CONNECT',
                    'SPEAK',
                    'USE_VAD',
                  ],
                },
                {
                id: oldState.guild.roles.everyone.id,
                deny: ["CONNECT"],
                },
              ),
            ],
          },
        )
        .then((channel) => {
          if (newState.member && newState.member.voice.channelID)
            newState.member.voice.setChannel(channel);
        });
    }
    return;
  } else if (
    oldState.channelID &&
    oldState.channel.parentID == mainChannel.parentID &&
    !newState.channelID
  ) {
    let oldChannel = oldState.channel;
    if (
      oldChannel.position > mainChannel.position &&
      oldChannel.members.size <= 0 &&
      !oldChannel.deleted
    )
      oldChannel.delete().catch(undefined);
  }
};

module.exports.config = {
  Event: 'voiceStateUpdate',
};

标签: javascriptnode.jsdiscorddiscord.js

解决方案


克隆集合后mainChannel.permissionOverwrites,您只能使用set()带有密钥的方法newState.member.id

set()方法只接受两个参数,即要添加的元素的键和值。在上面的代码中,您使用了三个参数,首先是键,其次是具有allow属性的对象,最后是具有属性的另一个对象deny(应该用于@everyone角色)。

在 JavaScript 中,如果你在一个函数只需要两个参数时传递了一些额外的参数,那么什么都不会发生,它只是忽略它。这就是这里发生的事情。allow您只需使用道具设置第一次覆盖。

要解决此问题,您可以使用两种set()方法;一份给成员,一份给@everyone角色:

{
  type: 'voice',
  parent: mainChannel.parentID,
  permissionOverwrites: [
    mainChannel.permissionOverwrites
      .clone()
      .set(newState.member.id, {
        id: newState.member.id,
        allow: [
          'MANAGE_CHANNELS',
          'STREAM',
          'VIEW_CHANNEL',
          'CONNECT',
          'SPEAK',
          'USE_VAD',
        ],
      })
      .set(oldState.guild.roles.everyone.id, {
        id: oldState.guild.roles.everyone.id,
        deny: ['CONNECT'],
      }),
  ],
}

推荐阅读