diff --git a/.npmignore b/.npmignore index d7d6c67e1..37d39c7f3 100644 --- a/.npmignore +++ b/.npmignore @@ -2,4 +2,5 @@ docs/ examples/ web-dist/ +src/ .travis.yml \ No newline at end of file diff --git a/examples/adminbot.js b/examples/adminbot.js new file mode 100644 index 000000000..740070b7e --- /dev/null +++ b/examples/adminbot.js @@ -0,0 +1,101 @@ +/* + this bot is a permissions bot and is currently working + with the experimental additions. Some functions may + change in the future. +*/ + +var Discord = require("../"); + +// Get the email and password +var AuthDetails = require("./auth.json"); + +var bot = new Discord.Client(); + +bot.on("ready", function () { + console.log("Ready to begin! Serving in " + bot.channels.length + " channels"); +}); + +bot.on("disconnected", function () { + + console.log("Disconnected!"); + process.exit(1); //exit node.js with an error + +}); + +bot.on("message", function (msg) { + if (msg.content === "skype") { + + //stop the user from speaking in the channel: + bot.overwritePermissions(msg.channel, msg.sender, { + sendMessages : false + }); + + // send a barely funny message ;) + bot.reply(msg, "how dare you mention that!"); + + } + + if (msg.content === "discord") { + + // see if there is a permission called 'good people' in the server already + var found = false; + + for(var role of msg.channel.server.roles){ + if(role.name === "good people"){ + found = role; + break; + } + } + + // if the role doesn't exist, make it + if(!found){ + bot.createRole(msg.channel.server, { + name : "good people", + color : Discord.Colors.BLUE, // colour of blue + hoist : true // make a seperate category in the users list + }).then(addUserToList); + }else{ + addUserToList(role); + } + + function addUserToList(role){ + + bot.addMemberToRole(msg.sender, role); + bot.reply(msg, "welcome to the good people!"); + + } + + } + + if( msg.content === "remove me" ){ + // remove the user from the good people list, if it exists + var found = false; + + for(var role of msg.channel.server.roles){ + if(role.name === "good people"){ + found = role; + break; + } + } + + if(found){ + // if the role exists + + if( msg.sender.hasRole(role) ){ + // remove the member from the role + bot.removeMemberFromRole(msg.sender, role); + bot.reply(msg, "removed!") + }else{ + bot.reply(msg, "you're not in the role!"); + } + + }else{ + // role doesn't exist + bot.reply(msg, "the role doesn't even exist!"); + } + + } + +}); + +bot.login("riftes@outlook.com", "bananaman"); \ No newline at end of file diff --git a/lib/ChannelPermissions.js b/lib/ChannelPermissions.js index 5193b5938..49c0c0c31 100644 --- a/lib/ChannelPermissions.js +++ b/lib/ChannelPermissions.js @@ -30,13 +30,85 @@ var ChannelPermissions = (function () { this.allow = data.allow; } + ChannelPermissions.prototype.serialise = function serialise() { + return { + createInstantInvite: this.createInstantInvite, + manageRoles: this.manageRoles, + manageChannels: this.manageChannels, + readMessages: this.readMessages, + sendMessages: this.sendMessage, + sendTTSMessages: this.sendTTSMessages, + manageMessages: this.manageMessages, + embedLinks: this.embedLinks, + attachFiles: this.attachFiles, + readMessageHistory: this.readMessageHistory, + mentionEveryone: this.mentionEveryone, + voiceConnect: this.voiceConnect, + voiceSpeak: this.voiceSpeak, + voiceMuteMembers: this.voiceMuteMembers, + voiceDeafenMembers: this.voiceDeafenMembers, + voiceMoveMember: this.voiceMoveMembers, + voiceUseVoiceActivation: this.voiceUseVoiceActivation + }; + }; + ChannelPermissions.prototype.getBit = function getBit(x) { + if ((this.packed >>> 3 & 1) === 1) { + return true; + } return (this.packed >>> x & 1) === 1; }; - ChannelPermissions.prototype.setBit = function setBit() {}; + ChannelPermissions.prototype.setBit = function setBit(location, value) { + + if (value) { + // allow that permission + this.packed |= 1 << location; + } else { + // not allowed + this.packed &= 1 << location; + } + }; _createClass(ChannelPermissions, [{ + key: "asAllowDisallow", + get: function get() { + + var allow = 0, + disallow = 0; + + function ad(value, position) { + if (value) { + allow |= 1 << position; + } else { + disallow |= 1 << position; + } + } + + ad(this.canCreateInstantInvite, 0); + ad(this.manageRoles, 3); + ad(this.manageChannels, 4); + ad(this.readMessages, 10); + ad(this.sendMessages, 11); + ad(this.sendTTSMessages, 12); + ad(this.manageMessages, 13); + ad(this.embedLinks, 14); + ad(this.attachFiles, 15); + ad(this.readMessageHistory, 16); + ad(this.mentionEveryone, 17); + ad(this.voiceConnect, 20); + ad(this.voiceSpeak, 21); + ad(this.voiceMuteMembers, 22); + ad(this.voiceDeafenMembers, 23); + ad(this.voiceMoveMembers, 24); + ad(this.voiceUseVoiceActivation, 25); + + return { + allow: allow, + deny: disallow + }; + } + }, { key: "createInstantInvite", get: function get() { return this.getBit(0); diff --git a/lib/Client.js b/lib/Client.js index 6f5b8eb32..cf86c3b2f 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -12,7 +12,7 @@ var Channel = require("./channel.js"); var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); - +var ServerPermissions = require("./ServerPermissions.js"); var gameMap = require("../ref/gameMap.json"); //node modules @@ -66,7 +66,7 @@ var Client = (function () { this.checkingQueue = {}; this.userTypingListener = {}; this.queue = {}; - + this.guildRoleCreateIgnoreList = {}; this.__idleTime = null; this.__gameId = null; } @@ -479,10 +479,13 @@ var Client = (function () { var mention = _ref2; - mentions.push(self.addUser(mention)); + var user = self.addUser(mention); + if (channel.server) mentions.push(channel.server.getMember("id", user.id) || user);else mentions.push(user); } - var author = self.addUser(message.author); + var authorRaw = self.addUser(message.author), + author; + if (channel.server) author = channel.server.getMember("id", authorRaw.id) || authorRaw;else author = authorRaw; logs.push(new Message(message, channel, mentions, author)); } @@ -712,6 +715,271 @@ var Client = (function () { return prom; }; + Client.prototype.createRole = function createRole(dest, data) { + var cb = arguments.length <= 2 || arguments[2] === undefined ? function (err, perm) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var ddest = self.resolveServerID(dest); + var server = self.getServer("id", ddest); + + request.post(Endpoints.SERVERS + "/" + ddest + "/roles").set("authorization", self.token).end(function (err, res) { + + if (err) { + cb(err); + reject(err); + } else { + + var moddedPerm = new ServerPermissions(res.body, server); + + for (var key in data) { + moddedPerm[key] = data[key]; + } + + var perms = server.addRole(res.body); + self.guildRoleCreateIgnoreList[res.body.id] = function () { + self.updateRole(server, moddedPerm).then(function (perm) { + cb(null, perm); + resolve(perm); + })["catch"](function (err) { + cb(err); + reject(err); + }); + }; + } + }); + }); + }; + + Client.prototype.updateRole = function updateRole(server, role) { + var cb = arguments.length <= 2 || arguments[2] === undefined ? function (err, perm) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + + server = self.resolveServerID(server); + + request.patch(Endpoints.SERVERS + "/" + server + "/roles/" + role.id).set("authorization", self.token).send({ + color: role.color, + hoist: role.hoist, + name: role.name, + permissions: role.packed + }).end(function (err, res) { + if (err) { + cb(err); + reject(err); + } else { + + var data = self.getServer("id", server).updateRole(res.body); + resolve(data); + cb(null, data); + } + }); + }); + }; + + Client.prototype.deleteRole = function deleteRole(role) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1]; + + // role is a ServerPermissions + var self = this; + + return new Promise(function (resolve, reject) { + + request.del(Endpoints.SERVERS + "/" + role.server.id + "/roles/" + role.id).set("authorization", self.token).end(function (err) { + if (err) { + reject(err); + callback(err); + } else { + resolve(); + callback(); + } + }); + }); + }; + + Client.prototype.addMemberToRole = function addMemberToRole(member, role) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + try { + var serverId = self.resolveServerID(member.server); + var memberId = self.resolveUserID(member); + + var acServer = self.getServer("id", serverId); + var acMember = acServer.getMember("id", memberId); + + if (acMember.rawRoles.indexOf(role.id) !== -1) { + // user already has role + return; + } + + request.patch("https://discordapp.com/api/guilds/" + serverId + "/members/" + memberId).set("authorization", self.token).send({ + roles: acMember.rawRoles.concat(role.id) + }).end(function (err) { + if (err) { + reject(err); + callback(err); + } else { + acMember.addRole(role); + resolve(); + callback(); + } + }); + } catch (e) { + reject(e); + } + }); + }; + + Client.prototype.removeMemberFromRole = function removeMemberFromRole(member, role) { + var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2]; + + var self = this; + + return new Promise(function (resolve, reject) { + try { + var serverId = self.resolveServerID(member.server); + var memberId = self.resolveUserID(member); + + var acServer = self.getServer("id", serverId); + var acMember = acServer.getMember("id", memberId); + + if (~acMember.rawRoles.indexOf(role.id)) { + acMember.removeRole(role); + } + + console.log("remainder: ", acMember.rawRoles, "wanting", role.id); + + request.patch("https://discordapp.com/api/guilds/" + serverId + "/members/" + memberId).set("authorization", self.token).send({ + roles: acMember.rawRoles + }).end(function (err) { + if (err) { + reject(err); + callback(err); + } else { + acMember.addRole(role); + resolve(); + callback(); + } + }); + } catch (e) { + reject(e); + } + }); + }; + + Client.prototype.overwritePermissions = function overwritePermissions(channel, role, updatedStuff) { + var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err) {} : arguments[3]; + + var self = this; + + return new Promise(function (resolve, reject) { + + var data; + + if (role instanceof ServerPermissions || role.type === "role") { + data = ad(updatedStuff); + data.id = role.id; + data.type = "role"; + } else { + + data = ad(updatedStuff); + data.id = role.id; + data.type = "member"; + } + request.put(Endpoints.CHANNELS + "/" + channel.id + "/permissions/" + role.id).set("authorization", self.token).send(data).end(function (err) { + if (err) { + reject(err); + callback(err); + } else { + resolve(); + callback(); + } + }); + }); + + function ad(data) { + var allow = 0, + disallow = 0; + function bitit(value, position) { + if (value) { + allow |= 1 << position; + } else { + disallow |= 1 << position; + } + } + + for (var perm in data) { + switch (perm) { + case "canCreateInstantInvite": + bitit(data[perm], 0); + break; + case "manageRoles": + bitit(data[perm], 3); + break; + case "manageChannels": + bitit(data[perm], 4); + break; + case "readMessages": + bitit(data[perm], 10); + break; + case "sendMessages": + bitit(data[perm], 11); + break; + case "sendTTSMessages": + bitit(data[perm], 12); + break; + case "manageMessages": + bitit(data[perm], 13); + break; + case "embedLinks": + bitit(data[perm], 14); + break; + case "attachFiles": + bitit(data[perm], 15); + break; + case "readMessageHistory": + bitit(data[perm], 16); + break; + case "mentionEveryone": + bitit(data[perm], 17); + break; + case "voiceConnect": + bitit(data[perm], 20); + break; + case "voiceSpeak": + bitit(data[perm], 21); + break; + case "voiceMuteMembers": + bitit(data[perm], 22); + break; + case "voiceDeafenMembers": + bitit(data[perm], 23); + break; + case "voiceMoveMembers": + bitit(data[perm], 24); + break; + case "voiceUseVoiceActivation": + bitit(data[perm], 25); + break; + default: + break; + } + } + + return { + allow: allow, + deny: disallow + }; + } + }; + //def createws Client.prototype.createws = function createws(url) { @@ -804,6 +1072,8 @@ var Client = (function () { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? + + var channel = self.getChannel("id", data.channel_id); for (var _iterator6 = data.mentions, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { var _ref6; @@ -818,12 +1088,12 @@ var Client = (function () { var mention = _ref6; - mentions.push(self.addUser(mention)); + var user = self.addUser(mention); + if (channel.server) mentions.push(channel.server.getMember("id", user.id) || user);else mentions.push(user); } - var channel = self.getChannel("id", data.channel_id); if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + var msg = channel.addMessage(new Message(data, channel, mentions, data.author)); self.trigger("message", msg); } @@ -860,8 +1130,10 @@ var Client = (function () { info[key] = data[key]; } + data.mentions = data.mentions || []; var mentions = []; - for (var _iterator7 = info.mentions, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { + + for (var _iterator7 = data.mentions, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { var _ref7; if (_isArray7) { @@ -875,7 +1147,8 @@ var Client = (function () { var mention = _ref7; - mentions.push(self.addUser(mention)); + var user = self.addUser(mention); + if (channel.server) mentions.push(channel.server.getMember("id", user.id) || user);else mentions.push(user); } var newMessage = new Message(info, channel, mentions, formerMessage.author); @@ -998,6 +1271,16 @@ var Client = (function () { break; + case "GUILD_MEMBER_UPDATE": + + var user = self.addUser(data.user); + var server = self.getServer("id", data.guild_id); + var member = server.getMember("id", user.id); + self.trigger("serverMemberUpdate", member, data.roles); + server.getMember("id", user.id).rawRoles = data.roles; + + break; + case "USER_UPDATE": if (self.user && data.id === self.user.id) { @@ -1089,6 +1372,22 @@ var Client = (function () { break; + case "GUILD_ROLE_CREATE": + + var server = self.getServer("id", data.guild_id); + var role = data.role; + + if (self.guildRoleCreateIgnoreList[data.role.id]) { + server.addRole(role); + self.guildRoleCreateIgnoreList[data.role.id](); + self.guildRoleCreateIgnoreList[data.role.id] = null; + break; + } + + self.trigger("serverRoleCreate", server, server.addRole(role)); + + break; + case "GUILD_ROLE_DELETE": var server = self.getServer("id", data.guild_id); @@ -1361,7 +1660,16 @@ var Client = (function () { if (resource instanceof Server) { return resource.id; - } else if (!isNaN(resource) && resource.length && resource.length === 17) { + } else { + return resource; + } + }; + + Client.prototype.resolveUserID = function resolveUserID(resource) { + if (resource instanceof User) { + // also accounts for Member + return resource.id; + } else { return resource; } }; @@ -1433,6 +1741,8 @@ var Client = (function () { data.mentions = data.mentions || []; //for some reason this was not defined at some point? + var channel = self.getChannel("id", data.channel_id); + for (var _iterator15 = data.mentions, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { var _ref15; @@ -1447,12 +1757,12 @@ var Client = (function () { var mention = _ref15; - mentions.push(self.addUser(mention)); + var user = self.addUser(mention); + if (channel.server) mentions.push(channel.server.getMember("id", user.id) || user);else mentions.push(user); } - var channel = self.getChannel("id", data.channel_id); if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + var msg = channel.addMessage(new Message(data, channel, mentions, { id: data.author.id })); resolve(msg); } } diff --git a/lib/Color.js b/lib/Color.js new file mode 100644 index 000000000..4b1fef101 --- /dev/null +++ b/lib/Color.js @@ -0,0 +1,7 @@ +"use strict"; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Color = function Color() { + _classCallCheck(this, Color); +}; \ No newline at end of file diff --git a/lib/EvaluatedPermissions.js b/lib/EvaluatedPermissions.js index c4720c46b..44107811a 100644 --- a/lib/EvaluatedPermissions.js +++ b/lib/EvaluatedPermissions.js @@ -38,10 +38,22 @@ var EvaluatedPermissions = (function () { }; EvaluatedPermissions.prototype.getBit = function getBit(x) { + if ((this.packed >>> 3 & 1) === 1) { + return true; + } return (this.packed >>> x & 1) === 1; }; - EvaluatedPermissions.prototype.setBit = function setBit() {}; + EvaluatedPermissions.prototype.setBit = function setBit(location, value) { + + if (value) { + // allow that permission + this.packed |= 1 << location; + } else { + // not allowed + this.packed &= 1 << location; + } + }; _createClass(EvaluatedPermissions, [{ key: "createInstantInvite", diff --git a/lib/Member.js b/lib/Member.js index 813acda1b..80a19370e 100644 --- a/lib/Member.js +++ b/lib/Member.js @@ -21,16 +21,19 @@ var Member = (function (_User) { this.rawRoles = roles; } - Member.prototype.permissionsIn = function permissionsIn(channel) { + Member.prototype.removeRole = function removeRole(role) { + this.rawRoles.splice(this.rawRoles.indexOf(role.id), 1); + }; - if (channel.server.ownerID === this.id) { - return new EvaluatedPermissions(4294967295); //all perms + Member.prototype.addRole = function addRole(role) { + if (this.rawRoles.indexOf(role.id) == -1) { + console.log("wanted to add", role.id, this.rawRoles.indexOf(role.id)); + this.rawRoles.push(role.id); } + }; - var affectingOverwrites = []; - var affectingMemberOverwrites = []; - - for (var _iterator = channel.roles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + Member.prototype.hasRole = function hasRole(role) { + for (var _iterator = this.roles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { @@ -42,7 +45,35 @@ var Member = (function (_User) { _ref = _i.value; } - var overwrite = _ref; + var _role = _ref; + + if (role.id === _role.id) return true; + } + return false; + }; + + Member.prototype.permissionsIn = function permissionsIn(channel) { + + if (channel.server.ownerID === this.id) { + return new EvaluatedPermissions(4294967295); //all perms + } + + var affectingOverwrites = []; + var affectingMemberOverwrites = []; + + for (var _iterator2 = channel.roles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } + + var overwrite = _ref2; if (overwrite.id === this.id && overwrite.type === "member") { affectingMemberOverwrites.push(overwrite); @@ -57,25 +88,7 @@ var Member = (function (_User) { var finalPacked = affectingOverwrites.length !== 0 ? affectingOverwrites[0].packed : affectingMemberOverwrites[0].packed; - for (var _iterator2 = affectingOverwrites, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - var overwrite = _ref2; - - finalPacked = finalPacked & ~overwrite.deny; - finalPacked = finalPacked | overwrite.allow; - } - - for (var _iterator3 = affectingMemberOverwrites, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { + for (var _iterator3 = affectingOverwrites, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { var _ref3; if (_isArray3) { @@ -93,6 +106,24 @@ var Member = (function (_User) { finalPacked = finalPacked | overwrite.allow; } + for (var _iterator4 = affectingMemberOverwrites, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { + var _ref4; + + if (_isArray4) { + if (_i4 >= _iterator4.length) break; + _ref4 = _iterator4[_i4++]; + } else { + _i4 = _iterator4.next(); + if (_i4.done) break; + _ref4 = _i4.value; + } + + var overwrite = _ref4; + + finalPacked = finalPacked & ~overwrite.deny; + finalPacked = finalPacked | overwrite.allow; + } + return new EvaluatedPermissions(finalPacked); }; @@ -102,19 +133,19 @@ var Member = (function (_User) { var ufRoles = [this.server.getRole(this.server.id)]; - for (var _iterator4 = this.rawRoles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { - var _ref4; + for (var _iterator5 = this.rawRoles, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { + var _ref5; - if (_isArray4) { - if (_i4 >= _iterator4.length) break; - _ref4 = _iterator4[_i4++]; + if (_isArray5) { + if (_i5 >= _iterator5.length) break; + _ref5 = _iterator5[_i5++]; } else { - _i4 = _iterator4.next(); - if (_i4.done) break; - _ref4 = _i4.value; + _i5 = _iterator5.next(); + if (_i5.done) break; + _ref5 = _i5.value; } - var rawRole = _ref4; + var rawRole = _ref5; ufRoles.push(this.server.getRole(rawRole)); } @@ -128,19 +159,20 @@ var Member = (function (_User) { //cache roles as it can be slightly expensive basePerm = basePerms[0].packed; - for (var _iterator5 = basePerms, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { - var _ref5; + basePerms = basePerms || []; + for (var _iterator6 = basePerms, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { + var _ref6; - if (_isArray5) { - if (_i5 >= _iterator5.length) break; - _ref5 = _iterator5[_i5++]; + if (_isArray6) { + if (_i6 >= _iterator6.length) break; + _ref6 = _iterator6[_i6++]; } else { - _i5 = _iterator5.next(); - if (_i5.done) break; - _ref5 = _i5.value; + _i6 = _iterator6.next(); + if (_i6.done) break; + _ref6 = _i6.value; } - var perm = _ref5; + var perm = _ref6; basePerm = basePerm | perm.packed; } diff --git a/lib/ServerPermissions.js b/lib/ServerPermissions.js index 6384f759b..e6bfd4bb5 100644 --- a/lib/ServerPermissions.js +++ b/lib/ServerPermissions.js @@ -5,7 +5,7 @@ var _createClass = (function () { function defineProperties(target, props) { for function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var ServerPermissions = (function () { - function ServerPermissions(data) { + function ServerPermissions(data, server) { _classCallCheck(this, ServerPermissions); var self = this; @@ -14,17 +14,54 @@ var ServerPermissions = (function () { return (self.packed >>> x & 1) === 1; } - this.packed = data.permissions; - this.name = data.name; - this.id = data.id; + this.managed = data.managed || false; + this.position = data.position || 1; + this.hoist = data.hoist || false; + this.color = data.color || 0; + this.packed = data.permissions || 36953089; + this.name = data.name || "new role"; + this.id = data.id || null; + this.server = server; } + ServerPermissions.prototype.serialise = function serialise() { + return { + createInstantInvite: this.createInstantInvite, + manageRoles: this.manageRoles, + manageChannels: this.manageChannels, + readMessages: this.readMessages, + sendMessages: this.sendMessage, + sendTTSMessages: this.sendTTSMessages, + manageMessages: this.manageMessages, + embedLinks: this.embedLinks, + attachFiles: this.attachFiles, + readMessageHistory: this.readMessageHistory, + mentionEveryone: this.mentionEveryone, + voiceConnect: this.voiceConnect, + voiceSpeak: this.voiceSpeak, + voiceMuteMembers: this.voiceMuteMembers, + voiceDeafenMembers: this.voiceDeafenMembers, + voiceMoveMember: this.voiceMoveMembers, + voiceUseVoiceActivation: this.voiceUseVoiceActivation + }; + }; + ServerPermissions.prototype.getBit = function getBit(x) { + if ((this.packed >>> 3 & 1) === 1) { + return true; + } return (this.packed >>> x & 1) === 1; }; - ServerPermissions.prototype.setBit = function setBit() { - //dummy function for now + ServerPermissions.prototype.setBit = function setBit(location, value) { + + if (value) { + // allow that permission + this.packed |= 1 << location; + } else { + // not allowed + this.packed &= 1 << location; + } }; ServerPermissions.prototype.toString = function toString() { diff --git a/lib/index.js b/lib/index.js index d0edc45cf..a11654b8e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,10 +3,12 @@ var request = require("superagent"); var Endpoints = require("./Endpoints.js"); var Client = require("./Client.js"); +var Colors = require("../ref/colours.js"); var Discord = { Endpoints: Endpoints, - Client: Client + Client: Client, + Colors: Colors }; Discord.patchStrings = function () { diff --git a/lib/server.js b/lib/server.js index 46676d5eb..0bad69c64 100644 --- a/lib/server.js +++ b/lib/server.js @@ -38,7 +38,7 @@ var Server = (function () { var permissionGroup = _ref; - this.roles.push(new ServerPermissions(permissionGroup)); + this.roles.push(new ServerPermissions(permissionGroup, this)); } if (!data.members) { @@ -86,7 +86,7 @@ var Server = (function () { var role = _ref3; - if (role.id === id) { + if (role.id == id) { return role; } } @@ -94,14 +94,24 @@ var Server = (function () { return null; }; + Server.prototype.addRole = function addRole(data) { + + if (this.getRole(data.id)) { + return this.getRole(data.id); + } + + var perms = new ServerPermissions(data); + this.roles.push(perms); + return perms; + }; + Server.prototype.updateRole = function updateRole(data) { var oldRole = this.getRole(data.id); if (oldRole) { - var index = this.roles.indexOf(oldRole); - this.roles[index] = new ServerPermissions(data); + this.roles[index] = new ServerPermissions(data, this); return this.roles[index]; } else { diff --git a/ref/colours.js b/ref/colours.js new file mode 100644 index 000000000..ce650dad2 --- /dev/null +++ b/ref/colours.js @@ -0,0 +1,27 @@ +/* + credits to izy521 for the colour list] + https://github.com/izy521/discord.io/blob/master/docs/colors.md +*/ +module.exports = { + DEFAULT: 0, + AQUA: 1752220, + GREEN: 3066993, + BLUE: 3447003, + PURPLE: 10181046, + GOLD: 15844367, + ORANGE: 15105570, + RED: 15158332, + GREY: 9807270, + DARKER_GREY: 8359053, + NAVY: 3426654, + DARK_AQUA: 1146986, + DARK_GREEN: 2067276, + DARK_BLUE: 2123412, + DARK_PURPLE: 7419530, + DARK_GOLD: 12745742, + DARK_ORANGE: 11027200, + DARK_RED: 10038562, + DARK_GREY: 9936031, + LIGHT_GREY: 12370112, + DARK_NAVY: 2899536 +} \ No newline at end of file diff --git a/src/ChannelPermissions.js b/src/ChannelPermissions.js index 9d6dce2e4..7433ec0c6 100644 --- a/src/ChannelPermissions.js +++ b/src/ChannelPermissions.js @@ -1,86 +1,157 @@ -class ChannelPermissions{ - constructor(data, channel){ - +class ChannelPermissions { + constructor(data, channel) { + var self = this; - + function getBit(x) { return ((self.packed >>> x) & 1) === 1; } - + this.type = data.type; //either member or role this.id = data.id; - - if(this.type === "member"){ - this.packed = channel.server.getMember("id", data.id).evalPerms.packed; - }else{ - this.packed = channel.server.getRole(data.id).packed; + + if (this.type === "member") { + this.packed = channel.server.getMember("id", data.id).evalPerms.packed; + } else { + this.packed = channel.server.getRole(data.id).packed; } - + this.packed = this.packed & ~data.deny; this.packed = this.packed | data.allow; - + this.deny = data.deny; this.allow = data.allow; - + } - - get createInstantInvite(){return this.getBit(0);} - set createInstantInvite(val){this.setBit(0, val);} - - get manageRoles(){return this.getBit(3);} - set manageRoles(val){this.setBit(3, val);} - - get manageChannels(){return this.getBit(4);} - set manageChannels(val){this.setBit(4, val);} - - get readMessages(){return this.getBit(10);} - set readMessages(val){this.setBit(10, val);} - - get sendMessages(){return this.getBit(11);} - set sendMessages(val){this.setBit(11, val);} - - get sendTTSMessages(){return this.getBit(12);} - set sendTTSMessages(val){this.setBit(12, val);} - - get manageMessages(){return this.getBit(13);} - set manageMessages(val){this.setBit(13, val);} - - get embedLinks(){return this.getBit(14);} - set embedLinks(val){this.setBit(14, val);} - - get attachFiles(){return this.getBit(15);} - set attachFiles(val){this.setBit(15, val);} - - get readMessageHistory(){return this.getBit(16);} - set readMessageHistory(val){this.setBit(16, val);} - - get mentionEveryone(){return this.getBit(17);} - set mentionEveryone(val){this.setBit(17, val);} - - get voiceConnect(){return this.getBit(20);} - set voiceConnect(val){this.setBit(20, val);} - - get voiceSpeak(){return this.getBit(21);} - set voiceSpeak(val){this.setBit(21, val);} - - get voiceMuteMembers(){return this.getBit(22);} - set voiceMuteMembers(val){this.setBit(22, val);} - - get voiceDeafenMembers(){return this.getBit(23);} - set voiceDeafenMembers(val){this.setBit(23, val);} - - get voiceMoveMembers(){return this.getBit(24);} - set voiceMoveMembers(val){this.setBit(24, val);} - - get voiceUseVoiceActivation(){return this.getBit(25);} - set voiceUseVoiceActivation(val){this.setBit(25, val);} - + + serialise() { + return { + createInstantInvite: this.createInstantInvite, + manageRoles: this.manageRoles, + manageChannels: this.manageChannels, + readMessages: this.readMessages, + sendMessages: this.sendMessage, + sendTTSMessages: this.sendTTSMessages, + manageMessages: this.manageMessages, + embedLinks: this.embedLinks, + attachFiles: this.attachFiles, + readMessageHistory: this.readMessageHistory, + mentionEveryone: this.mentionEveryone, + voiceConnect: this.voiceConnect, + voiceSpeak: this.voiceSpeak, + voiceMuteMembers: this.voiceMuteMembers, + voiceDeafenMembers: this.voiceDeafenMembers, + voiceMoveMember: this.voiceMoveMembers, + voiceUseVoiceActivation: this.voiceUseVoiceActivation + } + } + + get asAllowDisallow() { + + var allow = 0, disallow = 0; + + function ad(value, position) { + if (value) { + allow |= (1 << position); + } else { + disallow |= (1 << position); + } + } + + ad(this.canCreateInstantInvite, 0); + ad(this.manageRoles, 3); + ad(this.manageChannels, 4); + ad(this.readMessages, 10); + ad(this.sendMessages, 11); + ad(this.sendTTSMessages, 12); + ad(this.manageMessages, 13); + ad(this.embedLinks, 14); + ad(this.attachFiles, 15); + ad(this.readMessageHistory, 16); + ad(this.mentionEveryone, 17); + ad(this.voiceConnect, 20); + ad(this.voiceSpeak, 21); + ad(this.voiceMuteMembers, 22); + ad(this.voiceDeafenMembers, 23); + ad(this.voiceMoveMembers, 24); + ad(this.voiceUseVoiceActivation, 25); + + + return { + allow : allow, + deny : disallow + }; + } + + get createInstantInvite() { return this.getBit(0); } + set createInstantInvite(val) { this.setBit(0, val); } + + get manageRoles() { return this.getBit(3); } + set manageRoles(val) { this.setBit(3, val); } + + get manageChannels() { return this.getBit(4); } + set manageChannels(val) { this.setBit(4, val); } + + get readMessages() { return this.getBit(10); } + set readMessages(val) { this.setBit(10, val); } + + get sendMessages() { return this.getBit(11); } + set sendMessages(val) { this.setBit(11, val); } + + get sendTTSMessages() { return this.getBit(12); } + set sendTTSMessages(val) { this.setBit(12, val); } + + get manageMessages() { return this.getBit(13); } + set manageMessages(val) { this.setBit(13, val); } + + get embedLinks() { return this.getBit(14); } + set embedLinks(val) { this.setBit(14, val); } + + get attachFiles() { return this.getBit(15); } + set attachFiles(val) { this.setBit(15, val); } + + get readMessageHistory() { return this.getBit(16); } + set readMessageHistory(val) { this.setBit(16, val); } + + get mentionEveryone() { return this.getBit(17); } + set mentionEveryone(val) { this.setBit(17, val); } + + get voiceConnect() { return this.getBit(20); } + set voiceConnect(val) { this.setBit(20, val); } + + get voiceSpeak() { return this.getBit(21); } + set voiceSpeak(val) { this.setBit(21, val); } + + get voiceMuteMembers() { return this.getBit(22); } + set voiceMuteMembers(val) { this.setBit(22, val); } + + get voiceDeafenMembers() { return this.getBit(23); } + set voiceDeafenMembers(val) { this.setBit(23, val); } + + get voiceMoveMembers() { return this.getBit(24); } + set voiceMoveMembers(val) { this.setBit(24, val); } + + get voiceUseVoiceActivation() { return this.getBit(25); } + set voiceUseVoiceActivation(val) { this.setBit(25, val); } + getBit(x) { + if (((this.packed >>> 3) & 1) === 1) { + return true; + } return ((this.packed >>> x) & 1) === 1; } - - setBit() { - + + setBit(location, value) { + + if (value) { + // allow that permission + this.packed |= (1 << location); + + } else { + // not allowed + this.packed &= (1 << location); + } + } } diff --git a/src/Client.js b/src/Client.js index b51a9d446..ba20b7f46 100644 --- a/src/Client.js +++ b/src/Client.js @@ -6,7 +6,7 @@ var Channel = require("./channel.js"); var Message = require("./message.js"); var Invite = require("./invite.js"); var PMChannel = require("./PMChannel.js"); - +var ServerPermissions = require("./ServerPermissions.js"); var gameMap = require("../ref/gameMap.json"); //node modules @@ -56,7 +56,7 @@ class Client { this.checkingQueue = {}; this.userTypingListener = {}; this.queue = {}; - + this.guildRoleCreateIgnoreList = {}; this.__idleTime = null; this.__gameId = null; } @@ -518,10 +518,18 @@ class Client { var mentions = []; for (var mention of message.mentions) { - mentions.push(self.addUser(mention)); + var user = self.addUser(mention); + if(channel.server) + mentions.push(channel.server.getMember("id", user.id) || user); + else + mentions.push(user); } - var author = self.addUser(message.author); + var authorRaw = self.addUser(message.author), author; + if(channel.server) + author = channel.server.getMember("id", authorRaw.id) || authorRaw; + else + author = authorRaw; logs.push(new Message(message, channel, mentions, author)); } @@ -756,6 +764,302 @@ class Client { return prom; } + + createRole(dest, data, cb = function (err, perm) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + var ddest = self.resolveServerID(dest); + var server = self.getServer("id", ddest); + + request + .post(`${Endpoints.SERVERS}/${ddest}/roles`) + .set("authorization", self.token) + .end(function (err, res) { + + if (err) { + cb(err); + reject(err); + } else { + + var moddedPerm = new ServerPermissions(res.body, server); + + for (var key in data) { + moddedPerm[key] = data[key]; + } + + var perms = server.addRole(res.body); + self.guildRoleCreateIgnoreList[res.body.id] = function () { + self.updateRole(server, moddedPerm) + .then((perm) => { + cb(null, perm); + resolve(perm); + }) + .catch((err) => { + cb(err); + reject(err); + }); + + } + + + } + + }); + + }); + + } + + updateRole(server, role, cb = function (err, perm) { }) { + + var self = this; + + return new Promise(function (resolve, reject) { + + server = self.resolveServerID(server); + + request + .patch(`${Endpoints.SERVERS}/${server}/roles/${role.id}`) + .set("authorization", self.token) + .send({ + color: role.color, + hoist: role.hoist, + name: role.name, + permissions: role.packed + }) + .end(function (err, res) { + if (err) { + cb(err); + reject(err); + } else { + + var data = self.getServer("id", server).updateRole(res.body); + resolve(data); + cb(null, data); + + } + }); + + }); + + } + + deleteRole(role, callback = function(err){}){ + + // role is a ServerPermissions + var self = this; + + return new Promise(function(resolve, reject){ + + request + .del(`${Endpoints.SERVERS}/${role.server.id}/roles/${role.id}`) + .set("authorization", self.token) + .end(function(err){ + if(err){ + reject(err); + callback(err); + }else{ + resolve(); + callback(); + } + }) + + }); + + } + + addMemberToRole(member, role, callback = function (err) { }) { + var self = this; + + return new Promise(function (resolve, reject) { + try{ + var serverId = self.resolveServerID(member.server); + var memberId = self.resolveUserID(member); + + var acServer = self.getServer("id", serverId); + var acMember = acServer.getMember("id", memberId); + + if(acMember.rawRoles.indexOf(role.id) !== -1){ + // user already has role + return; + } + + request + .patch(`https://discordapp.com/api/guilds/${serverId}/members/${memberId}`) + .set("authorization", self.token) + .send({ + roles: acMember.rawRoles.concat(role.id) + }) + .end(function (err) { + if (err) { + reject(err); + callback(err); + } else { + acMember.addRole(role); + resolve(); + callback(); + } + + }); + }catch(e){ + reject(e); + } + }); + } + + removeMemberFromRole(member, role, callback = function (err) { }) { + var self = this; + + return new Promise(function (resolve, reject) { + try{ + var serverId = self.resolveServerID(member.server); + var memberId = self.resolveUserID(member); + + var acServer = self.getServer("id", serverId); + var acMember = acServer.getMember("id", memberId); + + if(~acMember.rawRoles.indexOf(role.id)){ + acMember.removeRole(role); + } + + console.log("remainder: ",acMember.rawRoles, "wanting", role.id); + + request + .patch(`https://discordapp.com/api/guilds/${serverId}/members/${memberId}`) + .set("authorization", self.token) + .send({ + roles: acMember.rawRoles + }) + .end(function (err) { + if (err) { + reject(err); + callback(err); + } else { + acMember.addRole(role); + resolve(); + callback(); + } + + }); + }catch(e){ + reject(e); + } + }); + } + + overwritePermissions(channel, role, updatedStuff, callback=function(err){}){ + + var self = this; + + return new Promise(function(resolve, reject){ + + var data; + + if( role instanceof ServerPermissions || role.type === "role" ){ + data = ad(updatedStuff); + data.id = role.id; + data.type = "role"; + }else{ + + data = ad(updatedStuff); + data.id = role.id; + data.type = "member"; + + } + request + .put(`${Endpoints.CHANNELS}/${channel.id}/permissions/${role.id}`) + .set("authorization", self.token) + .send(data) + .end(function(err){ + if (err) { + reject(err); + callback(err); + } else { + resolve(); + callback(); + } + }); + + }); + + function ad(data){ + var allow = 0, disallow = 0; + function bitit(value, position){ + if (value) { + allow |= (1 << position); + } else { + disallow |= (1 << position); + } + } + + for(var perm in data){ + switch(perm){ + case "canCreateInstantInvite": + bitit(data[perm], 0); + break; + case "manageRoles": + bitit(data[perm], 3); + break; + case "manageChannels": + bitit(data[perm], 4); + break; + case "readMessages": + bitit(data[perm], 10); + break; + case "sendMessages": + bitit(data[perm], 11); + break; + case "sendTTSMessages": + bitit(data[perm], 12); + break; + case "manageMessages": + bitit(data[perm], 13); + break; + case "embedLinks": + bitit(data[perm], 14); + break; + case "attachFiles": + bitit(data[perm], 15); + break; + case "readMessageHistory": + bitit(data[perm], 16); + break; + case "mentionEveryone": + bitit(data[perm], 17); + break; + case "voiceConnect": + bitit(data[perm], 20); + break; + case "voiceSpeak": + bitit(data[perm], 21); + break; + case "voiceMuteMembers": + bitit(data[perm], 22); + break; + case "voiceDeafenMembers": + bitit(data[perm], 23); + break; + case "voiceMoveMembers": + bitit(data[perm], 24); + break; + case "voiceUseVoiceActivation": + bitit(data[perm], 25); + break; + default: + break; + } + } + + return { + allow: allow, + deny: disallow + }; + } + + } //def createws createws(url) { @@ -824,13 +1128,18 @@ class Client { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - for (var mention of data.mentions) { - mentions.push(self.addUser(mention)); - } var channel = self.getChannel("id", data.channel_id); + for (var mention of data.mentions) { + var user = self.addUser(mention); + if(channel.server) + mentions.push(channel.server.getMember("id", user.id) || user); + else + mentions.push(user); + } + if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + var msg = channel.addMessage(new Message(data, channel, mentions, data.author)); self.trigger("message", msg); } @@ -867,9 +1176,15 @@ class Client { info[key] = data[key]; } + data.mentions = data.mentions || []; var mentions = []; - for (var mention of info.mentions) { - mentions.push(self.addUser(mention)); + + for (var mention of data.mentions) { + var user = self.addUser(mention); + if(channel.server) + mentions.push(channel.server.getMember("id", user.id) || user); + else + mentions.push(user); } var newMessage = new Message(info, channel, mentions, formerMessage.author); @@ -995,6 +1310,16 @@ class Client { } break; + + case "GUILD_MEMBER_UPDATE": + + var user = self.addUser(data.user); + var server = self.getServer("id", data.guild_id); + var member = server.getMember("id", user.id); + self.trigger("serverMemberUpdate", member, data.roles); + server.getMember("id", user.id).rawRoles = data.roles; + + break; case "USER_UPDATE": @@ -1088,6 +1413,22 @@ class Client { break; + case "GUILD_ROLE_CREATE": + + var server = self.getServer("id", data.guild_id); + var role = data.role; + + if (self.guildRoleCreateIgnoreList[data.role.id]) { + server.addRole(role); + self.guildRoleCreateIgnoreList[data.role.id](); + self.guildRoleCreateIgnoreList[data.role.id] = null; + break; + } + + self.trigger("serverRoleCreate", server, server.addRole(role)); + + break; + case "GUILD_ROLE_DELETE": var server = self.getServer("id", data.guild_id); @@ -1282,12 +1623,20 @@ class Client { if (resource instanceof Server) { return resource.id; - } else if (!isNaN(resource) && resource.length && resource.length === 17) { + } else { return resource; } } + resolveUserID(resource) { + if (resource instanceof User) { // also accounts for Member + return resource.id; + } else { + return resource; + } + } + resolveDestination(destination) { var channId = false; var self = this; @@ -1349,14 +1698,19 @@ class Client { var mentions = []; data.mentions = data.mentions || []; //for some reason this was not defined at some point? - - for (var mention of data.mentions) { - mentions.push(self.addUser(mention)); - } var channel = self.getChannel("id", data.channel_id); + + for (var mention of data.mentions) { + var user = self.addUser(mention); + if(channel.server) + mentions.push(channel.server.getMember("id", user.id) || user); + else + mentions.push(user); + } + if (channel) { - var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author))); + var msg = channel.addMessage(new Message(data, channel, mentions, {id:data.author.id})); resolve(msg); } } diff --git a/src/EvaluatedPermissions.js b/src/EvaluatedPermissions.js index b7ccd1dde..fbdab9799 100644 --- a/src/EvaluatedPermissions.js +++ b/src/EvaluatedPermissions.js @@ -83,10 +83,22 @@ class EvaluatedPermissions { set voiceUseVoiceActivation(val) { this.setBit(25, val); } getBit(x) { + if( ((this.packed >>> 3) & 1) === 1 ){ + return true; + } return ((this.packed >>> x) & 1) === 1; } - setBit() { + setBit(location, value){ + + if(value){ + // allow that permission + this.packed |= (1 << location); + + }else{ + // not allowed + this.packed &= (1 << location); + } } } diff --git a/src/Member.js b/src/Member.js index aa48d0327..48023f3db 100644 --- a/src/Member.js +++ b/src/Member.js @@ -25,7 +25,8 @@ class Member extends User{ get evalPerms(){ var basePerms = this.roles, //cache roles as it can be slightly expensive basePerm = basePerms[0].packed; - + + basePerms = basePerms || []; for(var perm of basePerms){ basePerm = basePerm | perm.packed; } @@ -35,6 +36,25 @@ class Member extends User{ }); } + removeRole(role){ + this.rawRoles.splice(this.rawRoles.indexOf(role.id), 1); + } + + addRole(role){ + if(this.rawRoles.indexOf(role.id) == -1){ + console.log("wanted to add", role.id, this.rawRoles.indexOf(role.id)); + this.rawRoles.push(role.id); + } + } + + hasRole(role){ + for(var _role of this.roles){ + if(role.id === _role.id) + return true; + } + return false; + } + permissionsIn(channel){ if(channel.server.ownerID === this.id){ diff --git a/src/ServerPermissions.js b/src/ServerPermissions.js index b3fd848ae..e571e0b75 100644 --- a/src/ServerPermissions.js +++ b/src/ServerPermissions.js @@ -1,6 +1,6 @@ class ServerPermissions { - constructor(data) { + constructor(data, server) { var self = this; @@ -8,81 +8,119 @@ class ServerPermissions { return ((self.packed >>> x) & 1) === 1; } - this.packed = data.permissions; - this.name = data.name; - this.id = data.id; - + this.managed = data.managed || false; + this.position = data.position || 1; + this.hoist = data.hoist || false; + this.color = data.color || 0; + this.packed = data.permissions || 36953089; + this.name = data.name || "new role"; + this.id = data.id || null; + this.server = server; } - - get createInstantInvite(){return this.getBit(0);} - set createInstantInvite(val){this.setBit(0, val);} - - get banMembers(){return this.getBit(1);} - set banMembers(val){this.setBit(1, val);} - - get kickMembers(){return this.getBit(2);} - set kickMembers(val){this.setBit(2, val);} - - get manageRoles(){return this.getBit(3);} - set manageRoles(val){this.setBit(3, val);} - - get manageChannels(){return this.getBit(4);} - set manageChannels(val){this.setBit(4, val);} - - get manageServer(){return this.getBit(5);} - set manageServer(val){this.setBit(5, val);} - - get readMessages(){return this.getBit(10);} - set readMessages(val){this.setBit(10, val);} - - get sendMessages(){return this.getBit(11);} - set sendMessages(val){this.setBit(11, val);} - - get sendTTSMessages(){return this.getBit(12);} - set sendTTSMessages(val){this.setBit(12, val);} - - get manageMessages(){return this.getBit(13);} - set manageMessages(val){this.setBit(13, val);} - - get embedLinks(){return this.getBit(14);} - set embedLinks(val){this.setBit(14, val);} - - get attachFiles(){return this.getBit(15);} - set attachFiles(val){this.setBit(15, val);} - - get readMessageHistory(){return this.getBit(16);} - set readMessageHistory(val){this.setBit(16, val);} - - get mentionEveryone(){return this.getBit(17);} - set mentionEveryone(val){this.setBit(17, val);} - - get voiceConnect(){return this.getBit(20);} - set voiceConnect(val){this.setBit(20, val);} - - get voiceSpeak(){return this.getBit(21);} - set voiceSpeak(val){this.setBit(21, val);} - - get voiceMuteMembers(){return this.getBit(22);} - set voiceMuteMembers(val){this.setBit(22, val);} - - get voiceDeafenMembers(){return this.getBit(23);} - set voiceDeafenMembers(val){this.setBit(23, val);} - - get voiceMoveMembers(){return this.getBit(24);} - set voiceMoveMembers(val){this.setBit(24, val);} - - get voiceUseVoiceActivation(){return this.getBit(25);} - set voiceUseVoiceActivation(val){this.setBit(25, val);} + + serialise() { + return { + createInstantInvite: this.createInstantInvite, + manageRoles: this.manageRoles, + manageChannels: this.manageChannels, + readMessages: this.readMessages, + sendMessages: this.sendMessage, + sendTTSMessages: this.sendTTSMessages, + manageMessages: this.manageMessages, + embedLinks: this.embedLinks, + attachFiles: this.attachFiles, + readMessageHistory: this.readMessageHistory, + mentionEveryone: this.mentionEveryone, + voiceConnect: this.voiceConnect, + voiceSpeak: this.voiceSpeak, + voiceMuteMembers: this.voiceMuteMembers, + voiceDeafenMembers: this.voiceDeafenMembers, + voiceMoveMember: this.voiceMoveMembers, + voiceUseVoiceActivation: this.voiceUseVoiceActivation + } + } + + get createInstantInvite() { return this.getBit(0); } + set createInstantInvite(val) { this.setBit(0, val); } + + get banMembers() { return this.getBit(1); } + set banMembers(val) { this.setBit(1, val); } + + get kickMembers() { return this.getBit(2); } + set kickMembers(val) { this.setBit(2, val); } + + get manageRoles() { return this.getBit(3); } + set manageRoles(val) { this.setBit(3, val); } + + get manageChannels() { return this.getBit(4); } + set manageChannels(val) { this.setBit(4, val); } + + get manageServer() { return this.getBit(5); } + set manageServer(val) { this.setBit(5, val); } + + get readMessages() { return this.getBit(10); } + set readMessages(val) { this.setBit(10, val); } + + get sendMessages() { return this.getBit(11); } + set sendMessages(val) { this.setBit(11, val); } + + get sendTTSMessages() { return this.getBit(12); } + set sendTTSMessages(val) { this.setBit(12, val); } + + get manageMessages() { return this.getBit(13); } + set manageMessages(val) { this.setBit(13, val); } + + get embedLinks() { return this.getBit(14); } + set embedLinks(val) { this.setBit(14, val); } + + get attachFiles() { return this.getBit(15); } + set attachFiles(val) { this.setBit(15, val); } + + get readMessageHistory() { return this.getBit(16); } + set readMessageHistory(val) { this.setBit(16, val); } + + get mentionEveryone() { return this.getBit(17); } + set mentionEveryone(val) { this.setBit(17, val); } + + get voiceConnect() { return this.getBit(20); } + set voiceConnect(val) { this.setBit(20, val); } + + get voiceSpeak() { return this.getBit(21); } + set voiceSpeak(val) { this.setBit(21, val); } + + get voiceMuteMembers() { return this.getBit(22); } + set voiceMuteMembers(val) { this.setBit(22, val); } + + get voiceDeafenMembers() { return this.getBit(23); } + set voiceDeafenMembers(val) { this.setBit(23, val); } + + get voiceMoveMembers() { return this.getBit(24); } + set voiceMoveMembers(val) { this.setBit(24, val); } + + get voiceUseVoiceActivation() { return this.getBit(25); } + set voiceUseVoiceActivation(val) { this.setBit(25, val); } getBit(x) { + if (((this.packed >>> 3) & 1) === 1) { + return true; + } return ((this.packed >>> x) & 1) === 1; } - - setBit(){ - //dummy function for now + + setBit(location, value) { + + if (value) { + // allow that permission + this.packed |= (1 << location); + + } else { + // not allowed + this.packed &= (1 << location); + } + } - - toString(){ + + toString() { return this.name; } } diff --git a/src/index.js b/src/index.js index 53d7be58e..6bfd12014 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,12 @@ var request = require("superagent"); var Endpoints = require("./Endpoints.js"); var Client = require("./Client.js"); +var Colors = require("../ref/colours.js"); var Discord = { Endpoints : Endpoints, - Client : Client + Client : Client, + Colors : Colors } Discord.patchStrings = function () { diff --git a/src/server.js b/src/server.js index 458afa5e2..99401db65 100644 --- a/src/server.js +++ b/src/server.js @@ -17,7 +17,7 @@ class Server { this.roles = []; for(var permissionGroup of data.roles){ - this.roles.push( new ServerPermissions(permissionGroup) ); + this.roles.push( new ServerPermissions(permissionGroup, this) ); } if(!data.members){ @@ -75,23 +75,33 @@ class Server { getRole(id){ for (var role of this.roles) { - if (role.id === id) { + if (role.id == id) { return role; } } - + return null; } - updateRole(data){ + addRole(data){ + if(this.getRole(data.id)){ + return this.getRole(data.id); + } + + var perms = new ServerPermissions(data); + this.roles.push(perms); + return perms; + + } + + updateRole(data){ + var oldRole = this.getRole(data.id); if(oldRole){ - var index = this.roles.indexOf(oldRole); - this.roles[index] = new ServerPermissions(data); - + this.roles[index] = new ServerPermissions(data, this); return this.roles[index]; diff --git a/test/bot.1.js b/test/bot.1.js index b607701eb..722656d26 100644 --- a/test/bot.1.js +++ b/test/bot.1.js @@ -1,4 +1,5 @@ var Discord = require("../"); +var Member = require("../lib/Member.js"); var mybot = new Discord.Client(); var fs = require("fs"); var request = require("request").defaults({ encoding: null }); @@ -10,60 +11,67 @@ var server, channel, message, sentMessage = false; counter = 1; mybot.on("message", function (message) { - + console.log("Everyone mentioned? " + message.everyoneMentioned); - if (message.content.substr(0,3) !== "$$$") { + if (message.content.substr(0, 3) !== "$$$") { return; } // we can go ahead :) var user; - if(message.mentions.length > 0){ + if (message.mentions.length > 0) { user = message.mentions[0]; - }else{ + } else { user = message.sender; } - - console.log( mybot.getUser("username", "meew0") ); - - var perms = JSON.stringify(message.channel.permissionsOf(user).serialise(), null, 4); - perms = JSON.parse(perms); - - request.get(message.sender.avatarURL, function(err, resp, body){ - mybot.setAvatar( new Buffer(body) ).catch(error).then(() => { - mybot.reply(message, "I have your avatar now!"); - }); - }); + + this.createRole(message.channel.server, { + hoist: true, + color: true, + name: "discord users" + }).then( + (perm) => { + + mybot.addMemberToRole(user, perm).then( + () => { + mybot.overwritePermissions(message.channel, perm, { + sendMessages : false + }); + } + ) + + } + ) }); mybot.on("ready", function () { console.log("im ready"); - - for(var server of mybot.servers){ - if(server.name === "test-server"){ + + for (var server of mybot.servers) { + if (server.name === "test-server") { mybot.leaveServer(server); } } - + }); -mybot.on("debug", function(info){ - +mybot.on("debug", function (info) { + }) -mybot.on("unknown", function(info){ +mybot.on("unknown", function (info) { console.log("warning!", info); }) -mybot.on("channelUpdate", function(oldChan, newChan){ - +mybot.on("channelUpdate", function (oldChan, newChan) { + }); function dump(msg) { - console.log(msg); + console.log("dump", msg); } function error(err) {