mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
fix: resolve bitfield correctly
This commit is contained in:
parent
cb52d6fe6b
commit
3ed0c8f293
@ -520,9 +520,9 @@ export class HandleCommand {
|
||||
}
|
||||
|
||||
checkPermissions(app: PermissionsBitField, bot: bigint) {
|
||||
if (app.has('Administrator')) return;
|
||||
if (app.has(['Administrator'])) return;
|
||||
|
||||
const permissions = app.missings(...app.values([bot]));
|
||||
const permissions = app.missings(app.values([bot]));
|
||||
if (permissions.length) {
|
||||
return app.keys(permissions);
|
||||
}
|
||||
|
@ -523,14 +523,14 @@ export class CommandHandler extends BaseHandler {
|
||||
option.onPermissionsFail?.bind(option) ??
|
||||
commandInstance.onPermissionsFail?.bind(commandInstance) ??
|
||||
this.client.options.commands?.defaults?.onPermissionsFail;
|
||||
option.botPermissions = PermissionsBitField.resolve(
|
||||
option.botPermissions = PermissionsBitField.resolve([
|
||||
option.botPermissions ?? PermissionsBitField.None,
|
||||
commandInstance.botPermissions ?? PermissionsBitField.None,
|
||||
);
|
||||
option.defaultMemberPermissions ??= PermissionsBitField.resolve(
|
||||
]);
|
||||
option.defaultMemberPermissions ??= PermissionsBitField.resolve([
|
||||
option.defaultMemberPermissions ?? PermissionsBitField.None,
|
||||
commandInstance.defaultMemberPermissions ?? PermissionsBitField.None,
|
||||
);
|
||||
]);
|
||||
option.contexts ??= commandInstance.contexts;
|
||||
option.integrationTypes ??= commandInstance.integrationTypes;
|
||||
option.props ??= commandInstance.props;
|
||||
|
@ -154,19 +154,19 @@ export class ChannelShorter extends BaseShorter {
|
||||
async memberPermissions(channelId: string, member: GuildMember, checkAdmin = true): Promise<PermissionsBitField> {
|
||||
const memberPermissions = await member.fetchPermissions();
|
||||
|
||||
if (checkAdmin && memberPermissions.has(PermissionFlagsBits.Administrator)) {
|
||||
if (checkAdmin && memberPermissions.has([PermissionFlagsBits.Administrator])) {
|
||||
return new PermissionsBitField(PermissionsBitField.All);
|
||||
}
|
||||
|
||||
const overwrites = await this.overwritesFor(channelId, member);
|
||||
const permissions = new PermissionsBitField(memberPermissions.bits);
|
||||
|
||||
permissions.remove(overwrites.everyone?.deny.bits ?? 0n);
|
||||
permissions.add(overwrites.everyone?.allow.bits ?? 0n);
|
||||
permissions.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny.bits) : 0n);
|
||||
permissions.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow.bits) : 0n);
|
||||
permissions.remove(overwrites.member?.deny.bits ?? 0n);
|
||||
permissions.add(overwrites.member?.allow.bits ?? 0n);
|
||||
permissions.remove([overwrites.everyone?.deny.bits ?? 0n]);
|
||||
permissions.add([overwrites.everyone?.allow.bits ?? 0n]);
|
||||
permissions.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny.bits) : [0n]);
|
||||
permissions.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow.bits) : [0n]);
|
||||
permissions.remove([overwrites.member?.deny.bits ?? 0n]);
|
||||
permissions.add([overwrites.member?.allow.bits ?? 0n]);
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ export class ChannelShorter extends BaseShorter {
|
||||
}
|
||||
|
||||
async rolePermissions(channelId: string, role: GuildRole, checkAdmin = true): Promise<PermissionsBitField> {
|
||||
if (checkAdmin && role.permissions.has(PermissionFlagsBits.Administrator)) {
|
||||
if (checkAdmin && role.permissions.has([PermissionFlagsBits.Administrator])) {
|
||||
return new PermissionsBitField(PermissionsBitField.All);
|
||||
}
|
||||
const channelOverwrites = (await this.client.cache.overwrites?.get(channelId)) ?? [];
|
||||
@ -204,10 +204,10 @@ export class ChannelShorter extends BaseShorter {
|
||||
const roleOverwrites = channelOverwrites.find(x => x.id === role.id);
|
||||
const permissions = new PermissionsBitField(role.permissions.bits);
|
||||
|
||||
permissions.remove(everyoneOverwrites?.deny.bits ?? 0n);
|
||||
permissions.add(everyoneOverwrites?.allow.bits ?? 0n);
|
||||
permissions.remove(roleOverwrites?.deny.bits ?? 0n);
|
||||
permissions.add(roleOverwrites?.allow.bits ?? 0n);
|
||||
permissions.remove([everyoneOverwrites?.deny.bits ?? 0n]);
|
||||
permissions.add([everyoneOverwrites?.allow.bits ?? 0n]);
|
||||
permissions.remove([roleOverwrites?.deny.bits ?? 0n]);
|
||||
permissions.add([roleOverwrites?.allow.bits ?? 0n]);
|
||||
return permissions;
|
||||
}
|
||||
|
||||
|
@ -242,18 +242,18 @@ export class GuildMember extends BaseGuildMember {
|
||||
}
|
||||
|
||||
async bannable(force = false) {
|
||||
return (await this.manageable(force)) && (await this.__me!.fetchPermissions(force)).has('BanMembers');
|
||||
return (await this.manageable(force)) && (await this.__me!.fetchPermissions(force)).has(['BanMembers']);
|
||||
}
|
||||
|
||||
async kickable(force = false) {
|
||||
return (await this.manageable(force)) && (await this.__me!.fetchPermissions(force)).has('KickMembers');
|
||||
return (await this.manageable(force)) && (await this.__me!.fetchPermissions(force)).has(['KickMembers']);
|
||||
}
|
||||
|
||||
async moderatable(force = false) {
|
||||
return (
|
||||
!(await this.roles.permissions(force)).has('Administrator') &&
|
||||
!(await this.roles.permissions(force)).has(['Administrator']) &&
|
||||
(await this.manageable(force)) &&
|
||||
(await this.__me!.fetchPermissions(force)).has('KickMembers')
|
||||
(await this.__me!.fetchPermissions(force)).has(['KickMembers'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
export type BitFieldResolvable<T extends object> = keyof T | number | bigint | (keyof T | number | bigint)[];
|
||||
export type BitFieldResolvable<T extends object> = keyof T | number | bigint;
|
||||
|
||||
export class BitField<T extends object> {
|
||||
static None = 0n;
|
||||
@ -18,17 +18,17 @@ export class BitField<T extends object> {
|
||||
return this.bit;
|
||||
}
|
||||
|
||||
has(...bits: BitFieldResolvable<T>[]) {
|
||||
has(bits: BitFieldResolvable<T>[]) {
|
||||
const bitsResolved = bits.map(bit => this.resolve(bit));
|
||||
return bitsResolved.every(bit => (this.bits & bit) === bit);
|
||||
}
|
||||
|
||||
missings(...bits: BitFieldResolvable<T>[]) {
|
||||
missings(bits: BitFieldResolvable<T>[]) {
|
||||
const bitsResolved = bits.map(bit => this.resolve(bit));
|
||||
return bitsResolved.filter(bit => (this.bits & bit) !== bit);
|
||||
}
|
||||
|
||||
equals(other: BitFieldResolvable<T>) {
|
||||
equals(other: BitFieldResolvable<T>[]) {
|
||||
return this.bits === this.resolve(other);
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ export class BitField<T extends object> {
|
||||
}, [] as bigint[]);
|
||||
}
|
||||
|
||||
add(...bits: (BitFieldResolvable<T> | undefined)[]) {
|
||||
add(bits: BitFieldResolvable<T>[]) {
|
||||
for (const bit of bits) {
|
||||
if (!bit) continue;
|
||||
this.bits |= this.resolve(bit);
|
||||
@ -62,20 +62,20 @@ export class BitField<T extends object> {
|
||||
return this.bits;
|
||||
}
|
||||
|
||||
remove(...bits: BitFieldResolvable<T>[]): bigint {
|
||||
remove(bits: BitFieldResolvable<T>[]): bigint {
|
||||
for (const bit of bits) {
|
||||
this.bits &= ~this.resolve(bit);
|
||||
}
|
||||
return this.bits;
|
||||
}
|
||||
|
||||
resolve(...bits: BitFieldResolvable<T>[]): bigint {
|
||||
resolve(bits: BitFieldResolvable<T> | BitFieldResolvable<T>[]): bigint {
|
||||
let bitsResult = 0n;
|
||||
|
||||
for (const bit of bits) {
|
||||
for (const bit of Array.isArray(bits) ? bits : [bits]) {
|
||||
switch (typeof bit) {
|
||||
case 'string':
|
||||
bitsResult |= this.resolve(this.Flags[bit]);
|
||||
bitsResult |= this.resolve([this.Flags[bit]]);
|
||||
break;
|
||||
case 'number':
|
||||
bitsResult |= BigInt(bit);
|
||||
@ -83,13 +83,6 @@ export class BitField<T extends object> {
|
||||
case 'bigint':
|
||||
bitsResult |= bit;
|
||||
break;
|
||||
case 'object': {
|
||||
if (!Array.isArray(bit)) {
|
||||
throw new TypeError(`Cannot resolve permission: ${bit}`);
|
||||
}
|
||||
bitsResult |= bits.reduce<bigint>((acc, val) => this.resolve(val) | acc, BitField.None);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new TypeError(`Cannot resolve permission: ${typeof bit === 'symbol' ? String(bit) : (bit as unknown)}`);
|
||||
}
|
||||
|
@ -6,29 +6,34 @@ export class PermissionsBitField extends BitField<typeof PermissionFlagsBits> {
|
||||
Flags = PermissionFlagsBits;
|
||||
static All = Object.values(PermissionFlagsBits).reduce((acc, value) => acc | value, 0n);
|
||||
|
||||
constructor(bitfields?: BitFieldResolvable<typeof PermissionFlagsBits>) {
|
||||
constructor(
|
||||
bitfields?: BitFieldResolvable<typeof PermissionFlagsBits> | BitFieldResolvable<typeof PermissionFlagsBits>[],
|
||||
) {
|
||||
super();
|
||||
if (bitfields) this.bit = this.resolve(bitfields);
|
||||
}
|
||||
|
||||
declare keys: (bits?: BitFieldResolvable<typeof PermissionFlagsBits>[]) => PermissionStrings;
|
||||
|
||||
has(...bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
||||
return super.has(...bits) || super.has('Administrator');
|
||||
has(bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
||||
return super.has(bits) || super.has(['Administrator']);
|
||||
}
|
||||
|
||||
strictHas(...bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
||||
return super.has(...bits);
|
||||
strictHas(bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
||||
return super.has(bits);
|
||||
}
|
||||
|
||||
resolve<T extends typeof PermissionFlagsBits>(...bits: BitFieldResolvable<T>[]): bigint {
|
||||
return bits.reduce<bigint>((acc, cur) => acc | PermissionsBitField.resolve(cur), BitField.None);
|
||||
resolve<T extends typeof PermissionFlagsBits>(bits: BitFieldResolvable<T> | BitFieldResolvable<T>[]): bigint {
|
||||
return (Array.isArray(bits) ? bits : [bits]).reduce<bigint>(
|
||||
(acc, cur) => acc | PermissionsBitField.resolve([cur]),
|
||||
BitField.None,
|
||||
);
|
||||
}
|
||||
|
||||
static resolve<T extends typeof PermissionFlagsBits>(...bits: BitFieldResolvable<T>[]): bigint {
|
||||
static resolve<T extends typeof PermissionFlagsBits>(bits: BitFieldResolvable<T> | BitFieldResolvable<T>[]): bigint {
|
||||
let bitsResult = 0n;
|
||||
|
||||
for (const bit of bits) {
|
||||
for (const bit of Array.isArray(bits) ? bits : [bits]) {
|
||||
switch (typeof bit) {
|
||||
case 'string':
|
||||
bitsResult |= PermissionsBitField.resolve(PermissionFlagsBits[bit as keyof typeof PermissionFlagsBits]);
|
||||
@ -39,13 +44,6 @@ export class PermissionsBitField extends BitField<typeof PermissionFlagsBits> {
|
||||
case 'bigint':
|
||||
bitsResult |= bit;
|
||||
break;
|
||||
case 'object': {
|
||||
if (!Array.isArray(bit)) {
|
||||
throw new TypeError(`Cannot resolve permission: ${bit}`);
|
||||
}
|
||||
bitsResult |= bit.reduce<bigint>((acc, val) => PermissionsBitField.resolve(val) | acc, BitField.None);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new TypeError(`Cannot resolve permission: ${typeof bit === 'symbol' ? String(bit) : (bit as any)}`);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ describe('PermissionsBitField', () => {
|
||||
test('add', () => {
|
||||
const p = new PermissionsBitField(['CreateEvents']);
|
||||
p.add(['AttachFiles']);
|
||||
p.add('ChangeNickname');
|
||||
p.add(['ChangeNickname']);
|
||||
assert.equal(
|
||||
p.bits,
|
||||
PermissionFlagsBits.CreateEvents | PermissionFlagsBits.AttachFiles | PermissionFlagsBits.ChangeNickname,
|
||||
@ -21,14 +21,14 @@ describe('PermissionsBitField', () => {
|
||||
|
||||
test('remove', () => {
|
||||
const p = new PermissionsBitField(['CreateEvents']);
|
||||
p.remove('CreateEvents');
|
||||
p.remove(['CreateEvents']);
|
||||
assert.equal(p.bits, BitField.None);
|
||||
});
|
||||
|
||||
test('keys', () => {
|
||||
const p = new PermissionsBitField(['CreateEvents', 'Administrator']);
|
||||
p.add(['AttachFiles']);
|
||||
p.add('ChangeNickname');
|
||||
p.add(['ChangeNickname']);
|
||||
|
||||
const keys = ['CreateEvents', 'Administrator', 'AttachFiles', 'ChangeNickname'];
|
||||
assert.equal(
|
||||
@ -40,7 +40,7 @@ describe('PermissionsBitField', () => {
|
||||
|
||||
test('values', () => {
|
||||
const p = new PermissionsBitField(['CreateEvents']);
|
||||
p.add('Administrator');
|
||||
p.add(['Administrator']);
|
||||
p.add(['ChangeNickname']);
|
||||
assert.deepEqual(p.values(), [
|
||||
PermissionFlagsBits.Administrator,
|
||||
@ -51,15 +51,15 @@ describe('PermissionsBitField', () => {
|
||||
|
||||
test('missings', () => {
|
||||
const p = new PermissionsBitField(['CreateEvents']);
|
||||
p.add('Administrator');
|
||||
p.add(['Administrator']);
|
||||
p.add(['ChangeNickname']);
|
||||
assert.deepEqual(p.missings('Connect'), [PermissionFlagsBits.Connect]);
|
||||
assert.deepEqual(p.missings(['Connect']), [PermissionFlagsBits.Connect]);
|
||||
});
|
||||
|
||||
test('equals', () => {
|
||||
const p = new PermissionsBitField(['CreateEvents']);
|
||||
p.add(['ChangeNickname']);
|
||||
assert.deepEqual(p.equals(['ChangeNickname', 'CreateEvents']), true);
|
||||
assert.deepEqual(p.equals('Connect'), false);
|
||||
assert.deepEqual(p.equals(['Connect']), false);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user