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) {
|
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) {
|
if (permissions.length) {
|
||||||
return app.keys(permissions);
|
return app.keys(permissions);
|
||||||
}
|
}
|
||||||
|
@ -523,14 +523,14 @@ export class CommandHandler extends BaseHandler {
|
|||||||
option.onPermissionsFail?.bind(option) ??
|
option.onPermissionsFail?.bind(option) ??
|
||||||
commandInstance.onPermissionsFail?.bind(commandInstance) ??
|
commandInstance.onPermissionsFail?.bind(commandInstance) ??
|
||||||
this.client.options.commands?.defaults?.onPermissionsFail;
|
this.client.options.commands?.defaults?.onPermissionsFail;
|
||||||
option.botPermissions = PermissionsBitField.resolve(
|
option.botPermissions = PermissionsBitField.resolve([
|
||||||
option.botPermissions ?? PermissionsBitField.None,
|
option.botPermissions ?? PermissionsBitField.None,
|
||||||
commandInstance.botPermissions ?? PermissionsBitField.None,
|
commandInstance.botPermissions ?? PermissionsBitField.None,
|
||||||
);
|
]);
|
||||||
option.defaultMemberPermissions ??= PermissionsBitField.resolve(
|
option.defaultMemberPermissions ??= PermissionsBitField.resolve([
|
||||||
option.defaultMemberPermissions ?? PermissionsBitField.None,
|
option.defaultMemberPermissions ?? PermissionsBitField.None,
|
||||||
commandInstance.defaultMemberPermissions ?? PermissionsBitField.None,
|
commandInstance.defaultMemberPermissions ?? PermissionsBitField.None,
|
||||||
);
|
]);
|
||||||
option.contexts ??= commandInstance.contexts;
|
option.contexts ??= commandInstance.contexts;
|
||||||
option.integrationTypes ??= commandInstance.integrationTypes;
|
option.integrationTypes ??= commandInstance.integrationTypes;
|
||||||
option.props ??= commandInstance.props;
|
option.props ??= commandInstance.props;
|
||||||
|
@ -154,19 +154,19 @@ export class ChannelShorter extends BaseShorter {
|
|||||||
async memberPermissions(channelId: string, member: GuildMember, checkAdmin = true): Promise<PermissionsBitField> {
|
async memberPermissions(channelId: string, member: GuildMember, checkAdmin = true): Promise<PermissionsBitField> {
|
||||||
const memberPermissions = await member.fetchPermissions();
|
const memberPermissions = await member.fetchPermissions();
|
||||||
|
|
||||||
if (checkAdmin && memberPermissions.has(PermissionFlagsBits.Administrator)) {
|
if (checkAdmin && memberPermissions.has([PermissionFlagsBits.Administrator])) {
|
||||||
return new PermissionsBitField(PermissionsBitField.All);
|
return new PermissionsBitField(PermissionsBitField.All);
|
||||||
}
|
}
|
||||||
|
|
||||||
const overwrites = await this.overwritesFor(channelId, member);
|
const overwrites = await this.overwritesFor(channelId, member);
|
||||||
const permissions = new PermissionsBitField(memberPermissions.bits);
|
const permissions = new PermissionsBitField(memberPermissions.bits);
|
||||||
|
|
||||||
permissions.remove(overwrites.everyone?.deny.bits ?? 0n);
|
permissions.remove([overwrites.everyone?.deny.bits ?? 0n]);
|
||||||
permissions.add(overwrites.everyone?.allow.bits ?? 0n);
|
permissions.add([overwrites.everyone?.allow.bits ?? 0n]);
|
||||||
permissions.remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny.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.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow.bits) : [0n]);
|
||||||
permissions.remove(overwrites.member?.deny.bits ?? 0n);
|
permissions.remove([overwrites.member?.deny.bits ?? 0n]);
|
||||||
permissions.add(overwrites.member?.allow.bits ?? 0n);
|
permissions.add([overwrites.member?.allow.bits ?? 0n]);
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ export class ChannelShorter extends BaseShorter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async rolePermissions(channelId: string, role: GuildRole, checkAdmin = true): Promise<PermissionsBitField> {
|
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);
|
return new PermissionsBitField(PermissionsBitField.All);
|
||||||
}
|
}
|
||||||
const channelOverwrites = (await this.client.cache.overwrites?.get(channelId)) ?? [];
|
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 roleOverwrites = channelOverwrites.find(x => x.id === role.id);
|
||||||
const permissions = new PermissionsBitField(role.permissions.bits);
|
const permissions = new PermissionsBitField(role.permissions.bits);
|
||||||
|
|
||||||
permissions.remove(everyoneOverwrites?.deny.bits ?? 0n);
|
permissions.remove([everyoneOverwrites?.deny.bits ?? 0n]);
|
||||||
permissions.add(everyoneOverwrites?.allow.bits ?? 0n);
|
permissions.add([everyoneOverwrites?.allow.bits ?? 0n]);
|
||||||
permissions.remove(roleOverwrites?.deny.bits ?? 0n);
|
permissions.remove([roleOverwrites?.deny.bits ?? 0n]);
|
||||||
permissions.add(roleOverwrites?.allow.bits ?? 0n);
|
permissions.add([roleOverwrites?.allow.bits ?? 0n]);
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,18 +242,18 @@ export class GuildMember extends BaseGuildMember {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async bannable(force = false) {
|
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) {
|
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) {
|
async moderatable(force = false) {
|
||||||
return (
|
return (
|
||||||
!(await this.roles.permissions(force)).has('Administrator') &&
|
!(await this.roles.permissions(force)).has(['Administrator']) &&
|
||||||
(await this.manageable(force)) &&
|
(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> {
|
export class BitField<T extends object> {
|
||||||
static None = 0n;
|
static None = 0n;
|
||||||
@ -18,17 +18,17 @@ export class BitField<T extends object> {
|
|||||||
return this.bit;
|
return this.bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
has(...bits: BitFieldResolvable<T>[]) {
|
has(bits: BitFieldResolvable<T>[]) {
|
||||||
const bitsResolved = bits.map(bit => this.resolve(bit));
|
const bitsResolved = bits.map(bit => this.resolve(bit));
|
||||||
return bitsResolved.every(bit => (this.bits & bit) === 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));
|
const bitsResolved = bits.map(bit => this.resolve(bit));
|
||||||
return bitsResolved.filter(bit => (this.bits & bit) !== bit);
|
return bitsResolved.filter(bit => (this.bits & bit) !== bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
equals(other: BitFieldResolvable<T>) {
|
equals(other: BitFieldResolvable<T>[]) {
|
||||||
return this.bits === this.resolve(other);
|
return this.bits === this.resolve(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ export class BitField<T extends object> {
|
|||||||
}, [] as bigint[]);
|
}, [] as bigint[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
add(...bits: (BitFieldResolvable<T> | undefined)[]) {
|
add(bits: BitFieldResolvable<T>[]) {
|
||||||
for (const bit of bits) {
|
for (const bit of bits) {
|
||||||
if (!bit) continue;
|
if (!bit) continue;
|
||||||
this.bits |= this.resolve(bit);
|
this.bits |= this.resolve(bit);
|
||||||
@ -62,20 +62,20 @@ export class BitField<T extends object> {
|
|||||||
return this.bits;
|
return this.bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(...bits: BitFieldResolvable<T>[]): bigint {
|
remove(bits: BitFieldResolvable<T>[]): bigint {
|
||||||
for (const bit of bits) {
|
for (const bit of bits) {
|
||||||
this.bits &= ~this.resolve(bit);
|
this.bits &= ~this.resolve(bit);
|
||||||
}
|
}
|
||||||
return this.bits;
|
return this.bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(...bits: BitFieldResolvable<T>[]): bigint {
|
resolve(bits: BitFieldResolvable<T> | BitFieldResolvable<T>[]): bigint {
|
||||||
let bitsResult = 0n;
|
let bitsResult = 0n;
|
||||||
|
|
||||||
for (const bit of bits) {
|
for (const bit of Array.isArray(bits) ? bits : [bits]) {
|
||||||
switch (typeof bit) {
|
switch (typeof bit) {
|
||||||
case 'string':
|
case 'string':
|
||||||
bitsResult |= this.resolve(this.Flags[bit]);
|
bitsResult |= this.resolve([this.Flags[bit]]);
|
||||||
break;
|
break;
|
||||||
case 'number':
|
case 'number':
|
||||||
bitsResult |= BigInt(bit);
|
bitsResult |= BigInt(bit);
|
||||||
@ -83,13 +83,6 @@ export class BitField<T extends object> {
|
|||||||
case 'bigint':
|
case 'bigint':
|
||||||
bitsResult |= bit;
|
bitsResult |= bit;
|
||||||
break;
|
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:
|
default:
|
||||||
throw new TypeError(`Cannot resolve permission: ${typeof bit === 'symbol' ? String(bit) : (bit as unknown)}`);
|
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;
|
Flags = PermissionFlagsBits;
|
||||||
static All = Object.values(PermissionFlagsBits).reduce((acc, value) => acc | value, 0n);
|
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();
|
super();
|
||||||
if (bitfields) this.bit = this.resolve(bitfields);
|
if (bitfields) this.bit = this.resolve(bitfields);
|
||||||
}
|
}
|
||||||
|
|
||||||
declare keys: (bits?: BitFieldResolvable<typeof PermissionFlagsBits>[]) => PermissionStrings;
|
declare keys: (bits?: BitFieldResolvable<typeof PermissionFlagsBits>[]) => PermissionStrings;
|
||||||
|
|
||||||
has(...bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
has(bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
||||||
return super.has(...bits) || super.has('Administrator');
|
return super.has(bits) || super.has(['Administrator']);
|
||||||
}
|
}
|
||||||
|
|
||||||
strictHas(...bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
strictHas(bits: BitFieldResolvable<typeof PermissionFlagsBits>[]) {
|
||||||
return super.has(...bits);
|
return super.has(bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve<T extends typeof PermissionFlagsBits>(...bits: BitFieldResolvable<T>[]): bigint {
|
resolve<T extends typeof PermissionFlagsBits>(bits: BitFieldResolvable<T> | BitFieldResolvable<T>[]): bigint {
|
||||||
return bits.reduce<bigint>((acc, cur) => acc | PermissionsBitField.resolve(cur), BitField.None);
|
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;
|
let bitsResult = 0n;
|
||||||
|
|
||||||
for (const bit of bits) {
|
for (const bit of Array.isArray(bits) ? bits : [bits]) {
|
||||||
switch (typeof bit) {
|
switch (typeof bit) {
|
||||||
case 'string':
|
case 'string':
|
||||||
bitsResult |= PermissionsBitField.resolve(PermissionFlagsBits[bit as keyof typeof PermissionFlagsBits]);
|
bitsResult |= PermissionsBitField.resolve(PermissionFlagsBits[bit as keyof typeof PermissionFlagsBits]);
|
||||||
@ -39,13 +44,6 @@ export class PermissionsBitField extends BitField<typeof PermissionFlagsBits> {
|
|||||||
case 'bigint':
|
case 'bigint':
|
||||||
bitsResult |= bit;
|
bitsResult |= bit;
|
||||||
break;
|
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:
|
default:
|
||||||
throw new TypeError(`Cannot resolve permission: ${typeof bit === 'symbol' ? String(bit) : (bit as any)}`);
|
throw new TypeError(`Cannot resolve permission: ${typeof bit === 'symbol' ? String(bit) : (bit as any)}`);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ describe('PermissionsBitField', () => {
|
|||||||
test('add', () => {
|
test('add', () => {
|
||||||
const p = new PermissionsBitField(['CreateEvents']);
|
const p = new PermissionsBitField(['CreateEvents']);
|
||||||
p.add(['AttachFiles']);
|
p.add(['AttachFiles']);
|
||||||
p.add('ChangeNickname');
|
p.add(['ChangeNickname']);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
p.bits,
|
p.bits,
|
||||||
PermissionFlagsBits.CreateEvents | PermissionFlagsBits.AttachFiles | PermissionFlagsBits.ChangeNickname,
|
PermissionFlagsBits.CreateEvents | PermissionFlagsBits.AttachFiles | PermissionFlagsBits.ChangeNickname,
|
||||||
@ -21,14 +21,14 @@ describe('PermissionsBitField', () => {
|
|||||||
|
|
||||||
test('remove', () => {
|
test('remove', () => {
|
||||||
const p = new PermissionsBitField(['CreateEvents']);
|
const p = new PermissionsBitField(['CreateEvents']);
|
||||||
p.remove('CreateEvents');
|
p.remove(['CreateEvents']);
|
||||||
assert.equal(p.bits, BitField.None);
|
assert.equal(p.bits, BitField.None);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('keys', () => {
|
test('keys', () => {
|
||||||
const p = new PermissionsBitField(['CreateEvents', 'Administrator']);
|
const p = new PermissionsBitField(['CreateEvents', 'Administrator']);
|
||||||
p.add(['AttachFiles']);
|
p.add(['AttachFiles']);
|
||||||
p.add('ChangeNickname');
|
p.add(['ChangeNickname']);
|
||||||
|
|
||||||
const keys = ['CreateEvents', 'Administrator', 'AttachFiles', 'ChangeNickname'];
|
const keys = ['CreateEvents', 'Administrator', 'AttachFiles', 'ChangeNickname'];
|
||||||
assert.equal(
|
assert.equal(
|
||||||
@ -40,7 +40,7 @@ describe('PermissionsBitField', () => {
|
|||||||
|
|
||||||
test('values', () => {
|
test('values', () => {
|
||||||
const p = new PermissionsBitField(['CreateEvents']);
|
const p = new PermissionsBitField(['CreateEvents']);
|
||||||
p.add('Administrator');
|
p.add(['Administrator']);
|
||||||
p.add(['ChangeNickname']);
|
p.add(['ChangeNickname']);
|
||||||
assert.deepEqual(p.values(), [
|
assert.deepEqual(p.values(), [
|
||||||
PermissionFlagsBits.Administrator,
|
PermissionFlagsBits.Administrator,
|
||||||
@ -51,15 +51,15 @@ describe('PermissionsBitField', () => {
|
|||||||
|
|
||||||
test('missings', () => {
|
test('missings', () => {
|
||||||
const p = new PermissionsBitField(['CreateEvents']);
|
const p = new PermissionsBitField(['CreateEvents']);
|
||||||
p.add('Administrator');
|
p.add(['Administrator']);
|
||||||
p.add(['ChangeNickname']);
|
p.add(['ChangeNickname']);
|
||||||
assert.deepEqual(p.missings('Connect'), [PermissionFlagsBits.Connect]);
|
assert.deepEqual(p.missings(['Connect']), [PermissionFlagsBits.Connect]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('equals', () => {
|
test('equals', () => {
|
||||||
const p = new PermissionsBitField(['CreateEvents']);
|
const p = new PermissionsBitField(['CreateEvents']);
|
||||||
p.add(['ChangeNickname']);
|
p.add(['ChangeNickname']);
|
||||||
assert.deepEqual(p.equals(['ChangeNickname', 'CreateEvents']), true);
|
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