From c5e5ab54db00b94e2971c17b2927ac0a315070ca Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Sat, 31 Oct 2015 20:31:05 +0000 Subject: [PATCH] Fixed PermissionOverwrites --- lib/Client/Client.js | 13 ++- lib/Client/InternalClient.js | 2 - lib/Constants.js | 32 +++++- lib/Structures/PermissionOverwrite.js | 86 +++++++++++++++ lib/Structures/Role.js | 148 ++++++++++++++++++++++++++ lib/Structures/Server.js | 6 +- lib/Structures/ServerRole.js | 9 ++ lib/Structures/TextChannel.js | 24 +++++ src/Client/Client.js | 10 +- src/Client/InternalClient.js | 2 - src/Constants.js | 32 +++++- src/Structures/PermissionOverwrite.js | 70 ++++++++++++ src/Structures/Role.js | 139 ++++++++++++++++++++++++ src/Structures/Server.js | 7 +- src/Structures/TextChannel.js | 16 ++- 15 files changed, 584 insertions(+), 12 deletions(-) create mode 100644 lib/Structures/PermissionOverwrite.js create mode 100644 lib/Structures/Role.js create mode 100644 lib/Structures/ServerRole.js create mode 100644 src/Structures/PermissionOverwrite.js create mode 100644 src/Structures/Role.js diff --git a/lib/Client/Client.js b/lib/Client/Client.js index ed5405ee9..9f9f0841e 100644 --- a/lib/Client/Client.js +++ b/lib/Client/Client.js @@ -23,19 +23,30 @@ var Client = (function (_EventEmitter) { this.internal = new InternalClient(this); } + /* + def login + */ + Client.prototype.login = function login(email, password) { var cb = arguments.length <= 2 || arguments[2] === undefined ? function (err, token) {} : arguments[2]; var self = this; return new Promise(function (resolve, reject) { - self.internal.login(email, password).then(function (token) {})["catch"](function (e) { + self.internal.login(email, password).then(function (token) { + cb(null, token); + resolve(token); + })["catch"](function (e) { cb(e); reject(e); }); }); }; + /* + + */ + return Client; })(EventEmitter); diff --git a/lib/Client/InternalClient.js b/lib/Client/InternalClient.js index 0a9d8db1d..dc16615c7 100644 --- a/lib/Client/InternalClient.js +++ b/lib/Client/InternalClient.js @@ -153,8 +153,6 @@ var InternalClient = (function () { self.servers.add(new Server(server, client)); }); - console.log(self.servers); - break; } diff --git a/lib/Constants.js b/lib/Constants.js index 1543911d5..88469eefb 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -66,10 +66,40 @@ var Endpoints = { } }; +var Permissions = { + // general + createInstantInvite: 1 << 0, + kickMembers: 1 << 1, + banMembers: 1 << 2, + manageRoles: 1 << 3, + managePermissions: 1 << 3, + manageChannels: 1 << 4, + manageChannel: 1 << 4, + manageServer: 1 << 5, + // text + readMessages: 1 << 10, + sendMessages: 1 << 11, + sendTTSMessages: 1 << 12, + manageMessages: 1 << 13, + embedLinks: 1 << 14, + attachFiles: 1 << 15, + readMessageHistory: 1 << 16, + mentionEveryone: 1 << 17, + // voice + voiceConnect: 1 << 20, + voiceSpeak: 1 << 21, + voiceMuteMembers: 1 << 22, + voiceDeafenMembers: 1 << 23, + voiceMoveMembers: 1 << 24, + voiceUseVAD: 1 << 25 + +}; + var PacketType = { READY: "READY" }; exports.API_ENDPOINT = API; exports.Endpoints = Endpoints; -exports.PacketType = PacketType; \ No newline at end of file +exports.PacketType = PacketType; +exports.Permissions = Permissions; \ No newline at end of file diff --git a/lib/Structures/PermissionOverwrite.js b/lib/Structures/PermissionOverwrite.js new file mode 100644 index 000000000..f20d61b7a --- /dev/null +++ b/lib/Structures/PermissionOverwrite.js @@ -0,0 +1,86 @@ +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Permissions = require("../Constants.js").Permissions; + +var PermissionOverwrite = (function () { + function PermissionOverwrite(data) { + _classCallCheck(this, PermissionOverwrite); + + this.id = data.id; + this.type = data.type; // member or role + this.deny = data.deny; + this.allow = data.allow; + } + + // returns an array of allowed permissions + + PermissionOverwrite.prototype.setAllowed = function setAllowed(allowedArray) { + var _this = this; + + allowedArray.forEach(function (permission) { + if (permission instanceof String || typeof permission === "string") { + permission = Permissions[permission]; + } + if (permission) { + _this.allow |= 1 << permission; + } + }); + }; + + PermissionOverwrite.prototype.setDenied = function setDenied(deniedArray) { + var _this2 = this; + + deniedArray.forEach(function (permission) { + if (permission instanceof String || typeof permission === "string") { + permission = Permissions[permission]; + } + if (permission) { + _this2.deny |= 1 << permission; + } + }); + }; + + _createClass(PermissionOverwrite, [{ + key: "allowed", + get: function get() { + var allowed = []; + for (var permName in Permissions) { + if (permName === "manageRoles" || permName === "manageChannels") { + // these permissions do not exist in overwrites. + continue; + } + + if (!!(this.allow & Permissions[permName])) { + allowed.push(permName); + } + } + return allowed; + } + + // returns an array of denied permissions + }, { + key: "denied", + get: function get() { + var denied = []; + for (var permName in Permissions) { + if (permName === "manageRoles" || permName === "manageChannels") { + // these permissions do not exist in overwrites. + continue; + } + + if (!!(this.deny & Permissions[permName])) { + denied.push(permName); + } + } + return denied; + } + }]); + + return PermissionOverwrite; +})(); + +module.exports = PermissionOverwrite; \ No newline at end of file diff --git a/lib/Structures/Role.js b/lib/Structures/Role.js new file mode 100644 index 000000000..74b18516f --- /dev/null +++ b/lib/Structures/Role.js @@ -0,0 +1,148 @@ +"use strict"; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Permissions = require("../Constants.js").Permissions; +/* + +example data + +{ position: -1, + permissions: 36953089, + name: '@everyone', + managed: false, + id: '110007368451915776', + hoist: false, + color: 0 } +*/ + +var DefaultRole = [Permissions.createInstantInvite, Permissions.readMessages, Permissions.readMessageHistory, Permissions.sendMessages, Permissions.sendTTSMessages, Permissions.embedLinks, Permissions.attachFiles, Permissions.readMessageHistory, Permissions.mentionEveryone, Permissions.voiceConnect, Permissions.voiceSpeak, Permissions.voiceUseVAD].reduce(function (previous, current) { + return previous | current; +}, 0); + +var Role = (function () { + function Role(data, serverID, client) { + _classCallCheck(this, Role); + + this.position = data.position || -1; + this.permissions = data.permissions || DefaultRole; + this.name = data.name || "@everyone"; + this.managed = data.managed || false; + this.id = data.id; + this.hoist = data.hoist || false; + this.color = data.color || 0; + this.serverID = serverID; + this.client = client; + } + + Role.prototype.serialise = function serialise(explicit) { + var _this = this; + + var hp = function hp(perm) { + return _this.hasPermission(perm, explicit); + }; + + return { + // general + createInstantInvite: hp(Permissions.createInstantInvite), + kickMembers: hp(Permissions.kickMembers), + banMembers: hp(Permissions.banMembers), + manageRoles: hp(Permissions.manageRoles), + manageChannels: hp(Permissions.manageChannels), + manageServer: hp(Permissions.manageServer), + // text + readMessages: hp(Permissions.readMessages), + sendMessages: hp(Permissions.sendMessages), + sendTTSMessages: hp(Permissions.sendTTSMessages), + manageMessages: hp(Permissions.manageMessages), + embedLinks: hp(Permissions.embedLinks), + attachFiles: hp(Permissions.attachFiles), + readMessageHistory: hp(Permissions.readMessageHistory), + mentionEveryone: hp(Permissions.mentionEveryone), + // voice + voiceConnect: hp(Permissions.voiceConnect), + voiceSpeak: hp(Permissions.voiceSpeak), + voiceMuteMembers: hp(Permissions.voiceMuteMembers), + voiceDeafenMembers: hp(Permissions.voiceDeafenMembers), + voiceMoveMembers: hp(Permissions.voiceMoveMembers), + voiceUseVAD: hp(Permissions.voiceUseVAD) + }; + }; + + Role.prototype.serialize = function serialize() { + // ;n; + return this.serialise(); + }; + + Role.prototype.hasPermission = function hasPermission(perm) { + var explicit = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; + + if (perm instanceof String || typeof perm === "string") { + perm = Permissions[perm]; + } + if (!perm) { + return false; + } + if (!explicit) { + // implicit permissions allowed + if (!!(this.permissions & Permissions.manageRoles)) { + // manageRoles allowed, they have all permissions + return true; + } + } + // e.g. + // !!(36953089 & Permissions.manageRoles) = not allowed to manage roles + // !!(36953089 & (1 << 21)) = voice speak allowed + + return !!(this.permissions & perm); + }; + + Role.prototype.setPermission = function setPermission(permission, value) { + if (permission instanceof String || typeof permission === "string") { + permission = Permissions[permission]; + } + if (permission) { + // valid permission + if (value) { + this.permissions |= permission; + } else { + this.permissions &= ~permission; + } + } + }; + + Role.prototype.setPermissions = function setPermissions(obj) { + var _this2 = this; + + obj.forEach(function (value, permission) { + if (permission instanceof String || typeof permission === "string") { + permission = Permissions[permission]; + } + if (permission) { + // valid permission + _this2.setPermission(permission, value); + } + }); + }; + + Role.prototype.colorAsHex = function colorAsHex() { + var val = this.color.toString(); + while (val.length < 6) { + val = "0" + val; + } + return "#" + val; + }; + + _createClass(Role, [{ + key: "server", + get: function get() { + return this.client.internal.servers.get("id", this.serverID); + } + }]); + + return Role; +})(); + +module.exports = Role; \ No newline at end of file diff --git a/lib/Structures/Server.js b/lib/Structures/Server.js index e4dabccd4..7827a2b39 100644 --- a/lib/Structures/Server.js +++ b/lib/Structures/Server.js @@ -13,6 +13,7 @@ var User = require("./User.js"); var Member = require("./Member.js"); var TextChannel = require("./TextChannel.js"); var VoiceChannel = require("./VoiceChannel.js"); +var Role = require("./Role.js"); var Server = (function (_Equality) { _inherits(Server, _Equality); @@ -44,7 +45,6 @@ var Server = (function (_Equality) { }); data.channels.forEach(function (dataChannel) { - if (dataChannel.type === "text") { var channel = client.internal.channels.add(new TextChannel(dataChannel, client)); _this.channels.add(channel); @@ -53,6 +53,10 @@ var Server = (function (_Equality) { _this.channels.add(channel); } }); + + data.roles.forEach(function (dataRole) { + _this.roles.add(new Role(dataRole, _this)); + }); } Server.prototype.toString = function toString() { diff --git a/lib/Structures/ServerRole.js b/lib/Structures/ServerRole.js new file mode 100644 index 000000000..41001accb --- /dev/null +++ b/lib/Structures/ServerRole.js @@ -0,0 +1,9 @@ +"use strict"; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ServerRole = function ServerRole() { + _classCallCheck(this, ServerRole); +}; + +module.exports = ServerRole; \ No newline at end of file diff --git a/lib/Structures/TextChannel.js b/lib/Structures/TextChannel.js index 7616fe915..3ff7c445d 100644 --- a/lib/Structures/TextChannel.js +++ b/lib/Structures/TextChannel.js @@ -1,22 +1,46 @@ "use strict"; +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Channel = require("./Channel.js"); var Cache = require("../Util/Cache.js"); +var PermissionOverwrite = require("./PermissionOverwrite.js"); var TextChannel = (function (_Channel) { _inherits(TextChannel, _Channel); function TextChannel(data, client) { + var _this = this; + _classCallCheck(this, TextChannel); _Channel.call(this, data, client); + + this.name = data.name; + this.topic = data.topic; + this.position = data.position; + this.lastMessageID = data.last_message_id; this.messages = new Cache("id", client.options.maximumMessages); + + this.permissionOverwrites = new Cache(); + data.permission_overwrites.forEach(function (permission) { + _this.permissionOverwrites.add(new PermissionOverwrite(permission)); + }); } + /* warning! may return null */ + + _createClass(TextChannel, [{ + key: "lastMessage", + get: function get() { + return this.messages.get("id", this.lastMessageID); + } + }]); + return TextChannel; })(Channel); diff --git a/src/Client/Client.js b/src/Client/Client.js index 056d1a2a8..0ed7092d4 100644 --- a/src/Client/Client.js +++ b/src/Client/Client.js @@ -14,13 +14,17 @@ class Client extends EventEmitter{ this.internal = new InternalClient(this); } + /* + def login + */ login(email, password, cb=function(err, token){}){ var self = this; return new Promise(function(resolve, reject){ self.internal.login(email, password) .then((token)=>{ - + cb(null, token); + resolve(token); }) .catch((e)=>{ cb(e); @@ -30,6 +34,10 @@ class Client extends EventEmitter{ }); } + /* + + */ + } module.exports = Client; \ No newline at end of file diff --git a/src/Client/InternalClient.js b/src/Client/InternalClient.js index 2c5a9121f..57432f906 100644 --- a/src/Client/InternalClient.js +++ b/src/Client/InternalClient.js @@ -163,8 +163,6 @@ class InternalClient { self.servers.add(new Server(server, client)); }); - console.log(self.servers); - break; } diff --git a/src/Constants.js b/src/Constants.js index 9c414600b..d0bf4576d 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -30,10 +30,40 @@ var Endpoints = { CHANNEL_PERMISSIONS: (channelID) => `${Endpoints.CHANNEL(channelID) }/permissions`, }; +var Permissions = { + // general + createInstantInvite: 1 << 0, + kickMembers: 1 << 1, + banMembers: 1 << 2, + manageRoles: 1 << 3, + managePermissions: 1 << 3, + manageChannels: 1 << 4, + manageChannel: 1 << 4, + manageServer: 1 << 5, + // text + readMessages: 1 << 10, + sendMessages: 1 << 11, + sendTTSMessages: 1 << 12, + manageMessages: 1 << 13, + embedLinks: 1 << 14, + attachFiles: 1 << 15, + readMessageHistory: 1 << 16, + mentionEveryone: 1 << 17, + // voice + voiceConnect: 1 << 20, + voiceSpeak: 1 << 21, + voiceMuteMembers: 1 << 22, + voiceDeafenMembers: 1 << 23, + voiceMoveMembers: 1 << 24, + voiceUseVAD: 1 << 25 + +}; + var PacketType = { READY : "READY" } exports.API_ENDPOINT = API; exports.Endpoints = Endpoints; -exports.PacketType = PacketType; \ No newline at end of file +exports.PacketType = PacketType; +exports.Permissions = Permissions; \ No newline at end of file diff --git a/src/Structures/PermissionOverwrite.js b/src/Structures/PermissionOverwrite.js new file mode 100644 index 000000000..1cca7def7 --- /dev/null +++ b/src/Structures/PermissionOverwrite.js @@ -0,0 +1,70 @@ +"use strict"; + +var Permissions = require("../Constants.js").Permissions; + +class PermissionOverwrite { + + constructor(data) { + this.id = data.id; + this.type = data.type; // member or role + this.deny = data.deny; + this.allow = data.allow; + } + + // returns an array of allowed permissions + get allowed(){ + var allowed = []; + for( var permName in Permissions ){ + if(permName === "manageRoles" || permName === "manageChannels"){ + // these permissions do not exist in overwrites. + continue; + } + + if(!!(this.allow & Permissions[permName])){ + allowed.push(permName); + } + } + return allowed; + } + + // returns an array of denied permissions + get denied(){ + var denied = []; + for( var permName in Permissions ){ + if(permName === "manageRoles" || permName === "manageChannels"){ + // these permissions do not exist in overwrites. + continue; + } + + if(!!(this.deny & Permissions[permName])){ + denied.push(permName); + } + } + return denied; + } + + setAllowed(allowedArray){ + allowedArray.forEach( (permission) => { + if(permission instanceof String || typeof permission === "string"){ + permission = Permissions[permission]; + } + if(permission){ + this.allow |= (1 << permission); + } + } ); + } + + setDenied(deniedArray){ + deniedArray.forEach( (permission) => { + if(permission instanceof String || typeof permission === "string"){ + permission = Permissions[permission]; + } + if(permission){ + this.deny |= (1 << permission); + } + } ); + } + +} + +module.exports = PermissionOverwrite; \ No newline at end of file diff --git a/src/Structures/Role.js b/src/Structures/Role.js new file mode 100644 index 000000000..2e4c62f80 --- /dev/null +++ b/src/Structures/Role.js @@ -0,0 +1,139 @@ +"use strict"; +var Permissions = require("../Constants.js").Permissions; +/* + +example data + +{ position: -1, + permissions: 36953089, + name: '@everyone', + managed: false, + id: '110007368451915776', + hoist: false, + color: 0 } +*/ + +const DefaultRole = [ + Permissions.createInstantInvite, + Permissions.readMessages, + Permissions.readMessageHistory, + Permissions.sendMessages, + Permissions.sendTTSMessages, + Permissions.embedLinks, + Permissions.attachFiles, + Permissions.readMessageHistory, + Permissions.mentionEveryone, + Permissions.voiceConnect, + Permissions.voiceSpeak, + Permissions.voiceUseVAD +].reduce( (previous, current) => previous | current, 0 ); + +class Role{ + constructor(data, serverID, client){ + this.position = data.position || -1; + this.permissions = data.permissions || DefaultRole; + this.name = data.name || "@everyone"; + this.managed = data.managed || false; + this.id = data.id; + this.hoist = data.hoist || false; + this.color = data.color || 0; + this.serverID = serverID; + this.client = client; + } + + get server(){ + return this.client.internal.servers.get("id", this.serverID); + } + + serialise(explicit){ + + var hp = (perm) => this.hasPermission(perm, explicit); + + return { + // general + createInstantInvite : hp( Permissions.createInstantInvite ), + kickMembers : hp( Permissions.kickMembers ), + banMembers : hp( Permissions.banMembers ), + manageRoles : hp ( Permissions.manageRoles ), + manageChannels : hp( Permissions.manageChannels ), + manageServer : hp( Permissions.manageServer ), + // text + readMessages : hp( Permissions.readMessages ), + sendMessages : hp( Permissions.sendMessages ), + sendTTSMessages : hp( Permissions.sendTTSMessages ), + manageMessages : hp( Permissions.manageMessages ), + embedLinks : hp( Permissions.embedLinks ), + attachFiles : hp( Permissions.attachFiles ), + readMessageHistory : hp( Permissions.readMessageHistory ), + mentionEveryone : hp( Permissions.mentionEveryone ), + // voice + voiceConnect : hp( Permissions.voiceConnect ), + voiceSpeak : hp( Permissions.voiceSpeak ), + voiceMuteMembers : hp( Permissions.voiceMuteMembers ), + voiceDeafenMembers : hp( Permissions.voiceDeafenMembers ), + voiceMoveMembers : hp( Permissions.voiceMoveMembers ), + voiceUseVAD : hp( Permissions.voiceUseVAD ) + }; + } + + serialize(){ + // ;n; + return this.serialise(); + } + + hasPermission(perm, explicit=false){ + if( perm instanceof String || typeof perm === "string" ){ + perm = Permissions[perm]; + } + if(!perm){ + return false; + } + if(!explicit){ // implicit permissions allowed + if( !!(this.permissions & Permissions.manageRoles) ){ + // manageRoles allowed, they have all permissions + return true; + } + } + // e.g. + // !!(36953089 & Permissions.manageRoles) = not allowed to manage roles + // !!(36953089 & (1 << 21)) = voice speak allowed + + return !!(this.permissions & perm); + } + + setPermission(permission, value){ + if( permission instanceof String || typeof permission === "string" ){ + permission = Permissions[permission]; + } + if(permission){ + // valid permission + if(value){ + this.permissions |= permission; + }else{ + this.permissions &= ~permission; + } + } + } + + setPermissions(obj){ + obj.forEach((value, permission) => { + if( permission instanceof String || typeof permission === "string" ){ + permission = Permissions[permission]; + } + if(permission){ + // valid permission + this.setPermission(permission, value); + } + }); + } + + colorAsHex(){ + var val = this.color.toString(); + while(val.length < 6){ + val = "0" + val; + } + return "#"+val; + } +} + +module.exports = Role; \ No newline at end of file diff --git a/src/Structures/Server.js b/src/Structures/Server.js index 84eb5ba14..a2c8203d4 100644 --- a/src/Structures/Server.js +++ b/src/Structures/Server.js @@ -7,6 +7,7 @@ var User = require("./User.js"); var Member = require("./Member.js"); var TextChannel = require("./TextChannel.js"); var VoiceChannel = require("./VoiceChannel.js"); +var Role = require("./Role.js"); class Server extends Equality { constructor(data, client) { @@ -33,7 +34,6 @@ class Server extends Equality { } ); data.channels.forEach( (dataChannel) => { - if(dataChannel.type === "text"){ var channel = client.internal.channels.add(new TextChannel(dataChannel, client)); this.channels.add(channel); @@ -41,7 +41,10 @@ class Server extends Equality { var channel = client.internal.channels.add(new VoiceChannel(dataChannel, client)); this.channels.add(channel); } - + } ); + + data.roles.forEach( (dataRole) => { + this.roles.add( new Role(dataRole, this) ); } ); } diff --git a/src/Structures/TextChannel.js b/src/Structures/TextChannel.js index df3881be4..adbc28b31 100644 --- a/src/Structures/TextChannel.js +++ b/src/Structures/TextChannel.js @@ -2,13 +2,27 @@ var Channel = require("./Channel.js"); var Cache = require("../Util/Cache.js"); +var PermissionOverwrite = require("./PermissionOverwrite.js"); class TextChannel extends Channel{ constructor(data, client){ - super(data, client); + + this.name = data.name; + this.topic = data.topic; + this.position = data.position; + this.lastMessageID = data.last_message_id; this.messages = new Cache("id", client.options.maximumMessages); + + this.permissionOverwrites = new Cache(); + data.permission_overwrites.forEach((permission) => { + this.permissionOverwrites.add( new PermissionOverwrite(permission) ); + }); + } + /* warning! may return null */ + get lastMessage(){ + return this.messages.get("id", this.lastMessageID); } }