mirror of
https://github.com/discordeno/discordeno.git
synced 2026-09-17 08:47:22 +00:00
Merge branch 'next' into large-bot-optimizations
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
MessageContent,
|
||||
} from "../types/channel.ts";
|
||||
import { Errors } from "../types/errors.ts";
|
||||
import { RawOverwrite } from "../types/guild.ts";
|
||||
import { PermissionOverwrite } from "../types/guild.ts";
|
||||
import { MessageCreateOptions } from "../types/message.ts";
|
||||
import { Permissions } from "../types/permission.ts";
|
||||
import { endpoints } from "../utils/constants.ts";
|
||||
@@ -23,7 +23,7 @@ import { botHasChannelPermissions } from "../utils/permissions.ts";
|
||||
export function channelOverwriteHasPermission(
|
||||
guildID: string,
|
||||
id: string,
|
||||
overwrites: RawOverwrite[],
|
||||
overwrites: PermissionOverwrite[],
|
||||
permissions: Permissions[],
|
||||
) {
|
||||
const overwrite = overwrites.find((perm) => perm.id === id) ||
|
||||
@@ -31,8 +31,10 @@ export function channelOverwriteHasPermission(
|
||||
|
||||
return permissions.every((perm) => {
|
||||
if (overwrite) {
|
||||
if (BigInt(overwrite.deny) & BigInt(perm)) return false;
|
||||
if (BigInt(overwrite.allow) & BigInt(perm)) return true;
|
||||
const allowBits = calculateBits(overwrite.allow);
|
||||
const denyBits = calculateBits(overwrite.deny);
|
||||
if (BigInt(denyBits) & BigInt(perm)) return false;
|
||||
if (BigInt(allowBits) & BigInt(perm)) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ export async function createGuildChannel(
|
||||
(await RequestManager.post(endpoints.GUILD_CHANNELS(guild.id), {
|
||||
...options,
|
||||
name,
|
||||
permission_overwrites: options?.permission_overwrites?.map((perm) => ({
|
||||
permission_overwrites: options?.permissionOverwrites?.map((perm) => ({
|
||||
...perm,
|
||||
|
||||
allow: perm.allow.reduce(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { cacheHandlers } from "../controllers/cache.ts";
|
||||
import { ChannelCreatePayload } from "../types/channel.ts";
|
||||
import { PermissionOverwrite } from "../types/guild.ts";
|
||||
import { Unpromise } from "../types/misc.ts";
|
||||
import { calculatePermissions } from "../utils/permissions.ts";
|
||||
|
||||
@@ -14,6 +15,7 @@ export async function createChannel(
|
||||
rate_limit_per_user: rateLimitPerUser,
|
||||
parent_id: parentID,
|
||||
last_pin_timestamp: lastPinTimestamp,
|
||||
permission_overwrites,
|
||||
...rest
|
||||
} = data;
|
||||
|
||||
@@ -32,13 +34,14 @@ export async function createChannel(
|
||||
/** The last time when a message was pinned in this channel */
|
||||
lastPinTimestamp,
|
||||
/** The permission overwrites for this channel */
|
||||
permissions: data.permission_overwrites
|
||||
? data.permission_overwrites.map((perm) => ({
|
||||
...perm,
|
||||
allow: calculatePermissions(BigInt(perm.allow)),
|
||||
deny: calculatePermissions(BigInt(perm.deny)),
|
||||
}))
|
||||
: [],
|
||||
permissionOverwrites:
|
||||
(data.permission_overwrites
|
||||
? data.permission_overwrites.map((perm) => ({
|
||||
...perm,
|
||||
allow: calculatePermissions(BigInt(perm.allow)),
|
||||
deny: calculatePermissions(BigInt(perm.deny)),
|
||||
}))
|
||||
: []) as PermissionOverwrite[],
|
||||
/** Whether this channel is nsfw or not */
|
||||
nsfw: data.nsfw || false,
|
||||
/** The mention of the channel */
|
||||
|
||||
+7
-1
@@ -474,6 +474,12 @@ export interface RawOverwrite {
|
||||
deny: number;
|
||||
}
|
||||
|
||||
export interface PermissionOverwrite
|
||||
extends Omit<RawOverwrite, "allow" | "deny"> {
|
||||
allow: Permission[];
|
||||
deny: Permission[];
|
||||
}
|
||||
|
||||
export interface ChannelCreateOptions {
|
||||
/** The type of the channel */
|
||||
type?: ChannelTypes;
|
||||
@@ -488,7 +494,7 @@ export interface ChannelCreateOptions {
|
||||
/** The sorting position of the channel */
|
||||
position?: number;
|
||||
/** The channel's permission overwrites */
|
||||
permission_overwrites?: Overwrite[];
|
||||
permissionOverwrites?: Overwrite[];
|
||||
/** The id of the parent category for the channel */
|
||||
parent_id?: string;
|
||||
/** Whether the channel is nsfw */
|
||||
|
||||
+19
-12
@@ -2,7 +2,7 @@ import { cacheHandlers } from "../controllers/cache.ts";
|
||||
import { botID } from "../module/client.ts";
|
||||
import { Guild } from "../structures/guild.ts";
|
||||
import { Role } from "../structures/role.ts";
|
||||
import { RawOverwrite } from "../types/guild.ts";
|
||||
import { PermissionOverwrite } from "../types/guild.ts";
|
||||
import { Permission, Permissions } from "../types/permission.ts";
|
||||
|
||||
/** Checks if the member has this permission. If the member is an owner or has admin perms it will always be true. */
|
||||
@@ -105,11 +105,11 @@ export async function hasChannelPermissions(
|
||||
const member = guild.members.get(memberID);
|
||||
if (!member) return false;
|
||||
|
||||
let memberOverwrite: RawOverwrite | undefined;
|
||||
let everyoneOverwrite: RawOverwrite | undefined;
|
||||
let rolesOverwrites: RawOverwrite[] = [];
|
||||
let memberOverwrite: PermissionOverwrite | undefined;
|
||||
let everyoneOverwrite: PermissionOverwrite | undefined;
|
||||
let rolesOverwrites: PermissionOverwrite[] = [];
|
||||
|
||||
for (const overwrite of channel.permission_overwrites || []) {
|
||||
for (const overwrite of channel.permissionOverwrites || []) {
|
||||
// If the overwrite on this channel is specific to this member
|
||||
if (overwrite.id === memberID) memberOverwrite = overwrite;
|
||||
// If it is the everyone role overwrite
|
||||
@@ -122,13 +122,16 @@ export async function hasChannelPermissions(
|
||||
|
||||
// Member perms override everything so we must check them first
|
||||
if (memberOverwrite) {
|
||||
const allowBits = calculateBits(memberOverwrite.allow);
|
||||
const denyBits = calculateBits(memberOverwrite.deny);
|
||||
for (const perm of permissions) {
|
||||
// One of the necessary permissions is denied. Since this is main permission we can cancel if its denied.
|
||||
if (BigInt(memberOverwrite.deny) & BigInt(perm)) return false;
|
||||
if (BigInt(denyBits) & BigInt(perm)) return false;
|
||||
// Already allowed perm
|
||||
if (allowedPermissions.has(perm)) continue;
|
||||
|
||||
// This perm is allowed so we save it
|
||||
if (BigInt(memberOverwrite.allow) & BigInt(perm)) {
|
||||
if (BigInt(allowBits) & BigInt(perm)) {
|
||||
allowedPermissions.add(perm);
|
||||
}
|
||||
}
|
||||
@@ -140,17 +143,19 @@ export async function hasChannelPermissions(
|
||||
if (allowedPermissions.has(perm)) continue;
|
||||
|
||||
for (const overwrite of rolesOverwrites) {
|
||||
const allowBits = calculateBits(overwrite.allow);
|
||||
// This perm is allowed so we save it
|
||||
if (BigInt(overwrite.allow) & BigInt(perm)) {
|
||||
if (BigInt(allowBits) & BigInt(perm)) {
|
||||
allowedPermissions.add(perm);
|
||||
break;
|
||||
}
|
||||
|
||||
const denyBits = calculateBits(overwrite.deny);
|
||||
// If this role denies it we need to save and check if another role allows it, allows > deny
|
||||
if (BigInt(overwrite.deny) & BigInt(perm)) {
|
||||
if (BigInt(denyBits) & BigInt(perm)) {
|
||||
// This role denies his perm, but before denying we need to check all other roles if any allow as allow > deny
|
||||
const isAllowed = rolesOverwrites.some((o) =>
|
||||
BigInt(o.allow) & BigInt(perm)
|
||||
BigInt(calculateBits(o.allow)) & BigInt(perm)
|
||||
);
|
||||
if (isAllowed) continue;
|
||||
// This permission is in fact denied. Since Roles overrule everything below here we can cancel ou here
|
||||
@@ -160,13 +165,15 @@ export async function hasChannelPermissions(
|
||||
}
|
||||
|
||||
if (everyoneOverwrite) {
|
||||
const allowBits = calculateBits(everyoneOverwrite.allow);
|
||||
const denyBits = calculateBits(everyoneOverwrite.deny);
|
||||
for (const perm of permissions) {
|
||||
// Already allowed perm
|
||||
if (allowedPermissions.has(perm)) continue;
|
||||
// One of the necessary permissions is denied. Since everyone overwrite overrides role perms we can cancel here
|
||||
if (BigInt(everyoneOverwrite.deny) & BigInt(perm)) return false;
|
||||
if (BigInt(denyBits) & BigInt(perm)) return false;
|
||||
// This perm is allowed so we save it
|
||||
if (BigInt(everyoneOverwrite.allow) & BigInt(perm)) {
|
||||
if (BigInt(allowBits) & BigInt(perm)) {
|
||||
allowedPermissions.add(perm);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -168,18 +168,18 @@ Deno.test({
|
||||
const channel = cache.channels.get(data.channelID);
|
||||
if (!channel) throw "Channel not found";
|
||||
|
||||
if (!channel.permission_overwrites) throw "Channel overwrites not found.";
|
||||
if (!channel.permissionOverwrites) throw "Channel overwrites not found.";
|
||||
|
||||
const hasPerm = channelOverwriteHasPermission(
|
||||
data.guildID,
|
||||
data.roleID,
|
||||
channel.permission_overwrites,
|
||||
channel.permissionOverwrites,
|
||||
[Permissions.VIEW_CHANNEL, Permissions.SEND_MESSAGES],
|
||||
);
|
||||
const missingPerm = channelOverwriteHasPermission(
|
||||
data.guildID,
|
||||
data.roleID,
|
||||
channel.permission_overwrites,
|
||||
channel.permissionOverwrites,
|
||||
[Permissions.USE_EXTERNAL_EMOJIS],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user