backport: GuildChannel#permissionsFor(role)

This commit is contained in:
Lewdcario
2018-08-08 22:16:46 -05:00
parent c76f3048af
commit 1e5b5b83c8
2 changed files with 52 additions and 29 deletions

View File

@@ -74,44 +74,63 @@ class GuildChannel extends Channel {
} }
/** /**
* Gets the overall set of permissions for a user in this channel, taking into account roles and permission * Gets the overall set of permissions for a user in this channel, taking into account channel overwrites.
* overwrites.
* @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for
* @returns {?Permissions} * @returns {?Permissions}
*/ */
permissionsFor(member) { memberPermissions(member) {
member = this.client.resolver.resolveGuildMember(this.guild, member); member = this.client.resolver.resolveGuildMember(this.guild, member);
if (!member) return null; if (!member) return null;
if (member.id === this.guild.ownerID) return new Permissions(member, Permissions.ALL); if (member.id === this.guild.ownerID) return new Permissions(member, Permissions.ALL);
let permissions = 0;
const roles = member.roles; const roles = member.roles;
for (const role of roles.values()) permissions |= role.permissions; const permissions = new Permissions(roles.map(role => role.permissions));
const admin = Boolean(permissions & Permissions.FLAGS.ADMINISTRATOR); if (permissions.has(Permissions.FLAGS.ADMINISTRATOR)) return new Permissions(Permissions.ALL).freeze();
if (admin) return new Permissions(Permissions.ALL);
const overwrites = this.overwritesFor(member, true, roles); const overwrites = this.overwritesFor(member, true, roles);
if (overwrites.everyone) { return permissions
permissions &= ~overwrites.everyone.deny; .remove(overwrites.everyone ? overwrites.everyone.deny : 0)
permissions |= overwrites.everyone.allow; .add(overwrites.everyone ? overwrites.everyone.allow : 0)
} .remove(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.deny) : 0)
.add(overwrites.roles.length > 0 ? overwrites.roles.map(role => role.allow) : 0)
.remove(overwrites.member ? overwrites.member.deny : 0)
.add(overwrites.member ? overwrites.member.allow : 0)
.freeze();
}
let allow = 0; /**
for (const overwrite of overwrites.roles) { * Gets the overall set of permissions for a role in this channel, taking into account channel overwrites.
permissions &= ~overwrite.deny; * @param {RoleResolvable} role The role that you want to obtain the overall permissions for
allow |= overwrite.allow; * @returns {?Permissions}
} */
permissions |= allow; rolePermissions(role) {
if (role.permissions & Permissions.FLAGS.ADMINISTRATOR) return new Permissions(Permissions.ALL).freeze();
if (overwrites.member) { const everyoneOverwrites = this.permissionOverwrites.get(this.guild.id);
permissions &= ~overwrites.member.deny; const roleOverwrites = this.permissionOverwrites.get(role.id);
permissions |= overwrites.member.allow;
}
return new Permissions(member, permissions); return new Permissions(role.permissions)
.remove(everyoneOverwrites ? everyoneOverwrites.deny : 0)
.add(everyoneOverwrites ? everyoneOverwrites.allow : 0)
.remove(roleOverwrites ? roleOverwrites.deny : 0)
.add(roleOverwrites ? roleOverwrites.allow : 0)
.freeze();
}
/**
* Get the overall set of permissions for a member or role in this channel, taking into account channel overwrites.
* @param {GuildMemberResolvable|RoleResolvable} memberOrRole The member or role to obtain the overall permissions for
* @returns {?Permissions}
*/
permissionsFor(memberOrRole) {
const member = this.guild.member(memberOrRole);
if (member) return this.memberPermissions(member);
const role = this.client.resolver.resolveRole(this.guild, memberOrRole);
if (role) return this.rolePermissions(role);
return null;
} }
overwritesFor(member, verified = false, roles = null) { overwritesFor(member, verified = false, roles = null) {

View File

@@ -82,11 +82,13 @@ class Permissions {
*/ */
add(...permissions) { add(...permissions) {
let total = 0; let total = 0;
for (let p = 0; p < permissions.length; p++) { for (let p = permissions.length - 1; p >= 0; p--) {
const perm = this.constructor.resolve(permissions[p]); const perm = this.constructor.resolve(permissions[p]);
if ((this.bitfield & perm) !== perm) total |= perm; total |= perm;
} }
return new this.constructor(this.member, this.bitfield | total); if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total);
this.bitfield |= total;
return this;
} }
/** /**
@@ -96,11 +98,13 @@ class Permissions {
*/ */
remove(...permissions) { remove(...permissions) {
let total = 0; let total = 0;
for (let p = 0; p < permissions.length; p++) { for (let p = permissions.length - 1; p >= 0; p--) {
const perm = this.constructor.resolve(permissions[p]); const perm = this.constructor.resolve(permissions[p]);
if ((this.bitfield & perm) === perm) total |= perm; total |= perm;
} }
return new this.constructor(this.member, this.bitfield & ~total); if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total);
this.bitfield &= ~total;
return this;
} }
/** /**