権限
ボットは権限を Discord 形式の 53 ビット整数ビットフィールドとして受け取ります。ビットとその意味は Discord と一致し、値は GameVox のネイティブなグループ/チャンネル権限テーブルから導かれます。GameVox に相当する概念がないビットは 0 を返します。
ネイティブ → Discord の対応
| Discord のビット | 16 進 | GameVox 側のソース |
|---|---|---|
| ADMINISTRATOR | 0x8 | groups.group_type IN ('owner', 'admin') |
| VIEW_CHANNEL | 0x400 | channel_permissions.view_channel / group_permissions.view_channels |
| READ_MESSAGE_HISTORY | 0x10000 | VIEW_CHANNEL と同じ(履歴用の個別トグルはありません) |
| SEND_MESSAGES | 0x800 | send_messages |
| MANAGE_MESSAGES | 0x2000 | manage_messages |
| EMBED_LINKS | 0x4000 | can_post_links |
| ATTACH_FILES | 0x8000 | send_files |
| ADD_REACTIONS | 0x40 | add_reactions |
| MENTION_EVERYONE | 0x20000 | v1 では管理者のみ |
| CONNECT (voice) | 0x100000 | join_voice |
| SPEAK | 0x200000 | speak_in_voice |
| STREAM (screen share) | 0x200 | screen_share |
| USE_VAD | 0x2000000 | use_vad(既定は true。false にするとプッシュ・トゥ・トークになります) |
| KICK_MEMBERS | 0x2 | kick_users != 'deny' |
| BAN_MEMBERS | 0x4 | ban_users != 'deny' |
| MUTE_MEMBERS | 0x400000 | mute_users != 'deny' |
| MOVE_MEMBERS | 0x1000000 | move_users != 'deny' |
| MANAGE_CHANNELS | 0x10 | create_channels / edit_channels / delete_channels がすべて 'deny' 以外 |
| MANAGE_GUILD | 0x20 | edit_server != 'deny' |
| MANAGE_ROLES | 0x10000000 | manage_members |
| MANAGE_NICKNAMES | 0x8000000 | manage_members(MANAGE_ROLES とまとめて扱います) |
| CHANGE_NICKNAME | 0x4000000 | 常に付与されます(Discord の既定と同じ) |
| MANAGE_WEBHOOKS | 0x20000000 | v1 ではオーナー / 管理者 |
| VIEW_AUDIT_LOG | 0x80 | v1 ではオーナー / 管理者 |
| PRIORITY_SPEAKER | 0x100 | priority_speaker |
| MANAGE_EVENTS | 0x200000000 | manage_events != 'deny' |
| CREATE_EVENTS | 0x100000000000 | manage_events != 'deny'(MANAGE_EVENTS とまとめて扱います) |
| MANAGE_GUILD_EXPRESSIONS | 0x40000000 | manage_emojis != 'deny' |
| CREATE_GUILD_EXPRESSIONS | 0x80000000000 | manage_emojis != 'deny'(まとめて扱います) |
| DEAFEN_MEMBERS | 0x800000 | deafen_users != 'deny' |
| SEND_MESSAGES_IN_THREADS | 0x4000000000 | send_messages(SEND_MESSAGES とまとめて扱います) |
既定でオンのビット
拒否されていないすべてのメンバーに設定され、Discord の既定ロールの挙動と一致します。ボットのロジックがこれらをチェックする場合、(BAN されていない限り)常に付与済みとして見えます。
CREATE_INSTANT_INVITE(0x1)USE_APPLICATION_COMMANDS(0x80000000)USE_EXTERNAL_EMOJIS(0x40000)USE_EXTERNAL_STICKERS(0x2000000000)
常にゼロを返すビット
GameVox にはまだ相当する概念がなく、未設定として報告されます。これらに依存するボットは、うまく機能を落として動作するようにしてください(多くのライブラリは、拒否されたビットをすでに「ここでは非対応の機能」として扱います)。
MANAGE_THREADS、USE_PUBLIC_THREADS、USE_PRIVATE_THREADS: v1 ではスレッドはスタブです。MODERATE_MEMBERS(タイムアウト): 相当する機能がありません。USE_EMBEDDED_ACTIVITIES: アクティビティ機能がありません。USE_SOUNDBOARD、SEND_VOICE_MESSAGES: 未実装です。- 収益化系のビット: Premium Apps はありません。
権限の計算
Discord の 7 ステップのアルゴリズムと同一です。
- ギルドの
@everyone権限から始めます。 - メンバーが持つすべてのロールを OR で合成します。
- 結果に ADMINISTRATOR が含まれる場合は打ち切り、すべての権限を持つとみなします。
@everyoneのチャンネル上書きを適用します(allow のあと deny)。- 各ロールのチャンネル上書きを適用します(allow のあと deny)。
- そのユーザーのチャンネル上書きを適用します(allow のあと deny)。
- チャンネルがカテゴリ内にある場合、カテゴリの上書きもロール/ユーザーの段階で適用されます。
下記の違いが現れるのはステップ 2 です。GameVox のメンバーは 1 つのグループにしか属さないため、OR で合成するロールは 1 つだけになります。メンバーにつき 1 グループをご覧ください。
メンバーにつき 1 グループ
Discord との最大の挙動の違いです。GameVox のメンバーはサーバーごとにちょうど 1 つのグループに属します。Discord では 1 人が複数のロールを同時に持てます。グループを割り当てると、それまでのグループは置き換えられます。
ロールのエンドポイントは引き続き動作し、既存のライブラリもこれまで通り呼び出せます。ただ、その 1 つのグループに解決されるだけです。
| 呼び出し | 何が起きるか |
|---|---|
PUT .../members/{id}/roles/{rid} | メンバーはそのグループに入ります。以前のグループは併存せず、置き換えられます。 |
DELETE .../members/{id}/roles/{rid} | 取り除きます。それが唯一のグループだった場合、グループなしにはならず、サーバーの既定グループに戻ります。 |
roles: [...] を付けた PATCH .../members/{id} | 受け付けたうえで、リスト中で最も上位のグループにまとめられます。空のリストは既定グループを意味します。 |
通常の member.roles.set([...]) が動き続けるよう、リストは拒否ではなくまとめられます。上位が勝つのは、立場を決めるのがランクだからです。モデレーターのグループと色分けのグループがあれば、そのメンバーはモデレーターです。
グループにはアップロード、ボイス、カメラ、画面共有の上限が設定されており、メンバーは所属グループのうち最も緩い上限を得ます。グループが 1 つなら、それは単にそのグループの上限です。これが、アプリが誰かを 2 つのグループに入れられないもう 1 つの理由でもあります(運営者が設定した上限を回避する手段になってしまうためです)。
アプリケーション自身のグループ(インストール時に作成されたもの)は、この話の対象外です。その所属はインストールに属し、どのアプリも自分を追加したり他のアプリを取り除いたりはできません。
ロールの階層
ネイティブの groups.rank は Discord の role.position に対応します。ボットが管理できるのは、自分の最上位ロールの位置より下のロールだけで、Discord のルールと同じです。ボットの最上位ロード以上のロールに対する PATCH .../members/{id}/roles/{rid} は 403 を返します。
タイムアウト
Discord の communication_disabled_until フィールドに相当するものは v1 の GameVox にはありません。このフィールドを付けてメンバーに PATCH すると、明確なエラーとともに 400 を返します。代わりにキック / ミュート / BAN を使ってください。